diff options
author | Bill Hoffman <bill.hoffman@kitware.com> | 2016-09-07 20:47:23 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2016-09-08 15:33:46 (GMT) |
commit | cb299acc27d5f80b2fc801f0f57358ec9f0303d1 (patch) | |
tree | db2426c946edfc3cd760edfc28f66a8bbedf4844 /Source | |
parent | f506489d1ed222761f9ce752144a458290020e55 (diff) | |
download | CMake-cb299acc27d5f80b2fc801f0f57358ec9f0303d1.zip CMake-cb299acc27d5f80b2fc801f0f57358ec9f0303d1.tar.gz CMake-cb299acc27d5f80b2fc801f0f57358ec9f0303d1.tar.bz2 |
cmake_parse_arguments: Add option to read arguments from ARGC/ARGV#
The `ARGC`/`ARGV#` variables in function scope hold the original
arguments with no ;-list flattening. Add a way for functions to
cleanly parse arguments that may contain `;`. This also avoids
extra copying of the arguments.
Co-Author: Brad King <brad.king@kitware.com>
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmParseArgumentsCommand.cxx | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx index 8f524ec..f9313c5 100644 --- a/Source/cmParseArgumentsCommand.cxx +++ b/Source/cmParseArgumentsCommand.cxx @@ -20,6 +20,8 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, { // cmake_parse_arguments(prefix options single multi <ARGN>) // 1 2 3 4 + // or + // cmake_parse_arguments(PARSE_ARGV N prefix options single multi) if (args.size() < 4) { this->SetError("must be called with at least 4 arguments."); return false; @@ -27,6 +29,27 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, std::vector<std::string>::const_iterator argIter = args.begin(), argEnd = args.end(); + bool parseFromArgV = false; + unsigned long argvStart = 0; + if (*argIter == "PARSE_ARGV") { + if (args.size() != 6) { + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + "PARSE_ARGV must be called with exactly 6 arguments."); + cmSystemTools::SetFatalErrorOccured(); + return true; + } + parseFromArgV = true; + argIter++; // move past PARSE_ARGV + if (!cmSystemTools::StringToULong(argIter->c_str(), &argvStart)) { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, "PARSE_ARGV index '" + + *argIter + + "' is not an unsigned integer"); + cmSystemTools::SetFatalErrorOccured(); + return true; + } + argIter++; // move past N + } // the first argument is the prefix const std::string prefix = (*argIter++) + "_"; @@ -90,11 +113,37 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, } insideValues = NONE; std::string currentArgName; - // Flatten ;-lists in the arguments into a single list as was done - // by the original function(CMAKE_PARSE_ARGUMENTS). list.clear(); - for (; argIter != argEnd; ++argIter) { - cmSystemTools::ExpandListArgument(*argIter, list); + if (!parseFromArgV) { + // Flatten ;-lists in the arguments into a single list as was done + // by the original function(CMAKE_PARSE_ARGUMENTS). + for (; argIter != argEnd; ++argIter) { + cmSystemTools::ExpandListArgument(*argIter, list); + } + } else { + // in the PARSE_ARGV move read the arguments from ARGC and ARGV# + std::string argc = this->Makefile->GetSafeDefinition("ARGC"); + unsigned long count; + if (!cmSystemTools::StringToULong(argc.c_str(), &count)) { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "PARSE_ARGV called with ARGC='" + argc + + "' that is not an unsigned integer"); + cmSystemTools::SetFatalErrorOccured(); + return true; + } + for (unsigned long i = argvStart; i < count; ++i) { + std::ostringstream argName; + argName << "ARGV" << i; + const char* arg = this->Makefile->GetDefinition(argName.str()); + if (!arg) { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "PARSE_ARGV called with " + + argName.str() + " not set"); + cmSystemTools::SetFatalErrorOccured(); + return true; + } + list.push_back(arg); + } } // iterate over the arguments list and fill in the values where applicable |