Skip to content

Commit 9846c5d

Browse files
committed
vendor(simplecpp): Update simplecpp.{h,cpp} to patched-2025-08-30-37fa4f49b (bfc53ad); was master (538c5c4)
Upstream: commontk/simplecpp@bfc53ad Source date: 2025-08-30 Files: generator/simplecpp/simplecpp.h, generator/simplecpp/simplecpp.cpp Patch: generator/simplecpp/do_not_stop_on_error.patch re-applied Compare: commontk/simplecpp@37fa4f4...bfc53ad
1 parent 2b02b85 commit 9846c5d

File tree

2 files changed

+196
-21
lines changed

2 files changed

+196
-21
lines changed

generator/simplecpp/simplecpp.cpp

Lines changed: 138 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "simplecpp.h"
1414

1515
#include <algorithm>
16+
#include <array>
1617
#include <cassert>
1718
#include <cctype>
1819
#include <climits>
@@ -2429,6 +2430,27 @@ static bool isAbsolutePath(const std::string &path)
24292430
}
24302431
#endif
24312432

2433+
namespace {
2434+
// "<Pkg/Hdr.h>" -> "<Pkg.framework/Headers/Hdr.h>" (and PrivateHeaders variant).
2435+
// Returns candidates in priority order (Headers, then PrivateHeaders).
2436+
inline std::array<std::string,2>
2437+
toAppleFrameworkRelatives(const std::string& header)
2438+
{
2439+
const std::size_t slash = header.find('/');
2440+
if (slash == std::string::npos)
2441+
return { header, header }; // no transformation applicable
2442+
const std::string pkg = header.substr(0, slash);
2443+
const std::string tail = header.substr(slash); // includes '/'
2444+
return { pkg + ".framework/Headers" + tail,
2445+
pkg + ".framework/PrivateHeaders" + tail };
2446+
}
2447+
2448+
inline void push_unique(std::vector<std::string> &v, std::string p) {
2449+
if (!p.empty() && (v.empty() || v.back() != p))
2450+
v.push_back(std::move(p));
2451+
}
2452+
}
2453+
24322454
namespace simplecpp {
24332455
/**
24342456
* perform path simplifications for . and ..
@@ -2999,12 +3021,61 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
29993021
}
30003022
}
30013023

3002-
// search the header on the include paths (provided by the flags "-I...")
3003-
for (const auto &includePath : dui.includePaths) {
3004-
std::string path = openHeaderDirect(f, simplecpp::simplifyPath(includePath + "/" + header));
3005-
if (!path.empty())
3006-
return path;
3024+
// Build an ordered, typed path list:
3025+
// - Prefer DUI::searchPaths when provided (interleaved -I/-F/-iframework).
3026+
// - Otherwise mirror legacy includePaths into Include entries (back-compat).
3027+
std::vector<simplecpp::DUI::SearchPath> searchPaths;
3028+
if (!dui.searchPaths.empty()) {
3029+
searchPaths = dui.searchPaths;
3030+
} else {
3031+
searchPaths.reserve(dui.includePaths.size());
3032+
for (const auto &includePath : dui.includePaths)
3033+
searchPaths.push_back({includePath, simplecpp::DUI::PathKind::Include});
30073034
}
3035+
3036+
// Interleave -I and -F in CLI order
3037+
for (const auto &searchPath : searchPaths) {
3038+
if (searchPath.kind == simplecpp::DUI::PathKind::Include) {
3039+
const std::string path = openHeaderDirect(f, simplecpp::simplifyPath(searchPath.path + "/" + header));
3040+
if (!path.empty())
3041+
return path;
3042+
} else if (searchPath.kind == simplecpp::DUI::PathKind::Framework) {
3043+
// try Headers then PrivateHeaders
3044+
const auto relatives = toAppleFrameworkRelatives(header);
3045+
if (relatives[0] != header) { // Skip if no framework rewrite was applied.
3046+
for (const auto &rel : relatives) {
3047+
const std::string frameworkPath = openHeaderDirect(f, simplecpp::simplifyPath(searchPath.path + "/" + rel));
3048+
if (!frameworkPath.empty())
3049+
return frameworkPath;
3050+
}
3051+
}
3052+
}
3053+
}
3054+
3055+
// -isystem
3056+
for (const auto &searchPath : searchPaths) {
3057+
if (searchPath.kind == simplecpp::DUI::PathKind::SystemInclude) {
3058+
std::string path = openHeaderDirect(f, simplecpp::simplifyPath(searchPath.path + "/" + header));
3059+
if (!path.empty())
3060+
return path;
3061+
}
3062+
}
3063+
3064+
// -iframework
3065+
for (const auto &searchPath : searchPaths) {
3066+
if (searchPath.kind == simplecpp::DUI::PathKind::SystemFramework) {
3067+
const auto relatives = toAppleFrameworkRelatives(header);
3068+
if (relatives[0] != header) { // Skip if no framework rewrite was applied.
3069+
// Try Headers then PrivateHeaders
3070+
for (const auto &rel : relatives) {
3071+
const std::string frameworkPath = openHeaderDirect(f, simplecpp::simplifyPath(searchPath.path + "/" + rel));
3072+
if (!frameworkPath.empty())
3073+
return frameworkPath;
3074+
}
3075+
}
3076+
}
3077+
}
3078+
30083079
return "";
30093080
}
30103081

@@ -3036,6 +3107,7 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
30363107

30373108
std::pair<simplecpp::FileData *, bool> 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)
30383109
{
3110+
// Absolute path: load directly
30393111
if (isAbsolutePath(header)) {
30403112
auto ins = mNameMap.emplace(simplecpp::simplifyPath(header), nullptr);
30413113

@@ -3051,32 +3123,78 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::get(const std::
30513123
return {nullptr, false};
30523124
}
30533125

3126+
// Build ordered candidates.
3127+
std::vector<std::string> candidates;
3128+
3129+
// Prefer first to search the header relatively to source file if found, when not a system header
30543130
if (!systemheader) {
3055-
auto ins = mNameMap.emplace(simplecpp::simplifyPath(dirPath(sourcefile) + header), nullptr);
3131+
push_unique(candidates, simplecpp::simplifyPath(dirPath(sourcefile) + header));
3132+
}
30563133

3057-
if (ins.second) {
3058-
const auto ret = tryload(ins.first, dui, filenames, outputList);
3059-
if (ret.first != nullptr) {
3060-
return ret;
3134+
// Build an ordered, typed path list:
3135+
// - Prefer DUI::searchPaths when provided (interleaved -I/-F/-iframework).
3136+
// - Otherwise mirror legacy includePaths into Include entries (back-compat).
3137+
std::vector<simplecpp::DUI::SearchPath> searchPaths;
3138+
if (!dui.searchPaths.empty()) {
3139+
searchPaths = dui.searchPaths;
3140+
} else {
3141+
searchPaths.reserve(dui.includePaths.size());
3142+
for (const auto &p : dui.includePaths)
3143+
searchPaths.push_back({p, simplecpp::DUI::PathKind::Include});
3144+
}
3145+
3146+
// Interleave -I and -F in CLI order
3147+
for (const auto &searchPath : searchPaths) {
3148+
if (searchPath.kind == simplecpp::DUI::PathKind::Include) {
3149+
push_unique(candidates, simplecpp::simplifyPath(searchPath.path + "/" + header));
3150+
} else if (searchPath.kind == simplecpp::DUI::PathKind::Framework) {
3151+
// Try Headers then PrivateHeaders
3152+
const auto relatives = toAppleFrameworkRelatives(header);
3153+
if (relatives[0] != header) { // Skip if no framework rewrite was applied.
3154+
push_unique(candidates, simplecpp::simplifyPath(searchPath.path + "/" + relatives[0]));
3155+
push_unique(candidates, simplecpp::simplifyPath(searchPath.path + "/" + relatives[1]));
30613156
}
3062-
} else if (ins.first->second != nullptr) {
3063-
return {ins.first->second, false};
30643157
}
30653158
}
30663159

3067-
for (const auto &includePath : dui.includePaths) {
3068-
auto ins = mNameMap.emplace(simplecpp::simplifyPath(includePath + "/" + header), nullptr);
3160+
// -isystem
3161+
for (const auto &searchPath : searchPaths) {
3162+
if (searchPath.kind == DUI::PathKind::SystemInclude) {
3163+
push_unique(candidates, simplecpp::simplifyPath(searchPath.path + "/" + header));
3164+
}
3165+
}
30693166

3070-
if (ins.second) {
3071-
const auto ret = tryload(ins.first, dui, filenames, outputList);
3072-
if (ret.first != nullptr) {
3073-
return ret;
3167+
// -iframework
3168+
for (const auto &searchPath : searchPaths) {
3169+
if (searchPath.kind == simplecpp::DUI::PathKind::SystemFramework) {
3170+
// Try Headers then PrivateHeaders
3171+
const auto relatives = toAppleFrameworkRelatives(header);
3172+
if (relatives[0] != header) { // Skip if no framework rewrite was applied.
3173+
push_unique(candidates, simplecpp::simplifyPath(searchPath.path + "/" + relatives[0]));
3174+
push_unique(candidates, simplecpp::simplifyPath(searchPath.path + "/" + relatives[1]));
30743175
}
3075-
} else if (ins.first->second != nullptr) {
3076-
return {ins.first->second, false};
30773176
}
30783177
}
30793178

3179+
// Try loading each candidate path (left-to-right).
3180+
for (const std::string &candidate : candidates) {
3181+
// Already loaded?
3182+
auto it = mNameMap.find(candidate);
3183+
if (it != mNameMap.end()) {
3184+
return {it->second, false};
3185+
}
3186+
3187+
auto ins = mNameMap.emplace(candidate, static_cast<FileData *>(nullptr));
3188+
const auto ret = tryload(ins.first, dui, filenames, outputList);
3189+
if (ret.first != nullptr) {
3190+
return ret;
3191+
}
3192+
3193+
// Failed: remove placeholder so we can retry later if needed.
3194+
mNameMap.erase(ins.first);
3195+
}
3196+
3197+
// Not found.
30803198
return {nullptr, false};
30813199
}
30823200

generator/simplecpp/simplecpp.h

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,13 +395,70 @@ namespace simplecpp {
395395

396396
/**
397397
* Command line preprocessor settings.
398-
* On the command line these are configured by -D, -U, -I, --include, -std
398+
*
399+
* Mirrors typical compiler options:
400+
* -D <name>=<value> Add macro definition
401+
* -U <name> Undefine macro
402+
* -I <dir> Add include search directory
403+
* -isystem <dir> Add system include search directory
404+
* -F <dir> Add framework search directory (Darwin)
405+
* -iframework <dir> Add system framework search directory (Darwin)
406+
* --include <file> Force inclusion of a header
407+
* -std=<version> Select language standard (C++17, C23, etc.)
408+
*
409+
* Path search behavior:
410+
* - If searchPaths is non-empty, it is used directly, preserving the
411+
* left-to-right order and distinguishing between Include, Framework,
412+
* and SystemFramework kinds.
413+
* - If searchPaths is empty, legacy includePaths is used instead, and
414+
* each entry is treated as a normal Include path (for backward
415+
* compatibility).
399416
*/
400417
struct SIMPLECPP_LIB DUI {
401418
DUI() : clearIncludeCache(false), removeComments(false) {}
419+
420+
// Typed search path entry. Mirrors GCC behavior for -I, -isystem, -F, -iframework.
421+
enum class PathKind { Include, SystemInclude, Framework, SystemFramework };
422+
struct SearchPath {
423+
std::string path;
424+
PathKind kind;
425+
};
426+
427+
/**
428+
* Mirrors compiler option -I<dir>
429+
*
430+
* If 'legacy' is true, the path is added to the 'includePaths' vector;
431+
* otherwise, it is added to 'searchPaths' with 'PathKind::Include'.
432+
*/
433+
void addIncludePath(const std::string& path, bool legacy=false) {
434+
if (legacy) {
435+
includePaths.push_back(path);
436+
} else {
437+
searchPaths.push_back({path, PathKind::Include});
438+
}
439+
}
440+
/** Mirrors compiler option -I<dir> */
441+
void addSystemIncludePath(const std::string& path) {
442+
searchPaths.push_back({path, PathKind::SystemInclude});
443+
}
444+
/** Mirrors compiler option -F<dir> */
445+
void addFrameworkPath(const std::string& path) {
446+
searchPaths.push_back({path, PathKind::Framework});
447+
}
448+
/** Mirrors compiler option -iframework<dir> */
449+
void addSystemFrameworkPath(const std::string& path) {
450+
searchPaths.push_back({path, PathKind::SystemFramework});
451+
}
452+
402453
std::list<std::string> defines;
403454
std::set<std::string> undefined;
455+
456+
// Back-compat: legacy -I list. If searchPaths is empty at use time,
457+
// consumers should mirror includePaths -> searchPaths as Include.
404458
std::list<std::string> includePaths;
459+
// New: ordered, interleaved search paths with kind.
460+
std::vector<SearchPath> searchPaths;
461+
405462
std::list<std::string> includes;
406463
std::string std;
407464
bool clearIncludeCache;

0 commit comments

Comments
 (0)