Skip to content

Commit

Permalink
bump simplecpp to 1.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
danmar committed Feb 12, 2025
1 parent 3db72cf commit 185091d
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 58 deletions.
224 changes: 166 additions & 58 deletions externals/simplecpp/simplecpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
#ifdef SIMPLECPP_WINDOWS
#include <windows.h>
#undef ERROR
#else
#include <unistd.h>
#endif

#if __cplusplus >= 201103L
Expand Down Expand Up @@ -147,6 +149,11 @@ static unsigned long long stringToULL(const std::string &s)
return ret;
}

static bool startsWith(const std::string &s, const std::string &p)
{
return (s.size() >= p.size()) && std::equal(p.begin(), p.end(), s.begin());
}

static bool endsWith(const std::string &s, const std::string &e)
{
return (s.size() >= e.size()) && std::equal(e.rbegin(), e.rend(), s.rbegin());
Expand Down Expand Up @@ -947,7 +954,7 @@ void simplecpp::TokenList::constFold()
constFoldQuestionOp(&tok);

// If there is no '(' we are done with the constant folding
if (tok->op != '(')
if (!tok || tok->op != '(')
break;

if (!tok->next || !tok->next->next || tok->next->next->op != ')')
Expand Down Expand Up @@ -1157,10 +1164,7 @@ void simplecpp::TokenList::constFoldMulDivRem(Token *tok)
} else
continue;

tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
simpleSquash(tok, toString(result));
}
}

Expand All @@ -1180,10 +1184,7 @@ void simplecpp::TokenList::constFoldAddSub(Token *tok)
else
continue;

tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
simpleSquash(tok, toString(result));
}
}

Expand All @@ -1203,10 +1204,7 @@ void simplecpp::TokenList::constFoldShift(Token *tok)
else
continue;

tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
simpleSquash(tok, toString(result));
}
}

Expand Down Expand Up @@ -1240,10 +1238,7 @@ void simplecpp::TokenList::constFoldComparison(Token *tok)
else
continue;

tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
simpleSquash(tok, toString(result));
}
}

Expand Down Expand Up @@ -1275,14 +1270,53 @@ void simplecpp::TokenList::constFoldBitwise(Token *tok)
result = (stringToLL(tok->previous->str()) ^ stringToLL(tok->next->str()));
else /*if (*op == '|')*/
result = (stringToLL(tok->previous->str()) | stringToLL(tok->next->str()));
tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
simpleSquash(tok, toString(result));
}
}
}

void simplecpp::TokenList::simpleSquash(Token *&tok, const std::string & result)
{
tok = tok->previous;
tok->setstr(result);
deleteToken(tok->next);
deleteToken(tok->next);
}

void simplecpp::TokenList::squashTokens(Token *&tok, const std::set<std::string> & breakPoints, bool forwardDirection, const std::string & result)
{
const char * const brackets = forwardDirection ? "()" : ")(";
Token* Token::* const step = forwardDirection ? &Token::next : &Token::previous;
int skip = 0;
const Token * const tok1 = tok->*step;
while (tok1 && tok1->*step) {
if ((tok1->*step)->op == brackets[1]){
if (skip) {
--skip;
deleteToken(tok1->*step);
} else
break;
} else if ((tok1->*step)->op == brackets[0]) {
++skip;
deleteToken(tok1->*step);
} else if (skip) {
deleteToken(tok1->*step);
} else if (breakPoints.count((tok1->*step)->str()) != 0) {
break;
} else {
deleteToken(tok1->*step);
}
}
simpleSquash(tok, result);
}

static simplecpp::Token * constFoldGetOperand(simplecpp::Token * tok, bool forwardDirection)
{
simplecpp::Token* simplecpp::Token::* const step = forwardDirection ? &simplecpp::Token::next : &simplecpp::Token::previous;
const char bracket = forwardDirection ? ')' : '(';
return tok->*step && (tok->*step)->number && (!((tok->*step)->*step) || (((tok->*step)->*step)->op == bracket)) ? tok->*step : nullptr;
}

static const std::string AND("and");
static const std::string OR("or");
void simplecpp::TokenList::constFoldLogicalOp(Token *tok)
Expand All @@ -1296,21 +1330,24 @@ void simplecpp::TokenList::constFoldLogicalOp(Token *tok)
}
if (tok->str() != "&&" && tok->str() != "||")
continue;
if (!tok->previous || !tok->previous->number)
continue;
if (!tok->next || !tok->next->number)
const Token* const lhs = constFoldGetOperand(tok, false);
const Token* const rhs = constFoldGetOperand(tok, true);
if (!lhs) // if lhs is not a single number we don't need to fold
continue;

int result;
if (tok->str() == "||")
result = (stringToLL(tok->previous->str()) || stringToLL(tok->next->str()));
else /*if (tok->str() == "&&")*/
result = (stringToLL(tok->previous->str()) && stringToLL(tok->next->str()));

