summaryrefslogtreecommitdiffstats
path: root/Source/kwsys
diff options
context:
space:
mode:
authorAndy Cedilnik <andy.cedilnik@kitware.com>2006-07-14 13:13:23 (GMT)
committerAndy Cedilnik <andy.cedilnik@kitware.com>2006-07-14 13:13:23 (GMT)
commitd2a3ccd50533a1ce5bbb081a6fe727ed184cdeb1 (patch)
tree63ad5b83e9f65bc99e210e8cdd25db96fec604b6 /Source/kwsys
parentfc49142fc634ae3b55feb744730251275d271dfc (diff)
downloadCMake-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.txt18
-rw-r--r--Source/kwsys/CommandLineArguments.cxx470
-rw-r--r--Source/kwsys/CommandLineArguments.hxx.in87
-rw-r--r--Source/kwsys/SystemTools.cxx2
-rw-r--r--Source/kwsys/testCommandLineArguments.cxx61
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;