Exemplo n.º 1
0
    void reportSuppressions(const Settings &settings, const std::map<std::string, std::string> &files) {
        // make it verbose that this check is disabled
        const bool unusedFunctionCheck = false;

        if (settings.jointSuppressionReport) {
            for (std::map<std::string, std::string>::const_iterator i = files.begin(); i != files.end(); ++i) {
                reportUnmatchedSuppressions(settings.nomsg.getUnmatchedLocalSuppressions(i->first, unusedFunctionCheck));
            }
        }

        reportUnmatchedSuppressions(settings.nomsg.getUnmatchedGlobalSuppressions(unusedFunctionCheck));
    }
Exemplo n.º 2
0
    void checkSuppressionThreads(const char code[], const std::string &suppression = "")
    {
        errout.str("");
        output.str("");

        std::vector<std::string> filenames;
        std::map<std::string, long> filesizes;
        filenames.push_back("test.cpp");

        Settings settings;
        settings._jobs = 1;
        settings._inlineSuppressions = true;
        if (!suppression.empty())
        {
            std::string r = settings.nomsg.addSuppressionLine(suppression);
            ASSERT_EQUALS("", r);
        }
        ThreadExecutor executor(filenames, filesizes, settings, *this);
        for (unsigned int i = 0; i < filenames.size(); ++i)
            executor.addFileContent(filenames[i], code);

        executor.check();

        reportUnmatchedSuppressions(settings.nomsg.getUnmatchedGlobalSuppressions());
    }
Exemplo n.º 3
0
    // Check the suppression for multiple files
    void checkSuppression(const char *names[], const char *codes[], const std::string &suppression = "") {
        // Clear the error log
        errout.str("");

        CppCheck cppCheck(*this, true);
        Settings& settings = cppCheck.settings();
        settings._inlineSuppressions = true;
        if (!suppression.empty())
            settings.nomsg.addSuppressionLine(suppression);

        for (int i = 0; names[i] != NULL; ++i)
            cppCheck.check(names[i], codes[i]);

        reportUnmatchedSuppressions(settings.nomsg.getUnmatchedGlobalSuppressions());
    }
Exemplo n.º 4
0
int CppCheckExecutor::check(int argc, const char* const argv[])
{
    CppCheck cppCheck(*this, true);
    if (!parseFromArgs(&cppCheck, argc, argv))
    {
        return EXIT_FAILURE;
    }

    if (cppCheck.settings().reportProgress)
        time1 = std::time(0);

    _settings = cppCheck.settings();
    if (_settings._xml)
    {
        reportErr(ErrorLogger::ErrorMessage::getXMLHeader(_settings._xml_version));
    }

    unsigned int returnValue = 0;
    if (_settings._jobs == 1)
    {
        // Single process
        returnValue = cppCheck.check();
    }
    else if (!ThreadExecutor::isEnabled())
    {
        std::cout << "No thread support yet implemented for this platform." << std::endl;
    }
    else
    {
        // Multiple processes
        const std::vector<std::string> &filenames = cppCheck.filenames();
        Settings &settings = cppCheck.settings();
        ThreadExecutor executor(filenames, settings, *this);
        returnValue = executor.check();
    }

    reportUnmatchedSuppressions(cppCheck.settings().nomsg.getUnmatchedGlobalSuppressions());

    if (_settings._xml)
    {
        reportErr(ErrorLogger::ErrorMessage::getXMLFooter(_settings._xml_version));
    }

    if (returnValue)
        return _settings._exitCode;
    else
        return 0;
}
Exemplo n.º 5
0
    // Check the suppression
    void checkSuppression(const char code[], const std::string &suppression = "") {
        // Clear the error log
        errout.str("");

        CppCheck cppCheck(*this, true);
        Settings& settings = cppCheck.settings();
        settings._inlineSuppressions = true;
        if (!suppression.empty()) {
            std::string r = settings.nomsg.addSuppressionLine(suppression);
            ASSERT_EQUALS("", r);
        }

        cppCheck.check("test.cpp", code);

        reportUnmatchedSuppressions(settings.nomsg.getUnmatchedGlobalSuppressions());
    }
Exemplo n.º 6
0
    void suppressUnmatchedSuppressions() {
        std::list<Suppressions::Suppression> suppressions;

        // No unmatched suppression
        errout.str("");
        suppressions.clear();
        reportUnmatchedSuppressions(suppressions);
        ASSERT_EQUALS("", errout.str());

        // suppress all unmatchedSuppression
        errout.str("");
        suppressions.clear();
        suppressions.emplace_back("abc", "a.c", 10U);
        suppressions.emplace_back("unmatchedSuppression", "*", Suppressions::Suppression::NO_LINE);
        reportUnmatchedSuppressions(suppressions);
        ASSERT_EQUALS("", errout.str());

        // suppress all unmatchedSuppression in a.c
        errout.str("");
        suppressions.clear();
        suppressions.emplace_back("abc", "a.c", 10U);
        suppressions.emplace_back("unmatchedSuppression", "a.c", Suppressions::Suppression::NO_LINE);
        reportUnmatchedSuppressions(suppressions);
        ASSERT_EQUALS("", errout.str());

        // suppress unmatchedSuppression in a.c at line 10
        errout.str("");
        suppressions.clear();
        suppressions.emplace_back("abc", "a.c", 10U);
        suppressions.emplace_back("unmatchedSuppression", "a.c", 10U);
        reportUnmatchedSuppressions(suppressions);
        ASSERT_EQUALS("", errout.str());

        // don't suppress unmatchedSuppression when file is mismatching
        errout.str("");
        suppressions.clear();
        suppressions.emplace_back("abc", "a.c", 10U);
        suppressions.emplace_back("unmatchedSuppression", "b.c", Suppressions::Suppression::NO_LINE);
        reportUnmatchedSuppressions(suppressions);
        ASSERT_EQUALS("[a.c:10]: (information) Unmatched suppression: abc\n", errout.str());

        // don't suppress unmatchedSuppression when line is mismatching
        errout.str("");
        suppressions.clear();
        suppressions.emplace_back("abc", "a.c", 10U);
        suppressions.emplace_back("unmatchedSuppression", "a.c", 1U);
        reportUnmatchedSuppressions(suppressions);
        ASSERT_EQUALS("[a.c:10]: (information) Unmatched suppression: abc\n", errout.str());
    }
Exemplo n.º 7
0
    void checkSuppressionThreads(const char code[], const std::string &suppression = emptyString) {
        errout.str("");
        output.str("");

        std::map<std::string, std::size_t> files;
        files["test.cpp"] = 1;

        Settings settings;
        settings._jobs = 1;
        settings._inlineSuppressions = true;
        settings.addEnabled("information");
        if (!suppression.empty()) {
            ASSERT_EQUALS("", settings.nomsg.addSuppressionLine(suppression));
        }
        ThreadExecutor executor(files, settings, *this);
        for (std::map<std::string, std::size_t>::const_iterator i = files.begin(); i != files.end(); ++i)
            executor.addFileContent(i->first, code);

        executor.check();

        reportUnmatchedSuppressions(settings.nomsg.getUnmatchedGlobalSuppressions(false));
    }
Exemplo n.º 8
0
/*
 * That is a method which gets called from check_wrapper
 * */
