From ceecd7902fe80baabfad0235c54719e19a3df06b Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 1 Dec 2014 10:51:49 -0500 Subject: [PATCH] cmMakefile: store the number of last matches in a CMake var With PushScope and PopScope, keeping track of another bit of data for each scope isn't easy. Instead, store it as another CMake variable so it gets implicitly tracked along with everything else. This works in a revert of commit 7d674b5f0b28a610333644d417c2e8cb796cc9e4. --- Help/manual/cmake-variables.7.rst | 1 + Help/release/dev/cached-regex-clear-fixed.rst | 5 ++ Help/variable/CMAKE_MATCH_COUNT.rst | 8 +++ Source/cmConditionEvaluator.cxx | 5 +- Source/cmMakefile.cxx | 58 +++++++++++++++++++ Source/cmMakefile.h | 3 + Source/cmStringCommand.cxx | 44 ++------------ Source/cmStringCommand.h | 2 - 8 files changed, 83 insertions(+), 43 deletions(-) create mode 100644 Help/release/dev/cached-regex-clear-fixed.rst create mode 100644 Help/variable/CMAKE_MATCH_COUNT.rst diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 99088e042..2de410365 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -47,6 +47,7 @@ Variables that Provide Information /variable/CMAKE_LINK_LIBRARY_SUFFIX /variable/CMAKE_MAJOR_VERSION /variable/CMAKE_MAKE_PROGRAM + /variable/CMAKE_MATCH_COUNT /variable/CMAKE_MINIMUM_REQUIRED_VERSION /variable/CMAKE_MINOR_VERSION /variable/CMAKE_PARENT_LIST_FILE diff --git a/Help/release/dev/cached-regex-clear-fixed.rst b/Help/release/dev/cached-regex-clear-fixed.rst new file mode 100644 index 000000000..fbf08cca7 --- /dev/null +++ b/Help/release/dev/cached-regex-clear-fixed.rst @@ -0,0 +1,5 @@ +cached-regex-clear-fixed +------------------------ + +* Add :variable:`CMAKE_MATCH_COUNT` for the number of matches made in the last + regular expression. diff --git a/Help/variable/CMAKE_MATCH_COUNT.rst b/Help/variable/CMAKE_MATCH_COUNT.rst new file mode 100644 index 000000000..8b1c0365b --- /dev/null +++ b/Help/variable/CMAKE_MATCH_COUNT.rst @@ -0,0 +1,8 @@ +CMAKE_MATCH_COUNT +----------------- + +The number of matches with the last regular expression. + +When a regular expression match is used, CMake fills in ``CMAKE_MATCH_`` +variables with the match contents. The ``CMAKE_MATCH_COUNT`` variable holds +the number of match expressions when these are filled. diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index 6065b8a3a..aba26de10 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -11,7 +11,6 @@ ============================================================================*/ #include "cmConditionEvaluator.h" -#include "cmStringCommand.h" cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile): Makefile(makefile), @@ -556,7 +555,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList &newArgs, { def = this->GetVariableOrString(*arg); const char* rex = argP2->c_str(); - cmStringCommand::ClearMatches(&this->Makefile); + this->Makefile.ClearMatches(); cmsys::RegularExpression regEntry; if ( !regEntry.compile(rex) ) { @@ -568,7 +567,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList &newArgs, } if (regEntry.find(def)) { - cmStringCommand::StoreMatches(&this->Makefile, regEntry); + this->Makefile.StoreMatches(regEntry); *arg = cmExpandedCommandArgument("1", true); } else diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 53fd56f75..a7acc2733 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -4841,6 +4841,64 @@ std::vector cmMakefile::GetQtUiFilesWithOptions() const return this->QtUiFilesWithOptions; } +static std::string const matchVariables[] = { + "CMAKE_MATCH_0", + "CMAKE_MATCH_1", + "CMAKE_MATCH_2", + "CMAKE_MATCH_3", + "CMAKE_MATCH_4", + "CMAKE_MATCH_5", + "CMAKE_MATCH_6", + "CMAKE_MATCH_7", + "CMAKE_MATCH_8", + "CMAKE_MATCH_9" +}; + +static std::string const nMatchesVariable = "CMAKE_MATCH_COUNT"; + +//---------------------------------------------------------------------------- +void cmMakefile::ClearMatches() +{ + const char* nMatchesStr = this->GetDefinition(nMatchesVariable); + if (!nMatchesStr) + { + return; + } + int nMatches = atoi(nMatchesStr); + for (int i=0; i<=nMatches; i++) + { + std::string const& var = matchVariables[i]; + std::string const& s = this->GetSafeDefinition(var); + if(!s.empty()) + { + this->AddDefinition(var, ""); + this->MarkVariableAsUsed(var); + } + } + this->AddDefinition(nMatchesVariable, "0"); + this->MarkVariableAsUsed(nMatchesVariable); +} + +//---------------------------------------------------------------------------- +void cmMakefile::StoreMatches(cmsys::RegularExpression& re) +{ + char highest = 0; + for (int i=0; i<10; i++) + { + std::string const& m = re.match(i); + if(!m.empty()) + { + std::string const& var = matchVariables[i]; + this->AddDefinition(var, m.c_str()); + this->MarkVariableAsUsed(var); + highest = static_cast('0' + i); + } + } + char nMatches[] = {highest, '\0'}; + this->AddDefinition(nMatchesVariable, nMatches); + this->MarkVariableAsUsed(nMatchesVariable); +} + //---------------------------------------------------------------------------- cmPolicies::PolicyStatus cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 05b7a376b..fcfec8dc1 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -976,6 +976,9 @@ public: void PopLoopBlock(); bool IsLoopBlock() const; + void ClearMatches(); + void StoreMatches(cmsys::RegularExpression& re); + protected: // add link libraries and directories to the target void AddGlobalLinkInformation(const std::string& name, cmTarget& target); diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 9827c6241..834102748 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -310,7 +310,7 @@ bool cmStringCommand::RegexMatch(std::vector const& args) input += args[i]; } - this->ClearMatches(this->Makefile); + this->Makefile->ClearMatches(); // Compile the regular expression. cmsys::RegularExpression re; if(!re.compile(regex.c_str())) @@ -325,7 +325,7 @@ bool cmStringCommand::RegexMatch(std::vector const& args) std::string output; if(re.find(input.c_str())) { - this->StoreMatches(this->Makefile, re); + this->Makefile->StoreMatches(re); std::string::size_type l = re.start(); std::string::size_type r = re.end(); if(r-l == 0) @@ -359,7 +359,7 @@ bool cmStringCommand::RegexMatchAll(std::vector const& args) input += args[i]; } - this->ClearMatches(this->Makefile); + this->Makefile->ClearMatches(); // Compile the regular expression. cmsys::RegularExpression re; if(!re.compile(regex.c_str())) @@ -376,7 +376,7 @@ bool cmStringCommand::RegexMatchAll(std::vector const& args) const char* p = input.c_str(); while(re.find(p)) { - this->StoreMatches(this->Makefile, re); + this->Makefile->StoreMatches(re); std::string::size_type l = re.start(); std::string::size_type r = re.end(); if(r-l == 0) @@ -463,7 +463,7 @@ bool cmStringCommand::RegexReplace(std::vector const& args) input += args[i]; } - this->ClearMatches(this->Makefile); + this->Makefile->ClearMatches(); // Compile the regular expression. cmsys::RegularExpression re; if(!re.compile(regex.c_str())) @@ -480,7 +480,7 @@ bool cmStringCommand::RegexReplace(std::vector const& args) std::string::size_type base = 0; while(re.find(input.c_str()+base)) { - this->StoreMatches(this->Makefile, re); + this->Makefile->StoreMatches(re); std::string::size_type l2 = re.start(); std::string::size_type r = re.end(); @@ -540,38 +540,6 @@ bool cmStringCommand::RegexReplace(std::vector const& args) return true; } -//---------------------------------------------------------------------------- -void cmStringCommand::ClearMatches(cmMakefile* mf) -{ - for (unsigned int i=0; i<10; i++) - { - char name[128]; - sprintf(name, "CMAKE_MATCH_%d", i); - const char* s = mf->GetDefinition(name); - if(s && *s != 0) - { - mf->AddDefinition(name, ""); - mf->MarkVariableAsUsed(name); - } - } -} - -//---------------------------------------------------------------------------- -void cmStringCommand::StoreMatches(cmMakefile* mf,cmsys::RegularExpression& re) -{ - for (unsigned int i=0; i<10; i++) - { - std::string m = re.match(i); - if(m.size() > 0) - { - char name[128]; - sprintf(name, "CMAKE_MATCH_%d", i); - mf->AddDefinition(name, re.match(i).c_str()); - mf->MarkVariableAsUsed(name); - } - } -} - //---------------------------------------------------------------------------- bool cmStringCommand::HandleFindCommand(std::vector const& args) diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index a5fe89386..9c75095c1 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -53,8 +53,6 @@ public: virtual std::string GetName() const { return "string";} cmTypeMacro(cmStringCommand, cmCommand); - static void ClearMatches(cmMakefile* mf); - static void StoreMatches(cmMakefile* mf, cmsys::RegularExpression& re); protected: bool HandleConfigureCommand(std::vector const& args); bool HandleAsciiCommand(std::vector const& args);