Add Lua-style long brackets and long comments to CMake language

Teach the CMake language parser to recognize Lua-style "long bracket"
arguments.  These start with two '[' separated by zero or more '='
characters e.g. "[[" or "[=[" or "[==[".  They end with two ']'
separated by the same number of '=' as the opening bracket.  There is no
nesting of brackets of the same level (number of '=').  No escapes,
variable expansion, or other processing is performed on the content
between such brackets so they always represent exactly one argument.

Also teach CMake to parse and ignore "long comment" syntax.  A long
comment starts with "#" immediately followed by an opening long bracket.
It ends at the matching close long bracket.

Teach the RunCMake.Syntax test to cover long bracket and long comment
cases.
This commit is contained in:
Brad King
2013-08-06 15:58:22 -04:00
parent a8c652342f
commit daa0f6f98d
75 changed files with 639 additions and 195 deletions
+49 -31
View File
@@ -29,14 +29,14 @@ struct cmListFileParser
~cmListFileParser();
bool ParseFile();
bool ParseFunction(const char* name, long line);
void AddArgument(cmListFileLexer_Token* token,
bool AddArgument(cmListFileLexer_Token* token,
cmListFileArgument::Delimiter delim);
cmListFile* ListFile;
cmMakefile* Makefile;
const char* FileName;
cmListFileLexer* Lexer;
cmListFileFunction Function;
enum { SeparationOkay, SeparationWarning } Separation;
enum { SeparationOkay, SeparationWarning, SeparationError} Separation;
};
//----------------------------------------------------------------------------
@@ -90,6 +90,10 @@ bool cmListFileParser::ParseFile()
{
haveNewline = true;
}
else if(token->type == cmListFileLexer_Token_CommentBracket)
{
haveNewline = false;
}
else if(token->type == cmListFileLexer_Token_Identifier)
{
if(haveNewline)
@@ -301,7 +305,10 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
{
parenDepth++;
this->Separation = SeparationOkay;
this->AddArgument(token, cmListFileArgument::Unquoted);
if(!this->AddArgument(token, cmListFileArgument::Unquoted))
{
return false;
}
}
else if(token->type == cmListFileLexer_Token_ParenRight)
{
@@ -311,20 +318,41 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
}
parenDepth--;
this->Separation = SeparationOkay;
this->AddArgument(token, cmListFileArgument::Unquoted);
if(!this->AddArgument(token, cmListFileArgument::Unquoted))
{
return false;
}
this->Separation = SeparationWarning;
}
else if(token->type == cmListFileLexer_Token_Identifier ||
token->type == cmListFileLexer_Token_ArgumentUnquoted)
{
this->AddArgument(token, cmListFileArgument::Unquoted);
if(!this->AddArgument(token, cmListFileArgument::Unquoted))
{
return false;
}
this->Separation = SeparationWarning;
}
else if(token->type == cmListFileLexer_Token_ArgumentQuoted)
{
this->AddArgument(token, cmListFileArgument::Quoted);
if(!this->AddArgument(token, cmListFileArgument::Quoted))
{
return false;
}
this->Separation = SeparationWarning;
}
else if(token->type == cmListFileLexer_Token_ArgumentBracket)
{
if(!this->AddArgument(token, cmListFileArgument::Bracket))
{
return false;
}
this->Separation = SeparationError;
}
else if(token->type == cmListFileLexer_Token_CommentBracket)
{
this->Separation = SeparationError;
}
else
{
// Error.
@@ -351,42 +379,32 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
}
//----------------------------------------------------------------------------
void cmListFileParser::AddArgument(cmListFileLexer_Token* token,
bool cmListFileParser::AddArgument(cmListFileLexer_Token* token,
cmListFileArgument::Delimiter delim)
{
cmListFileArgument a(token->text, delim, this->FileName, token->line);
this->Function.Arguments.push_back(a);
if(delim == cmListFileArgument::Unquoted)
{
// Warn about a future behavior change.
const char* c = a.Value.c_str();
if(*c++ == '[')
{
while(*c == '=')
{ ++c; }
if(*c == '[')
{
cmOStringStream m;
m << "Syntax Warning in cmake code at\n"
<< " " << this->FileName << ":" << token->line << ":"
<< token->column << "\n"
<< "A future version of CMake may treat unquoted argument:\n"
<< " " << a.Value << "\n"
<< "as an opening long bracket. Double-quote the argument.";
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str().c_str());
}
}
}
if(this->Separation == SeparationOkay)
{
return;
return true;
}
bool isError = (this->Separation == SeparationError ||
delim == cmListFileArgument::Bracket);
cmOStringStream m;
m << "Syntax Warning in cmake code at\n"
m << "Syntax " << (isError? "Error":"Warning") << " in cmake code at\n"
<< " " << this->FileName << ":" << token->line << ":"
<< token->column << "\n"
<< "Argument not separated from preceding token by whitespace.";
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str().c_str());
if(isError)
{
this->Makefile->IssueMessage(cmake::FATAL_ERROR, m.str().c_str());
return false;
}
else
{
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str().c_str());
return true;
}
}
//----------------------------------------------------------------------------