33 * Copyright (C) 2016-2023 simplecpp team
44 */
55
6+ // needs to be specified here otherwise _mingw.h will define it as 0x0601
7+ // causing FileIdInfo not to be available
68#if defined(_WIN32)
79# ifndef _WIN32_WINNT
810# define _WIN32_WINNT 0x0602
911# endif
10- # ifndef NOMINMAX
11- # define NOMINMAX
12- # endif
13- # ifndef WIN32_LEAN_AND_MEAN
14- # define WIN32_LEAN_AND_MEAN
15- # endif
16- # include < windows.h>
17- # undef ERROR
1812#endif
1913
2014#include " simplecpp.h"
5145#include < utility>
5246#include < vector>
5347
54- #ifdef _WIN32
48+ #if defined(_WIN32)
49+ # ifndef NOMINMAX
50+ # define NOMINMAX
51+ # endif
52+ # ifndef WIN32_LEAN_AND_MEAN
53+ # define WIN32_LEAN_AND_MEAN
54+ # endif
55+ # include < windows.h>
56+ # undef ERROR
5557# include < direct.h>
5658#else
5759# include < sys/stat.h>
60+ # include < sys/types.h>
5861#endif
5962
6063static bool isHex (const std::string &s)
@@ -658,8 +661,6 @@ static const std::string COMMENT_END("*/");
658661
659662void simplecpp::TokenList::readfile (Stream &stream, const std::string &filename, OutputList *outputList)
660663{
661- std::stack<simplecpp::Location> loc;
662-
663664 unsigned int multiline = 0U ;
664665
665666 const Token *oldLastToken = nullptr ;
@@ -698,59 +699,44 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename,
698699
699700 if (oldLastToken != cback ()) {
700701 oldLastToken = cback ();
701- const Token * const llTok = isLastLinePreprocessor ();
702- if (!llTok)
702+
703+ // #line 3
704+ // #line 3 "file.c"
705+ // #3
706+ // #3 "file.c"
707+ const Token * ppTok = isLastLinePreprocessor ();
708+ if (!ppTok)
703709 continue ;
704- const Token * const llNextToken = llTok->next ;
705- if (!llTok->next )
710+
711+ const auto advanceAndSkipComments = [](const Token* tok) {
712+ do {
713+ tok = tok->next ;
714+ } while (tok && tok->comment );
715+ return tok;
716+ };
717+
718+ // skip #
719+ ppTok = advanceAndSkipComments (ppTok);
720+ if (!ppTok)
706721 continue ;
707- if (llNextToken->next ) {
708- // #file "file.c"
709- if (llNextToken->str () == " file" &&
710- llNextToken->next ->str ()[0 ] == ' \" ' )
711- {
712- const Token *strtok = cback ();
713- while (strtok->comment )
714- strtok = strtok->previous ;
715- loc.push (location);
716- location.fileIndex = fileIndex (strtok->str ().substr (1U , strtok->str ().size () - 2U ));
717- location.line = 1U ;
718- }
719- // TODO: add support for "# 3"
720- // #3 "file.c"
721- // #line 3 "file.c"
722- else if ((llNextToken->number &&
723- llNextToken->next ->str ()[0 ] == ' \" ' ) ||
724- (llNextToken->str () == " line" &&
725- llNextToken->next ->number &&
726- llNextToken->next ->next &&
727- llNextToken->next ->next ->str ()[0 ] == ' \" ' ))
728- {
729- const Token *strtok = cback ();
730- while (strtok->comment )
731- strtok = strtok->previous ;
732- const Token *numtok = strtok->previous ;
733- while (numtok->comment )
734- numtok = numtok->previous ;
735- lineDirective (fileIndex (replaceAll (strtok->str ().substr (1U , strtok->str ().size () - 2U )," \\\\ " ," \\ " )),
736- std::atol (numtok->str ().c_str ()), location);
737- }
738- // #line 3
739- else if (llNextToken->str () == " line" &&
740- llNextToken->next ->number )
741- {
742- const Token *numtok = cback ();
743- while (numtok->comment )
744- numtok = numtok->previous ;
745- lineDirective (location.fileIndex , std::atol (numtok->str ().c_str ()), location);
746- }
747- }
748- // #endfile
749- else if (llNextToken->str () == " endfile" && !loc.empty ())
750- {
751- location = loc.top ();
752- loc.pop ();
753- }
722+
723+ if (ppTok->str () == " line" )
724+ ppTok = advanceAndSkipComments (ppTok);
725+
726+ if (!ppTok || !ppTok->number )
727+ continue ;
728+
729+ const unsigned int line = std::atol (ppTok->str ().c_str ());
730+ ppTok = advanceAndSkipComments (ppTok);
731+
732+ unsigned int fileindex;
733+
734+ if (ppTok && ppTok->str ()[0 ] == ' \" ' )
735+ fileindex = fileIndex (replaceAll (ppTok->str ().substr (1U , ppTok->str ().size () - 2U )," \\\\ " ," \\ " ));
736+ else
737+ fileindex = location.fileIndex ;
738+
739+ lineDirective (fileindex, line, location);
754740 }
755741
756742 continue ;
@@ -1040,7 +1026,7 @@ void simplecpp::TokenList::combineOperators()
10401026 continue ;
10411027 }
10421028 const Token *prev = tok->previous ;
1043- while (prev && prev->isOneOf (" ;{}() " ))
1029+ while (prev && prev->isOneOf (" ;{}(" ))
10441030 prev = prev->previous ;
10451031 executableScope.push (prev && prev->op == ' )' );
10461032 continue ;
@@ -2332,9 +2318,6 @@ namespace simplecpp {
23322318 const Token *nextTok = B->next ;
23332319
23342320 if (canBeConcatenatedStringOrChar) {
2335- if (unexpectedA)
2336- throw invalidHashHash::unexpectedToken (tok->location , name (), A);
2337-
23382321 // It seems clearer to handle this case separately even though the code is similar-ish, but we don't want to merge here.
23392322 // TODO The question is whether the ## or varargs may still apply, and how to provoke?
23402323 if (expandArg (tokensB, B, parametertokens)) {
@@ -3090,6 +3073,65 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
30903073 return " " ;
30913074}
30923075
3076+ namespace {
3077+ struct FileID {
3078+ #ifdef _WIN32
3079+ struct {
3080+ std::uint64_t VolumeSerialNumber;
3081+ struct {
3082+ std::uint64_t IdentifierHi;
3083+ std::uint64_t IdentifierLo;
3084+ } FileId;
3085+ } fileIdInfo;
3086+
3087+ bool operator ==(const FileID &that) const noexcept {
3088+ return fileIdInfo.VolumeSerialNumber == that.fileIdInfo .VolumeSerialNumber &&
3089+ fileIdInfo.FileId .IdentifierHi == that.fileIdInfo .FileId .IdentifierHi &&
3090+ fileIdInfo.FileId .IdentifierLo == that.fileIdInfo .FileId .IdentifierLo ;
3091+ }
3092+ #else
3093+ dev_t dev;
3094+ ino_t ino;
3095+
3096+ bool operator ==(const FileID& that) const noexcept {
3097+ return dev == that.dev && ino == that.ino ;
3098+ }
3099+ #endif
3100+ struct Hasher {
3101+ std::size_t operator ()(const FileID &id) const {
3102+ #ifdef _WIN32
3103+ return static_cast <std::size_t >(id.fileIdInfo .FileId .IdentifierHi ^ id.fileIdInfo .FileId .IdentifierLo ^
3104+ id.fileIdInfo .VolumeSerialNumber );
3105+ #else
3106+ return static_cast <std::size_t >(id.dev ) ^ static_cast <std::size_t >(id.ino );
3107+ #endif
3108+ }
3109+ };
3110+ };
3111+ }
3112+
3113+ struct simplecpp ::FileDataCache::Impl
3114+ {
3115+ void clear ()
3116+ {
3117+ mIdMap .clear ();
3118+ }
3119+
3120+ using id_map_type = std::unordered_map<FileID, FileData *, FileID::Hasher>;
3121+
3122+ id_map_type mIdMap ;
3123+ };
3124+
3125+ simplecpp::FileDataCache::FileDataCache ()
3126+ : mImpl(new Impl)
3127+ {}
3128+
3129+ simplecpp::FileDataCache::~FileDataCache () = default ;
3130+ simplecpp::FileDataCache::FileDataCache (FileDataCache &&) noexcept = default;
3131+ simplecpp::FileDataCache &simplecpp::FileDataCache::operator =(simplecpp::FileDataCache &&) noexcept = default ;
3132+
3133+ static bool getFileId (const std::string &path, FileID &id);
3134+
30933135std::pair<simplecpp::FileData *, bool > simplecpp::FileDataCache::tryload (FileDataCache::name_map_type::iterator &name_it, const simplecpp::DUI &dui, std::vector<std::string> &filenames, simplecpp::OutputList *outputList)
30943136{
30953137 const std::string &path = name_it->first ;
@@ -3098,8 +3140,8 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
30983140 if (!getFileId (path, fileId))
30993141 return {nullptr , false };
31003142
3101- const auto id_it = mIdMap .find (fileId);
3102- if (id_it != mIdMap .end ()) {
3143+ const auto id_it = mImpl -> mIdMap .find (fileId);
3144+ if (id_it != mImpl -> mIdMap .end ()) {
31033145 name_it->second = id_it->second ;
31043146 return {id_it->second , false };
31053147 }
@@ -3110,9 +3152,12 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
31103152 data->tokens .removeComments ();
31113153
31123154 name_it->second = data;
3113- mIdMap .emplace (fileId, data);
3155+ mImpl -> mIdMap .emplace (fileId, data);
31143156 mData .emplace_back (data);
31153157
3158+ if (mLoadCallback )
3159+ mLoadCallback (*data);
3160+
31163161 return {data, true };
31173162}
31183163
@@ -3162,7 +3207,14 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::get(const std::
31623207 return {nullptr , false };
31633208}
31643209
3165- bool simplecpp::FileDataCache::getFileId (const std::string &path, FileID &id)
3210+ void simplecpp::FileDataCache::clear ()
3211+ {
3212+ mImpl ->clear ();
3213+ mNameMap .clear ();
3214+ mData .clear ();
3215+ }
3216+
3217+ static bool getFileId (const std::string &path, FileID &id)
31663218{
31673219#ifdef _WIN32
31683220 HANDLE hFile = CreateFileA (path.c_str (), 0 , FILE_SHARE_READ | FILE_SHARE_WRITE , nullptr , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , nullptr );
@@ -3349,20 +3401,20 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
33493401 std::map<std::string, std::size_t > sizeOfType (rawtokens.sizeOfType );
33503402 sizeOfType.insert (std::make_pair (" char" , sizeof (char )));
33513403 sizeOfType.insert (std::make_pair (" short" , sizeof (short )));
3352- sizeOfType.insert (std::make_pair (" short int" , sizeOfType[ " short" ] ));
3404+ sizeOfType.insert (std::make_pair (" short int" , sizeof ( short ) ));
33533405 sizeOfType.insert (std::make_pair (" int" , sizeof (int )));
33543406 sizeOfType.insert (std::make_pair (" long" , sizeof (long )));
3355- sizeOfType.insert (std::make_pair (" long int" , sizeOfType[ " long" ] ));
3407+ sizeOfType.insert (std::make_pair (" long int" , sizeof ( long ) ));
33563408 sizeOfType.insert (std::make_pair (" long long" , sizeof (long long )));
33573409 sizeOfType.insert (std::make_pair (" float" , sizeof (float )));
33583410 sizeOfType.insert (std::make_pair (" double" , sizeof (double )));
33593411 sizeOfType.insert (std::make_pair (" long double" , sizeof (long double )));
33603412 sizeOfType.insert (std::make_pair (" char *" , sizeof (char *)));
33613413 sizeOfType.insert (std::make_pair (" short *" , sizeof (short *)));
3362- sizeOfType.insert (std::make_pair (" short int *" , sizeOfType[ " short *" ] ));
3414+ sizeOfType.insert (std::make_pair (" short int *" , sizeof ( short *) ));
33633415 sizeOfType.insert (std::make_pair (" int *" , sizeof (int *)));
33643416 sizeOfType.insert (std::make_pair (" long *" , sizeof (long *)));
3365- sizeOfType.insert (std::make_pair (" long int *" , sizeOfType[ " long *" ] ));
3417+ sizeOfType.insert (std::make_pair (" long int *" , sizeof ( long *) ));
33663418 sizeOfType.insert (std::make_pair (" long long *" , sizeof (long long *)));
33673419 sizeOfType.insert (std::make_pair (" float *" , sizeof (float *)));
33683420 sizeOfType.insert (std::make_pair (" double *" , sizeof (double *)));
0 commit comments