⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tokenize.cpp

📁 cppcheck is a static C/C++ code analyzer that checks for memory leaks, mismatching allocation-deallo
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                while (tok2)                {                    if (strchr("{(", tok2->aaaa0()))                    {                        ++parlevel;                    }                    else if (strchr("})", tok2->aaaa0()))                    {                        if (parlevel < 0)                            break;                        --parlevel;                    }                    else if (parlevel == 0 && strchr(";,", tok2->aaaa0()))                    {                        // "type var ="   =>   "type var; var ="                        Token *VarTok = type0->tokAt(typelen);                        if (VarTok->aaaa0() == '*')                            VarTok = VarTok->next();                        InsertTokens(eq, VarTok, 2);                        eq->str(";");                        // "= x, "   =>   "= x; type "                        if (tok2->str() == ",")                        {                            tok2->str(";");                            InsertTokens(tok2, type0, typelen);                        }                        break;                    }                    tok2 = tok2->next();                }            }        }    }    // In case variable declarations have been updated...    setVarId();    // Replace NULL with 0..    for (Token *tok = _tokens; tok; tok = tok->next())    {        if (tok->str() == "NULL")            tok->str("0");    }    // Replace pointer casts of 0.. "(char *)0" => "0"    for (Token *tok = _tokens; tok; tok = tok->next())    {        if (Token::Match(tok->next(), "( %type% * ) 0") || Token::Match(tok->next(), "( %type% %type% * ) 0"))        {            while (!Token::simpleMatch(tok->next(), "0"))                tok->deleteNext();        }    }    simplifyIfAddBraces();    simplifyFunctionParameters();    elseif();    for (Token *tok = _tokens; tok; tok = tok->next())    {        if (Token::Match(tok, "case %any% : %var%"))            tok->next()->next()->insertToken(";");        if (Token::Match(tok, "default : %var%"))            tok->next()->insertToken(";");    }    bool modified = true;    while (modified)    {        modified = false;        modified |= simplifyConditions();        modified |= simplifyFunctionReturn();        modified |= simplifyKnownVariables();        modified |= removeReduntantConditions();        modified |= simplifyRedundantParanthesis();        modified |= simplifyCalculations();    }}//---------------------------------------------------------------------------const Token *Tokenizer::findClosing(const Token *tok, const char *start, const char *end){    if (!tok)        return 0;    // Find the closing "}"    int indentLevel = 0;    for (const Token *closing = tok->next(); closing; closing = closing->next())    {        if (closing->str() == start)        {            ++indentLevel;            continue;        }        if (closing->str() == end)            --indentLevel;        if (indentLevel >= 0)            continue;        // Closing } is found.        return closing;    }    return 0;}bool Tokenizer::removeReduntantConditions(){    bool ret = false;    for (Token *tok = _tokens; tok; tok = tok->next())    {        if (!Token::simpleMatch(tok, "if"))            continue;        if (!Token::Match(tok->tokAt(1), "( %bool% ) {"))            continue;        // Find matching else        const Token *elseTag = 0;        // Find the closing "}"        elseTag = Tokenizer::findClosing(tok->tokAt(4), "{", "}");        if (elseTag)            elseTag = elseTag->next();        bool boolValue = false;        if (tok->tokAt(2)->str() == "true")            boolValue = true;        // Handle if with else        if (elseTag && elseTag->str() == "else")        {            if (Token::simpleMatch(elseTag->next(), "if"))            {                // Handle "else if"                if (boolValue == false)                {                    // Convert "if( false ) {aaa;} else if() {bbb;}" => "if() {bbb;}"                    Token::eraseTokens(tok, elseTag->tokAt(2));                    ret = true;                }                else                {                    // Keep first if, remove every else if and else after it                    const Token *lastTagInIf = elseTag->tokAt(2);                    while (lastTagInIf)                    {                        if (lastTagInIf->str() == "(")                        {                            lastTagInIf = Tokenizer::findClosing(lastTagInIf, "(", ")");                            lastTagInIf = lastTagInIf->next();                        }                        lastTagInIf = Tokenizer::findClosing(lastTagInIf, "{", "}");                        lastTagInIf = lastTagInIf->next();                        if (!Token::simpleMatch(lastTagInIf, "else"))                            break;                        lastTagInIf = lastTagInIf->next();                        if (Token::simpleMatch(lastTagInIf, "if"))                            lastTagInIf = lastTagInIf->next();                    }                    Token::eraseTokens(elseTag->previous(), lastTagInIf);                    ret = true;                }            }            else            {                // Handle else                if (boolValue == false)                {                    // Convert "if( false ) {aaa;} else {bbb;}" => "{bbb;}" or ";{bbb;}"                    if (tok->previous())                        tok = tok->previous();                    else                        tok->str(";");                    Token::eraseTokens(tok, elseTag->tokAt(1));                }                else                {                    if (Token::simpleMatch(elseTag->tokAt(1), "{"))                    {                        // Convert "if( true ) {aaa;} else {bbb;}" => "{aaa;}"                        const Token *end = Tokenizer::findClosing(elseTag->tokAt(1), "{", "}");                        if (!end)                        {                            // Possibly syntax error in code                            return false;                        }                        // Remove the "else { aaa; }"                        Token::eraseTokens(elseTag->previous(), end->tokAt(1));                    }                    // Remove "if( true )"                    if (tok->previous())                        tok = tok->previous();                    else                        tok->str(";");                    Token::eraseTokens(tok, tok->tokAt(5));                }                ret = true;            }        }        // Handle if without else        else        {            if (boolValue == false)            {                // Remove if and its content                if (tok->previous())                    tok = tok->previous();                else                    tok->str(";");                Token::eraseTokens(tok, elseTag);            }            else            {                // convert "if( true ) {aaa;}" => "{aaa;}"                if (tok->previous())                    tok = tok->previous();                else                    tok->str(";");                Token::eraseTokens(tok, tok->tokAt(5));            }            ret = true;        }    }    return ret;}bool Tokenizer::simplifyIfAddBraces(){    bool ret = false;    for (Token *tok = _tokens; tok; tok = tok ? tok->next() : NULL)    {        if (Token::Match(tok, "if|for|while ("))        {            // Goto the ending ')'            int parlevel = 1;            tok = tok->next();            while (parlevel >= 1 && (tok = tok->next()))            {                if (tok->str() == "(")                    ++parlevel;                else if (tok->str() == ")")                    --parlevel;            }            // ')' should be followed by '{'            if (!tok || Token::simpleMatch(tok, ") {"))                continue;        }        else if (tok->str() == "else")        {            // An else followed by an if or brace don't need to be processed further            if (Token::Match(tok, "else if|{"))                continue;        }        else        {            continue;        }        // insert open brace..        tok->insertToken("{");        tok = tok->next();        // insert close brace..        // In most cases it would work to just search for the next ';' and insert a closing brace after it.        // But here are special cases..        // * if (cond) for (;;) break;        // * if (cond1) if (cond2) { }        int parlevel = 0;        int indentlevel = 0;        while ((tok = tok->next()) != NULL)        {            if (tok->str() == "{")                ++indentlevel;            else if (tok->str() == "}")            {                --indentlevel;                if (indentlevel == 0)                    break;            }            else if (tok->str() == "(")                ++parlevel;            else if (tok->str() == ")")                --parlevel;            else if (indentlevel == 0 && parlevel == 0 && tok->str() == ";")                break;        }        if (tok)        {            tok->insertToken("}");            ret = true;        }    }    return ret;}bool Tokenizer::simplifyConditions(){    bool ret = false;    for (Token *tok = _tokens; tok; tok = tok->next())    {        if (Token::simpleMatch(tok, "( true &&") || Token::simpleMatch(tok, "&& true &&") || Token::simpleMatch(tok->next(), "&& true )"))        {            tok->deleteNext();            tok->deleteNext();            ret = true;        }        else if (Token::simpleMatch(tok, "( false ||") || Token::simpleMatch(tok, "|| false ||") || Token::simpleMatch(tok->next(), "|| false )"))        {            tok->deleteNext();            tok->deleteNext();            ret = true;        }        // Change numeric constant in condition to "true" or "false"        if (Token::Match(tok, "if|while ( %num%") &&            (tok->tokAt(3)->str() == ")" || tok->tokAt(3)->str() == "||" || tok->tokAt(3)->str() == "&&"))        {            tok->next()->next()->str((tok->tokAt(2)->str() != "0") ? "true" : "false");            ret = true;        }        Token *tok2 = tok->tokAt(2);        if (tok2                                        &&            (tok->str() == "&&" || tok->str() == "||")  &&            Token::Match(tok->next(), "%num%")          &&            (tok2->str() == ")" || tok2->str() == "&&" || tok2->str() == "||"))        {            tok->next()->str((tok->next()->str() != "0") ? "true" : "false");            ret = true;        }        // Reduce "(%num% == %num%)" => "(true)"/"(false)"        const Token *tok4 = tok->tokAt(4);        if (! tok4)            break;        if ((tok->str() == "&&" || tok->str() == "||" || tok->str() == "(") &&            Token::Match(tok->tokAt(1), "%num% %any% %num%") &&            (tok4->str() == "&&" || tok4->str() == "||" || tok4->str() == ")"))        {            double op1 = (strstr(tok->strAt(1), "0x")) ? std::strtol(tok->strAt(1), 0, 16) : std::atof(tok->strAt(1));            double op2 = (strstr(tok->strAt(3), "0x")) ? std::strtol(tok->strAt(3), 0, 16) : std::atof(tok->strAt(3));            std::string cmp = tok->strAt(2);            bool result = false;            if (cmp == "==")                result = (op1 == op2);            else if (cmp == "!=")                result = (op1 != op2);            else if (cmp == ">=")                result = (op1 >= op2);            else if (cmp == ">")                result = (op1 > op2);            else if (cmp == "<=")                result = (op1 <= op2);            else if (cmp == "<")                result = (op1 < op2);            else                cmp = "";            if (! cmp.empty())            {                tok = tok->next();                tok->deleteNext();                tok->deleteNext();                tok->str(result ? "true" : "false");                ret = true;            }        }    }    return ret;}bool Tokenizer::simplifyCasts(){    bool ret = false;    for (Token *tok = _tokens; tok; tok = tok->next())    {        if (!tok->isName() && Token::Match(tok->next(), "( %type% * )"))        {            tok->deleteNext();            tok->deleteNext();            tok->deleteNext();            tok->deleteNext();            ret = true;        }        else if (Token::Match(tok->next(), "dynamic_cast|reinterpret_cast|const_cast|static_cast <"))        {            while (tok->next() && tok->next()->str() != ">")                tok->deleteNext();            tok->deleteNext();            tok->deleteNext();            Token *tok2 = tok;            int parlevel = 0;            while (tok2->next() && parlevel >= 0)            {                tok2 = tok2->next();                if (Token::simpleMatch(tok2->next(), "("))                    ++parlevel;                else if (Token::simpleMatch(tok2->next(), ")"))                    --parlevel;            }            if (tok2->next())                tok2->deleteNext();            ret = true;        }    }    return ret;}bool Tokenizer::simplifyFunctionParameters(){    bool ret = false;    int indentlevel = 0;    for (Token *tok = _tokens; tok; tok = tok->next())    {        if (tok->str() == "{")            ++indentlevel;        else if (tok->str() == "}")            --indentlevel;        // Find the function e.g. foo( x ) or foo( x, y )        else if (indentlevel == 0 && Token::Match(tok, "%var% ( %var% [,)]"))        {            // We have found old style function, now we need to change it            // Get list of argument names            std::map<std::string, Token*> argumentNames;            bool bailOut = false;            for (tok = tok->tokAt(2); tok; tok = tok->tokAt(2))            {                if (!Token::Match(tok, "%var% [,)]"))                {                    bailOut = true;                    break;                }                argumentNames[tok->str()] = tok;                if (tok->next()->str() == ")")                {                    tok = tok->tokAt(2);                    break;                }            }            if (bailOut)            {                continue;            }            Token *start = tok;            while (tok && tok->str() != "{")

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -