| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ |
| #include "kwsysPrivate.h" |
| #include KWSYS_HEADER(CommandLineArguments.hxx) |
| |
| #include KWSYS_HEADER(Configure.hxx) |
| #include KWSYS_HEADER(String.hxx) |
| |
| // Work-around CMake dependency scanning limitation. This must |
| // duplicate the above list of headers. |
| #if 0 |
| # include "CommandLineArguments.hxx.in" |
| # include "Configure.hxx.in" |
| # include "String.hxx.in" |
| #endif |
| |
| #include <iostream> |
| #include <map> |
| #include <set> |
| #include <sstream> |
| #include <vector> |
| |
| #include <cstdio> |
| #include <cstdlib> |
| #include <cstring> |
| |
| #ifdef _MSC_VER |
| # pragma warning(disable : 4786) |
| #endif |
| |
| #if defined(__sgi) && !defined(__GNUC__) |
| # pragma set woff 1375 /* base class destructor not virtual */ |
| #endif |
| |
| #if 0 |
| # define CommandLineArguments_DEBUG(x) \ |
| std::cout << __LINE__ << " CLA: " << x << std::endl |
| #else |
| # define CommandLineArguments_DEBUG(x) |
| #endif |
| |
| namespace KWSYS_NAMESPACE { |
| |
| struct CommandLineArgumentsCallbackStructure |
| { |
| const char* Argument; |
| int ArgumentType; |
| CommandLineArguments::CallbackType Callback; |
| void* CallData; |
| void* Variable; |
| int VariableType; |
| const char* Help; |
| }; |
| |
| class CommandLineArgumentsVectorOfStrings : public std::vector<kwsys::String> |
| { |
| }; |
| class CommandLineArgumentsSetOfStrings : public std::set<kwsys::String> |
| { |
| }; |
| class CommandLineArgumentsMapOfStrucs |
| : public std::map<kwsys::String, CommandLineArgumentsCallbackStructure> |
| { |
| }; |
| |
| class CommandLineArgumentsInternal |
| { |
| public: |
| CommandLineArgumentsInternal() = default; |
| |
| using VectorOfStrings = CommandLineArgumentsVectorOfStrings; |
| using CallbacksMap = CommandLineArgumentsMapOfStrucs; |
| using String = kwsys::String; |
| using SetOfStrings = CommandLineArgumentsSetOfStrings; |
| |
| VectorOfStrings Argv; |
| String Argv0; |
| CallbacksMap Callbacks; |
| |
| CommandLineArguments::ErrorCallbackType UnknownArgumentCallback{ nullptr }; |
| void* ClientData{ nullptr }; |
| |
| VectorOfStrings::size_type LastArgument{ 0 }; |
| |
| VectorOfStrings UnusedArguments; |
| }; |
| |
| CommandLineArguments::CommandLineArguments() |
| { |
| this->Internals = new CommandLineArguments::Internal; |
| this->Help = ""; |
| this->LineLength = 80; |
| this->StoreUnusedArgumentsFlag = false; |
| } |
| |
| CommandLineArguments::~CommandLineArguments() |
| { |
| delete this->Internals; |
| } |
| |
| void CommandLineArguments::Initialize(int argc, const char* const argv[]) |
| { |
| int cc; |
| |
| this->Initialize(); |
| this->Internals->Argv0 = argv[0]; |
| for (cc = 1; cc < argc; cc++) { |
| this->ProcessArgument(argv[cc]); |
| } |
| } |
| |
| void CommandLineArguments::Initialize(int argc, char* argv[]) |
| { |
| this->Initialize(argc, static_cast<const char* const*>(argv)); |
| } |
| |
| void CommandLineArguments::Initialize() |
| { |
| this->Internals->Argv.clear(); |
| this->Internals->LastArgument = 0; |
| } |
| |
| void CommandLineArguments::ProcessArgument(const char* arg) |
| { |
| this->Internals->Argv.push_back(arg); |
| } |
| |
| bool CommandLineArguments::GetMatchedArguments( |
| std::vector<std::string>* matches, const std::string& arg) |
| { |
| 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++) { |
| 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) { |
| matches->push_back(parg); |
| } |
| } else if (arg.find(parg) == 0) { |
| matches->push_back(parg); |
| } |
| } |
| return !matches->empty(); |
| } |
| |
| int CommandLineArguments::Parse() |
| { |
| std::vector<std::string>::size_type cc; |
| std::vector<std::string> matches; |
| if (this->StoreUnusedArgumentsFlag) { |
| this->Internals->UnusedArguments.clear(); |
| } |
| for (cc = 0; cc < this->Internals->Argv.size(); cc++) { |
| const std::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. |
| CommandLineArguments::Internal::VectorOfStrings::size_type kk; |
| CommandLineArguments::Internal::VectorOfStrings::size_type maxidx = 0; |
| CommandLineArguments::Internal::String::size_type maxlen = 0; |
| for (kk = 0; kk < matches.size(); kk++) { |
| if (matches[kk].size() > maxlen) { |
| maxlen = matches[kk].size(); |
| maxidx = kk; |
| } |
| } |
| // So, the longest one is probably the right one. Now see if it has any |
| // additional value |
| CommandLineArgumentsCallbackStructure* cs = |
| &this->Internals->Callbacks[matches[maxidx]]; |
| const std::string& sarg = matches[maxidx]; |
| if (cs->Argument != sarg) { |
| abort(); |
| } |
| switch (cs->ArgumentType) { |
| case NO_ARGUMENT: |
| // No value |
| if (!this->PopulateVariable(cs, nullptr)) { |
| 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]); |
| // Value is the next argument |
| if (!this->PopulateVariable(cs, |
| this->Internals->Argv[cc + 1].c_str())) { |
| return 0; |
| } |
| cc++; |
| break; |
| case EQUAL_ARGUMENT: |
| if (arg.size() == sarg.size() || arg.at(sarg.size()) != '=') { |
| this->Internals->LastArgument--; |
| return 0; |
| } |
| // Value is everythng followed the '=' sign |
| if (!this->PopulateVariable(cs, arg.c_str() + sarg.size() + 1)) { |
| return 0; |
| } |
| break; |
| case CONCAT_ARGUMENT: |
| // Value is whatever follows the argument |
| if (!this->PopulateVariable(cs, arg.c_str() + sarg.size())) { |
| return 0; |
| } |
| 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) { |
| const std::string& marg = this->Internals->Argv[cc]; |
| CommandLineArguments_DEBUG( |
| " check multi argument value: " << marg); |
| if (this->GetMatchedArguments(&matches, marg)) { |
| CommandLineArguments_DEBUG("End of multi argument " |
| << arg << " with value: " << marg); |
| break; |
| } |
| CommandLineArguments_DEBUG( |
| " populate multi argument value: " << marg); |
| if (!this->PopulateVariable(cs, marg.c_str())) { |
| return 0; |
| } |
| } |
| if (cc != this->Internals->Argv.size()) { |
| CommandLineArguments_DEBUG("Again End of multi argument " << arg); |
| cc--; |
| continue; |
| } |
| break; |
| default: |
| std::cerr << "Got unknown argument type: \"" << cs->ArgumentType |
| << "\"" << std::endl; |
| this->Internals->LastArgument--; |
| return 0; |
| } |
| } else { |
| // Handle unknown arguments |
| if (this->Internals->UnknownArgumentCallback) { |
| if (!this->Internals->UnknownArgumentCallback( |
| arg.c_str(), this->Internals->ClientData)) { |
| this->Internals->LastArgument--; |
| return 0; |
| } |
| return 1; |
| } else if (this->StoreUnusedArgumentsFlag) { |
| CommandLineArguments_DEBUG("Store unused argument " << arg); |
| this->Internals->UnusedArguments.push_back(arg); |
| } else { |
| std::cerr << "Got unknown argument: \"" << arg << "\"" << std::endl; |
| this->Internals->LastArgument--; |
| return 0; |
| } |
| } |
| } |
| return 1; |
| } |
| |
| void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv) |
| { |
| CommandLineArguments::Internal::VectorOfStrings::size_type size = |
| this->Internals->Argv.size() - this->Internals->LastArgument + 1; |
| CommandLineArguments::Internal::VectorOfStrings::size_type cc; |
| |
| // Copy Argv0 as the first argument |
| char** args = new char*[size]; |
| args[0] = new char[this->Internals->Argv0.size() + 1]; |
| strcpy(args[0], this->Internals->Argv0.c_str()); |
| int cnt = 1; |
| |
| // Copy everything after the LastArgument, since that was not parsed. |
| for (cc = this->Internals->LastArgument + 1; |
| cc < this->Internals->Argv.size(); cc++) { |
| args[cnt] = new char[this->Internals->Argv[cc].size() + 1]; |
| strcpy(args[cnt], this->Internals->Argv[cc].c_str()); |
| cnt++; |
| } |
| *argc = cnt; |
| *argv = args; |
| } |
| |
| void CommandLineArguments::GetUnusedArguments(int* argc, char*** argv) |
| { |
| CommandLineArguments::Internal::VectorOfStrings::size_type size = |
| this->Internals->UnusedArguments.size() + 1; |
| CommandLineArguments::Internal::VectorOfStrings::size_type cc; |
| |
| // Copy Argv0 as the first argument |
| char** args = new char*[size]; |
| args[0] = new char[this->Internals->Argv0.size() + 1]; |
| strcpy(args[0], this->Internals->Argv0.c_str()); |
| int cnt = 1; |
| |
| // Copy everything after the LastArgument, since that was not parsed. |
| for (cc = 0; cc < this->Internals->UnusedArguments.size(); cc++) { |
| kwsys::String& str = this->Internals->UnusedArguments[cc]; |
| args[cnt] = new char[str.size() + 1]; |
| strcpy(args[cnt], str.c_str()); |
| cnt++; |
| } |
| *argc = cnt; |
| *argv = args; |
| } |
| |
| void CommandLineArguments::DeleteRemainingArguments(int argc, char*** argv) |
| { |
| int cc; |
| for (cc = 0; cc < argc; ++cc) { |
| delete[](*argv)[cc]; |
| } |
| delete[] * argv; |
| } |
| |
| void CommandLineArguments::AddCallback(const char* argument, |
| ArgumentTypeEnum type, |
| CallbackType callback, void* call_data, |
| const char* help) |
| { |
| CommandLineArgumentsCallbackStructure s; |
| s.Argument = argument; |
| s.ArgumentType = type; |
| s.Callback = callback; |
| s.CallData = call_data; |
| s.VariableType = CommandLineArguments::NO_VARIABLE_TYPE; |
| s.Variable = nullptr; |
| s.Help = help; |
| |
| this->Internals->Callbacks[argument] = s; |
| this->GenerateHelp(); |
| } |
| |
| void CommandLineArguments::AddArgument(const char* argument, |
| ArgumentTypeEnum type, |
| VariableTypeEnum vtype, void* variable, |
| const char* help) |
| { |
| CommandLineArgumentsCallbackStructure s; |
| s.Argument = argument; |
| s.ArgumentType = type; |
| s.Callback = nullptr; |
| s.CallData = nullptr; |
| s.VariableType = vtype; |
| s.Variable = variable; |
| s.Help = help; |
| |
| this->Internals->Callbacks[argument] = s; |
| this->GenerateHelp(); |
| } |
| |
| #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); \ |
| } |
| |
| /* clang-format off */ |
| CommandLineArgumentsAddArgumentMacro(BOOL, bool) |
| CommandLineArgumentsAddArgumentMacro(INT, int) |
| CommandLineArgumentsAddArgumentMacro(DOUBLE, double) |
| CommandLineArgumentsAddArgumentMacro(STRING, char*) |
| CommandLineArgumentsAddArgumentMacro(STL_STRING, std::string) |
| |
| CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, std::vector<bool>) |
| CommandLineArgumentsAddArgumentMacro(VECTOR_INT, std::vector<int>) |
| CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE, std::vector<double>) |
| CommandLineArgumentsAddArgumentMacro(VECTOR_STRING, std::vector<char*>) |
| CommandLineArgumentsAddArgumentMacro(VECTOR_STL_STRING, |
| std::vector<std::string>) |
| #ifdef HELP_CLANG_FORMAT |
| ; |
| #endif |
| /* clang-format on */ |
| |
| #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); \ |
| } |
| |
| /* clang-format off */ |
| CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool) |
| CommandLineArgumentsAddBooleanArgumentMacro(INT, int) |
| CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE, double) |
| CommandLineArgumentsAddBooleanArgumentMacro(STRING, char*) |
| CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, std::string) |
| #ifdef HELP_CLANG_FORMAT |
| ; |
| #endif |
| /* clang-format on */ |
| |
| void CommandLineArguments::SetClientData(void* client_data) |
| { |
| this->Internals->ClientData = client_data; |
| } |
| |
| void CommandLineArguments::SetUnknownArgumentCallback( |
| CommandLineArguments::ErrorCallbackType callback) |
| { |
| this->Internals->UnknownArgumentCallback = callback; |
| } |
| |
| const char* CommandLineArguments::GetHelp(const char* arg) |
| { |
| auto it = this->Internals->Callbacks.find(arg); |
| if (it == this->Internals->Callbacks.end()) { |
| return nullptr; |
| } |
| |
| // Since several arguments may point to the same argument, find the one this |
| // one point to if this one is pointing to another argument. |
| CommandLineArgumentsCallbackStructure* cs = &(it->second); |
| for (;;) { |
| auto hit = this->Internals->Callbacks.find(cs->Help); |
| if (hit == this->Internals->Callbacks.end()) { |
| break; |
| } |
| cs = &(hit->second); |
| } |
| return cs->Help; |
| } |
| |
| void CommandLineArguments::SetLineLength(unsigned int ll) |
| { |
| if (ll < 9 || ll > 1000) { |
| return; |
| } |
| this->LineLength = ll; |
| this->GenerateHelp(); |
| } |
| |
| const char* CommandLineArguments::GetArgv0() |
| { |
| return this->Internals->Argv0.c_str(); |
| } |
| |
| unsigned int CommandLineArguments::GetLastArgument() |
| { |
| return static_cast<unsigned int>(this->Internals->LastArgument + 1); |
| } |
| |
| void CommandLineArguments::GenerateHelp() |
| { |
| std::ostringstream str; |
| |
| // Collapse all arguments into the map of vectors of all arguments that do |
| // the same thing. |
| CommandLineArguments::Internal::CallbacksMap::iterator it; |
| using MapArgs = std::map<CommandLineArguments::Internal::String, |
| CommandLineArguments::Internal::SetOfStrings>; |
| MapArgs mp; |
| MapArgs::iterator mpit, smpit; |
| for (it = this->Internals->Callbacks.begin(); |
| it != this->Internals->Callbacks.end(); it++) { |
| CommandLineArgumentsCallbackStructure* cs = &(it->second); |
| mpit = mp.find(cs->Help); |
| if (mpit != mp.end()) { |
| mpit->second.insert(it->first); |
| mp[it->first].insert(it->first); |
| } else { |
| mp[it->first].insert(it->first); |
| } |
| } |
| for (it = this->Internals->Callbacks.begin(); |
| it != this->Internals->Callbacks.end(); it++) { |
| CommandLineArgumentsCallbackStructure* cs = &(it->second); |
| mpit = mp.find(cs->Help); |
| if (mpit != mp.end()) { |
| mpit->second.insert(it->first); |
| smpit = mp.find(it->first); |
| CommandLineArguments::Internal::SetOfStrings::iterator sit; |
| for (sit = smpit->second.begin(); sit != smpit->second.end(); sit++) { |
| mpit->second.insert(*sit); |
| } |
| mp.erase(smpit); |
| } else { |
| mp[it->first].insert(it->first); |
| } |
| } |
| |
| // Find the length of the longest string |
| CommandLineArguments::Internal::String::size_type maxlen = 0; |
| for (mpit = mp.begin(); mpit != mp.end(); mpit++) { |
| CommandLineArguments::Internal::SetOfStrings::iterator sit; |
| for (sit = mpit->second.begin(); sit != mpit->second.end(); sit++) { |
| CommandLineArguments::Internal::String::size_type clen = sit->size(); |
| switch (this->Internals->Callbacks[*sit].ArgumentType) { |
| case CommandLineArguments::NO_ARGUMENT: |
| clen += 0; |
| break; |
| case CommandLineArguments::CONCAT_ARGUMENT: |
| clen += 3; |
| break; |
| case CommandLineArguments::SPACE_ARGUMENT: |
| clen += 4; |
| break; |
| case CommandLineArguments::EQUAL_ARGUMENT: |
| clen += 4; |
| break; |
| } |
| if (clen > maxlen) { |
| maxlen = clen; |
| } |
| } |
| } |
| |
| CommandLineArguments::Internal::String::size_type maxstrlen = maxlen; |
| maxlen += 4; // For the space before and after the option |
| |
| // Print help for each option |
| for (mpit = mp.begin(); mpit != mp.end(); mpit++) { |
| CommandLineArguments::Internal::SetOfStrings::iterator sit; |
| for (sit = mpit->second.begin(); sit != mpit->second.end(); sit++) { |
| str << std::endl; |
| std::string argument = *sit; |
| switch (this->Internals->Callbacks[*sit].ArgumentType) { |
| case CommandLineArguments::NO_ARGUMENT: |
| break; |
| case CommandLineArguments::CONCAT_ARGUMENT: |
| argument += "opt"; |
| break; |
| case CommandLineArguments::SPACE_ARGUMENT: |
| argument += " opt"; |
| break; |
| case CommandLineArguments::EQUAL_ARGUMENT: |
| argument += "=opt"; |
| break; |
| case CommandLineArguments::MULTI_ARGUMENT: |
| argument += " opt opt ..."; |
| break; |
| } |
| str << " " << argument.substr(0, maxstrlen) << " "; |
| } |
| const char* ptr = this->Internals->Callbacks[mpit->first].Help; |
| size_t len = strlen(ptr); |
| int cnt = 0; |
| while (len > 0) { |
| // If argument with help is longer than line length, split it on previous |
| // space (or tab) and continue on the next line |
| CommandLineArguments::Internal::String::size_type cc; |
| for (cc = 0; ptr[cc]; cc++) { |
| if (*ptr == ' ' || *ptr == '\t') { |
| ptr++; |
| len--; |
| } |
| } |
| if (cnt > 0) { |
| for (cc = 0; cc < maxlen; cc++) { |
| str << " "; |
| } |
| } |
| CommandLineArguments::Internal::String::size_type skip = len; |
| if (skip > this->LineLength - maxlen) { |
| skip = this->LineLength - maxlen; |
| for (cc = skip - 1; cc > 0; cc--) { |
| if (ptr[cc] == ' ' || ptr[cc] == '\t') { |
| break; |
| } |
| } |
| if (cc != 0) { |
| skip = cc; |
| } |
| } |
| str.write(ptr, static_cast<std::streamsize>(skip)); |
| str << std::endl; |
| ptr += skip; |
| len -= skip; |
| cnt++; |
| } |
| } |
| /* |
| // This can help debugging help string |
| str << endl; |
| unsigned int cc; |
| for ( cc = 0; cc < this->LineLength; cc ++ ) |
| { |
| str << cc % 10; |
| } |
| str << endl; |
| */ |
| this->Help = str.str(); |
| } |
| |
| void CommandLineArguments::PopulateVariable(bool* variable, |
| const std::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 std::string& value) |
| { |
| char* res = nullptr; |
| *variable = static_cast<int>(strtol(value.c_str(), &res, 10)); |
| // if ( res && *res ) |
| // { |
| // Can handle non-int |
| // } |
| } |
| |
| void CommandLineArguments::PopulateVariable(double* variable, |
| const std::string& value) |
| { |
| char* res = nullptr; |
| *variable = strtod(value.c_str(), &res); |
| // if ( res && *res ) |
| // { |
| // Can handle non-double |
| // } |
| } |
| |
| void CommandLineArguments::PopulateVariable(char** variable, |
| const std::string& value) |
| { |
| delete[] * variable; |
| *variable = new char[value.size() + 1]; |
| strcpy(*variable, value.c_str()); |
| } |
| |
| void CommandLineArguments::PopulateVariable(std::string* variable, |
| const std::string& value) |
| { |
| *variable = value; |
| } |
| |
| void CommandLineArguments::PopulateVariable(std::vector<bool>* variable, |
| const std::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(std::vector<int>* variable, |
| const std::string& value) |
| { |
| char* res = nullptr; |
| variable->push_back(static_cast<int>(strtol(value.c_str(), &res, 10))); |
| // if ( res && *res ) |
| // { |
| // Can handle non-int |
| // } |
| } |
| |
| void CommandLineArguments::PopulateVariable(std::vector<double>* variable, |
| const std::string& value) |
| { |
| char* res = nullptr; |
| variable->push_back(strtod(value.c_str(), &res)); |
| // if ( res && *res ) |
| // { |
| // Can handle non-int |
| // } |
| } |
| |
| void CommandLineArguments::PopulateVariable(std::vector<char*>* variable, |
| const std::string& value) |
| { |
| char* var = new char[value.size() + 1]; |
| strcpy(var, value.c_str()); |
| variable->push_back(var); |
| } |
| |
| void CommandLineArguments::PopulateVariable(std::vector<std::string>* variable, |
| const std::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 false; |
| } |
| } |
| CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to " |
| << value); |
| if (cs->Variable) { |
| std::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<std::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<std::vector<bool>*>(cs->Variable), |
| var); |
| break; |
| case CommandLineArguments::VECTOR_INT_TYPE: |
| this->PopulateVariable(static_cast<std::vector<int>*>(cs->Variable), |
| var); |
| break; |
| case CommandLineArguments::VECTOR_DOUBLE_TYPE: |
| this->PopulateVariable(static_cast<std::vector<double>*>(cs->Variable), |
| var); |
| break; |
| case CommandLineArguments::VECTOR_STRING_TYPE: |
| this->PopulateVariable(static_cast<std::vector<char*>*>(cs->Variable), |
| var); |
| break; |
| case CommandLineArguments::VECTOR_STL_STRING_TYPE: |
| this->PopulateVariable( |
| static_cast<std::vector<std::string>*>(cs->Variable), var); |
| break; |
| default: |
| std::cerr << "Got unknown variable type: \"" << cs->VariableType |
| << "\"" << std::endl; |
| this->Internals->LastArgument--; |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| } // namespace KWSYS_NAMESPACE |