2 #include "precomp.hpp"
\r
9 struct CommandLineParserParams
\r
12 string help_message;
\r
14 vector<string> keys;
\r
19 struct CommandLineParser::Impl
\r
22 string error_message;
\r
23 string about_message;
\r
28 vector<CommandLineParserParams> data;
\r
30 Impl() { refcount = 1; }
\r
31 Impl(int argc, const char* const argv[], const char* keys);
\r
33 vector<string> split_range_string(const string& str, char fs, char ss) const;
\r
34 vector<string> split_string(const string& str, char symbol = ' ', bool create_empty_item = false) const;
\r
35 string trim_spaces(const string& str) const;
\r
37 void apply_params(const string& key, const string& value);
\r
38 void apply_params(int i, string value);
\r
45 static string get_type_name(int type)
\r
47 if( type == Param::INT )
\r
49 if( type == Param::UNSIGNED_INT )
\r
51 if( type == Param::UINT64 )
\r
52 return "unsigned long long";
\r
53 if( type == Param::FLOAT )
\r
55 if( type == Param::REAL )
\r
57 if( type == Param::STRING )
\r
62 static void from_str(const string& str, int type, void* dst)
\r
64 std::stringstream ss(str);
\r
65 if( type == Param::INT )
\r
67 else if( type == Param::UNSIGNED_INT )
\r
68 ss >> *(unsigned*)dst;
\r
69 else if( type == Param::UINT64 )
\r
70 ss >> *(uint64*)dst;
\r
71 else if( type == Param::FLOAT )
\r
73 else if( type == Param::REAL )
\r
74 ss >> *(double*)dst;
\r
75 else if( type == Param::STRING )
\r
76 ss >> *(string*)dst;
\r
78 throw cv::Exception(CV_StsBadArg, "unknown/unsupported parameter type", "", __FILE__, __LINE__);
\r
82 string err_msg = "can not convert: [" + str +
\r
83 + "] to [" + get_type_name(type) + "]";
\r
85 throw cv::Exception(CV_StsBadArg, err_msg, "", __FILE__, __LINE__);
\r
89 string CommandLineParser::getString(const string& name)
\r
91 for (size_t i = 0; i < impl->data.size(); i++)
\r
93 for (size_t j = 0; j < impl->data[i].keys.size(); j++)
\r
95 if (name.compare(impl->data[i].keys[j]) == 0)
\r
97 string v = impl->data[i].def_value;
\r
105 void CommandLineParser::getByName(const string& name, bool space_delete, int type, void* dst) const
\r
109 string v = ((CommandLineParser*)this)->getString(name);
\r
112 impl->error = true;
\r
113 impl->error_message += "Unknown parametes " + name + "\n";
\r
118 v = impl->trim_spaces(v);
\r
119 from_str(v, type, dst);
\r
123 catch (std::exception& e)
\r
125 impl->error = true;
\r
126 impl->error_message += "Exception: " + string(e.what()) + "\n";
\r
131 void CommandLineParser::getByIndex(int index, bool space_delete, int type, void* dst) const
\r
135 for (size_t i = 0; i < impl->data.size(); i++)
\r
137 if (impl->data[i].number == index)
\r
139 string v = impl->data[i].def_value;
\r
140 if (space_delete == true) v = impl->trim_spaces(v);
\r
141 from_str(v, type, dst);
\r
145 impl->error = true;
\r
146 impl->error_message += "Unknown parametes #" + format("%d", index) + "\n";
\r
148 catch(std::exception & e)
\r
150 impl->error = true;
\r
151 impl->error_message += "Exception: " + string(e.what()) + "\n";
\r
155 static bool cmp_params(const CommandLineParserParams & p1, const CommandLineParserParams & p2)
\r
157 if (p1.number > p2.number)
\r
160 if (p1.number == -1 && p2.number == -1)
\r
162 if (p1.keys[0].compare(p2.keys[0]) > 0)
\r
171 CommandLineParser::CommandLineParser(int argc, const char* const argv[], const string& keys)
\r
173 impl = new Impl(argc, argv, keys.c_str());
\r
176 CommandLineParser::CommandLineParser(int argc, const char* const argv[], const char* keys)
\r
178 impl = new Impl(argc, argv, keys);
\r
181 CommandLineParser::Impl::Impl(int argc, const char* const argv[], const char* keys)
\r
185 // path to application
\r
186 size_t pos_s = string(argv[0]).find_last_of("/\\");
\r
187 if (pos_s == string::npos)
\r
190 app_name = string(argv[0]);
\r
194 path_to_app = string(argv[0]).substr(0, pos_s);
\r
195 app_name = string(argv[0]).substr(pos_s + 1, string(argv[0]).length() - pos_s);
\r
199 error_message = "";
\r
202 vector<string> k = split_range_string(keys, '{', '}');
\r
205 for (size_t i = 0; i < k.size(); i++)
\r
207 vector<string> l = split_string(k[i], '|', true);
\r
208 CommandLineParserParams p;
\r
209 p.keys = split_string(l[0]);
\r
210 p.def_value = l[1];
\r
211 p.help_message = trim_spaces(l[2]);
\r
213 if (p.keys[0][0] == '@')
\r
224 for (int i = 1; i < argc; i++)
\r
226 string s = string(argv[i]);
\r
228 if (s.find('=') != string::npos && s.find('=') < s.length())
\r
230 vector<string> k_v = split_string(s, '=', true);
\r
231 for (int h = 0; h < 2; h++)
\r
233 if (k_v[0][0] == '-')
\r
234 k_v[0] = k_v[0].substr(1, k_v[0].length() -1);
\r
236 apply_params(k_v[0], k_v[1]);
\r
238 else if (s.length() > 1 && s[0] == '-')
\r
240 for (int h = 0; h < 2; h++)
\r
243 s = s.substr(1, s.length() - 1);
\r
245 apply_params(s, "true");
\r
247 else if (s[0] != '-')
\r
249 apply_params(jj, s);
\r
258 CommandLineParser::CommandLineParser(const CommandLineParser& parser)
\r
260 impl = parser.impl;
\r
261 CV_XADD(&impl->refcount, 1);
\r
264 CommandLineParser& CommandLineParser::operator = (const CommandLineParser& parser)
\r
266 if( this != &parser )
\r
268 if(CV_XADD(&impl->refcount, -1) == 1)
\r
270 impl = parser.impl;
\r
271 CV_XADD(&impl->refcount, 1);
\r
276 void CommandLineParser::about(const string& message)
\r
278 impl->about_message = message;
\r
281 void CommandLineParser::Impl::apply_params(const string& key, const string& value)
\r
283 for (size_t i = 0; i < data.size(); i++)
\r
285 for (size_t k = 0; k < data[i].keys.size(); k++)
\r
287 if (key.compare(data[i].keys[k]) == 0)
\r
289 data[i].def_value = value;
\r
296 void CommandLineParser::Impl::apply_params(int i, string value)
\r
298 for (size_t j = 0; j < data.size(); j++)
\r
300 if (data[j].number == i)
\r
302 data[j].def_value = value;
\r
308 void CommandLineParser::Impl::sort_params()
\r
310 for (size_t i = 0; i < data.size(); i++)
\r
312 sort(data[i].keys.begin(), data[i].keys.end());
\r
315 sort (data.begin(), data.end(), cmp_params);
\r
318 string CommandLineParser::Impl::trim_spaces(const string& str) const
\r
320 int left = 0, right = (int)str.length();
\r
321 while( left <= right && str[left] == ' ' )
\r
323 while( right > left && str[right-1] == ' ' )
\r
325 return left >= right ? string("") : str.substr(left, right-left);
\r
328 string CommandLineParser::getPathToApplication() const
\r
330 return impl->path_to_app;
\r
333 bool CommandLineParser::has(const string& name)
\r
335 for (size_t i = 0; i < impl->data.size(); i++)
\r
337 for (size_t j = 0; j < impl->data[i].keys.size(); j++)
\r
339 if (name.compare(impl->data[i].keys[j]) == 0 && string("true").compare(impl->data[i].def_value) == 0)
\r
348 bool CommandLineParser::check() const
\r
350 return impl->error == false;
\r
353 void CommandLineParser::printErrors() const
\r
357 std::cout << std::endl << "ERRORS:" << std::endl << impl->error_message << std::endl;
\r
361 void CommandLineParser::printParams()
\r
366 void CommandLineParser::printMessage() const
\r
368 if (impl->about_message != "")
\r
369 std::cout << impl->about_message << std::endl;
\r
371 std::cout << "Usage: " << impl->app_name << " [params] ";
\r
373 for (size_t i = 0; i < impl->data.size(); i++)
\r
375 if (impl->data[i].number > -1)
\r
377 string name = impl->data[i].keys[0].substr(1, impl->data[i].keys[0].length() - 1);
\r
378 std::cout << name << " ";
\r
382 std::cout << std::endl << std::endl;
\r
384 for (size_t i = 0; i < impl->data.size(); i++)
\r
386 if (impl->data[i].number == -1)
\r
389 for (size_t j = 0; j < impl->data[i].keys.size(); j++)
\r
391 string k = impl->data[i].keys[j];
\r
392 if (k.length() > 1)
\r
402 if (j != impl->data[i].keys.size() - 1)
\r
407 string dv = impl->trim_spaces(impl->data[i].def_value);
\r
408 if (dv.compare("") != 0)
\r
410 std::cout << " (value:" << dv << ")";
\r
412 std::cout << std::endl << "\t\t" << impl->data[i].help_message << std::endl;
\r
415 std::cout << std::endl;
\r
417 for (size_t i = 0; i < impl->data.size(); i++)
\r
419 if (impl->data[i].number != -1)
\r
422 string k = impl->data[i].keys[0];
\r
423 k = k.substr(1, k.length() - 1);
\r
427 string dv = impl->trim_spaces(impl->data[i].def_value);
\r
428 if (dv.compare("") != 0)
\r
430 std::cout << " (value:" << dv << ")";
\r
432 std::cout << std::endl << "\t\t" << impl->data[i].help_message << std::endl;
\r
437 vector<string> CommandLineParser::Impl::split_range_string(const string& _str, char fs, char ss) const
\r
440 vector<string> vec;
\r
442 bool begin = false;
\r
444 while (!str.empty())
\r
450 throw cv::Exception(CV_StsParseError,
\r
451 string("error in split_range_string(")
\r
458 "", __FILE__, __LINE__
\r
463 str = str.substr(1, str.length() - 1);
\r
468 if (begin == false)
\r
470 throw cv::Exception(CV_StsParseError,
\r
471 string("error in split_range_string(")
\r
478 "", __FILE__, __LINE__
\r
482 vec.push_back(word);
\r
489 str = str.substr(1, str.length() - 1);
\r
494 throw cv::Exception(CV_StsParseError,
\r
495 string("error in split_range_string(")
\r
502 "", __FILE__, __LINE__
\r
509 vector<string> CommandLineParser::Impl::split_string(const string& _str, char symbol, bool create_empty_item) const
\r
512 vector<string> vec;
\r
515 while (!str.empty())
\r
517 if (str[0] == symbol)
\r
519 if (!word.empty() || create_empty_item)
\r
521 vec.push_back(word);
\r
529 str = str.substr(1, str.length() - 1);
\r
532 if (word != "" || create_empty_item)
\r
534 vec.push_back(word);
\r