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:
Andy Cedilnik 2006-07-14 09:13:23 -04:00
parent fc49142fc6
commit d2a3ccd505
5 changed files with 463 additions and 173 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;