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

📄 checkother.cpp

📁 cppcheck is a static C/C++ code analyzer that checks for memory leaks, mismatching allocation-deallo
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{    // Walk through all tokens..    bool func = false;    int indentlevel = 0;    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())    {        // Skip class and struct declarations..        if ((tok->str() == "class") || (tok->str() == "struct"))        {            for (const Token *tok2 = tok; tok2; tok2 = tok2->next())            {                if (tok2->str() == "{")                {                    int indentlevel2 = 0;                    for (tok = tok2; tok; tok = tok->next())                    {                        if (tok->str() == "{")                        {                            ++indentlevel2;                        }                        if (tok->str() == "}")                        {                            --indentlevel2;                            if (indentlevel2 <= 0)                            {                                tok = tok->next();                                break;                            }                        }                    }                    break;                }                if (Token::Match(tok2, "[,);]"))                {                    break;                }            }            if (! tok)                break;        }        if (tok->str() == "{")        {            ++indentlevel;        }        if (tok->str() == "}")        {            --indentlevel;            if (indentlevel == 0)                func = false;        }        if (indentlevel == 0 && Token::Match(tok, ") {"))        {            func = true;        }        if (indentlevel > 0 && func && Token::Match(tok, "[{};]"))        {            // First token of statement..            const Token *tok1 = tok->next();            if (! tok1)                continue;            if ((tok1->str() == "return") ||                (tok1->str() == "delete") ||                (tok1->str() == "goto") ||                (tok1->str() == "else"))                continue;            // Variable declaration?            if (Token::Match(tok1, "%var% %var% ;") ||                Token::Match(tok1, "%var% %var% ="))            {                CheckVariableScope_LookupVar(tok1, tok1->strAt(1));            }        }    }}//---------------------------------------------------------------------------void CheckOther::CheckVariableScope_LookupVar(const Token *tok1, const char varname[]){    const Token *tok = tok1;    // Skip the variable declaration..    while (tok && !Token::Match(tok, ";"))        tok = tok->next();    // Check if the variable is used in this indentlevel..    bool used = false, used1 = false;    int indentlevel = 0;    int parlevel = 0;    bool for_or_while = false;    while (indentlevel >= 0 && tok)    {        if (tok->str() == "{")        {            ++indentlevel;        }        else if (tok->str() == "}")        {            --indentlevel;            if (indentlevel == 0)            {                if (for_or_while && used)                    return;                used1 = used;                used = false;            }        }        else if (tok->str() == "(")        {            ++parlevel;        }        else if (tok->str() == ")")        {            --parlevel;        }        else if (tok->str() == varname)        {            if (indentlevel == 0 || used1)                return;            used = true;        }        else if (indentlevel == 0)        {            if ((tok->str() == "for") || (tok->str() == "while"))                for_or_while = true;            if (parlevel == 0 && (tok->str() == ";"))                for_or_while = false;        }        tok = tok->next();    }    // Warning if "used" is true    _errorLogger->variableScope(_tokenizer, tok1, varname);}//---------------------------------------------------------------------------//---------------------------------------------------------------------------// Check for constant function parameters//---------------------------------------------------------------------------void CheckOther::CheckConstantFunctionParameter(){    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())    {        if (Token::Match(tok, "[,(] const std :: %type% %var% [,)]"))        {            _errorLogger->passedByValue(_tokenizer, tok, tok->strAt(5));        }        else if (Token::Match(tok, "[,(] const %type% %var% [,)]"))        {            // Check if type is a struct or class.            const std::string pattern(std::string("class|struct ") + tok->strAt(2));            if (Token::findmatch(_tokenizer->tokens(), pattern.c_str()))            {                _errorLogger->passedByValue(_tokenizer, tok, tok->strAt(3));            }        }    }}//---------------------------------------------------------------------------//---------------------------------------------------------------------------// Check that all struct members are used//---------------------------------------------------------------------------void CheckOther::CheckStructMemberUsage(){    const char *structname = 0;    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())    {        if (tok->fileIndex() != 0)            continue;        if (Token::Match(tok, "struct|union %type% {"))        {            structname = tok->strAt(1);            // Bail out if struct/union contain any functions            for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next())            {                if (tok2->str() == "(")                {                    structname = 0;                    break;                }                if (tok2->str() == "}")                    break;            }        }        if (tok->str() == "}")            structname = 0;        if (structname && Token::Match(tok, "[{;]"))        {            const char *varname = 0;            if (Token::Match(tok->next(), "%type% %var% [;[]"))                varname = tok->strAt(2);            else if (Token::Match(tok->next(), "%type% %type% %var% [;[]"))                varname = tok->strAt(3);            else if (Token::Match(tok->next(), "%type% * %var% [;[]"))                varname = tok->strAt(3);            else if (Token::Match(tok->next(), "%type% %type% * %var% [;[]"))                varname = tok->strAt(4);            else                continue;            const std::string usagePattern(". " + std::string(varname));            bool used = false;            for (const Token *tok2 = _tokenizer->tokens(); tok2; tok2 = tok2->next())            {                if (Token::simpleMatch(tok2, usagePattern.c_str()))                {                    used = true;                    break;                }            }            if (! used)            {                _errorLogger->unusedStructMember(_tokenizer, tok->next(), structname, varname);            }        }    }}//---------------------------------------------------------------------------// Check usage of char variables..//---------------------------------------------------------------------------void CheckOther::CheckCharVariable(){    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())    {        // Declaring the variable..        if (Token::Match(tok, "[{};(,] signed| char %var% [;=,)]"))        {            // Set tok to point to the variable name            tok = tok->tokAt(2);            if (tok->str() == "char")                tok = tok->next();            // Check usage of char variable..            int indentlevel = 0;            for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next())            {                if (tok2->str() == "{")                    ++indentlevel;                else if (tok2->str() == "}")                {                    --indentlevel;                    if (indentlevel <= 0)                        break;                }                std::string temp = "%var% [ " + tok->str() + " ]";                if ((tok2->str() != ".") && Token::Match(tok2->next(), temp.c_str()))                {                    _errorLogger->charArrayIndex(_tokenizer, tok2->next());                    break;                }                std::string tempFirst = "%var% [&|] " + tok->str();                std::string tempSecond = tok->str() + " [&|]";                if (Token::Match(tok2, tempFirst.c_str()) || Token::Match(tok2, tempSecond.c_str()))                {                    _errorLogger->charBitOp(_tokenizer, tok2);                    break;                }            }        }    }}//---------------------------------------------------------------------------//---------------------------------------------------------------------------// Incomplete statement..//---------------------------------------------------------------------------void CheckOther::CheckIncompleteStatement(){    int parlevel = 0;    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())    {        if (tok->str() == "(")            ++parlevel;        else if (tok->str() == ")")            --parlevel;        if (parlevel != 0)            continue;        if (Token::Match(tok, "= {"))        {            /* We are in an assignment, so it's not a statement.             * Skip until ";" */            while (!Token::Match(tok, ";"))            {                int level = 0;                do                {                    if (tok->str() == "(" || tok->str() == "{")                        ++level;                    else if (tok->str() == ")" || tok->str() == "}")                        --level;                    tok = tok->next();                    if (tok == NULL)                        return;                }                while (level > 0);            }            continue;        }        if (Token::Match(tok, "[;{}] %str%") && !Token::Match(tok->tokAt(2), "[,}]"))        {            _errorLogger->constStatement(_tokenizer, tok->next(), "string");        }        if (Token::Match(tok, "[;{}] %num%") && !Token::Match(tok->tokAt(2), "[,}]"))        {            _errorLogger->constStatement(_tokenizer, tok->next(), "numeric");        }    }}//---------------------------------------------------------------------------//---------------------------------------------------------------------------// str plus char//---------------------------------------------------------------------------void CheckOther::strPlusChar(){    bool charVars[10000] = {0};    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())    {        // Declaring char variable..        if (Token::Match(tok, "char %var% [;=]"))        {            unsigned int varid = tok->next()->varId();            if (varid > 0 && varid < 10000)                charVars[varid] = true;        }        //        else if (Token::Match(tok, "[=(] %str% + %any%"))        {            // char constant..            const char *s = tok->strAt(3);            if (*s == '\'')                _errorLogger->strPlusChar(_tokenizer, tok->next());            // char variable..            unsigned int varid = tok->tokAt(3)->varId();            if (varid > 0 && varid < 10000 && charVars[varid])                _errorLogger->strPlusChar(_tokenizer, tok->next());        }    }}void CheckOther::returnPointerToStackData(){    bool infunc = false;    int indentlevel = 0;    std::list<unsigned int> arrayVar;    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())    {        if (!infunc && Token::simpleMatch(tok, ") {"))        {            infunc = true;            indentlevel = 0;            arrayVar.clear();        }        if (infunc)        {            if (tok->str() == "{")                ++indentlevel;            else if (tok->str() == "}")            {                --indentlevel;                if (indentlevel <= 0)                    infunc = false;                continue;            }            // Declaring a local array..            if (Token::Match(tok, "[;{}] %type% %var% ["))            {                arrayVar.push_back(tok->tokAt(2)->varId());            }            // Return pointer to local array variable..            if (Token::Match(tok, "return %var% ;"))            {                unsigned int varid = tok->next()->varId();                if (varid > 0 && std::find(arrayVar.begin(), arrayVar.end(), varid) != arrayVar.end())                    _errorLogger->returnLocalVariable(_tokenizer, tok);            }        }        // Declaring array variable..    }}

⌨️ 快捷键说明

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