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
7d674b5f0b.
This commit is contained in:
Ben Boeckel 2014-12-01 10:51:49 -05:00
parent 7878d06189
commit ceecd7902f
8 changed files with 83 additions and 43 deletions

View File

@ -47,6 +47,7 @@ Variables that Provide Information
/variable/CMAKE_LINK_LIBRARY_SUFFIX /variable/CMAKE_LINK_LIBRARY_SUFFIX
/variable/CMAKE_MAJOR_VERSION /variable/CMAKE_MAJOR_VERSION
/variable/CMAKE_MAKE_PROGRAM /variable/CMAKE_MAKE_PROGRAM
/variable/CMAKE_MATCH_COUNT
/variable/CMAKE_MINIMUM_REQUIRED_VERSION /variable/CMAKE_MINIMUM_REQUIRED_VERSION
/variable/CMAKE_MINOR_VERSION /variable/CMAKE_MINOR_VERSION
/variable/CMAKE_PARENT_LIST_FILE /variable/CMAKE_PARENT_LIST_FILE

View File

@ -0,0 +1,5 @@
cached-regex-clear-fixed
------------------------
* Add :variable:`CMAKE_MATCH_COUNT` for the number of matches made in the last
regular expression.

View File

@ -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_<n>``
variables with the match contents. The ``CMAKE_MATCH_COUNT`` variable holds
the number of match expressions when these are filled.

View File

@ -11,7 +11,6 @@
============================================================================*/ ============================================================================*/
#include "cmConditionEvaluator.h" #include "cmConditionEvaluator.h"
#include "cmStringCommand.h"
cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile): cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile):
Makefile(makefile), Makefile(makefile),
@ -556,7 +555,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList &newArgs,
{ {
def = this->GetVariableOrString(*arg); def = this->GetVariableOrString(*arg);
const char* rex = argP2->c_str(); const char* rex = argP2->c_str();
cmStringCommand::ClearMatches(&this->Makefile); this->Makefile.ClearMatches();
cmsys::RegularExpression regEntry; cmsys::RegularExpression regEntry;
if ( !regEntry.compile(rex) ) if ( !regEntry.compile(rex) )
{ {
@ -568,7 +567,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList &newArgs,
} }
if (regEntry.find(def)) if (regEntry.find(def))
{ {
cmStringCommand::StoreMatches(&this->Makefile, regEntry); this->Makefile.StoreMatches(regEntry);
*arg = cmExpandedCommandArgument("1", true); *arg = cmExpandedCommandArgument("1", true);
} }
else else

View File

@ -4841,6 +4841,64 @@ std::vector<cmSourceFile*> cmMakefile::GetQtUiFilesWithOptions() const
return this->QtUiFilesWithOptions; 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<char>('0' + i);
}
}
char nMatches[] = {highest, '\0'};
this->AddDefinition(nMatchesVariable, nMatches);
this->MarkVariableAsUsed(nMatchesVariable);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmPolicies::PolicyStatus cmPolicies::PolicyStatus
cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const

View File

@ -976,6 +976,9 @@ public:
void PopLoopBlock(); void PopLoopBlock();
bool IsLoopBlock() const; bool IsLoopBlock() const;
void ClearMatches();
void StoreMatches(cmsys::RegularExpression& re);
protected: protected:
// add link libraries and directories to the target // add link libraries and directories to the target
void AddGlobalLinkInformation(const std::string& name, cmTarget& target); void AddGlobalLinkInformation(const std::string& name, cmTarget& target);

View File

@ -310,7 +310,7 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args)
input += args[i]; input += args[i];
} }
this->ClearMatches(this->Makefile); this->Makefile->ClearMatches();
// Compile the regular expression. // Compile the regular expression.
cmsys::RegularExpression re; cmsys::RegularExpression re;
if(!re.compile(regex.c_str())) if(!re.compile(regex.c_str()))
@ -325,7 +325,7 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args)
std::string output; std::string output;
if(re.find(input.c_str())) 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 l = re.start();
std::string::size_type r = re.end(); std::string::size_type r = re.end();
if(r-l == 0) if(r-l == 0)
@ -359,7 +359,7 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
input += args[i]; input += args[i];
} }
this->ClearMatches(this->Makefile); this->Makefile->ClearMatches();
// Compile the regular expression. // Compile the regular expression.
cmsys::RegularExpression re; cmsys::RegularExpression re;
if(!re.compile(regex.c_str())) if(!re.compile(regex.c_str()))
@ -376,7 +376,7 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
const char* p = input.c_str(); const char* p = input.c_str();
while(re.find(p)) while(re.find(p))
{ {
this->StoreMatches(this->Makefile, re); this->Makefile->StoreMatches(re);
std::string::size_type l = re.start(); std::string::size_type l = re.start();
std::string::size_type r = re.end(); std::string::size_type r = re.end();
if(r-l == 0) if(r-l == 0)
@ -463,7 +463,7 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
input += args[i]; input += args[i];
} }
this->ClearMatches(this->Makefile); this->Makefile->ClearMatches();
// Compile the regular expression. // Compile the regular expression.
cmsys::RegularExpression re; cmsys::RegularExpression re;
if(!re.compile(regex.c_str())) if(!re.compile(regex.c_str()))
@ -480,7 +480,7 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
std::string::size_type base = 0; std::string::size_type base = 0;
while(re.find(input.c_str()+base)) 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 l2 = re.start();
std::string::size_type r = re.end(); std::string::size_type r = re.end();
@ -540,38 +540,6 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
return true; 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<std::string> const& bool cmStringCommand::HandleFindCommand(std::vector<std::string> const&
args) args)

View File

@ -53,8 +53,6 @@ public:
virtual std::string GetName() const { return "string";} virtual std::string GetName() const { return "string";}
cmTypeMacro(cmStringCommand, cmCommand); cmTypeMacro(cmStringCommand, cmCommand);
static void ClearMatches(cmMakefile* mf);
static void StoreMatches(cmMakefile* mf, cmsys::RegularExpression& re);
protected: protected:
bool HandleConfigureCommand(std::vector<std::string> const& args); bool HandleConfigureCommand(std::vector<std::string> const& args);
bool HandleAsciiCommand(std::vector<std::string> const& args); bool HandleAsciiCommand(std::vector<std::string> const& args);