bump simplecpp

This commit is contained in:
Daniel Marjamäki 2016-07-23 16:26:11 +02:00
parent f931c0cf2b
commit 88d1911538
1 changed files with 81 additions and 84 deletions

View File

@ -755,67 +755,64 @@ public:
} }
} }
const Token * expand(TokenList * const output,
const Token * rawtok,
const std::map<TokenString,Macro> &macros,
std::vector<std::string> &files) const {
std::set<TokenString> expandedmacros;
TokenList output2(files);
rawtok = expand(&output2,rawtok->location,rawtok,macros,expandedmacros);
while (output2.cend() && rawtok && (rawtok->op == '(' || output2.cend()->op == '(')) {
Token* macro2tok = output2.end();
if (macro2tok->op == '(')
macro2tok = macro2tok->previous;
if (!macro2tok || !macro2tok->name)
break;
if (output2.cbegin() != output2.cend() && macro2tok->str == this->name())
break;
const std::map<TokenString,Macro>::const_iterator macro = macros.find(macro2tok->str);
if (macro == macros.end() || !macro->second.functionLike())
break;
TokenList rawtokens2(files);
while (macro2tok) {
Token *next = macro2tok->next;
rawtokens2.push_back(new Token(*macro2tok));
output2.deleteToken(macro2tok);
macro2tok = next;
}
unsigned int par = (rawtokens2.cend()->op == '(') ? 1U : 0U;
const Token *rawtok2 = rawtok;
for (; rawtok2; rawtok2 = rawtok2->next) {
rawtokens2.push_back(new Token(*rawtok2));
if (rawtok2->op == '(')
++par;
else if (rawtok2->op == ')') {
if (par <= 1U)
break;
--par;
}
}
if (!rawtok2 || par != 1U)
break;
if (macro->second.expand(&output2, rawtok->location, rawtokens2.cbegin(), macros, expandedmacros) != NULL)
break;
rawtok = rawtok2->next;
}
output->takeTokens(output2);
return rawtok;
}
const Token * expand(TokenList * const output, const Location &loc, const Token * const nameToken, const std::map<TokenString,Macro> &macros, std::set<TokenString> expandedmacros) const { const Token * expand(TokenList * const output, const Location &loc, const Token * const nameToken, const std::map<TokenString,Macro> &macros, std::set<TokenString> expandedmacros) const {
const std::set<TokenString> expandedmacros1(expandedmacros); const std::set<TokenString> expandedmacros1(expandedmacros);
expandedmacros.insert(nameToken->str); expandedmacros.insert(nameToken->str);
usageList.push_back(loc); usageList.push_back(loc);
if (!functionLike()) { const std::vector<const Token*> parametertokens(getMacroParameters(nameToken, !expandedmacros1.empty()));
Token * const token1 = output->end();
for (const Token *macro = valueToken; macro != endToken;) {
const std::map<TokenString, Macro>::const_iterator it = macros.find(macro->str);
if (it != macros.end() && expandedmacros.find(macro->str) == expandedmacros.end()) {
try {
const Token *macro2 = it->second.expand(output, loc, macro, macros, expandedmacros);
while (macro != macro2 && macro != endToken)
macro = macro->next;
} catch (const wrongNumberOfParameters &) {
if (sameline(macro,macro->next) && macro->next->op == '(') {
unsigned int par = 1U;
for (const Token *tok = macro->next->next; sameline(macro,tok); tok = tok->next) {
if (tok->op == '(')
++par;
else if (tok->op == ')') {
--par;
if (par == 0U)
break;
}
}
if (par > 0U) {
TokenList tokens(files);
const Token *tok;
for (tok = macro; sameline(macro,tok); tok = tok->next)
tokens.push_back(new Token(*tok));
for (tok = nameToken->next; tok; tok = tok->next) {
tokens.push_back(new Token(tok->str, macro->location));
if (tok->op == '(')
++par;
else if (tok->op == ')') {
--par;
if (par == 0U)
break;
}
}
if (par == 0U) {
it->second.expand(output, loc, tokens.cbegin(), macros, expandedmacros);
return tok->next;
}
}
} else {
output->push_back(newMacroToken(macro->str, loc, false));
macro = macro->next;
}
}
} else {
output->push_back(newMacroToken(macro->str, loc, false));
macro = macro->next;
}
}
setMacroName(output, token1, expandedmacros1);
return nameToken->next;
}
Token * const output_end_1 = output->end();
if (functionLike()) {
// No arguments => not macro expansion // No arguments => not macro expansion
if (nameToken->next && nameToken->next->op != '(') { if (nameToken->next && nameToken->next->op != '(') {
output->push_back(new Token(nameToken->str, loc)); output->push_back(new Token(nameToken->str, loc));
@ -823,10 +820,10 @@ public:
} }
// Parse macro-call // Parse macro-call
const std::vector<const Token*> parametertokens(getMacroParameters(nameToken, !expandedmacros1.empty()));
if (parametertokens.size() != args.size() + (args.empty() ? 2U : 1U)) { if (parametertokens.size() != args.size() + (args.empty() ? 2U : 1U)) {
throw wrongNumberOfParameters(nameToken->location, name()); throw wrongNumberOfParameters(nameToken->location, name());
} }
}
// expand // expand
for (const Token *tok = valueToken; tok != endToken;) { for (const Token *tok = valueToken; tok != endToken;) {
@ -871,7 +868,10 @@ public:
} }
} }
return parametertokens.back()->next; if (!functionLike())
setMacroName(output, output_end_1, expandedmacros1);
return functionLike() ? parametertokens.back()->next : nameToken->next;
} }
const TokenString &name() const { const TokenString &name() const {
@ -886,6 +886,13 @@ public:
return usageList; return usageList;
} }
bool functionLike() const {
return nameToken->next &&
nameToken->next->op == '(' &&
sameline(nameToken, nameToken->next) &&
nameToken->next->location.col == nameToken->location.col + nameToken->str.size();
}
struct Error { struct Error {
Error(const Location &loc, const std::string &s) : location(loc), what(s) {} Error(const Location &loc, const std::string &s) : location(loc), what(s) {}
Location location; Location location;
@ -968,7 +975,7 @@ private:
} }
std::vector<const Token *> getMacroParameters(const Token *nameToken, bool def) const { std::vector<const Token *> getMacroParameters(const Token *nameToken, bool def) const {
if (!nameToken->next || nameToken->next->op != '(') if (!nameToken->next || nameToken->next->op != '(' || !functionLike())
return std::vector<const Token *>(); return std::vector<const Token *>();
std::vector<const Token *> parametertokens; std::vector<const Token *> parametertokens;
@ -1061,20 +1068,20 @@ private:
// Macro.. // Macro..
const std::map<TokenString, Macro>::const_iterator it = macros.find(tok->str); const std::map<TokenString, Macro>::const_iterator it = macros.find(tok->str);
if (it != macros.end() && expandedmacros1.find(tok->str) == expandedmacros1.end()) { if (it != macros.end() && expandedmacros.find(tok->str) == expandedmacros.end()) {
const Macro &calledMacro = it->second; const Macro &calledMacro = it->second;
if (!calledMacro.functionLike()) if (!calledMacro.functionLike())
return calledMacro.expand(output, loc, tok, macros, expandedmacros); return calledMacro.expand(output, loc, tok, macros, expandedmacros);
if (!sameline(tok, tok->next) || tok->next->op != '(') { if (!sameline(tok, tok->next) || tok->next->op != '(') {
// FIXME: handle this output->push_back(newMacroToken(tok->str, loc, false));
throw wrongNumberOfParameters(tok->location, tok->str); return tok->next;
} }
TokenList tokens(files); TokenList tokens(files);
tokens.push_back(new Token(*tok)); tokens.push_back(new Token(*tok));
const Token *tok2 = appendTokens(&tokens, tok->next, macros, expandedmacros1, expandedmacros, parametertokens); const Token *tok2 = appendTokens(&tokens, tok->next, macros, expandedmacros1, expandedmacros, parametertokens);
if (!tok2) { if (!tok2) {
// FIXME: handle this output->push_back(newMacroToken(tok->str, loc, false));
throw wrongNumberOfParameters(tok->location, tok->str); return tok->next;
} }
calledMacro.expand(output, loc, tokens.cbegin(), macros, expandedmacros); calledMacro.expand(output, loc, tokens.cbegin(), macros, expandedmacros);
return tok2->next; return tok2->next;
@ -1136,13 +1143,6 @@ private:
} }
} }
bool functionLike() const {
return nameToken->next &&
nameToken->next->op == '(' &&
sameline(nameToken, nameToken->next) &&
nameToken->next->location.col == nameToken->location.col + nameToken->str.size();
}
const Token *nameToken; const Token *nameToken;
std::vector<TokenString> args; std::vector<TokenString> args;
bool variadic; bool variadic;
@ -1491,9 +1491,8 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
const std::map<std::string,Macro>::const_iterator it = macros.find(tok->str); const std::map<std::string,Macro>::const_iterator it = macros.find(tok->str);
if (it != macros.end()) { if (it != macros.end()) {
TokenList value(files); TokenList value(files);
std::set<TokenString> expandedmacros;
try { try {
it->second.expand(&value, tok->location, tok, macros, expandedmacros); it->second.expand(&value, tok, macros, files);
} catch (Macro::Error &err) { } catch (Macro::Error &err) {
Output out(rawtok->location.files); Output out(rawtok->location.files);
out.type = Output::ERROR; out.type = Output::ERROR;
@ -1504,8 +1503,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
output.clear(); output.clear();
return; return;
} }
for (const Token *tok2 = value.cbegin(); tok2; tok2 = tok2->next) expr.takeTokens(value);
expr.push_back(new Token(tok2->str, tok->location));
} else { } else {
expr.push_back(new Token(*tok)); expr.push_back(new Token(*tok));
} }
@ -1564,9 +1562,8 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
if (macros.find(rawtok->str) != macros.end()) { if (macros.find(rawtok->str) != macros.end()) {
std::map<TokenString,Macro>::const_iterator macro = macros.find(rawtok->str); std::map<TokenString,Macro>::const_iterator macro = macros.find(rawtok->str);
if (macro != macros.end()) { if (macro != macros.end()) {
std::set<TokenString> expandedmacros;
try { try {
rawtok = macro->second.expand(&output,rawtok->location,rawtok,macros,expandedmacros); rawtok = macro->second.expand(&output, rawtok, macros, files);
} catch (const simplecpp::Macro::Error &err) { } catch (const simplecpp::Macro::Error &err) {
Output out(err.location.files); Output out(err.location.files);
out.type = Output::ERROR; out.type = Output::ERROR;