📄 checkother.cpp
字号:
{ // 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 + -