Skip to content

Commit 42a0805

Browse files
authored
Fix #14898: Update simplecpp to 1.8.1 (#8702)
1 parent 08db304 commit 42a0805

3 files changed

Lines changed: 154 additions & 128 deletions

File tree

.selfcheck_suppressions

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,3 @@ useStlAlgorithm:externals/simplecpp/simplecpp.cpp
7979
funcArgNamesDifferentUnnamed:externals/simplecpp/simplecpp.h
8080
missingMemberCopy:externals/simplecpp/simplecpp.h
8181
shadowFunction:externals/simplecpp/simplecpp.h
82-
knownConditionTrueFalse:externals/simplecpp/simplecpp.cpp

externals/simplecpp/simplecpp.cpp

Lines changed: 139 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,12 @@
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"
@@ -51,10 +45,19 @@
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

6063
static bool isHex(const std::string &s)
@@ -658,8 +661,6 @@ static const std::string COMMENT_END("*/");
658661

659662
void 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;
@@ -1031,16 +1017,15 @@ static bool isAlternativeAndBitandBitor(const simplecpp::Token* tok)
10311017

10321018
void simplecpp::TokenList::combineOperators()
10331019
{
1034-
std::stack<bool> executableScope;
1035-
executableScope.push(false);
1020+
std::stack<bool, std::vector<bool>> executableScope{{false}};
10361021
for (Token *tok = front(); tok; tok = tok->next) {
10371022
if (tok->op == '{') {
10381023
if (executableScope.top()) {
10391024
executableScope.push(true);
10401025
continue;
10411026
}
10421027
const Token *prev = tok->previous;
1043-
while (prev && prev->isOneOf(";{}()"))
1028+
while (prev && prev->isOneOf(";{}("))
10441029
prev = prev->previous;
10451030
executableScope.push(prev && prev->op == ')');
10461031
continue;
@@ -2332,9 +2317,6 @@ namespace simplecpp {
23322317
const Token *nextTok = B->next;
23332318

23342319
if (canBeConcatenatedStringOrChar) {
2335-
if (unexpectedA)
2336-
throw invalidHashHash::unexpectedToken(tok->location, name(), A);
2337-
23382320
// It seems clearer to handle this case separately even though the code is similar-ish, but we don't want to merge here.
23392321
// TODO The question is whether the ## or varargs may still apply, and how to provoke?
23402322
if (expandArg(tokensB, B, parametertokens)) {
@@ -3090,6 +3072,65 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
30903072
return "";
30913073
}
30923074

3075+
namespace {
3076+
struct FileID {
3077+
#ifdef _WIN32
3078+
struct {
3079+
std::uint64_t VolumeSerialNumber;
3080+
struct {
3081+
std::uint64_t IdentifierHi;
3082+
std::uint64_t IdentifierLo;
3083+
} FileId;
3084+
} fileIdInfo;
3085+
3086+
bool operator==(const FileID &that) const noexcept {
3087+
return fileIdInfo.VolumeSerialNumber == that.fileIdInfo.VolumeSerialNumber &&
3088+
fileIdInfo.FileId.IdentifierHi == that.fileIdInfo.FileId.IdentifierHi &&
3089+
fileIdInfo.FileId.IdentifierLo == that.fileIdInfo.FileId.IdentifierLo;
3090+
}
3091+
#else
3092+
dev_t dev;
3093+
ino_t ino;
3094+
3095+
bool operator==(const FileID& that) const noexcept {
3096+
return dev == that.dev && ino == that.ino;
3097+
}
3098+
#endif
3099+
struct Hasher {
3100+
std::size_t operator()(const FileID &id) const {
3101+
#ifdef _WIN32
3102+
return static_cast<std::size_t>(id.fileIdInfo.FileId.IdentifierHi ^ id.fileIdInfo.FileId.IdentifierLo ^
3103+
id.fileIdInfo.VolumeSerialNumber);
3104+
#else
3105+
return static_cast<std::size_t>(id.dev) ^ static_cast<std::size_t>(id.ino);
3106+
#endif
3107+
}
3108+
};
3109+
};
3110+
}
3111+
3112+
struct simplecpp::FileDataCache::Impl
3113+
{
3114+
void clear()
3115+
{
3116+
mIdMap.clear();
3117+
}
3118+
3119+
using id_map_type = std::unordered_map<FileID, FileData *, FileID::Hasher>;
3120+
3121+
id_map_type mIdMap;
3122+
};
3123+
3124+
simplecpp::FileDataCache::FileDataCache()
3125+
: mImpl(new Impl)
3126+
{}
3127+
3128+
simplecpp::FileDataCache::~FileDataCache() = default;
3129+
simplecpp::FileDataCache::FileDataCache(FileDataCache &&) noexcept = default;
3130+
simplecpp::FileDataCache &simplecpp::FileDataCache::operator=(simplecpp::FileDataCache &&) noexcept = default;
3131+
3132+
static bool getFileId(const std::string &path, FileID &id);
3133+
30933134
std::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)
30943135
{
30953136
const std::string &path = name_it->first;
@@ -3098,8 +3139,8 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
30983139
if (!getFileId(path, fileId))
30993140
return {nullptr, false};
31003141

3101-
const auto id_it = mIdMap.find(fileId);
3102-
if (id_it != mIdMap.end()) {
3142+
const auto id_it = mImpl->mIdMap.find(fileId);
3143+
if (id_it != mImpl->mIdMap.end()) {
31033144
name_it->second = id_it->second;
31043145
return {id_it->second, false};
31053146
}
@@ -3110,9 +3151,12 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
31103151
data->tokens.removeComments();
31113152

31123153
name_it->second = data;
3113-
mIdMap.emplace(fileId, data);
3154+
mImpl->mIdMap.emplace(fileId, data);
31143155
mData.emplace_back(data);
31153156

3157+
if (mLoadCallback)
3158+
mLoadCallback(*data);
3159+
31163160
return {data, true};
31173161
}
31183162

@@ -3162,7 +3206,14 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::get(const std::
31623206
return {nullptr, false};
31633207
}
31643208

3165-
bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id)
3209+
void simplecpp::FileDataCache::clear()
3210+
{
3211+
mImpl->clear();
3212+
mNameMap.clear();
3213+
mData.clear();
3214+
}
3215+
3216+
static bool getFileId(const std::string &path, FileID &id)
31663217
{
31673218
#ifdef _WIN32
31683219
HANDLE hFile = CreateFileA(path.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
@@ -3349,20 +3400,20 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
33493400
std::map<std::string, std::size_t> sizeOfType(rawtokens.sizeOfType);
33503401
sizeOfType.insert(std::make_pair("char", sizeof(char)));
33513402
sizeOfType.insert(std::make_pair("short", sizeof(short)));
3352-
sizeOfType.insert(std::make_pair("short int", sizeOfType["short"]));
3403+
sizeOfType.insert(std::make_pair("short int", sizeof(short)));
33533404
sizeOfType.insert(std::make_pair("int", sizeof(int)));
33543405
sizeOfType.insert(std::make_pair("long", sizeof(long)));
3355-
sizeOfType.insert(std::make_pair("long int", sizeOfType["long"]));
3406+
sizeOfType.insert(std::make_pair("long int", sizeof(long)));
33563407
sizeOfType.insert(std::make_pair("long long", sizeof(long long)));
33573408
sizeOfType.insert(std::make_pair("float", sizeof(float)));
33583409
sizeOfType.insert(std::make_pair("double", sizeof(double)));
33593410
sizeOfType.insert(std::make_pair("long double", sizeof(long double)));
33603411
sizeOfType.insert(std::make_pair("char *", sizeof(char *)));
33613412
sizeOfType.insert(std::make_pair("short *", sizeof(short *)));
3362-
sizeOfType.insert(std::make_pair("short int *", sizeOfType["short *"]));
3413+
sizeOfType.insert(std::make_pair("short int *", sizeof(short *)));
33633414
sizeOfType.insert(std::make_pair("int *", sizeof(int *)));
33643415
sizeOfType.insert(std::make_pair("long *", sizeof(long *)));
3365-
sizeOfType.insert(std::make_pair("long int *", sizeOfType["long *"]));
3416+
sizeOfType.insert(std::make_pair("long int *", sizeof(long *)));
33663417
sizeOfType.insert(std::make_pair("long long *", sizeof(long long *)));
33673418
sizeOfType.insert(std::make_pair("float *", sizeof(float *)));
33683419
sizeOfType.insert(std::make_pair("double *", sizeof(double *)));
@@ -3466,8 +3517,19 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
34663517
includetokenstack.push(rawtokens.cfront());
34673518
for (auto it = dui.includes.cbegin(); it != dui.includes.cend(); ++it) {
34683519
const FileData *const filedata = cache.get("", *it, dui, false, files, outputList).first;
3469-
if (filedata != nullptr && filedata->tokens.cfront() != nullptr)
3520+
if (filedata == nullptr) {
3521+
if (outputList) {
3522+
simplecpp::Output err{
3523+
simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND,
3524+
{},
3525+
"Can not open include file '" + *it + "' that is explicitly included."
3526+
};
3527+
outputList->emplace_back(std::move(err));
3528+
}
3529+
}
3530+
else if (filedata->tokens.cfront() != nullptr) {
34703531
includetokenstack.push(filedata->tokens.cfront());
3532+
}
34713533
}
34723534

34733535
std::map<std::string, std::list<Location>> maybeUsedMacros;

0 commit comments

Comments
 (0)