Other improvements to tokenizer code.

Handle SQL code better, even when there's no ';' after 'EXEC SQL'.
simplifyVarDecl: Check with 'Token::Match' once when you have to check a pattern inside which there should be a number or a variable. Use '%any%' and after that check if that string is a number or a variable name later.
simplifyGoto: process also anonymous structs and unions which should have 'indentspecial' incremented, skip code like 'var = { ... }'.
This commit is contained in:
Edoardo Prezioso 2011-12-11 01:11:15 +01:00
parent 5134964026
commit 27801b35eb
2 changed files with 56 additions and 50 deletions

View File

@ -2011,15 +2011,18 @@ bool Tokenizer::tokenize(std::istream &code,
const Token *end = tok;
while (end && end->str() != ";")
end = end->next();
Token::eraseTokens(tok, end);
if (tok) {
// insert "asm ( ) ;"
tok->str("asm");
tok->insertToken("(");
tok = tok->next();
tok->insertToken(")");
}
// insert "asm ( ) ;"
tok->str("asm");
// it can happen that 'end' is NULL when wrong code is inserted
if (!tok->next())
tok->insertToken(";");
tok->insertToken(")");
tok->insertToken("(");
// jump to ';' and continue
tok = tok->tokAt(3);
}
}
@ -5500,13 +5503,10 @@ void Tokenizer::simplifyFunctionParameters()
for (Token *tok = _tokens; tok; tok = tok->next()) {
if (tok->str() == "{" || tok->str() == "[" || tok->str() == "(") {
tok = tok->link();
if (!tok)
break;
continue;
}
// Find the function e.g. foo( x ) or foo( x, y )
if (Token::Match(tok, "%var% ( %var% [,)]")) {
else if (Token::Match(tok, "%var% ( %var% [,)]")) {
// We have found old style function, now we need to change it
// backup pointer to the '(' token
@ -5806,31 +5806,36 @@ void Tokenizer::simplifyVarDecl(bool only_k_r_fpar)
}
}
else if (Token::Match(tok2, "%type% %var% [ %num% ] ,|=|[") ||
Token::Match(tok2, "%type% %var% [ %var% ] ,|=|[")) {
tok2 = tok2->tokAt(5); // The ',' token
while (Token::Match(tok2, "[ %num% ]") || Token::Match(tok2, "[ %var% ]"))
tok2 = tok2->tokAt(3);
if (!Token::Match(tok2, "=|,")) {
tok2 = NULL;
}
if (tok2 && tok2->str() == "=") {
while (tok2 && tok2->str() != ",") {
if (tok2->str() == "{")
tok2 = tok2->link();
tok2 = tok2->next();
else if (Token::Match(tok2, "%type% %var% [ %any% ] ,|=|[")) {
tok2 = tok2->tokAt(2);
if (tok2->next()->isName() || tok2->next()->isNumber()) {
tok2 = tok2->link()->next(); // The ',' token
while (Token::Match(tok2, "[ %any% ]") &&
(tok2->next()->isName() || tok2->next()->isNumber()))
tok2 = tok2->link()->next();
if (!Token::Match(tok2, "=|,")) {
tok2 = NULL;
}
if (tok2 && tok2->str() == "=") {
while (tok2 && tok2->str() != "," && tok2->str() != ";") {
if (tok2->str() == "{")
tok2 = tok2->link();
tok2 = tok2->next();
}
if (tok2 && tok2->str() == ";")
tok2 = NULL;
}
}
} else
tok2 = NULL;
}
else if (Token::Match(tok2, "%type% * %var% [ %num% ] ,") ||
Token::Match(tok2, "%type% * %var% [ %var% ] ,")) {
tok2 = tok2->tokAt(6); // The ',' token
else if (Token::Match(tok2, "%type% * %var% [ %any% ] ,")) {
tok2 = tok2->tokAt(3);
if (tok2->next()->isName() || tok2->next()->isNumber())
tok2 = tok2->link()->next(); // The ',' token
else
tok2 = NULL;
}
else if (Token::Match(tok2, "%type% <")) {
@ -7577,10 +7582,11 @@ void Tokenizer::simplifyGoto()
tok = tok->link();
else if (tok->str() == "{") {
if (Token::Match(tok->tokAt(-2),"namespace|struct|class|union %var% {") ||
Token::simpleMatch(tok->previous(),"namespace {"))
if (Token::Match(tok->tokAt(-2),"class|namespace|struct|union %var% {") ||
Token::Match(tok->previous(),"namespace|struct|union {"))
++indentspecial;
else if (!beginfunction && !indentlevel)
else if ((!beginfunction && !indentlevel) ||
(tok->previous() && tok->previous()->str() == "="))
tok = tok->link();
else
++indentlevel;
@ -7601,23 +7607,27 @@ void Tokenizer::simplifyGoto()
}
}
else if (Token::Match(tok, "goto %var% ;"))
gotos.push_back(tok);
if (!indentlevel && Token::Match(tok, ") const| {")) {
gotos.clear();
beginfunction = tok;
}
if (indentlevel == 1 && Token::Match(tok->previous(), "[{};] %var% : ;") && tok->str() != "default") {
else if (indentlevel && Token::Match(tok, "[{};] goto %var% ;"))
gotos.push_back(tok->next());
else if (indentlevel == 1 && Token::Match(tok, "[{};] %var% : ;") && tok->next()->str() != "default") {
// Is this label at the end..
bool end = false;
unsigned int level = 0;
for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) {
for (const Token *tok2 = tok->tokAt(3); tok2; tok2 = tok2->next()) {
if (tok2->str() == "(" || tok2->str() == "[")
tok2 = tok2->link();
if (tok2->str() == "}") {
else if (tok2->str() == "{") {
++level;
}
else if (tok2->str() == "}") {
if (!level) {
end = true;
break;
@ -7625,21 +7635,17 @@ void Tokenizer::simplifyGoto()
--level;
}
else if (tok2->str() == "{") {
++level;
}
if ((Token::Match(tok2->previous(), "[{};] %var% : ;") && tok2->str() != "default") || tok2->str() == "goto") {
if ((Token::Match(tok2, "[{};] %var% : ;") && tok2->next()->str() != "default") ||
Token::Match(tok2, "[{};] goto %var% ;")) {
break;
}
}
if (!end)
continue;
const std::string name(tok->str());
const std::string name(tok->next()->str());
tok->deleteNext(2);
tok->deleteThis();
tok->deleteNext(3);
// This label is at the end of the function.. replace all matching goto statements..
for (std::list<Token *>::iterator it = gotos.begin(); it != gotos.end(); ++it) {
@ -7657,7 +7663,7 @@ void Tokenizer::simplifyGoto()
std::list<Token*> links3;
unsigned int lev = 0;
unsigned int roundbraces = 0;
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
if (tok2->str() == ")") {
if (!roundbraces)
break;

View File

@ -5774,8 +5774,8 @@ private:
void sql() {
// Oracle PRO*C extensions for inline SQL. Just replace the SQL with "asm()" to fix wrong error messages
// ticket: #1959
const char code1[] = "; EXEC SQL SELECT A FROM B;";
ASSERT_EQUALS("; asm ( ) ;", tokenizeAndStringify(code1,false));
ASSERT_EQUALS("asm ( ) ;", tokenizeAndStringify("EXEC SQL SELECT A FROM B;",false));
ASSERT_EQUALS("asm ( ) ;", tokenizeAndStringify("EXEC SQL",false));
}