From 621c1e59c65cd63288cd3aa926ff18ef0fe97357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 11 Nov 2016 16:22:14 +0100 Subject: [PATCH] --project: handle SolutionDir and ProjectDir. This is a partial fix for #7791. custom build macros are still not handled. --- lib/importproject.cpp | 34 ++++++++++++++++++++++++++-------- lib/importproject.h | 5 +++-- test/testimportproject.cpp | 19 ++++++++++++++++--- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/lib/importproject.cpp b/lib/importproject.cpp index b2507268b..6a5e29a9b 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -23,7 +23,6 @@ #include "token.h" #include "tinyxml2.h" #include -#include //#include void ImportProject::ignorePaths(std::vector &ipaths) @@ -92,7 +91,7 @@ void ImportProject::FileSettings::setDefines(std::string defs) defines.swap(defs); } -void ImportProject::FileSettings::setIncludePaths(const std::string &basepath, const std::list &in) +void ImportProject::FileSettings::setIncludePaths(const std::string &basepath, const std::list &in, const std::map &variables) { std::list I; for (std::list::const_iterator it = in.begin(); it != in.end(); ++it) { @@ -107,9 +106,22 @@ void ImportProject::FileSettings::setIncludePaths(const std::string &basepath, c I.push_back(s); continue; } + if (s[s.size()-1U] == '/') // this is a temporary hack, simplifyPath can crash if path ends with '/' s.erase(s.size() - 1U); - s = Path::simplifyPath(basepath + s); + + if (s.compare(0,2,"$(")==0) { + std::string::size_type end = s.find(")"); + if (end == std::string::npos) + continue; + const std::string &var = s.substr(2,end-2); + std::map::const_iterator it1 = variables.find(var); + if (it1 == variables.end()) + continue; + s = Path::simplifyPath(it1->second + s.substr(end+1)); + } else { + s = Path::simplifyPath(basepath + s); + } if (s.empty()) continue; I.push_back(s + '/'); @@ -130,7 +142,8 @@ void ImportProject::import(const std::string &filename) path += '/'; importSln(fin,path); } else if (filename.find(".vcxproj") != std::string::npos) { - importVcxproj(filename); + std::map variables; + importVcxproj(filename, variables); } } @@ -180,7 +193,8 @@ void ImportProject::importCompileCommands(std::istream &istr) else if (F=='I') fs.includePaths.push_back(fval); } - fs.setIncludePaths(directory, fs.includePaths); + std::map variables; + fs.setIncludePaths(directory, fs.includePaths, variables); fs.setDefines(fs.defines); fileSettings.push_back(fs); } @@ -191,6 +205,8 @@ void ImportProject::importCompileCommands(std::istream &istr) void ImportProject::importSln(std::istream &istr, const std::string &path) { + std::map variables; + variables["SolutionDir"] = path; std::string line; while (std::getline(istr,line)) { if (line.compare(0,8,"Project(")!=0) @@ -203,7 +219,7 @@ void ImportProject::importSln(std::istream &istr, const std::string &path) continue; const std::string vcxproj(line.substr(pos1+1, pos-pos1+7)); //std::cout << "Importing " << vcxproj << "..." << std::endl; - importVcxproj(path + Path::fromNativeSeparators(vcxproj)); + importVcxproj(path + Path::fromNativeSeparators(vcxproj), variables); } } @@ -296,8 +312,10 @@ static std::list toStringList(const std::string &s) return ret; } -void ImportProject::importVcxproj(const std::string &filename) +void ImportProject::importVcxproj(const std::string &filename, std::map variables) { + variables["ProjectDir"] = Path::getPathFromFilename(filename); + std::list projectConfigurationList; std::list compileList; std::list itemDefinitionGroupList; @@ -352,7 +370,7 @@ void ImportProject::importVcxproj(const std::string &filename) if (useOfMfc) fs.defines += ";__AFXWIN_H__"; fs.setDefines(fs.defines); - fs.setIncludePaths(Path::getPathFromFilename(filename), toStringList(i->additionalIncludePaths)); + fs.setIncludePaths(Path::getPathFromFilename(filename), toStringList(i->additionalIncludePaths), variables); fileSettings.push_back(fs); } } diff --git a/lib/importproject.h b/lib/importproject.h index 48e795c56..bf33f99c7 100644 --- a/lib/importproject.h +++ b/lib/importproject.h @@ -22,6 +22,7 @@ //--------------------------------------------------------------------------- #include +#include #include #include #include @@ -47,7 +48,7 @@ public: cppcheck::Platform::PlatformType platformType; void setDefines(std::string defs); - void setIncludePaths(const std::string &basepath, const std::list &in); + void setIncludePaths(const std::string &basepath, const std::list &in, const std::map &variables); }; std::list fileSettings; @@ -59,7 +60,7 @@ public: private: void importCompileCommands(std::istream &istr); void importSln(std::istream &istr, const std::string &path); - void importVcxproj(const std::string &filename); + void importVcxproj(const std::string &filename, std::map variables); }; /// @} diff --git a/test/testimportproject.cpp b/test/testimportproject.cpp index 9a1119b77..3fad76c88 100644 --- a/test/testimportproject.cpp +++ b/test/testimportproject.cpp @@ -29,7 +29,8 @@ private: void run() { TEST_CASE(setDefines); - TEST_CASE(setIncludePaths); + TEST_CASE(setIncludePaths1); + TEST_CASE(setIncludePaths2); } void setDefines() { @@ -48,14 +49,26 @@ private: ASSERT_EQUALS("A=1;B=1", fs.defines); } - void setIncludePaths() { + void setIncludePaths1() { ImportProject::FileSettings fs; std::list in; in.push_back("../include"); - fs.setIncludePaths("abc/def/", in); + std::map variables; + fs.setIncludePaths("abc/def/", in, variables); ASSERT_EQUALS(1U, fs.includePaths.size()); ASSERT_EQUALS("abc/include/", fs.includePaths.front()); } + + void setIncludePaths2() { + ImportProject::FileSettings fs; + std::list in; + in.push_back("$(SolutionDir)other"); + std::map variables; + variables["SolutionDir"] = "c:/abc/"; + fs.setIncludePaths("/home/fred", in, variables); + ASSERT_EQUALS(1U, fs.includePaths.size()); + ASSERT_EQUALS("c:/abc/other/", fs.includePaths.front()); + } }; REGISTER_TEST(TestImportProject)