Merge topic 'clean-up-Parser'

905e738f Parser: Out-of-line conditional code to cmMakefile
0a9094cd Parser: Issue file open error messages through dedicated API
This commit is contained in:
Brad King 2016-06-16 09:46:44 -04:00 committed by CMake Topic Stage
commit 2701b519b1
7 changed files with 90 additions and 102 deletions

View File

@ -23,6 +23,7 @@ struct cmListFileParser
{ {
cmListFileParser(cmListFile* lf, cmMakefile* mf, const char* filename); cmListFileParser(cmListFile* lf, cmMakefile* mf, const char* filename);
~cmListFileParser(); ~cmListFileParser();
void IssueFileOpenError(std::string const& text) const;
bool ParseFile(); bool ParseFile();
bool ParseFunction(const char* name, long line); bool ParseFunction(const char* name, long line);
bool AddArgument(cmListFileLexer_Token* token, bool AddArgument(cmListFileLexer_Token* token,
@ -54,23 +55,25 @@ cmListFileParser::~cmListFileParser()
cmListFileLexer_Delete(this->Lexer); cmListFileLexer_Delete(this->Lexer);
} }
void cmListFileParser::IssueFileOpenError(const std::string& text) const
{
this->Makefile->IssueMessage(cmake::FATAL_ERROR, text);
}
bool cmListFileParser::ParseFile() bool cmListFileParser::ParseFile()
{ {
// Open the file. // Open the file.
cmListFileLexer_BOM bom; cmListFileLexer_BOM bom;
if (!cmListFileLexer_SetFileName(this->Lexer, this->FileName, &bom)) { if (!cmListFileLexer_SetFileName(this->Lexer, this->FileName, &bom)) {
cmSystemTools::Error("cmListFileCache: error can not open file ", this->IssueFileOpenError("cmListFileCache: error can not open file.");
this->FileName);
return false; return false;
} }
// Verify the Byte-Order-Mark, if any. // Verify the Byte-Order-Mark, if any.
if (bom != cmListFileLexer_BOM_None && bom != cmListFileLexer_BOM_UTF8) { if (bom != cmListFileLexer_BOM_None && bom != cmListFileLexer_BOM_UTF8) {
cmListFileLexer_SetFileName(this->Lexer, 0, 0); cmListFileLexer_SetFileName(this->Lexer, 0, 0);
std::ostringstream m; this->IssueFileOpenError(
m << "File\n " << this->FileName << "\n" "File starts with a Byte-Order-Mark that is not UTF-8.");
<< "starts with a Byte-Order-Mark that is not UTF-8.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, m.str());
return false; return false;
} }
@ -115,7 +118,7 @@ bool cmListFileParser::ParseFile()
return true; return true;
} }
bool cmListFile::ParseFile(const char* filename, bool topLevel, cmMakefile* mf) bool cmListFile::ParseFile(const char* filename, cmMakefile* mf)
{ {
if (!cmSystemTools::FileExists(filename) || if (!cmSystemTools::FileExists(filename) ||
cmSystemTools::FileIsDirectory(filename)) { cmSystemTools::FileIsDirectory(filename)) {
@ -129,76 +132,6 @@ bool cmListFile::ParseFile(const char* filename, bool topLevel, cmMakefile* mf)
parseError = !parser.ParseFile(); parseError = !parser.ParseFile();
} }
// do we need a cmake_policy(VERSION call?
if (topLevel) {
bool hasVersion = false;
// search for the right policy command
for (std::vector<cmListFileFunction>::iterator i = this->Functions.begin();
i != this->Functions.end(); ++i) {
if (cmSystemTools::LowerCase(i->Name) == "cmake_minimum_required") {
hasVersion = true;
break;
}
}
// if no policy command is found this is an error if they use any
// non advanced functions or a lot of functions
if (!hasVersion) {
bool isProblem = true;
if (this->Functions.size() < 30) {
// the list of simple commands DO NOT ADD TO THIS LIST!!!!!
// these commands must have backwards compatibility forever and
// and that is a lot longer than your tiny mind can comprehend mortal
std::set<std::string> allowedCommands;
allowedCommands.insert("project");
allowedCommands.insert("set");
allowedCommands.insert("if");
allowedCommands.insert("endif");
allowedCommands.insert("else");
allowedCommands.insert("elseif");
allowedCommands.insert("add_executable");
allowedCommands.insert("add_library");
allowedCommands.insert("target_link_libraries");
allowedCommands.insert("option");
allowedCommands.insert("message");
isProblem = false;
for (std::vector<cmListFileFunction>::iterator i =
this->Functions.begin();
i != this->Functions.end(); ++i) {
std::string name = cmSystemTools::LowerCase(i->Name);
if (allowedCommands.find(name) == allowedCommands.end()) {
isProblem = true;
break;
}
}
}
if (isProblem) {
// Tell the top level cmMakefile to diagnose
// this violation of CMP0000.
mf->SetCheckCMP0000(true);
// Implicitly set the version for the user.
mf->SetPolicyVersion("2.4");
}
}
bool hasProject = false;
// search for a project command
for (std::vector<cmListFileFunction>::iterator i = this->Functions.begin();
i != this->Functions.end(); ++i) {
if (cmSystemTools::LowerCase(i->Name) == "project") {
hasProject = true;
break;
}
}
// if no project command is found, add one
if (!hasProject) {
cmListFileFunction project;
project.Name = "PROJECT";
cmListFileArgument prj("Project", cmListFileArgument::Unquoted, 0);
project.Arguments.push_back(prj);
this->Functions.insert(this->Functions.begin(), project);
}
}
return !parseError; return !parseError;
} }

View File

@ -158,7 +158,7 @@ private:
struct cmListFile struct cmListFile
{ {
bool ParseFile(const char* path, bool topLevel, cmMakefile* mf); bool ParseFile(const char* path, cmMakefile* mf);
std::vector<cmListFileFunction> Functions; std::vector<cmListFileFunction> Functions;
}; };

View File

@ -426,7 +426,7 @@ bool cmMakefile::ReadDependentFile(const char* filename, bool noPolicyScope)
IncludeScope incScope(this, filenametoread, noPolicyScope); IncludeScope incScope(this, filenametoread, noPolicyScope);
cmListFile listFile; cmListFile listFile;
if (!listFile.ParseFile(filenametoread.c_str(), false, this)) { if (!listFile.ParseFile(filenametoread.c_str(), this)) {
return false; return false;
} }
@ -475,7 +475,7 @@ bool cmMakefile::ReadListFile(const char* filename)
ListFileScope scope(this, filenametoread); ListFileScope scope(this, filenametoread);
cmListFile listFile; cmListFile listFile;
if (!listFile.ParseFile(filenametoread.c_str(), false, this)) { if (!listFile.ParseFile(filenametoread.c_str(), this)) {
return false; return false;
} }
@ -1423,10 +1423,81 @@ void cmMakefile::Configure()
this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart.c_str()); this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart.c_str());
cmListFile listFile; cmListFile listFile;
if (!listFile.ParseFile(currentStart.c_str(), this->IsRootMakefile(), if (!listFile.ParseFile(currentStart.c_str(), this)) {
this)) {
return; return;
} }
if (this->IsRootMakefile()) {
bool hasVersion = false;
// search for the right policy command
for (std::vector<cmListFileFunction>::iterator i =
listFile.Functions.begin();
i != listFile.Functions.end(); ++i) {
if (cmSystemTools::LowerCase(i->Name) == "cmake_minimum_required") {
hasVersion = true;
break;
}
}
// if no policy command is found this is an error if they use any
// non advanced functions or a lot of functions
if (!hasVersion) {
bool isProblem = true;
if (listFile.Functions.size() < 30) {
// the list of simple commands DO NOT ADD TO THIS LIST!!!!!
// these commands must have backwards compatibility forever and
// and that is a lot longer than your tiny mind can comprehend mortal
std::set<std::string> allowedCommands;
allowedCommands.insert("project");
allowedCommands.insert("set");
allowedCommands.insert("if");
allowedCommands.insert("endif");
allowedCommands.insert("else");
allowedCommands.insert("elseif");
allowedCommands.insert("add_executable");
allowedCommands.insert("add_library");
allowedCommands.insert("target_link_libraries");
allowedCommands.insert("option");
allowedCommands.insert("message");
isProblem = false;
for (std::vector<cmListFileFunction>::iterator i =
listFile.Functions.begin();
i != listFile.Functions.end(); ++i) {
std::string name = cmSystemTools::LowerCase(i->Name);
if (allowedCommands.find(name) == allowedCommands.end()) {
isProblem = true;
break;
}
}
}
if (isProblem) {
// Tell the top level cmMakefile to diagnose
// this violation of CMP0000.
this->SetCheckCMP0000(true);
// Implicitly set the version for the user.
this->SetPolicyVersion("2.4");
}
}
bool hasProject = false;
// search for a project command
for (std::vector<cmListFileFunction>::iterator i =
listFile.Functions.begin();
i != listFile.Functions.end(); ++i) {
if (cmSystemTools::LowerCase(i->Name) == "project") {
hasProject = true;
break;
}
}
// if no project command is found, add one
if (!hasProject) {
cmListFileFunction project;
project.Name = "PROJECT";
cmListFileArgument prj("Project", cmListFileArgument::Unquoted, 0);
project.Arguments.push_back(prj);
listFile.Functions.insert(listFile.Functions.begin(), project);
}
}
this->ReadListFile(listFile, currentStart); this->ReadListFile(listFile, currentStart);
if (cmSystemTools::GetFatalErrorOccured()) { if (cmSystemTools::GetFatalErrorOccured()) {
scope.Quiet(); scope.Quiet();

View File

@ -1,8 +1,4 @@
CMake Error in BOM-UTF-16-BE.cmake: CMake Error in BOM-UTF-16-BE.cmake:
File File starts with a Byte-Order-Mark that is not UTF-8.
.*/Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmake
starts with a Byte-Order-Mark that is not UTF-8.
Call Stack \(most recent call first\): Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\) CMakeLists.txt:3 \(include\)

View File

@ -1,8 +1,4 @@
CMake Error in BOM-UTF-16-LE.cmake: CMake Error in BOM-UTF-16-LE.cmake:
File File starts with a Byte-Order-Mark that is not UTF-8.
.*/Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmake
starts with a Byte-Order-Mark that is not UTF-8.
Call Stack \(most recent call first\): Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\) CMakeLists.txt:3 \(include\)

View File

@ -1,8 +1,4 @@
CMake Error in BOM-UTF-32-BE.cmake: CMake Error in BOM-UTF-32-BE.cmake:
File File starts with a Byte-Order-Mark that is not UTF-8.
.*/Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmake
starts with a Byte-Order-Mark that is not UTF-8.
Call Stack \(most recent call first\): Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\) CMakeLists.txt:3 \(include\)

View File

@ -1,8 +1,4 @@
CMake Error in BOM-UTF-32-LE.cmake: CMake Error in BOM-UTF-32-LE.cmake:
File File starts with a Byte-Order-Mark that is not UTF-8.
.*/Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmake
starts with a Byte-Order-Mark that is not UTF-8.
Call Stack \(most recent call first\): Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\) CMakeLists.txt:3 \(include\)