12 printf("\nThe CommandLineParser class is designed for command line arguments parsing\n"
14 "Before you start to work with CommandLineParser you have to create a map for keys.\n"
15 " It will look like this\n"
16 " const char* keys =\n"
18 " { s| string| 123asd |string parameter}\n"
19 " { d| digit | 100 |digit parameter }\n"
20 " { c|noCamera|false |without camera }\n"
21 " { 1| |some text|help }\n"
22 " { 2| |333 |another help }\n"
25 " \"{\" - start of parameter string.\n"
26 " \"}\" - end of parameter string\n"
27 " \"|\" - separator between short name, full name, default value and help\n"
28 "Supported syntax: \n"
29 " --key1=arg1 <If a key with '--' must has an argument\n"
30 " you have to assign it through '=' sign.> \n"
31 "<If the key with '--' doesn't have any argument, it means that it is a bool key>\n"
32 " -key2=arg2 <If a key with '-' must has an argument \n"
33 " you have to assign it through '=' sign.> \n"
34 "If the key with '-' doesn't have any argument, it means that it is a bool key\n"
35 " key3 <This key can't has any parameter> \n"
37 " Imagine that the input parameters are next:\n"
38 " -s=string_value --digit=250 --noCamera lena.jpg 10000\n"
39 " CommandLineParser parser(argc, argv, keys) - create a parser object\n"
40 " parser.get<string>(\"s\" or \"string\") will return you first parameter value\n"
41 " parser.get<string>(\"s\", false or \"string\", false) will return you first parameter value\n"
42 " without spaces in end and begin\n"
43 " parser.get<int>(\"d\" or \"digit\") will return you second parameter value.\n"
44 " It also works with 'unsigned int', 'double', and 'float' types>\n"
45 " parser.get<bool>(\"c\" or \"noCamera\") will return you true .\n"
46 " If you enter this key in commandline>\n"
47 " It return you false otherwise.\n"
48 " parser.get<string>(\"1\") will return you the first argument without parameter (lena.jpg) \n"
49 " parser.get<int>(\"2\") will return you the second argument without parameter (10000)\n"
50 " It also works with 'unsigned int', 'double', and 'float' types \n"
54 vector<string> split_string(const string& str, const string& delimiters)
58 string split_str = str;
59 size_t pos_delim = split_str.find(delimiters);
61 while ( pos_delim != string::npos)
66 split_str.erase(0, 1);
70 res.push_back(split_str.substr(0, pos_delim));
71 split_str.erase(0, pos_delim + 1);
74 pos_delim = split_str.find(delimiters);
77 res.push_back(split_str);
82 string del_space(string name)
84 while ((name.find_first_of(' ') == 0) && (name.length() > 0))
87 while ((name.find_last_of(' ') == (name.length() - 1)) && (name.length() > 0))
88 name.erase(name.end() - 1, name.end());
95 static bool keyIsNumber(const std::string & option, size_t start)
98 size_t end = option.find_first_of('=', start);
99 end = option.npos == end ? option.length() : end;
101 for ( ; start < end; ++start)
102 if (!isdigit(option[start]))
111 CommandLineParser::CommandLineParser(int argc, const char* const argv[], const char* keys)
113 std::string keys_buffer;
114 std::string values_buffer;
117 std::vector<string> keysVector;
118 std::vector<string> paramVector;
119 std::map<std::string, std::vector<std::string> >::iterator it;
121 int currentIndex = 1;
122 //bool isFound = false;
123 bool withNoKey = false;
124 bool hasValueThroughEq = false;
127 while (!keys_buffer.empty())
130 flagPosition = keys_buffer.find_first_of('}');
132 buffer = keys_buffer.substr(0, flagPosition);
133 keys_buffer.erase(0, flagPosition);
135 flagPosition = buffer.find('{');
136 if (flagPosition != buffer.npos)
137 buffer.erase(flagPosition, (flagPosition + 1));
139 flagPosition = buffer.find('}');
140 if (flagPosition != buffer.npos)
141 buffer.erase(flagPosition);
143 paramVector = split_string(buffer, "|");
144 while (paramVector.size() < 4) paramVector.push_back("");
146 buffer = paramVector[0];
147 buffer += '|' + paramVector[1];
149 //if (buffer == "") CV_ERROR(CV_StsBadArg, "In CommandLineParser need set short and full name");
151 paramVector.erase(paramVector.begin(), paramVector.begin() + 2);
152 data[buffer] = paramVector;
158 for (int i = 1; i < argc; i++)
164 size_t nondash = curName.find_first_not_of("-");
165 if (nondash == 0 || nondash == curName.npos || keyIsNumber(curName, nondash))
168 curName.erase(0, nondash);
170 if (curName.find('=') != curName.npos)
172 hasValueThroughEq = true;
174 curName.erase(curName.find('='));
175 buffer.erase(0, (buffer.find('=') + 1));
178 values_buffer = del_space(values_buffer);
180 for(it = data.begin(); it != data.end(); it++)
182 keys_buffer = it->first;
183 keysVector = split_string(keys_buffer, "|");
185 for (size_t j = 0; j < keysVector.size(); j++) keysVector[j] = del_space(keysVector[j]);
187 values_buffer = it->second[0];
188 if (((curName == keysVector[0]) || (curName == keysVector[1])) && hasValueThroughEq)
190 it->second[0] = buffer;
195 if (!hasValueThroughEq && ((curName == keysVector[0]) || (curName == keysVector[1]))
197 values_buffer.find("false") != values_buffer.npos ||
201 it->second[0] = "true";
206 if (!hasValueThroughEq && (values_buffer.find("false") == values_buffer.npos) &&
207 ((curName == keysVector[0]) || (curName == keysVector[1])))
209 it->second[0] = argv[++i];
217 std::string noKeyStr = it->first;
218 if(atoi(noKeyStr.c_str()) == currentIndex)
220 it->second[0] = curName;
229 hasValueThroughEq = false;
234 bool CommandLineParser::has(const std::string& keys)
236 std::map<std::string, std::vector<std::string> >::iterator it;
237 std::vector<string> keysVector;
239 for(it = data.begin(); it != data.end(); it++)
241 keysVector = split_string(it->first, "|");
242 for (size_t i = 0; i < keysVector.size(); i++) keysVector[i] = del_space(keysVector[i]);
244 if (keysVector.size() == 1) keysVector.push_back("");
246 if ((del_space(keys).compare(keysVector[0]) == 0) ||
247 (del_space(keys).compare(keysVector[1]) == 0))
254 std::string CommandLineParser::getString(const std::string& keys)
256 std::map<std::string, std::vector<std::string> >::iterator it;
257 std::vector<string> valueVector;
259 for(it = data.begin(); it != data.end(); it++)
261 valueVector = split_string(it->first, "|");
262 for (size_t i = 0; i < valueVector.size(); i++) valueVector[i] = del_space(valueVector[i]);
264 if (valueVector.size() == 1) valueVector.push_back("");
266 if ((del_space(keys).compare(valueVector[0]) == 0) ||
267 (del_space(keys).compare(valueVector[1]) == 0))
268 return it->second[0];
273 template<typename _Tp>
274 _Tp CommandLineParser::fromStringNumber(const std::string& str)//the default conversion function for numbers
276 return getData<_Tp>(str);
279 void CommandLineParser::printParams()
284 std::map<std::string, std::vector<std::string> >::iterator it;
285 std::vector<string> keysVector;
287 for(it = data.begin(); it != data.end(); it++)
289 keysVector = split_string(it->first, "|");
290 for (size_t i = 0; i < keysVector.size(); i++) keysVector[i] = del_space(keysVector[i]);
294 if (keysVector[0] != "")
296 buf = "-" + keysVector[0];
297 if (keysVector[1] != "") buf += ", --" + keysVector[1];
299 else if (keysVector[1] != "") buf += "--" + keysVector[1];
300 if (del_space(it->second[0]) != "") buf += "=[" + del_space(it->second[0]) + "]";
302 cout << setw(col_p-2) << left << buf;
304 if ((int)buf.length() > col_p-2)
307 cout << setw(col_p-2) << left << " ";
311 if (del_space(it->second[1]) != "") buf += del_space(it->second[1]);
315 bool tr = ((int)buf.length() > col_d-2) ? true: false;
316 std::string::size_type pos = 0;
320 pos = buf.find_first_of(' ');
323 if (buf.find_first_of(' ', pos + 1 ) < (std::string::size_type)(col_d-2) &&
324 buf.find_first_of(' ', pos + 1 ) != std::string::npos)
325 pos = buf.find_first_of(' ', pos + 1);
330 cout << setw(col_d-2) << left << buf.substr(0, pos) << endl;
334 cout << setw(col_d-2) << left << buf<< endl;
340 cout << setw(col_p-2) << left << " ";
346 bool CommandLineParser::get<bool>(const std::string& name, bool space_delete)
348 std::string str_buf = getString(name);
350 if (space_delete && str_buf != "")
352 str_buf = del_space(str_buf);
355 if (str_buf == "true")
361 std::string CommandLineParser::analyzeValue<std::string>(const std::string& str, bool space_delete)
365 return del_space(str);
371 int CommandLineParser::analyzeValue<int>(const std::string& str, bool /*space_delete*/)
373 return fromStringNumber<int>(str);
377 unsigned int CommandLineParser::analyzeValue<unsigned int>(const std::string& str, bool /*space_delete*/)
379 return fromStringNumber<unsigned int>(str);
383 uint64 CommandLineParser::analyzeValue<uint64>(const std::string& str, bool /*space_delete*/)
385 return fromStringNumber<uint64>(str);
389 float CommandLineParser::analyzeValue<float>(const std::string& str, bool /*space_delete*/)
391 return fromStringNumber<float>(str);
395 double CommandLineParser::analyzeValue<double>(const std::string& str, bool /*space_delete*/)
397 return fromStringNumber<double>(str);