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

📄 tokenize.cpp

📁 cppcheck is a static C/C++ code analyzer that checks for memory leaks, mismatching allocation-deallo
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            {                if (tok->str() == ";")                {                    tok = tok->previous();                    // Move tokens from start to tok into the place of                    // argumentNames[tok->str()] and remove the ";"                    if (argumentNames.find(tok->str()) == argumentNames.end())                    {                        bailOut = true;                        break;                    }                    // Remove the following ";"                    Token *temp = tok->tokAt(2);                    tok->deleteNext();                    // Replace "x" with "int x" or similar                    Token::replace(argumentNames[tok->str()], start, tok);                    ret = true;                    tok = temp;                    start = tok;                }                else                {                    tok = tok->next();                }            }            if (tok == NULL)            {                break;            }            if (bailOut)            {                continue;            }            ++indentlevel;        }    }    return ret;}bool Tokenizer::simplifyFunctionReturn(){    bool ret = false;    int indentlevel = 0;    for (const Token *tok = tokens(); tok; tok = tok->next())    {        if (tok->str() == "{")            ++indentlevel;        else if (tok->str() == "}")            --indentlevel;        else if (indentlevel == 0 && Token::Match(tok, "%var% ( ) { return %num% ; }"))        {            std::ostringstream pattern;            pattern << "[(=+-*/] " << tok->str() << " ( ) [;)+-*/]";            for (Token *tok2 = _tokens; tok2; tok2 = tok2->next())            {                if (Token::Match(tok2, pattern.str().c_str()))                {                    tok2 = tok2->next();                    tok2->str(tok->strAt(5));                    tok2->deleteNext();                    tok2->deleteNext();                    ret = true;                }            }        }    }    return ret;}static void incdec(std::string &value, const std::string &op){    int ivalue = 0;    std::istringstream istr(value.c_str());    istr >> ivalue;    if (op == "++")        ++ivalue;    else if (op == "--")        --ivalue;    std::ostringstream ostr;    ostr << ivalue;    value = ostr.str();}bool Tokenizer::simplifyKnownVariables(){    bool ret = false;    for (Token *tok = _tokens; tok; tok = tok->next())    {        // Search for a block of code        if (! Token::Match(tok, ") const| {"))            continue;        // parse the block of code..        int indentlevel = 0;        for (Token *tok2 = tok; tok2; tok2 = tok2->next())        {            if (tok2->str() == "{")                ++indentlevel;            else if (tok2->str() == "}")            {                --indentlevel;                if (indentlevel <= 0)                    break;            }            else if (Token::Match(tok2, "%var% = %num% ;") ||                     Token::Match(tok2, "%var% = %bool% ;"))            {                unsigned int varid = tok2->varId();                if (varid == 0)                    continue;                std::string value(tok2->strAt(2));                for (Token *tok3 = tok2->next(); tok3; tok3 = tok3->next())                {                    // Perhaps it's a loop => bail out                    if (Token::Match(tok3, "[{}]"))                        break;                    // Variable is used somehow in a non-defined pattern => bail out                    if (tok3->varId() == varid)                        break;                    // Replace variable with numeric constant..                    if (Token::Match(tok3, "if ( %varid% )", varid))                    {                        tok3 = tok3->next()->next();                        tok3->str(value.c_str());                        ret = true;                    }                    // Variable is used in calculation..                    if (Token::Match(tok3, "[=+-*/[] %varid% [+-*/;]]", varid))                    {                        tok3 = tok3->next();                        tok3->str(value.c_str());                        ret = true;                    }                    if (Token::Match(tok3->next(), "%varid% ++|--", varid))                    {                        const std::string op(tok3->strAt(2));                        if (Token::Match(tok3, "; %any% %any% ;"))                        {                            tok3->deleteNext();                            tok3->deleteNext();                        }                        else                        {                            tok3 = tok3->next();                            tok3->str(value.c_str());                            tok3->deleteNext();                        }                        incdec(value, op);                        tok2->tokAt(2)->str(value.c_str());                        ret = true;                    }                    if (Token::Match(tok3->next(), "++|-- %varid%", varid))                    {                        incdec(value, tok3->strAt(1));                        tok2->tokAt(2)->str(value.c_str());                        if (Token::Match(tok3, "; %any% %any% ;"))                        {                            tok3->deleteNext();                            tok3->deleteNext();                        }                        else                        {                            tok3->deleteNext();                            tok3->next()->str(value.c_str());                        }                        tok3 = tok3->next();                        ret = true;                    }                }            }        }    }    return ret;}bool Tokenizer::elseif(){    bool ret = false;    for (Token *tok = _tokens; tok; tok = tok->next())    {        if (!Token::simpleMatch(tok, "else if"))            continue;        int indent = 0;        for (Token *tok2 = tok; indent >= 0 && tok2; tok2 = tok2->next())        {            if (Token::Match(tok2, "(|{"))                ++indent;            else if (Token::Match(tok2, ")|}"))                --indent;            if (indent == 0 && Token::Match(tok2, "}|;"))            {                if (!Token::simpleMatch(tok2->next(), "else"))                {                    tok->insertToken("{");                    tok2->insertToken("}");                    ret = true;                    break;                }            }        }    }    return ret;}bool Tokenizer::simplifyRedundantParanthesis(){    bool ret = false;    for (Token *tok = _tokens; tok; tok = tok->next())    {        if (Token::simpleMatch(tok, "( ("))        {            int parlevel = 0;            for (Token *tok2 = tok; tok2; tok2 = tok2->next())            {                if (tok2->str() == "(")                    ++parlevel;                else if (tok2->str() == ")")                {                    --parlevel;                    if (parlevel == 1)                    {                        if (Token::simpleMatch(tok2, ") )"))                        {                            tok->deleteNext();                            tok2->deleteNext();                        }                        break;                    }                }            }        }    }    return ret;}bool Tokenizer::simplifyCalculations(){    bool ret = false;    for (Token *tok = _tokens; tok; tok = tok->next())    {        if (Token::simpleMatch(tok->next(), "* 1") || Token::simpleMatch(tok->next(), "1 *"))        {            for (int i = 0; i < 2; i++)                tok->deleteNext();            ret = true;        }        // (1-2)        if (Token::Match(tok, "[[,(=<>] %num% [+-*/] %num% [],);=<>]"))        {            int i1 = std::atoi(tok->strAt(1));            int i2 = std::atoi(tok->strAt(3));            if (i2 == 0 && *(tok->strAt(2)) == '/')            {                continue;            }            switch (*(tok->strAt(2)))            {            case '+':                i1 += i2;                break;            case '-':                i1 -= i2;                break;            case '*':                i1 *= i2;                break;            case '/':                i1 /= i2;                break;            }            tok = tok->next();            std::ostringstream str;            str <<  i1;            tok->str(str.str().c_str());            for (int i = 0; i < 2; i++)            {                tok->deleteNext();            }            ret = true;        }        // Remove parantheses around number..        if (!tok->isName() && Token::Match(tok->next(), "( %num% )"))        {            tok->deleteNext();            tok = tok->next();            tok->deleteNext();            ret = true;        }        // Remove parantheses around variable..        // keep parantheses here: dynamic_cast<Fred *>(p);        if (!tok->isName() && tok->str() != ">" && Token::Match(tok->next(), "( %var% ) [;),+-*/><]]"))        {            tok->deleteNext();            tok = tok->next();            tok->deleteNext();            ret = true;        }    }    return ret;}//---------------------------------------------------------------------------// Helper functions for handling the tokens list//---------------------------------------------------------------------------//---------------------------------------------------------------------------const Token *Tokenizer::GetFunctionTokenByName(const char funcname[]) const{    for (unsigned int i = 0; i < _functionList.size(); ++i)    {        if (_functionList[i]->str() == funcname)        {            return _functionList[i];        }    }    return NULL;}void Tokenizer::fillFunctionList(){    _functionList.clear();    int indentlevel = 0;    for (const Token *tok = _tokens; tok; tok = tok->next())    {        if (tok->str() == "{")            ++indentlevel;        else if (tok->str() == "}")            --indentlevel;        if (indentlevel > 0)        {            continue;        }        if (Token::Match(tok, "%var% ("))        {            // Check if this is the first token of a function implementation..            for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next())            {                if (tok2->str() == ";")                {                    tok = tok2;                    break;                }                else if (tok2->str() == "{")                {                    break;                }                else if (tok2->str() == ")")                {                    if (Token::Match(tok2, ") const| {"))                    {                        _functionList.push_back(tok);                        tok = tok2;                    }                    else                    {                        tok = tok2;                        while (tok->next() && !strchr(";{", tok->next()->aaaa0()))                            tok = tok->next();                    }                    break;                }            }        }    }    // If the _functionList functions with duplicate names, remove them    // TODO this will need some better handling    for (unsigned int func1 = 0; func1 < _functionList.size();)    {        bool hasDuplicates = false;        for (unsigned int func2 = func1 + 1; func2 < _functionList.size();)        {            if (_functionList[func1]->str() == _functionList[func2]->str())            {                hasDuplicates = true;                _functionList.erase(_functionList.begin() + func2);            }            else            {                ++func2;            }        }        if (! hasDuplicates)        {            ++func1;        }        else        {            _functionList.erase(_functionList.begin() + func1);        }    }}//---------------------------------------------------------------------------// Deallocate lists..void Tokenizer::DeallocateTokens(){    deleteTokens(_tokens);    _tokens = 0;    _tokensBack = 0;    _files.clear();}void Tokenizer::deleteTokens(Token *tok){    while (tok)    {        Token *next = tok->next();        delete tok;        tok = next;    }}//---------------------------------------------------------------------------const char *Tokenizer::getParameterName(const Token *ftok, int par){    int _par = 1;    for (; ftok; ftok = ftok->next())    {        if (ftok->str() == ",")            ++_par;        if (par == _par && Token::Match(ftok, "%var% [,)]"))            return ftok->aaaa();    }    return NULL;}//---------------------------------------------------------------------------std::string Tokenizer::fileLine(const Token *tok) const{    std::ostringstream ostr;    ostr << "[" << _files.at(tok->fileIndex()) << ":" << tok->linenr() << "]";    return ostr.str();}std::string Tokenizer::file(const Token *tok) const{    return _files.at(tok->fileIndex());}//---------------------------------------------------------------------------

⌨️ 快捷键说明

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