Commit fe279279 authored by Kirill Kornyakov's avatar Kirill Kornyakov

Update CommandLineParser class

parent 4b405370
...@@ -4171,126 +4171,85 @@ protected: ...@@ -4171,126 +4171,85 @@ protected:
The class is used for reading command arguments. The class is used for reading command arguments.
Supports the following syntax: Supports the following syntax:
//-k 10 1 2 --x 0.001 --size 640 480 --inputFile lena.jpg //-k=10 --x 0.001 --inputFile lena.jpg
int k = parser.get<int>("--k | -k", -1); int k = parser.get<int>("--k | -k", -1);
vector<int> kValues=parser.getVec<int>("--k | -k");
double x = parser.get<double>("--x"); double x = parser.get<double>("--x");
cv::Size size = parser.get<cv::Size>("--size");
string inputFile = parser.get<string>("--inputFile"); string inputFile = parser.get<string>("--inputFile");
*/ */
class CV_EXPORTS CommandLineParser class CV_EXPORTS CommandLineParser
{ {
public: public:
//! the default constructor
CommandLineParser(int argc, const char* argv[]);
//! allows to check if parameter is given
bool has(const std::string& keys) const;
//! get parameter //! the default constructor
template<typename _Tp> CommandLineParser(int argc, const char* argv[]);
_Tp get(const std::string& name)
{
return fromStringsVec<_Tp>(getVec<std::string>(name));
}
//! get parameter with default value
template<typename _Tp>
_Tp get(const std::string& name, const _Tp& default_value)
{
if (!has(name))
return default_value;
return get<_Tp>(name);
}
//! get a vector of values for specified key //! allows to check if parameter is given
template<typename _Tp> bool has(const std::string& keys) const;
std::vector<_Tp> getVec(const std::string& keys);
protected: //! get parameter, if parameter is not given get default parameter
std::map<std::string, std::vector<std::string> > data; template<typename _Tp>
_Tp get(const std::string& name, const _Tp& default_value = _Tp())
template<typename _Tp> {
static _Tp fromStringSimple(const std::string& str)//the default conversion function std::string str = getString(name);
{ if (!has(name))
_Tp res; return default_value;
std::stringstream s1(str); return analizeValue<_Tp>(str);
s1 >> res; }
return res;
}
template<typename _Tp>
static _Tp fromString(const std::string& str)
{
return fromStringSimple<_Tp>(str);
}
template<typename _Tp> protected:
static _Tp fromStringNumber(const std::string& str)//the default conversion function for numbers std::map<std::string, std::vector<std::string> > data;
{ std::string getString(const std::string& name) const;
_Tp dummy_val=0; dummy_val+=1;
if (str.empty()) template<typename _Tp>
CV_Error(CV_StsParseError, "Empty string cannot be converted to a number"); _Tp analizeValue(const std::string& str);
const char* c_str=str.c_str(); template<typename _Tp>
if((!isdigit(c_str[0])) static _Tp getData(const std::string& str)
&&
(
(c_str[0]!='-') || (strlen(c_str) <= 1) || ( !isdigit(c_str[1]) )
)
)
{ {
CV_Error(CV_StsParseError, "The string '"+ str +"' cannot be converted to a number"); _Tp res;
std::stringstream s1(str);
s1 >> res;
return res;
} }
return fromStringSimple<_Tp>(str); template<typename _Tp>
} static _Tp fromStringNumber(const std::string& str)//the default conversion function for numbers
{
template<typename _Tp> if (str.empty())
static _Tp fromStringsVec(const std::vector<std::string>& vec_str) CV_Error(CV_StsParseError, "Empty string cannot be converted to a number");
{
if (vec_str.empty())
CV_Error(CV_StsParseError, "Cannot convert from an empty vector");
return fromString<_Tp>(vec_str[0]);
}
};
template<> CV_EXPORTS const char* c_str=str.c_str();
std::vector<std::string> CommandLineParser::getVec<std::string>(const std::string& keys); if((!isdigit(c_str[0]))
&&
(
(c_str[0]!='-') || (strlen(c_str) <= 1) || ( !isdigit(c_str[1]) )
)
)
template<typename _Tp> inline {
std::vector<_Tp> CommandLineParser::getVec(const std::string& keys) CV_Error(CV_StsParseError, "The string '"+ str +"' cannot be converted to a number");
{ }
if (!has(keys))
return std::vector<_Tp>();
std::vector<std::string> v=getVec<std::string>(keys); return getData<_Tp>(str);
}
std::vector<_Tp> res; };
for(size_t i=0; i < v.size(); i++)
{
_Tp val=fromString<_Tp>(v[i]);
res.push_back(val);
}
return res;
}
template<> CV_EXPORTS template<> CV_EXPORTS
std::string CommandLineParser::fromString<std::string>(const std::string& str); std::string CommandLineParser::analizeValue<std::string>(const std::string& str);
template<> CV_EXPORTS template<> CV_EXPORTS
int CommandLineParser::fromString<int>(const std::string& str); int CommandLineParser::analizeValue<int>(const std::string& str);
template<> CV_EXPORTS template<> CV_EXPORTS
unsigned int CommandLineParser::fromString<unsigned int>(const std::string& str); unsigned CommandLineParser::analizeValue<unsigned int>(const std::string& str);
template<> CV_EXPORTS template<> CV_EXPORTS
double CommandLineParser::fromString<double>(const std::string& str); float CommandLineParser::analizeValue<float>(const std::string& str);
template<> CV_EXPORTS template<> CV_EXPORTS
cv::Size CommandLineParser::fromStringsVec<cv::Size>(const std::vector<std::string>& str); double CommandLineParser::analizeValue<double>(const std::string& str);
} }
......
...@@ -32,7 +32,7 @@ void PreprocessArgs(int _argc, const char* _argv[], int& argc, char**& argv) ...@@ -32,7 +32,7 @@ void PreprocessArgs(int _argc, const char* _argv[], int& argc, char**& argv)
find_symbol = buffer_string.find('='); find_symbol = buffer_string.find('=');
if (find_symbol == -1) if (find_symbol == -1)
buffer_vector.push_back(buffer_string); buffer_vector.push_back(buffer_string);
else if (find_symbol == 0 || find_symbol == ((int)buffer_string.length() - 1)) else if (find_symbol == 0 || find_symbol == (buffer_string.length() - 1))
{ {
buffer_string.erase(find_symbol, (find_symbol + 1)); buffer_string.erase(find_symbol, (find_symbol + 1));
if(!buffer_string.empty()) if(!buffer_string.empty())
...@@ -45,6 +45,7 @@ void PreprocessArgs(int _argc, const char* _argv[], int& argc, char**& argv) ...@@ -45,6 +45,7 @@ void PreprocessArgs(int _argc, const char* _argv[], int& argc, char**& argv)
buffer_vector.push_back(buffer_string); buffer_vector.push_back(buffer_string);
buffer2_string.erase(0, find_symbol + 1); buffer2_string.erase(0, find_symbol + 1);
buffer_vector.push_back(buffer2_string); buffer_vector.push_back(buffer2_string);
} }
} }
...@@ -57,78 +58,70 @@ void PreprocessArgs(int _argc, const char* _argv[], int& argc, char**& argv) ...@@ -57,78 +58,70 @@ void PreprocessArgs(int _argc, const char* _argv[], int& argc, char**& argv)
} }
} }
CommandLineParser::CommandLineParser(int _argc, const char* _argv[]) CommandLineParser::CommandLineParser(int _argc, const char* _argv[])
{ {
std::string cur_name; std::string cur_name;
bool was_pushed=false; bool was_pushed=false;
int argc; int argc;
char** argv; char** argv;
PreprocessArgs(_argc, _argv, argc, argv); PreprocessArgs(_argc, _argv, argc, argv);
for(int i=1; i < argc; i++) for(int i=1; i < argc; i++) {
{
if(!argv[i])
break;
if( (argv[i][0]== '-') && (strlen(argv[i]) > 1) &&
((argv[i][1] < '0') || (argv[i][1] > '9')) )
{
if (!cur_name.empty() && !was_pushed)
{
data[cur_name].push_back("");
}
cur_name=argv[i];
while (cur_name.find('-') == 0)
{
cur_name.erase(0,1);
}
was_pushed=false; if(!argv[i])
break;
if (data.find(cur_name) != data.end()) if( (argv[i][0]== '-') && (strlen(argv[i]) > 1)
&&
( (argv[i][1] < '0') || (argv[i][1] > '9')) )
{ {
string str_exception = "dublicating parameters for name='" + cur_name + "'"; if (!cur_name.empty() && !was_pushed) {
CV_Error(CV_StsParseError, str_exception); data[cur_name].push_back("");
}
cur_name=argv[i];
while (cur_name.find('-') == 0)
{
cur_name.erase(0,1);
}
was_pushed=false;
if (data.find(cur_name) != data.end()) {
string str_exception="dublicating parameters for name='" + cur_name + "'";
CV_Error(CV_StsParseError, str_exception);
}
continue;
} }
continue;
}
data[cur_name].push_back(argv[i]); data[cur_name].push_back(argv[i]);
was_pushed=true; was_pushed=true;
} }
if (!cur_name.empty() && !was_pushed) if (!cur_name.empty() && !was_pushed)
data[cur_name].push_back(""); data[cur_name].push_back("");
} }
bool CommandLineParser::has(const std::string& keys) const bool CommandLineParser::has(const std::string& keys) const
{ {
vector<string> names=split_string(keys, " |"); vector<string> names=split_string(keys, " |");
for(size_t j=0; j < names.size(); j++) for(size_t j=0; j < names.size(); j++) {
{
if (data.find(names[j])!=data.end()) if (data.find(names[j])!=data.end())
return true; return true;
} }
return false; return false;
} }
template<> std::string CommandLineParser::getString(const std::string& keys) const
std::vector<std::string> CommandLineParser::getVec<std::string>(const std::string& keys)
{ {
vector<string> names=split_string(keys, " |"); vector<string> names=split_string(keys, " |");
int found_index=-1; int found_index=-1;
for(size_t j=0; j < names.size(); j++) for(size_t j=0; j < names.size(); j++) {
{
const string& cur_name=names[j]; const string& cur_name=names[j];
bool is_cur_found=has(cur_name); bool is_cur_found=has(cur_name);
if (is_cur_found && (found_index >= 0)) if (is_cur_found && (found_index >= 0)) {
{ string str_exception="dublicating parameters for "
string str_exception = "dublicating parameters for " "name='" + names[found_index] + "' and name='"+cur_name+"'";
"name='" + names[found_index] + "' and name='"+cur_name+"'";
CV_Error(CV_StsParseError, str_exception); CV_Error(CV_StsParseError, str_exception);
} }
...@@ -137,45 +130,38 @@ std::vector<std::string> CommandLineParser::getVec<std::string>(const std::strin ...@@ -137,45 +130,38 @@ std::vector<std::string> CommandLineParser::getVec<std::string>(const std::strin
} }
if (found_index<0) if (found_index<0)
return vector<string>(); return string();
return data.find(names[found_index])->second[0];
return data.find(names[found_index])->second;
} }
template<> template<>
std::string CommandLineParser::fromString<std::string>(const std::string& str) std::string CommandLineParser::analizeValue<std::string>(const std::string& str)
{ {
return str; return str;
} }
template<> template<>
int CommandLineParser::fromString<int>(const std::string& str) int CommandLineParser::analizeValue<int>(const std::string& str)
{ {
return fromStringNumber<int>(str); return fromStringNumber<int>(str);
} }
template<> template<>
unsigned int CommandLineParser::fromString<unsigned int>(const std::string& str) unsigned int CommandLineParser::analizeValue<unsigned int>(const std::string& str)
{ {
return fromStringNumber<unsigned int>(str); return fromStringNumber<unsigned int>(str);
} }
template<> template<>
double CommandLineParser::fromString<double>(const std::string& str) float CommandLineParser::analizeValue<float>(const std::string& str)
{ {
return fromStringNumber<double>(str); return fromStringNumber<float>(str);
} }
template<> template<>
cv::Size CommandLineParser::fromStringsVec<cv::Size>(const std::vector<std::string>& vec_str) double CommandLineParser::analizeValue<double>(const std::string& str)
{ {
if (vec_str.size() < 2) return fromStringNumber<double>(str);
CV_Error(CV_StsParseError, "Cannot convert vector of string to cv::Size : less than two strings");
cv::Size res;
res.width=fromString<int>(vec_str[0]);
res.height=fromString<int>(vec_str[1]);
return res;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment