diff options
Diffstat (limited to 'Source/cmVisualStudioSlnParser.cxx')
-rw-r--r-- | Source/cmVisualStudioSlnParser.cxx | 362 |
1 files changed, 159 insertions, 203 deletions
diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx index 2bbea55..7d7bb5b 100644 --- a/Source/cmVisualStudioSlnParser.cxx +++ b/Source/cmVisualStudioSlnParser.cxx @@ -18,15 +18,14 @@ #include <cassert> #include <stack> -namespace +namespace { +enum LineFormat { - enum LineFormat - { - LineMultiValueTag, - LineSingleValueTag, - LineKeyValuePair, - LineVerbatim - }; + LineMultiValueTag, + LineSingleValueTag, + LineKeyValuePair, + LineVerbatim +}; } class cmVisualStudioSlnParser::ParsedLine @@ -45,11 +44,17 @@ public: void SetTag(const std::string& tag) { this->Tag = tag; } void SetArg(const std::string& arg) { this->Arg = StringData(arg, false); } void SetQuotedArg(const std::string& arg) - { this->Arg = StringData(arg, true); } + { + this->Arg = StringData(arg, true); + } void AddValue(const std::string& value) - { this->Values.push_back(StringData(value, false)); } + { + this->Values.push_back(StringData(value, false)); + } void AddQuotedValue(const std::string& value) - { this->Values.push_back(StringData(value, true)); } + { + this->Values.push_back(StringData(value, true)); + } void CopyVerbatim(const std::string& line) { this->Tag = line; } @@ -68,7 +73,7 @@ const std::string cmVisualStudioSlnParser::ParsedLine::Quote("\""); bool cmVisualStudioSlnParser::ParsedLine::IsComment() const { assert(!this->Tag.empty()); - return (this->Tag[0]== '#'); + return (this->Tag[0] == '#'); } bool cmVisualStudioSlnParser::ParsedLine::IsKeyValuePair() const @@ -85,8 +90,8 @@ std::string cmVisualStudioSlnParser::ParsedLine::GetArgVerbatim() const return this->Arg.first; } -const std::string& -cmVisualStudioSlnParser::ParsedLine::GetValue(size_t idxValue) const +const std::string& cmVisualStudioSlnParser::ParsedLine::GetValue( + size_t idxValue) const { if (idxValue < this->Values.size()) return this->Values[idxValue].first; @@ -94,18 +99,16 @@ cmVisualStudioSlnParser::ParsedLine::GetValue(size_t idxValue) const return BadString; } -std::string -cmVisualStudioSlnParser::ParsedLine::GetValueVerbatim(size_t idxValue) const +std::string cmVisualStudioSlnParser::ParsedLine::GetValueVerbatim( + size_t idxValue) const { - if (idxValue < this->Values.size()) - { + if (idxValue < this->Values.size()) { const StringData& data = this->Values[idxValue]; if (data.second) return Quote + data.first + Quote; else return data.first; - } - else + } else return BadString; } @@ -120,8 +123,7 @@ public: LineFormat NextLineFormat() const; bool Process(const cmVisualStudioSlnParser::ParsedLine& line, - cmSlnData& output, - cmVisualStudioSlnParser::ResultData& result); + cmSlnData& output, cmVisualStudioSlnParser::ResultData& result); bool Finished(cmVisualStudioSlnParser::ResultData& result); @@ -147,9 +149,9 @@ private: void IgnoreUntilTag(const std::string& endTag); }; -cmVisualStudioSlnParser::State::State(DataGroupSet requestedData) : - RequestedData(requestedData), - CurrentLine(0) +cmVisualStudioSlnParser::State::State(DataGroupSet requestedData) + : RequestedData(requestedData) + , CurrentLine(0) { if (this->RequestedData.test(DataGroupProjectDependenciesBit)) this->RequestedData.set(DataGroupProjectsBit); @@ -165,92 +167,86 @@ bool cmVisualStudioSlnParser::State::ReadLine(std::istream& input, LineFormat cmVisualStudioSlnParser::State::NextLineFormat() const { - switch (this->Stack.top()) - { - case FileStateStart: return LineVerbatim; - case FileStateTopLevel: return LineMultiValueTag; - case FileStateProject: return LineSingleValueTag; - case FileStateProjectDependencies: return LineKeyValuePair; - case FileStateGlobal: return LineSingleValueTag; - case FileStateSolutionConfigurations: return LineKeyValuePair; - case FileStateProjectConfigurations: return LineKeyValuePair; - case FileStateSolutionFilters: return LineKeyValuePair; - case FileStateGlobalSection: return LineKeyValuePair; - case FileStateIgnore: return LineVerbatim; + switch (this->Stack.top()) { + case FileStateStart: + return LineVerbatim; + case FileStateTopLevel: + return LineMultiValueTag; + case FileStateProject: + return LineSingleValueTag; + case FileStateProjectDependencies: + return LineKeyValuePair; + case FileStateGlobal: + return LineSingleValueTag; + case FileStateSolutionConfigurations: + return LineKeyValuePair; + case FileStateProjectConfigurations: + return LineKeyValuePair; + case FileStateSolutionFilters: + return LineKeyValuePair; + case FileStateGlobalSection: + return LineKeyValuePair; + case FileStateIgnore: + return LineVerbatim; default: assert(false); return LineVerbatim; - } + } } bool cmVisualStudioSlnParser::State::Process( - const cmVisualStudioSlnParser::ParsedLine& line, - cmSlnData& output, cmVisualStudioSlnParser::ResultData& result) + const cmVisualStudioSlnParser::ParsedLine& line, cmSlnData& output, + cmVisualStudioSlnParser::ResultData& result) { assert(!line.IsComment()); - switch (this->Stack.top()) - { + switch (this->Stack.top()) { case FileStateStart: if (!cmSystemTools::StringStartsWith( - line.GetTag().c_str(), "Microsoft Visual Studio Solution File")) - { + line.GetTag().c_str(), "Microsoft Visual Studio Solution File")) { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; - } + } this->Stack.pop(); this->Stack.push(FileStateTopLevel); break; case FileStateTopLevel: - if (line.GetTag().compare("Project") == 0) - { - if (line.GetValueCount() != 3) - { + if (line.GetTag().compare("Project") == 0) { + if (line.GetValueCount() != 3) { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; - } - if (this->RequestedData.test(DataGroupProjectsBit)) - { - if (!output.AddProject(line.GetValue(2), - line.GetValue(0), - line.GetValue(1))) - { + } + if (this->RequestedData.test(DataGroupProjectsBit)) { + if (!output.AddProject(line.GetValue(2), line.GetValue(0), + line.GetValue(1))) { result.SetError(ResultErrorInputData, this->GetCurrentLine()); return false; - } - this->Stack.push(FileStateProject); } - else + this->Stack.push(FileStateProject); + } else this->IgnoreUntilTag("EndProject"); - } - else if (line.GetTag().compare("Global") == 0) + } else if (line.GetTag().compare("Global") == 0) this->Stack.push(FileStateGlobal); - else - { + else { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; - } + } break; case FileStateProject: if (line.GetTag().compare("EndProject") == 0) this->Stack.pop(); - else if (line.GetTag().compare("ProjectSection") == 0) - { + else if (line.GetTag().compare("ProjectSection") == 0) { if (line.GetArg().compare("ProjectDependencies") == 0 && - line.GetValue(0).compare("postProject") == 0) - { + line.GetValue(0).compare("postProject") == 0) { if (this->RequestedData.test(DataGroupProjectDependenciesBit)) this->Stack.push(FileStateProjectDependencies); else this->IgnoreUntilTag("EndProjectSection"); - } - else + } else this->IgnoreUntilTag("EndProjectSection"); - } - else - { + } else { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; - } + } break; case FileStateProjectDependencies: if (line.GetTag().compare("EndProjectSection") == 0) @@ -258,51 +254,42 @@ bool cmVisualStudioSlnParser::State::Process( else if (line.IsKeyValuePair()) // implement dependency storing here, once needed ; - else - { + else { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; - } + } break; case FileStateGlobal: if (line.GetTag().compare("EndGlobal") == 0) this->Stack.pop(); - else if (line.GetTag().compare("GlobalSection") == 0) - { + else if (line.GetTag().compare("GlobalSection") == 0) { if (line.GetArg().compare("SolutionConfigurationPlatforms") == 0 && - line.GetValue(0).compare("preSolution") == 0) - { + line.GetValue(0).compare("preSolution") == 0) { if (this->RequestedData.test(DataGroupSolutionConfigurationsBit)) this->Stack.push(FileStateSolutionConfigurations); else this->IgnoreUntilTag("EndGlobalSection"); - } - else if (line.GetArg().compare("ProjectConfigurationPlatforms") == 0 && - line.GetValue(0).compare("postSolution") == 0) - { + } else if (line.GetArg().compare("ProjectConfigurationPlatforms") == + 0 && + line.GetValue(0).compare("postSolution") == 0) { if (this->RequestedData.test(DataGroupProjectConfigurationsBit)) this->Stack.push(FileStateProjectConfigurations); else this->IgnoreUntilTag("EndGlobalSection"); - } - else if (line.GetArg().compare("NestedProjects") == 0 && - line.GetValue(0).compare("preSolution") == 0) - { + } else if (line.GetArg().compare("NestedProjects") == 0 && + line.GetValue(0).compare("preSolution") == 0) { if (this->RequestedData.test(DataGroupSolutionFiltersBit)) this->Stack.push(FileStateSolutionFilters); else this->IgnoreUntilTag("EndGlobalSection"); - } - else if (this->RequestedData.test(DataGroupGenericGlobalSectionsBit)) + } else if (this->RequestedData.test(DataGroupGenericGlobalSectionsBit)) this->Stack.push(FileStateGlobalSection); else this->IgnoreUntilTag("EndGlobalSection"); - } - else - { + } else { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; - } + } break; case FileStateSolutionConfigurations: if (line.GetTag().compare("EndGlobalSection") == 0) @@ -310,11 +297,10 @@ bool cmVisualStudioSlnParser::State::Process( else if (line.IsKeyValuePair()) // implement configuration storing here, once needed ; - else - { + else { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; - } + } break; case FileStateProjectConfigurations: if (line.GetTag().compare("EndGlobalSection") == 0) @@ -322,11 +308,10 @@ bool cmVisualStudioSlnParser::State::Process( else if (line.IsKeyValuePair()) // implement configuration storing here, once needed ; - else - { + else { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; - } + } break; case FileStateSolutionFilters: if (line.GetTag().compare("EndGlobalSection") == 0) @@ -334,11 +319,10 @@ bool cmVisualStudioSlnParser::State::Process( else if (line.IsKeyValuePair()) // implement filter storing here, once needed ; - else - { + else { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; - } + } break; case FileStateGlobalSection: if (line.GetTag().compare("EndGlobalSection") == 0) @@ -346,34 +330,31 @@ bool cmVisualStudioSlnParser::State::Process( else if (line.IsKeyValuePair()) // implement section storing here, once needed ; - else - { + else { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; - } + } break; case FileStateIgnore: - if (line.GetTag() == this->EndIgnoreTag) - { + if (line.GetTag() == this->EndIgnoreTag) { this->Stack.pop(); this->EndIgnoreTag = ""; - } + } break; default: result.SetError(ResultErrorBadInternalState, this->GetCurrentLine()); return false; - } + } return true; } bool cmVisualStudioSlnParser::State::Finished( cmVisualStudioSlnParser::ResultData& result) { - if (this->Stack.top() != FileStateTopLevel) - { + if (this->Stack.top() != FileStateTopLevel) { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; - } + } result.Result = ResultOK; return true; } @@ -387,7 +368,8 @@ void cmVisualStudioSlnParser::State::IgnoreUntilTag(const std::string& endTag) cmVisualStudioSlnParser::ResultData::ResultData() : Result(ResultOK) , ResultLine(0) -{} +{ +} void cmVisualStudioSlnParser::ResultData::Clear() { @@ -402,42 +384,40 @@ void cmVisualStudioSlnParser::ResultData::SetError(ParseResult error, } const cmVisualStudioSlnParser::DataGroupSet -cmVisualStudioSlnParser::DataGroupProjects( - 1 << cmVisualStudioSlnParser::DataGroupProjectsBit); + cmVisualStudioSlnParser::DataGroupProjects( + 1 << cmVisualStudioSlnParser::DataGroupProjectsBit); const cmVisualStudioSlnParser::DataGroupSet -cmVisualStudioSlnParser::DataGroupProjectDependencies( - 1 << cmVisualStudioSlnParser::DataGroupProjectDependenciesBit); + cmVisualStudioSlnParser::DataGroupProjectDependencies( + 1 << cmVisualStudioSlnParser::DataGroupProjectDependenciesBit); const cmVisualStudioSlnParser::DataGroupSet -cmVisualStudioSlnParser::DataGroupSolutionConfigurations( - 1 << cmVisualStudioSlnParser::DataGroupSolutionConfigurationsBit); + cmVisualStudioSlnParser::DataGroupSolutionConfigurations( + 1 << cmVisualStudioSlnParser::DataGroupSolutionConfigurationsBit); const cmVisualStudioSlnParser::DataGroupSet -cmVisualStudioSlnParser::DataGroupProjectConfigurations( - 1 << cmVisualStudioSlnParser::DataGroupProjectConfigurationsBit); + cmVisualStudioSlnParser::DataGroupProjectConfigurations( + 1 << cmVisualStudioSlnParser::DataGroupProjectConfigurationsBit); const cmVisualStudioSlnParser::DataGroupSet -cmVisualStudioSlnParser::DataGroupSolutionFilters( - 1 << cmVisualStudioSlnParser::DataGroupSolutionFiltersBit); + cmVisualStudioSlnParser::DataGroupSolutionFilters( + 1 << cmVisualStudioSlnParser::DataGroupSolutionFiltersBit); const cmVisualStudioSlnParser::DataGroupSet -cmVisualStudioSlnParser::DataGroupGenericGlobalSections( - 1 << cmVisualStudioSlnParser::DataGroupGenericGlobalSectionsBit); + cmVisualStudioSlnParser::DataGroupGenericGlobalSections( + 1 << cmVisualStudioSlnParser::DataGroupGenericGlobalSectionsBit); const cmVisualStudioSlnParser::DataGroupSet -cmVisualStudioSlnParser::DataGroupAll(~0); + cmVisualStudioSlnParser::DataGroupAll(~0); -bool cmVisualStudioSlnParser::Parse(std::istream& input, - cmSlnData& output, +bool cmVisualStudioSlnParser::Parse(std::istream& input, cmSlnData& output, DataGroupSet dataGroups) { this->LastResult.Clear(); - if (!this->IsDataGroupSetSupported(dataGroups)) - { + if (!this->IsDataGroupSetSupported(dataGroups)) { this->LastResult.SetError(ResultErrorUnsupportedDataGroup, 0); return false; - } + } State state(dataGroups); return this->ParseImpl(input, output, state); } @@ -447,23 +427,21 @@ bool cmVisualStudioSlnParser::ParseFile(const std::string& file, DataGroupSet dataGroups) { this->LastResult.Clear(); - if (!this->IsDataGroupSetSupported(dataGroups)) - { + if (!this->IsDataGroupSetSupported(dataGroups)) { this->LastResult.SetError(ResultErrorUnsupportedDataGroup, 0); return false; - } + } cmsys::ifstream f(file.c_str()); - if (!f) - { + if (!f) { this->LastResult.SetError(ResultErrorOpeningInput, 0); return false; - } + } State state(dataGroups); return this->ParseImpl(f, output, state); } -cmVisualStudioSlnParser::ParseResult -cmVisualStudioSlnParser::GetParseResult() const +cmVisualStudioSlnParser::ParseResult cmVisualStudioSlnParser::GetParseResult() + const { return this->LastResult.Result; } @@ -478,29 +456,26 @@ bool cmVisualStudioSlnParser::GetParseHadBOM() const return this->LastResult.HadBOM; } -bool -cmVisualStudioSlnParser::IsDataGroupSetSupported(DataGroupSet dataGroups) const +bool cmVisualStudioSlnParser::IsDataGroupSetSupported( + DataGroupSet dataGroups) const { return (dataGroups & DataGroupProjects) == dataGroups; - //only supporting DataGroupProjects for now + // only supporting DataGroupProjects for now } -bool cmVisualStudioSlnParser::ParseImpl(std::istream& input, - cmSlnData& output, +bool cmVisualStudioSlnParser::ParseImpl(std::istream& input, cmSlnData& output, State& state) { std::string line; // Does the .sln start with a Byte Order Mark? if (!this->ParseBOM(input, line, state)) return false; - do - { + do { line = cmSystemTools::TrimWhitespace(line); if (line.empty()) continue; ParsedLine parsedLine; - switch (state.NextLineFormat()) - { + switch (state.NextLineFormat()) { case LineMultiValueTag: if (!this->ParseMultiValueTag(line, parsedLine, state)) return false; @@ -516,35 +491,31 @@ bool cmVisualStudioSlnParser::ParseImpl(std::istream& input, case LineVerbatim: parsedLine.CopyVerbatim(line); break; - } + } if (parsedLine.IsComment()) continue; if (!state.Process(parsedLine, output, this->LastResult)) return false; - } - while (state.ReadLine(input, line)); + } while (state.ReadLine(input, line)); return state.Finished(this->LastResult); } -bool cmVisualStudioSlnParser::ParseBOM(std::istream& input, - std::string& line, +bool cmVisualStudioSlnParser::ParseBOM(std::istream& input, std::string& line, State& state) { char bom[4]; - if (!input.get(bom, 4)) - { + if (!input.get(bom, 4)) { this->LastResult.SetError(ResultErrorReadingInput, 1); return false; - } + } this->LastResult.HadBOM = (bom[0] == char(0xEF) && bom[1] == char(0xBB) && bom[2] == char(0xBF)); - if (!state.ReadLine(input, line)) - { + if (!state.ReadLine(input, line)) { this->LastResult.SetError(ResultErrorReadingInput, 1); return false; - } + } if (!this->LastResult.HadBOM) - line = bom + line; // it wasn't a BOM, prepend it to first line + line = bom + line; // it wasn't a BOM, prepend it to first line return true; } @@ -556,45 +527,38 @@ bool cmVisualStudioSlnParser::ParseMultiValueTag(const std::string& line, const std::string& fullTag = line.substr(0, idxEqualSign); if (!this->ParseTag(fullTag, parsedLine, state)) return false; - if (idxEqualSign != line.npos) - { + if (idxEqualSign != line.npos) { size_t idxFieldStart = idxEqualSign + 1; - if (idxFieldStart < line.size()) - { + if (idxFieldStart < line.size()) { size_t idxParsing = idxFieldStart; bool inQuotes = false; - for (;;) - { + for (;;) { idxParsing = line.find_first_of(",\"", idxParsing); bool fieldOver = false; - if (idxParsing == line.npos) - { + if (idxParsing == line.npos) { fieldOver = true; - if (inQuotes) - { + if (inQuotes) { this->LastResult.SetError(ResultErrorInputStructure, state.GetCurrentLine()); return false; - } } - else if (line[idxParsing] == ',' && !inQuotes) + } else if (line[idxParsing] == ',' && !inQuotes) fieldOver = true; else if (line[idxParsing] == '"') inQuotes = !inQuotes; - if (fieldOver) - { - if (!this->ParseValue(line.substr(idxFieldStart, - idxParsing - idxFieldStart), - parsedLine)) + if (fieldOver) { + if (!this->ParseValue( + line.substr(idxFieldStart, idxParsing - idxFieldStart), + parsedLine)) return false; if (idxParsing == line.npos) - break; //end of last field + break; // end of last field idxFieldStart = idxParsing + 1; - } - ++idxParsing; } + ++idxParsing; } } + } return true; } @@ -606,11 +570,10 @@ bool cmVisualStudioSlnParser::ParseSingleValueTag(const std::string& line, const std::string& fullTag = line.substr(0, idxEqualSign); if (!this->ParseTag(fullTag, parsedLine, state)) return false; - if (idxEqualSign != line.npos) - { + if (idxEqualSign != line.npos) { if (!this->ParseValue(line.substr(idxEqualSign + 1), parsedLine)) return false; - } + } return true; } @@ -619,11 +582,10 @@ bool cmVisualStudioSlnParser::ParseKeyValuePair(const std::string& line, State& /*state*/) { size_t idxEqualSign = line.find('='); - if (idxEqualSign == line.npos) - { + if (idxEqualSign == line.npos) { parsedLine.CopyVerbatim(line); return true; - } + } const std::string& key = line.substr(0, idxEqualSign); parsedLine.SetTag(cmSystemTools::TrimWhitespace(key)); const std::string& value = line.substr(idxEqualSign + 1); @@ -632,37 +594,31 @@ bool cmVisualStudioSlnParser::ParseKeyValuePair(const std::string& line, } bool cmVisualStudioSlnParser::ParseTag(const std::string& fullTag, - ParsedLine& parsedLine, - State& state) + ParsedLine& parsedLine, State& state) { size_t idxLeftParen = fullTag.find('('); - if (idxLeftParen == fullTag.npos) - { + if (idxLeftParen == fullTag.npos) { parsedLine.SetTag(cmSystemTools::TrimWhitespace(fullTag)); return true; - } + } parsedLine.SetTag( cmSystemTools::TrimWhitespace(fullTag.substr(0, idxLeftParen))); size_t idxRightParen = fullTag.rfind(')'); - if (idxRightParen == fullTag.npos) - { + if (idxRightParen == fullTag.npos) { this->LastResult.SetError(ResultErrorInputStructure, state.GetCurrentLine()); return false; - } + } const std::string& arg = cmSystemTools::TrimWhitespace( fullTag.substr(idxLeftParen + 1, idxRightParen - idxLeftParen - 1)); - if (arg[0] == '"') - { - if (arg[arg.size() - 1] != '"') - { + if (arg[0] == '"') { + if (arg[arg.size() - 1] != '"') { this->LastResult.SetError(ResultErrorInputStructure, state.GetCurrentLine()); return false; - } - parsedLine.SetQuotedArg(arg.substr(1, arg.size() - 2)); } - else + parsedLine.SetQuotedArg(arg.substr(1, arg.size() - 2)); + } else parsedLine.SetArg(arg); return true; } |