Skip to content

Commit 621c1e5

Browse files
committed
--project: handle SolutionDir and ProjectDir. This is a partial fix for cppcheck-opensource#7791. custom build macros are still not handled.
1 parent b04f6fb commit 621c1e5

3 files changed

Lines changed: 45 additions & 13 deletions

File tree

lib/importproject.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include "token.h"
2424
#include "tinyxml2.h"
2525
#include <fstream>
26-
#include <map>
2726
//#include <iostream>
2827

2928
void ImportProject::ignorePaths(std::vector<std::string> &ipaths)
@@ -92,7 +91,7 @@ void ImportProject::FileSettings::setDefines(std::string defs)
9291
defines.swap(defs);
9392
}
9493

95-
void ImportProject::FileSettings::setIncludePaths(const std::string &basepath, const std::list<std::string> &in)
94+
void ImportProject::FileSettings::setIncludePaths(const std::string &basepath, const std::list<std::string> &in, const std::map<std::string, std::string> &variables)
9695
{
9796
std::list<std::string> I;
9897
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
107106
I.push_back(s);
108107
continue;
109108
}
109+
110110
if (s[s.size()-1U] == '/') // this is a temporary hack, simplifyPath can crash if path ends with '/'
111111
s.erase(s.size() - 1U);
112-
s = Path::simplifyPath(basepath + s);
112+
113+
if (s.compare(0,2,"$(")==0) {
114+
std::string::size_type end = s.find(")");
115+
if (end == std::string::npos)
116+
continue;
117+
const std::string &var = s.substr(2,end-2);
118+
std::map<std::string, std::string>::const_iterator it1 = variables.find(var);
119+
if (it1 == variables.end())
120+
continue;
121+
s = Path::simplifyPath(it1->second + s.substr(end+1));
122+
} else {
123+
s = Path::simplifyPath(basepath + s);
124+
}
113125
if (s.empty())
114126
continue;
115127
I.push_back(s + '/');
@@ -130,7 +142,8 @@ void ImportProject::import(const std::string &filename)
130142
path += '/';
131143
importSln(fin,path);
132144
} else if (filename.find(".vcxproj") != std::string::npos) {
133-
importVcxproj(filename);
145+
std::map<std::string, std::string> variables;
146+
importVcxproj(filename, variables);
134147
}
135148
}
136149

@@ -180,7 +193,8 @@ void ImportProject::importCompileCommands(std::istream &istr)
180193
else if (F=='I')
181194
fs.includePaths.push_back(fval);
182195
}
183-
fs.setIncludePaths(directory, fs.includePaths);
196+
std::map<std::string, std::string> variables;
197+
fs.setIncludePaths(directory, fs.includePaths, variables);
184198
fs.setDefines(fs.defines);
185199
fileSettings.push_back(fs);
186200
}
@@ -191,6 +205,8 @@ void ImportProject::importCompileCommands(std::istream &istr)
191205

192206
void ImportProject::importSln(std::istream &istr, const std::string &path)
193207
{
208+
std::map<std::string,std::string> variables;
209+
variables["SolutionDir"] = path;
194210
std::string line;
195211
while (std::getline(istr,line)) {
196212
if (line.compare(0,8,"Project(")!=0)
@@ -203,7 +219,7 @@ void ImportProject::importSln(std::istream &istr, const std::string &path)
203219
continue;
204220
const std::string vcxproj(line.substr(pos1+1, pos-pos1+7));
205221
//std::cout << "Importing " << vcxproj << "..." << std::endl;
206-
importVcxproj(path + Path::fromNativeSeparators(vcxproj));
222+
importVcxproj(path + Path::fromNativeSeparators(vcxproj), variables);
207223
}
208224
}
209225

@@ -296,8 +312,10 @@ static std::list<std::string> toStringList(const std::string &s)
296312
return ret;
297313
}
298314

299-
void ImportProject::importVcxproj(const std::string &filename)
315+
void ImportProject::importVcxproj(const std::string &filename, std::map<std::string, std::string> variables)
300316
{
317+
variables["ProjectDir"] = Path::getPathFromFilename(filename);
318+
301319
std::list<ProjectConfiguration> projectConfigurationList;
302320
std::list<std::string> compileList;
303321
std::list<ItemDefinitionGroup> itemDefinitionGroupList;
@@ -352,7 +370,7 @@ void ImportProject::importVcxproj(const std::string &filename)
352370
if (useOfMfc)
353371
fs.defines += ";__AFXWIN_H__";
354372
fs.setDefines(fs.defines);
355-
fs.setIncludePaths(Path::getPathFromFilename(filename), toStringList(i->additionalIncludePaths));
373+
fs.setIncludePaths(Path::getPathFromFilename(filename), toStringList(i->additionalIncludePaths), variables);
356374
fileSettings.push_back(fs);
357375
}
358376
}

lib/importproject.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
//---------------------------------------------------------------------------
2323

2424
#include <list>
25+
#include <map>
2526
#include <string>
2627
#include <set>
2728
#include <vector>
@@ -47,7 +48,7 @@ class CPPCHECKLIB ImportProject {
4748
cppcheck::Platform::PlatformType platformType;
4849

4950
void setDefines(std::string defs);
50-
void setIncludePaths(const std::string &basepath, const std::list<std::string> &in);
51+
void setIncludePaths(const std::string &basepath, const std::list<std::string> &in, const std::map<std::string, std::string> &variables);
5152
};
5253
std::list<FileSettings> fileSettings;
5354

@@ -59,7 +60,7 @@ class CPPCHECKLIB ImportProject {
5960
private:
6061
void importCompileCommands(std::istream &istr);
6162
void importSln(std::istream &istr, const std::string &path);
62-
void importVcxproj(const std::string &filename);
63+
void importVcxproj(const std::string &filename, std::map<std::string, std::string> variables);
6364
};
6465

6566
/// @}

test/testimportproject.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ class TestImportProject : public TestFixture {
2929

3030
void run() {
3131
TEST_CASE(setDefines);
32-
TEST_CASE(setIncludePaths);
32+
TEST_CASE(setIncludePaths1);
33+
TEST_CASE(setIncludePaths2);
3334
}
3435

3536
void setDefines() {
@@ -48,14 +49,26 @@ class TestImportProject : public TestFixture {
4849
ASSERT_EQUALS("A=1;B=1", fs.defines);
4950
}
5051

51-
void setIncludePaths() {
52+
void setIncludePaths1() {
5253
ImportProject::FileSettings fs;
5354
std::list<std::string> in;
5455
in.push_back("../include");
55-
fs.setIncludePaths("abc/def/", in);
56+
std::map<std::string, std::string> variables;
57+
fs.setIncludePaths("abc/def/", in, variables);
5658
ASSERT_EQUALS(1U, fs.includePaths.size());
5759
ASSERT_EQUALS("abc/include/", fs.includePaths.front());
5860
}
61+
62+
void setIncludePaths2() {
63+
ImportProject::FileSettings fs;
64+
std::list<std::string> in;
65+
in.push_back("$(SolutionDir)other");
66+
std::map<std::string, std::string> variables;
67+
variables["SolutionDir"] = "c:/abc/";
68+
fs.setIncludePaths("/home/fred", in, variables);
69+
ASSERT_EQUALS(1U, fs.includePaths.size());
70+
ASSERT_EQUALS("c:/abc/other/", fs.includePaths.front());
71+
}
5972
};
6073

6174
REGISTER_TEST(TestImportProject)

0 commit comments

Comments
 (0)