diff options
author | Andy Cedilnik <andy.cedilnik@kitware.com> | 2006-07-14 13:13:23 (GMT) |
---|---|---|
committer | Andy Cedilnik <andy.cedilnik@kitware.com> | 2006-07-14 13:13:23 (GMT) |
commit | d2a3ccd50533a1ce5bbb081a6fe727ed184cdeb1 (patch) | |
tree | 63ad5b83e9f65bc99e210e8cdd25db96fec604b6 /Source/kwsys | |
parent | fc49142fc634ae3b55feb744730251275d271dfc (diff) | |
download | CMake-d2a3ccd50533a1ce5bbb081a6fe727ed184cdeb1.zip CMake-d2a3ccd50533a1ce5bbb081a6fe727ed184cdeb1.tar.gz CMake-d2a3ccd50533a1ce5bbb081a6fe727ed184cdeb1.tar.bz2 |
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
Diffstat (limited to 'Source/kwsys')
-rw-r--r-- | Source/kwsys/CMakeLists.txt | 18 | ||||
-rw-r--r-- | Source/kwsys/CommandLineArguments.cxx | 470 | ||||
-rw-r--r-- | Source/kwsys/CommandLineArguments.hxx.in | 87 | ||||
-rw-r--r-- | Source/kwsys/SystemTools.cxx | 2 | ||||
-rw-r--r-- | Source/kwsys/testCommandLineArguments.cxx | 61 |
5 files changed, 464 insertions, 174 deletions
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index a62c798..f160657 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -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 diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx index 38061a5..66f87b0 100644 --- a/Source/kwsys/CommandLineArguments.cxx +++ b/Source/kwsys/CommandLineArguments.cxx @@ -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 ++ ) + 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 ++ ) { - this->Internals->LastArgument = cc; - matches.clear(); - CommandLineArguments::Internal::String& arg = this->Internals->Argv[cc]; - 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 ++ ) + 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 ) - { - // 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() + 1) ) { - this->Internals->LastArgument --; return 0; } - } - if ( cs->Variable ) - { - kwsys_stl::string var = "1"; - if ( value ) - { - 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 ) - { - delete [] *variable; - *variable = 0; - } - *variable = new char[ strlen(var.c_str()) + 1 ]; - strcpy(*variable, var.c_str()); - } - else if ( cs->VariableType == CommandLineArguments::STL_STRING_TYPE ) + break; + case CONCAT_ARGUMENT: + // Value is whatever follows the argument + if ( !this->PopulateVariable(cs, arg.c_str() + sarg.size()) ) { - kwsys_stl::string* variable = static_cast<kwsys_stl::string*>(cs->Variable); - *variable = var; + return 0; } - else if ( cs->VariableType == CommandLineArguments::BOOL_TYPE ) + 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 ) { - 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" ) + const kwsys_stl::string& marg = this->Internals->Argv[cc]; + CommandLineArguments_DEBUG(" check multi argument value: " << marg); + if ( this->GetMatchedArguments(&matches, marg) ) { - *variable = true; + CommandLineArguments_DEBUG("End of multi argument " << arg << " with value: " << marg); + break; } - else + CommandLineArguments_DEBUG(" populate multi argument value: " << marg); + if ( !this->PopulateVariable(cs, marg.c_str()) ) { - *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); -} - -//---------------------------------------------------------------------------- -void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, - double* variable, const char* help) -{ - this->AddArgument(argument, type, CommandLineArguments::DOUBLE_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); -} - -//---------------------------------------------------------------------------- -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); -} +#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::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); -} +#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); \ + } + +CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool); +CommandLineArgumentsAddBooleanArgumentMacro(INT, int); +CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE, double); +CommandLineArgumentsAddBooleanArgumentMacro(STRING, char*); +CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, kwsys_stl::string); + +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 diff --git a/Source/kwsys/CommandLineArguments.hxx.in b/Source/kwsys/CommandLineArguments.hxx.in index eea51eb..db5ffc7 100644 --- a/Source/kwsys/CommandLineArguments.hxx.in +++ b/Source/kwsys/CommandLineArguments.hxx.in @@ -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, @@ -150,14 +160,52 @@ public: 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; diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index b98d6ff..e4efe39 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -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 diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx index 73207c9..35afa4e 100644 --- a/Source/kwsys/testCommandLineArguments.cxx +++ b/Source/kwsys/testCommandLineArguments.cxx @@ -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; |