From 44333f316a6008bf5936ff6a860042f48956a64e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 24 Jul 2013 13:06:59 +0200 Subject: [PATCH] Added terminate() handling to get quicker response when the user wants to terminate --- lib/cppcheck.cpp | 6 ++++ lib/preprocessor.cpp | 43 +++++++++++++++++++++++--- lib/preprocessor.h | 2 +- lib/tokenize.cpp | 64 +++++++++++++++++++++++++++++++++++++++ lib/tokenlist.cpp | 3 ++ test/testpreprocessor.cpp | 3 +- 6 files changed, 115 insertions(+), 6 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index f71606a34..11a08aa86 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -397,7 +397,13 @@ void CppCheck::checkFile(const std::string &code, const char FileName[]) (*it)->runSimplifiedChecks(&_tokenizer, &_settings, this); } + if (_settings.terminated()) + return; + executeRules("simple", _tokenizer); + + if (_settings.terminated()) + return; } catch (const InternalError &e) { std::list locationList; ErrorLogger::ErrorMessage::FileLocation loc2; diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 518b9ac00..0bb1abf97 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -169,6 +169,9 @@ std::string Preprocessor::read(std::istream &istr, const std::string &filename) bom |= (unsigned int)istr.get(); } + if (_settings && _settings->terminated()) + return ""; + // ------------------------------------------------------------------------------------------ // // handling @@ -231,20 +234,28 @@ std::string Preprocessor::read(std::istream &istr, const std::string &filename) // // Remove all comments.. result = removeComments(result, filename); + if (_settings && _settings->terminated()) + return ""; // ------------------------------------------------------------------------------------------ // // Clean up all preprocessor statements result = preprocessCleanupDirectives(result); + if (_settings && _settings->terminated()) + return ""; // ------------------------------------------------------------------------------------------ // // Clean up preprocessor #if statements with Parentheses result = removeParentheses(result); + if (_settings && _settings->terminated()) + return ""; // Remove '#if 0' blocks if (result.find("#if 0\n") != std::string::npos) result = removeIf0(result); + if (_settings && _settings->terminated()) + return ""; return result; } @@ -392,6 +403,9 @@ std::string Preprocessor::removeComments(const std::string &str, const std::stri writeError(filename, lineno, _errorLogger, "syntaxError", errmsg.str()); } + if (_settings && _settings->terminated()) + return ""; + if ((str.compare(i, 7, "#error ") == 0 && (!_settings || _settings->userDefines.empty())) || str.compare(i, 9, "#warning ") == 0) { @@ -775,7 +789,7 @@ std::string Preprocessor::removeSpaceNearNL(const std::string &str) return tmp; } -std::string Preprocessor::replaceIfDefined(const std::string &str) +std::string Preprocessor::replaceIfDefined(const std::string &str) const { std::string ret(str); std::string::size_type pos; @@ -791,6 +805,9 @@ std::string Preprocessor::replaceIfDefined(const std::string &str) ret.insert(pos + 3, "def "); } ++pos; + + if (_settings && _settings->terminated()) + return ""; } pos = 0; @@ -804,6 +821,9 @@ std::string Preprocessor::replaceIfDefined(const std::string &str) ret.insert(pos + 3, "ndef "); } ++pos; + + if (_settings && _settings->terminated()) + return ""; } pos = 0; @@ -816,6 +836,9 @@ std::string Preprocessor::replaceIfDefined(const std::string &str) ret.erase(pos + 6, 8); } ++pos; + + if (_settings && _settings->terminated()) + return ""; } return ret; @@ -903,6 +926,9 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe line += ")"; else line.insert(pos, ")"); + + if (_settings && _settings->terminated()) + return; } } ostr << line << "\n"; @@ -1084,6 +1110,9 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const while (std::getline(istr, line)) { ++linenr; + if (_settings && _settings->terminated()) + return ret; + if (_errorLogger) _errorLogger->reportProgress(filename, "Preprocessing (get configurations 1)", 0); @@ -1634,6 +1663,9 @@ std::string Preprocessor::getcode(const std::string &filedata, const std::string while (std::getline(istr, line)) { ++lineno; + if (_settings && _settings->terminated()) + return ""; + if (line.compare(0, 11, "#pragma asm") == 0) { ret << "\n"; bool found_end = false; @@ -1918,9 +1950,6 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str if (_errorLogger) _errorLogger->reportProgress(filePath, "Preprocessor (handleIncludes)", 0); - if (_settings && _settings->terminated()) - return ""; - std::ostringstream ostr; std::istringstream istr(code); std::string line; @@ -1928,6 +1957,9 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str while (std::getline(istr,line)) { ++linenr; + if (_settings && _settings->terminated()) + return ""; + // has there been a true #if condition at the current indentmatch level? // then no more #elif or #else can be true before the #endif is seen. while (elseIsTrueStack.size() != indentmatch + 1) { @@ -2109,6 +2141,9 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filePath std::string::size_type endfilePos = 0; std::set handledFiles; while ((pos = code.find("#include", pos)) != std::string::npos) { + if (_settings && _settings->terminated()) + return; + // Accept only includes that are at the start of a line if (pos > 0 && code[pos-1] != '\n') { pos += 8; // length of "#include" diff --git a/lib/preprocessor.h b/lib/preprocessor.h index 4155c1565..a15b8cf2f 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -142,7 +142,7 @@ public: * @param str The string to be converted * @return The replaced string */ - static std::string replaceIfDefined(const std::string &str); + std::string replaceIfDefined(const std::string &str) const; /** * expand macros in code. ifdefs etc are ignored so the code must be a single configuration diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index a74cb3f1f..9e32e436f 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -510,6 +510,9 @@ void Tokenizer::simplifyTypedef() if (_errorLogger && !list.getFiles().empty()) _errorLogger->reportProgress(list.getFiles()[0], "Tokenize (typedef)", tok->progressValue()); + if (_settings && _settings->terminated()) + return; + if (goback) { //jump back once, see the comment at the end of the function goback = false; @@ -953,6 +956,9 @@ void Tokenizer::simplifyTypedef() std::size_t classLevel = spaceInfo.size(); for (Token *tok2 = tok; tok2; tok2 = tok2->next()) { + if (_settings && _settings->terminated()) + return; + // check for end of scope if (tok2->str() == "}") { // check for end of member function @@ -1570,6 +1576,9 @@ bool Tokenizer::tokenize(std::istream &code, return false; } + if (_settings->terminated()) + return false; + // if MACRO for (Token *tok = list.front(); tok; tok = tok->next()) { if (Token::Match(tok, "if|for|while|BOOST_FOREACH %var% (")) { @@ -1616,6 +1625,9 @@ bool Tokenizer::tokenize(std::istream &code, } } + if (_settings->terminated()) + return false; + // replace 'NULL' and similar '0'-defined macros with '0' simplifyNull(); @@ -1663,6 +1675,9 @@ bool Tokenizer::tokenize(std::istream &code, } } + if (_settings->terminated()) + return false; + // Remove "volatile", "inline", "register", and "restrict" simplifyKeyword(); @@ -1689,6 +1704,9 @@ bool Tokenizer::tokenize(std::istream &code, return false; } + if (_settings->terminated()) + return false; + // Remove __declspec() simplifyDeclspec(); @@ -1713,6 +1731,9 @@ bool Tokenizer::tokenize(std::istream &code, // convert Microsoft string functions simplifyMicrosoftStringFunctions(); + if (_settings->terminated()) + return false; + // Remove Qt signals and slots simplifyQtSignalsSlots(); @@ -1767,6 +1788,10 @@ bool Tokenizer::tokenize(std::istream &code, // enum.. simplifyEnum(); + // The simplify enum have inner loops + if (_settings && _settings->terminated()) + return false; + // Remove __asm.. simplifyAsm(); @@ -1824,6 +1849,10 @@ bool Tokenizer::tokenize(std::istream &code, // unsigned long long int => long _isUnsigned=true,_isLong=true simplifyStdType(); + // The simplifyTemplates have inner loops + if (_settings && _settings->terminated()) + return false; + // simplify bit fields.. simplifyBitfields(); @@ -1914,6 +1943,10 @@ bool Tokenizer::tokenize(std::istream &code, tok = fortok; }*/ + // The simplifyTemplates have inner loops + if (_settings && _settings->terminated()) + return false; + simplifyConst(); // struct simplification "struct S {} s; => struct S { } ; S s ; @@ -1925,6 +1958,10 @@ bool Tokenizer::tokenize(std::istream &code, // Change initialisation of variable to assignment simplifyInitVar(); + // The simplifyTemplates have inner loops + if (_settings && _settings->terminated()) + return false; + // Split up variable declarations. simplifyVarDecl(false); @@ -1937,6 +1974,10 @@ bool Tokenizer::tokenize(std::istream &code, // x = ({ 123; }); => { x = 123; } simplifyAssignmentBlock(); + // The simplifyTemplates have inner loops + if (_settings && _settings->terminated()) + return false; + simplifyVariableMultipleAssign(); // Remove redundant parentheses @@ -1948,6 +1989,10 @@ bool Tokenizer::tokenize(std::istream &code, // Handle templates.. simplifyTemplates(); + // The simplifyTemplates have inner loops + if (_settings && _settings->terminated()) + return false; + // Simplify templates.. sometimes the "simplifyTemplates" fail and // then unsimplified function calls etc remain. These have the // "wrong" syntax. So this function will just fix so that the @@ -1988,6 +2033,10 @@ bool Tokenizer::tokenize(std::istream &code, setVarId(); } + // The simplify enum might have inner loops + if (_settings && _settings->terminated()) + return false; + // Add std:: in front of std classes, when using namespace std; was given simplifyNamespaceStd(); @@ -2863,6 +2912,9 @@ void Tokenizer::setVarId() continue; } + if (_settings->terminated()) + return; + // locate the variable name.. const Token *tok2 = (tok->isName()) ? tok : tok->next(); @@ -3379,6 +3431,9 @@ bool Tokenizer::simplifyTokenList() simplifyGoto(); + if (_settings && _settings->terminated()) + return false; + simplifySizeof(); simplifyUndefinedSizeArray(); @@ -3421,6 +3476,9 @@ bool Tokenizer::simplifyTokenList() } } + if (_settings && _settings->terminated()) + return false; + // Simplify simple calculations.. simplifyCalculations(); @@ -3564,6 +3622,9 @@ bool Tokenizer::simplifyTokenList() tok->deleteNext(); } + if (_settings->terminated()) + return false; + if (_settings->debug) { list.front()->printOut(0, list.getFiles()); @@ -7414,6 +7475,9 @@ void Tokenizer::simplifyEnum() // Substitute enum values { + if (_settings && _settings->terminated()) + return; + const std::string pattern = className.empty() ? std::string("") : std::string(className + " :: "); diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 57ab2033b..5b36ac6c9 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -322,6 +322,9 @@ bool TokenList::createTokens(std::istream &code, const std::string& file0) CurrentToken.clear(); if (ch == '\n') { + if (_settings->terminated()) + return false; + ++lineno; continue; } else if (ch == ' ') { diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index f781cbe0f..0c744fb17 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -49,7 +49,8 @@ public: class OurPreprocessor : public Preprocessor { public: static std::string replaceIfDefined(const std::string &str) { - return Preprocessor::replaceIfDefined(str); + Preprocessor p; + return p.replaceIfDefined(str); } static std::string expandMacros(const std::string& code, ErrorLogger *errorLogger = 0) {