39 #include <simplecpp.h> 
   41 static bool sameline(
const simplecpp::Token *tok1, 
const simplecpp::Token *tok2)
 
   43     return tok1 && tok2 && tok1->location.sameline(tok2->location);
 
   47     file(std::move(_file)),
 
   59     for (
const std::pair<const std::string, simplecpp::TokenList*>& tokenList : 
mTokenLists)
 
   60         delete tokenList.second;
 
   64     struct BadInlineSuppression {
 
   65         BadInlineSuppression(std::string file, 
const int line, std::string msg) : file(std::move(file)), line(line), errmsg(std::move(msg)) {}
 
   74     const std::string cppchecksuppress(
"cppcheck-suppress");
 
   76     const std::string &comment = tok->str();
 
   77     if (comment.size() < cppchecksuppress.size())
 
   79     const std::string::size_type pos1 = comment.find_first_not_of(
"/* \t");
 
   80     if (pos1 == std::string::npos)
 
   82     if (pos1 + cppchecksuppress.size() >= comment.size())
 
   84     if (comment.substr(pos1, cppchecksuppress.size()) != cppchecksuppress)
 
   88     const std::string::size_type posEndComment = comment.find_first_of(
" [", pos1+cppchecksuppress.size());
 
   91     const std::string::size_type pos2 = comment.find_first_not_of(
' ', posEndComment);
 
   92     if (pos2 == std::string::npos)
 
   98     if (posEndComment >= (pos1 + cppchecksuppress.size() + 1)) {
 
   99         if (comment.at(pos1 + cppchecksuppress.size()) != 
'-')
 
  102         const unsigned int argumentLength =
 
  103             posEndComment - (pos1 + cppchecksuppress.size() + 1);
 
  105         const std::string suppressTypeString =
 
  106             comment.substr(pos1 + cppchecksuppress.size() + 1, argumentLength);
 
  108         if (
"file" == suppressTypeString)
 
  110         else if (
"begin" == suppressTypeString)
 
  112         else if (
"end" == suppressTypeString)
 
  114         else if (
"macro" == suppressTypeString)
 
  120     if (comment[pos2] == 
'[') {
 
  127             s.lineNumber = tok->location.line;
 
  131             bad.emplace_back(tok->location.file(), tok->location.line, std::move(errmsg));
 
  133         std::copy_if(suppressions.cbegin(), suppressions.cend(), std::back_inserter(inlineSuppressions), [](
const SuppressionList::Suppression& s) {
 
  134             return !s.errorId.empty();
 
  147             inlineSuppressions.push_back(std::move(s));
 
  150             bad.emplace_back(tok->location.file(), tok->location.line, std::move(errmsg));
 
  158     std::list<SuppressionList::Suppression> inlineSuppressionsBlockBegin;
 
  160     bool onlyComments = 
true;
 
  162     for (
const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) {
 
  164             onlyComments = 
false;
 
  168         std::list<SuppressionList::Suppression> inlineSuppressions;
 
  172         if (!
sameline(tok->previous, tok)) {
 
  177                 while (tok->comment) {
 
  188         if (inlineSuppressions.empty())
 
  196         std::string relativeFilename(tok->location.file());
 
  198             for (
const std::string & basePath : settings.
basePaths) {
 
  199                 const std::string bp = basePath + 
"/";
 
  200                 if (relativeFilename.compare(0,bp.size(),bp)==0) {
 
  201                     relativeFilename = relativeFilename.substr(bp.size());
 
  208         std::string macroName;
 
  209         if (tok->str() == 
"#" && tok->next && tok->next->str() == 
"define") {
 
  210             const simplecpp::Token *macroNameTok = tok->next->next;
 
  211             if (
sameline(tok, macroNameTok) && macroNameTok->name) {
 
  212                 macroName = macroNameTok->str();
 
  218             suppr.fileName = relativeFilename;
 
  222                 inlineSuppressionsBlockBegin.push_back(std::move(suppr));
 
  224                 bool throwError = 
true;
 
  226                 if (!inlineSuppressionsBlockBegin.empty()) {
 
  229                     auto supprBegin = inlineSuppressionsBlockBegin.begin();
 
  230                     while (supprBegin != inlineSuppressionsBlockBegin.end())
 
  232                         if (lastBeginSuppression.
lineNumber != supprBegin->lineNumber) {
 
  237                         if (suppr.symbolName == supprBegin->symbolName && suppr.lineNumber > supprBegin->lineNumber) {
 
  238                             suppr.
lineBegin = supprBegin->lineNumber;
 
  239                             suppr.lineEnd = suppr.lineNumber;
 
  240                             suppr.lineNumber = supprBegin->lineNumber;
 
  242                             inlineSuppressionsBlockBegin.erase(supprBegin);
 
  253                     bad.emplace_back(suppr.fileName, suppr.lineNumber, 
"Suppress End: No matching begin");
 
  257                 const bool thisAndNextLine = tok->previous &&
 
  258                                              tok->previous->previous &&
 
  260                                              !
sameline(tok->previous->previous, tok->previous) &&
 
  261                                              tok->location.line + 1 == tok->next->location.line &&
 
  262                                              tok->location.fileIndex == tok->next->location.fileIndex &&
 
  263                                              tok->previous->str() == 
"{";
 
  265                 suppr.thisAndNextLine = thisAndNextLine;
 
  266                 suppr.lineNumber = tok->location.line;
 
  267                 suppr.macroName = macroName;
 
  273                     bad.emplace_back(suppr.fileName, suppr.lineNumber, 
"File suppression should be at the top of the file");
 
  280         bad.emplace_back(suppr.fileName, suppr.lineNumber, 
"Suppress Begin: No matching end");
 
  287     std::list<BadInlineSuppression> err;
 
  289     for (std::map<std::string,simplecpp::TokenList*>::const_iterator it = 
mTokenLists.cbegin(); it != 
mTokenLists.cend(); ++it) {
 
  293     for (
const BadInlineSuppression &bad : err) {
 
  294         error(bad.file, bad.line, bad.errmsg);
 
  301     std::list<Directive> directives;
 
  303     std::vector<const simplecpp::TokenList *> list;
 
  305     list.push_back(&tokens);
 
  306     for (std::map<std::string, simplecpp::TokenList *>::const_iterator it = 
mTokenLists.cbegin(); it != 
mTokenLists.cend(); ++it) {
 
  307         list.push_back(it->second);
 
  310     for (
const simplecpp::TokenList *tokenList : list) {
 
  311         for (
const simplecpp::Token *tok = tokenList->cfront(); tok; tok = tok->next) {
 
  312             if ((tok->op != 
'#') || (tok->previous && tok->previous->location.line == tok->location.line))
 
  314             if (tok->next && tok->next->str() == 
"endfile")
 
  317             for (
const simplecpp::Token *tok2 = tok; tok2 && tok2->location.line == directive.
linenr; tok2 = tok2->next) {
 
  320                 if (!directive.
str.empty() && (tok2->location.col > tok2->previous->location.col + tok2->previous->str().size()))
 
  321                     directive.
str += 
' ';
 
  322                 if (directive.
str == 
"#" && tok2->str() == 
"file")
 
  323                     directive.
str += 
"include";
 
  325                     directive.
str += tok2->str();
 
  327             directives.push_back(std::move(directive));
 
  334 static std::string 
readcondition(
const simplecpp::Token *iftok, 
const std::set<std::string> &defined, 
const std::set<std::string> &undefined)
 
  336     const simplecpp::Token *cond = iftok->next;
 
  340     const simplecpp::Token *next1 = cond->next;
 
  341     const simplecpp::Token *next2 = next1 ? next1->next : 
nullptr;
 
  342     const simplecpp::Token *next3 = next2 ? next2->next : 
nullptr;
 
  344     unsigned int len = 1;
 
  352     if (len == 1 && cond->str() == 
"0")
 
  355     if (len == 1 && cond->name) {
 
  356         if (defined.find(cond->str()) == defined.end())
 
  360     if (len == 2 && cond->op == 
'!' && next1->name) {
 
  361         if (defined.find(next1->str()) == defined.end())
 
  362             return next1->str() + 
"=0";
 
  365     if (len == 3 && cond->op == 
'(' && next1->name && next2->op == 
')') {
 
  366         if (defined.find(next1->str()) == defined.end() && undefined.find(next1->str()) == undefined.end())
 
  370     if (len == 3 && cond->name && next1->str() == 
"==" && next2->number) {
 
  371         if (defined.find(cond->str()) == defined.end())
 
  372             return cond->str() + 
'=' + cond->next->next->str();
 
  375     std::set<std::string> configset;
 
  376     for (; 
sameline(iftok,cond); cond = cond->next) {
 
  377         if (cond->op == 
'!') {
 
  378             if (!
sameline(iftok,cond->next) || !cond->next->name)
 
  380             if (cond->next->str() == 
"defined")
 
  382             configset.insert(cond->next->str() + 
"=0");
 
  385         if (cond->str() != 
"defined")
 
  387         const simplecpp::Token *dtok = cond->next;
 
  392         if (
sameline(iftok,dtok) && dtok->name && defined.find(dtok->str()) == defined.end() && undefined.find(dtok->str()) == undefined.end())
 
  393             configset.insert(dtok->str());
 
  396     for (
const std::string &s : configset) {
 
  404 static bool hasDefine(
const std::string &userDefines, 
const std::string &
cfg)
 
  410     std::string::size_type pos = 0;
 
  411     while (pos < userDefines.size()) {
 
  412         pos = userDefines.find(
cfg, pos);
 
  413         if (pos == std::string::npos)
 
  415         const std::string::size_type pos2 = pos + 
cfg.size();
 
  416         if ((pos == 0 || userDefines[pos-1U] == 
';') && (pos2 == userDefines.size() || userDefines[pos2] == 
'='))
 
  423 static std::string 
cfg(
const std::vector<std::string> &configs, 
const std::string &userDefines)
 
  425     std::set<std::string> configs2(configs.cbegin(), configs.cend());
 
  427     for (
const std::string &c : configs2) {
 
  441 static bool isUndefined(
const std::string &
cfg, 
const std::set<std::string> &undefined)
 
  443     for (std::string::size_type pos1 = 0U; pos1 < 
cfg.size();) {
 
  444         const std::string::size_type pos2 = 
cfg.find(
';',pos1);
 
  445         const std::string def = (pos2 == std::string::npos) ? 
cfg.substr(pos1) : 
cfg.substr(pos1, pos2 - pos1);
 
  447         const std::string::size_type eq = def.find(
'=');
 
  448         if (eq == std::string::npos && undefined.find(def) != undefined.end())
 
  450         if (eq != std::string::npos && undefined.find(def.substr(0,eq)) != undefined.end() && def.substr(eq) != 
"=0")
 
  453         pos1 = (pos2 == std::string::npos) ? pos2 : pos2 + 1U;
 
  460     return std::any_of(configs_if.cbegin(), configs_if.cend(),
 
  461                        [=](
const std::string &
cfg) {
 
  462         return hasDefine(userDefines, cfg);
 
  466 static const simplecpp::Token *
gotoEndIf(
const simplecpp::Token *cmdtok)
 
  469     while (
nullptr != (cmdtok = cmdtok->next)) {
 
  470         if (cmdtok->op == 
'#' && !
sameline(cmdtok->previous,cmdtok) && 
sameline(cmdtok, cmdtok->next)) {
 
  473             else if (cmdtok->next->str() == 
"endif") {
 
  483 static void getConfigs(
const simplecpp::TokenList &tokens, std::set<std::string> &defined, 
const std::string &userDefines, 
const std::set<std::string> &undefined, std::set<std::string> &ret)
 
  485     std::vector<std::string> configs_if;
 
  486     std::vector<std::string> configs_ifndef;
 
  487     std::string elseError;
 
  489     for (
const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) {
 
  490         if (tok->op != 
'#' || 
sameline(tok->previous, tok))
 
  492         const simplecpp::Token *cmdtok = tok->next;
 
  495         if (cmdtok->str() == 
"ifdef" || cmdtok->str() == 
"ifndef" || cmdtok->str() == 
"if") {
 
  497             if (cmdtok->str() == 
"ifdef" || cmdtok->str() == 
"ifndef") {
 
  498                 const simplecpp::Token *expr1 = cmdtok->next;
 
  500                     config = expr1->str();
 
  501                 if (defined.find(config) != defined.end())
 
  503             } 
else if (cmdtok->str() == 
"if") {
 
  512             if (cmdtok->str() == 
"ifndef")
 
  515                 const std::array<std::string, 6> 
match{
"if", 
"!", 
"defined", 
"(", config, 
")"};
 
  518                 for (
const simplecpp::Token *t = cmdtok; i < 
match.size(); t = t->next) {
 
  519                     if (!t || t->str() != 
match[i++]) {
 
  527             if (ifndef && tok->location.fileIndex > 0) {
 
  528                 bool includeGuard = 
true;
 
  529                 for (
const simplecpp::Token *t = tok->previous; t; t = t->previous) {
 
  530                     if (t->location.fileIndex == tok->location.fileIndex) {
 
  531                         includeGuard = 
false;
 
  536                     configs_if.emplace_back();
 
  537                     configs_ifndef.emplace_back();
 
  542             configs_if.push_back((cmdtok->str() == 
"ifndef") ? std::string() : config);
 
  543             configs_ifndef.push_back((cmdtok->str() == 
"ifndef") ? std::move(config) : std::string());
 
  544             ret.insert(
cfg(configs_if,userDefines));
 
  545         } 
else if (cmdtok->str() == 
"elif" || cmdtok->str() == 
"else") {
 
  553             if (cmdtok->str() == 
"else" &&
 
  556                 sameline(cmdtok->next, cmdtok->next->next) &&
 
  557                 cmdtok->next->op == 
'#' &&
 
  558                 cmdtok->next->next->str() == 
"error") {
 
  559                 const std::string &ifcfg = 
cfg(configs_if, userDefines);
 
  560                 if (!ifcfg.empty()) {
 
  561                     if (!elseError.empty())
 
  566             if (!configs_if.empty())
 
  567                 configs_if.pop_back();
 
  568             if (cmdtok->str() == 
"elif") {
 
  569                 std::string config = 
readcondition(cmdtok, defined, undefined);
 
  572                 configs_if.push_back(std::move(config));
 
  573                 ret.insert(
cfg(configs_if, userDefines));
 
  574             } 
else if (!configs_ifndef.empty()) {
 
  575                 configs_if.push_back(configs_ifndef.back());
 
  576                 ret.insert(
cfg(configs_if, userDefines));
 
  578         } 
else if (cmdtok->str() == 
"endif" && !
sameline(tok, cmdtok->next)) {
 
  579             if (!configs_if.empty())
 
  580                 configs_if.pop_back();
 
  581             if (!configs_ifndef.empty())
 
  582                 configs_ifndef.pop_back();
 
  583         } 
else if (cmdtok->str() == 
"error") {
 
  584             if (!configs_ifndef.empty() && !configs_ifndef.back().empty()) {
 
  585                 if (configs_ifndef.size() == 1U)
 
  587                 std::vector<std::string> configs(configs_if);
 
  588                 configs.push_back(configs_ifndef.back());
 
  589                 ret.erase(
cfg(configs, userDefines));
 
  590                 std::set<std::string> temp;
 
  592                 for (
const std::string &c: temp) {
 
  593                     if (c.find(configs_ifndef.back()) != std::string::npos)
 
  598                         ret.insert(c + 
";" + configs_ifndef.back());
 
  600                 if (!elseError.empty())
 
  602                 elseError += 
cfg(configs_ifndef, userDefines);
 
  604             if (!configs_if.empty() && !configs_if.back().empty()) {
 
  605                 const std::string &last = configs_if.back();
 
  606                 if (last.size() > 2U && last.compare(last.size()-2U,2,
"=0") == 0) {
 
  607                     std::vector<std::string> configs(configs_if);
 
  608                     ret.erase(
cfg(configs, userDefines));
 
  609                     configs[configs.size() - 1U] = last.substr(0,last.size()-2U);
 
  610                     if (configs.size() == 1U)
 
  612                     if (!elseError.empty())
 
  614                     elseError += 
cfg(configs, userDefines);
 
  617         } 
else if (cmdtok->str() == 
"define" && 
sameline(tok, cmdtok->next) && cmdtok->next->name) {
 
  618             defined.insert(cmdtok->next->str());
 
  621     if (!elseError.empty())
 
  622         ret.insert(std::move(elseError));
 
  628     std::set<std::string> ret = { 
"" };
 
  629     if (!tokens.cfront())
 
  632     std::set<std::string> defined = { 
"__cplusplus" };
 
  636     for (std::map<std::string, simplecpp::TokenList*>::const_iterator it = 
mTokenLists.cbegin(); it != 
mTokenLists.cend(); ++it) {
 
  644 static void splitcfg(
const std::string &
cfg, std::list<std::string> &defines, 
const std::string &defaultValue)
 
  646     for (std::string::size_type defineStartPos = 0U; defineStartPos < 
cfg.size();) {
 
  647         const std::string::size_type defineEndPos = 
cfg.find(
';', defineStartPos);
 
  648         std::string def = (defineEndPos == std::string::npos) ? 
cfg.substr(defineStartPos) : 
cfg.substr(defineStartPos, defineEndPos - defineStartPos);
 
  649         if (!defaultValue.empty() && def.find(
'=') == std::string::npos)
 
  650             def += 
'=' + defaultValue;
 
  651         defines.push_back(std::move(def));
 
  652         if (defineEndPos == std::string::npos)
 
  654         defineStartPos = defineEndPos + 1U;
 
  658 static simplecpp::DUI 
createDUI(
const Settings &mSettings, 
const std::string &
cfg, 
const std::string &filename)
 
  668         const std::string::size_type pos = def.find_first_of(
" (");
 
  669         if (pos == std::string::npos) {
 
  670             dui.defines.push_back(def);
 
  677             s[s.find(
')')+1] = 
'=';
 
  679         dui.defines.push_back(std::move(s));
 
  688     if (lang == Standards::Language::CPP) {
 
  692     else if (lang == Standards::Language::C) {
 
  702     switch (output.type) {
 
  703     case simplecpp::Output::ERROR:
 
  704     case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY:
 
  705     case simplecpp::Output::SYNTAX_ERROR:
 
  706     case simplecpp::Output::UNHANDLED_CHAR_ERROR:
 
  707     case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
 
  708     case simplecpp::Output::FILE_NOT_FOUND:
 
  710     case simplecpp::Output::WARNING:
 
  711     case simplecpp::Output::MISSING_HEADER:
 
  712     case simplecpp::Output::PORTABILITY_BACKSLASH:
 
  720     const auto it = std::find_if(outputList.cbegin(), outputList.cend(), [](
const simplecpp::Output &output) {
 
  721         return hasErrors(output);
 
  723     return it != outputList.cend();
 
  731         const auto it = std::find_if(outputList.cbegin(), outputList.cend(), [](
const simplecpp::Output &output){
 
  732             return hasErrors(output);
 
  734         if (it != outputList.cend()) {
 
  744     simplecpp::OutputList outputList;
 
  745     mTokenLists = simplecpp::load(rawtokens, files, dui, &outputList);
 
  752     for (std::pair<const std::string, simplecpp::TokenList*>& tokenList : 
mTokenLists) {
 
  753         if (tokenList.second)
 
  754             tokenList.second->removeComments();
 
  778 simplecpp::TokenList 
Preprocessor::preprocess(
const simplecpp::TokenList &tokens1, 
const std::string &
cfg, std::vector<std::string> &files, 
bool throwError)
 
  782     simplecpp::OutputList outputList;
 
  783     std::list<simplecpp::MacroUsage> macroUsage;
 
  784     std::list<simplecpp::IfCond> ifCond;
 
  785     simplecpp::TokenList tokens2(files);
 
  786     simplecpp::preprocess(tokens2, tokens1, files, 
mTokenLists, dui, &outputList, ¯oUsage, &ifCond);
 
  792     tokens2.removeComments();
 
  797 std::string 
Preprocessor::getcode(
const simplecpp::TokenList &tokens1, 
const std::string &
cfg, std::vector<std::string> &files, 
const bool writeLocations)
 
  799     simplecpp::TokenList tokens2 = 
preprocess(tokens1, 
cfg, files, 
false);
 
  800     unsigned int prevfile = 0;
 
  801     unsigned int line = 1;
 
  802     std::ostringstream ret;
 
  803     for (
const simplecpp::Token *tok = tokens2.cfront(); tok; tok = tok->next) {
 
  804         if (writeLocations && tok->location.fileIndex != prevfile) {
 
  805             ret << 
"\n#line " << tok->location.line << 
" \"" << tok->location.file() << 
"\"\n";
 
  806             prevfile = tok->location.fileIndex;
 
  807             line = tok->location.line;
 
  810         if (tok->previous && line >= tok->location.line) 
 
  812         while (tok->location.line > line) {
 
  816         if (!tok->macro.empty())
 
  826     for (
const simplecpp::Output &out : outputList) {
 
  828         case simplecpp::Output::ERROR:
 
  829             if (!
startsWith(out.msg,
"#error") || showerror)
 
  830                 error(out.location.file(), out.location.line, out.msg);
 
  832         case simplecpp::Output::WARNING:
 
  833         case simplecpp::Output::PORTABILITY_BACKSLASH:
 
  835         case simplecpp::Output::MISSING_HEADER: {
 
  836             const std::string::size_type pos1 = out.msg.find_first_of(
"<\"");
 
  837             const std::string::size_type pos2 = out.msg.find_first_of(
">\"", pos1 + 1U);
 
  838             if (pos1 < pos2 && pos2 != std::string::npos)
 
  842         case simplecpp::Output::INCLUDE_NESTED_TOO_DEEPLY:
 
  843         case simplecpp::Output::SYNTAX_ERROR:
 
  844         case simplecpp::Output::UNHANDLED_CHAR_ERROR:
 
  845             error(out.location.file(), out.location.line, out.msg);
 
  847         case simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND:
 
  848         case simplecpp::Output::FILE_NOT_FOUND:
 
  857     std::list<ErrorMessage::FileLocation> locationList;
 
  858     if (!filename.empty()) {
 
  863         locationList.emplace_back(file, linenr, 0);
 
  869                                         "preprocessorErrorDirective",
 
  879     std::list<ErrorMessage::FileLocation> locationList;
 
  880     if (!filename.empty()) {
 
  881         locationList.emplace_back(filename, linenr, 0);
 
  885                         "Include file: <" + header + 
"> not found. Please note: Cppcheck does not need standard library headers to get proper results." :
 
  886                         "Include file: \"" + header + 
"\" not found.",
 
  887                         (headerType==
SystemHeader) ? 
"missingIncludeSystem" : 
"missingInclude",
 
  905         out << 
"  <macro-usage>" << std::endl;
 
  906         for (
const simplecpp::MacroUsage ¯oUsage: 
mMacroUsage) {
 
  908                 << 
" name=\"" << macroUsage.macroName << 
"\"" 
  910                 << 
" line=\"" << macroUsage.macroLocation.line << 
"\"" 
  911                 << 
" column=\"" << macroUsage.macroLocation.col << 
"\"" 
  913                 << 
" useline=\"" << macroUsage.useLocation.line << 
"\"" 
  914                 << 
" usecolumn=\"" << macroUsage.useLocation.col << 
"\"" 
  915                 << 
" is-known-value=\"" << 
bool_to_string(macroUsage.macroValueKnown) << 
"\"" 
  916                 << 
"/>" << std::endl;
 
  918         out << 
"  </macro-usage>" << std::endl;
 
  922         out << 
"  <simplecpp-if-cond>" << std::endl;
 
  923         for (
const simplecpp::IfCond &ifCond: 
mIfCond) {
 
  926                 << 
" line=\"" << ifCond.location.line << 
"\"" 
  927                 << 
" column=\"" << ifCond.location.col << 
"\"" 
  929                 << 
" result=\"" << ifCond.result << 
"\"" 
  930                 << 
"/>" << std::endl;
 
  932         out << 
"  </simplecpp-if-cond>" << std::endl;
 
  938     std::string hashData = toolinfo;
 
  939     for (
const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) {
 
  941             hashData += tok->str();
 
  943     for (std::map<std::string, simplecpp::TokenList *>::const_iterator it = 
mTokenLists.cbegin(); it != 
mTokenLists.cend(); ++it) {
 
  944         for (
const simplecpp::Token *tok = it->second->cfront(); tok; tok = tok->next) {
 
  946                 hashData += tok->str();
 
  949     return (std::hash<std::string>{})(hashData);
 
  955     for (
const std::pair<const std::string, simplecpp::TokenList*>& list : 
mTokenLists) {
 
  963     for (simplecpp::Token *tok = tokenList->front(); tok; tok = tok->next) {
 
  966         if (
sameline(tok, tok->previousSkipComments()))
 
  969         const simplecpp::Token * 
const tok2 = tok->nextSkipComments();
 
  970         if (!tok2 || !
sameline(tok, tok2) || tok2->str() != 
"pragma")
 
  973         const simplecpp::Token * 
const tok3 = tok2->nextSkipComments();
 
  974         if (!tok3 || !
sameline(tok, tok3) || tok3->str() != 
"asm")
 
  977         const simplecpp::Token *endasm = tok3;
 
  978         while ((endasm = endasm->next) != 
nullptr) {
 
  979             if (endasm->op != 
'#' || 
sameline(endasm,endasm->previousSkipComments()))
 
  981             const simplecpp::Token * 
const endasm2 = endasm->nextSkipComments();
 
  982             if (!endasm2 || !
sameline(endasm, endasm2) || endasm2->str() != 
"pragma")
 
  984             const simplecpp::Token * 
const endasm3 = endasm2->nextSkipComments();
 
  985             if (!endasm3 || !
sameline(endasm2, endasm3) || endasm3->str() != 
"endasm")
 
  988                 endasm = endasm->next;
 
  992         const simplecpp::Token * 
const tok4 = tok3->next;
 
  994         const_cast<simplecpp::Token *
>(tok2)->setstr(
"(");
 
  995         const_cast<simplecpp::Token *
>(tok3)->setstr(
")");
 
  996         const_cast<simplecpp::Token *
>(tok4)->setstr(
";");
 
  997         while (tok4->next != endasm)
 
  998             tokenList->deleteToken(tok4->next);
 
static bool match(const Token *tok, const std::string &rhs)
 
This is an interface, which the class responsible of error logging should implement.
 
virtual void reportErr(const ErrorMessage &msg)=0
Information about found errors and warnings is directed here.
 
static std::string toxml(const std::string &str)
Convert XML-sensitive characters into XML entities.
 
Wrapper for error messages, provided by reportErr()
 
std::set< std::string > defines
 
static std::string simplifyPath(std::string originalPath)
Simplify path "foo/bar/.." => "foo".
 
static std::string fromNativeSeparators(std::string path)
Convert path to use internal path separators.
 
static Standards::Language identify(const std::string &path, bool *header=nullptr)
Identify the language based on the file extension.
 
static std::string getRelativePath(const std::string &absolutePath, const std::vector< std::string > &basePaths)
Create a relative path from an absolute one, if absolute path is inside the basePaths.
 
The cppcheck preprocessor.
 
void error(const std::string &filename, unsigned int linenr, const std::string &msg)
 
void handleErrors(const simplecpp::OutputList &outputList, bool throwError)
 
void reportOutput(const simplecpp::OutputList &outputList, bool showerror)
 
void setPlatformInfo(simplecpp::TokenList *tokens) const
 
void simplifyPragmaAsm(simplecpp::TokenList *tokenList) const
 
bool loadFiles(const simplecpp::TokenList &rawtokens, std::vector< std::string > &files)
 
void missingInclude(const std::string &filename, unsigned int linenr, const std::string &header, HeaderTypes headerType)
 
HeaderTypes
Include file types.
 
Preprocessor(const Settings &settings, ErrorLogger &errorLogger)
 
static void simplifyPragmaAsmPrivate(simplecpp::TokenList *tokenList)
 
std::set< std::string > getConfigs(const simplecpp::TokenList &tokens) const
 
static void getErrorMessages(ErrorLogger &errorLogger, const Settings &settings)
 
std::size_t calculateHash(const simplecpp::TokenList &tokens1, const std::string &toolinfo) const
Calculate HASH.
 
std::string getcode(const simplecpp::TokenList &tokens1, const std::string &cfg, std::vector< std::string > &files, const bool writeLocations)
 
std::list< simplecpp::MacroUsage > mMacroUsage
simplecpp tracking info
 
std::list< simplecpp::IfCond > mIfCond
 
std::string mFile0
filename for cpp/c file - useful when reporting errors
 
const Settings & mSettings
 
std::map< std::string, simplecpp::TokenList * > mTokenLists
list of all directives met while preprocessing file
 
static bool hasErrors(const simplecpp::Output &output)
 
simplecpp::TokenList preprocess(const simplecpp::TokenList &tokens1, const std::string &cfg, std::vector< std::string > &files, bool throwError=false)
 
static char macroChar
character that is inserted in expanded macros
 
ErrorLogger & mErrorLogger
 
void dump(std::ostream &out) const
dump all directives present in source file
 
void inlineSuppressions(const simplecpp::TokenList &tokens, SuppressionList &suppressions)
 
std::list< Directive > createDirectives(const simplecpp::TokenList &tokens) const
 
This is just a container for general settings so that we don't need to pass individual values to func...
 
std::set< std::string > userUndefs
undefines given by the user
 
bool clearIncludeCache
Internal: Clear the simplecpp non-existing include cache.
 
std::vector< std::string > basePaths
Paths used as base for conversion to relative paths.
 
bool configurationExcluded(const std::string &file) const
return true if a included file is to be excluded in Preprocessor::getConfigs
 
SimpleEnableGroup< Checks > checks
 
bool relativePaths
Use relative paths in output.
 
std::string userDefines
defines given by the user
 
bool inlineSuppressions
Is –inline-suppr given?
 
bool force
Force checking the files with "too many" configurations (–force).
 
std::list< std::string > includePaths
List of include paths, e.g.
 
std::list< std::string > userIncludes
forced includes given by the user
 
Standards standards
Struct contains standards settings.
 
bool isEnabled(T flag) const
 
class for handling suppressions
 
static std::vector< Suppression > parseMultiSuppressComment(const std::string &comment, std::string *errorMessage)
Parse multi inline suppression in comment.
 
std::string addSuppression(Suppression suppression)
Don't show this error.
 
static const std::string emptyString
 
@ information
Checking information.
 
@ error
Programming error.
 
static bool hasDefine(const std::string &userDefines, const std::string &cfg)
 
static void addInlineSuppressions(const simplecpp::TokenList &tokens, const Settings &settings, SuppressionList &suppressions, std::list< BadInlineSuppression > &bad)
 
static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std::list< SuppressionList::Suppression > &inlineSuppressions, std::list< BadInlineSuppression > &bad)
 
static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cfg, const std::string &filename)
 
static bool isUndefined(const std::string &cfg, const std::set< std::string > &undefined)
 
static std::string readcondition(const simplecpp::Token *iftok, const std::set< std::string > &defined, const std::set< std::string > &undefined)
 
static const simplecpp::Token * gotoEndIf(const simplecpp::Token *cmdtok)
 
static bool sameline(const simplecpp::Token *tok1, const simplecpp::Token *tok2)
 
static void splitcfg(const std::string &cfg, std::list< std::string > &defines, const std::string &defaultValue)
 
static std::string cfg(const std::vector< std::string > &configs, const std::string &userDefines)
 
static bool getConfigsElseIsFalse(const std::vector< std::string > &configs_if, const std::string &userDefines)
 
static void getConfigs(const simplecpp::TokenList &tokens, std::set< std::string > &defined, const std::string &userDefines, const std::set< std::string > &undefined, std::set< std::string > &ret)
 
A preprocessor directive Each preprocessor directive (#include, #define, #undef, #if,...
 
Directive(std::string _file, const int _linenr, const std::string &_str)
record a directive (possibly filtering src)
 
std::string str
the actual directive text
 
unsigned int linenr
line number in (possibly included) file where directive is defined
 
std::string getCPP() const
 
bool parseComment(std::string comment, std::string *errorMessage)
Parse inline suppression in comment.
 
std::string trim(const std::string &s, const std::string &t)
Remove heading and trailing whitespaces from the input parameter.
 
bool startsWith(const std::string &str, const char start[], std::size_t startlen)
 
static const char * bool_to_string(bool b)