diff options
Diffstat (limited to 'Source/cmListCommand.cxx')
-rw-r--r-- | Source/cmListCommand.cxx | 499 |
1 files changed, 248 insertions, 251 deletions
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index 1b01ea2..91dea58 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -13,89 +13,35 @@ #include <stdio.h> #include <stdlib.h> // required for atoi #include <utility> +#include <vector> + +#include "cm_memory.hxx" +#include "cm_static_string_view.hxx" #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmStringReplaceHelper.h" +#include "cmSubcommandTable.h" #include "cmSystemTools.h" -class cmExecutionStatus; - -bool cmListCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) -{ - if (args.size() < 2) { - this->SetError("must be called with at least two arguments."); - return false; - } - - const std::string& subCommand = args[0]; - if (subCommand == "LENGTH") { - return this->HandleLengthCommand(args); - } - if (subCommand == "GET") { - return this->HandleGetCommand(args); - } - if (subCommand == "APPEND") { - return this->HandleAppendCommand(args); - } - if (subCommand == "PREPEND") { - return this->HandlePrependCommand(args); - } - if (subCommand == "POP_BACK") { - return this->HandlePopBackCommand(args); - } - if (subCommand == "POP_FRONT") { - return this->HandlePopFrontCommand(args); - } - if (subCommand == "FIND") { - return this->HandleFindCommand(args); - } - if (subCommand == "INSERT") { - return this->HandleInsertCommand(args); - } - if (subCommand == "JOIN") { - return this->HandleJoinCommand(args); - } - if (subCommand == "REMOVE_AT") { - return this->HandleRemoveAtCommand(args); - } - if (subCommand == "REMOVE_ITEM") { - return this->HandleRemoveItemCommand(args); - } - if (subCommand == "REMOVE_DUPLICATES") { - return this->HandleRemoveDuplicatesCommand(args); - } - if (subCommand == "TRANSFORM") { - return this->HandleTransformCommand(args); - } - if (subCommand == "SORT") { - return this->HandleSortCommand(args); - } - if (subCommand == "SUBLIST") { - return this->HandleSublistCommand(args); - } - if (subCommand == "REVERSE") { - return this->HandleReverseCommand(args); - } - if (subCommand == "FILTER") { - return this->HandleFilterCommand(args); - } +namespace { - std::string e = "does not recognize sub-command " + subCommand; - this->SetError(e); - return false; -} +bool FilterRegex(std::vector<std::string> const& args, bool includeMatches, + std::string const& listName, + std::vector<std::string>& varArgsExpanded, + cmExecutionStatus& status); -bool cmListCommand::GetListString(std::string& listString, - const std::string& var) +bool GetListString(std::string& listString, const std::string& var, + const cmMakefile& makefile) { // get the old value - const char* cacheValue = this->Makefile->GetDefinition(var); + const char* cacheValue = makefile.GetDefinition(var); if (!cacheValue) { return false; } @@ -103,11 +49,11 @@ bool cmListCommand::GetListString(std::string& listString, return true; } -bool cmListCommand::GetList(std::vector<std::string>& list, - const std::string& var) +bool GetList(std::vector<std::string>& list, const std::string& var, + const cmMakefile& makefile) { std::string listString; - if (!this->GetListString(listString, var)) { + if (!GetListString(listString, var, makefile)) { return false; } // if the size of the list @@ -115,25 +61,24 @@ bool cmListCommand::GetList(std::vector<std::string>& list, return true; } // expand the variable into a list - cmSystemTools::ExpandListArgument(listString, list, true); + cmExpandList(listString, list, true); // if no empty elements then just return - if (std::find(list.begin(), list.end(), std::string()) == list.end()) { + if (!cmContains(list, std::string())) { return true; } // if we have empty elements we need to check policy CMP0007 - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0007)) { + switch (makefile.GetPolicyStatus(cmPolicies::CMP0007)) { case cmPolicies::WARN: { // Default is to warn and use old behavior // OLD behavior is to allow compatibility, so recall // ExpandListArgument without the true which will remove // empty values list.clear(); - cmSystemTools::ExpandListArgument(listString, list); - std::string warn = cmPolicies::GetPolicyWarning(cmPolicies::CMP0007); - warn += " List has value = ["; - warn += listString; - warn += "]."; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, warn); + cmExpandList(listString, list); + std::string warn = + cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0007), + " List has value = [", listString, "]."); + makefile.IssueMessage(MessageType::AUTHOR_WARNING, warn); return true; } case cmPolicies::OLD: @@ -141,13 +86,13 @@ bool cmListCommand::GetList(std::vector<std::string>& list, // ExpandListArgument without the true which will remove // empty values list.clear(); - cmSystemTools::ExpandListArgument(listString, list); + cmExpandList(listString, list); return true; case cmPolicies::NEW: return true; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: - this->Makefile->IssueMessage( + makefile.IssueMessage( MessageType::FATAL_ERROR, cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0007)); return false; @@ -155,10 +100,11 @@ bool cmListCommand::GetList(std::vector<std::string>& list, return true; } -bool cmListCommand::HandleLengthCommand(std::vector<std::string> const& args) +bool HandleLengthCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 3) { - this->SetError("sub-command LENGTH requires two arguments."); + status.SetError("sub-command LENGTH requires two arguments."); return false; } @@ -168,19 +114,20 @@ bool cmListCommand::HandleLengthCommand(std::vector<std::string> const& args) // do not check the return value here // if the list var is not found varArgsExpanded will have size 0 // and we will return 0 - this->GetList(varArgsExpanded, listName); + GetList(varArgsExpanded, listName, status.GetMakefile()); size_t length = varArgsExpanded.size(); char buffer[1024]; sprintf(buffer, "%d", static_cast<int>(length)); - this->Makefile->AddDefinition(variableName, buffer); + status.GetMakefile().AddDefinition(variableName, buffer); return true; } -bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args) +bool HandleGetCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 4) { - this->SetError("sub-command GET requires at least three arguments."); + status.SetError("sub-command GET requires at least three arguments."); return false; } @@ -188,13 +135,13 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args) const std::string& variableName = args.back(); // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { - this->Makefile->AddDefinition(variableName, "NOTFOUND"); + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { + status.GetMakefile().AddDefinition(variableName, "NOTFOUND"); return true; } // FIXME: Add policy to make non-existing lists an error like empty lists. if (varArgsExpanded.empty()) { - this->SetError("GET given empty list"); + status.SetError("GET given empty list"); return false; } @@ -213,17 +160,18 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args) std::ostringstream str; str << "index: " << item << " out of range (-" << nitem << ", " << nitem - 1 << ")"; - this->SetError(str.str()); + status.SetError(str.str()); return false; } value += varArgsExpanded[item]; } - this->Makefile->AddDefinition(variableName, value.c_str()); + status.GetMakefile().AddDefinition(variableName, value); return true; } -bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args) +bool HandleAppendCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); @@ -232,10 +180,11 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args) return true; } + cmMakefile& makefile = status.GetMakefile(); std::string const& listName = args[1]; // expand the variable std::string listString; - this->GetListString(listString, listName); + GetListString(listString, listName, makefile); // If `listString` or `args` is empty, no need to append `;`, // then index is going to be `1` and points to the end-of-string ";" @@ -243,11 +192,12 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args) std::string::size_type(listString.empty() || args.empty()); listString += &";"[offset] + cmJoin(cmMakeRange(args).advance(2), ";"); - this->Makefile->AddDefinition(listName, listString.c_str()); + makefile.AddDefinition(listName, listString); return true; } -bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args) +bool HandlePrependCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); @@ -256,10 +206,11 @@ bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args) return true; } + cmMakefile& makefile = status.GetMakefile(); std::string const& listName = args[1]; // expand the variable std::string listString; - this->GetListString(listString, listName); + GetListString(listString, listName, makefile); // If `listString` or `args` is empty, no need to append `;`, // then `offset` is going to be `1` and points to the end-of-string ";" @@ -268,22 +219,24 @@ bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args) listString.insert(0, cmJoin(cmMakeRange(args).advance(2), ";") + &";"[offset]); - this->Makefile->AddDefinition(listName, listString.c_str()); + makefile.AddDefinition(listName, listString); return true; } -bool cmListCommand::HandlePopBackCommand(std::vector<std::string> const& args) +bool HandlePopBackCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); + cmMakefile& makefile = status.GetMakefile(); auto ai = args.cbegin(); ++ai; // Skip subcommand name std::string const& listName = *ai++; std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, makefile)) { // Can't get the list definition... undefine any vars given after. for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } return true; } @@ -296,41 +249,42 @@ bool cmListCommand::HandlePopBackCommand(std::vector<std::string> const& args) // Ok, assign elements to be removed to the given variables for (; !varArgsExpanded.empty() && ai != args.cend(); ++ai) { assert(!ai->empty()); - this->Makefile->AddDefinition(*ai, varArgsExpanded.back().c_str()); + makefile.AddDefinition(*ai, varArgsExpanded.back()); varArgsExpanded.pop_back(); } // Undefine the rest variables if the list gets empty earlier... for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } } - this->Makefile->AddDefinition(listName, - cmJoin(varArgsExpanded, ";").c_str()); + makefile.AddDefinition(listName, cmJoin(varArgsExpanded, ";")); } else if (ai != args.cend()) { // The list is empty, but some args were given // Need to *undefine* 'em all, cuz there are no items to assign... for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } } return true; } -bool cmListCommand::HandlePopFrontCommand(std::vector<std::string> const& args) +bool HandlePopFrontCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); + cmMakefile& makefile = status.GetMakefile(); auto ai = args.cbegin(); ++ai; // Skip subcommand name std::string const& listName = *ai++; std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, makefile)) { // Can't get the list definition... undefine any vars given after. for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } return true; } @@ -344,33 +298,33 @@ bool cmListCommand::HandlePopFrontCommand(std::vector<std::string> const& args) auto vi = varArgsExpanded.begin(); for (; vi != varArgsExpanded.end() && ai != args.cend(); ++ai, ++vi) { assert(!ai->empty()); - this->Makefile->AddDefinition(*ai, vi->c_str()); + makefile.AddDefinition(*ai, *vi); } varArgsExpanded.erase(varArgsExpanded.begin(), vi); // Undefine the rest variables if the list gets empty earlier... for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } } - this->Makefile->AddDefinition(listName, - cmJoin(varArgsExpanded, ";").c_str()); + makefile.AddDefinition(listName, cmJoin(varArgsExpanded, ";")); } else if (ai != args.cend()) { // The list is empty, but some args were given // Need to *undefine* 'em all, cuz there are no items to assign... for (; ai != args.cend(); ++ai) { - this->Makefile->RemoveDefinition(*ai); + makefile.RemoveDefinition(*ai); } } return true; } -bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args) +bool HandleFindCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 4) { - this->SetError("sub-command FIND requires three arguments."); + status.SetError("sub-command FIND requires three arguments."); return false; } @@ -378,28 +332,29 @@ bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args) const std::string& variableName = args.back(); // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { - this->Makefile->AddDefinition(variableName, "-1"); + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { + status.GetMakefile().AddDefinition(variableName, "-1"); return true; } std::vector<std::string>::iterator it = std::find(varArgsExpanded.begin(), varArgsExpanded.end(), args[2]); if (it != varArgsExpanded.end()) { - std::ostringstream indexStream; - indexStream << std::distance(varArgsExpanded.begin(), it); - this->Makefile->AddDefinition(variableName, indexStream.str().c_str()); + status.GetMakefile().AddDefinition( + variableName, + std::to_string(std::distance(varArgsExpanded.begin(), it))); return true; } - this->Makefile->AddDefinition(variableName, "-1"); + status.GetMakefile().AddDefinition(variableName, "-1"); return true; } -bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args) +bool HandleInsertCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 4) { - this->SetError("sub-command INSERT requires at least three arguments."); + status.SetError("sub-command INSERT requires at least three arguments."); return false; } @@ -408,11 +363,12 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args) // expand the variable int item = atoi(args[2].c_str()); std::vector<std::string> varArgsExpanded; - if ((!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) && + if ((!GetList(varArgsExpanded, listName, status.GetMakefile()) || + varArgsExpanded.empty()) && item != 0) { std::ostringstream str; str << "index: " << item << " out of range (0, 0)"; - this->SetError(str.str()); + status.SetError(str.str()); return false; } @@ -425,7 +381,7 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args) std::ostringstream str; str << "index: " << item << " out of range (-" << varArgsExpanded.size() << ", " << varArgsExpanded.size() << ")"; - this->SetError(str.str()); + status.SetError(str.str()); return false; } } @@ -434,17 +390,18 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args) args.end()); std::string value = cmJoin(varArgsExpanded, ";"); - this->Makefile->AddDefinition(listName, value.c_str()); + status.GetMakefile().AddDefinition(listName, value); return true; } -bool cmListCommand::HandleJoinCommand(std::vector<std::string> const& args) +bool HandleJoinCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 4) { std::ostringstream error; error << "sub-command JOIN requires three arguments (" << args.size() - 1 << " found)."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -454,30 +411,30 @@ bool cmListCommand::HandleJoinCommand(std::vector<std::string> const& args) // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { - this->Makefile->AddDefinition(variableName, ""); + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { + status.GetMakefile().AddDefinition(variableName, ""); return true; } std::string value = cmJoin(cmMakeRange(varArgsExpanded.begin(), varArgsExpanded.end()), glue); - this->Makefile->AddDefinition(variableName, value.c_str()); + status.GetMakefile().AddDefinition(variableName, value); return true; } -bool cmListCommand::HandleRemoveItemCommand( - std::vector<std::string> const& args) +bool HandleRemoveItemCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("sub-command REMOVE_ITEM requires two or more arguments."); + status.SetError("sub-command REMOVE_ITEM requires two or more arguments."); return false; } const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { return true; } @@ -491,44 +448,45 @@ bool cmListCommand::HandleRemoveItemCommand( cmRemoveMatching(varArgsExpanded, cmMakeRange(remBegin, remEnd)); std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin(); std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";"); - this->Makefile->AddDefinition(listName, value.c_str()); + status.GetMakefile().AddDefinition(listName, value); return true; } -bool cmListCommand::HandleReverseCommand(std::vector<std::string> const& args) +bool HandleReverseCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); if (args.size() > 2) { - this->SetError("sub-command REVERSE only takes one argument."); + status.SetError("sub-command REVERSE only takes one argument."); return false; } const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { return true; } std::string value = cmJoin(cmReverseRange(varArgsExpanded), ";"); - this->Makefile->AddDefinition(listName, value.c_str()); + status.GetMakefile().AddDefinition(listName, value); return true; } -bool cmListCommand::HandleRemoveDuplicatesCommand( - std::vector<std::string> const& args) +bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); if (args.size() > 2) { - this->SetError("sub-command REMOVE_DUPLICATES only takes one argument."); + status.SetError("sub-command REMOVE_DUPLICATES only takes one argument."); return false; } const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { return true; } @@ -537,12 +495,11 @@ bool cmListCommand::HandleRemoveDuplicatesCommand( std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin(); std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";"); - this->Makefile->AddDefinition(listName, value.c_str()); + status.GetMakefile().AddDefinition(listName, value); return true; } // Helpers for list(TRANSFORM <list> ...) -namespace { using transform_type = std::function<std::string(const std::string&)>; class transform_error : public std::runtime_error @@ -693,7 +650,8 @@ public: } this->Indexes.resize(size); - auto start = this->Start, step = this->Step; + auto start = this->Start; + auto step = this->Step; std::generate(this->Indexes.begin(), this->Indexes.end(), [&start, step]() -> int { auto r = start; @@ -757,13 +715,12 @@ public: private: cmStringReplaceHelper ReplaceHelper; }; -} -bool cmListCommand::HandleTransformCommand( - std::vector<std::string> const& args) +bool HandleTransformCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError( + status.SetError( "sub-command TRANSFORM requires an action to be specified."); return false; } @@ -853,7 +810,7 @@ bool cmListCommand::HandleTransformCommand( { "STRIP", 0, [&command](const std::string& s) -> std::string { if (command.Selector->InSelection(s)) { - return cmSystemTools::TrimWhitespace(s); + return cmTrimWhitespace(s); } return s; @@ -886,7 +843,7 @@ bool cmListCommand::HandleTransformCommand( if (descriptor == descriptors.end()) { std::ostringstream error; error << " sub-command TRANSFORM, " << args[index] << " invalid action."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -896,7 +853,7 @@ bool cmListCommand::HandleTransformCommand( std::ostringstream error; error << "sub-command TRANSFORM, action " << descriptor->Name << " expects " << descriptor->Arity << " argument(s)."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -909,16 +866,18 @@ bool cmListCommand::HandleTransformCommand( if (command.Name == "REPLACE") { try { - command.Action = - cm::make_unique<TransformReplace>(command.Arguments, this->Makefile); + command.Action = cm::make_unique<TransformReplace>( + command.Arguments, &status.GetMakefile()); } catch (const transform_error& e) { - this->SetError(e.what()); + status.SetError(e.what()); return false; } } - const std::string REGEX{ "REGEX" }, AT{ "AT" }, FOR{ "FOR" }, - OUTPUT_VARIABLE{ "OUTPUT_VARIABLE" }; + const std::string REGEX{ "REGEX" }; + const std::string AT{ "AT" }; + const std::string FOR{ "FOR" }; + const std::string OUTPUT_VARIABLE{ "OUTPUT_VARIABLE" }; // handle optional arguments while (args.size() > index) { @@ -927,15 +886,15 @@ bool cmListCommand::HandleTransformCommand( std::ostringstream error; error << "sub-command TRANSFORM, selector already specified (" << command.Selector->Tag << ")."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } // REGEX selector if (args[index] == REGEX) { if (args.size() == ++index) { - this->SetError("sub-command TRANSFORM, selector REGEX expects " - "'regular expression' argument."); + status.SetError("sub-command TRANSFORM, selector REGEX expects " + "'regular expression' argument."); return false; } @@ -945,7 +904,7 @@ bool cmListCommand::HandleTransformCommand( error << "sub-command TRANSFORM, selector REGEX failed to compile " "regex \""; error << args[index] << "\"."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -975,7 +934,7 @@ bool cmListCommand::HandleTransformCommand( } if (indexes.empty()) { - this->SetError( + status.SetError( "sub-command TRANSFORM, selector AT expects at least one " "numeric value."); return false; @@ -990,12 +949,15 @@ bool cmListCommand::HandleTransformCommand( // FOR selector if (args[index] == FOR) { if (args.size() <= ++index + 1) { - this->SetError("sub-command TRANSFORM, selector FOR expects, at least," - " two arguments."); + status.SetError( + "sub-command TRANSFORM, selector FOR expects, at least," + " two arguments."); return false; } - int start = 0, stop = 0, step = 1; + int start = 0; + int stop = 0; + int step = 1; bool valid = true; try { std::size_t pos; @@ -1016,8 +978,8 @@ bool cmListCommand::HandleTransformCommand( valid = false; } if (!valid) { - this->SetError("sub-command TRANSFORM, selector FOR expects, " - "at least, two numeric values."); + status.SetError("sub-command TRANSFORM, selector FOR expects, " + "at least, two numeric values."); return false; } // try to read a third numeric value for step @@ -1038,8 +1000,8 @@ bool cmListCommand::HandleTransformCommand( } if (step < 0) { - this->SetError("sub-command TRANSFORM, selector FOR expects " - "non negative numeric value for <step>."); + status.SetError("sub-command TRANSFORM, selector FOR expects " + "non negative numeric value for <step>."); } command.Selector = @@ -1051,8 +1013,8 @@ bool cmListCommand::HandleTransformCommand( // output variable if (args[index] == OUTPUT_VARIABLE) { if (args.size() == ++index) { - this->SetError("sub-command TRANSFORM, OUTPUT_VARIABLE " - "expects variable name argument."); + status.SetError("sub-command TRANSFORM, OUTPUT_VARIABLE " + "expects variable name argument."); return false; } @@ -1064,14 +1026,14 @@ bool cmListCommand::HandleTransformCommand( error << "sub-command TRANSFORM, '" << cmJoin(cmMakeRange(args).advance(index), " ") << "': unexpected argument(s)."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } // expand the list variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, command.ListName)) { - this->Makefile->AddDefinition(command.OutputName, ""); + if (!GetList(varArgsExpanded, command.ListName, status.GetMakefile())) { + status.GetMakefile().AddDefinition(command.OutputName, ""); return true; } @@ -1083,12 +1045,12 @@ bool cmListCommand::HandleTransformCommand( try { command.Selector->Transform(varArgsExpanded, descriptor->Transform); } catch (const transform_error& e) { - this->SetError(e.what()); + status.SetError(e.what()); return false; } - this->Makefile->AddDefinition(command.OutputName, - cmJoin(varArgsExpanded, ";").c_str()); + status.GetMakefile().AddDefinition(command.OutputName, + cmJoin(varArgsExpanded, ";")); return true; } @@ -1168,11 +1130,12 @@ protected: bool descending; }; -bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) +bool HandleSortCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { assert(args.size() >= 2); if (args.size() > 8) { - this->SetError("sub-command SORT only takes up to six arguments."); + status.SetError("sub-command SORT only takes up to six arguments."); return false; } @@ -1187,9 +1150,9 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) const std::string option = args[argumentIndex++]; if (option == "COMPARE") { if (sortCompare != cmStringSorter::Compare::UNINITIALIZED) { - std::string error = messageHint + "option \"" + option + - "\" has been specified multiple times."; - this->SetError(error); + std::string error = cmStrCat(messageHint, "option \"", option, + "\" has been specified multiple times."); + status.SetError(error); return false; } if (argumentIndex < args.size()) { @@ -1199,23 +1162,22 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) } else if (argument == "FILE_BASENAME") { sortCompare = cmStringSorter::Compare::FILE_BASENAME; } else { - std::string error = messageHint + "value \"" + argument + - "\" for option \"" + option + "\" is invalid."; - this->SetError(error); + std::string error = + cmStrCat(messageHint, "value \"", argument, "\" for option \"", + option, "\" is invalid."); + status.SetError(error); return false; } } else { - std::string error = - messageHint + "missing argument for option \"" + option + "\"."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "missing argument for option \"", + option, "\".")); return false; } } else if (option == "CASE") { if (sortCaseSensitivity != cmStringSorter::CaseSensitivity::UNINITIALIZED) { - std::string error = messageHint + "option \"" + option + - "\" has been specified multiple times."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "option \"", option, + "\" has been specified multiple times.")); return false; } if (argumentIndex < args.size()) { @@ -1225,23 +1187,21 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) } else if (argument == "INSENSITIVE") { sortCaseSensitivity = cmStringSorter::CaseSensitivity::INSENSITIVE; } else { - std::string error = messageHint + "value \"" + argument + - "\" for option \"" + option + "\" is invalid."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "value \"", argument, + "\" for option \"", option, + "\" is invalid.")); return false; } } else { - std::string error = - messageHint + "missing argument for option \"" + option + "\"."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "missing argument for option \"", + option, "\".")); return false; } } else if (option == "ORDER") { if (sortOrder != cmStringSorter::Order::UNINITIALIZED) { - std::string error = messageHint + "option \"" + option + - "\" has been specified multiple times."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "option \"", option, + "\" has been specified multiple times.")); return false; } if (argumentIndex < args.size()) { @@ -1251,21 +1211,19 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) } else if (argument == "DESCENDING") { sortOrder = cmStringSorter::Order::DESCENDING; } else { - std::string error = messageHint + "value \"" + argument + - "\" for option \"" + option + "\" is invalid."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "value \"", argument, + "\" for option \"", option, + "\" is invalid.")); return false; } } else { - std::string error = - messageHint + "missing argument for option \"" + option + "\"."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "missing argument for option \"", + option, "\".")); return false; } } else { - std::string error = - messageHint + "option \"" + option + "\" is unknown."; - this->SetError(error); + status.SetError( + cmStrCat(messageHint, "option \"", option, "\" is unknown.")); return false; } } @@ -1283,7 +1241,7 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { return true; } @@ -1297,17 +1255,18 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) } std::string value = cmJoin(varArgsExpanded, ";"); - this->Makefile->AddDefinition(listName, value.c_str()); + status.GetMakefile().AddDefinition(listName, value); return true; } -bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args) +bool HandleSublistCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 5) { std::ostringstream error; error << "sub-command SUBLIST requires four arguments (" << args.size() - 1 << " found)."; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -1316,8 +1275,9 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args) // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) { - this->Makefile->AddDefinition(variableName, ""); + if (!GetList(varArgsExpanded, listName, status.GetMakefile()) || + varArgsExpanded.empty()) { + status.GetMakefile().AddDefinition(variableName, ""); return true; } @@ -1330,13 +1290,13 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args) std::ostringstream error; error << "begin index: " << start << " is out of range 0 - " << varArgsExpanded.size() - 1; - this->SetError(error.str()); + status.SetError(error.str()); return false; } if (length < -1) { std::ostringstream error; error << "length: " << length << " should be -1 or greater"; - this->SetError(error.str()); + status.SetError(error.str()); return false; } @@ -1346,22 +1306,24 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args) : size_type(start + length); std::vector<std::string> sublist(varArgsExpanded.begin() + start, varArgsExpanded.begin() + end); - this->Makefile->AddDefinition(variableName, cmJoin(sublist, ";").c_str()); + status.GetMakefile().AddDefinition(variableName, cmJoin(sublist, ";")); return true; } -bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args) +bool HandleRemoveAtCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("sub-command REMOVE_AT requires at least " - "two arguments."); + status.SetError("sub-command REMOVE_AT requires at least " + "two arguments."); return false; } const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile()) || + varArgsExpanded.empty()) { std::ostringstream str; str << "index: "; for (size_t i = 1; i < args.size(); ++i) { @@ -1371,7 +1333,7 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args) } } str << " out of range (0, 0)"; - this->SetError(str.str()); + status.SetError(str.str()); return false; } @@ -1387,7 +1349,7 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args) std::ostringstream str; str << "index: " << item << " out of range (-" << nitem << ", " << nitem - 1 << ")"; - this->SetError(str.str()); + status.SetError(str.str()); return false; } removed.push_back(static_cast<size_t>(item)); @@ -1403,24 +1365,26 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args) std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin(); std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";"); - this->Makefile->AddDefinition(listName, value.c_str()); + status.GetMakefile().AddDefinition(listName, value); return true; } -bool cmListCommand::HandleFilterCommand(std::vector<std::string> const& args) +bool HandleFilterCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("sub-command FILTER requires a list to be specified."); + status.SetError("sub-command FILTER requires a list to be specified."); return false; } if (args.size() < 3) { - this->SetError("sub-command FILTER requires an operator to be specified."); + status.SetError( + "sub-command FILTER requires an operator to be specified."); return false; } if (args.size() < 4) { - this->SetError("sub-command FILTER requires a mode to be specified."); + status.SetError("sub-command FILTER requires a mode to be specified."); return false; } @@ -1431,28 +1395,29 @@ bool cmListCommand::HandleFilterCommand(std::vector<std::string> const& args) } else if (op == "EXCLUDE") { includeMatches = false; } else { - this->SetError("sub-command FILTER does not recognize operator " + op); + status.SetError("sub-command FILTER does not recognize operator " + op); return false; } const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; - if (!this->GetList(varArgsExpanded, listName)) { + if (!GetList(varArgsExpanded, listName, status.GetMakefile())) { return true; } const std::string& mode = args[3]; if (mode == "REGEX") { if (args.size() != 5) { - this->SetError("sub-command FILTER, mode REGEX " - "requires five arguments."); + status.SetError("sub-command FILTER, mode REGEX " + "requires five arguments."); return false; } - return this->FilterRegex(args, includeMatches, listName, varArgsExpanded); + return FilterRegex(args, includeMatches, listName, varArgsExpanded, + status); } - this->SetError("sub-command FILTER does not recognize mode " + mode); + status.SetError("sub-command FILTER does not recognize mode " + mode); return false; } @@ -1475,19 +1440,18 @@ private: const bool includeMatches; }; -bool cmListCommand::FilterRegex(std::vector<std::string> const& args, - bool includeMatches, - std::string const& listName, - std::vector<std::string>& varArgsExpanded) +bool FilterRegex(std::vector<std::string> const& args, bool includeMatches, + std::string const& listName, + std::vector<std::string>& varArgsExpanded, + cmExecutionStatus& status) { const std::string& pattern = args[4]; cmsys::RegularExpression regex(pattern); if (!regex.is_valid()) { - std::string error = "sub-command FILTER, mode REGEX "; - error += "failed to compile regex \""; - error += pattern; - error += "\"."; - this->SetError(error); + std::string error = + cmStrCat("sub-command FILTER, mode REGEX failed to compile regex \"", + pattern, "\"."); + status.SetError(error); return false; } @@ -1497,6 +1461,39 @@ bool cmListCommand::FilterRegex(std::vector<std::string> const& args, std::remove_if(argsBegin, argsEnd, MatchesRegex(regex, includeMatches)); std::string value = cmJoin(cmMakeRange(argsBegin, newArgsEnd), ";"); - this->Makefile->AddDefinition(listName, value.c_str()); + status.GetMakefile().AddDefinition(listName, value); return true; } + +} // namespace + +bool cmListCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + if (args.size() < 2) { + status.SetError("must be called with at least two arguments."); + return false; + } + + static cmSubcommandTable const subcommand{ + { "LENGTH"_s, HandleLengthCommand }, + { "GET"_s, HandleGetCommand }, + { "APPEND"_s, HandleAppendCommand }, + { "PREPEND"_s, HandlePrependCommand }, + { "POP_BACK"_s, HandlePopBackCommand }, + { "POP_FRONT"_s, HandlePopFrontCommand }, + { "FIND"_s, HandleFindCommand }, + { "INSERT"_s, HandleInsertCommand }, + { "JOIN"_s, HandleJoinCommand }, + { "REMOVE_AT"_s, HandleRemoveAtCommand }, + { "REMOVE_ITEM"_s, HandleRemoveItemCommand }, + { "REMOVE_DUPLICATES"_s, HandleRemoveDuplicatesCommand }, + { "TRANSFORM"_s, HandleTransformCommand }, + { "SORT"_s, HandleSortCommand }, + { "SUBLIST"_s, HandleSublistCommand }, + { "REVERSE"_s, HandleReverseCommand }, + { "FILTER"_s, HandleFilterCommand }, + }; + + return subcommand(args[0], args, status); +} |