Skip to content

Commit 0bf6e86

Browse files
committed
simplecpp
1 parent 610386c commit 0bf6e86

File tree

1 file changed

+109
-28
lines changed

1 file changed

+109
-28
lines changed

externals/simplecpp/simplecpp.cpp

+109-28
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
#ifdef SIMPLECPP_WINDOWS
4444
#include <windows.h>
4545
#undef ERROR
46+
#else
47+
#include <unistd.h>
4648
#endif
4749

4850
#if __cplusplus >= 201103L
@@ -147,6 +149,12 @@ static unsigned long long stringToULL(const std::string &s)
147149
return ret;
148150
}
149151

152+
// TODO: added an undercore since this conflicts with a function of the same name in utils.h from Cppcheck source when building Cppcheck with MSBuild
153+
static bool startsWith_(const std::string &s, const std::string &p)
154+
{
155+
return (s.size() >= p.size()) && std::equal(p.begin(), p.end(), s.begin());
156+
}
157+
150158
static bool endsWith(const std::string &s, const std::string &e)
151159
{
152160
return (s.size() >= e.size()) && std::equal(e.rbegin(), e.rend(), s.rbegin());
@@ -2334,17 +2342,12 @@ namespace simplecpp {
23342342
namespace simplecpp {
23352343

23362344
#ifdef __CYGWIN__
2337-
bool startsWith(const std::string &str, const std::string &s)
2338-
{
2339-
return (str.size() >= s.size() && str.compare(0, s.size(), s) == 0);
2340-
}
2341-
23422345
std::string convertCygwinToWindowsPath(const std::string &cygwinPath)
23432346
{
23442347
std::string windowsPath;
23452348

23462349
std::string::size_type pos = 0;
2347-
if (cygwinPath.size() >= 11 && startsWith(cygwinPath, "/cygdrive/")) {
2350+
if (cygwinPath.size() >= 11 && startsWith_(cygwinPath, "/cygdrive/")) {
23482351
const unsigned char driveLetter = cygwinPath[10];
23492352
if (std::isalpha(driveLetter)) {
23502353
if (cygwinPath.size() == 11) {
@@ -2681,6 +2684,54 @@ static bool isCpp17OrLater(const simplecpp::DUI &dui)
26812684
return !std_ver.empty() && (std_ver >= "201703L");
26822685
}
26832686

2687+
2688+
static std::string currentDirectoryOSCalc() {
2689+
#ifdef SIMPLECPP_WINDOWS
2690+
TCHAR NPath[MAX_PATH];
2691+
GetCurrentDirectory(MAX_PATH, NPath);
2692+
#ifdef _UNICODE
2693+
// convert the result from TCHAR* to char*
2694+
char NPathA[MAX_PATH];
2695+
::WideCharToMultiByte(CP_ACP, 0, NPath, lstrlen(NPath), NPathA, MAX_PATH, NULL, NULL);
2696+
return NPathA;
2697+
#else
2698+
// in this case, TCHAR* is just defined to be a char*
2699+
return NPath;
2700+
#endif
2701+
#else
2702+
const std::size_t size = 1024;
2703+
char the_path[size];
2704+
getcwd(the_path, size);
2705+
return the_path;
2706+
#endif
2707+
}
2708+
2709+
static const std::string& currentDirectory() {
2710+
static const std::string curdir = simplecpp::simplifyPath(currentDirectoryOSCalc());
2711+
return curdir;
2712+
}
2713+
2714+
static std::string toAbsolutePath(const std::string& path) {
2715+
if (path.empty()) {
2716+
return path;// preserve error file path that is indicated by an empty string
2717+
}
2718+
if (!isAbsolutePath(path)) {
2719+
return simplecpp::simplifyPath(currentDirectory() + "/" + path);
2720+
}
2721+
// otherwise
2722+
return simplecpp::simplifyPath(path);
2723+
}
2724+
2725+
static std::pair<std::string, bool> extractRelativePathFromAbsolute(const std::string& absolutepath) {
2726+
static const std::string prefix = currentDirectory() + "/";
2727+
if (startsWith_(absolutepath, prefix)) {
2728+
const std::size_t size = prefix.size();
2729+
return std::make_pair(absolutepath.substr(size, absolutepath.size() - size), true);
2730+
}
2731+
// otherwise
2732+
return std::make_pair("", false);
2733+
}
2734+
26842735
static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader);
26852736
static void simplifyHasInclude(simplecpp::TokenList &expr, const simplecpp::DUI &dui)
26862737
{
@@ -3099,9 +3150,12 @@ static std::string openHeader(std::ifstream &f, const std::string &path)
30993150

31003151
static std::string getRelativeFileName(const std::string &sourcefile, const std::string &header)
31013152
{
3153+
std::string path;
31023154
if (sourcefile.find_first_of("\\/") != std::string::npos)
3103-
return simplecpp::simplifyPath(sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header);
3104-
return simplecpp::simplifyPath(header);
3155+
path = sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header;
3156+
else
3157+
path = header;
3158+
return simplecpp::simplifyPath(path);
31053159
}
31063160

31073161
static std::string openHeaderRelative(std::ifstream &f, const std::string &sourcefile, const std::string &header)
@@ -3111,7 +3165,7 @@ static std::string openHeaderRelative(std::ifstream &f, const std::string &sourc
31113165

31123166
static std::string getIncludePathFileName(const std::string &includePath, const std::string &header)
31133167
{
3114-
std::string path = includePath;
3168+
std::string path = toAbsolutePath(includePath);
31153169
if (!path.empty() && path[path.size()-1U]!='/' && path[path.size()-1U]!='\\')
31163170
path += '/';
31173171
return path + header;
@@ -3120,9 +3174,9 @@ static std::string getIncludePathFileName(const std::string &includePath, const
31203174
static std::string openHeaderIncludePath(std::ifstream &f, const simplecpp::DUI &dui, const std::string &header)
31213175
{
31223176
for (std::list<std::string>::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) {
3123-
std::string simplePath = openHeader(f, getIncludePathFileName(*it, header));
3124-
if (!simplePath.empty())
3125-
return simplePath;
3177+
std::string path = openHeader(f, getIncludePathFileName(*it, header));
3178+
if (!path.empty())
3179+
return path;
31263180
}
31273181
return "";
31283182
}
@@ -3132,49 +3186,76 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
31323186
if (isAbsolutePath(header))
31333187
return openHeader(f, header);
31343188

3135-
std::string ret;
3136-
31373189
if (systemheader) {
3138-
ret = openHeaderIncludePath(f, dui, header);
3139-
return ret;
3190+
// always return absolute path for systemheaders
3191+
return toAbsolutePath(openHeaderIncludePath(f, dui, header));
31403192
}
31413193

3194+
std::string ret;
3195+
31423196
ret = openHeaderRelative(f, sourcefile, header);
31433197
if (ret.empty())
3144-
return openHeaderIncludePath(f, dui, header);
3198+
return toAbsolutePath(openHeaderIncludePath(f, dui, header));// in a similar way to system headers
31453199
return ret;
31463200
}
31473201

3148-
static std::string getFileName(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader)
3202+
static std::string findPathInMapBothRelativeAndAbsolute(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string& path) {
3203+
// here there are two possibilities - either we match this from absolute path or from a relative one
3204+
if (filedata.find(path) != filedata.end()) {// try first to respect the exact match
3205+
return path;
3206+
}
3207+
// otherwise - try to use the normalize to the correct representation
3208+
if (isAbsolutePath(path)) {
3209+
const std::pair<std::string, bool> relativeExtractedResult = extractRelativePathFromAbsolute(path);
3210+
if (relativeExtractedResult.second) {
3211+
const std::string relativePath = relativeExtractedResult.first;
3212+
if (filedata.find(relativePath) != filedata.end()) {
3213+
return relativePath;
3214+
}
3215+
}
3216+
} else {
3217+
const std::string absolutePath = toAbsolutePath(path);
3218+
if (filedata.find(absolutePath) != filedata.end())
3219+
return absolutePath;
3220+
}
3221+
// otherwise
3222+
return "";
3223+
}
3224+
3225+
static std::string getFileIdPath(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader)
31493226
{
31503227
if (filedata.empty()) {
31513228
return "";
31523229
}
31533230
if (isAbsolutePath(header)) {
3154-
return (filedata.find(header) != filedata.end()) ? simplecpp::simplifyPath(header) : "";
3231+
const std::string simplifiedHeaderPath = simplecpp::simplifyPath(header);
3232+
return (filedata.find(simplifiedHeaderPath) != filedata.end()) ? simplifiedHeaderPath : "";
31553233
}
31563234

31573235
if (!systemheader) {
3158-
const std::string relativeFilename = getRelativeFileName(sourcefile, header);
3159-
if (filedata.find(relativeFilename) != filedata.end())
3160-
return relativeFilename;
3236+
const std::string relativeOrAbsoluteFilename = getRelativeFileName(sourcefile, header);// unknown if absolute or relative, but always simplified
3237+
const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, relativeOrAbsoluteFilename);
3238+
if (!match.empty()) {
3239+
return match;
3240+
}
31613241
}
31623242

31633243
for (std::list<std::string>::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) {
3164-
std::string s = simplecpp::simplifyPath(getIncludePathFileName(*it, header));
3165-
if (filedata.find(s) != filedata.end())
3166-
return s;
3244+
const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, simplecpp::simplifyPath(getIncludePathFileName(*it, header)));
3245+
if (!match.empty()) {
3246+
return match;
3247+
}
31673248
}
31683249

31693250
if (systemheader && filedata.find(header) != filedata.end())
3170-
return header;
3251+
return header;// system header that its file wasn't found in the included paths but alreasy in the filedata - return this as is
31713252

31723253
return "";
31733254
}
31743255

31753256
static bool hasFile(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader)
31763257
{
3177-
return !getFileName(filedata, sourcefile, header, dui, systemheader).empty();
3258+
return !getFileIdPath(filedata, sourcefile, header, dui, systemheader).empty();
31783259
}
31793260

31803261
std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::TokenList &rawtokens, std::vector<std::string> &filenames, const simplecpp::DUI &dui, simplecpp::OutputList *outputList)
@@ -3530,7 +3611,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
35303611

35313612
const bool systemheader = (inctok->str()[0] == '<');
35323613
const std::string header(realFilename(inctok->str().substr(1U, inctok->str().size() - 2U)));
3533-
std::string header2 = getFileName(filedata, rawtok->location.file(), header, dui, systemheader);
3614+
std::string header2 = getFileIdPath(filedata, rawtok->location.file(), header, dui, systemheader);
35343615
if (header2.empty()) {
35353616
// try to load file..
35363617
std::ifstream f;

0 commit comments

Comments
 (0)