diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 9cba73b28..87eeaceb2 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -266,7 +266,7 @@ std::string Preprocessor::preprocessCleanupDirectives(const std::string &process static bool hasbom(const std::string &str) { - return bool(str.size() > 3 && + return bool(str.size() >= 3 && static_cast(str[0]) == 0xef && static_cast(str[1]) == 0xbb && static_cast(str[2]) == 0xbf); @@ -284,13 +284,13 @@ static int tolowerWrapper(int c) static bool isFallThroughComment(std::string comment) { // convert comment to lower case without whitespace - std::transform(comment.begin(), comment.end(), comment.begin(), tolowerWrapper); for (std::string::iterator i = comment.begin(); i != comment.end();) { if (std::isspace(static_cast(*i))) i = comment.erase(i); else ++i; } + std::transform(comment.begin(), comment.end(), comment.begin(), tolowerWrapper); return comment.find("fallthr") != std::string::npos || comment.find("fallsthr") != std::string::npos || @@ -650,83 +650,16 @@ std::string Preprocessor::removeParentheses(const std::string &str) } - -static void _removeAsm(std::string &str, const std::string::size_type pos) -{ - unsigned int newlines = 0; - bool instr = false; - int parlevel = 0; - std::string::size_type pos2 = pos + 1; - while (pos2 < str.length()) { - if (str[pos2] == '\"') - instr = !instr; - - else if (str[pos2] == '\n') - ++newlines; - - else if (!instr) { - if (str[pos2] == '(') - ++parlevel; - else if (str[pos2] == ')') { - if (parlevel <= 1) - break; - --parlevel; - } - } - - ++pos2; - } - str.erase(pos + 1, pos2 - pos); - str.insert(pos, std::string(newlines, '\n')); -} - void Preprocessor::removeAsm(std::string &str) { std::string::size_type pos = 0; - while ((pos = str.find("\nasm(", pos)) != std::string::npos) { - _removeAsm(str, pos++); - str.insert(pos, "asm()"); - } - - pos = 0; - while ((pos = str.find("\nasm (", pos)) != std::string::npos) { - _removeAsm(str, pos++); - str.insert(pos, "asm()"); - } - - pos = 0; - while ((pos = str.find("\nasm __volatile(", pos)) != std::string::npos) - _removeAsm(str, pos); - - pos = 0; - while ((pos = str.find("\nasm __volatile (", pos)) != std::string::npos) - _removeAsm(str, pos); - - pos = 0; while ((pos = str.find("#asm\n", pos)) != std::string::npos) { - const std::string::size_type pos1 = pos; - ++pos; + str.replace(pos, 4, "asm("); - if (pos1 > 0 && str[pos1-1] != '\n') - continue; - - const std::string::size_type endpos = str.find("\n#endasm", pos1); - if (endpos != std::string::npos) { - if (endpos + 8U < str.size() && str[endpos+8U] != '\n') - break; - - // Remove '#endasm' - str.erase(endpos+1, 7); - - // Remove non-newline characters between pos1 and endpos - for (std::string::size_type p = endpos; p > pos1; --p) { - if (str[p] != '\n') - str.erase(p,1); - } - str.erase(pos1,1); - - // Insert 'asm();' to make the checks bailout properly - str.insert(pos1, ";asm();"); + std::string::size_type pos2 = str.find("#endasm", pos); + if (pos2 != std::string::npos) { + str.replace(pos2, 7, ");"); + pos = pos2; } } } diff --git a/lib/token.cpp b/lib/token.cpp index e5a9119a5..5ca38979a 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -893,6 +893,9 @@ void Token::printOut(const char *title, const std::vector &fileName std::string Token::stringify(const Token* end) const { + if (this == end) + return ""; + std::ostringstream ret; if (isUnsigned()) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index ae482b814..c5b6119eb 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4019,86 +4019,68 @@ void Tokenizer::setVarId() } } +bool linkBrackets(Tokenizer* tokenizer, std::stack& type, std::stack& links, Token* token, char open, char close) +{ + if (token->str().back() == open) { + links.push(token); + type.push(token); + } else if (token->str().back() == close) { + if (links.empty()) { + // Error, { and } don't match. + tokenizer->syntaxError(token, open); + return false; + } + if (type.top()->str().back() != open) { + tokenizer->syntaxError(type.top(), type.top()->str()[0]); + return false; + } + type.pop(); + + Token::createMutualLinks(links.top(), token); + links.pop(); + } + return(true); +} + bool Tokenizer::createLinks() { - std::list type; - std::list links; - std::list links2; - std::list links3; + std::stack type; + std::stack links1; + std::stack links2; + std::stack links3; for (Token *token = _tokens; token; token = token->next()) { if (token->link()) { token->link(0); } - if (token->str() == "{") { - links.push_back(token); - type.push_back(token); - } else if (token->str() == "}") { - if (links.empty()) { - // Error, { and } don't match. - syntaxError(token, '{'); - return false; - } - if (type.back()->str() != "{") { - syntaxError(type.back(), type.back()->str()[0]); - return false; - } - type.pop_back(); + bool validSyntax = validSyntax = linkBrackets(this, type, links1, token, '{', '}'); + if (!validSyntax) + return false; - Token::createMutualLinks(links.back(), token); - links.pop_back(); - } else if (token->str() == "(") { - links2.push_back(token); - type.push_back(token); - } else if (token->str() == ")") { - if (links2.empty()) { - // Error, ( and ) don't match. - syntaxError(token, '('); - return false; - } - if (type.back()->str() != "(") { - syntaxError(type.back(), type.back()->str()[0]); - return false; - } - type.pop_back(); + validSyntax = linkBrackets(this, type, links2, token, '(', ')'); + if (!validSyntax) + return false; - Token::createMutualLinks(links2.back(), token); - links2.pop_back(); - } else if (token->str() == "[") { - links3.push_back(token); - type.push_back(token); - } else if (token->str() == "]") { - if (links3.empty()) { - // Error, [ and ] don't match. - syntaxError(token, '['); - return false; - } - if (type.back()->str() != "[") { - syntaxError(type.back(), type.back()->str()[0]); - return false; - } - type.pop_back(); - - Token::createMutualLinks(links3.back(), token); - links3.pop_back(); - } + validSyntax = linkBrackets(this, type, links3, token, '[', ']'); + if (!validSyntax) + return false; } - if (!links.empty()) { + if (!links1.empty()) { // Error, { and } don't match. - syntaxError(links.back(), '{'); + syntaxError(links1.top(), '{'); return false; } if (!links2.empty()) { // Error, ( and ) don't match. - syntaxError(links2.back(), '('); + syntaxError(links2.top(), '('); return false; } if (!links3.empty()) { // Error, [ and ] don't match. - syntaxError(links3.back(), '['); + syntaxError(links3.top(), '['); return false; } @@ -4479,7 +4461,7 @@ bool Tokenizer::simplifyTokenList() // simplify "x=realloc(y,0);" => "free(y); x=0;".. // and "x = realloc (0, n);" => "x = malloc(n);" for (Token *tok = _tokens; tok; tok = tok->next()) { - if (Token::Match(tok, "; %var% = realloc ( %var% , 0 ) ;")) { + if (Token::Match(tok, "[;{}:] %var% = realloc ( %var% , 0 ) ;")) { const std::string varname(tok->next()->str()); const unsigned int varid(tok->next()->varId()); @@ -4502,7 +4484,7 @@ bool Tokenizer::simplifyTokenList() tok->insertToken("="); tok->insertToken(varname); tok->next()->varId(varid); - } else if (Token::Match(tok, "; %var% = realloc ( 0 , %num% ) ;")) { + } else if (Token::Match(tok, "[;{}:] %var% = realloc ( 0 , %num% ) ;")) { tok = tok->tokAt(3); // Change function name "realloc" to "malloc" tok->str("malloc"); @@ -9360,7 +9342,7 @@ void Tokenizer::simplifyStructDecl() void Tokenizer::simplifyCallingConvention() { - const char pattern[] = "__cdecl|__stdcall|__fastcall|__thiscall|__clrcall|__syscall|__pascal|__fortran|__far|__near|WINAPI|APIENTRY|CALLBACK"; + static const char pattern[] = "__cdecl|__stdcall|__fastcall|__thiscall|__clrcall|__syscall|__pascal|__fortran|__far|__near|WINAPI|APIENTRY|CALLBACK"; for (Token *tok = _tokens; tok; tok = tok->next()) { while (Token::Match(tok, pattern)) { tok->deleteThis(); @@ -9403,7 +9385,7 @@ void Tokenizer::simplifyAttribute() // Remove "volatile", "inline", "register", and "restrict" void Tokenizer::simplifyKeyword() { - const char pattern[] = "volatile|inline|__inline|__forceinline|register|restrict|__restrict|__restrict__"; + static const char pattern[] = "volatile|inline|__inline|__forceinline|register|restrict|__restrict|__restrict__"; for (Token *tok = _tokens; tok; tok = tok->next()) { while (Token::Match(tok, pattern)) { tok->deleteThis(); diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index f80d491d0..ecdc380e3 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -1549,21 +1549,13 @@ private: } void remove_asm() { - std::string str1("\nasm(\n\n\n);"); + std::string str1("#asm\nmov ax,bx\n#endasm"); Preprocessor::removeAsm(str1); - ASSERT_EQUALS("\nasm()\n\n\n;", str1); + ASSERT_EQUALS("asm(\nmov ax,bx\n);", str1); - std::string str2("\nasm __volatile(\"\nlw iScale, 0x00(pScale)\n\", ());"); + std::string str2("\n#asm\nmov ax,bx\n#endasm\n"); Preprocessor::removeAsm(str2); - ASSERT_EQUALS("\n\n\n;", str2); - - std::string str3("#asm\nmov ax,bx\n#endasm"); - Preprocessor::removeAsm(str3); - ASSERT_EQUALS(";asm();\n\n", str3); - - std::string str4("\n#asm\nmov ax,bx\n#endasm\n"); - Preprocessor::removeAsm(str4); - ASSERT_EQUALS("\n;asm();\n\n\n", str4); + ASSERT_EQUALS("\nasm(\nmov ax,bx\n);\n", str2); } void if_defined() {