summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx25
-rw-r--r--Source/cmCommandArgumentParserHelper.h1
-rw-r--r--Source/cmMakefile.cxx62
-rw-r--r--Source/cmPolicies.cxx12
-rw-r--r--Source/cmPolicies.h1
5 files changed, 79 insertions, 22 deletions
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index f1efa68..2aa6c0c 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -87,8 +87,10 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key,
}
return this->EmptyVariable;
}
- cmSystemTools::Error("Key ", key,
- " is not used yet. For now only $ENV{..} is allowed");
+ cmOStringStream e;
+ e << "Syntax $" << key << "{} is not supported. "
+ << "Only ${} and ENV{} are allowed.";
+ this->SetError(e.str());
return 0;
}
@@ -216,10 +218,11 @@ bool cmCommandArgumentParserHelper::HandleEscapeSymbol
this->AllocateParserType(pt, "\0", 1);
break;
default:
- char buffer[2];
- buffer[0] = symbol;
- buffer[1] = 0;
- cmSystemTools::Error("Invalid escape sequence \\", buffer);
+ {
+ cmOStringStream e;
+ e << "Invalid escape sequence \\" << symbol;
+ this->SetError(e.str());
+ }
return false;
}
return true;
@@ -300,7 +303,7 @@ void cmCommandArgumentParserHelper::Error(const char* str)
unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
cmOStringStream ostr;
ostr << str << " (" << pos << ")";
- this->ErrorString = ostr.str();
+ this->SetError(ostr.str());
}
void cmCommandArgumentParserHelper::SetMakefile(const cmMakefile* mf)
@@ -318,3 +321,11 @@ void cmCommandArgumentParserHelper::SetResult(const char* value)
this->Result = value;
}
+void cmCommandArgumentParserHelper::SetError(std::string const& msg)
+{
+ // Keep only the first error.
+ if(this->ErrorString.empty())
+ {
+ this->ErrorString = msg;
+ }
+}
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
index c5cfc1e..5652ccc 100644
--- a/Source/cmCommandArgumentParserHelper.h
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -95,6 +95,7 @@ private:
char* AddString(const char* str);
void CleanupParser();
+ void SetError(std::string const& msg);
std::vector<char*> Variables;
const cmMakefile* Makefile;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index a251462..8456d58 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -2168,28 +2168,60 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
parser.SetReplaceAtSyntax(replaceAt);
parser.SetRemoveEmpty(removeEmpty);
int res = parser.ParseString(source.c_str(), 0);
- if ( res )
+ const char* emsg = parser.GetError();
+ if ( res && !emsg[0] )
{
source = parser.GetResult();
}
else
{
+ // Construct the main error message.
cmOStringStream error;
- error << "Syntax error in cmake code at\n"
- << (filename?filename:"(no filename given)")
- << ":" << line << ":\n"
- << parser.GetError() << ", when parsing string \""
- << source.c_str() << "\"";
- if(this->NeedBackwardsCompatibility(2,0))
- {
- cmSystemTools::Error(error.str().c_str());
- cmSystemTools::SetFatalErrorOccured();
- return source.c_str();
- }
- else
- {
- cmSystemTools::Message(error.str().c_str());
+ error << "Syntax error in cmake code ";
+ if(filename && line > 0)
+ {
+ // This filename and line number may be more specific than the
+ // command context because one command invocation can have
+ // arguments on multiple lines.
+ error << "at\n"
+ << " " << filename << ":" << line << "\n";
+ }
+ error << "when parsing string\n"
+ << " " << source.c_str() << "\n";
+ error << emsg;
+
+ // If the parser failed ("res" is false) then this is a real
+ // argument parsing error, so the policy applies. Otherwise the
+ // parser reported an error message without failing because the
+ // helper implementation is unhappy, which has always reported an
+ // error.
+ cmake::MessageType mtype = cmake::FATAL_ERROR;
+ if(!res)
+ {
+ // This is a real argument parsing error. Use policy CMP0010 to
+ // decide whether it is an error.
+ switch(this->GetPolicyStatus(cmPolicies::CMP0010))
+ {
+ case cmPolicies::WARN:
+ error << "\n"
+ << (this->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0010));
+ case cmPolicies::OLD:
+ // OLD behavior is to just warn and continue.
+ mtype = cmake::AUTHOR_WARNING;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ error << "\n"
+ << (this->GetPolicies()
+ ->GetRequiredPolicyError(cmPolicies::CMP0010));
+ case cmPolicies::NEW:
+ // NEW behavior is to report the error.
+ cmSystemTools::SetFatalErrorOccured();
+ break;
+ }
}
+ this->IssueMessage(mtype, error.str());
}
return source.c_str();
}
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 5d8c71f..be546f8 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -323,6 +323,18 @@ cmPolicies::cmPolicies()
"by default, but only if FOLLOW_SYMLINKS is given as an additional "
"argument to the FILE command.",
2,6,2, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0010, "CMP0010",
+ "Bad variable reference syntax is an error.",
+ "In CMake 2.6.2 and below, incorrect variable reference syntax such as "
+ "a missing close-brace (\"${FOO\") was reported but did not stop "
+ "processing of CMake code. "
+ "This policy determines whether a bad variable reference is an error. "
+ "The OLD behavior for this policy is to warn about the error, leave "
+ "the string untouched, and continue. "
+ "The NEW behavior for this policy is to report an error.",
+ 2,6,3, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 06079b0..02f7276 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -50,6 +50,7 @@ public:
CMP0007, // list command handling of empty elements
CMP0008, // Full-path libraries must be a valid library file name
CMP0009, // GLOB_RECURSE should not follow symlinks by default
+ CMP0010, // Bad variable reference syntax is an error
// Always the last entry. Useful mostly to avoid adding a comma
// the last policy when adding a new one.