| /* 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 |