ENH: Add support for multi-arguments: -f arg1 arg2 arg3 ... and support for lists: -f arg1 -f arg2 -f arg3 ... and for boolean to be stored as strings and doubles
This commit is contained in:
parent
fc49142fc6
commit
d2a3ccd505
|
@ -819,6 +819,24 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
|
|||
ENDIF(NOT CYGWIN)
|
||||
ADD_TEST(kwsys.testHashSTL ${EXEC_DIR}/testHashSTL)
|
||||
ADD_TEST(kwsys.testRegistry ${EXEC_DIR}/testRegistry)
|
||||
ADD_TEST(kwsys.testCommandLineArguments ${EXEC_DIR}/testCommandLineArguments
|
||||
--another-bool-variable
|
||||
--long3=opt
|
||||
--set-bool-arg1
|
||||
-SSS ken brad bill andy
|
||||
--some-bool-variable=true
|
||||
--some-double-variable12.5
|
||||
--some-int-variable 14
|
||||
"--some-string-variable=test string with space"
|
||||
--some-multi-argument 5 1 8 3 7 1 3 9 7 1
|
||||
-N 12.5 -SS=andy -N 1.31 -N 22
|
||||
-SS=bill -BBtrue -SS=brad
|
||||
-BBtrue
|
||||
-BBfalse
|
||||
-SS=ken
|
||||
-A
|
||||
-C=test
|
||||
--long2 hello)
|
||||
IF(COMMAND SET_TESTS_PROPERTIES AND COMMAND GET_TEST_PROPERTY AND KWSYS_STANDALONE)
|
||||
ADD_TEST(kwsys.testFail ${EXEC_DIR}/testFail)
|
||||
# We expect test to fail
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include KWSYS_HEADER(CommandLineArguments.hxx)
|
||||
|
||||
#include KWSYS_HEADER(Configure.hxx)
|
||||
#include KWSYS_HEADER(String.hxx)
|
||||
|
||||
#include KWSYS_HEADER(stl/vector)
|
||||
#include KWSYS_HEADER(stl/map)
|
||||
|
@ -44,22 +45,18 @@
|
|||
# pragma set woff 1375 /* base class destructor not virtual */
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
# define CommandLineArguments_DEBUG(x) \
|
||||
kwsys_ios::cout << __LINE__ << " CLA: " << x << kwsys_ios::endl
|
||||
#else
|
||||
# define CommandLineArguments_DEBUG(x)
|
||||
#endif
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//============================================================================
|
||||
class CommandLineArgumentsString : public kwsys_stl::string
|
||||
{
|
||||
public:
|
||||
typedef kwsys_stl::string StdString;
|
||||
CommandLineArgumentsString(): StdString() {}
|
||||
CommandLineArgumentsString(const value_type* s): StdString(s) {}
|
||||
CommandLineArgumentsString(const value_type* s, size_type n): StdString(s, n) {}
|
||||
CommandLineArgumentsString(const StdString& s, size_type pos=0, size_type n=npos):
|
||||
StdString(s, pos, n) {}
|
||||
};
|
||||
|
||||
struct CommandLineArgumentsCallbackStructure
|
||||
{
|
||||
const char* Argument;
|
||||
|
@ -72,11 +69,11 @@ struct CommandLineArgumentsCallbackStructure
|
|||
};
|
||||
|
||||
class CommandLineArgumentsVectorOfStrings :
|
||||
public kwsys_stl::vector<CommandLineArgumentsString> {};
|
||||
public kwsys_stl::vector<kwsys::String> {};
|
||||
class CommandLineArgumentsSetOfStrings :
|
||||
public kwsys_stl::set<CommandLineArgumentsString> {};
|
||||
public kwsys_stl::set<kwsys::String> {};
|
||||
class CommandLineArgumentsMapOfStrucs :
|
||||
public kwsys_stl::map<CommandLineArgumentsString,
|
||||
public kwsys_stl::map<kwsys::String,
|
||||
CommandLineArgumentsCallbackStructure> {};
|
||||
|
||||
class CommandLineArgumentsInternal
|
||||
|
@ -91,7 +88,7 @@ public:
|
|||
|
||||
typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
|
||||
typedef CommandLineArgumentsMapOfStrucs CallbacksMap;
|
||||
typedef CommandLineArgumentsString String;
|
||||
typedef kwsys::String String;
|
||||
typedef CommandLineArgumentsSetOfStrings SetOfStrings;
|
||||
|
||||
VectorOfStrings Argv;
|
||||
|
@ -153,38 +150,47 @@ void CommandLineArguments::ProcessArgument(const char* arg)
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int CommandLineArguments::Parse()
|
||||
bool CommandLineArguments::GetMatchedArguments(
|
||||
kwsys_stl::vector<kwsys_stl::string>* matches,
|
||||
const kwsys_stl::string& arg)
|
||||
{
|
||||
CommandLineArguments::Internal::VectorOfStrings::size_type cc;
|
||||
CommandLineArguments::Internal::VectorOfStrings matches;
|
||||
for ( cc = 0; cc < this->Internals->Argv.size(); cc ++ )
|
||||
{
|
||||
this->Internals->LastArgument = cc;
|
||||
matches.clear();
|
||||
CommandLineArguments::Internal::String& arg = this->Internals->Argv[cc];
|
||||
CommandLineArguments::Internal::CallbacksMap::iterator it;
|
||||
matches->clear();
|
||||
CommandLineArguments::Internal::CallbacksMap::iterator it;
|
||||
|
||||
// Does the argument match to any we know about?
|
||||
for ( it = this->Internals->Callbacks.begin();
|
||||
it != this->Internals->Callbacks.end();
|
||||
it ++ )
|
||||
// Does the argument match to any we know about?
|
||||
for ( it = this->Internals->Callbacks.begin();
|
||||
it != this->Internals->Callbacks.end();
|
||||
it ++ )
|
||||
{
|
||||
const CommandLineArguments::Internal::String& parg = it->first;
|
||||
CommandLineArgumentsCallbackStructure *cs = &it->second;
|
||||
if (cs->ArgumentType == CommandLineArguments::NO_ARGUMENT ||
|
||||
cs->ArgumentType == CommandLineArguments::SPACE_ARGUMENT)
|
||||
{
|
||||
const CommandLineArguments::Internal::String& parg = it->first;
|
||||
CommandLineArgumentsCallbackStructure *cs = &it->second;
|
||||
if (cs->ArgumentType == CommandLineArguments::NO_ARGUMENT ||
|
||||
cs->ArgumentType == CommandLineArguments::SPACE_ARGUMENT)
|
||||
if ( arg == parg )
|
||||
{
|
||||
if ( arg == parg )
|
||||
{
|
||||
matches.push_back(parg);
|
||||
}
|
||||
}
|
||||
else if ( arg.find( parg ) == 0 )
|
||||
{
|
||||
matches.push_back(parg);
|
||||
matches->push_back(parg);
|
||||
}
|
||||
}
|
||||
if ( matches.size() > 0 )
|
||||
else if ( arg.find( parg ) == 0 )
|
||||
{
|
||||
matches->push_back(parg);
|
||||
}
|
||||
}
|
||||
return matches->size() > 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int CommandLineArguments::Parse()
|
||||
{
|
||||
kwsys_stl::vector<kwsys_stl::string>::size_type cc;
|
||||
kwsys_stl::vector<kwsys_stl::string> matches;
|
||||
for ( cc = 0; cc < this->Internals->Argv.size(); cc ++ )
|
||||
{
|
||||
const kwsys_stl::string& arg = this->Internals->Argv[cc];
|
||||
CommandLineArguments_DEBUG("Process argument: " << arg);
|
||||
this->Internals->LastArgument = cc;
|
||||
if ( this->GetMatchedArguments(&matches, arg) )
|
||||
{
|
||||
// Ok, we found one or more arguments that match what user specified.
|
||||
// Let's find the longest one.
|
||||
|
@ -201,112 +207,84 @@ int CommandLineArguments::Parse()
|
|||
}
|
||||
// So, the longest one is probably the right one. Now see if it has any
|
||||
// additional value
|
||||
const char* value = 0;
|
||||
CommandLineArgumentsCallbackStructure *cs
|
||||
= &this->Internals->Callbacks[matches[maxidx]];
|
||||
const CommandLineArguments::Internal::String& sarg = matches[maxidx];
|
||||
if ( cs->ArgumentType == NO_ARGUMENT )
|
||||
if ( cs->Argument != sarg )
|
||||
{
|
||||
// No value
|
||||
abort();
|
||||
}
|
||||
else if ( cs->ArgumentType == SPACE_ARGUMENT )
|
||||
switch ( cs->ArgumentType )
|
||||
{
|
||||
case NO_ARGUMENT:
|
||||
// No value
|
||||
if ( !this->PopulateVariable(cs, 0) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case SPACE_ARGUMENT:
|
||||
if ( cc == this->Internals->Argv.size()-1 )
|
||||
{
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
}
|
||||
CommandLineArguments_DEBUG("This is a space argument: " << arg
|
||||
<< " value: " << this->Internals->Argv[cc+1].c_str());
|
||||
// Value is the next argument
|
||||
value = this->Internals->Argv[cc+1].c_str();
|
||||
if ( !this->PopulateVariable(cs, this->Internals->Argv[cc+1].c_str()) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cc ++;
|
||||
}
|
||||
else if ( cs->ArgumentType == EQUAL_ARGUMENT )
|
||||
{
|
||||
break;
|
||||
case EQUAL_ARGUMENT:
|
||||
if ( arg.size() == sarg.size() || *(arg.c_str() + sarg.size()) != '=' )
|
||||
{
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
}
|
||||
// Value is everythng followed the '=' sign
|
||||
value = arg.c_str() + sarg.size()+1;
|
||||
}
|
||||
else if ( cs->ArgumentType == CONCAT_ARGUMENT )
|
||||
{
|
||||
if ( !this->PopulateVariable(cs, arg.c_str() + sarg.size() + 1) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case CONCAT_ARGUMENT:
|
||||
// Value is whatever follows the argument
|
||||
value = arg.c_str() + sarg.size();
|
||||
}
|
||||
|
||||
// Call the callback
|
||||
if ( cs->Callback )
|
||||
{
|
||||
if ( !cs->Callback(sarg.c_str(), value, cs->CallData) )
|
||||
if ( !this->PopulateVariable(cs, arg.c_str() + sarg.size()) )
|
||||
{
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ( cs->Variable )
|
||||
{
|
||||
kwsys_stl::string var = "1";
|
||||
if ( value )
|
||||
break;
|
||||
case MULTI_ARGUMENT:
|
||||
// Suck in all the rest of the arguments
|
||||
CommandLineArguments_DEBUG("This is a multi argument: " << arg);
|
||||
for (cc++; cc < this->Internals->Argv.size(); ++ cc )
|
||||
{
|
||||
var = value;
|
||||
}
|
||||
if ( cs->VariableType == CommandLineArguments::INT_TYPE )
|
||||
{
|
||||
int* variable = static_cast<int*>(cs->Variable);
|
||||
char* res = 0;
|
||||
*variable = strtol(var.c_str(), &res, 10);
|
||||
//if ( res && *res )
|
||||
// {
|
||||
// Can handle non-int
|
||||
// }
|
||||
}
|
||||
else if ( cs->VariableType == CommandLineArguments::DOUBLE_TYPE )
|
||||
{
|
||||
double* variable = static_cast<double*>(cs->Variable);
|
||||
char* res = 0;
|
||||
*variable = strtod(var.c_str(), &res);
|
||||
//if ( res && *res )
|
||||
// {
|
||||
// Can handle non-int
|
||||
// }
|
||||
}
|
||||
else if ( cs->VariableType == CommandLineArguments::STRING_TYPE )
|
||||
{
|
||||
char** variable = static_cast<char**>(cs->Variable);
|
||||
if ( *variable )
|
||||
const kwsys_stl::string& marg = this->Internals->Argv[cc];
|
||||
CommandLineArguments_DEBUG(" check multi argument value: " << marg);
|
||||
if ( this->GetMatchedArguments(&matches, marg) )
|
||||
{
|
||||
delete [] *variable;
|
||||
*variable = 0;
|
||||
CommandLineArguments_DEBUG("End of multi argument " << arg << " with value: " << marg);
|
||||
break;
|
||||
}
|
||||
*variable = new char[ strlen(var.c_str()) + 1 ];
|
||||
strcpy(*variable, var.c_str());
|
||||
}
|
||||
else if ( cs->VariableType == CommandLineArguments::STL_STRING_TYPE )
|
||||
{
|
||||
kwsys_stl::string* variable = static_cast<kwsys_stl::string*>(cs->Variable);
|
||||
*variable = var;
|
||||
}
|
||||
else if ( cs->VariableType == CommandLineArguments::BOOL_TYPE )
|
||||
{
|
||||
bool* variable = static_cast<bool*>(cs->Variable);
|
||||
if ( var == "1" || var == "ON" || var == "TRUE" || var == "true" || var == "on" ||
|
||||
var == "True" || var == "yes" || var == "Yes" || var == "YES" )
|
||||
CommandLineArguments_DEBUG(" populate multi argument value: " << marg);
|
||||
if ( !this->PopulateVariable(cs, marg.c_str()) )
|
||||
{
|
||||
*variable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*variable = false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
if ( cc != this->Internals->Argv.size() )
|
||||
{
|
||||
kwsys_ios::cerr << "Got unknown argument type: \"" << cs->VariableType << "\"" << kwsys_ios::endl;
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
CommandLineArguments_DEBUG("Again End of multi argument " << arg);
|
||||
cc--;
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
kwsys_ios::cerr << "Got unknown argument type: \"" << cs->ArgumentType << "\"" << kwsys_ios::endl;
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -404,55 +382,45 @@ void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum ty
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
int* variable, const char* help)
|
||||
{
|
||||
this->AddArgument(argument, type, CommandLineArguments::INT_TYPE, variable, help);
|
||||
}
|
||||
#define CommandLineArgumentsAddArgumentMacro(type, ctype) \
|
||||
void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, \
|
||||
ctype* variable, const char* help) \
|
||||
{ \
|
||||
this->AddArgument(argument, type, CommandLineArguments::type##_TYPE, variable, help); \
|
||||
}
|
||||
|
||||
CommandLineArgumentsAddArgumentMacro(BOOL, bool);
|
||||
CommandLineArgumentsAddArgumentMacro(INT, int);
|
||||
CommandLineArgumentsAddArgumentMacro(DOUBLE, double);
|
||||
CommandLineArgumentsAddArgumentMacro(STRING, char*);
|
||||
CommandLineArgumentsAddArgumentMacro(STL_STRING, kwsys_stl::string);
|
||||
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, kwsys_stl::vector<bool>);
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_INT, kwsys_stl::vector<int>);
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE, kwsys_stl::vector<double>);
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_STRING, kwsys_stl::vector<char*>);
|
||||
CommandLineArgumentsAddArgumentMacro(VECTOR_STL_STRING, kwsys_stl::vector<kwsys_stl::string>);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
double* variable, const char* help)
|
||||
{
|
||||
this->AddArgument(argument, type, CommandLineArguments::DOUBLE_TYPE, variable, help);
|
||||
}
|
||||
#define CommandLineArgumentsAddBooleanArgumentMacro(type, ctype) \
|
||||
void CommandLineArguments::AddBooleanArgument(const char* argument, \
|
||||
ctype* variable, const char* help) \
|
||||
{ \
|
||||
this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT, \
|
||||
CommandLineArguments::type##_TYPE, variable, help); \
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
char** variable, const char* help)
|
||||
{
|
||||
this->AddArgument(argument, type, CommandLineArguments::STRING_TYPE, variable, help);
|
||||
}
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool);
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(INT, int);
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE, double);
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(STRING, char*);
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, kwsys_stl::string);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
kwsys_stl::string* variable, const char* help)
|
||||
{
|
||||
this->AddArgument(argument, type, CommandLineArguments::STL_STRING_TYPE, variable, help);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
bool* variable, const char* help)
|
||||
{
|
||||
this->AddArgument(argument, type, CommandLineArguments::BOOL_TYPE, variable, help);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::AddBooleanArgument(const char* argument, bool*
|
||||
variable, const char* help)
|
||||
{
|
||||
this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT,
|
||||
CommandLineArguments::BOOL_TYPE, variable, help);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::AddBooleanArgument(const char* argument, int*
|
||||
variable, const char* help)
|
||||
{
|
||||
this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT,
|
||||
CommandLineArguments::INT_TYPE, variable, help);
|
||||
}
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(VECTOR_BOOL, kwsys_stl::vector<bool>);
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(VECTOR_INT, kwsys_stl::vector<int>);
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(VECTOR_DOUBLE, kwsys_stl::vector<double>);
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(VECTOR_STRING, kwsys_stl::vector<char*>);
|
||||
CommandLineArgumentsAddBooleanArgumentMacro(VECTOR_STL_STRING, kwsys_stl::vector<kwsys_stl::string>);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::SetClientData(void* client_data)
|
||||
|
@ -614,6 +582,7 @@ void CommandLineArguments::GenerateHelp()
|
|||
case CommandLineArguments::CONCAT_ARGUMENT: strcat(argument, "opt"); break;
|
||||
case CommandLineArguments::SPACE_ARGUMENT: strcat(argument, " opt"); break;
|
||||
case CommandLineArguments::EQUAL_ARGUMENT: strcat(argument, "=opt"); break;
|
||||
case CommandLineArguments::MULTI_ARGUMENT: strcat(argument, " opt opt ..."); break;
|
||||
}
|
||||
char buffer[80];
|
||||
sprintf(buffer, format, argument);
|
||||
|
@ -678,4 +647,181 @@ void CommandLineArguments::GenerateHelp()
|
|||
this->Help = str.str();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
bool* variable, const kwsys_stl::string& value)
|
||||
{
|
||||
if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
|
||||
value == "TRUE" || value == "true" || value == "True" ||
|
||||
value == "yes" || value == "Yes" || value == "YES" )
|
||||
{
|
||||
*variable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*variable = false;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
int* variable, const kwsys_stl::string& value)
|
||||
{
|
||||
char* res = 0;
|
||||
*variable = strtol(value.c_str(), &res, 10);
|
||||
//if ( res && *res )
|
||||
// {
|
||||
// Can handle non-int
|
||||
// }
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
double* variable, const kwsys_stl::string& value)
|
||||
{
|
||||
char* res = 0;
|
||||
*variable = strtod(value.c_str(), &res);
|
||||
//if ( res && *res )
|
||||
// {
|
||||
// Can handle non-double
|
||||
// }
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
char** variable, const kwsys_stl::string& value)
|
||||
{
|
||||
if ( *variable )
|
||||
{
|
||||
delete [] *variable;
|
||||
*variable = 0;
|
||||
}
|
||||
*variable = new char[ value.size() + 1 ];
|
||||
strcpy(*variable, value.c_str());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
kwsys_stl::string* variable, const kwsys_stl::string& value)
|
||||
{
|
||||
*variable = value;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
kwsys_stl::vector<bool>* variable, const kwsys_stl::string& value)
|
||||
{
|
||||
bool val = false;
|
||||
if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
|
||||
value == "TRUE" || value == "true" || value == "True" ||
|
||||
value == "yes" || value == "Yes" || value == "YES" )
|
||||
{
|
||||
val = true;
|
||||
}
|
||||
variable->push_back(val);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
kwsys_stl::vector<int>* variable, const kwsys_stl::string& value)
|
||||
{
|
||||
char* res = 0;
|
||||
variable->push_back(strtol(value.c_str(), &res, 10));
|
||||
//if ( res && *res )
|
||||
// {
|
||||
// Can handle non-int
|
||||
// }
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
kwsys_stl::vector<double>* variable, const kwsys_stl::string& value)
|
||||
{
|
||||
char* res = 0;
|
||||
variable->push_back(strtod(value.c_str(), &res));
|
||||
//if ( res && *res )
|
||||
// {
|
||||
// Can handle non-int
|
||||
// }
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
kwsys_stl::vector<char*>* variable, const kwsys_stl::string& value)
|
||||
{
|
||||
char* var = new char[ value.size() + 1 ];
|
||||
strcpy(var, value.c_str());
|
||||
variable->push_back(var);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void CommandLineArguments::PopulateVariable(
|
||||
kwsys_stl::vector<kwsys_stl::string>* variable,
|
||||
const kwsys_stl::string& value)
|
||||
{
|
||||
variable->push_back(value);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool CommandLineArguments::PopulateVariable(CommandLineArgumentsCallbackStructure* cs,
|
||||
const char* value)
|
||||
{
|
||||
// Call the callback
|
||||
if ( cs->Callback )
|
||||
{
|
||||
if ( !cs->Callback(cs->Argument, value, cs->CallData) )
|
||||
{
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ( cs->Variable )
|
||||
{
|
||||
kwsys_stl::string var = "1";
|
||||
if ( value )
|
||||
{
|
||||
var = value;
|
||||
}
|
||||
switch ( cs->VariableType )
|
||||
{
|
||||
case CommandLineArguments::INT_TYPE:
|
||||
this->PopulateVariable(static_cast<int*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::DOUBLE_TYPE:
|
||||
this->PopulateVariable(static_cast<double*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::STRING_TYPE:
|
||||
this->PopulateVariable(static_cast<char**>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::STL_STRING_TYPE:
|
||||
this->PopulateVariable(static_cast<kwsys_stl::string*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::BOOL_TYPE:
|
||||
this->PopulateVariable(static_cast<bool*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_BOOL_TYPE:
|
||||
this->PopulateVariable(static_cast<kwsys_stl::vector<bool>*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_INT_TYPE:
|
||||
this->PopulateVariable(static_cast<kwsys_stl::vector<int>*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_DOUBLE_TYPE:
|
||||
this->PopulateVariable(static_cast<kwsys_stl::vector<double>*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_STRING_TYPE:
|
||||
this->PopulateVariable(static_cast<kwsys_stl::vector<char*>*>(cs->Variable), var);
|
||||
break;
|
||||
case CommandLineArguments::VECTOR_STL_STRING_TYPE:
|
||||
this->PopulateVariable(static_cast<kwsys_stl::vector<kwsys_stl::string>*>(cs->Variable), var);
|
||||
break;
|
||||
default:
|
||||
kwsys_ios::cerr << "Got unknown variable type: \"" << cs->VariableType << "\"" << kwsys_ios::endl;
|
||||
this->Internals->LastArgument --;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
} // namespace KWSYS_NAMESPACE
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <@KWSYS_NAMESPACE@/Configure.hxx>
|
||||
|
||||
#include <@KWSYS_NAMESPACE@/stl/string>
|
||||
#include <@KWSYS_NAMESPACE@/stl/vector>
|
||||
|
||||
/* Define this macro temporarily to keep the code readable. */
|
||||
#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
|
||||
|
@ -28,6 +29,7 @@ namespace @KWSYS_NAMESPACE@
|
|||
{
|
||||
|
||||
class CommandLineArgumentsInternal;
|
||||
class CommandLineArgumentsCallbackStructure;
|
||||
|
||||
/** \class CommandLineArguments
|
||||
* \brief Command line arguments processing code.
|
||||
|
@ -53,6 +55,7 @@ class CommandLineArgumentsInternal;
|
|||
* CONCAT_ARGUMENT - The argument takes value after no space : --Aval
|
||||
* SPACE_ARGUMENT - The argument takes value after space : --A val
|
||||
* EQUAL_ARGUMENT - The argument takes value after equal : --A=val
|
||||
* MULTI_ARGUMENT - The argument takes values after space : --A val1 val2 val3 ...
|
||||
*
|
||||
* Example use:
|
||||
*
|
||||
|
@ -82,7 +85,8 @@ public:
|
|||
NO_ARGUMENT,
|
||||
CONCAT_ARGUMENT,
|
||||
SPACE_ARGUMENT,
|
||||
EQUAL_ARGUMENT
|
||||
EQUAL_ARGUMENT,
|
||||
MULTI_ARGUMENT
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -95,7 +99,13 @@ public:
|
|||
BOOL_TYPE, // The vairable is boolean (bool)
|
||||
DOUBLE_TYPE, // The variable is float (double)
|
||||
STRING_TYPE, // The variable is string (char*)
|
||||
STL_STRING_TYPE // The variable is string (char*)
|
||||
STL_STRING_TYPE, // The variable is string (char*)
|
||||
VECTOR_INT_TYPE, // The variable is integer (int)
|
||||
VECTOR_BOOL_TYPE, // The vairable is boolean (bool)
|
||||
VECTOR_DOUBLE_TYPE, // The variable is float (double)
|
||||
VECTOR_STRING_TYPE, // The variable is string (char*)
|
||||
VECTOR_STL_STRING_TYPE, // The variable is string (char*)
|
||||
LAST_VARIABLE_TYPE
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -138,10 +148,10 @@ public:
|
|||
* specified value. If the argument is specified, the option is casted to the
|
||||
* apropriate type.
|
||||
*/
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type, bool* variable,
|
||||
const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type, int* variable,
|
||||
const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
bool* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
int* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
double* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
|
@ -149,15 +159,53 @@ public:
|
|||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
kwsys_stl::string* variable, const char* help);
|
||||
|
||||
/**
|
||||
* Add handler for argument which is going to set the variable to the
|
||||
* specified value. If the argument is specified, the option is casted to the
|
||||
* apropriate type. This will handle the multi argument values.
|
||||
*/
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
kwsys_stl::vector<bool>* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
kwsys_stl::vector<int>* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
kwsys_stl::vector<double>* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
kwsys_stl::vector<char*>* variable, const char* help);
|
||||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
kwsys_stl::vector<kwsys_stl::string>* variable, const char* help);
|
||||
|
||||
/**
|
||||
* Add handler for boolean argument. The argument does not take any option
|
||||
* and if it is specified, the value of the variable is true/1, otherwise it
|
||||
* is false/0.
|
||||
*/
|
||||
void AddBooleanArgument(const char* argument, bool* variable, const char*
|
||||
help);
|
||||
void AddBooleanArgument(const char* argument, int* variable, const char*
|
||||
help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
bool* variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
int* variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
double* variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
char** variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
kwsys_stl::string* variable, const char* help);
|
||||
|
||||
/**
|
||||
* Add handler for boolean argument. The argument does not take any option
|
||||
* and if it is specified, the value of the variable is true/1, otherwise it
|
||||
* is false/0. This will handle the multi argument values.
|
||||
*/
|
||||
void AddBooleanArgument(const char* argument,
|
||||
kwsys_stl::vector<bool>* variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
kwsys_stl::vector<int>* variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
kwsys_stl::vector<double>* variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
kwsys_stl::vector<char*>* variable, const char* help);
|
||||
void AddBooleanArgument(const char* argument,
|
||||
kwsys_stl::vector<kwsys_stl::string>* variable, const char* help);
|
||||
|
||||
/**
|
||||
* Set the callbacks for error handling.
|
||||
|
@ -205,6 +253,25 @@ protected:
|
|||
void AddArgument(const char* argument, ArgumentTypeEnum type,
|
||||
VariableTypeEnum vtype, void* variable, const char* help);
|
||||
|
||||
bool GetMatchedArguments(kwsys_stl::vector<kwsys_stl::string>* matches,
|
||||
const kwsys_stl::string& arg);
|
||||
|
||||
//! Populate individual variables
|
||||
bool PopulateVariable(CommandLineArgumentsCallbackStructure* cs,
|
||||
const char* value);
|
||||
|
||||
//! Populate individual variables of type ...
|
||||
void PopulateVariable(bool* variable, const kwsys_stl::string& value);
|
||||
void PopulateVariable(int* variable, const kwsys_stl::string& value);
|
||||
void PopulateVariable(double* variable, const kwsys_stl::string& value);
|
||||
void PopulateVariable(char** variable, const kwsys_stl::string& value);
|
||||
void PopulateVariable(kwsys_stl::string* variable, const kwsys_stl::string& value);
|
||||
void PopulateVariable(kwsys_stl::vector<bool>* variable, const kwsys_stl::string& value);
|
||||
void PopulateVariable(kwsys_stl::vector<int>* variable, const kwsys_stl::string& value);
|
||||
void PopulateVariable(kwsys_stl::vector<double>* variable, const kwsys_stl::string& value);
|
||||
void PopulateVariable(kwsys_stl::vector<char*>* variable, const kwsys_stl::string& value);
|
||||
void PopulateVariable(kwsys_stl::vector<kwsys_stl::string>* variable, const kwsys_stl::string& value);
|
||||
|
||||
typedef CommandLineArgumentsInternal Internal;
|
||||
Internal* Internals;
|
||||
kwsys_stl::string Help;
|
||||
|
|
|
@ -3157,7 +3157,7 @@ bool SystemTools::LocateFileInDir(const char *filename,
|
|||
{
|
||||
filename_dir = SystemTools::GetFilenamePath(filename_dir);
|
||||
filename_dir_base = SystemTools::GetFilenameName(filename_dir);
|
||||
#if _WIN32
|
||||
#if defined( _WIN32 )
|
||||
if (!filename_dir_base.size() ||
|
||||
filename_dir_base[filename_dir_base.size() - 1] == ':')
|
||||
#else
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "kwsysPrivate.h"
|
||||
#include KWSYS_HEADER(CommandLineArguments.hxx)
|
||||
#include KWSYS_HEADER(ios/iostream)
|
||||
#include KWSYS_HEADER(stl/vector)
|
||||
|
||||
// Work-around CMake dependency scanning limitation. This must
|
||||
// duplicate the above list of headers.
|
||||
|
@ -46,6 +47,12 @@ int unknown_argument(const char* argument, void* call_data)
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool CompareTwoItemsOnList(bool i1, bool i2) { return i1 == i2; }
|
||||
bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; }
|
||||
bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; }
|
||||
bool CompareTwoItemsOnList(const kwsys_stl::string& i1,
|
||||
const kwsys_stl::string& i2) { return i1 == i2; }
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// Example run: ./testCommandLineArguments --some-int-variable 4
|
||||
|
@ -70,6 +77,21 @@ int main(int argc, char* argv[])
|
|||
bool bool_arg1 = false;
|
||||
int bool_arg2 = 0;
|
||||
|
||||
kwsys_stl::vector<int> numbers_argument;
|
||||
int valid_numbers[] = { 5, 1, 8, 3, 7, 1, 3, 9, 7, 1 };
|
||||
|
||||
kwsys_stl::vector<double> doubles_argument;
|
||||
double valid_doubles[] = { 12.5, 1.31, 22 };
|
||||
|
||||
kwsys_stl::vector<bool> bools_argument;
|
||||
bool valid_bools[] = { true, true, false };
|
||||
|
||||
kwsys_stl::vector<char*> strings_argument;
|
||||
char* valid_strings[] = { "andy", "bill", "brad", "ken" };
|
||||
|
||||
kwsys_stl::vector<kwsys_stl::string> stl_strings_argument;
|
||||
kwsys_stl::string valid_stl_strings[] = { "ken", "brad", "bill", "andy" };
|
||||
|
||||
typedef kwsys::CommandLineArguments argT;
|
||||
|
||||
arg.AddArgument("--some-int-variable", argT::SPACE_ARGUMENT, &some_int_variable, "Set some random int variable");
|
||||
|
@ -80,6 +102,11 @@ int main(int argc, char* argv[])
|
|||
arg.AddArgument("--another-bool-variable", argT::NO_ARGUMENT, &some_bool_variable1, "Set some random bool variable 1");
|
||||
arg.AddBooleanArgument("--set-bool-arg1", &bool_arg1, "Test AddBooleanArgument 1");
|
||||
arg.AddBooleanArgument("--set-bool-arg2", &bool_arg2, "Test AddBooleanArgument 2");
|
||||
arg.AddArgument("--some-multi-argument", argT::MULTI_ARGUMENT, &numbers_argument, "Some multiple values variable");
|
||||
arg.AddArgument("-N", argT::SPACE_ARGUMENT, &doubles_argument, "Some explicit multiple values variable");
|
||||
arg.AddArgument("-BB", argT::CONCAT_ARGUMENT, &bools_argument, "Some explicit multiple values variable");
|
||||
arg.AddArgument("-SS", argT::EQUAL_ARGUMENT, &strings_argument, "Some explicit multiple values variable");
|
||||
arg.AddArgument("-SSS", argT::MULTI_ARGUMENT, &stl_strings_argument, "Some explicit multiple values variable");
|
||||
|
||||
arg.AddCallback("-A", argT::NO_ARGUMENT, argument, random_ptr, "Some option -A. This option has a multiline comment. It should demonstrate how the code splits lines.");
|
||||
arg.AddCallback("-B", argT::SPACE_ARGUMENT, argument, random_ptr, "Option -B takes argument with space");
|
||||
|
@ -99,7 +126,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
kwsys_ios::cout << "Some int variable was set to: " << some_int_variable << kwsys_ios::endl;
|
||||
kwsys_ios::cout << "Some double variable was set to: " << some_double_variable << kwsys_ios::endl;
|
||||
if ( some_string_variable )
|
||||
if ( some_string_variable && strcmp(some_string_variable, "test string with space") == 0)
|
||||
{
|
||||
kwsys_ios::cout << "Some string variable was set to: " << some_string_variable << kwsys_ios::endl;
|
||||
delete [] some_string_variable;
|
||||
|
@ -109,6 +136,38 @@ int main(int argc, char* argv[])
|
|||
kwsys_ios::cerr << "Problem setting string variable" << kwsys_ios::endl;
|
||||
res = 1;
|
||||
}
|
||||
size_t cc;
|
||||
#define CompareTwoLists(list1, list_valid, lsize) \
|
||||
if ( list1.size() != lsize ) \
|
||||
{ \
|
||||
kwsys_ios::cerr << "Problem setting " #list1 ". Size is: " << list1.size() \
|
||||
<< " should be: " << lsize << kwsys_ios::endl; \
|
||||
res = 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
kwsys_ios::cout << #list1 " argument set:"; \
|
||||
for ( cc =0; cc < lsize; ++ cc ) \
|
||||
{ \
|
||||
kwsys_ios::cout << " " << list1[cc]; \
|
||||
if ( !CompareTwoItemsOnList(list1[cc], list_valid[cc]) ) \
|
||||
{ \
|
||||
kwsys_ios::cerr << "Problem setting " #list1 ". Value of " \
|
||||
<< cc << " is: [" << list1[cc] << "] <> [" \
|
||||
<< list_valid[cc] << "]" << kwsys_ios::endl; \
|
||||
res = 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
kwsys_ios::cout << kwsys_ios::endl; \
|
||||
}
|
||||
|
||||
CompareTwoLists(numbers_argument, valid_numbers, 10);
|
||||
CompareTwoLists(doubles_argument, valid_doubles, 3);
|
||||
CompareTwoLists(bools_argument, valid_bools, 3);
|
||||
CompareTwoLists(strings_argument, valid_strings, 4);
|
||||
CompareTwoLists(stl_strings_argument, valid_stl_strings, 4);
|
||||
|
||||
kwsys_ios::cout << "Some STL String variable was set to: " << some_stl_string_variable.c_str() << kwsys_ios::endl;
|
||||
kwsys_ios::cout << "Some bool variable was set to: " << some_bool_variable << kwsys_ios::endl;
|
||||
kwsys_ios::cout << "Some bool variable was set to: " << some_bool_variable1 << kwsys_ios::endl;
|
||||
|
|
Loading…
Reference in New Issue