Update CommandLineParser class
This commit is contained in:
parent
4b4053705d
commit
fe279279e6
@ -4171,126 +4171,85 @@ protected:
|
||||
|
||||
The class is used for reading command arguments.
|
||||
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);
|
||||
vector<int> kValues=parser.getVec<int>("--k | -k");
|
||||
double x = parser.get<double>("--x");
|
||||
cv::Size size = parser.get<cv::Size>("--size");
|
||||
string inputFile = parser.get<string>("--inputFile");
|
||||
*/
|
||||
class CV_EXPORTS CommandLineParser
|
||||
{
|
||||
public:
|
||||
//! the default constructor
|
||||
CommandLineParser(int argc, const char* argv[]);
|
||||
public:
|
||||
|
||||
//! allows to check if parameter is given
|
||||
bool has(const std::string& keys) const;
|
||||
//! the default constructor
|
||||
CommandLineParser(int argc, const char* argv[]);
|
||||
|
||||
//! get parameter
|
||||
template<typename _Tp>
|
||||
_Tp get(const std::string& name)
|
||||
{
|
||||
return fromStringsVec<_Tp>(getVec<std::string>(name));
|
||||
}
|
||||
//! allows to check if parameter is given
|
||||
bool has(const std::string& keys) const;
|
||||
|
||||
//! 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
|
||||
template<typename _Tp>
|
||||
std::vector<_Tp> getVec(const std::string& keys);
|
||||
|
||||
protected:
|
||||
std::map<std::string, std::vector<std::string> > data;
|
||||
|
||||
template<typename _Tp>
|
||||
static _Tp fromStringSimple(const std::string& str)//the default conversion function
|
||||
{
|
||||
_Tp res;
|
||||
std::stringstream s1(str);
|
||||
s1 >> res;
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename _Tp>
|
||||
static _Tp fromString(const std::string& str)
|
||||
{
|
||||
return fromStringSimple<_Tp>(str);
|
||||
}
|
||||
|
||||
template<typename _Tp>
|
||||
static _Tp fromStringNumber(const std::string& str)//the default conversion function for numbers
|
||||
{
|
||||
_Tp dummy_val=0; dummy_val+=1;
|
||||
|
||||
if (str.empty())
|
||||
CV_Error(CV_StsParseError, "Empty string cannot be converted to a number");
|
||||
|
||||
const char* c_str=str.c_str();
|
||||
if((!isdigit(c_str[0]))
|
||||
&&
|
||||
(
|
||||
(c_str[0]!='-') || (strlen(c_str) <= 1) || ( !isdigit(c_str[1]) )
|
||||
)
|
||||
)
|
||||
//! get parameter, if parameter is not given get default parameter
|
||||
template<typename _Tp>
|
||||
_Tp get(const std::string& name, const _Tp& default_value = _Tp())
|
||||
{
|
||||
CV_Error(CV_StsParseError, "The string '"+ str +"' cannot be converted to a number");
|
||||
std::string str = getString(name);
|
||||
if (!has(name))
|
||||
return default_value;
|
||||
return analizeValue<_Tp>(str);
|
||||
}
|
||||
|
||||
return fromStringSimple<_Tp>(str);
|
||||
}
|
||||
protected:
|
||||
std::map<std::string, std::vector<std::string> > data;
|
||||
std::string getString(const std::string& name) const;
|
||||
|
||||
template<typename _Tp>
|
||||
static _Tp fromStringsVec(const std::vector<std::string>& vec_str)
|
||||
{
|
||||
if (vec_str.empty())
|
||||
CV_Error(CV_StsParseError, "Cannot convert from an empty vector");
|
||||
return fromString<_Tp>(vec_str[0]);
|
||||
}
|
||||
};
|
||||
template<typename _Tp>
|
||||
_Tp analizeValue(const std::string& str);
|
||||
|
||||
template<> CV_EXPORTS
|
||||
std::vector<std::string> CommandLineParser::getVec<std::string>(const std::string& keys);
|
||||
template<typename _Tp>
|
||||
static _Tp getData(const std::string& str)
|
||||
{
|
||||
_Tp res;
|
||||
std::stringstream s1(str);
|
||||
s1 >> res;
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
std::vector<_Tp> CommandLineParser::getVec(const std::string& keys)
|
||||
{
|
||||
if (!has(keys))
|
||||
return std::vector<_Tp>();
|
||||
template<typename _Tp>
|
||||
static _Tp fromStringNumber(const std::string& str)//the default conversion function for numbers
|
||||
{
|
||||
|
||||
std::vector<std::string> v=getVec<std::string>(keys);
|
||||
if (str.empty())
|
||||
CV_Error(CV_StsParseError, "Empty string cannot be converted to a number");
|
||||
|
||||
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;
|
||||
}
|
||||
const char* c_str=str.c_str();
|
||||
if((!isdigit(c_str[0]))
|
||||
&&
|
||||
(
|
||||
(c_str[0]!='-') || (strlen(c_str) <= 1) || ( !isdigit(c_str[1]) )
|
||||
)
|
||||
)
|
||||
|
||||
template<> CV_EXPORTS
|
||||
std::string CommandLineParser::fromString<std::string>(const std::string& str);
|
||||
{
|
||||
CV_Error(CV_StsParseError, "The string '"+ str +"' cannot be converted to a number");
|
||||
}
|
||||
|
||||
template<> CV_EXPORTS
|
||||
int CommandLineParser::fromString<int>(const std::string& str);
|
||||
return getData<_Tp>(str);
|
||||
}
|
||||
|
||||
template<> CV_EXPORTS
|
||||
unsigned int CommandLineParser::fromString<unsigned int>(const std::string& str);
|
||||
};
|
||||
|
||||
template<> CV_EXPORTS
|
||||
double CommandLineParser::fromString<double>(const std::string& str);
|
||||
template<> CV_EXPORTS
|
||||
std::string CommandLineParser::analizeValue<std::string>(const std::string& str);
|
||||
|
||||
template<> CV_EXPORTS
|
||||
cv::Size CommandLineParser::fromStringsVec<cv::Size>(const std::vector<std::string>& str);
|
||||
template<> CV_EXPORTS
|
||||
int CommandLineParser::analizeValue<int>(const std::string& str);
|
||||
|
||||
template<> CV_EXPORTS
|
||||
unsigned CommandLineParser::analizeValue<unsigned int>(const std::string& str);
|
||||
|
||||
template<> CV_EXPORTS
|
||||
float CommandLineParser::analizeValue<float>(const std::string& str);
|
||||
|
||||
template<> CV_EXPORTS
|
||||
double CommandLineParser::analizeValue<double>(const std::string& str);
|
||||
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ void PreprocessArgs(int _argc, const char* _argv[], int& argc, char**& argv)
|
||||
find_symbol = buffer_string.find('=');
|
||||
if (find_symbol == -1)
|
||||
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));
|
||||
if(!buffer_string.empty())
|
||||
@ -45,6 +45,7 @@ void PreprocessArgs(int _argc, const char* _argv[], int& argc, char**& argv)
|
||||
buffer_vector.push_back(buffer_string);
|
||||
buffer2_string.erase(0, find_symbol + 1);
|
||||
buffer_vector.push_back(buffer2_string);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,78 +58,70 @@ void PreprocessArgs(int _argc, const char* _argv[], int& argc, char**& argv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CommandLineParser::CommandLineParser(int _argc, const char* _argv[])
|
||||
{
|
||||
std::string cur_name;
|
||||
bool was_pushed=false;
|
||||
int argc;
|
||||
char** argv;
|
||||
|
||||
PreprocessArgs(_argc, _argv, argc, argv);
|
||||
|
||||
for(int i=1; i < argc; i++)
|
||||
{
|
||||
if(!argv[i])
|
||||
break;
|
||||
for(int i=1; i < argc; i++) {
|
||||
|
||||
if( (argv[i][0]== '-') && (strlen(argv[i]) > 1) &&
|
||||
((argv[i][1] < '0') || (argv[i][1] > '9')) )
|
||||
{
|
||||
if (!cur_name.empty() && !was_pushed)
|
||||
if(!argv[i])
|
||||
break;
|
||||
|
||||
if( (argv[i][0]== '-') && (strlen(argv[i]) > 1)
|
||||
&&
|
||||
( (argv[i][1] < '0') || (argv[i][1] > '9')) )
|
||||
{
|
||||
data[cur_name].push_back("");
|
||||
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 (data.find(cur_name) != data.end()) {
|
||||
string str_exception="dublicating parameters for name='" + cur_name + "'";
|
||||
CV_Error(CV_StsParseError, str_exception);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
data[cur_name].push_back(argv[i]);
|
||||
was_pushed=true;
|
||||
data[cur_name].push_back(argv[i]);
|
||||
was_pushed=true;
|
||||
}
|
||||
if (!cur_name.empty() && !was_pushed)
|
||||
data[cur_name].push_back("");
|
||||
data[cur_name].push_back("");
|
||||
}
|
||||
|
||||
bool CommandLineParser::has(const std::string& keys) const
|
||||
{
|
||||
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())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::vector<std::string> CommandLineParser::getVec<std::string>(const std::string& keys)
|
||||
std::string CommandLineParser::getString(const std::string& keys) const
|
||||
{
|
||||
vector<string> names=split_string(keys, " |");
|
||||
|
||||
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];
|
||||
bool is_cur_found=has(cur_name);
|
||||
|
||||
if (is_cur_found && (found_index >= 0))
|
||||
{
|
||||
string str_exception = "dublicating parameters for "
|
||||
"name='" + names[found_index] + "' and name='"+cur_name+"'";
|
||||
if (is_cur_found && (found_index >= 0)) {
|
||||
string str_exception="dublicating parameters for "
|
||||
"name='" + names[found_index] + "' and name='"+cur_name+"'";
|
||||
CV_Error(CV_StsParseError, str_exception);
|
||||
}
|
||||
|
||||
@ -137,45 +130,38 @@ std::vector<std::string> CommandLineParser::getVec<std::string>(const std::strin
|
||||
}
|
||||
|
||||
if (found_index<0)
|
||||
return vector<string>();
|
||||
|
||||
return data.find(names[found_index])->second;
|
||||
return string();
|
||||
return data.find(names[found_index])->second[0];
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
std::string CommandLineParser::fromString<std::string>(const std::string& str)
|
||||
std::string CommandLineParser::analizeValue<std::string>(const std::string& str)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
template<>
|
||||
int CommandLineParser::fromString<int>(const std::string& str)
|
||||
int CommandLineParser::analizeValue<int>(const std::string& str)
|
||||
{
|
||||
return fromStringNumber<int>(str);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template<>
|
||||
double CommandLineParser::fromString<double>(const std::string& str)
|
||||
float CommandLineParser::analizeValue<float>(const std::string& str)
|
||||
{
|
||||
return fromStringNumber<float>(str);
|
||||
}
|
||||
|
||||
template<>
|
||||
double CommandLineParser::analizeValue<double>(const std::string& str)
|
||||
{
|
||||
return fromStringNumber<double>(str);
|
||||
}
|
||||
|
||||
template<>
|
||||
cv::Size CommandLineParser::fromStringsVec<cv::Size>(const std::vector<std::string>& vec_str)
|
||||
{
|
||||
if (vec_str.size() < 2)
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user