tok = tok->previous;
tok->setstr(toString(result));
deleteToken(tok->next);
deleteToken(tok->next);
std::set<std::string> breakPoints;
breakPoints.insert(":");
breakPoints.insert("?");
if (tok->str() == "||"){
if (stringToLL(lhs->str()) != 0LL || (rhs && stringToLL(rhs->str()) != 0LL))
squashTokens(tok, breakPoints, stringToLL(lhs->str()) != 0LL, toString(1));
} else /*if (tok->str() == "&&")*/ {
breakPoints.insert("||");
if (stringToLL(lhs->str()) == 0LL || (rhs && stringToLL(rhs->str()) == 0LL))
squashTokens(tok, breakPoints, stringToLL(lhs->str()) == 0LL, toString(0));
else if (rhs && stringToLL(lhs->str()) && stringToLL(rhs->str()))
simpleSquash(tok, "1");
}
}
}

Expand Down Expand Up @@ -2088,7 +2125,7 @@ namespace simplecpp {
if (expandArg(&temp, defToken, parametertokens))
macroName = temp.cback()->str();
if (expandArg(&temp, defToken->next->next->next, parametertokens))
macroName += temp.cback()->str();
macroName += temp.cback() ? temp.cback()->str() : "";
else
macroName += defToken->next->next->next->str();
lastToken = defToken->next->next->next;
Expand Down Expand Up @@ -2132,7 +2169,8 @@ namespace simplecpp {
for (const Token *partok = parametertokens[argnr]->next; partok != parametertokens[argnr + 1U];) {
const MacroMap::const_iterator it = macros.find(partok->str());
if (it != macros.end() && !partok->isExpandedFrom(&it->second) && (partok->str() == name() || expandedmacros.find(partok->str()) == expandedmacros.end())) {
const std::set<TokenString> expandedmacros2; // temporary amnesia to allow reexpansion of currently expanding macros during argument evaluation
std::set<TokenString> expandedmacros2(expandedmacros); // temporary amnesia to allow reexpansion of currently expanding macros during argument evaluation
expandedmacros2.erase(name());
partok = it->second.expand(output, loc, partok, macros, expandedmacros2);
} else {
output->push_back(newMacroToken(partok->str(), loc, isReplaced(expandedmacros), partok));
Expand Down Expand Up @@ -2680,6 +2718,46 @@ static bool isCpp17OrLater(const simplecpp::DUI &dui)
return !std_ver.empty() && (std_ver >= "201703L");
}


static std::string currentDirectoryOSCalc() {
#ifdef SIMPLECPP_WINDOWS
TCHAR NPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH, NPath);
return NPath;
#else
const std::size_t size = 1024;
char the_path[size];
getcwd(the_path, size);
return the_path;
#endif
}

static const std::string& currentDirectory() {
static const std::string curdir = simplecpp::simplifyPath(currentDirectoryOSCalc());
return curdir;
}

static std::string toAbsolutePath(const std::string& path) {
if (path.empty()) {
return path;// preserve error file path that is indicated by an empty string
}
if (!isAbsolutePath(path)) {
return currentDirectory() + "/" + path;
}
// otherwise
return path;
}

static std::pair<std::string, bool> extractRelativePathFromAbsolute(const std::string& absolutepath) {
static const std::string prefix = currentDirectory() + "/";
if (startsWith(absolutepath, prefix)) {
const std::size_t size = prefix.size();
return std::make_pair(absolutepath.substr(size, absolutepath.size() - size), true);
}
// otherwise
return std::make_pair("", false);
}

static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader);
static void simplifyHasInclude(simplecpp::TokenList &expr, const simplecpp::DUI &dui)
{
Expand Down Expand Up @@ -3098,9 +3176,12 @@ static std::string openHeader(std::ifstream &f, const std::string &path)

static std::string getRelativeFileName(const std::string &sourcefile, const std::string &header)
{
std::string path;
if (sourcefile.find_first_of("\\/") != std::string::npos)
return simplecpp::simplifyPath(sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header);
return simplecpp::simplifyPath(header);
path = sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header;
else
path = header;
return simplecpp::simplifyPath(path);
}

static std::string openHeaderRelative(std::ifstream &f, const std::string &sourcefile, const std::string &header)
Expand All @@ -3110,7 +3191,7 @@ static std::string openHeaderRelative(std::ifstream &f, const std::string &sourc

static std::string getIncludePathFileName(const std::string &includePath, const std::string &header)
{
std::string path = includePath;
std::string path = toAbsolutePath(includePath);
if (!path.empty() && path[path.size()-1U]!='/' && path[path.size()-1U]!='\\')
path += '/';
return path + header;
Expand All @@ -3119,9 +3200,9 @@ static std::string getIncludePathFileName(const std::string &includePath, const
static std::string openHeaderIncludePath(std::ifstream &f, const simplecpp::DUI &dui, const std::string &header)
{
for (std::list<std::string>::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) {
std::string simplePath = openHeader(f, getIncludePathFileName(*it, header));
if (!simplePath.empty())
return simplePath;
std::string path = openHeader(f, getIncludePathFileName(*it, header));
if (!path.empty())
return path;
}
return "";
}
Expand All @@ -3131,49 +3212,76 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
if (isAbsolutePath(header))
return openHeader(f, header);

std::string ret;

if (systemheader) {
ret = openHeaderIncludePath(f, dui, header);
return ret;
// always return absolute path for systemheaders
return toAbsolutePath(openHeaderIncludePath(f, dui, header));
}

std::string ret;

ret = openHeaderRelative(f, sourcefile, header);
if (ret.empty())
return openHeaderIncludePath(f, dui, header);
return toAbsolutePath(openHeaderIncludePath(f, dui, header));// in a similar way to system headers
return ret;
}

static std::string getFileName(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader)
static std::string findPathInMapBothRelativeAndAbsolute(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string& path) {
// here there are two possibilities - either we match this from absolute path or from a relative one
if (filedata.find(path) != filedata.end()) {// try first to respect the exact match
return path;
}
// otherwise - try to use the normalize to the correct representation
if (isAbsolutePath(path)) {
const std::pair<std::string, bool> relativeExtractedResult = extractRelativePathFromAbsolute(path);
if (relativeExtractedResult.second) {
const std::string relativePath = relativeExtractedResult.first;
if (filedata.find(relativePath) != filedata.end()) {
return relativePath;
}
}
} else {
const std::string absolutePath = toAbsolutePath(path);
if (filedata.find(absolutePath) != filedata.end())
return absolutePath;
}
// otherwise
return "";
}

static std::string getFileIdPath(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader)
{
if (filedata.empty()) {
return "";
}
if (isAbsolutePath(header)) {
return (filedata.find(header) != filedata.end()) ? simplecpp::simplifyPath(header) : "";
const std::string simplifiedHeaderPath = simplecpp::simplifyPath(header);
return (filedata.find(simplifiedHeaderPath) != filedata.end()) ? simplifiedHeaderPath : "";
}

if (!systemheader) {
const std::string relativeFilename = getRelativeFileName(sourcefile, header);
if (filedata.find(relativeFilename) != filedata.end())
return relativeFilename;
const std::string relativeOrAbsoluteFilename = getRelativeFileName(sourcefile, header);// unknown if absolute or relative, but always simplified
const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, relativeOrAbsoluteFilename);
if (!match.empty()) {
return match;
}
}

for (std::list<std::string>::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) {
std::string s = simplecpp::simplifyPath(getIncludePathFileName(*it, header));
if (filedata.find(s) != filedata.end())
return s;
const std::string match = findPathInMapBothRelativeAndAbsolute(filedata, simplecpp::simplifyPath(getIncludePathFileName(*it, header)));
if (!match.empty()) {
return match;
}
}

if (systemheader && filedata.find(header) != filedata.end())
return header;
return header;// system header that its file wasn't found in the included paths but alreasy in the filedata - return this as is

return "";
}

static bool hasFile(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader)
{
return !getFileName(filedata, sourcefile, header, dui, systemheader).empty();
return !getFileIdPath(filedata, sourcefile, header, dui, systemheader).empty();
}

std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::TokenList &rawtokens, std::vector<std::string> &filenames, const simplecpp::DUI &dui, simplecpp::OutputList *outputList)
Expand Down Expand Up @@ -3529,7 +3637,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL

const bool systemheader = (inctok->str()[0] == '<');
const std::string header(realFilename(inctok->str().substr(1U, inctok->str().size() - 2U)));
std::string header2 = getFileName(filedata, rawtok->location.file(), header, dui, systemheader);
std::string header2 = getFileIdPath(filedata, rawtok->location.file(), header, dui, systemheader);
if (header2.empty()) {
// try to load file..
std::ifstream f;
Expand Down
2 changes: 2 additions & 0 deletions externals/simplecpp/simplecpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ namespace simplecpp {
void constFoldLogicalOp(Token *tok);
void constFoldQuestionOp(Token **tok1);

void simpleSquash(Token *&tok, const std::string & result);
void squashTokens(Token *&tok, const std::set<std::string> & breakPoints, bool forwardDirection, const std::string & result);
std::string readUntil(Stream &stream, const Location &location, char start, char end, OutputList *outputList);
void lineDirective(unsigned int fileIndex, unsigned int line, Location *location);

Expand Down

0 comments on commit 185091d

Please sign in to comment.