Commit 54541bd4 authored by Brad King's avatar Brad King
Browse files

ENH: Improved filename/line number reporting in error message. Macro...

ENH: Improved filename/line number reporting in error message.  Macro invocations now chain up the error message.
parent fe26cf51
...@@ -97,7 +97,7 @@ bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand) ...@@ -97,7 +97,7 @@ bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand)
{ {
cmListFileFunction inFunction; cmListFileFunction inFunction;
if(cmListFileCache::ParseFunction(fin, inFunction, path, parseError, if(cmListFileCache::ParseFunction(fin, inFunction, path, parseError,
&line)) line))
{ {
inFunction.m_FilePath = path; inFunction.m_FilePath = path;
inFile.m_Functions.push_back(inFunction); inFile.m_Functions.push_back(inFunction);
...@@ -162,7 +162,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, ...@@ -162,7 +162,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
cmListFileFunction& function, cmListFileFunction& function,
const char* filename, const char* filename,
bool& parseError, bool& parseError,
long* line) long& line)
{ {
parseError = false; parseError = false;
std::string& name = function.m_Name; std::string& name = function.m_Name;
...@@ -177,7 +177,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, ...@@ -177,7 +177,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
} }
if(fin.getline(inbuffer, BUFFER_SIZE ) ) if(fin.getline(inbuffer, BUFFER_SIZE ) )
{ {
if(line) { ++*line; } ++line;
RemoveComments(inbuffer); RemoveComments(inbuffer);
cmRegularExpression blankLine("^[ \t\r]*$"); cmRegularExpression blankLine("^[ \t\r]*$");
cmRegularExpression oneLiner("^[ \t]*([A-Za-z_0-9]*)[ \t]*\\((.*)\\)[ \t\r]*$"); cmRegularExpression oneLiner("^[ \t]*([A-Za-z_0-9]*)[ \t]*\\((.*)\\)[ \t\r]*$");
...@@ -197,10 +197,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, ...@@ -197,10 +197,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
name = oneLiner.match(1); name = oneLiner.match(1);
// break up the arguments // break up the arguments
cmListFileCache::GetArguments(args, arguments); cmListFileCache::GetArguments(args, arguments);
if(line) function.m_Line = line;
{
function.m_Line = *line;
}
return true; return true;
} }
// look for a start of a multiline with no trailing ")" fun(arg arg2 // look for a start of a multiline with no trailing ")" fun(arg arg2
...@@ -209,10 +206,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, ...@@ -209,10 +206,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
name = multiLine.match(1); name = multiLine.match(1);
std::string args = multiLine.match(2); std::string args = multiLine.match(2);
cmListFileCache::GetArguments(args, arguments); cmListFileCache::GetArguments(args, arguments);
if(line) function.m_Line = line;
{
function.m_Line = *line;
}
// Read lines until the closing paren is hit // Read lines until the closing paren is hit
bool done = false; bool done = false;
while(!done) while(!done)
...@@ -220,7 +214,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, ...@@ -220,7 +214,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
// read lines until the end paren is found // read lines until the end paren is found
if(fin.getline(inbuffer, BUFFER_SIZE ) ) if(fin.getline(inbuffer, BUFFER_SIZE ) )
{ {
if(line) { ++*line; } ++line;
RemoveComments(inbuffer); RemoveComments(inbuffer);
// Check for comment lines and ignore them. // Check for comment lines and ignore them.
if(blankLine.find(inbuffer)) if(blankLine.find(inbuffer))
...@@ -234,15 +228,18 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, ...@@ -234,15 +228,18 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
} }
else else
{ {
std::string line = inbuffer; std::string lineB = inbuffer;
cmListFileCache::GetArguments(line, arguments); cmListFileCache::GetArguments(lineB, arguments);
} }
} }
else else
{ {
parseError = true; parseError = true;
cmSystemTools::Error("Parse error in read function missing end )\nIn File: ", cmOStringStream error;
filename, "\nCurrent line:", inbuffer); error << "Error in cmake code at\n"
<< filename << ":" << line << ":\n"
<< "Parse error. Function missing ending \")\".";
cmSystemTools::Error(error.str().c_str());
return false; return false;
} }
} }
...@@ -251,8 +248,11 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, ...@@ -251,8 +248,11 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
else else
{ {
parseError = true; parseError = true;
cmSystemTools::Error("Parse error in read function\nIn file:", cmOStringStream error;
filename, "\nCurrent line:", inbuffer); error << "Error in cmake code at\n"
<< filename << ":" << line << ":\n"
<< "Parse error.";
cmSystemTools::Error(error.str().c_str());
return false; return false;
} }
} }
......
...@@ -84,7 +84,7 @@ public: ...@@ -84,7 +84,7 @@ public:
*/ */
static bool ParseFunction(std::ifstream&, cmListFileFunction& function, static bool ParseFunction(std::ifstream&, cmListFileFunction& function,
const char* filename, bool& parseError, const char* filename, bool& parseError,
long* line = 0); long& line);
/** /**
* Extract white-space separated arguments from a string. * Extract white-space separated arguments from a string.
......
...@@ -59,6 +59,8 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) ...@@ -59,6 +59,8 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
// Replace the formal arguments and then invoke the command. // Replace the formal arguments and then invoke the command.
cmListFileFunction newLFF; cmListFileFunction newLFF;
newLFF.m_Name = m_Functions[c].m_Name; newLFF.m_Name = m_Functions[c].m_Name;
newLFF.m_FilePath = m_Functions[c].m_FilePath;
newLFF.m_Line = m_Functions[c].m_Line;
for (std::vector<cmListFileArgument>::const_iterator k = for (std::vector<cmListFileArgument>::const_iterator k =
m_Functions[c].m_Arguments.begin(); m_Functions[c].m_Arguments.begin();
k != m_Functions[c].m_Arguments.end(); ++k) k != m_Functions[c].m_Arguments.end(); ++k)
...@@ -74,10 +76,16 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) ...@@ -74,10 +76,16 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
} }
cmListFileArgument arg(tmps, k->Quoted); cmListFileArgument arg(tmps, k->Quoted);
newLFF.m_Arguments.push_back(arg); newLFF.m_Arguments.push_back(arg);
newLFF.m_FilePath = m_Functions[c].m_FilePath;
newLFF.m_Line = m_Functions[c].m_Line;
} }
mf.ExecuteCommand(newLFF); if(!mf.ExecuteCommand(newLFF))
{
cmOStringStream error;
error << "Error in cmake code at\n"
<< lff.m_FilePath << ":" << lff.m_Line << ":\n"
<< "A command failed during the invocation of macro \""
<< lff.m_Name.c_str() << "\".";
cmSystemTools::Error(error.str().c_str());
}
} }
return true; return true;
} }
......
...@@ -156,13 +156,15 @@ bool cmMakefile::CommandExists(const char* name) const ...@@ -156,13 +156,15 @@ bool cmMakefile::CommandExists(const char* name) const
{ {
return m_LocalGenerator->GetGlobalGenerator()->GetCMakeInstance()->CommandExists(name); return m_LocalGenerator->GetGlobalGenerator()->GetCMakeInstance()->CommandExists(name);
} }
void cmMakefile::ExecuteCommand(const cmListFileFunction& lff) bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff)
{ {
bool result = true;
// quick return if blocked // quick return if blocked
if(this->IsFunctionBlocked(lff)) if(this->IsFunctionBlocked(lff))
{ {
return; // No error.
return result;
} }
std::string name = lff.m_Name; std::string name = lff.m_Name;
// execute the command // execute the command
...@@ -186,6 +188,7 @@ void cmMakefile::ExecuteCommand(const cmListFileFunction& lff) ...@@ -186,6 +188,7 @@ void cmMakefile::ExecuteCommand(const cmListFileFunction& lff)
<< lff.m_FilePath << ":" << lff.m_Line << ":\n" << lff.m_FilePath << ":" << lff.m_Line << ":\n"
<< usedCommand->GetError(); << usedCommand->GetError();
cmSystemTools::Error(error.str().c_str()); cmSystemTools::Error(error.str().c_str());
result = false;
} }
else else
{ {
...@@ -209,7 +212,10 @@ void cmMakefile::ExecuteCommand(const cmListFileFunction& lff) ...@@ -209,7 +212,10 @@ void cmMakefile::ExecuteCommand(const cmListFileFunction& lff)
<< lff.m_FilePath << ":" << lff.m_Line << ":\n" << lff.m_FilePath << ":" << lff.m_Line << ":\n"
<< "Unknown CMake command \"" << lff.m_Name.c_str() << "\"."; << "Unknown CMake command \"" << lff.m_Name.c_str() << "\".";
cmSystemTools::Error(error.str().c_str()); cmSystemTools::Error(error.str().c_str());
result = false;
} }
return result;
} }
// Parse the given CMakeLists.txt file into a list of classes. // Parse the given CMakeLists.txt file into a list of classes.
......
...@@ -510,9 +510,10 @@ public: ...@@ -510,9 +510,10 @@ public:
cmData* LookupData(const char*) const; cmData* LookupData(const char*) const;
/** /**
* execute a single CMake command * Execute a single CMake command. Returns true if the command
* succeeded or false if it failed.
*/ */
void ExecuteCommand(const cmListFileFunction& lff); bool ExecuteCommand(const cmListFileFunction& lff);
/** Check if a command exists. */ /** Check if a command exists. */
bool CommandExists(const char* name) const; bool CommandExists(const char* name) const;
......
...@@ -1102,6 +1102,7 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed, ...@@ -1102,6 +1102,7 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed,
} }
int firstTest = 1; int firstTest = 1;
long line = 0;
std::string name; std::string name;
std::vector<std::string> args; std::vector<std::string> args;
...@@ -1113,7 +1114,8 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed, ...@@ -1113,7 +1114,8 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed,
while ( fin ) while ( fin )
{ {
cmListFileFunction lff; cmListFileFunction lff;
if(cmListFileCache::ParseFunction(fin, lff, "DartTestfile.txt", parseError)) if(cmListFileCache::ParseFunction(fin, lff, "DartTestfile.txt",
parseError, line))
{ {
const std::string& name = lff.m_Name; const std::string& name = lff.m_Name;
const std::vector<cmListFileArgument>& args = lff.m_Arguments; const std::vector<cmListFileArgument>& args = lff.m_Arguments;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment