Skip to content

Commit 5ba370f

Browse files
committed
Fix #13894 (Update simplecpp to 1.4.2)
1 parent 60eb475 commit 5ba370f

1 file changed

Lines changed: 69 additions & 29 deletions

File tree

externals/simplecpp/simplecpp.cpp

Lines changed: 69 additions & 29 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);
@@ -3147,12 +3175,17 @@ static std::string openHeader(std::ifstream &f, const std::string &path)
31473175

31483176
static std::string getRelativeFileName(const std::string &baseFile, const std::string &header)
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 extractRelativePathFromAbsolute(path);
31563189
}
31573190

31583191
static std::string openHeaderRelative(std::ifstream &f, const std::string &sourcefile, const std::string &header)
@@ -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

@@ -3267,6 +3297,16 @@ static bool hasFile(const std::map<std::string, simplecpp::TokenList *> &filedat
32673297
return !getFileIdPath(filedata, sourcefile, header, dui, systemheader).empty();
32683298
}
32693299

3300+
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)
3301+
{
3302+
const bool inserted = filedata.insert(std::make_pair(header2, tokens)).second;
3303+
if (!inserted) {
3304+
std::cerr << "error in " << contextDesc << " - attempt to add a tokenized file to the file map, but this file is already in the map! Details:" <<
3305+
"header: " << header << " header2: " << header2 << " source: " << sourcefile << " systemheader: " << systemheader << std::endl;
3306+
std::abort();
3307+
}
3308+
}
3309+
32703310
std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::TokenList &rawtokens, std::vector<std::string> &filenames, const simplecpp::DUI &dui, simplecpp::OutputList *outputList)
32713311
{
32723312
#ifdef SIMPLECPP_WINDOWS
@@ -3343,7 +3383,7 @@ std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::To
33433383
TokenList *tokens = new TokenList(header2, filenames, outputList);
33443384
if (dui.removeComments)
33453385
tokens->removeComments();
3346-
ret[header2] = tokens;
3386+
safeInsertTokenListToMap(ret, header2, tokens, header, rawtok->location.file(), systemheader, "simplecpp::load");
33473387
if (tokens->front())
33483388
filelist.push_back(tokens->front());
33493389
}
@@ -3630,7 +3670,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
36303670
TokenList * const tokens = new TokenList(header2, files, outputList);
36313671
if (dui.removeComments)
36323672
tokens->removeComments();
3633-
filedata[header2] = tokens;
3673+
safeInsertTokenListToMap(filedata, header2, tokens, header, rawtok->location.file(), systemheader, "simplecpp::preprocess");
36343674
}
36353675
}
36363676
if (header2.empty()) {

0 commit comments

Comments
 (0)