Skip to content

Commit 84f910b

Browse files
authored
Fix #13894 (Update simplecpp to 1.4.3) (danmar#7554)
1 parent 8605900 commit 84f910b

File tree

1 file changed

+80
-33
lines changed

1 file changed

+80
-33
lines changed

externals/simplecpp/simplecpp.cpp

Lines changed: 80 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2719,14 +2719,42 @@ static std::string toAbsolutePath(const std::string& path) {
27192719
return simplecpp::simplifyPath(path);
27202720
}
27212721

2722-
static std::pair<std::string, bool> extractRelativePathFromAbsolute(const std::string& absolutepath) {
2723-
static const std::string prefix = currentDirectory() + "/";
2724-
if (startsWith_(absolutepath, prefix)) {
2725-
const std::size_t size = prefix.size();
2726-
return std::make_pair(absolutepath.substr(size, absolutepath.size() - size), true);
2722+
static std::string dirPath(const std::string& path, bool withTrailingSlash=true) {
2723+
const std::size_t lastSlash = path.find_last_of("\\/");
2724+
if (lastSlash == std::string::npos) {
2725+
return "";
27272726
}
2728-
// otherwise
2729-
return std::make_pair("", false);
2727+
return path.substr(0, lastSlash + (withTrailingSlash ? 1U : 0U));
2728+
}
2729+
2730+
static std::string omitPathTrailingSlash(const std::string& path) {
2731+
if (endsWith(path, "/")) {
2732+
return path.substr(0, path.size() - 1U);
2733+
}
2734+
return path;
2735+
}
2736+
2737+
static std::string extractRelativePathFromAbsolute(const std::string& absoluteSimplifiedPath, const std::string& prefixSimplifiedAbsoluteDir = currentDirectory()) {
2738+
const std::string normalizedAbsolutePath = omitPathTrailingSlash(absoluteSimplifiedPath);
2739+
std::string currentPrefix = omitPathTrailingSlash(prefixSimplifiedAbsoluteDir);
2740+
std::string leadingParenting;
2741+
while (!startsWith_(normalizedAbsolutePath, currentPrefix)) {
2742+
leadingParenting = "../" + leadingParenting;
2743+
currentPrefix = dirPath(currentPrefix, false);
2744+
}
2745+
const std::size_t size = currentPrefix.size();
2746+
std::string relativeFromMeetingPath = normalizedAbsolutePath.substr(size, normalizedAbsolutePath.size() - size);
2747+
if (currentPrefix.empty() && !(startsWith_(absoluteSimplifiedPath, "/") && startsWith_(prefixSimplifiedAbsoluteDir, "/"))) {
2748+
// In the case that there is no common prefix path,
2749+
// and at not both of the paths start with `/` (can happen only in Windows paths on distinct partitions),
2750+
// return the absolute simplified path as is because no relative path can match.
2751+
return absoluteSimplifiedPath;
2752+
}
2753+
if (startsWith_(relativeFromMeetingPath, "/")) {
2754+
// omit the leading slash
2755+
relativeFromMeetingPath = relativeFromMeetingPath.substr(1, relativeFromMeetingPath.size());
2756+
}
2757+
return leadingParenting + relativeFromMeetingPath;
27302758
}
27312759

27322760
static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader);
@@ -3145,19 +3173,24 @@ static std::string openHeader(std::ifstream &f, const std::string &path)
31453173
return "";
31463174
}
31473175

3148-
static std::string getRelativeFileName(const std::string &baseFile, const std::string &header)
3176+
static std::string getRelativeFileName(const std::string &baseFile, const std::string &header, bool returnAbsolutePath)
31493177
{
3150-
std::string path;
3151-
if (baseFile.find_first_of("\\/") != std::string::npos)
3152-
path = baseFile.substr(0, baseFile.find_last_of("\\/") + 1U) + header;
3153-
else
3154-
path = header;
3155-
return simplecpp::simplifyPath(path);
3178+
const std::string baseFileSimplified = simplecpp::simplifyPath(baseFile);
3179+
const std::string baseFileAbsolute = isAbsolutePath(baseFileSimplified) ?
3180+
baseFileSimplified :
3181+
simplecpp::simplifyPath(currentDirectory() + "/" + baseFileSimplified);
3182+
3183+
const std::string headerSimplified = simplecpp::simplifyPath(header);
3184+
const std::string path = isAbsolutePath(headerSimplified) ?
3185+
headerSimplified :
3186+
simplecpp::simplifyPath(dirPath(baseFileAbsolute) + headerSimplified);
3187+
3188+
return returnAbsolutePath ? toAbsolutePath(path) : extractRelativePathFromAbsolute(path);
31563189
}
31573190

31583191
static std::string openHeaderRelative(std::ifstream &f, const std::string &sourcefile, const std::string &header)
31593192
{
3160-
return openHeader(f, getRelativeFileName(sourcefile, header));
3193+
return openHeader(f, getRelativeFileName(sourcefile, header, isAbsolutePath(sourcefile)));
31613194
}
31623195

