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)