[CMake] a backwards compatible language simplification
Lloyd Hilaiel
lloydh at yahoo-inc.com
Thu May 11 16:45:24 EDT 2006
>Personally I like the extra text but I certainly
>understand how it might drive some folks batty.
I understand your side too. I particularly like this change because it's
backwards compatible and allows both preferences to co-exist.
>But to answer the meat of your question I do not think it can be trivially
>changed to not require the extra text but I'll try to take a look at it over
>the next few days.
Attached is a patch which makes the change (on 2.4.1-beta). I'm sure it's
full of holes, and don't know if it's welcome, but fwiw...
tests are passing 100%, and cmake bootstraps and builds itself fine with
the patch applied. Also my big ol' camke project works fine with the
patch .
attached are three cmake files that address cases
of nesting ifs, foreach, and while (nested whiles cause and infinite loop
in 2.4.1 beta, btw), and the patch itself.
best,
lloyd
--
lloydh at yahoo-inc.com | surface the individual anywhere
http://docs.yahoo.com/info/values/
-------------- next part --------------
diff -ur cmake-2.4.1.orig/Source/cmFileCommand.cxx cmake-2.4.1/Source/cmFileCommand.cxx
--- cmake-2.4.1.orig/Source/cmFileCommand.cxx Sun Apr 30 09:06:34 2006
+++ cmake-2.4.1/Source/cmFileCommand.cxx Thu May 11 13:37:52 2006
@@ -924,7 +924,7 @@
}
if(!cmSystemTools::FileIsFullPath(fileName.c_str()))
{
- std::string errstring = "RelativePath must be passed a full path to the directory: " + directoryName;
+ std::string errstring = "RelativePath must be passed a full path to the file: " + fileName;
this->SetError(errstring.c_str());
return false;
}
diff -ur cmake-2.4.1.orig/Source/cmForEachCommand.cxx cmake-2.4.1/Source/cmForEachCommand.cxx
--- cmake-2.4.1.orig/Source/cmForEachCommand.cxx Sun Apr 30 09:06:37 2006
+++ cmake-2.4.1/Source/cmForEachCommand.cxx Thu May 11 14:25:23 2006
@@ -25,14 +25,17 @@
{
return false;
}
-
- // at end of for each execute recorded commands
- if (cmSystemTools::LowerCase(lff.Name) == "endforeach")
+
+ if (cmSystemTools::LowerCase(lff.Name) == "foreach")
{
- std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments);
- if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0]))
- {
+ // record the number of nested foreach commands
+ this->depth++;
+ }
+ else if (cmSystemTools::LowerCase(lff.Name) == "endforeach")
+ {
+ if (!this->depth) {
+ // at end of for each execute recorded commands
+
// store the old value
std::string oldDef;
if (mf.GetDefinition(this->Args[0].c_str()))
@@ -60,8 +63,12 @@
mf.RemoveFunctionBlocker(lff);
return true;
}
+ else
+ {
+ this->depth--;
+ }
}
-
+
// record the command
this->Functions.push_back(lff);
@@ -74,12 +81,7 @@
{
if(cmSystemTools::LowerCase(lff.Name) == "endforeach")
{
- std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments);
- if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0]))
- {
- return true;
- }
+ return true;
}
return false;
}
diff -ur cmake-2.4.1.orig/Source/cmForEachCommand.h cmake-2.4.1/Source/cmForEachCommand.h
--- cmake-2.4.1.orig/Source/cmForEachCommand.h Sun Apr 30 09:06:36 2006
+++ cmake-2.4.1/Source/cmForEachCommand.h Thu May 11 14:06:30 2006
@@ -29,7 +29,7 @@
class cmForEachFunctionBlocker : public cmFunctionBlocker
{
public:
- cmForEachFunctionBlocker() {this->Executing = false;}
+ cmForEachFunctionBlocker() {this->Executing = false; depth = 0;}
virtual ~cmForEachFunctionBlocker() {}
virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
cmMakefile &mf);
@@ -39,6 +39,8 @@
std::vector<std::string> Args;
std::vector<cmListFileFunction> Functions;
bool Executing;
+private:
+ int depth;
};
/** \class cmForEachCommand
diff -ur cmake-2.4.1.orig/Source/cmIfCommand.cxx cmake-2.4.1/Source/cmIfCommand.cxx
--- cmake-2.4.1.orig/Source/cmIfCommand.cxx Sun Apr 30 09:06:37 2006
+++ cmake-2.4.1/Source/cmIfCommand.cxx Thu May 11 13:37:52 2006
@@ -34,39 +34,19 @@
if (cmSystemTools::LowerCase(lff.Name) == "else" ||
cmSystemTools::LowerCase(lff.Name) == "endif")
{
- if (args == this->Args)
+ // if it was an else statement then we should change state
+ // and block this Else Command
+ if (cmSystemTools::LowerCase(lff.Name) == "else")
{
- // if it was an else statement then we should change state
- // and block this Else Command
- if (cmSystemTools::LowerCase(lff.Name) == "else")
- {
- this->IsBlocking = !this->IsBlocking;
- return true;
- }
- // otherwise it must be an ENDIF statement, in that case remove the
- // function blocker
- mf.RemoveFunctionBlocker(lff);
+ this->IsBlocking = !this->IsBlocking;
return true;
}
- else if(args.empty())
- {
- std::string err = "Empty arguments for ";
- err += name;
- err += ". Did you mean ";
- err += name;
- err += "( ";
- for(std::vector<cmListFileArgument>::const_iterator a = this->Args.begin();
- a != this->Args.end();++a)
- {
- err += (a->Quoted?"\"":"");
- err += a->Value;
- err += (a->Quoted?"\"":"");
- err += " ";
- }
- err += ")?";
- cmSystemTools::Error(err.c_str());
- }
- }
+ // otherwise it must be an ENDIF statement, in that case remove the
+ // function blocker
+ mf.RemoveFunctionBlocker(lff);
+ return true;
+ }
+
return this->IsBlocking;
}
@@ -75,11 +55,9 @@
{
if (cmSystemTools::LowerCase(lff.Name) == "endif")
{
- if (lff.Arguments == this->Args)
- {
- return true;
- }
+ return true;
}
+
return false;
}
diff -ur cmake-2.4.1.orig/Source/cmListFileCache.cxx cmake-2.4.1/Source/cmListFileCache.cxx
--- cmake-2.4.1.orig/Source/cmListFileCache.cxx Sun Apr 30 09:06:37 2006
+++ cmake-2.4.1/Source/cmListFileCache.cxx Thu May 11 13:37:52 2006
@@ -52,45 +52,25 @@
// stream.
this->ModifiedTime = cmSystemTools::ModifiedTime(filename);
bool parseError = false;
- bool haveNewline = true;
cmListFileLexer_Token* token;
while(!parseError && (token = cmListFileLexer_Scan(lexer)))
{
- if(token->type == cmListFileLexer_Token_Newline)
+ if(token->type == cmListFileLexer_Token_Identifier)
{
- haveNewline = true;
- }
- else if(token->type == cmListFileLexer_Token_Identifier)
- {
- if(haveNewline)
+ cmListFileFunction inFunction;
+ inFunction.Name = token->text;
+ inFunction.FilePath = filename;
+ inFunction.Line = token->line;
+ if(cmListFileCacheParseFunction(lexer, inFunction, filename))
{
- haveNewline = false;
- cmListFileFunction inFunction;
- inFunction.Name = token->text;
- inFunction.FilePath = filename;
- inFunction.Line = token->line;
- if(cmListFileCacheParseFunction(lexer, inFunction, filename))
- {
- this->Functions.push_back(inFunction);
- }
- else
- {
- parseError = true;
- }
+ this->Functions.push_back(inFunction);
}
else
{
- cmOStringStream error;
- error << "Error in cmake code at\n"
- << filename << ":" << token->line << ":\n"
- << "Parse error. Expected a newline, got "
- << cmListFileLexer_GetTypeAsString(lexer, token->type)
- << " with text \"" << token->text << "\".";
- cmSystemTools::Error(error.str().c_str());
parseError = true;
}
}
- else
+ else if(token->type != cmListFileLexer_Token_Newline)
{
cmOStringStream error;
error << "Error in cmake code at\n"
@@ -141,17 +121,14 @@
cmListFileFunction& function,
const char* filename)
{
- // Command name has already been parsed. Read the left paren.
+ // allow no parens.. interpret as function call with no arguments.
cmListFileLexer_Token* token;
- if(!(token = cmListFileLexer_Scan(lexer)))
+ if(!(token = cmListFileLexer_Scan(lexer)) ||
+ token->type == cmListFileLexer_Token_Newline)
{
- cmOStringStream error;
- error << "Error in cmake code at\n"
- << filename << ":" << cmListFileLexer_GetCurrentLine(lexer) << ":\n"
- << "Parse error. Function missing opening \"(\".";
- cmSystemTools::Error(error.str().c_str());
- return false;
+ return true;
}
+
if(token->type != cmListFileLexer_Token_ParenLeft)
{
cmOStringStream error;
diff -ur cmake-2.4.1.orig/Source/cmWhileCommand.cxx cmake-2.4.1/Source/cmWhileCommand.cxx
--- cmake-2.4.1.orig/Source/cmWhileCommand.cxx Sun Apr 30 09:06:37 2006
+++ cmake-2.4.1/Source/cmWhileCommand.cxx Thu May 11 14:27:28 2006
@@ -28,30 +28,42 @@
}
// at end of for each execute recorded commands
- if (cmSystemTools::LowerCase(lff.Name) == "endwhile")
+ if (cmSystemTools::LowerCase(lff.Name) == "while")
{
- char* errorString = 0;
+ // record the number of while commands
+ this->depth++;
+ }
+ else if (cmSystemTools::LowerCase(lff.Name) == "endwhile")
+ {
+ if (!this->depth)
+ {
+ char* errorString = 0;
- std::vector<std::string> expandedArguments;
- mf.ExpandArguments(this->Args, expandedArguments);
- bool isTrue =
- cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
-
- this->Executing = true;
- while (isTrue)
- {
- // Invoke all the functions that were collected in the block.
- for(unsigned int c = 0; c < this->Functions.size(); ++c)
- {
- mf.ExecuteCommand(this->Functions[c]);
- }
- expandedArguments.clear();
+ std::vector<std::string> expandedArguments;
mf.ExpandArguments(this->Args, expandedArguments);
- isTrue =
+ bool isTrue =
cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
+
+ this->Executing = true;
+ while (isTrue)
+ {
+ // Invoke all the functions that were collected in the block.
+ for(unsigned int c = 0; c < this->Functions.size(); ++c)
+ {
+ mf.ExecuteCommand(this->Functions[c]);
+ }
+ expandedArguments.clear();
+ mf.ExpandArguments(this->Args, expandedArguments);
+ isTrue =
+ cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
+ }
+ mf.RemoveFunctionBlocker(lff);
+ return true;
+ }
+ else
+ {
+ this->depth--;
}
- mf.RemoveFunctionBlocker(lff);
- return true;
}
// record the command
@@ -66,10 +78,7 @@
{
if(cmSystemTools::LowerCase(lff.Name) == "endwhile")
{
- if (lff.Arguments == this->Args)
- {
- return true;
- }
+ return true;
}
return false;
}
diff -ur cmake-2.4.1.orig/Source/cmWhileCommand.h cmake-2.4.1/Source/cmWhileCommand.h
--- cmake-2.4.1.orig/Source/cmWhileCommand.h Sun Apr 30 09:06:37 2006
+++ cmake-2.4.1/Source/cmWhileCommand.h Thu May 11 14:27:54 2006
@@ -29,7 +29,7 @@
class cmWhileFunctionBlocker : public cmFunctionBlocker
{
public:
- cmWhileFunctionBlocker() {Executing = false;}
+ cmWhileFunctionBlocker() {Executing = false; depth=0;}
virtual ~cmWhileFunctionBlocker() {}
virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
cmMakefile &mf);
@@ -39,6 +39,8 @@
std::vector<cmListFileArgument> Args;
std::vector<cmListFileFunction> Functions;
bool Executing;
+private:
+ int depth;
};
/** \class cmWhileCommand
-------------- next part --------------
FOREACH(x RANGE 7)
FOREACH(y RANGE 7)
MESSAGE("${x}-${y}")
ENDFOREACH
ENDFOREACH
-------------- next part --------------
IF ("bar" STREQUAL "bar")
IF ("foo" STREQUAL "foo")
MESSAGE("FOO")
ELSE ("foo" STREQUAL "foo")
MESSAGE("NOT FOO")
ENDIF ("foo" STREQUAL "foo")
IF ("foo" STREQUAL "foo")
MESSAGE("FOO")
ELSE ("foo" STREQUAL "foo")
MESSAGE("NOT FOO")
ENDIF ("foo" STREQUAL "foo")
ELSE ("bar" STREQUAL "bar")
IF ("foo" STREQUAL "foo")
MESSAGE("else FOO")
ELSE ("foo" STREQUAL "foo")
MESSAGE("else NOT FOO")
ENDIF ("foo" STREQUAL "foo")
IF ("foo" STREQUAL "foo")
MESSAGE("else FOO")
ELSE ("foo" STREQUAL "foo")
MESSAGE("else NOT FOO")
ENDIF ("foo" STREQUAL "foo")
ENDIF ("bar" STREQUAL "bar")
-------------- next part --------------
MESSAGE("-3")
SET(y 1)
SET(z 1)
WHILE (y)
MESSAGE("-2")
WHILE (z)
MESSAGE("-2.5")
SET(y)
SET(z)
ENDWHILE (z)
MESSAGE("-1")
ENDWHILE (y)
MESSAGE("1")
SET(foo 1)
WHILE (foo)
MESSAGE("2")
SET(bar 1)
WHILE (bar)
FOREACH (x RANGE 3 5)
MESSAGE("${x}")
ENDFOREACH (x)
MESSAGE("6")
SET(bar)
MESSAGE("7")
ENDWHILE (bar)
SET(foo)
MESSAGE("8")
ENDWHILE (foo)
MESSAGE("9")
More information about the CMake
mailing list