Exemple #1
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;
}
Exemple #2
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;
}
//---------------------------------------------------------------------------
//Reading geometric information of the RVE
int Input::Read_rve_geometry(struct Geom_RVE &geom_rve, ifstream &infile)
{
    if(geom_rve.mark)
    {
        cout << "Attention: \"" << geom_rve.keywords << "\" has been input!" << endl;
        hout << "Attention: \"" << geom_rve.keywords << "\" has been input!" << endl;
        return 0;
    }
    else geom_rve.mark = true;

    //-----------------------------------------------------------------------------------------------------------------------------------------
    //Define the domain of RVE: the lower-left corner point of RVE and the length, width and height of RVE
    istringstream istr0(Get_Line(infile));
    istr0 >> geom_rve.origin.x >> geom_rve.origin.y >> geom_rve.origin.z;
    istr0 >> geom_rve.len_x >> geom_rve.wid_y >> geom_rve.hei_z;
    if(geom_rve.len_x<=0||geom_rve.wid_y<=0||geom_rve.hei_z<=0)
    {
        cout << "Error: the sizes of RVE should be positive!" << endl;
        hout << "Error: the sizes of RVE should be positive!" << endl;
        return 0;
    }
    geom_rve.volume = geom_rve.len_x*geom_rve.wid_y*geom_rve.hei_z;

    //-----------------------------------------------------------------------------------------------------------------------------------------
    //Define the size range of the observation window and descrement by every step in x, y and z directions
    istringstream istr1(Get_Line(infile));
    istr1 >> geom_rve.win_max_x >> geom_rve.win_max_y >> geom_rve.win_max_z;
    istringstream istr2(Get_Line(infile));
    istr2 >> geom_rve.win_delt_x >> geom_rve.win_delt_y >> geom_rve.win_delt_z;
    istringstream istr3(Get_Line(infile));
    istr3 >> geom_rve.win_min_x >> geom_rve.win_min_y >> geom_rve.win_min_z;

    if(geom_rve.win_max_x<=0.0||geom_rve.win_max_y<=0.0||geom_rve.win_max_z<=0.0||
            geom_rve.win_max_x>geom_rve.len_x||geom_rve.win_max_y>geom_rve.wid_y||geom_rve.win_max_z>geom_rve.hei_z)
    {
        cout << "Error: the win_max in each direction of RVE should be positive and must be smaller than the size of RVE." << endl;
        hout << "Error: the win_max in each direction of RVE should be positive and must be smaller than the size of RVE." << endl;
        return 0;
    }
    if(geom_rve.win_min_x<=0.0||geom_rve.win_min_y<=0.0||geom_rve.win_min_z<=0.0||
            geom_rve.win_min_x>geom_rve.win_max_x||geom_rve.win_min_y>geom_rve.win_max_y||geom_rve.win_min_z>geom_rve.win_max_z)
    {
        cout << "Error: the win_min in each direction of RVE should be positive and must be smaller than max." << endl;
        hout << "Error: the win_min in each direction of RVE should be positive and must be smaller than max." << endl;
        return 0;
    }
    if(geom_rve.win_delt_x<=0.0||geom_rve.win_delt_y<=0.0||geom_rve.win_delt_z<=0.0)
    {
        cout << "Error: the win_delt in each direction of RVE should be positive." << endl;
        hout << "Error: the win_delt in each direction of RVE should be positive." << endl;
        return 0;
    }

    //Details: +Zero for reducing the error of division
    int num[3] = {	(int)((geom_rve.win_max_x-geom_rve.win_min_x + Zero)/geom_rve.win_delt_x),
                    (int)((geom_rve.win_max_y-geom_rve.win_min_y + Zero)/geom_rve.win_delt_y),
                    (int)((geom_rve.win_max_z-geom_rve.win_min_z + Zero)/geom_rve.win_delt_z)
                 };

    if(num[0]!=num[1]||num[0]!=num[2])
    {
        cout << "Error: the numbers of cutoff times are different in three directions (x, y, z)." << endl;
        hout << "Error: the numbers of cutoff times are different in three directions (x, y, z)." << endl;
        return 0;
    }
    else geom_rve.cut_num = num[0];

    //-----------------------------------------------------------------------------------------------------------------------------------------
    //Define the minimum size for background grids (looking for contact points)
    istringstream istr4(Get_Line(infile));
    istr4 >> geom_rve.gs_minx >> geom_rve.gs_miny >> geom_rve.gs_minz;
    if(geom_rve.gs_minx<=0||geom_rve.gs_miny<=0||geom_rve.gs_minz<=0)
    {
        cout << "Error: the number of segments in each direction of RVE should be positive!" << endl;
        hout << "Error: the number of segments in each direction of RVE should be positive" << endl;
        return 0;
    }
    else if((int)(geom_rve.win_max_x/geom_rve.gs_minx)>500||
            (int)(geom_rve.win_max_y/geom_rve.gs_miny)>500||
            (int)(geom_rve.win_max_z/geom_rve.gs_minz)>500)
    {
        cout << "Error: the number of divisions in one of boundary is too big (>500), which leads to the memory problem!" << endl;
        hout << "Error: the number of divisions in one of boundary is too big (>500), which leads to the memory problem!" << endl;
        return 0;
    }

    return 1;
}