Updated simplecpp to 95be502385518402ee61830be2ce3cd0ea02eee2
This commit is contained in:
parent
2f6350a0d0
commit
75528adea0
|
@ -36,9 +36,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
|
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
|
||||||
|
#define NOMINMAX
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#undef min
|
|
||||||
#undef max
|
|
||||||
#undef ERROR
|
#undef ERROR
|
||||||
#undef TRUE
|
#undef TRUE
|
||||||
#define SIMPLECPP_WINDOWS
|
#define SIMPLECPP_WINDOWS
|
||||||
|
@ -64,7 +63,8 @@ const simplecpp::TokenString ENDIF("endif");
|
||||||
const simplecpp::TokenString PRAGMA("pragma");
|
const simplecpp::TokenString PRAGMA("pragma");
|
||||||
const simplecpp::TokenString ONCE("once");
|
const simplecpp::TokenString ONCE("once");
|
||||||
|
|
||||||
template<class T> std::string toString(T t) {
|
template<class T> std::string toString(T t)
|
||||||
|
{
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
ostr << t;
|
ostr << t;
|
||||||
return ostr.str();
|
return ostr.str();
|
||||||
|
@ -92,20 +92,24 @@ unsigned long long stringToULL(const std::string &s)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool startsWith(const std::string &str, const std::string &s) {
|
bool startsWith(const std::string &str, const std::string &s)
|
||||||
|
{
|
||||||
return (str.size() >= s.size() && str.compare(0, s.size(), s) == 0);
|
return (str.size() >= s.size() && str.compare(0, s.size(), s) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool endsWith(const std::string &s, const std::string &e) {
|
bool endsWith(const std::string &s, const std::string &e)
|
||||||
|
{
|
||||||
return (s.size() >= e.size() && s.compare(s.size() - e.size(), e.size(), e) == 0);
|
return (s.size() >= e.size() && s.compare(s.size() - e.size(), e.size(), e) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sameline(const simplecpp::Token *tok1, const simplecpp::Token *tok2) {
|
bool sameline(const simplecpp::Token *tok1, const simplecpp::Token *tok2)
|
||||||
|
{
|
||||||
return tok1 && tok2 && tok1->location.sameline(tok2->location);
|
return tok1 && tok2 && tok1->location.sameline(tok2->location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool isAlternativeBinaryOp(const simplecpp::Token *tok, const std::string &alt) {
|
static bool isAlternativeBinaryOp(const simplecpp::Token *tok, const std::string &alt)
|
||||||
|
{
|
||||||
return (tok->name &&
|
return (tok->name &&
|
||||||
tok->str == alt &&
|
tok->str == alt &&
|
||||||
tok->previous &&
|
tok->previous &&
|
||||||
|
@ -114,14 +118,16 @@ static bool isAlternativeBinaryOp(const simplecpp::Token *tok, const std::string
|
||||||
(tok->next->number || tok->next->name || tok->next->op == '('));
|
(tok->next->number || tok->next->name || tok->next->op == '('));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isAlternativeUnaryOp(const simplecpp::Token *tok, const std::string &alt) {
|
static bool isAlternativeUnaryOp(const simplecpp::Token *tok, const std::string &alt)
|
||||||
|
{
|
||||||
return ((tok->name && tok->str == alt) &&
|
return ((tok->name && tok->str == alt) &&
|
||||||
(!tok->previous || tok->previous->op == '(') &&
|
(!tok->previous || tok->previous->op == '(') &&
|
||||||
(tok->next && (tok->next->name || tok->next->number)));
|
(tok->next && (tok->next->name || tok->next->number)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::Location::adjust(const std::string &str) {
|
void simplecpp::Location::adjust(const std::string &str)
|
||||||
|
{
|
||||||
if (str.find_first_of("\r\n") == std::string::npos) {
|
if (str.find_first_of("\r\n") == std::string::npos) {
|
||||||
col += str.size();
|
col += str.size();
|
||||||
return;
|
return;
|
||||||
|
@ -138,23 +144,27 @@ void simplecpp::Location::adjust(const std::string &str) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool simplecpp::Token::isOneOf(const char ops[]) const {
|
bool simplecpp::Token::isOneOf(const char ops[]) const
|
||||||
|
{
|
||||||
return (op != '\0') && (std::strchr(ops, op) != 0);
|
return (op != '\0') && (std::strchr(ops, op) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool simplecpp::Token::startsWithOneOf(const char c[]) const {
|
bool simplecpp::Token::startsWithOneOf(const char c[]) const
|
||||||
|
{
|
||||||
return std::strchr(c, str[0]) != 0;
|
return std::strchr(c, str[0]) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool simplecpp::Token::endsWithOneOf(const char c[]) const {
|
bool simplecpp::Token::endsWithOneOf(const char c[]) const
|
||||||
|
{
|
||||||
return std::strchr(c, str[str.size() - 1U]) != 0;
|
return std::strchr(c, str[str.size() - 1U]) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::Token::printAll() const {
|
void simplecpp::Token::printAll() const
|
||||||
|
{
|
||||||
const Token *tok = this;
|
const Token *tok = this;
|
||||||
while (tok->previous)
|
while (tok->previous)
|
||||||
tok = tok->previous;
|
tok = tok->previous;
|
||||||
for (const Token *tok = this; tok; tok = tok->next) {
|
for (; tok; tok = tok->next) {
|
||||||
if (tok->previous) {
|
if (tok->previous) {
|
||||||
std::cout << (sameline(tok, tok->previous) ? ' ' : '\n');
|
std::cout << (sameline(tok, tok->previous) ? ' ' : '\n');
|
||||||
}
|
}
|
||||||
|
@ -163,7 +173,8 @@ void simplecpp::Token::printAll() const {
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::Token::printOut() const {
|
void simplecpp::Token::printOut() const
|
||||||
|
{
|
||||||
for (const Token *tok = this; tok; tok = tok->next) {
|
for (const Token *tok = this; tok; tok = tok->next) {
|
||||||
if (tok != this) {
|
if (tok != this) {
|
||||||
std::cout << (sameline(tok, tok->previous) ? ' ' : '\n');
|
std::cout << (sameline(tok, tok->previous) ? ' ' : '\n');
|
||||||
|
@ -176,19 +187,23 @@ void simplecpp::Token::printOut() const {
|
||||||
simplecpp::TokenList::TokenList(std::vector<std::string> &filenames) : frontToken(NULL), backToken(NULL), files(filenames) {}
|
simplecpp::TokenList::TokenList(std::vector<std::string> &filenames) : frontToken(NULL), backToken(NULL), files(filenames) {}
|
||||||
|
|
||||||
simplecpp::TokenList::TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList)
|
simplecpp::TokenList::TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList)
|
||||||
: frontToken(NULL), backToken(NULL), files(filenames) {
|
: frontToken(NULL), backToken(NULL), files(filenames)
|
||||||
|
{
|
||||||
readfile(istr,filename,outputList);
|
readfile(istr,filename,outputList);
|
||||||
}
|
}
|
||||||
|
|
||||||
simplecpp::TokenList::TokenList(const TokenList &other) : frontToken(NULL), backToken(NULL), files(other.files) {
|
simplecpp::TokenList::TokenList(const TokenList &other) : frontToken(NULL), backToken(NULL), files(other.files)
|
||||||
|
{
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
simplecpp::TokenList::~TokenList() {
|
simplecpp::TokenList::~TokenList()
|
||||||
|
{
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::operator=(const TokenList &other) {
|
void simplecpp::TokenList::operator=(const TokenList &other)
|
||||||
|
{
|
||||||
if (this == &other)
|
if (this == &other)
|
||||||
return;
|
return;
|
||||||
clear();
|
clear();
|
||||||
|
@ -197,7 +212,8 @@ void simplecpp::TokenList::operator=(const TokenList &other) {
|
||||||
sizeOfType = other.sizeOfType;
|
sizeOfType = other.sizeOfType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::clear() {
|
void simplecpp::TokenList::clear()
|
||||||
|
{
|
||||||
backToken = NULL;
|
backToken = NULL;
|
||||||
while (frontToken) {
|
while (frontToken) {
|
||||||
Token *next = frontToken->next;
|
Token *next = frontToken->next;
|
||||||
|
@ -207,7 +223,8 @@ void simplecpp::TokenList::clear() {
|
||||||
sizeOfType.clear();
|
sizeOfType.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::push_back(Token *tok) {
|
void simplecpp::TokenList::push_back(Token *tok)
|
||||||
|
{
|
||||||
if (!frontToken)
|
if (!frontToken)
|
||||||
frontToken = tok;
|
frontToken = tok;
|
||||||
else
|
else
|
||||||
|
@ -216,11 +233,13 @@ void simplecpp::TokenList::push_back(Token *tok) {
|
||||||
backToken = tok;
|
backToken = tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::dump() const {
|
void simplecpp::TokenList::dump() const
|
||||||
|
{
|
||||||
std::cout << stringify() << std::endl;
|
std::cout << stringify() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string simplecpp::TokenList::stringify() const {
|
std::string simplecpp::TokenList::stringify() const
|
||||||
|
{
|
||||||
std::ostringstream ret;
|
std::ostringstream ret;
|
||||||
Location loc(files);
|
Location loc(files);
|
||||||
for (const Token *tok = cfront(); tok; tok = tok->next) {
|
for (const Token *tok = cfront(); tok; tok = tok->next) {
|
||||||
|
@ -276,7 +295,8 @@ static unsigned char readChar(std::istream &istr, unsigned int bom)
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char peekChar(std::istream &istr, unsigned int bom) {
|
static unsigned char peekChar(std::istream &istr, unsigned int bom)
|
||||||
|
{
|
||||||
unsigned char ch = (unsigned char)istr.peek();
|
unsigned char ch = (unsigned char)istr.peek();
|
||||||
|
|
||||||
// For UTF-16 encoded files the BOM is 0xfeff/0xfffe. If the
|
// For UTF-16 encoded files the BOM is 0xfeff/0xfffe. If the
|
||||||
|
@ -296,13 +316,15 @@ static unsigned char peekChar(std::istream &istr, unsigned int bom) {
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ungetChar(std::istream &istr, unsigned int bom) {
|
static void ungetChar(std::istream &istr, unsigned int bom)
|
||||||
|
{
|
||||||
istr.unget();
|
istr.unget();
|
||||||
if (bom == 0xfeff || bom == 0xfffe)
|
if (bom == 0xfeff || bom == 0xfffe)
|
||||||
istr.unget();
|
istr.unget();
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned short getAndSkipBOM(std::istream &istr) {
|
static unsigned short getAndSkipBOM(std::istream &istr)
|
||||||
|
{
|
||||||
const unsigned char ch1 = istr.peek();
|
const unsigned char ch1 = istr.peek();
|
||||||
|
|
||||||
// The UTF-16 BOM is 0xfffe or 0xfeff.
|
// The UTF-16 BOM is 0xfffe or 0xfeff.
|
||||||
|
@ -327,11 +349,13 @@ static unsigned short getAndSkipBOM(std::istream &istr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNameChar(unsigned char ch) {
|
bool isNameChar(unsigned char ch)
|
||||||
|
{
|
||||||
return std::isalnum(ch) || ch == '_' || ch == '$';
|
return std::isalnum(ch) || ch == '_' || ch == '$';
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string escapeString(const std::string &str) {
|
static std::string escapeString(const std::string &str)
|
||||||
|
{
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
ostr << '\"';
|
ostr << '\"';
|
||||||
for (std::size_t i = 1U; i < str.size() - 1; ++i) {
|
for (std::size_t i = 1U; i < str.size() - 1; ++i) {
|
||||||
|
@ -344,7 +368,8 @@ static std::string escapeString(const std::string &str) {
|
||||||
return ostr.str();
|
return ostr.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void portabilityBackslash(simplecpp::OutputList *outputList, const std::vector<std::string> &files, const simplecpp::Location &location) {
|
static void portabilityBackslash(simplecpp::OutputList *outputList, const std::vector<std::string> &files, const simplecpp::Location &location)
|
||||||
|
{
|
||||||
if (!outputList)
|
if (!outputList)
|
||||||
return;
|
return;
|
||||||
simplecpp::Output err(files);
|
simplecpp::Output err(files);
|
||||||
|
@ -526,7 +551,8 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen
|
||||||
combineOperators();
|
combineOperators();
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::constFold() {
|
void simplecpp::TokenList::constFold()
|
||||||
|
{
|
||||||
while (cfront()) {
|
while (cfront()) {
|
||||||
// goto last '('
|
// goto last '('
|
||||||
Token *tok = back();
|
Token *tok = back();
|
||||||
|
@ -559,7 +585,8 @@ void simplecpp::TokenList::constFold() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::combineOperators() {
|
void simplecpp::TokenList::combineOperators()
|
||||||
|
{
|
||||||
for (Token *tok = front(); tok; tok = tok->next) {
|
for (Token *tok = front(); tok; tok = tok->next) {
|
||||||
if (tok->op == '.') {
|
if (tok->op == '.') {
|
||||||
// float literals..
|
// float literals..
|
||||||
|
@ -623,8 +650,9 @@ void simplecpp::TokenList::combineOperators() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::constFoldUnaryNotPosNeg(simplecpp::Token *tok) {
|
static const std::string NOT("not");
|
||||||
const std::string NOT("not");
|
void simplecpp::TokenList::constFoldUnaryNotPosNeg(simplecpp::Token *tok)
|
||||||
|
{
|
||||||
for (; tok && tok->op != ')'; tok = tok->next) {
|
for (; tok && tok->op != ')'; tok = tok->next) {
|
||||||
// "not" might be !
|
// "not" might be !
|
||||||
if (isAlternativeUnaryOp(tok, NOT))
|
if (isAlternativeUnaryOp(tok, NOT))
|
||||||
|
@ -633,8 +661,7 @@ void simplecpp::TokenList::constFoldUnaryNotPosNeg(simplecpp::Token *tok) {
|
||||||
if (tok->op == '!' && tok->next && tok->next->number) {
|
if (tok->op == '!' && tok->next && tok->next->number) {
|
||||||
tok->setstr(tok->next->str == "0" ? "1" : "0");
|
tok->setstr(tok->next->str == "0" ? "1" : "0");
|
||||||
deleteToken(tok->next);
|
deleteToken(tok->next);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (tok->previous && (tok->previous->number || tok->previous->name))
|
if (tok->previous && (tok->previous->number || tok->previous->name))
|
||||||
continue;
|
continue;
|
||||||
if (!tok->next || !tok->next->number)
|
if (!tok->next || !tok->next->number)
|
||||||
|
@ -653,7 +680,8 @@ void simplecpp::TokenList::constFoldUnaryNotPosNeg(simplecpp::Token *tok) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::constFoldMulDivRem(Token *tok) {
|
void simplecpp::TokenList::constFoldMulDivRem(Token *tok)
|
||||||
|
{
|
||||||
for (; tok && tok->op != ')'; tok = tok->next) {
|
for (; tok && tok->op != ')'; tok = tok->next) {
|
||||||
if (!tok->previous || !tok->previous->number)
|
if (!tok->previous || !tok->previous->number)
|
||||||
continue;
|
continue;
|
||||||
|
@ -674,8 +702,7 @@ void simplecpp::TokenList::constFoldMulDivRem(Token *tok) {
|
||||||
result = (lhs / rhs);
|
result = (lhs / rhs);
|
||||||
else
|
else
|
||||||
result = (lhs % rhs);
|
result = (lhs % rhs);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tok = tok->previous;
|
tok = tok->previous;
|
||||||
|
@ -685,7 +712,8 @@ void simplecpp::TokenList::constFoldMulDivRem(Token *tok) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::constFoldAddSub(Token *tok) {
|
void simplecpp::TokenList::constFoldAddSub(Token *tok)
|
||||||
|
{
|
||||||
for (; tok && tok->op != ')'; tok = tok->next) {
|
for (; tok && tok->op != ')'; tok = tok->next) {
|
||||||
if (!tok->previous || !tok->previous->number)
|
if (!tok->previous || !tok->previous->number)
|
||||||
continue;
|
continue;
|
||||||
|
@ -707,9 +735,9 @@ void simplecpp::TokenList::constFoldAddSub(Token *tok) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::constFoldComparison(Token *tok) {
|
static const std::string NOTEQ("not_eq");
|
||||||
const std::string NOTEQ("not_eq");
|
void simplecpp::TokenList::constFoldComparison(Token *tok)
|
||||||
|
{
|
||||||
for (; tok && tok->op != ')'; tok = tok->next) {
|
for (; tok && tok->op != ')'; tok = tok->next) {
|
||||||
if (isAlternativeBinaryOp(tok,NOTEQ))
|
if (isAlternativeBinaryOp(tok,NOTEQ))
|
||||||
tok->setstr("!=");
|
tok->setstr("!=");
|
||||||
|
@ -744,19 +772,22 @@ void simplecpp::TokenList::constFoldComparison(Token *tok) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const std::string BITAND("bitand");
|
||||||
|
static const std::string BITOR("bitor");
|
||||||
|
static const std::string XOR("xor");
|
||||||
void simplecpp::TokenList::constFoldBitwise(Token *tok)
|
void simplecpp::TokenList::constFoldBitwise(Token *tok)
|
||||||
{
|
{
|
||||||
Token * const tok1 = tok;
|
Token * const tok1 = tok;
|
||||||
for (const char *op = "&^|"; *op; op++) {
|
for (const char *op = "&^|"; *op; op++) {
|
||||||
std::string altop;
|
const std::string* altop;
|
||||||
if (*op == '&')
|
if (*op == '&')
|
||||||
altop = "bitand";
|
altop = &BITAND;
|
||||||
else if (*op == '|')
|
else if (*op == '|')
|
||||||
altop = "bitor";
|
altop = &BITOR;
|
||||||
else
|
else
|
||||||
altop = "xor";
|
altop = &XOR;
|
||||||
for (tok = tok1; tok && tok->op != ')'; tok = tok->next) {
|
for (tok = tok1; tok && tok->op != ')'; tok = tok->next) {
|
||||||
if (tok->op != *op && !isAlternativeBinaryOp(tok, altop))
|
if (tok->op != *op && !isAlternativeBinaryOp(tok, *altop))
|
||||||
continue;
|
continue;
|
||||||
if (!tok->previous || !tok->previous->number)
|
if (!tok->previous || !tok->previous->number)
|
||||||
continue;
|
continue;
|
||||||
|
@ -777,10 +808,10 @@ void simplecpp::TokenList::constFoldBitwise(Token *tok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::constFoldLogicalOp(Token *tok) {
|
static const std::string AND("and");
|
||||||
const std::string AND("and");
|
static const std::string OR("or");
|
||||||
const std::string OR("or");
|
void simplecpp::TokenList::constFoldLogicalOp(Token *tok)
|
||||||
|
{
|
||||||
for (; tok && tok->op != ')'; tok = tok->next) {
|
for (; tok && tok->op != ')'; tok = tok->next) {
|
||||||
if (tok->name) {
|
if (tok->name) {
|
||||||
if (isAlternativeBinaryOp(tok,AND))
|
if (isAlternativeBinaryOp(tok,AND))
|
||||||
|
@ -808,7 +839,8 @@ void simplecpp::TokenList::constFoldLogicalOp(Token *tok) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::constFoldQuestionOp(Token **tok1) {
|
void simplecpp::TokenList::constFoldQuestionOp(Token **tok1)
|
||||||
|
{
|
||||||
bool gotoTok1 = false;
|
bool gotoTok1 = false;
|
||||||
for (Token *tok = *tok1; tok && tok->op != ')'; tok = gotoTok1 ? *tok1 : tok->next) {
|
for (Token *tok = *tok1; tok && tok->op != ')'; tok = gotoTok1 ? *tok1 : tok->next) {
|
||||||
gotoTok1 = false;
|
gotoTok1 = false;
|
||||||
|
@ -835,7 +867,8 @@ void simplecpp::TokenList::constFoldQuestionOp(Token **tok1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::TokenList::removeComments() {
|
void simplecpp::TokenList::removeComments()
|
||||||
|
{
|
||||||
Token *tok = frontToken;
|
Token *tok = frontToken;
|
||||||
while (tok) {
|
while (tok) {
|
||||||
Token *tok1 = tok;
|
Token *tok1 = tok;
|
||||||
|
@ -845,7 +878,8 @@ void simplecpp::TokenList::removeComments() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string simplecpp::TokenList::readUntil(std::istream &istr, const Location &location, const char start, const char end, OutputList *outputList) {
|
std::string simplecpp::TokenList::readUntil(std::istream &istr, const Location &location, const char start, const char end, OutputList *outputList)
|
||||||
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret += start;
|
ret += start;
|
||||||
|
|
||||||
|
@ -872,7 +906,8 @@ std::string simplecpp::TokenList::readUntil(std::istream &istr, const Location &
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string simplecpp::TokenList::lastLine(int maxsize) const {
|
std::string simplecpp::TokenList::lastLine(int maxsize) const
|
||||||
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (const Token *tok = cback(); sameline(tok,cback()); tok = tok->previous) {
|
for (const Token *tok = cback(); sameline(tok,cback()); tok = tok->previous) {
|
||||||
|
@ -888,7 +923,8 @@ std::string simplecpp::TokenList::lastLine(int maxsize) const {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int simplecpp::TokenList::fileIndex(const std::string &filename) {
|
unsigned int simplecpp::TokenList::fileIndex(const std::string &filename)
|
||||||
|
{
|
||||||
for (unsigned int i = 0; i < files.size(); ++i) {
|
for (unsigned int i = 0; i < files.size(); ++i) {
|
||||||
if (files[i] == filename)
|
if (files[i] == filename)
|
||||||
return i;
|
return i;
|
||||||
|
@ -901,9 +937,9 @@ unsigned int simplecpp::TokenList::fileIndex(const std::string &filename) {
|
||||||
namespace simplecpp {
|
namespace simplecpp {
|
||||||
class Macro {
|
class Macro {
|
||||||
public:
|
public:
|
||||||
explicit Macro(std::vector<std::string> &f) : nameToken(NULL), variadic(false), valueToken(NULL), endToken(NULL), files(f), tokenListDefine(f) {}
|
explicit Macro(std::vector<std::string> &f) : nameTokDef(NULL), variadic(false), valueToken(NULL), endToken(NULL), files(f), tokenListDefine(f) {}
|
||||||
|
|
||||||
Macro(const Token *tok, std::vector<std::string> &f) : nameToken(NULL), files(f), tokenListDefine(f) {
|
Macro(const Token *tok, std::vector<std::string> &f) : nameTokDef(NULL), files(f), tokenListDefine(f) {
|
||||||
if (sameline(tok->previous, tok))
|
if (sameline(tok->previous, tok))
|
||||||
throw std::runtime_error("bad macro syntax");
|
throw std::runtime_error("bad macro syntax");
|
||||||
if (tok->op != '#')
|
if (tok->op != '#')
|
||||||
|
@ -919,7 +955,7 @@ public:
|
||||||
throw std::runtime_error("bad macro syntax");
|
throw std::runtime_error("bad macro syntax");
|
||||||
}
|
}
|
||||||
|
|
||||||
Macro(const std::string &name, const std::string &value, std::vector<std::string> &f) : nameToken(NULL), files(f), tokenListDefine(f) {
|
Macro(const std::string &name, const std::string &value, std::vector<std::string> &f) : nameTokDef(NULL), files(f), tokenListDefine(f) {
|
||||||
const std::string def(name + ' ' + value);
|
const std::string def(name + ' ' + value);
|
||||||
std::istringstream istr(def);
|
std::istringstream istr(def);
|
||||||
tokenListDefine.readfile(istr);
|
tokenListDefine.readfile(istr);
|
||||||
|
@ -927,14 +963,14 @@ public:
|
||||||
throw std::runtime_error("bad macro syntax");
|
throw std::runtime_error("bad macro syntax");
|
||||||
}
|
}
|
||||||
|
|
||||||
Macro(const Macro ¯o) : nameToken(NULL), files(macro.files), tokenListDefine(macro.files) {
|
Macro(const Macro ¯o) : nameTokDef(NULL), files(macro.files), tokenListDefine(macro.files) {
|
||||||
*this = macro;
|
*this = macro;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator=(const Macro ¯o) {
|
void operator=(const Macro ¯o) {
|
||||||
if (this != ¯o) {
|
if (this != ¯o) {
|
||||||
if (macro.tokenListDefine.empty())
|
if (macro.tokenListDefine.empty())
|
||||||
parseDefine(macro.nameToken);
|
parseDefine(macro.nameTokDef);
|
||||||
else {
|
else {
|
||||||
tokenListDefine = macro.tokenListDefine;
|
tokenListDefine = macro.tokenListDefine;
|
||||||
parseDefine(tokenListDefine.cfront());
|
parseDefine(tokenListDefine.cfront());
|
||||||
|
@ -989,16 +1025,14 @@ public:
|
||||||
if (par==0)
|
if (par==0)
|
||||||
break;
|
break;
|
||||||
--par;
|
--par;
|
||||||
}
|
} else if (macro2tok->op == ')')
|
||||||
else if (macro2tok->op == ')')
|
|
||||||
++par;
|
++par;
|
||||||
macro2tok = macro2tok->previous;
|
macro2tok = macro2tok->previous;
|
||||||
}
|
}
|
||||||
if (macro2tok) { // macro2tok->op == '('
|
if (macro2tok) { // macro2tok->op == '('
|
||||||
macro2tok = macro2tok->previous;
|
macro2tok = macro2tok->previous;
|
||||||
expandedmacros.insert(name());
|
expandedmacros.insert(name());
|
||||||
}
|
} else if (rawtok->op == '(')
|
||||||
else if (rawtok->op == '(')
|
|
||||||
macro2tok = output2.back();
|
macro2tok = output2.back();
|
||||||
if (!macro2tok || !macro2tok->name)
|
if (!macro2tok || !macro2tok->name)
|
||||||
break;
|
break;
|
||||||
|
@ -1039,12 +1073,12 @@ public:
|
||||||
|
|
||||||
/** macro name */
|
/** macro name */
|
||||||
const TokenString &name() const {
|
const TokenString &name() const {
|
||||||
return nameToken->str;
|
return nameTokDef->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** location for macro definition */
|
/** location for macro definition */
|
||||||
const Location &defineLocation() const {
|
const Location &defineLocation() const {
|
||||||
return nameToken->location;
|
return nameTokDef->location;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** how has this macro been used so far */
|
/** how has this macro been used so far */
|
||||||
|
@ -1054,10 +1088,10 @@ public:
|
||||||
|
|
||||||
/** is this a function like macro */
|
/** is this a function like macro */
|
||||||
bool functionLike() const {
|
bool functionLike() const {
|
||||||
return nameToken->next &&
|
return nameTokDef->next &&
|
||||||
nameToken->next->op == '(' &&
|
nameTokDef->next->op == '(' &&
|
||||||
sameline(nameToken, nameToken->next) &&
|
sameline(nameTokDef, nameTokDef->next) &&
|
||||||
nameToken->next->location.col == nameToken->location.col + nameToken->str.size();
|
nameTokDef->next->location.col == nameTokDef->location.col + nameTokDef->str.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** base class for errors */
|
/** base class for errors */
|
||||||
|
@ -1081,14 +1115,14 @@ private:
|
||||||
Token *newMacroToken(const TokenString &str, const Location &loc, bool replaced) const {
|
Token *newMacroToken(const TokenString &str, const Location &loc, bool replaced) const {
|
||||||
Token *tok = new Token(str,loc);
|
Token *tok = new Token(str,loc);
|
||||||
if (replaced)
|
if (replaced)
|
||||||
tok->macro = nameToken->str;
|
tok->macro = nameTokDef->str;
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseDefine(const Token *nametoken) {
|
bool parseDefine(const Token *nametoken) {
|
||||||
nameToken = nametoken;
|
nameTokDef = nametoken;
|
||||||
variadic = false;
|
variadic = false;
|
||||||
if (!nameToken) {
|
if (!nameTokDef) {
|
||||||
valueToken = endToken = NULL;
|
valueToken = endToken = NULL;
|
||||||
args.clear();
|
args.clear();
|
||||||
return false;
|
return false;
|
||||||
|
@ -1097,7 +1131,7 @@ private:
|
||||||
// function like macro..
|
// function like macro..
|
||||||
if (functionLike()) {
|
if (functionLike()) {
|
||||||
args.clear();
|
args.clear();
|
||||||
const Token *argtok = nameToken->next->next;
|
const Token *argtok = nameTokDef->next->next;
|
||||||
while (sameline(nametoken, argtok) && argtok->op != ')') {
|
while (sameline(nametoken, argtok) && argtok->op != ')') {
|
||||||
if (argtok->op == '.' &&
|
if (argtok->op == '.' &&
|
||||||
argtok->next && argtok->next->op == '.' &&
|
argtok->next && argtok->next->op == '.' &&
|
||||||
|
@ -1119,13 +1153,13 @@ private:
|
||||||
valueToken = argtok ? argtok->next : NULL;
|
valueToken = argtok ? argtok->next : NULL;
|
||||||
} else {
|
} else {
|
||||||
args.clear();
|
args.clear();
|
||||||
valueToken = nameToken->next;
|
valueToken = nameTokDef->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sameline(valueToken, nameToken))
|
if (!sameline(valueToken, nameTokDef))
|
||||||
valueToken = NULL;
|
valueToken = NULL;
|
||||||
endToken = valueToken;
|
endToken = valueToken;
|
||||||
while (sameline(endToken, nameToken))
|
while (sameline(endToken, nameTokDef))
|
||||||
endToken = endToken->next;
|
endToken = endToken->next;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1140,14 +1174,14 @@ private:
|
||||||
return ~0U;
|
return ~0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const Token *> getMacroParameters(const Token *nameToken, bool calledInDefine) const {
|
std::vector<const Token *> getMacroParameters(const Token *nameTokInst, bool calledInDefine) const {
|
||||||
if (!nameToken->next || nameToken->next->op != '(' || !functionLike())
|
if (!nameTokInst->next || nameTokInst->next->op != '(' || !functionLike())
|
||||||
return std::vector<const Token *>();
|
return std::vector<const Token *>();
|
||||||
|
|
||||||
std::vector<const Token *> parametertokens;
|
std::vector<const Token *> parametertokens;
|
||||||
parametertokens.push_back(nameToken->next);
|
parametertokens.push_back(nameTokInst->next);
|
||||||
unsigned int par = 0U;
|
unsigned int par = 0U;
|
||||||
for (const Token *tok = nameToken->next->next; calledInDefine ? sameline(tok,nameToken) : (tok != NULL); tok = tok->next) {
|
for (const Token *tok = nameTokInst->next->next; calledInDefine ? sameline(tok, nameTokInst) : (tok != NULL); tok = tok->next) {
|
||||||
if (tok->op == '(')
|
if (tok->op == '(')
|
||||||
++par;
|
++par;
|
||||||
else if (tok->op == ')') {
|
else if (tok->op == ')') {
|
||||||
|
@ -1156,8 +1190,7 @@ private:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
--par;
|
--par;
|
||||||
}
|
} else if (par == 0U && tok->op == ',' && (!variadic || parametertokens.size() < args.size()))
|
||||||
else if (par == 0U && tok->op == ',' && (!variadic || parametertokens.size() < args.size()))
|
|
||||||
parametertokens.push_back(tok);
|
parametertokens.push_back(tok);
|
||||||
}
|
}
|
||||||
return parametertokens;
|
return parametertokens;
|
||||||
|
@ -1206,44 +1239,44 @@ private:
|
||||||
return sameline(lpar,tok) ? tok : NULL;
|
return sameline(lpar,tok) ? tok : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token * expand(TokenList * const output, const Location &loc, const Token * const nameToken, const std::map<TokenString,Macro> ¯os, std::set<TokenString> expandedmacros) const {
|
const Token * expand(TokenList * const output, const Location &loc, const Token * const nameTokInst, const std::map<TokenString,Macro> ¯os, std::set<TokenString> expandedmacros) const {
|
||||||
expandedmacros.insert(nameToken->str);
|
expandedmacros.insert(nameTokInst->str);
|
||||||
|
|
||||||
usageList.push_back(loc);
|
usageList.push_back(loc);
|
||||||
|
|
||||||
if (nameToken->str == "__FILE__") {
|
if (nameTokInst->str == "__FILE__") {
|
||||||
output->push_back(new Token('\"'+loc.file()+'\"', loc));
|
output->push_back(new Token('\"'+loc.file()+'\"', loc));
|
||||||
return nameToken->next;
|
return nameTokInst->next;
|
||||||
}
|
}
|
||||||
if (nameToken->str == "__LINE__") {
|
if (nameTokInst->str == "__LINE__") {
|
||||||
output->push_back(new Token(toString(loc.line), loc));
|
output->push_back(new Token(toString(loc.line), loc));
|
||||||
return nameToken->next;
|
return nameTokInst->next;
|
||||||
}
|
}
|
||||||
if (nameToken->str == "__COUNTER__") {
|
if (nameTokInst->str == "__COUNTER__") {
|
||||||
output->push_back(new Token(toString(usageList.size()-1U), loc));
|
output->push_back(new Token(toString(usageList.size()-1U), loc));
|
||||||
return nameToken->next;
|
return nameTokInst->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool calledInDefine = (loc.fileIndex != nameToken->location.fileIndex ||
|
const bool calledInDefine = (loc.fileIndex != nameTokInst->location.fileIndex ||
|
||||||
loc.line < nameToken->location.line);
|
loc.line < nameTokInst->location.line);
|
||||||
|
|
||||||
std::vector<const Token*> parametertokens1(getMacroParameters(nameToken, calledInDefine));
|
std::vector<const Token*> parametertokens1(getMacroParameters(nameTokInst, calledInDefine));
|
||||||
|
|
||||||
if (functionLike()) {
|
if (functionLike()) {
|
||||||
// No arguments => not macro expansion
|
// No arguments => not macro expansion
|
||||||
if (nameToken->next && nameToken->next->op != '(') {
|
if (nameTokInst->next && nameTokInst->next->op != '(') {
|
||||||
output->push_back(new Token(nameToken->str, loc));
|
output->push_back(new Token(nameTokInst->str, loc));
|
||||||
return nameToken->next;
|
return nameTokInst->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse macro-call
|
// Parse macro-call
|
||||||
if (variadic) {
|
if (variadic) {
|
||||||
if (parametertokens1.size() < args.size()) {
|
if (parametertokens1.size() < args.size()) {
|
||||||
throw wrongNumberOfParameters(nameToken->location, name());
|
throw wrongNumberOfParameters(nameTokInst->location, name());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (parametertokens1.size() != args.size() + (args.empty() ? 2U : 1U))
|
if (parametertokens1.size() != args.size() + (args.empty() ? 2U : 1U))
|
||||||
throw wrongNumberOfParameters(nameToken->location, name());
|
throw wrongNumberOfParameters(nameTokInst->location, name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1327,14 +1360,14 @@ private:
|
||||||
|
|
||||||
if (!functionLike()) {
|
if (!functionLike()) {
|
||||||
for (Token *tok = output_end_1 ? output_end_1->next : output->front(); tok; tok = tok->next) {
|
for (Token *tok = output_end_1 ? output_end_1->next : output->front(); tok; tok = tok->next) {
|
||||||
tok->macro = nameToken->str;
|
tok->macro = nameTokInst->str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parametertokens1.empty())
|
if (!parametertokens1.empty())
|
||||||
parametertokens1.swap(parametertokens2);
|
parametertokens1.swap(parametertokens2);
|
||||||
|
|
||||||
return functionLike() ? parametertokens2.back()->next : nameToken->next;
|
return functionLike() ? parametertokens2.back()->next : nameTokInst->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token *expandToken(TokenList *output, const Location &loc, const Token *tok, const std::map<TokenString,Macro> ¯os, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> ¶metertokens) const {
|
const Token *expandToken(TokenList *output, const Location &loc, const Token *tok, const std::map<TokenString,Macro> ¯os, const std::set<TokenString> &expandedmacros, const std::vector<const Token*> ¶metertokens) const {
|
||||||
|
@ -1555,7 +1588,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** name token in definition */
|
/** name token in definition */
|
||||||
const Token *nameToken;
|
const Token *nameTokDef;
|
||||||
|
|
||||||
/** arguments for macro */
|
/** arguments for macro */
|
||||||
std::vector<TokenString> args;
|
std::vector<TokenString> args;
|
||||||
|
@ -1584,27 +1617,27 @@ private:
|
||||||
namespace simplecpp {
|
namespace simplecpp {
|
||||||
#ifdef SIMPLECPP_WINDOWS
|
#ifdef SIMPLECPP_WINDOWS
|
||||||
|
|
||||||
static bool realFileName(const std::vector<TCHAR> &buf, std::ostream &ostr) {
|
static bool realFileName(const std::vector<CHAR> &buf, std::ostream &ostr)
|
||||||
|
{
|
||||||
// Detect root directory, see simplecpp:realFileName returns the wrong root path #45
|
// Detect root directory, see simplecpp:realFileName returns the wrong root path #45
|
||||||
if ((buf.size()==2 || (buf.size()>2 && buf[2]=='\0'))
|
if ((buf.size()==2 || (buf.size()>2 && buf[2]=='\0'))
|
||||||
&& std::isalpha(buf[0]) && buf[1]==':')
|
&& std::isalpha(buf[0]) && buf[1]==':') {
|
||||||
{
|
|
||||||
ostr << (char)buf[0];
|
ostr << (char)buf[0];
|
||||||
ostr << (char)buf[1];
|
ostr << (char)buf[1];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
WIN32_FIND_DATA FindFileData;
|
WIN32_FIND_DATAA FindFileData;
|
||||||
HANDLE hFind = FindFirstFile(&buf[0], &FindFileData);
|
HANDLE hFind = FindFirstFileA(&buf[0], &FindFileData);
|
||||||
if (hFind == INVALID_HANDLE_VALUE)
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
return false;
|
return false;
|
||||||
for (const TCHAR *c = FindFileData.cFileName; *c; c++)
|
ostr << FindFileData.cFileName;
|
||||||
ostr << (char)*c;
|
|
||||||
FindClose(hFind);
|
FindClose(hFind);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string realFilename(const std::string &f) {
|
std::string realFilename(const std::string &f)
|
||||||
std::vector<TCHAR> buf(f.size()+1U, 0);
|
{
|
||||||
|
std::vector<CHAR> buf(f.size()+1U, 0);
|
||||||
for (unsigned int i = 0; i < f.size(); ++i)
|
for (unsigned int i = 0; i < f.size(); ++i)
|
||||||
buf[i] = f[i];
|
buf[i] = f[i];
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
|
@ -1627,7 +1660,8 @@ std::string realFilename(const std::string &f) {
|
||||||
/**
|
/**
|
||||||
* perform path simplifications for . and ..
|
* perform path simplifications for . and ..
|
||||||
*/
|
*/
|
||||||
std::string simplifyPath(std::string path) {
|
std::string simplifyPath(std::string path)
|
||||||
|
{
|
||||||
std::string::size_type pos;
|
std::string::size_type pos;
|
||||||
|
|
||||||
// replace backslash separators
|
// replace backslash separators
|
||||||
|
@ -1661,7 +1695,8 @@ std::string simplifyPath(std::string path) {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/** Evaluate sizeof(type) */
|
/** Evaluate sizeof(type) */
|
||||||
void simplifySizeof(simplecpp::TokenList &expr, const std::map<std::string, std::size_t> &sizeOfType) {
|
void simplifySizeof(simplecpp::TokenList &expr, const std::map<std::string, std::size_t> &sizeOfType)
|
||||||
|
{
|
||||||
for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) {
|
for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) {
|
||||||
if (tok->str != "sizeof")
|
if (tok->str != "sizeof")
|
||||||
continue;
|
continue;
|
||||||
|
@ -1702,7 +1737,8 @@ void simplifySizeof(simplecpp::TokenList &expr, const std::map<std::string, std:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplifyName(simplecpp::TokenList &expr) {
|
void simplifyName(simplecpp::TokenList &expr)
|
||||||
|
{
|
||||||
std::set<std::string> altop;
|
std::set<std::string> altop;
|
||||||
altop.insert("and");
|
altop.insert("and");
|
||||||
altop.insert("or");
|
altop.insert("or");
|
||||||
|
@ -1728,7 +1764,8 @@ void simplifyName(simplecpp::TokenList &expr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplifyNumbers(simplecpp::TokenList &expr) {
|
void simplifyNumbers(simplecpp::TokenList &expr)
|
||||||
|
{
|
||||||
for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) {
|
for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) {
|
||||||
if (tok->str.size() == 1U)
|
if (tok->str.size() == 1U)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1739,7 +1776,8 @@ void simplifyNumbers(simplecpp::TokenList &expr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long long evaluate(simplecpp::TokenList &expr, const std::map<std::string, std::size_t> &sizeOfType) {
|
long long evaluate(simplecpp::TokenList &expr, const std::map<std::string, std::size_t> &sizeOfType)
|
||||||
|
{
|
||||||
simplifySizeof(expr, sizeOfType);
|
simplifySizeof(expr, sizeOfType);
|
||||||
simplifyName(expr);
|
simplifyName(expr);
|
||||||
simplifyNumbers(expr);
|
simplifyNumbers(expr);
|
||||||
|
@ -1748,7 +1786,8 @@ long long evaluate(simplecpp::TokenList &expr, const std::map<std::string, std::
|
||||||
return expr.cfront() && expr.cfront() == expr.cback() && expr.cfront()->number ? stringToLL(expr.cfront()->str) : 0LL;
|
return expr.cfront() && expr.cfront() == expr.cback() && expr.cfront()->number ? stringToLL(expr.cfront()->str) : 0LL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const simplecpp::Token *gotoNextLine(const simplecpp::Token *tok) {
|
const simplecpp::Token *gotoNextLine(const simplecpp::Token *tok)
|
||||||
|
{
|
||||||
const unsigned int line = tok->location.line;
|
const unsigned int line = tok->location.line;
|
||||||
const unsigned int file = tok->location.fileIndex;
|
const unsigned int file = tok->location.fileIndex;
|
||||||
while (tok && tok->location.line == line && tok->location.fileIndex == file)
|
while (tok && tok->location.line == line && tok->location.fileIndex == file)
|
||||||
|
@ -1756,7 +1795,8 @@ const simplecpp::Token *gotoNextLine(const simplecpp::Token *tok) {
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader) {
|
std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader)
|
||||||
|
{
|
||||||
if (!systemheader) {
|
if (!systemheader) {
|
||||||
if (sourcefile.find_first_of("\\/") != std::string::npos) {
|
if (sourcefile.find_first_of("\\/") != std::string::npos) {
|
||||||
const std::string s = sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header;
|
const std::string s = sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header;
|
||||||
|
@ -1783,15 +1823,17 @@ std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::s
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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)
|
||||||
|
{
|
||||||
if (!systemheader) {
|
if (!systemheader) {
|
||||||
if (sourcefile.find_first_of("\\/") != std::string::npos) {
|
if (sourcefile.find_first_of("\\/") != std::string::npos) {
|
||||||
const std::string s(simplecpp::simplifyPath(sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header));
|
const std::string s(simplecpp::simplifyPath(sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header));
|
||||||
if (filedata.find(s) != filedata.end())
|
if (filedata.find(s) != filedata.end())
|
||||||
return s;
|
return s;
|
||||||
} else {
|
} else {
|
||||||
if (filedata.find(simplecpp::simplifyPath(header)) != filedata.end())
|
std::string s = simplecpp::simplifyPath(header);
|
||||||
return simplecpp::simplifyPath(header);
|
if (filedata.find(s) != filedata.end())
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1808,7 +1850,8 @@ std::string getFileName(const std::map<std::string, simplecpp::TokenList *> &fil
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasFile(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader) {
|
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 !getFileName(filedata, sourcefile, header, dui, systemheader).empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1879,7 +1922,8 @@ std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::To
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token **tok1, std::map<std::string, simplecpp::Macro> ¯os, std::vector<std::string> &files, simplecpp::OutputList *outputList) {
|
static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token **tok1, std::map<std::string, simplecpp::Macro> ¯os, std::vector<std::string> &files, simplecpp::OutputList *outputList)
|
||||||
|
{
|
||||||
const simplecpp::Token *tok = *tok1;
|
const simplecpp::Token *tok = *tok1;
|
||||||
const std::map<std::string,simplecpp::Macro>::const_iterator it = macros.find(tok->str);
|
const std::map<std::string,simplecpp::Macro>::const_iterator it = macros.find(tok->str);
|
||||||
if (it != macros.end()) {
|
if (it != macros.end()) {
|
||||||
|
@ -1887,12 +1931,13 @@ static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token
|
||||||
try {
|
try {
|
||||||
*tok1 = it->second.expand(&value, tok, macros, files);
|
*tok1 = it->second.expand(&value, tok, macros, files);
|
||||||
} catch (simplecpp::Macro::Error &err) {
|
} catch (simplecpp::Macro::Error &err) {
|
||||||
|
if (outputList) {
|
||||||
simplecpp::Output out(files);
|
simplecpp::Output out(files);
|
||||||
out.type = simplecpp::Output::SYNTAX_ERROR;
|
out.type = simplecpp::Output::SYNTAX_ERROR;
|
||||||
out.location = err.location;
|
out.location = err.location;
|
||||||
out.msg = "failed to expand \'" + tok->str + "\', " + err.what;
|
out.msg = "failed to expand \'" + tok->str + "\', " + err.what;
|
||||||
if (outputList)
|
|
||||||
outputList->push_back(out);
|
outputList->push_back(out);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
output.takeTokens(value);
|
output.takeTokens(value);
|
||||||
|
@ -1981,12 +2026,13 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifstates.size() <= 1U && (rawtok->str == ELIF || rawtok->str == ELSE || rawtok->str == ENDIF)) {
|
if (ifstates.size() <= 1U && (rawtok->str == ELIF || rawtok->str == ELSE || rawtok->str == ENDIF)) {
|
||||||
|
if (outputList) {
|
||||||
simplecpp::Output err(files);
|
simplecpp::Output err(files);
|
||||||
err.type = Output::SYNTAX_ERROR;
|
err.type = Output::SYNTAX_ERROR;
|
||||||
err.location = rawtok->location;
|
err.location = rawtok->location;
|
||||||
err.msg = "#" + rawtok->str + " without #if";
|
err.msg = "#" + rawtok->str + " without #if";
|
||||||
if (outputList)
|
|
||||||
outputList->push_back(err);
|
outputList->push_back(err);
|
||||||
|
}
|
||||||
output.clear();
|
output.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2023,12 +2069,13 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
|
||||||
it->second = macro;
|
it->second = macro;
|
||||||
}
|
}
|
||||||
} catch (const std::runtime_error &) {
|
} catch (const std::runtime_error &) {
|
||||||
|
if (outputList) {
|
||||||
simplecpp::Output err(files);
|
simplecpp::Output err(files);
|
||||||
err.type = Output::SYNTAX_ERROR;
|
err.type = Output::SYNTAX_ERROR;
|
||||||
err.location = rawtok->location;
|
err.location = rawtok->location;
|
||||||
err.msg = "Failed to parse #define";
|
err.msg = "Failed to parse #define";
|
||||||
if (outputList)
|
|
||||||
outputList->push_back(err);
|
outputList->push_back(err);
|
||||||
|
}
|
||||||
output.clear();
|
output.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2050,12 +2097,13 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inc2.empty() || inc2.cfront()->str.size() <= 2U) {
|
if (inc2.empty() || inc2.cfront()->str.size() <= 2U) {
|
||||||
|
if (outputList) {
|
||||||
simplecpp::Output err(files);
|
simplecpp::Output err(files);
|
||||||
err.type = Output::SYNTAX_ERROR;
|
err.type = Output::SYNTAX_ERROR;
|
||||||
err.location = rawtok->location;
|
err.location = rawtok->location;
|
||||||
err.msg = "No header in #include";
|
err.msg = "No header in #include";
|
||||||
if (outputList)
|
|
||||||
outputList->push_back(err);
|
outputList->push_back(err);
|
||||||
|
}
|
||||||
output.clear();
|
output.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2075,19 +2123,21 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (header2.empty()) {
|
if (header2.empty()) {
|
||||||
simplecpp::Output output(files);
|
if (outputList) {
|
||||||
output.type = Output::MISSING_HEADER;
|
simplecpp::Output out(files);
|
||||||
output.location = rawtok->location;
|
out.type = Output::MISSING_HEADER;
|
||||||
output.msg = "Header not found: " + rawtok->next->str;
|
out.location = rawtok->location;
|
||||||
if (outputList)
|
out.msg = "Header not found: " + rawtok->next->str;
|
||||||
outputList->push_back(output);
|
outputList->push_back(out);
|
||||||
|
}
|
||||||
} else if (includetokenstack.size() >= 400) {
|
} else if (includetokenstack.size() >= 400) {
|
||||||
|
if (outputList) {
|
||||||
simplecpp::Output out(files);
|
simplecpp::Output out(files);
|
||||||
out.type = Output::INCLUDE_NESTED_TOO_DEEPLY;
|
out.type = Output::INCLUDE_NESTED_TOO_DEEPLY;
|
||||||
out.location = rawtok->location;
|
out.location = rawtok->location;
|
||||||
out.msg = "#include nested too deeply";
|
out.msg = "#include nested too deeply";
|
||||||
if (outputList)
|
|
||||||
outputList->push_back(out);
|
outputList->push_back(out);
|
||||||
|
}
|
||||||
} else if (pragmaOnce.find(header2) == pragmaOnce.end()) {
|
} else if (pragmaOnce.find(header2) == pragmaOnce.end()) {
|
||||||
includetokenstack.push(gotoNextLine(rawtok));
|
includetokenstack.push(gotoNextLine(rawtok));
|
||||||
const TokenList *includetokens = filedata.find(header2)->second;
|
const TokenList *includetokens = filedata.find(header2)->second;
|
||||||
|
@ -2096,12 +2146,13 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
|
||||||
}
|
}
|
||||||
} else if (rawtok->str == IF || rawtok->str == IFDEF || rawtok->str == IFNDEF || rawtok->str == ELIF) {
|
} else if (rawtok->str == IF || rawtok->str == IFDEF || rawtok->str == IFNDEF || rawtok->str == ELIF) {
|
||||||
if (!sameline(rawtok,rawtok->next)) {
|
if (!sameline(rawtok,rawtok->next)) {
|
||||||
|
if (outputList) {
|
||||||
simplecpp::Output out(files);
|
simplecpp::Output out(files);
|
||||||
out.type = Output::SYNTAX_ERROR;
|
out.type = Output::SYNTAX_ERROR;
|
||||||
out.location = rawtok->location;
|
out.location = rawtok->location;
|
||||||
out.msg = "Syntax error in #" + rawtok->str;
|
out.msg = "Syntax error in #" + rawtok->str;
|
||||||
if (outputList)
|
|
||||||
outputList->push_back(out);
|
outputList->push_back(out);
|
||||||
|
}
|
||||||
output.clear();
|
output.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2135,12 +2186,13 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
|
||||||
if (par)
|
if (par)
|
||||||
tok = tok ? tok->next : NULL;
|
tok = tok ? tok->next : NULL;
|
||||||
if (!tok || !sameline(rawtok,tok) || (par && tok->op != ')')) {
|
if (!tok || !sameline(rawtok,tok) || (par && tok->op != ')')) {
|
||||||
|
if (outputList) {
|
||||||
Output out(rawtok->location.files);
|
Output out(rawtok->location.files);
|
||||||
out.type = Output::SYNTAX_ERROR;
|
out.type = Output::SYNTAX_ERROR;
|
||||||
out.location = rawtok->location;
|
out.location = rawtok->location;
|
||||||
out.msg = "failed to evaluate " + std::string(rawtok->str == IF ? "#if" : "#elif") + " condition";
|
out.msg = "failed to evaluate " + std::string(rawtok->str == IF ? "#if" : "#elif") + " condition";
|
||||||
if (outputList)
|
|
||||||
outputList->push_back(out);
|
outputList->push_back(out);
|
||||||
|
}
|
||||||
output.clear();
|
output.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2156,12 +2208,13 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
|
||||||
try {
|
try {
|
||||||
conditionIsTrue = (evaluate(expr, sizeOfType) != 0);
|
conditionIsTrue = (evaluate(expr, sizeOfType) != 0);
|
||||||
} catch (const std::exception &) {
|
} catch (const std::exception &) {
|
||||||
|
if (outputList) {
|
||||||
Output out(rawtok->location.files);
|
Output out(rawtok->location.files);
|
||||||
out.type = Output::SYNTAX_ERROR;
|
out.type = Output::SYNTAX_ERROR;
|
||||||
out.location = rawtok->location;
|
out.location = rawtok->location;
|
||||||
out.msg = "failed to evaluate " + std::string(rawtok->str == IF ? "#if" : "#elif") + " condition";
|
out.msg = "failed to evaluate " + std::string(rawtok->str == IF ? "#if" : "#elif") + " condition";
|
||||||
if (outputList)
|
|
||||||
outputList->push_back(out);
|
outputList->push_back(out);
|
||||||
|
}
|
||||||
output.clear();
|
output.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2252,7 +2305,8 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplecpp::cleanup(std::map<std::string, TokenList*> &filedata) {
|
void simplecpp::cleanup(std::map<std::string, TokenList*> &filedata)
|
||||||
|
{
|
||||||
for (std::map<std::string, TokenList*>::iterator it = filedata.begin(); it != filedata.end(); ++it)
|
for (std::map<std::string, TokenList*>::iterator it = filedata.begin(); it != filedata.end(); ++it)
|
||||||
delete it->second;
|
delete it->second;
|
||||||
filedata.clear();
|
filedata.clear();
|
||||||
|
|
|
@ -76,8 +76,9 @@ public:
|
||||||
return fileIndex == other.fileIndex && line == other.line;
|
return fileIndex == other.fileIndex && line == other.line;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string file() const {
|
const std::string& file() const {
|
||||||
return fileIndex < files.size() ? files[fileIndex] : std::string("");
|
static const std::string temp;
|
||||||
|
return fileIndex < files.size() ? files[fileIndex] : temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> &files;
|
const std::vector<std::string> &files;
|
||||||
|
@ -93,14 +94,12 @@ public:
|
||||||
class SIMPLECPP_LIB Token {
|
class SIMPLECPP_LIB Token {
|
||||||
public:
|
public:
|
||||||
Token(const TokenString &s, const Location &loc) :
|
Token(const TokenString &s, const Location &loc) :
|
||||||
str(string), location(loc), previous(NULL), next(NULL), string(s)
|
str(string), location(loc), previous(NULL), next(NULL), string(s) {
|
||||||
{
|
|
||||||
flags();
|
flags();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token(const Token &tok) :
|
Token(const Token &tok) :
|
||||||
str(string), macro(tok.macro), location(tok.location), previous(NULL), next(NULL), string(tok.str)
|
str(string), macro(tok.macro), location(tok.location), previous(NULL), next(NULL), string(tok.str) {
|
||||||
{
|
|
||||||
flags();
|
flags();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue