--project: handle SolutionDir and ProjectDir. This is a partial fix for #7791. custom build macros are still not handled.

This commit is contained in:
Daniel Marjamäki 2016-11-11 16:22:14 +01:00
parent b04f6fb359
commit 621c1e59c6
3 changed files with 45 additions and 13 deletions

View File

@ -23,7 +23,6 @@
#include "token.h" #include "token.h"
#include "tinyxml2.h" #include "tinyxml2.h"
#include <fstream> #include <fstream>
#include <map>
//#include <iostream> //#include <iostream>
void ImportProject::ignorePaths(std::vector<std::string> &ipaths) void ImportProject::ignorePaths(std::vector<std::string> &ipaths)
@ -92,7 +91,7 @@ void ImportProject::FileSettings::setDefines(std::string defs)
defines.swap(defs); defines.swap(defs);
} }
void ImportProject::FileSettings::setIncludePaths(const std::string &basepath, const std::list<std::string> &in) void ImportProject::FileSettings::setIncludePaths(const std::string &basepath, const std::list<std::string> &in, const std::map<std::string, std::string> &variables)
{ {
std::list<std::string> I; std::list<std::string> I;
for (std::list<std::string>::const_iterator it = in.begin(); it != in.end(); ++it) { for (std::list<std::string>::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); I.push_back(s);
continue; continue;
} }
if (s[s.size()-1U] == '/') // this is a temporary hack, simplifyPath can crash if path ends with '/' if (s[s.size()-1U] == '/') // this is a temporary hack, simplifyPath can crash if path ends with '/'
s.erase(s.size() - 1U); 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<std::string, std::string>::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()) if (s.empty())
continue; continue;
I.push_back(s + '/'); I.push_back(s + '/');
@ -130,7 +142,8 @@ void ImportProject::import(const std::string &filename)
path += '/'; path += '/';
importSln(fin,path); importSln(fin,path);
} else if (filename.find(".vcxproj") != std::string::npos) { } else if (filename.find(".vcxproj") != std::string::npos) {
importVcxproj(filename); std::map<std::string, std::string> variables;
importVcxproj(filename, variables);
} }
} }
@ -180,7 +193,8 @@ void ImportProject::importCompileCommands(std::istream &istr)
else if (F=='I') else if (F=='I')
fs.includePaths.push_back(fval); fs.includePaths.push_back(fval);
} }
fs.setIncludePaths(directory, fs.includePaths); std::map<std::string, std::string> variables;
fs.setIncludePaths(directory, fs.includePaths, variables);
fs.setDefines(fs.defines); fs.setDefines(fs.defines);
fileSettings.push_back(fs); fileSettings.push_back(fs);
} }
@ -191,6 +205,8 @@ void ImportProject::importCompileCommands(std::istream &istr)
void ImportProject::importSln(std::istream &istr, const std::string &path) void ImportProject::importSln(std::istream &istr, const std::string &path)
{ {
std::map<std::string,std::string> variables;
variables["SolutionDir"] = path;
std::string line; std::string line;
while (std::getline(istr,line)) { while (std::getline(istr,line)) {
if (line.compare(0,8,"Project(")!=0) if (line.compare(0,8,"Project(")!=0)
@ -203,7 +219,7 @@ void ImportProject::importSln(std::istream &istr, const std::string &path)
continue; continue;
const std::string vcxproj(line.substr(pos1+1, pos-pos1+7)); const std::string vcxproj(line.substr(pos1+1, pos-pos1+7));
//std::cout << "Importing " << vcxproj << "..." << std::endl; //std::cout << "Importing " << vcxproj << "..." << std::endl;
importVcxproj(path + Path::fromNativeSeparators(vcxproj)); importVcxproj(path + Path::fromNativeSeparators(vcxproj), variables);
} }
} }
@ -296,8 +312,10 @@ static std::list<std::string> toStringList(const std::string &s)
return ret; return ret;
} }
void ImportProject::importVcxproj(const std::string &filename) void ImportProject::importVcxproj(const std::string &filename, std::map<std::string, std::string> variables)
{ {
variables["ProjectDir"] = Path::getPathFromFilename(filename);
std::list<ProjectConfiguration> projectConfigurationList; std::list<ProjectConfiguration> projectConfigurationList;
std::list<std::string> compileList; std::list<std::string> compileList;
std::list<ItemDefinitionGroup> itemDefinitionGroupList; std::list<ItemDefinitionGroup> itemDefinitionGroupList;
@ -352,7 +370,7 @@ void ImportProject::importVcxproj(const std::string &filename)
if (useOfMfc) if (useOfMfc)
fs.defines += ";__AFXWIN_H__"; fs.defines += ";__AFXWIN_H__";
fs.setDefines(fs.defines); 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); fileSettings.push_back(fs);
} }
} }

View File

@ -22,6 +22,7 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include <list> #include <list>
#include <map>
#include <string> #include <string>
#include <set> #include <set>
#include <vector> #include <vector>
@ -47,7 +48,7 @@ public:
cppcheck::Platform::PlatformType platformType; cppcheck::Platform::PlatformType platformType;
void setDefines(std::string defs); void setDefines(std::string defs);
void setIncludePaths(const std::string &basepath, const std::list<std::string> &in); void setIncludePaths(const std::string &basepath, const std::list<std::string> &in, const std::map<std::string, std::string> &variables);
}; };
std::list<FileSettings> fileSettings; std::list<FileSettings> fileSettings;
@ -59,7 +60,7 @@ public:
private: private:
void importCompileCommands(std::istream &istr); void importCompileCommands(std::istream &istr);
void importSln(std::istream &istr, const std::string &path); void importSln(std::istream &istr, const std::string &path);
void importVcxproj(const std::string &filename); void importVcxproj(const std::string &filename, std::map<std::string, std::string> variables);
}; };
/// @} /// @}

View File

@ -29,7 +29,8 @@ private:
void run() { void run() {
TEST_CASE(setDefines); TEST_CASE(setDefines);
TEST_CASE(setIncludePaths); TEST_CASE(setIncludePaths1);
TEST_CASE(setIncludePaths2);
} }
void setDefines() { void setDefines() {
@ -48,14 +49,26 @@ private:
ASSERT_EQUALS("A=1;B=1", fs.defines); ASSERT_EQUALS("A=1;B=1", fs.defines);
} }
void setIncludePaths() { void setIncludePaths1() {
ImportProject::FileSettings fs; ImportProject::FileSettings fs;
std::list<std::string> in; std::list<std::string> in;
in.push_back("../include"); in.push_back("../include");
fs.setIncludePaths("abc/def/", in); std::map<std::string, std::string> variables;
fs.setIncludePaths("abc/def/", in, variables);
ASSERT_EQUALS(1U, fs.includePaths.size()); ASSERT_EQUALS(1U, fs.includePaths.size());
ASSERT_EQUALS("abc/include/", fs.includePaths.front()); ASSERT_EQUALS("abc/include/", fs.includePaths.front());
} }
void setIncludePaths2() {
ImportProject::FileSettings fs;
std::list<std::string> in;
in.push_back("$(SolutionDir)other");
std::map<std::string, std::string> 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) REGISTER_TEST(TestImportProject)