void CheckInternal::checkMissingPercentCharacter() { static std::set<std::string> magics; if (magics.empty()) { magics.insert("%any%"); magics.insert("%bool%"); magics.insert("%char%"); magics.insert("%comp%"); magics.insert("%num%"); magics.insert("%op%"); magics.insert("%cop%"); magics.insert("%or%"); magics.insert("%oror%"); magics.insert("%str%"); magics.insert("%type%"); magics.insert("%var%"); magics.insert("%varid%"); } for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { if (!Token::simpleMatch(tok, "Token :: Match (") && !Token::simpleMatch(tok, "Token :: findmatch (")) continue; const std::string& funcname = tok->strAt(2); // Get pattern string const Token *pattern_tok = tok->tokAt(4)->nextArgument(); if (!pattern_tok || pattern_tok->type() != Token::eString) continue; const std::string pattern = pattern_tok->strValue(); std::set<std::string>::const_iterator magic, magics_end = magics.end(); for (magic = magics.begin(); magic != magics_end; ++magic) { const std::string broken_magic = (*magic).substr(0, (*magic).size()-1); std::string::size_type pos = 0; while ((pos = pattern.find(broken_magic, pos)) != std::string::npos) { // Check if it's the full pattern if (pattern.find(*magic, pos) != pos) { // Known whitelist of substrings if ((broken_magic == "%var" && pattern.find("%varid%", pos) == pos) || (broken_magic == "%or" && pattern.find("%oror%", pos) == pos)) { ++pos; continue; } missingPercentCharacterError(tok, pattern, funcname); } ++pos; } } } }
void CheckInternal::checkMissingPercentCharacter() { const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (std::size_t i = 0; i < symbolDatabase->functionScopes.size(); ++i) { const Scope * scope = symbolDatabase->functionScopes[i]; for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { if (!Token::simpleMatch(tok, "Token :: Match (") && !Token::simpleMatch(tok, "Token :: findmatch (")) continue; const std::string& funcname = tok->strAt(2); // Get pattern string const Token *patternTok = tok->tokAt(4)->nextArgument(); if (!patternTok || patternTok->tokType() != Token::eString) continue; const std::string pattern = patternTok->strValue(); std::set<std::string>::const_iterator knownPattern, knownPatternsEnd = knownPatterns.end(); for (knownPattern = knownPatterns.begin(); knownPattern != knownPatternsEnd; ++knownPattern) { const std::string brokenPattern = (*knownPattern).substr(0, (*knownPattern).size() - 1); std::string::size_type pos = 0; while ((pos = pattern.find(brokenPattern, pos)) != std::string::npos) { // Check if it's the full pattern if (pattern.find(*knownPattern, pos) != pos) { // Known whitelist of substrings if ((brokenPattern == "%var" && pattern.find("%varid%", pos) == pos) || (brokenPattern == "%or" && pattern.find("%oror%", pos) == pos)) { ++pos; continue; } missingPercentCharacterError(tok, pattern, funcname); } ++pos; } } } } }