Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 36 additions & 24 deletions simplecpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
#include <sstream>
#include <stack>
#include <stdexcept>
#if __cplusplus >= 201103L
#include <unordered_map>
#endif
#include <utility>

#ifdef SIMPLECPP_WINDOWS
Expand Down Expand Up @@ -155,7 +158,7 @@ const std::string simplecpp::Location::emptyFileName;

void simplecpp::Location::adjust(const std::string &str)
{
if (str.find_first_of("\r\n") == std::string::npos) {
if (strpbrk(str.c_str(), "\r\n") == nullptr) {
col += str.size();
return;
}
Expand Down Expand Up @@ -453,6 +456,8 @@ void simplecpp::TokenList::lineDirective(unsigned int fileIndex, unsigned int li
}
}

static const std::string COMMENT_END("*/");

void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filename, OutputList *outputList)
{
std::stack<simplecpp::Location> loc;
Expand Down Expand Up @@ -593,7 +598,7 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen
ch = readChar(istr,bom);
while (istr.good()) {
currentToken += ch;
if (currentToken.size() >= 4U && endsWith(currentToken, "*/"))
if (currentToken.size() >= 4U && endsWith(currentToken, COMMENT_END))
break;
ch = readChar(istr,bom);
}
Expand Down Expand Up @@ -1200,12 +1205,12 @@ std::string simplecpp::TokenList::lastLine(int maxsize) const
for (const Token *tok = cback(); sameline(tok,cback()); tok = tok->previous) {
if (tok->comment)
continue;
if (++count > maxsize)
return "";
if (!ret.empty())
ret.insert(0, 1, ' ');
ret.insert(0, tok->str()[0] == '\"' ? std::string("%str%")
: tok->number ? std::string("%num%") : tok->str());
if (++count > maxsize)
return "";
}
return ret;
}
Expand All @@ -1222,6 +1227,13 @@ unsigned int simplecpp::TokenList::fileIndex(const std::string &filename)