int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const char* const argv[])
{
    Settings& settings = cppcheck.settings();
    _settings = &settings;
    bool std = tryLoadLibrary(settings.library, argv[0], "std.cfg");
    bool posix = true;
    if (settings.standards.posix)
        posix = tryLoadLibrary(settings.library, argv[0], "posix.cfg");
    bool windows = true;
    if (settings.isWindowsPlatform())
        windows = tryLoadLibrary(settings.library, argv[0], "windows.cfg");

    if (!std || !posix || !windows) {
        const std::list<ErrorLogger::ErrorMessage::FileLocation> callstack;
        const std::string msg("Failed to load " + std::string(!std ? "std.cfg" : !posix ? "posix.cfg" : "windows.cfg") + ". Your Cppcheck installation is broken, please re-install.");
#ifdef CFGDIR
        const std::string details("The Cppcheck binary was compiled with CFGDIR set to \"" +
                                  std::string(CFGDIR) + "\" and will therefore search for "
                                  "std.cfg in that path.");
#else
        const std::string cfgfolder(Path::fromNativeSeparators(Path::getPathFromFilename(argv[0])) + "cfg");
        const std::string details("The Cppcheck binary was compiled without CFGDIR set. Either the "
                                  "std.cfg should be available in " + cfgfolder + " or the CFGDIR "
                                  "should be configured.");
#endif
        ErrorLogger::ErrorMessage errmsg(callstack, Severity::information, msg+" "+details, "failedToLoadCfg", false);
        reportErr(errmsg);
        return EXIT_FAILURE;
    }

    if (settings.reportProgress)
        time1 = std::time(0);

    if (settings._xml) {
        reportErr(ErrorLogger::ErrorMessage::getXMLHeader(settings._xml_version));
    }

    unsigned int returnValue = 0;
    if (settings._jobs == 1) {
        // Single process
        settings.jointSuppressionReport = true;

        std::size_t totalfilesize = 0;
        for (std::map<std::string, std::size_t>::const_iterator i = _files.begin(); i != _files.end(); ++i) {
            totalfilesize += i->second;
        }

        std::size_t processedsize = 0;
        unsigned int c = 0;
        for (std::map<std::string, std::size_t>::const_iterator i = _files.begin(); i != _files.end(); ++i) {
            if (!_settings->library.markupFile(i->first)
                || !_settings->library.processMarkupAfterCode(i->first)) {
                returnValue += cppcheck.check(i->first);
                processedsize += i->second;
                if (!settings.quiet)
                    reportStatus(c + 1, _files.size(), processedsize, totalfilesize);
                c++;
            }
        }

        // second loop to parse all markup files which may not work until all
        // c/cpp files have been parsed and checked
        for (std::map<std::string, std::size_t>::const_iterator i = _files.begin(); i != _files.end(); ++i) {
            if (_settings->library.markupFile(i->first) && _settings->library.processMarkupAfterCode(i->first)) {
                returnValue += cppcheck.check(i->first);
                processedsize += i->second;
                if (!settings.quiet)
                    reportStatus(c + 1, _files.size(), processedsize, totalfilesize);
                c++;
            }
        }
        cppcheck.analyseWholeProgram();
    } else if (!ThreadExecutor::isEnabled()) {
        std::cout << "No thread support yet implemented for this platform." << std::endl;
    } else {
        // Multiple processes
        ThreadExecutor executor(_files, settings, *this);
        returnValue = executor.check();
    }

    if (settings.isEnabled("information") || settings.checkConfiguration) {
        const bool enableUnusedFunctionCheck = cppcheck.unusedFunctionCheckIsEnabled();

        if (settings.jointSuppressionReport) {
            for (std::map<std::string, std::size_t>::const_iterator i = _files.begin(); i != _files.end(); ++i) {
                reportUnmatchedSuppressions(settings.nomsg.getUnmatchedLocalSuppressions(i->first, enableUnusedFunctionCheck));
            }
        }

        reportUnmatchedSuppressions(settings.nomsg.getUnmatchedGlobalSuppressions(enableUnusedFunctionCheck));
    }

    if (!settings.checkConfiguration) {
        cppcheck.tooManyConfigsError("",0U);

        if (settings.isEnabled("missingInclude") && (Preprocessor::missingIncludeFlag || Preprocessor::missingSystemIncludeFlag)) {
            const std::list<ErrorLogger::ErrorMessage::FileLocation> callStack;
            ErrorLogger::ErrorMessage msg(callStack,
                                          Severity::information,
                                          "Cppcheck cannot find all the include files (use --check-config for details)\n"
                                          "Cppcheck cannot find all the include files. Cppcheck can check the code without the "
                                          "include files found. But the results will probably be more accurate if all the include "
                                          "files are found. Please check your project's include directories and add all of them "
                                          "as include directories for Cppcheck. To see what files Cppcheck cannot find use "
                                          "--check-config.",
                                          Preprocessor::missingIncludeFlag ? "missingInclude" : "missingIncludeSystem",
                                          false);
            reportInfo(msg);
        }
    }

    if (settings._xml) {
        reportErr(ErrorLogger::ErrorMessage::getXMLFooter(settings._xml_version));
    }

    _settings = 0;
    if (returnValue)
        return settings._exitCode;
    else
        return 0;
}
Exemplo n.º 9
0
unsigned int CppCheck::processFile(const std::string& filename, std::istream& fileStream)
{
    exitcode = 0;

    // only show debug warnings for accepted C/C++ source files
    if (!Path::acceptFile(filename))
        _settings.debugwarnings = false;

    if (_settings.terminated())
        return exitcode;

    if (_settings.quiet == false) {
        std::string fixedpath = Path::simplifyPath(filename);
        fixedpath = Path::toNativeSeparators(fixedpath);
        _errorLogger.reportOut(std::string("Checking ") + fixedpath + std::string("..."));
    }

    bool internalErrorFound(false);
    try {
        Preprocessor preprocessor(_settings, this);
        std::list<std::string> configurations;
        std::string filedata;

        {
            Timer t("Preprocessor::preprocess", _settings.showtime, &S_timerResults);
            preprocessor.preprocess(fileStream, filedata, configurations, filename, _settings.includePaths);
        }

        if (_settings.checkConfiguration) {
            return 0;
        }

        // Run define rules on raw code
        for (std::list<Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
            if (it->tokenlist == "define") {
                Tokenizer tokenizer2(&_settings, this);
                std::istringstream istr2(filedata);
                tokenizer2.list.createTokens(istr2, filename);

                for (const Token *tok = tokenizer2.list.front(); tok; tok = tok->next()) {
                    if (tok->str() == "#define") {
                        std::string code = std::string(tok->linenr()-1U, '\n');
                        for (const Token *tok2 = tok; tok2 && tok2->linenr() == tok->linenr(); tok2 = tok2->next())
                            code += " " + tok2->str();
                        Tokenizer tokenizer3(&_settings, this);
                        std::istringstream istr3(code);
                        tokenizer3.list.createTokens(istr3, tokenizer2.list.file(tok));
                        executeRules("define", tokenizer3);
                    }
                }
                break;
            }
        }

        if (!_settings.userDefines.empty() && _settings.maxConfigs==1U) {
            configurations.clear();
            configurations.push_back(_settings.userDefines);
        }

        if (!_settings.force && configurations.size() > _settings.maxConfigs) {
            if (_settings.isEnabled("information")) {
                tooManyConfigsError(Path::toNativeSeparators(filename),configurations.size());
            } else {
                tooManyConfigs = true;
            }
        }

        // write dump file xml prolog
        std::ofstream fdump;
        if (_settings.dump) {
            const std::string dumpfile(filename + ".dump");
            fdump.open(dumpfile.c_str());
            if (fdump.is_open()) {
                fdump << "<?xml version=\"1.0\"?>" << std::endl;
                fdump << "<dumps>" << std::endl;
            }
        }

        std::set<unsigned long long> checksums;
        unsigned int checkCount = 0;
        for (std::list<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it) {
            // bail out if terminated
            if (_settings.terminated())
                break;

            // Check only a few configurations (default 12), after that bail out, unless --force
            // was used.
            if (!_settings.force && ++checkCount > _settings.maxConfigs)
                break;

            cfg = *it;

            // If only errors are printed, print filename after the check
            if (_settings.quiet == false && it != configurations.begin()) {
                std::string fixedpath = Path::simplifyPath(filename);
                fixedpath = Path::toNativeSeparators(fixedpath);
                _errorLogger.reportOut("Checking " + fixedpath + ": " + cfg + "...");
            }

            if (!_settings.userDefines.empty()) {
                if (!cfg.empty())
                    cfg = ";" + cfg;
                cfg = _settings.userDefines + cfg;
            }

            Timer t("Preprocessor::getcode", _settings.showtime, &S_timerResults);
            std::string codeWithoutCfg = preprocessor.getcode(filedata, cfg, filename);
            t.Stop();

            codeWithoutCfg += _settings.append();

            if (_settings.preprocessOnly) {
                if (codeWithoutCfg.compare(0,5,"#file") == 0)
                    codeWithoutCfg.insert(0U, "//");
                std::string::size_type pos = 0;
                while ((pos = codeWithoutCfg.find("\n#file",pos)) != std::string::npos)
                    codeWithoutCfg.insert(pos+1U, "//");
                pos = 0;
                while ((pos = codeWithoutCfg.find("\n#endfile",pos)) != std::string::npos)
                    codeWithoutCfg.insert(pos+1U, "//");
                pos = 0;
                while ((pos = codeWithoutCfg.find(Preprocessor::macroChar,pos)) != std::string::npos)
                    codeWithoutCfg[pos] = ' ';
                reportOut(codeWithoutCfg);
                continue;
            }

            Tokenizer _tokenizer(&_settings, this);
            if (_settings.showtime != SHOWTIME_NONE)
                _tokenizer.setTimerResults(&S_timerResults);

            try {
                // Create tokens, skip rest of iteration if failed
                std::istringstream istr(codeWithoutCfg);
                Timer timer("Tokenizer::createTokens", _settings.showtime, &S_timerResults);
                bool result = _tokenizer.createTokens(istr, filename.c_str());
                timer.Stop();
                if (!result)
                    continue;

                // skip rest of iteration if just checking configuration
                if (_settings.checkConfiguration)
                    continue;

                // Check raw tokens
                checkRawTokens(_tokenizer);

                // Simplify tokens into normal form, skip rest of iteration if failed
                Timer timer2("Tokenizer::simplifyTokens1", _settings.showtime, &S_timerResults);
                result = _tokenizer.simplifyTokens1(cfg);
                timer2.Stop();
                if (!result)
                    continue;

                // dump xml if --dump
                if (_settings.dump && fdump.is_open()) {
                    fdump << "<dump cfg=\"" << cfg << "\">" << std::endl;
                    preprocessor.dump(fdump);
                    _tokenizer.dump(fdump);
                    fdump << "</dump>" << std::endl;
                }

                // Skip if we already met the same simplified token list
                if (_settings.force || _settings.maxConfigs > 1) {
                    const unsigned long long checksum = _tokenizer.list.calculateChecksum();
                    if (checksums.find(checksum) != checksums.end())
                        continue;
                    checksums.insert(checksum);
                }

                // Check normal tokens
                checkNormalTokens(_tokenizer);

                // simplify more if required, skip rest of iteration if failed
                if (_simplify) {
                    // if further simplification fails then skip rest of iteration
                    Timer timer3("Tokenizer::simplifyTokenList2", _settings.showtime, &S_timerResults);
                    result = _tokenizer.simplifyTokenList2();
                    timer3.Stop();
                    if (!result)
                        continue;

                    // Check simplified tokens
                    checkSimplifiedTokens(_tokenizer);
                }

            } catch (const InternalError &e) {
                if (_settings.isEnabled("information") && (_settings.debug || _settings.verbose))
                    purgedConfigurationMessage(filename, cfg);
                internalErrorFound=true;
                std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
                ErrorLogger::ErrorMessage::FileLocation loc;
                if (e.token) {
                    loc.line = e.token->linenr();
                    const std::string fixedpath = Path::toNativeSeparators(_tokenizer.list.file(e.token));
                    loc.setfile(fixedpath);
                } else {
                    ErrorLogger::ErrorMessage::FileLocation loc2;
                    loc2.setfile(Path::toNativeSeparators(filename.c_str()));
                    locationList.push_back(loc2);
                    loc.setfile(_tokenizer.list.getSourceFilePath());
                }
                locationList.push_back(loc);
                const ErrorLogger::ErrorMessage errmsg(locationList,
                                                       Severity::error,
                                                       e.errorMessage,
                                                       e.id,
                                                       false);

                reportErr(errmsg);
            }
        }

        // dumped all configs, close root </dumps> element now
        if (_settings.dump && fdump.is_open())
            fdump << "</dumps>" << std::endl;

    } catch (const std::runtime_error &e) {
        internalError(filename, e.what());
    } catch (const InternalError &e) {
        internalError(filename, e.errorMessage);
        exitcode=1; // e.g. reflect a syntax error
    }

    // In jointSuppressionReport mode, unmatched suppressions are
    // collected after all files are processed
    if (!_settings.jointSuppressionReport && (_settings.isEnabled("information") || _settings.checkConfiguration)) {
        reportUnmatchedSuppressions(_settings.nomsg.getUnmatchedLocalSuppressions(filename, unusedFunctionCheckIsEnabled()));
    }

    _errorList.clear();
    if (internalErrorFound && (exitcode==0)) {
        exitcode=1;
    }
    return exitcode;
}
Exemplo n.º 10
0
unsigned int CppCheck::processFile()
{
    exitcode = 0;

    // TODO: Should this be moved out to its own function so all the files can be
    // analysed before any files are checked?
    if (_settings.test_2_pass && _settings._jobs == 1)
    {
        const std::string printname = Path::toNativeSeparators(_filename);
        reportOut("Analysing " + printname + "...");

        std::ifstream f(_filename.c_str());
        analyseFile(f, _filename);
    }

    _errout.str("");

    if (_settings.terminated())
        return exitcode;

    if (_settings._errorsOnly == false)
    {
        std::string fixedpath(_filename);
        fixedpath = Path::simplifyPath(fixedpath.c_str());
        fixedpath = Path::toNativeSeparators(fixedpath);
        _errorLogger.reportOut(std::string("Checking ") + fixedpath + std::string("..."));
    }

    try
    {
        Preprocessor preprocessor(&_settings, this);
        std::list<std::string> configurations;
        std::string filedata = "";

        if (!_fileContent.empty())
        {
            // File content was given as a string
            std::istringstream iss(_fileContent);
            preprocessor.preprocess(iss, filedata, configurations, _filename, _settings._includePaths);
        }
        else
        {
            // Only file name was given, read the content from file
            std::ifstream fin(_filename.c_str());
            Timer t("Preprocessor::preprocess", _settings._showtime, &S_timerResults);
            preprocessor.preprocess(fin, filedata, configurations, _filename, _settings._includePaths);
        }

        if (_settings.checkConfiguration)
        {
            return 0;
        }

        _settings.ifcfg = bool(configurations.size() > 1);

        if (!_settings.userDefines.empty())
        {
            configurations.clear();
            configurations.push_back(_settings.userDefines);
        }

        int checkCount = 0;
        for (std::list<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it)
        {
            // Check only 12 first configurations, after that bail out, unless --force
            // was used.
            if (!_settings._force && checkCount > 11)
            {
                const std::string fixedpath = Path::toNativeSeparators(_filename);
                ErrorLogger::ErrorMessage::FileLocation location;
                location.setfile(fixedpath);
                std::list<ErrorLogger::ErrorMessage::FileLocation> loclist;
                loclist.push_back(location);
                const std::string msg("Interrupted checking because of too many #ifdef configurations.\n"
                                      "The checking of the file was interrupted because there were too many "
                                      "#ifdef configurations. Checking of all #ifdef configurations can be forced "
                                      "by --force command line option or from GUI preferences. However that may "
                                      "increase the checking time.");
                ErrorLogger::ErrorMessage errmsg(loclist,
                                                 Severity::information,
                                                 msg,
                                                 "toomanyconfigs",
                                                 false);
                _errorLogger.reportErr(errmsg);
                break;
            }

            cfg = *it;
            Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults);
            const std::string codeWithoutCfg = Preprocessor::getcode(filedata, *it, _filename, &_settings, &_errorLogger);
            t.Stop();

            // If only errors are printed, print filename after the check
            if (_settings._errorsOnly == false && it != configurations.begin())
            {
                std::string fixedpath = Path::simplifyPath(_filename.c_str());
                fixedpath = Path::toNativeSeparators(fixedpath);
                _errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("..."));
            }

            std::string appendCode = _settings.append();
            if (!appendCode.empty())
                Preprocessor::preprocessWhitespaces(appendCode);

            checkFile(codeWithoutCfg + appendCode, _filename.c_str());
            ++checkCount;
        }
    }
    catch (std::runtime_error &e)
    {
        // Exception was thrown when checking this file..
        const std::string fixedpath = Path::toNativeSeparators(_filename);
        _errorLogger.reportOut("Bailing out from checking " + fixedpath + ": " + e.what());
    }

    reportUnmatchedSuppressions(_settings.nomsg.getUnmatchedLocalSuppressions(_filename));

    // This generates false positives - especially for libraries
    const bool verbose_orig = _settings._verbose;
    _settings._verbose = false;
    if (_settings.isEnabled("unusedFunction") && _settings._jobs == 1)
    {
        _errout.str("");
        if (_settings._errorsOnly == false)
            _errorLogger.reportOut("Checking usage of global functions..");

        _checkUnusedFunctions.check(this);
    }
    _settings._verbose = verbose_orig;

    _errorList.clear();
    return exitcode;
}
Exemplo n.º 11
0
int CppCheckExecutor::check(int argc, const char* const argv[])
{
    Preprocessor::missingIncludeFlag = false;

    CppCheck cppCheck(*this, true);

    Settings& settings = cppCheck.settings();
    _settings = &settings;

    if (!parseFromArgs(&cppCheck, argc, argv)) {
        return EXIT_FAILURE;
    }

    if (settings.reportProgress)
        time1 = std::time(0);

    if (settings._xml) {
        reportErr(ErrorLogger::ErrorMessage::getXMLHeader(settings._xml_version));
    }

    unsigned int returnValue = 0;
    if (settings._jobs == 1) {
        // Single process

        std::size_t totalfilesize = 0;
        for (std::map<std::string, std::size_t>::const_iterator i = _files.begin(); i != _files.end(); ++i) {
            totalfilesize += i->second;
        }

        std::size_t processedsize = 0;
        unsigned int c = 0;
        for (std::map<std::string, std::size_t>::const_iterator i = _files.begin(); i != _files.end(); ++i) {
            returnValue += cppCheck.check(i->first);
            processedsize += i->second;
            if (!settings._errorsOnly)
                reportStatus(c + 1, _files.size(), processedsize, totalfilesize);
            c++;
        }

        cppCheck.checkFunctionUsage();
    } else if (!ThreadExecutor::isEnabled()) {
        std::cout << "No thread support yet implemented for this platform." << std::endl;
    } else {
        // Multiple processes
        ThreadExecutor executor(_files, settings, *this);
        returnValue = executor.check();
    }

    if (!settings.checkConfiguration) {
        if (!settings._errorsOnly)
            reportUnmatchedSuppressions(settings.nomsg.getUnmatchedGlobalSuppressions());

        cppCheck.tooManyConfigsError("",0U);

        if (settings.isEnabled("missingInclude") && Preprocessor::missingIncludeFlag) {
            const std::list<ErrorLogger::ErrorMessage::FileLocation> callStack;
            ErrorLogger::ErrorMessage msg(callStack,
                                          Severity::information,
                                          "Cppcheck cannot find all the include files (use --check-config for details)\n"
                                          "Cppcheck cannot find all the include files. Cppcheck can check the code without the "
                                          "include files found. But the results will probably be more accurate if all the include "
                                          "files are found. Please check your project's include directories and add all of them "
                                          "as include directories for Cppcheck. To see what files Cppcheck cannot find use "
                                          "--check-config.",
                                          "missingInclude",
                                          false);
            reportInfo(msg);
        }
    }

    if (settings._xml) {
        reportErr(ErrorLogger::ErrorMessage::getXMLFooter(settings._xml_version));
    }

    _settings = 0;
    if (returnValue)
        return settings._exitCode;
    else
        return 0;
}
Exemplo n.º 12
0
unsigned int CppCheck::processFile()
{
    exitcode = 0;

    // only show debug warnings for C/C++ source files (don't fix
    // debug warnings for java/c#/etc files)
    if (!Path::acceptFile(_filename))
        _settings.debugwarnings = false;

    // TODO: Should this be moved out to its own function so all the files can be
    // analysed before any files are checked?
    if (_settings.test_2_pass && _settings._jobs == 1) {
        const std::string printname = Path::toNativeSeparators(_filename);
        reportOut("Analysing " + printname + "...");

        std::ifstream f(_filename.c_str());
        analyseFile(f, _filename);
    }

    _errout.str("");

    if (_settings.terminated())
        return exitcode;

    if (_settings._errorsOnly == false) {
        std::string fixedpath(_filename);
        fixedpath = Path::simplifyPath(fixedpath.c_str());
        fixedpath = Path::toNativeSeparators(fixedpath);
        _errorLogger.reportOut(std::string("Checking ") + fixedpath + std::string("..."));
    }

    try {
        Preprocessor preprocessor(&_settings, this);
        std::list<std::string> configurations;
        std::string filedata = "";

        if (!_fileContent.empty()) {
            // File content was given as a string
            std::istringstream iss(_fileContent);
            preprocessor.preprocess(iss, filedata, configurations, _filename, _settings._includePaths);
        } else {
            // Only file name was given, read the content from file
            std::ifstream fin(_filename.c_str());
            Timer t("Preprocessor::preprocess", _settings._showtime, &S_timerResults);
            preprocessor.preprocess(fin, filedata, configurations, _filename, _settings._includePaths);
        }

        if (_settings.checkConfiguration) {
            return 0;
        }

        _settings.ifcfg = bool(configurations.size() > 1);

        if (!_settings.userDefines.empty()) {
            configurations.clear();
            configurations.push_back(_settings.userDefines);
        }

        int checkCount = 0;
        for (std::list<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it) {
            // Check only a few configurations (default 12), after that bail out, unless --force
            // was used.
            if (!_settings._force && checkCount >= _settings._maxConfigs) {

                const std::string fixedpath = Path::toNativeSeparators(_filename);
                ErrorLogger::ErrorMessage::FileLocation location;
                location.setfile(fixedpath);
                std::list<ErrorLogger::ErrorMessage::FileLocation> loclist;
                loclist.push_back(location);
                const std::string msg("Interrupted checking because of too many #ifdef configurations.\n"
                                      "The checking of the file was interrupted because there were too many "
                                      "#ifdef configurations. Checking of all #ifdef configurations can be forced "
                                      "by --force command line option or from GUI preferences. However that may "
                                      "increase the checking time.");
                ErrorLogger::ErrorMessage errmsg(loclist,
                                                 Severity::information,
                                                 msg,
                                                 "toomanyconfigs",
                                                 false);

                if (!_settings.nomsg.isSuppressedLocal(errmsg._id, fixedpath, location.line)) {
                    reportErr(errmsg);
                }

                break;
            }

            cfg = *it;
            Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults);
            const std::string codeWithoutCfg = preprocessor.getcode(filedata, *it, _filename);
            t.Stop();

            // If only errors are printed, print filename after the check
            if (_settings._errorsOnly == false && it != configurations.begin()) {
                std::string fixedpath = Path::simplifyPath(_filename.c_str());
                fixedpath = Path::toNativeSeparators(fixedpath);
                _errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("..."));
            }

            const std::string &appendCode = _settings.append();

            if (_settings.debugFalsePositive) {
                if (findError(codeWithoutCfg + appendCode, _filename.c_str())) {
                    return exitcode;
                }
            } else {
                checkFile(codeWithoutCfg + appendCode, _filename.c_str());
            }

            ++checkCount;
        }
    } catch (std::runtime_error &e) {
        // Exception was thrown when checking this file..
        const std::string fixedpath = Path::toNativeSeparators(_filename);
        _errorLogger.reportOut("Bailing out from checking " + fixedpath + ": " + e.what());
    }

    if (!_settings._errorsOnly)
        reportUnmatchedSuppressions(_settings.nomsg.getUnmatchedLocalSuppressions(_filename));

    _errorList.clear();
    return exitcode;
}
Exemplo n.º 13
0
unsigned int CppCheck::processFile(const std::string& filename, const std::string& fileContent)
{
    exitcode = 0;

    // only show debug warnings for accepted C/C++ source files
    if (!Path::acceptFile(filename))
        _settings.debugwarnings = false;

    if (_settings.terminated())
        return exitcode;

    if (_settings._errorsOnly == false) {
        std::string fixedpath = Path::simplifyPath(filename);
        fixedpath = Path::toNativeSeparators(fixedpath);
        _errorLogger.reportOut(std::string("Checking ") + fixedpath + std::string("..."));
    }

    try {
        Preprocessor preprocessor(&_settings, this);
        std::list<std::string> configurations;
        std::string filedata = "";

        if (!fileContent.empty()) {
            // File content was given as a string (democlient)
            std::istringstream iss(fileContent);
            preprocessor.preprocess(iss, filedata, configurations, filename, _settings._includePaths);
        } else {
            // Only file name was given, read the content from file
            std::ifstream fin(filename.c_str());
            Timer t("Preprocessor::preprocess", _settings._showtime, &S_timerResults);
            preprocessor.preprocess(fin, filedata, configurations, filename, _settings._includePaths);
        }

        if (_settings.checkConfiguration) {
            return 0;
        }

        // Run rules on this code
        for (std::list<Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
            if (it->tokenlist == "define") {
                Tokenizer tokenizer2(&_settings, this);
                std::istringstream istr2(filedata);
                tokenizer2.list.createTokens(istr2, filename);

                for (const Token *tok = tokenizer2.list.front(); tok; tok = tok->next()) {
                    if (tok->str() == "#define") {
                        std::string code = std::string(tok->linenr()-1U, '\n');
                        for (const Token *tok2 = tok; tok2 && tok2->linenr() == tok->linenr(); tok2 = tok2->next())
                            code += " " + tok2->str();
                        Tokenizer tokenizer3(&_settings, this);
                        std::istringstream istr3(code);
                        tokenizer3.list.createTokens(istr3, tokenizer2.list.file(tok));
                        executeRules("define", tokenizer3);
                    }
                }
                break;
            }
        }

        if (!_settings.userDefines.empty() && _settings._maxConfigs==1U) {
            configurations.clear();
            configurations.push_back(_settings.userDefines);
        }

        if (!_settings._force && configurations.size() > _settings._maxConfigs) {
            if (_settings.isEnabled("information")) {
                tooManyConfigsError(Path::toNativeSeparators(filename),configurations.size());
            } else {
                tooManyConfigs = true;
            }
        }

        unsigned int checkCount = 0;
        for (std::list<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it) {
            // Check only a few configurations (default 12), after that bail out, unless --force
            // was used.
            if (!_settings._force && ++checkCount > _settings._maxConfigs)
                break;

            cfg = *it;

            // If only errors are printed, print filename after the check
            if (_settings._errorsOnly == false && it != configurations.begin()) {
                std::string fixedpath = Path::simplifyPath(filename);
                fixedpath = Path::toNativeSeparators(fixedpath);
                _errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("..."));
            }

            if (!_settings.userDefines.empty()) {
                if (!cfg.empty())
                    cfg = ";" + cfg;
                cfg = _settings.userDefines + cfg;
            }

            Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults);
            const std::string codeWithoutCfg = preprocessor.getcode(filedata, cfg, filename);
            t.Stop();

            const std::string &appendCode = _settings.append();

            if (_settings.debugFalsePositive) {
                if (findError(codeWithoutCfg + appendCode, filename.c_str())) {
                    return exitcode;
                }
            } else {
                checkFile(codeWithoutCfg + appendCode, filename.c_str());
            }
        }
    } catch (const std::runtime_error &e) {
        internalError(filename, e.what());
    } catch (const InternalError &e) {
        internalError(filename, e.errorMessage);
    }

    if (_settings.isEnabled("information") || _settings.checkConfiguration)
        reportUnmatchedSuppressions(_settings.nomsg.getUnmatchedLocalSuppressions(filename));

    _errorList.clear();
    return exitcode;
}
Exemplo n.º 14
0
unsigned int CppCheck::processFile(const std::string& filename)
{
    exitcode = 0;

    // only show debug warnings for accepted C/C++ source files
    if (!Path::acceptFile(filename))
        _settings.debugwarnings = false;

    if (_settings.terminated())
        return exitcode;

    if (_settings._errorsOnly == false) {
        std::string fixedpath = Path::simplifyPath(filename.c_str());
        fixedpath = Path::toNativeSeparators(fixedpath);
        _errorLogger.reportOut(std::string("Checking ") + fixedpath + std::string("..."));
    }

    try {
        Preprocessor preprocessor(&_settings, this);
        std::list<std::string> configurations;
        std::string filedata = "";

        if (!_fileContent.empty()) {
            // File content was given as a string
            std::istringstream iss(_fileContent);
            preprocessor.preprocess(iss, filedata, configurations, filename, _settings._includePaths);
        } else {
            // Only file name was given, read the content from file
            std::ifstream fin(filename.c_str());
            Timer t("Preprocessor::preprocess", _settings._showtime, &S_timerResults);
            preprocessor.preprocess(fin, filedata, configurations, filename, _settings._includePaths);
        }

        if (_settings.checkConfiguration) {
            return 0;
        }

        if (!_settings.userDefines.empty()) {
            configurations.clear();
            configurations.push_back(_settings.userDefines);
        }

        if (!_settings._force && configurations.size() > _settings._maxConfigs) {
            if (_settings.isEnabled("information")) {
                tooManyConfigsError(Path::toNativeSeparators(filename),configurations.size());
            } else {
                tooManyConfigs = true;
            }
        }

        unsigned int checkCount = 0;
        for (std::list<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it) {
            // Check only a few configurations (default 12), after that bail out, unless --force
            // was used.
            if (!_settings._force && ++checkCount > _settings._maxConfigs)
                break;

            cfg = *it;

            // If only errors are printed, print filename after the check
            if (_settings._errorsOnly == false && it != configurations.begin()) {
                std::string fixedpath = Path::simplifyPath(filename.c_str());
                fixedpath = Path::toNativeSeparators(fixedpath);
                _errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("..."));
            }

            Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults);
            const std::string codeWithoutCfg = preprocessor.getcode(filedata, *it, filename, _settings.userDefines.empty());
            t.Stop();

            const std::string &appendCode = _settings.append();

            if (_settings.debugFalsePositive) {
                if (findError(codeWithoutCfg + appendCode, filename.c_str())) {
                    return exitcode;
                }
            } else {
                checkFile(codeWithoutCfg + appendCode, filename.c_str());
            }
        }
    } catch (const std::runtime_error &e) {
        internalError(filename, e.what());
    } catch (const InternalError &e) {
        internalError(filename, e.errorMessage);
    }

    if (!_settings._errorsOnly)
        reportUnmatchedSuppressions(_settings.nomsg.getUnmatchedLocalSuppressions(filename));

    _errorList.clear();
    return exitcode;
}
Exemplo n.º 15
0
unsigned int CppCheck::processFile(const std::string& filename, const std::string &cfgname, std::istream& fileStream)
{
    exitcode = 0;

    // only show debug warnings for accepted C/C++ source files
    if (!Path::acceptFile(filename))
        _settings.debugwarnings = false;

    if (_settings.terminated())
        return exitcode;

    if (!_settings.quiet) {
        std::string fixedpath = Path::simplifyPath(filename);
        fixedpath = Path::toNativeSeparators(fixedpath);
        _errorLogger.reportOut(std::string("Checking ") + fixedpath + ' ' + cfgname + std::string("..."));

        if (_settings.verbose) {
            _errorLogger.reportOut("Defines: " + _settings.userDefines);
            std::string includePaths;
            for (std::list<std::string>::const_iterator I = _settings.includePaths.begin(); I != _settings.includePaths.end(); ++I)
                includePaths += " -I" + *I;
            _errorLogger.reportOut("Includes:" + includePaths);
            _errorLogger.reportOut(std::string("Platform:") + _settings.platformString());
        }
    }

    if (plistFile.is_open()) {
        plistFile << ErrorLogger::plistFooter();
        plistFile.close();
    }

    CheckUnusedFunctions checkUnusedFunctions(nullptr, nullptr, nullptr);

    bool internalErrorFound(false);
    try {
        Preprocessor preprocessor(_settings, this);
        std::set<std::string> configurations;

        simplecpp::OutputList outputList;
        std::vector<std::string> files;
        simplecpp::TokenList tokens1(fileStream, files, filename, &outputList);

        // If there is a syntax error, report it and stop
        for (simplecpp::OutputList::const_iterator it = outputList.begin(); it != outputList.end(); ++it) {
            bool err;
            switch (it->type) {
            case simplecpp::Output::ERROR:
            case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY:
            case simplecpp::Output::SYNTAX_ERROR:
            case simplecpp::Output::UNHANDLED_CHAR_ERROR:
                err = true;
                break;
            case simplecpp::Output::WARNING:
            case simplecpp::Output::MISSING_HEADER:
            case simplecpp::Output::PORTABILITY_BACKSLASH:
                err = false;
                break;
            };

            if (err) {
                const ErrorLogger::ErrorMessage::FileLocation loc1(it->location.file(), it->location.line);
                std::list<ErrorLogger::ErrorMessage::FileLocation> callstack;
                callstack.push_back(loc1);

                ErrorLogger::ErrorMessage errmsg(callstack,
                                                 "",
                                                 Severity::error,
                                                 it->msg,
                                                 "syntaxError",
                                                 false);
                _errorLogger.reportErr(errmsg);
                return 1;
            }
        }

        preprocessor.loadFiles(tokens1, files);

        if (!_settings.plistOutput.empty()) {
            std::string filename2;
            if (filename.find('/') != std::string::npos)
                filename2 = filename.substr(filename.rfind('/') + 1);
            else
                filename2 = filename;
            filename2 = _settings.plistOutput + filename2.substr(0, filename2.find('.')) + ".plist";
            plistFile.open(filename2);
            plistFile << ErrorLogger::plistHeader(version(), files);
        }

        // write dump file xml prolog
        std::ofstream fdump;
        if (_settings.dump) {
            const std::string dumpfile(_settings.dumpFile.empty() ? (filename + ".dump") : _settings.dumpFile);
            fdump.open(dumpfile.c_str());
            if (fdump.is_open()) {
                fdump << "<?xml version=\"1.0\"?>" << std::endl;
                fdump << "<dumps>" << std::endl;
                fdump << "  <platform"
                      << " name=\"" << _settings.platformString() << '\"'
                      << " char_bit=\"" << _settings.char_bit << '\"'
                      << " short_bit=\"" << _settings.short_bit << '\"'
                      << " int_bit=\"" << _settings.int_bit << '\"'
                      << " long_bit=\"" << _settings.long_bit << '\"'
                      << " long_long_bit=\"" << _settings.long_long_bit << '\"'
                      << " pointer_bit=\"" << (_settings.sizeof_pointer * _settings.char_bit) << '\"'
                      << "/>\n";
                fdump << "  <rawtokens>" << std::endl;
                for (unsigned int i = 0; i < files.size(); ++i)
                    fdump << "    <file index=\"" << i << "\" name=\"" << ErrorLogger::toxml(files[i]) << "\"/>" << std::endl;
                for (const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) {
                    fdump << "    <tok "
                          << "fileIndex=\"" << tok->location.fileIndex << "\" "
                          << "linenr=\"" << tok->location.line << "\" "
                          << "str=\"" << ErrorLogger::toxml(tok->str) << "\""
                          << "/>" << std::endl;
                }
                fdump << "  </rawtokens>" << std::endl;
            }
        }

        // Parse comments and then remove them
        preprocessor.inlineSuppressions(tokens1);
        tokens1.removeComments();
        preprocessor.removeComments();

        if (!_settings.buildDir.empty()) {
            // Get toolinfo
            std::string toolinfo;
            toolinfo += CPPCHECK_VERSION_STRING;
            toolinfo += _settings.isEnabled(Settings::WARNING) ? 'w' : ' ';
            toolinfo += _settings.isEnabled(Settings::STYLE) ? 's' : ' ';
            toolinfo += _settings.isEnabled(Settings::PERFORMANCE) ? 'p' : ' ';
            toolinfo += _settings.isEnabled(Settings::PORTABILITY) ? 'p' : ' ';
            toolinfo += _settings.isEnabled(Settings::INFORMATION) ? 'i' : ' ';
            toolinfo += _settings.userDefines;

            // Calculate checksum so it can be compared with old checksum / future checksums
            const unsigned int checksum = preprocessor.calculateChecksum(tokens1, toolinfo);
            std::list<ErrorLogger::ErrorMessage> errors;
            if (!analyzerInformation.analyzeFile(_settings.buildDir, filename, cfgname, checksum, &errors)) {
                while (!errors.empty()) {
                    reportErr(errors.front());
                    errors.pop_front();
                }
                return exitcode;  // known results => no need to reanalyze file
            }
        }

        // Get directives
        preprocessor.setDirectives(tokens1);
        preprocessor.simplifyPragmaAsm(&tokens1);

        preprocessor.setPlatformInfo(&tokens1);

        // Get configurations..
        if (_settings.userDefines.empty() || _settings.force) {
            Timer t("Preprocessor::getConfigs", _settings.showtime, &S_timerResults);
            configurations = preprocessor.getConfigs(tokens1);
        } else {
            configurations.insert(_settings.userDefines);
        }

        if (_settings.checkConfiguration) {
            for (std::set<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it)
                (void)preprocessor.getcode(tokens1, *it, files, true);

            return 0;
        }

        // Run define rules on raw code
        for (std::list<Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
            if (it->tokenlist != "define")
                continue;

            std::string code;
            const std::list<Directive> &directives = preprocessor.getDirectives();
            for (std::list<Directive>::const_iterator dir = directives.begin(); dir != directives.end(); ++dir) {
                if (dir->str.compare(0,8,"#define ") == 0)
                    code += "#line " + MathLib::toString(dir->linenr) + " \"" + dir->file + "\"\n" + dir->str + '\n';
            }
            Tokenizer tokenizer2(&_settings, this);
            std::istringstream istr2(code);
            tokenizer2.list.createTokens(istr2);
            executeRules("define", tokenizer2);
            break;
        }

        if (!_settings.force && configurations.size() > _settings.maxConfigs) {
            if (_settings.isEnabled(Settings::INFORMATION)) {
                tooManyConfigsError(Path::toNativeSeparators(filename),configurations.size());
            } else {
                tooManyConfigs = true;
            }
        }

        std::set<unsigned long long> checksums;
        unsigned int checkCount = 0;
        for (std::set<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it) {
            // bail out if terminated
            if (_settings.terminated())
                break;

            // Check only a few configurations (default 12), after that bail out, unless --force
            // was used.
            if (!_settings.force && ++checkCount > _settings.maxConfigs)
                break;

            cfg = *it;

            // If only errors are printed, print filename after the check
            if (!_settings.quiet && (!cfg.empty() || it != configurations.begin())) {
                std::string fixedpath = Path::simplifyPath(filename);
                fixedpath = Path::toNativeSeparators(fixedpath);
                _errorLogger.reportOut("Checking " + fixedpath + ": " + cfg + "...");
            }

            if (!_settings.userDefines.empty()) {
                if (!cfg.empty())
                    cfg = ";" + cfg;
                cfg = _settings.userDefines + cfg;
            }

            if (_settings.preprocessOnly) {
                Timer t("Preprocessor::getcode", _settings.showtime, &S_timerResults);
                std::string codeWithoutCfg = preprocessor.getcode(tokens1, cfg, files, true);
                t.Stop();

                if (codeWithoutCfg.compare(0,5,"#file") == 0)
                    codeWithoutCfg.insert(0U, "//");
                std::string::size_type pos = 0;
                while ((pos = codeWithoutCfg.find("\n#file",pos)) != std::string::npos)
                    codeWithoutCfg.insert(pos+1U, "//");
                pos = 0;
                while ((pos = codeWithoutCfg.find("\n#endfile",pos)) != std::string::npos)
                    codeWithoutCfg.insert(pos+1U, "//");
                pos = 0;
                while ((pos = codeWithoutCfg.find(Preprocessor::macroChar,pos)) != std::string::npos)
                    codeWithoutCfg[pos] = ' ';
                reportOut(codeWithoutCfg);
                continue;
            }

            Tokenizer _tokenizer(&_settings, this);
            if (_settings.showtime != SHOWTIME_NONE)
                _tokenizer.setTimerResults(&S_timerResults);

            try {
                bool result;

                // Create tokens, skip rest of iteration if failed
                Timer timer("Tokenizer::createTokens", _settings.showtime, &S_timerResults);
                const simplecpp::TokenList &tokensP = preprocessor.preprocess(tokens1, cfg, files);
                _tokenizer.createTokens(&tokensP);
                timer.Stop();
                if (tokensP.empty())
                    continue;

                // skip rest of iteration if just checking configuration
                if (_settings.checkConfiguration)
                    continue;

                // Check raw tokens
                checkRawTokens(_tokenizer);

                // Simplify tokens into normal form, skip rest of iteration if failed
                Timer timer2("Tokenizer::simplifyTokens1", _settings.showtime, &S_timerResults);
                result = _tokenizer.simplifyTokens1(cfg);
                timer2.Stop();
                if (!result)
                    continue;

                // dump xml if --dump
                if (_settings.dump && fdump.is_open()) {
                    fdump << "<dump cfg=\"" << ErrorLogger::toxml(cfg) << "\">" << std::endl;
                    preprocessor.dump(fdump);
                    _tokenizer.dump(fdump);
                    fdump << "</dump>" << std::endl;
                }

                // Skip if we already met the same simplified token list
                if (_settings.force || _settings.maxConfigs > 1) {
                    const unsigned long long checksum = _tokenizer.list.calculateChecksum();
                    if (checksums.find(checksum) != checksums.end()) {
                        if (_settings.isEnabled(Settings::INFORMATION) && (_settings.debug || _settings.verbose))
                            purgedConfigurationMessage(filename, cfg);
                        continue;
                    }
                    checksums.insert(checksum);
                }

                // Check normal tokens
                checkNormalTokens(_tokenizer);

                // Analyze info..
                if (!_settings.buildDir.empty())
                    checkUnusedFunctions.parseTokens(_tokenizer, filename.c_str(), &_settings, false);

                // simplify more if required, skip rest of iteration if failed
                if (_simplify) {
                    // if further simplification fails then skip rest of iteration
                    Timer timer3("Tokenizer::simplifyTokenList2", _settings.showtime, &S_timerResults);
                    result = _tokenizer.simplifyTokenList2();
                    timer3.Stop();
                    if (!result)
                        continue;

                    // Check simplified tokens
                    checkSimplifiedTokens(_tokenizer);
                }

            } catch (const InternalError &e) {
                internalErrorFound=true;
                std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
                ErrorLogger::ErrorMessage::FileLocation loc;
                if (e.token) {
                    loc.line = e.token->linenr();
                    const std::string fixedpath = Path::toNativeSeparators(_tokenizer.list.file(e.token));
                    loc.setfile(fixedpath);
                } else {
                    ErrorLogger::ErrorMessage::FileLocation loc2;
                    loc2.setfile(Path::toNativeSeparators(filename));
                    locationList.push_back(loc2);
                    loc.setfile(_tokenizer.list.getSourceFilePath());
                }
                locationList.push_back(loc);
                ErrorLogger::ErrorMessage errmsg(locationList,
                                                 _tokenizer.list.getSourceFilePath(),
                                                 Severity::error,
                                                 e.errorMessage,
                                                 e.id,
                                                 false);

                reportErr(errmsg);
            }
        }

        // dumped all configs, close root </dumps> element now
        if (_settings.dump && fdump.is_open())
            fdump << "</dumps>" << std::endl;

    } catch (const std::runtime_error &e) {
        internalError(filename, e.what());
    } catch (const std::bad_alloc &e) {
        internalError(filename, e.what());
    } catch (const InternalError &e) {
        internalError(filename, e.errorMessage);
        exitcode=1; // e.g. reflect a syntax error
    }

    analyzerInformation.setFileInfo("CheckUnusedFunctions", checkUnusedFunctions.analyzerInfo());
    analyzerInformation.close();

    // In jointSuppressionReport mode, unmatched suppressions are
    // collected after all files are processed
    if (!_settings.jointSuppressionReport && (_settings.isEnabled(Settings::INFORMATION) || _settings.checkConfiguration)) {
        reportUnmatchedSuppressions(_settings.nomsg.getUnmatchedLocalSuppressions(filename, isUnusedFunctionCheckEnabled()));
    }

    _errorList.clear();
    if (internalErrorFound && (exitcode==0)) {
        exitcode=1;
    }
    return exitcode;
}
Exemplo n.º 16
0
unsigned int CppCheck::processFile(const std::string& filename)
{
    exitcode = 0;

    // only show debug warnings for accepted C/C++ source files
    if (!Path::acceptFile(filename))
        _settings.debugwarnings = false;

    if (_settings.terminated())
        return exitcode;

    if (_settings._errorsOnly == false) {
        std::string fixedpath = Path::simplifyPath(filename.c_str());
        fixedpath = Path::toNativeSeparators(fixedpath);
        _errorLogger.reportOut(std::string("Checking ") + fixedpath + std::string("..."));
    }

    try {
        Preprocessor preprocessor(&_settings, this);
        std::list<std::string> configurations;
        std::string filedata = "";

        if (!_fileContent.empty()) {
            // File content was given as a string
            std::istringstream iss(_fileContent);
            preprocessor.preprocess(iss, filedata, configurations, filename, _settings._includePaths);
        } else {
            // Only file name was given, read the content from file
            std::ifstream fin(filename.c_str());
            Timer t("Preprocessor::preprocess", _settings._showtime, &S_timerResults);
            preprocessor.preprocess(fin, filedata, configurations, filename, _settings._includePaths);
        }

        if (_settings.checkConfiguration) {
            return 0;
        }

        if (!_settings.userDefines.empty()) {
            configurations.clear();
            configurations.push_back(_settings.userDefines);
        }

        if (!_settings._force && configurations.size() > _settings._maxConfigs) {
            const std::string fixedpath = Path::toNativeSeparators(filename);
            ErrorLogger::ErrorMessage::FileLocation location;
            location.setfile(fixedpath);
            const std::list<ErrorLogger::ErrorMessage::FileLocation> loclist(1, location);
            std::ostringstream msg;
            msg << "Too many #ifdef configurations - cppcheck will only check " << _settings._maxConfigs << " of " << configurations.size() << ".\n"
                "The checking of the file will be interrupted because there are too many "
                "#ifdef configurations. Checking of all #ifdef configurations can be forced "
                "by --force command line option or from GUI preferences. However that may "
                "increase the checking time.";
            ErrorLogger::ErrorMessage errmsg(loclist,
                                             Severity::information,
                                             msg.str(),
                                             "toomanyconfigs",
                                             false);

            reportErr(errmsg);
        }

        unsigned int checkCount = 0;
        for (std::list<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it) {
            // Check only a few configurations (default 12), after that bail out, unless --force
            // was used.
            if (!_settings._force && checkCount >= _settings._maxConfigs) {

                const std::string fixedpath = Path::toNativeSeparators(filename);
                ErrorLogger::ErrorMessage::FileLocation location;
                location.setfile(fixedpath);
                std::list<ErrorLogger::ErrorMessage::FileLocation> loclist;
                loclist.push_back(location);
                ErrorLogger::ErrorMessage errmsg(loclist,
                                                 Severity::information,
                                                 "Interrupted checking because of too many #ifdef configurations.",
                                                 "toomanyconfigs",
                                                 false);

                reportInfo(errmsg);
                break;
            }

            cfg = *it;

            // If only errors are printed, print filename after the check
            if (_settings._errorsOnly == false && it != configurations.begin()) {
                std::string fixedpath = Path::simplifyPath(filename.c_str());
                fixedpath = Path::toNativeSeparators(fixedpath);
                _errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("..."));
            }

            Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults);
            const std::string codeWithoutCfg = preprocessor.getcode(filedata, *it, filename, _settings.userDefines.empty());
            t.Stop();

            const std::string &appendCode = _settings.append();

            if (_settings.debugFalsePositive) {
                if (findError(codeWithoutCfg + appendCode, filename.c_str())) {
                    return exitcode;
                }
            } else {
                checkFile(codeWithoutCfg + appendCode, filename.c_str());
            }

            ++checkCount;
        }
    } catch (const std::runtime_error &e) {
        // Exception was thrown when checking this file..
        const std::string fixedpath = Path::toNativeSeparators(filename);
        _errorLogger.reportOut("Bailing out from checking " + fixedpath + ": " + e.what());
    }

    if (!_settings._errorsOnly)
        reportUnmatchedSuppressions(_settings.nomsg.getUnmatchedLocalSuppressions(filename));

    _errorList.clear();
    return exitcode;
}