30 #include <visp3/io/vpJsonArgumentParser.h>
31 #include <visp3/core/vpException.h>
32 #include <visp3/core/vpConfig.h>
36 #if defined(VISP_HAVE_NLOHMANN_JSON)
38 using json = nlohmann::json;
41 const std::string &nestSeparator) :
42 description(description),
43 jsonFileArgumentName(jsonFileArgumentName),
44 nestSeparator(nestSeparator)
46 if (jsonFileArgumentName.empty()) {
50 if (nestSeparator.empty()) {
54 helpers[jsonFileArgumentName] = []() -> std::string {
55 return "Path to the JSON configuration file. Values in this files are loaded, and can be overridden by command line arguments.\nOptional";
63 ss <<
"Program description: " << description << std::endl;
64 ss <<
"Arguments: " << std::endl;
65 unsigned spacesBetweenArgAndDescription = 0;
66 for (
const auto &helper : helpers) {
67 if (helper.first.size() > spacesBetweenArgAndDescription) {
68 spacesBetweenArgAndDescription =
static_cast<unsigned int>(helper.first.size());
71 spacesBetweenArgAndDescription += 4;
73 for (
const auto &helper : helpers) {
74 std::stringstream argss(helper.second());
77 while (getline(argss, line,
'\n')) {
78 const unsigned lineSpace = first ? spacesBetweenArgAndDescription -
static_cast<unsigned>(helper.first.size()) : spacesBetweenArgAndDescription;
79 const std::string spaceBetweenArgAndDescription(lineSpace,
' ');
81 ss <<
"\t" << helper.first << spaceBetweenArgAndDescription << line << std::endl;
84 ss <<
"\t" << spaceBetweenArgAndDescription << line << std::endl;
91 ss <<
"Example JSON configuration file: " << std::endl << std::endl;
92 ss << exampleJson.dump(2) << std::endl;
99 const std::vector<std::string> arguments(argv + 1, argv + argc);
100 std::vector<unsigned> ignoredArguments;
101 const auto jsonFileArgumentPos = std::find(arguments.begin(), arguments.end(), jsonFileArgumentName);
103 if (jsonFileArgumentPos != arguments.end()) {
104 ignoredArguments.push_back(
static_cast<unsigned>(jsonFileArgumentPos - arguments.begin() + 1));
105 ignoredArguments.push_back(
static_cast<unsigned>(jsonFileArgumentPos - arguments.begin() + 2));
107 if (jsonFileArgumentPos == arguments.end() - 1) {
110 const std::string jsonFileName = *(jsonFileArgumentPos + 1);
111 std::ifstream jsonFile(jsonFileName);
112 if (!jsonFile.good()) {
113 std::stringstream ss;
114 ss <<
"Could not open JSON file " << jsonFileName <<
"! Make sure it exists and is readable" << std::endl;
117 j = json::parse(jsonFile);
121 for (
int i = 1; i < argc; ++i) {
122 const std::string arg = argv[i];
123 if (std::find(ignoredArguments.begin(), ignoredArguments.end(), i) != ignoredArguments.end()) {
126 if (arg ==
"-h" || arg ==
"--help") {
127 std::cout <<
help() << std::endl;
131 if (parsers.find(arg) != parsers.end()) {
133 updaters[arg](j, std::string(argv[i + 1]));
137 std::stringstream ss;
138 ss <<
"Argument " << arg <<
" was passed but no value was provided" << std::endl;
143 std::cerr <<
"Unknown parameter when parsing: " << arg << std::endl;
148 for (
const auto &parser : parsers) {
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
std::string help() const
Generate a help message, containing the description of the arguments, their default value and whether...
void parse(int argc, const char *argv[])
Parse the arguments.
vpJsonArgumentParser(const std::string &description, const std::string &jsonFileArgumentName, const std::string &nestSeparator)
Create a new argument parser, that can take into account both a JSON configuration file and command l...