namespace simplecpp {
class Macro;
#if __cplusplus >= 201103L
using MacroMap = std::unordered_map<TokenString,Macro>;
#else
typedef std::map<TokenString,Macro> MacroMap;
#endif

class Macro {
public:
explicit Macro(std::vector<std::string> &f) : nameTokDef(nullptr), variadic(false), valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(f), valueDefinedInCode_(false) {}
Expand Down Expand Up @@ -1281,7 +1293,7 @@ namespace simplecpp {
*/
const Token * expand(TokenList * const output,
const Token * rawtok,
const std::map<TokenString,Macro> &macros,
const MacroMap &macros,
std::vector<std::string> &inputFiles) const {
std::set<TokenString> expandedmacros;

Expand Down Expand Up @@ -1335,7 +1347,7 @@ namespace simplecpp {
break;
if (output2.cfront() != output2.cback() && macro2tok->str() == this->name())
break;
const std::map<TokenString,Macro>::const_iterator macro = macros.find(macro2tok->str());
const MacroMap::const_iterator macro = macros.find(macro2tok->str());
if (macro == macros.end() || !macro->second.functionLike())
break;
TokenList rawtokens2(inputFiles);
Expand Down Expand Up @@ -1498,7 +1510,7 @@ namespace simplecpp {
const Token *appendTokens(TokenList *tokens,
const Location &rawloc,
const Token * const lpar,
const std::map<TokenString,Macro> &macros,
const MacroMap &macros,
const std::set<TokenString> &expandedmacros,
const std::vector<const Token*> &parametertokens) const {
if (!lpar || lpar->op != '(')
Expand All @@ -1514,7 +1526,7 @@ namespace simplecpp {
} else {
if (!expandArg(tokens, tok, rawloc, macros, expandedmacros, parametertokens)) {
bool expanded = false;
const std::map<TokenString, Macro>::const_iterator it = macros.find(tok->str());
const MacroMap::const_iterator it = macros.find(tok->str());
if (it != macros.end() && expandedmacros.find(tok->str()) == expandedmacros.end()) {
const Macro &m = it->second;
if (!m.functionLike()) {
Expand Down Expand Up @@ -1544,7 +1556,7 @@ namespace simplecpp {
return sameline(lpar,tok) ? tok : nullptr;
}

const Token * expand(TokenList * const output, const Location &loc, const Token * const nameTokInst, const std::map<TokenString,Macro> &macros, std::set<TokenString> expandedmacros, bool first=false) const {
const Token * expand(TokenList * const output, const Location &loc, const Token * const nameTokInst, const MacroMap &macros, std::set<TokenString> expandedmacros, bool first=false) const {

if (!first)
expandedmacros.insert(nameTokInst->str());
Expand Down Expand Up @@ -1599,7 +1611,7 @@ namespace simplecpp {
}
}

const std::map<TokenString,Macro>::const_iterator m = macros.find("__COUNTER__");
const MacroMap::const_iterator m = macros.find("__COUNTER__");

if (!counter || m == macros.end())
parametertokens2.swap(parametertokens1);
Expand Down Expand Up @@ -1690,7 +1702,7 @@ namespace simplecpp {
return functionLike() ? parametertokens2.back()->next : nameTokInst->next;
}

const Token *recursiveExpandToken(TokenList *output, TokenList &temp, const Location &loc, const Token *tok, const std::map<TokenString,Macro> &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
const Token *recursiveExpandToken(TokenList *output, TokenList &temp, const Location &loc, const Token *tok, const MacroMap &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
if (!(temp.cback() && temp.cback()->name && tok->next && tok->next->op == '(')) {
output->takeTokens(temp);
return tok->next;
Expand All @@ -1701,7 +1713,7 @@ namespace simplecpp {
return tok->next;
}

const std::map<TokenString, Macro>::const_iterator it = macros.find(temp.cback()->str());
const MacroMap::const_iterator it = macros.find(temp.cback()->str());
if (it == macros.end() || expandedmacros.find(temp.cback()->str()) != expandedmacros.end()) {
output->takeTokens(temp);
return tok->next;
Expand All @@ -1725,7 +1737,7 @@ namespace simplecpp {
return tok2->next;
}

const Token *expandToken(TokenList *output, const Location &loc, const Token *tok, const std::map<TokenString,Macro> &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
const Token *expandToken(TokenList *output, const Location &loc, const Token *tok, const MacroMap &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
// Not name..
if (!tok->name) {
output->push_back(newMacroToken(tok->str(), loc, true, tok));
Expand All @@ -1740,7 +1752,7 @@ namespace simplecpp {
}

// Macro..
const std::map<TokenString, Macro>::const_iterator it = macros.find(tok->str());
const MacroMap::const_iterator it = macros.find(tok->str());
if (it != macros.end() && expandedmacros.find(tok->str()) == expandedmacros.end()) {
std::set<std::string> expandedmacros2(expandedmacros);
expandedmacros2.insert(tok->str());
Expand Down Expand Up @@ -1819,7 +1831,7 @@ namespace simplecpp {
return true;
}

bool expandArg(TokenList *output, const Token *tok, const Location &loc, const std::map<TokenString, Macro> &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
bool expandArg(TokenList *output, const Token *tok, const Location &loc, const MacroMap &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
if (!tok->name)
return false;
const unsigned int argnr = getArgNum(tok->str());
Expand All @@ -1828,7 +1840,7 @@ namespace simplecpp {
if (variadic && argnr + 1U >= parametertokens.size()) // empty variadic parameter
return true;
for (const Token *partok = parametertokens[argnr]->next; partok != parametertokens[argnr + 1U];) {
const std::map<TokenString, Macro>::const_iterator it = macros.find(partok->str());
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()))
partok = it->second.expand(output, loc, partok, macros, expandedmacros);
else {
Expand All @@ -1850,7 +1862,7 @@ namespace simplecpp {
* @param parametertokens parameters given when expanding this macro
* @return token after the X
*/
const Token *expandHash(TokenList *output, const Location &loc, const Token *tok, const std::map<TokenString, Macro> &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
const Token *expandHash(TokenList *output, const Location &loc, const Token *tok, const MacroMap &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
TokenList tokenListHash(files);
tok = expandToken(&tokenListHash, loc, tok->next, macros, expandedmacros, parametertokens);
std::ostringstream ostr;
Expand All @@ -1873,7 +1885,7 @@ namespace simplecpp {
* @param parametertokens parameters given when expanding this macro
* @return token after B
*/
const Token *expandHashHash(TokenList *output, const Location &loc, const Token *tok, const std::map<TokenString, Macro> &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
const Token *expandHashHash(TokenList *output, const Location &loc, const Token *tok, const MacroMap &macros, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> &parametertokens) const {
Token *A = output->back();
if (!A)
throw invalidHashHash(tok->location, name());
Expand Down Expand Up @@ -1930,7 +1942,7 @@ namespace simplecpp {
tokens.push_back(new Token(strAB, tok->location));
// for function like macros, push the (...)
if (tokensB.empty() && sameline(B,B->next) && B->next->op=='(') {
const std::map<TokenString,Macro>::const_iterator it = macros.find(strAB);
const MacroMap::const_iterator it = macros.find(strAB);
if (it != macros.end() && expandedmacros.find(strAB) == expandedmacros.end() && it->second.functionLike()) {
const Token *tok2 = appendTokens(&tokens, loc, B->next, macros, expandedmacros, parametertokens);
if (tok2)
Expand Down Expand Up @@ -2795,10 +2807,10 @@ std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::To
return ret;
}

static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token **tok1, std::map<std::string, simplecpp::Macro> &macros, std::vector<std::string> &files, simplecpp::OutputList *outputList)
static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token **tok1, simplecpp::MacroMap &macros, std::vector<std::string> &files, simplecpp::OutputList *outputList)
{
const simplecpp::Token *tok = *tok1;
const std::map<std::string,simplecpp::Macro>::const_iterator it = macros.find(tok->str());
const simplecpp::MacroMap::const_iterator it = macros.find(tok->str());
if (it != macros.end()) {
simplecpp::TokenList value(files);
try {
Expand Down Expand Up @@ -2847,7 +2859,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
sizeOfType.insert(std::make_pair("long double *", sizeof(long double *)));

const bool hasInclude = (dui.std.size() == 5 && dui.std.compare(0,3,"c++") == 0 && dui.std >= "c++17");
std::map<TokenString, Macro> macros;
MacroMap macros;
for (std::list<std::string>::const_iterator it = dui.defines.begin(); it != dui.defines.end(); ++it) {
const std::string &macrostr = *it;
const std::string::size_type eq = macrostr.find('=');
Expand Down Expand Up @@ -2947,7 +2959,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
try {
const Macro &macro = Macro(rawtok->previous, files);
if (dui.undefined.find(macro.name()) == dui.undefined.end()) {
std::map<TokenString, Macro>::iterator it = macros.find(macro.name());
MacroMap::iterator it = macros.find(macro.name());
if (it == macros.end())
macros.insert(std::pair<TokenString, Macro>(macro.name(), macro));
else
Expand Down Expand Up @@ -3234,7 +3246,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
}

if (macroUsage) {
for (std::map<TokenString, simplecpp::Macro>::const_iterator macroIt = macros.begin(); macroIt != macros.end(); ++macroIt) {
for (simplecpp::MacroMap::const_iterator macroIt = macros.begin(); macroIt != macros.end(); ++macroIt) {
const Macro &macro = macroIt->second;
const std::list<Location> &usage = macro.usage();
for (std::list<Location>::const_iterator usageIt = usage.begin(); usageIt != usage.end(); ++usageIt) {
Expand Down
6 changes: 3 additions & 3 deletions simplecpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <cctype>
#include <cstddef>
#include <cstring>
#include <istream>
#include <list>
#include <map>
Expand Down Expand Up @@ -105,13 +106,12 @@ namespace simplecpp {
}

Token(const Token &tok) :
macro(tok.macro), location(tok.location), previous(nullptr), next(nullptr), string(tok.string) {
flags();
macro(tok.macro), op(tok.op), comment(tok.comment), name(tok.name), number(tok.number), location(tok.location), previous(nullptr), next(nullptr), string(tok.string) {
}

void flags() {
name = (std::isalpha((unsigned char)string[0]) || string[0] == '_' || string[0] == '$')
&& (string.find('\'') == string.npos);
&& (std::memchr(string.c_str(), '\'', string.size()) == nullptr);
comment = string.size() > 1U && string[0] == '/' && (string[1] == '/' || string[1] == '*');
number = std::isdigit((unsigned char)string[0]) || (string.size() > 1U && string[0] == '-' && std::isdigit((unsigned char)string[1]));
op = (string.size() == 1U) ? string[0] : '\0';
Expand Down