88#define NOMINMAX
99#endif
1010
11+ #ifdef SIMPLECPP_WINDOWS
12+ #define _WIN32_WINNT 0x0602
13+ #include < windows.h>
14+ #undef ERROR
15+ #else
16+ #include < sys/stat.h>
17+ #endif
18+
1119#include " simplecpp.h"
1220
1321#include < algorithm>
2634#include < limits>
2735#include < list>
2836#include < map>
37+ #include < memory>
2938#include < set>
3039#include < sstream>
3140#include < stack>
4655#include < unistd.h>
4756#endif
4857
49- #ifdef SIMPLECPP_WINDOWS
50- #include < windows.h>
51- #undef ERROR
52- #else
53- #include < sys/stat.h>
54- #endif
55-
5658#if __cplusplus >= 201103L
5759#define OVERRIDE override
5860#define EXPLICIT explicit
@@ -155,7 +157,7 @@ static unsigned long long stringToULL(const std::string &s)
155157 return ret;
156158}
157159
158- // 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
160+ // 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
159161static bool startsWith_ (const std::string &s, const std::string &p)
160162{
161163 return (s.size () >= p.size ()) && std::equal (p.begin (), p.end (), s.begin ());
@@ -2568,7 +2570,8 @@ static bool isCpp17OrLater(const simplecpp::DUI &dui)
25682570}
25692571
25702572
2571- static std::string currentDirectoryOSCalc () {
2573+ static std::string currentDirectoryOSCalc ()
2574+ {
25722575 const std::size_t size = 4096 ;
25732576 char currentPath[size];
25742577
@@ -2582,12 +2585,14 @@ static std::string currentDirectoryOSCalc() {
25822585 return " " ;
25832586}
25842587
2585- static const std::string& currentDirectory () {
2588+ static const std::string& currentDirectory ()
2589+ {
25862590 static const std::string curdir = simplecpp::simplifyPath (currentDirectoryOSCalc ());
25872591 return curdir;
25882592}
25892593
2590- static std::string toAbsolutePath (const std::string& path) {
2594+ static std::string toAbsolutePath (const std::string& path)
2595+ {
25912596 if (path.empty ()) {
25922597 return path;// preserve error file path that is indicated by an empty string
25932598 }
@@ -2598,22 +2603,25 @@ static std::string toAbsolutePath(const std::string& path) {
25982603 return simplecpp::simplifyPath (path);
25992604}
26002605
2601- static std::string dirPath (const std::string& path, bool withTrailingSlash=true ) {
2606+ static std::string dirPath (const std::string& path, bool withTrailingSlash=true )
2607+ {
26022608 const std::size_t lastSlash = path.find_last_of (" \\ /" );
26032609 if (lastSlash == std::string::npos) {
26042610 return " " ;
26052611 }
26062612 return path.substr (0 , lastSlash + (withTrailingSlash ? 1U : 0U ));
26072613}
26082614
2609- static std::string omitPathTrailingSlash (const std::string& path) {
2615+ static std::string omitPathTrailingSlash (const std::string& path)
2616+ {
26102617 if (endsWith (path, " /" )) {
26112618 return path.substr (0 , path.size () - 1U );
26122619 }
26132620 return path;
26142621}
26152622
2616- static std::string extractRelativePathFromAbsolute (const std::string& absoluteSimplifiedPath, const std::string& prefixSimplifiedAbsoluteDir = currentDirectory()) {
2623+ static std::string extractRelativePathFromAbsolute (const std::string& absoluteSimplifiedPath, const std::string& prefixSimplifiedAbsoluteDir = currentDirectory())
2624+ {
26172625 const std::string normalizedAbsolutePath = omitPathTrailingSlash (absoluteSimplifiedPath);
26182626 std::string currentPrefix = omitPathTrailingSlash (prefixSimplifiedAbsoluteDir);
26192627 std::string leadingParenting;
@@ -3054,13 +3062,13 @@ static std::string getRelativeFileName(const std::string &baseFile, const std::s
30543062{
30553063 const std::string baseFileSimplified = simplecpp::simplifyPath (baseFile);
30563064 const std::string baseFileAbsolute = isAbsolutePath (baseFileSimplified) ?
3057- baseFileSimplified :
3058- simplecpp::simplifyPath (currentDirectory () + " /" + baseFileSimplified);
3065+ baseFileSimplified :
3066+ simplecpp::simplifyPath (currentDirectory () + " /" + baseFileSimplified);
30593067
30603068 const std::string headerSimplified = simplecpp::simplifyPath (header);
30613069 const std::string path = isAbsolutePath (headerSimplified) ?
3062- headerSimplified :
3063- simplecpp::simplifyPath (dirPath (baseFileAbsolute) + headerSimplified);
3070+ headerSimplified :
3071+ simplecpp::simplifyPath (dirPath (baseFileAbsolute) + headerSimplified);
30643072
30653073 return returnAbsolutePath ? toAbsolutePath (path) : extractRelativePathFromAbsolute (path);
30663074}
@@ -3116,45 +3124,25 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
31163124 return openHeaderIncludePath (f, dui, header);
31173125}
31183126
3119- simplecpp::TokenList *simplecpp::FileDataCache::get (const std::string &sourcefile, const std::string &header, std::string *header2 , const simplecpp::DUI &dui, bool systemheader)
3127+ simplecpp::FileData *simplecpp::FileDataCache::lookup (const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader)
31203128{
3121- if (mDataMap .empty ())
3129+ if (mData .empty ())
31223130 return nullptr ;
31233131
31243132 if (isAbsolutePath (header)) {
31253133 std::string path = simplecpp::simplifyPath (header);
3126- const auto data = mDataMap .find (path);
3127-
3128- if (data != mDataMap .end ()) {
3129- if (header2 != nullptr ) {
3130- const auto uniquePath = mAliasMap .find (path);
3131-
3132- if (uniquePath != mAliasMap .end ())
3133- *header2 = uniquePath->second ;
3134- else
3135- *header2 = std::move (path);
3136- }
3134+ const auto name_it = mNameMap .find (path);
31373135
3138- return data-> second . get ();
3139- }
3136+ if (name_it != mNameMap . end ())
3137+ return name_it-> second ;
31403138 }
31413139
31423140 if (!systemheader) {
31433141 std::string path = getRelativeFileName (sourcefile, header, true );
3144- const auto data = mDataMap .find (path);
3145-
3146- if (data != mDataMap .end ()) {
3147- if (header2 != nullptr ) {
3148- const auto uniquePath = mAliasMap .find (path);
3149-
3150- if (uniquePath != mAliasMap .end ())
3151- *header2 = uniquePath->second ;
3152- else
3153- *header2 = std::move (path);
3154- }
3142+ const auto name_it = mNameMap .find (path);
31553143
3156- return data-> second . get ();
3157- }
3144+ if (name_it != mNameMap . end ())
3145+ return name_it-> second ;
31583146
31593147 // If the file exists but hasn't been loaded yet then we need to stop searching here or we could get a false match
31603148 std::ifstream f;
@@ -3165,75 +3153,55 @@ simplecpp::TokenList *simplecpp::FileDataCache::get(const std::string &sourcefil
31653153
31663154 for (std::list<std::string>::const_iterator it = dui.includePaths .begin (); it != dui.includePaths .end (); ++it) {
31673155 std::string path = getIncludePathFileName (*it, header);
3168- const auto data = mDataMap .find (path);
3169-
3170- if (data != mDataMap .end ()) {
3171- if (header2 != nullptr ) {
3172- const auto uniquePath = mAliasMap .find (path);
3173-
3174- if (uniquePath != mAliasMap .end ())
3175- *header2 = uniquePath->second ;
3176- else
3177- *header2 = std::move (path);
3178- }
3156+ const auto name_it = mNameMap .find (path);
31793157
3180- return data-> second . get ();
3181- }
3158+ if (name_it != mNameMap . end ())
3159+ return name_it-> second ;
31823160 }
31833161
31843162 return nullptr ;
31853163}
31863164
3187- simplecpp::TokenList * simplecpp::FileDataCache::load (const std::string &sourcefile, const std::string &header, std::string *header2 , const simplecpp::DUI &dui, bool systemheader, std::vector<std::string> &filenames, simplecpp::OutputList *outputList)
3165+ std::pair< bool , simplecpp::FileData *> simplecpp::FileDataCache::load (const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader, std::vector<std::string> &filenames, simplecpp::OutputList *outputList)
31883166{
31893167 std::ifstream f;
31903168 std::string path = openHeader (f, dui, sourcefile, header, systemheader);
31913169
31923170 if (path.empty ())
3193- return nullptr ;
3171+ return std::make_pair ( false , nullptr ) ;
31943172
31953173 FileID fileId;
31963174
31973175 if (!getFileId (path, fileId))
3198- return nullptr ;
3176+ return std::make_pair ( false , nullptr ) ;
31993177
3200- const auto id = mIdMap .find (fileId);
3201- if (id != mIdMap .end ()) {
3202- const auto &data = mDataMap . at (id ->second );
3178+ const auto id_it = mIdMap .find (fileId);
3179+ if (id_it != mIdMap .end ()) {
3180+ mNameMap . insert ( std::make_pair ( std::move (path), id_it ->second ) );
32033181
3204- mAliasMap .insert (std::make_pair (path, id->second ));
3205- mDataMap .insert (std::make_pair (path, data));
3206-
3207- if (header2 != nullptr )
3208- *header2 = id->second ;
3209-
3210- return data.get ();
3211- }
3212- else {
3213- auto data = std::make_shared<simplecpp::TokenList>(f, filenames, path, outputList);
3214- simplecpp::TokenList *const tokens = data.get ();
3182+ return std::make_pair (false , id_it->second );
3183+ } else {
3184+ FileData *data = new FileData {path, TokenList (f, filenames, path, outputList)};
32153185
32163186 if (dui.removeComments )
3217- tokens->removeComments ();
3218-
3219- mIdMap .insert (std::make_pair (fileId, path));
3220- mDataMap .insert (std::make_pair (path, std::move (data)));
3187+ data->tokens .removeComments ();
32213188
3222- if (header2 != nullptr )
3223- *header2 = std::move (path);
3189+ mNameMap .insert (std::make_pair (std::move (path), data));
3190+ mIdMap .insert (std::make_pair (fileId, data));
3191+ mData .push_back (std::unique_ptr<FileData>(data));
32243192
3225- return tokens ;
3193+ return std::make_pair ( true , data) ;
32263194 }
32273195}
32283196
3229- simplecpp::TokenList * simplecpp::FileDataCache::get_or_load (const std::string &sourcefile, const std::string &header, std::string *header2 , const simplecpp::DUI &dui, bool systemheader, std::vector<std::string> &filenames, simplecpp::OutputList *outputList)
3197+ std::pair< bool , simplecpp::FileData *> simplecpp::FileDataCache::get (const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader, std::vector<std::string> &filenames, simplecpp::OutputList *outputList)
32303198{
3231- simplecpp::TokenList *tokens = get (sourcefile, header, header2 , dui, systemheader);
3199+ FileData *data = lookup (sourcefile, header, dui, systemheader);
32323200
3233- if (tokens = = nullptr )
3234- tokens = load (sourcefile, header, header2, dui, systemheader, filenames, outputList );
3201+ if (data ! = nullptr )
3202+ return std::make_pair ( false , data );
32353203
3236- return tokens ;
3204+ return load (sourcefile, header, dui, systemheader, filenames, outputList) ;
32373205}
32383206
32393207bool simplecpp::FileDataCache::getFileId (const std::string &path, FileID &id)
@@ -3278,17 +3246,19 @@ simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens,
32783246 nonExistingFilesCache.clear ();
32793247#endif
32803248
3281- FileDataCache filedata ;
3249+ FileDataCache cache ;
32823250
32833251 std::list<const Token *> filelist;
32843252
32853253 // -include files
32863254 for (std::list<std::string>::const_iterator it = dui.includes .begin (); it != dui.includes .end (); ++it) {
32873255 const std::string &filename = *it;
32883256
3289- TokenList *tokenlist = filedata.get_or_load (" " , filename, nullptr , dui, false , filenames, outputList);
3257+ const auto loadResult = cache.get (" " , filename, dui, false , filenames, outputList);
3258+ const bool loaded = loadResult.first ;
3259+ FileData *const filedata = loadResult.second ;
32903260
3291- if (tokenlist == nullptr ) {
3261+ if (filedata == nullptr ) {
32923262 if (outputList) {
32933263 simplecpp::Output err (filenames);
32943264 err.type = simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND;
@@ -3299,14 +3269,16 @@ simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens,
32993269 continue ;
33003270 }
33013271
3302- if (!tokenlist->front ()) {
3272+ if (!loaded)
3273+ continue ;
3274+
3275+ if (!filedata->tokens .front ())
33033276 continue ;
3304- }
33053277
33063278 if (dui.removeComments )
3307- tokenlist-> removeComments ();
3279+ filedata-> tokens . removeComments ();
33083280
3309- filelist.push_back (tokenlist-> front ());
3281+ filelist.push_back (filedata-> tokens . front ());
33103282 }
33113283
33123284 for (const Token *rawtok = rawtokens.cfront (); rawtok || !filelist.empty (); rawtok = rawtok ? rawtok->next : nullptr ) {
@@ -3331,18 +3303,18 @@ simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens,
33313303 const bool systemheader = (htok->str ()[0 ] == ' <' );
33323304 const std::string header (htok->str ().substr (1U , htok->str ().size () - 2U ));
33333305
3334- TokenList *tokenlist = filedata. get_or_load (sourcefile, header, nullptr , dui, systemheader, filenames, outputList);
3335- if (!tokenlist )
3306+ FileData * const filedata = cache. get (sourcefile, header, dui, systemheader, filenames, outputList). second ;
3307+ if (!filedata )
33363308 continue ;
33373309
33383310 if (dui.removeComments )
3339- tokenlist-> removeComments ();
3311+ filedata-> tokens . removeComments ();
33403312
3341- if (tokenlist-> front ())
3342- filelist.push_back (tokenlist-> front ());
3313+ if (filedata-> tokens . front ())
3314+ filelist.push_back (filedata-> tokens . front ());
33433315 }
33443316
3345- return filedata ;
3317+ return cache ;
33463318}
33473319
33483320static bool preprocessToken (simplecpp::TokenList &output, const simplecpp::Token **tok1, simplecpp::MacroMap ¯os, std::vector<std::string> &files, simplecpp::OutputList *outputList)
@@ -3398,7 +3370,7 @@ static std::string getTimeDefine(const struct tm *timep)
33983370 return std::string (" \" " ).append (buf).append (" \" " );
33993371}
34003372
3401- void simplecpp::preprocess (simplecpp::TokenList &output, const simplecpp::TokenList &rawtokens, std::vector<std::string> &files, simplecpp::FileDataCache &filedata , const simplecpp::DUI &dui, simplecpp::OutputList *outputList, std::list<simplecpp::MacroUsage> *macroUsage, std::list<simplecpp::IfCond> *ifCond)
3373+ void simplecpp::preprocess (simplecpp::TokenList &output, const simplecpp::TokenList &rawtokens, std::vector<std::string> &files, simplecpp::FileDataCache &cache , const simplecpp::DUI &dui, simplecpp::OutputList *outputList, std::list<simplecpp::MacroUsage> *macroUsage, std::list<simplecpp::IfCond> *ifCond)
34023374{
34033375#ifdef SIMPLECPP_WINDOWS
34043376 if (dui.clearIncludeCache )
@@ -3490,9 +3462,9 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
34903462
34913463 includetokenstack.push (rawtokens.cfront ());
34923464 for (std::list<std::string>::const_iterator it = dui.includes .begin (); it != dui.includes .end (); ++it) {
3493- const TokenList *const includetokens = filedata. get_or_load (" " , *it, nullptr , dui, false , files, outputList);
3494- if (includetokens != nullptr )
3495- includetokenstack.push (includetokens-> cfront ());
3465+ const FileData *const filedata = cache. get (" " , *it, dui, false , files, outputList). second ;
3466+ if (filedata != nullptr && filedata-> tokens . cfront () != nullptr )
3467+ includetokenstack.push (filedata-> tokens . cfront ());
34963468 }
34973469
34983470 std::map<std::string, std::list<Location> > maybeUsedMacros;
@@ -3614,9 +3586,8 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
36143586
36153587 const bool systemheader = (inctok->str ()[0 ] == ' <' );
36163588 const std::string header (inctok->str ().substr (1U , inctok->str ().size () - 2U ));
3617- std::string header2;
3618- const TokenList *const includetokens = filedata.get_or_load (rawtok->location .file (), header, &header2, dui, systemheader, files, outputList);
3619- if (includetokens == nullptr ) {
3589+ const FileData *const filedata = cache.get (rawtok->location .file (), header, dui, systemheader, files, outputList).second ;
3590+ if (filedata == nullptr ) {
36203591 if (outputList) {
36213592 simplecpp::Output out (files);
36223593 out.type = Output::MISSING_HEADER;
@@ -3632,9 +3603,9 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
36323603 out.msg = " #include nested too deeply" ;
36333604 outputList->push_back (out);
36343605 }
3635- } else if (pragmaOnce.find (header2 ) == pragmaOnce.end ()) {
3606+ } else if (pragmaOnce.find (filedata-> filename ) == pragmaOnce.end ()) {
36363607 includetokenstack.push (gotoNextLine (rawtok));
3637- rawtok = includetokens ? includetokens-> cfront () : nullptr ;
3608+ rawtok = filedata-> tokens . cfront ();
36383609 continue ;
36393610 }
36403611 } else if (rawtok->str () == IF || rawtok->str () == IFDEF || rawtok->str () == IFNDEF || rawtok->str () == ELIF) {
@@ -3862,9 +3833,9 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
38623833 }
38633834}
38643835
3865- void simplecpp::cleanup (FileDataCache &filedata )
3836+ void simplecpp::cleanup (FileDataCache &cache )
38663837{
3867- ( void ) filedata ;
3838+ cache. clear () ;
38683839}
38693840
38703841simplecpp::cstd_t simplecpp::getCStd (const std::string &std)
0 commit comments