43
43
#ifdef SIMPLECPP_WINDOWS
44
44
#include < windows.h>
45
45
#undef ERROR
46
+ #else
47
+ #include < unistd.h>
46
48
#endif
47
49
48
50
#if __cplusplus >= 201103L
@@ -147,6 +149,11 @@ static unsigned long long stringToULL(const std::string &s)
147
149
return ret;
148
150
}
149
151
152
+ static bool startsWith (const std::string &s, const std::string &p)
153
+ {
154
+ return (s.size () >= p.size ()) && std::equal (p.begin (), p.end (), s.begin ());
155
+ }
156
+
150
157
static bool endsWith (const std::string &s, const std::string &e)
151
158
{
152
159
return (s.size () >= e.size ()) && std::equal (e.rbegin (), e.rend (), s.rbegin ());
@@ -2680,6 +2687,46 @@ static bool isCpp17OrLater(const simplecpp::DUI &dui)
2680
2687
return !std_ver.empty () && (std_ver >= " 201703L" );
2681
2688
}
2682
2689
2690
+
2691
+ static std::string currentDirectoryOSCalc () {
2692
+ #ifdef SIMPLECPP_WINDOWS
2693
+ TCHAR NPath[MAX_PATH];
2694
+ GetCurrentDirectory (MAX_PATH, NPath);
2695
+ return NPath;
2696
+ #else
2697
+ const std::size_t size = 1024 ;
2698
+ char the_path[size];
2699
+ getcwd (the_path, size);
2700
+ return the_path;
2701
+ #endif
2702
+ }
2703
+
2704
+ static const std::string& currentDirectory () {
2705
+ static const std::string curdir = simplecpp::simplifyPath (currentDirectoryOSCalc ());
2706
+ return curdir;
2707
+ }
2708
+
2709
+ static std::string toAbsolutePath (const std::string& path) {
2710
+ if (path.empty ()) {
2711
+ return path;// preserve error file path that is indicated by an empty string
2712
+ }
2713
+ if (!isAbsolutePath (path)) {
2714
+ return currentDirectory () + " /" + path;
2715
+ }
2716
+ // otherwise
2717
+ return path;
2718
+ }
2719
+
2720
+ static std::pair<std::string, bool > extractRelativePathFromAbsolute (const std::string& absolutepath) {
2721
+ static const std::string prefix = currentDirectory () + " /" ;
2722
+ if (startsWith (absolutepath, prefix)) {
2723
+ const std::size_t size = prefix.size ();
2724
+ return std::make_pair (absolutepath.substr (size, absolutepath.size () - size), true );
2725
+ }
2726
+ // otherwise
2727
+ return std::make_pair (" " , false );
2728
+ }
2729
+
2683
2730
static std::string openHeader (std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader);
2684
2731
static void simplifyHasInclude (simplecpp::TokenList &expr, const simplecpp::DUI &dui)
2685
2732
{
@@ -3098,9 +3145,12 @@ static std::string openHeader(std::ifstream &f, const std::string &path)
3098
3145
3099
3146
static std::string getRelativeFileName (const std::string &sourcefile, const std::string &header)
3100
3147
{
3148
+ std::string path;
3101
3149
if (sourcefile.find_first_of (" \\ /" ) != std::string::npos)
3102
- return simplecpp::simplifyPath (sourcefile.substr (0 , sourcefile.find_last_of (" \\ /" ) + 1U ) + header);
3103
- return simplecpp::simplifyPath (header);
3150
+ path = sourcefile.substr (0 , sourcefile.find_last_of (" \\ /" ) + 1U ) + header;
3151
+ else
3152
+ path = header;
3153
+ return simplecpp::simplifyPath (path);
3104
3154
}
3105
3155
3106
3156
static std::string openHeaderRelative (std::ifstream &f, const std::string &sourcefile, const std::string &header)
@@ -3110,7 +3160,7 @@ static std::string openHeaderRelative(std::ifstream &f, const std::string &sourc
3110
3160
3111
3161
static std::string getIncludePathFileName (const std::string &includePath, const std::string &header)
3112
3162
{
3113
- std::string path = includePath;
3163
+ std::string path = toAbsolutePath ( includePath) ;
3114
3164
if (!path.empty () && path[path.size ()-1U ]!=' /' && path[path.size ()-1U ]!=' \\ ' )
3115
3165
path += ' /' ;
3116
3166
return path + header;
@@ -3119,9 +3169,9 @@ static std::string getIncludePathFileName(const std::string &includePath, const
3119
3169
static std::string openHeaderIncludePath (std::ifstream &f, const simplecpp::DUI &dui, const std::string &header)
3120
3170
{
3121
3171
for (std::list<std::string>::const_iterator it = dui.includePaths .begin (); it != dui.includePaths .end (); ++it) {
3122
- std::string simplePath = openHeader (f, getIncludePathFileName (*it, header));
3123
- if (!simplePath .empty ())
3124
- return simplePath ;
3172
+ std::string path = openHeader (f, getIncludePathFileName (*it, header));
3173
+ if (!path .empty ())
3174
+ return path ;
3125
3175
}
3126
3176
return " " ;
3127
3177
}
@@ -3131,49 +3181,76 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
3131
3181
if (isAbsolutePath (header))
3132
3182
return openHeader (f, header);
3133
3183
3134
- std::string ret;
3135
-
3136
3184
if (systemheader) {
3137
- ret = openHeaderIncludePath (f, dui, header);
3138
- return ret ;
3185
+ // always return absolute path for systemheaders
3186
+ return toAbsolutePath ( openHeaderIncludePath (f, dui, header)) ;
3139
3187
}
3140
3188
3189
+ std::string ret;
3190
+
3141
3191
ret = openHeaderRelative (f, sourcefile, header);
3142
3192
if (ret.empty ())
3143
- return openHeaderIncludePath (f, dui, header);
3193
+ return toAbsolutePath ( openHeaderIncludePath (f, dui, header)); // in a similar way to system headers
3144
3194
return ret;
3145
3195
}
3146
3196
3147
- 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)
3197
+ static std::string findPathInMapBothRelativeAndAbsolute (const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string& path) {
3198
+ // here there are two possibilities - either we match this from absolute path or from a relative one
3199
+ if (filedata.find (path) != filedata.end ()) {// try first to respect the exact match
3200
+ return path;
3201
+ }
3202
+ // otherwise - try to use the normalize to the correct representation
3203
+ if (isAbsolutePath (path)) {
3204
+ const std::pair<std::string, bool > relativeExtractedResult = extractRelativePathFromAbsolute (path);
3205
+ if (relativeExtractedResult.second ) {
3206
+ const std::string relativePath = relativeExtractedResult.first ;
3207
+ if (filedata.find (relativePath) != filedata.end ()) {
3208
+ return relativePath;
3209
+ }
3210
+ }
3211
+ } else {
3212
+ const std::string absolutePath = toAbsolutePath (path);
3213
+ if (filedata.find (absolutePath) != filedata.end ())
3214
+ return absolutePath;
3215
+ }
3216
+ // otherwise
3217
+ return " " ;
3218
+ }
3219
+
3220
+ 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)
3148
3221
{
3149
3222
if (filedata.empty ()) {
3150
3223
return " " ;
3151
3224
}
3152
3225
if (isAbsolutePath (header)) {
3153
- return (filedata.find (header) != filedata.end ()) ? simplecpp::simplifyPath (header) : " " ;
3226
+ const std::string simplifiedHeaderPath = simplecpp::simplifyPath (header);
3227
+ return (filedata.find (simplifiedHeaderPath) != filedata.end ()) ? simplifiedHeaderPath : " " ;
3154
3228
}
3155
3229
3156
3230
if (!systemheader) {
3157
- const std::string relativeFilename = getRelativeFileName (sourcefile, header);
3158
- if (filedata.find (relativeFilename) != filedata.end ())
3159
- return relativeFilename;
3231
+ const std::string relativeOrAbsoluteFilename = getRelativeFileName (sourcefile, header);// unknown if absolute or relative, but always simplified
3232
+ const std::string match = findPathInMapBothRelativeAndAbsolute (filedata, relativeOrAbsoluteFilename);
3233
+ if (!match.empty ()) {
3234
+ return match;
3235
+ }
3160
3236
}
3161
3237
3162
3238
for (std::list<std::string>::const_iterator it = dui.includePaths .begin (); it != dui.includePaths .end (); ++it) {
3163
- std::string s = simplecpp::simplifyPath (getIncludePathFileName (*it, header));
3164
- if (filedata.find (s) != filedata.end ())
3165
- return s;
3239
+ const std::string match = findPathInMapBothRelativeAndAbsolute (filedata, simplecpp::simplifyPath (getIncludePathFileName (*it, header)));
3240
+ if (!match.empty ()) {
3241
+ return match;
3242
+ }
3166
3243
}
3167
3244
3168
3245
if (systemheader && filedata.find (header) != filedata.end ())
3169
- return header;
3246
+ return header;// system header that its file wasn't found in the included paths but alreasy in the filedata - return this as is
3170
3247
3171
3248
return " " ;
3172
3249
}
3173
3250
3174
3251
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)
3175
3252
{
3176
- return !getFileName (filedata, sourcefile, header, dui, systemheader).empty ();
3253
+ return !getFileIdPath (filedata, sourcefile, header, dui, systemheader).empty ();
3177
3254
}
3178
3255
3179
3256
std::map<std::string, simplecpp::TokenList*> simplecpp::load (const simplecpp::TokenList &rawtokens, std::vector<std::string> &filenames, const simplecpp::DUI &dui, simplecpp::OutputList *outputList)
@@ -3529,7 +3606,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
3529
3606
3530
3607
const bool systemheader = (inctok->str ()[0 ] == ' <' );
3531
3608
const std::string header (realFilename (inctok->str ().substr (1U , inctok->str ().size () - 2U )));
3532
- std::string header2 = getFileName (filedata, rawtok->location .file (), header, dui, systemheader);
3609
+ std::string header2 = getFileIdPath (filedata, rawtok->location .file (), header, dui, systemheader);
3533
3610
if (header2.empty ()) {
3534
3611
// try to load file..
3535
3612
std::ifstream f;
0 commit comments