31633196
// returns the simplified header path:
@@ -3174,8 +3207,9 @@ static std::string getIncludePathFileName(const std::string &includePath, const
31743207
std::string basePath = toAbsolutePath(includePath);
31753208
if (!basePath.empty() && basePath[basePath.size()-1U]!='/' && basePath[basePath.size()-1U]!='\\')
31763209
basePath += '/';
3177-
const std::string absolutesimplifiedHeaderPath = basePath + simplifiedHeader;
3178-
return extractRelativePathFromAbsolute(absolutesimplifiedHeaderPath).first;
3210+
const std::string absoluteSimplifiedHeaderPath = simplecpp::simplifyPath(basePath + simplifiedHeader);
3211+
// preserve absoluteness/relativieness of the including dir
3212+
return isAbsolutePath(includePath) ? absoluteSimplifiedHeaderPath : extractRelativePathFromAbsolute(absoluteSimplifiedHeaderPath);
31793213
}
31803214

31813215
static std::string openHeaderIncludePath(std::ifstream &f, const simplecpp::DUI &dui, const std::string &header)
@@ -3210,22 +3244,18 @@ static std::string findPathInMapBothRelativeAndAbsolute(const std::map<std::stri
32103244
if (filedata.find(path) != filedata.end()) {// try first to respect the exact match
32113245
return path;
32123246
}
3247+
32133248
// otherwise - try to use the normalize to the correct representation
3249+
std::string alternativePath;
32143250
if (isAbsolutePath(path)) {
3215-
const std::pair<std::string, bool> relativeExtractedResult = extractRelativePathFromAbsolute(path);
3216-
if (relativeExtractedResult.second) {
3217-
const std::string relativePath = relativeExtractedResult.first;
3218-
if (filedata.find(relativePath) != filedata.end()) {
3219-
return relativePath;
3220-
}
3221-
}
3251+
alternativePath = extractRelativePathFromAbsolute(simplecpp::simplifyPath(path));
32223252
} else {
3223-
const std::string absolutePath = toAbsolutePath(path);
3224-
if (filedata.find(absolutePath) != filedata.end()) {
3225-
return absolutePath;
3226-
}
3253+
alternativePath = toAbsolutePath(path);
3254+
}
3255+
3256+
if (filedata.find(alternativePath) != filedata.end()) {
3257+
return alternativePath;
32273258
}
3228-
// otherwise
32293259
return "";
32303260
}
32313261

@@ -3243,11 +3273,18 @@ static std::string getFileIdPath(const std::map<std::string, simplecpp::TokenLis
32433273
}
32443274

32453275
if (!systemheader) {
3246-
const std::string relativeOrAbsoluteFilename = getRelativeFileName(sourcefile, header);// unknown if absolute or relative, but always simplified
3247-
const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, relativeOrAbsoluteFilename);
3276+
const std::string relativeFilename = getRelativeFileName(sourcefile, header, true);
3277+
const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, relativeFilename);
32483278
if (!match.empty()) {
32493279
return match;
32503280
}
3281+
// if the file exists but hasn't been loaded yet then we need to stop searching here or we could get a false match
3282+
std::ifstream f;
3283+
openHeader(f, relativeFilename);
3284+
if (f.is_open()) {
3285+
f.close();
3286+
return "";
3287+
}
32513288
} else if (filedata.find(header) != filedata.end()) {
32523289
return header;// system header that its file is already in the filedata - return that as is
32533290
}
@@ -3267,6 +3304,16 @@ static bool hasFile(const std::map<std::string, simplecpp::TokenList *> &filedat
32673304
return !getFileIdPath(filedata, sourcefile, header, dui, systemheader).empty();
32683305
}
32693306

3307+
static void safeInsertTokenListToMap(std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &header2, simplecpp::TokenList *tokens, const std::string &header, const std::string &sourcefile, bool systemheader, const char* contextDesc)
3308+
{
3309+
const bool inserted = filedata.insert(std::make_pair(header2, tokens)).second;
3310+
if (!inserted) {
3311+
std::cerr << "error in " << contextDesc << " - attempt to add a tokenized file to the file map, but this file is already in the map! Details:" <<
3312+
"header: " << header << " header2: " << header2 << " source: " << sourcefile << " systemheader: " << systemheader << std::endl;
3313+
std::abort();
3314+
}
3315+
}
3316+
32703317
std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::TokenList &rawtokens, std::vector<std::string> &filenames, const simplecpp::DUI &dui, simplecpp::OutputList *outputList)
32713318
{
32723319
#ifdef SIMPLECPP_WINDOWS
@@ -3343,7 +3390,7 @@ std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::To
33433390
TokenList *tokens = new TokenList(header2, filenames, outputList);
33443391
if (dui.removeComments)
33453392
tokens->removeComments();
3346-
ret[header2] = tokens;
3393+
safeInsertTokenListToMap(ret, header2, tokens, header, rawtok->location.file(), systemheader, "simplecpp::load");
33473394
if (tokens->front())
33483395
filelist.push_back(tokens->front());
33493396
}
@@ -3630,7 +3677,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
36303677
TokenList * const tokens = new TokenList(header2, files, outputList);
36313678
if (dui.removeComments)
36323679
tokens->removeComments();
3633-
filedata[header2] = tokens;
3680+
safeInsertTokenListToMap(filedata, header2, tokens, header, rawtok->location.file(), systemheader, "simplecpp::preprocess");
36343681
}
36353682
}
36363683
if (header2.empty()) {

0 commit comments

Comments
 (0)