15%option never-interactive
18%option extra-type="struct preYY_state *"
22#define YY_TYPEDEF_YY_SCANNER_T
67#define YY_NO_UNISTD_H 1
95 PreIncludeInfo(
const QCString &fn,FileDef *srcFd, FileDef *dstFd,
const QCString &iName,
bool loc,
bool imp)
131 for (
auto &[name,define] : fromMap)
149 if (dpf && includeStack.find(incFile)==includeStack.end())
151 includeStack.insert(incFile);
158 toMap.emplace(name,define);
172 void addInclude(
const std::string &fromFileName,
const std::string &toFileName)
178 it =
m_fileMap.emplace(fromFileName,std::make_unique<DefinesPerFile>(
this)).first;
180 auto &dpf = it->second;
181 dpf->addInclude(toFileName);
190 it =
m_fileMap.emplace(fileName,std::make_unique<DefinesPerFile>(
this)).first;
192 it->second->store(fromMap);
200 auto &dpf = it->second;
201 dpf->retrieve(toMap);
211 return it->second->stored();
221 return it!=
m_fileMap.end() ? it->second.get() :
nullptr;
224 std::unordered_map< std::string, std::unique_ptr<DefinesPerFile> >
m_fileMap;
343static yy_size_t
getFenceSize(
char *txt, yy_size_t leng);
348#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
A class representing a macro definition.
Local class used to hold the defines for a single file.
void addInclude(const std::string &fileName)
DefinesPerFile(DefineManager *parent)
Creates an empty container for defines.
void retrieveRec(DefineMap &toMap, StringUnorderedSet &includeStack)
void store(const DefineMap &fromMap)
StringUnorderedSet m_includedFiles
void retrieve(DefineMap &toMap)
Class that manages the defines available while preprocessing files.
bool alreadyProcessed(const std::string &fileName) const
void addInclude(const std::string &fromFileName, const std::string &toFileName)
void store(const std::string &fileName, const DefineMap &fromMap)
std::unordered_map< std::string, std::unique_ptr< DefinesPerFile > > m_fileMap
void retrieve(const std::string &fileName, DefineMap &toMap)
DefinesPerFile * find(const std::string &fileName) const
Helper function to return the DefinesPerFile object for a given file name.
This is an alternative implementation of QCString.
std::stack< bool > BoolStack
std::unordered_set< std::string > StringUnorderedSet
std::vector< std::string > StringVector
std::map< std::string, int > IntMap
std::vector< Define > DefineList
List of all macro definitions.
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Portable versions of functions that are platform dependent.
std::map< std::string, Define > DefineMap
A dictionary of managed Define objects.
static void startCondSection(yyscan_t yyscanner, const QCString §Id)
static void setCaseDone(yyscan_t yyscanner, bool value)
static void addMacroDefinition(yyscan_t yyscanner)
static void decrLevel(yyscan_t yyscanner)
static void addDefine(yyscan_t yyscanner)
static void determineBlockName(yyscan_t yyscanner)
static void incrLevel(yyscan_t yyscanner)
static QCString expandMacro(yyscan_t yyscanner, const QCString &name)
static void outputSpaces(yyscan_t yyscanner, char *s)
static void endCondSection(yyscan_t yyscanner)
static Define * isDefined(yyscan_t yyscanner, const QCString &name)
Returns a reference to a Define object given its name or 0 if the Define does not exist.
static void outputString(yyscan_t yyscanner, const QCString &s)
static void setFileName(yyscan_t yyscanner, const QCString &name)
static std::mutex g_globalDefineMutex
static void outputChar(yyscan_t yyscanner, char c)
static QCString extractTrailingComment(const QCString &s)
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
static char resolveTrigraph(char c)
static const char * stateToString(int state)
static DefineManager g_defineManager
static void readIncludeFile(yyscan_t yyscanner, const QCString &inc)
static yy_size_t getFenceSize(char *txt, yy_size_t leng)
static std::mutex g_updateGlobals
static bool otherCaseDone(yyscan_t yyscanner)
static void outputArray(yyscan_t yyscanner, const char *a, yy_size_t len)
static void extraSpacing(yyscan_t yyscanner)
static const char * getLexerFILE()
static QCString escapeAt(const QCString &text)
static bool computeExpression(yyscan_t yyscanner, const QCString &expr)
static void outputSpace(yyscan_t yyscanner, char c)
static std::mutex g_debugMutex
const std::string * oldFileBuf
PreIncludeInfo(const QCString &fn, FileDef *srcFd, FileDef *dstFd, const QCString &iName, bool loc, bool imp)
preYY_CondCtx(const QCString &file, int line, const QCString &id, bool b)
StringUnorderedSet expanded
LinkedMap< PreIncludeInfo > includeRelations
StringUnorderedSet pragmaSet
ConstExpressionParser constExpParser
std::unordered_map< std::string, Define * > expandedDict
std::deque< std::unique_ptr< FileState > > includeStack
std::stack< std::unique_ptr< preYY_CondCtx > > condStack
const std::string * inputBuf
DefineList macroDefinitions
A bunch of utility functions.
358IDSTART [a-z_A-Z\x80-\xFF]
359ID {IDSTART}[a-z_A-Z0-9\x80-\xFF]*
363RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
364RAWEND ")"[^ \t\(\)\\]{0,16}\"
365CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
367FORMULA_START [\\@]("f{"|"f$"|"f["|"f(")
368FORMULA_END [\\@]("f}"|"f$"|"f]"|"f)")
369VERBATIM_START [\\@]("verbatim"|"iliteral"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"rtfonly"|"manonly"|"dot"|"msc"|"startuml"|"code"("{"[^}]*"}")?){BN}+
370VERBATIM_END [\\@]("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"enddot"|"endmsc"|"enduml"|"endcode")
371VERBATIM_LINE [\\@]"noop"{B}+
372LITERAL_BLOCK {FORMULA_START}|{VERBATIM_START}
373LITERAL_BLOCK_END {FORMULA_END}|{VERBATIM_END}
378RulesSharp "<"[^>\n]*">"
379RulesCurly "{"[^{}\n]*"}"
384EscapeRulesCharOpen "\\["|"\<"|"\\{"|"\\("|"\\\""|"\\ "|"\\\\"
385EscapeRulesCharClose "\\]"|"\>"|"\\}"|"\\)"
386EscapeRulesChar {EscapeRulesCharOpen}|{EscapeRulesCharClose}
412%x CopyStringFtnDouble
429%x JavaDocVerbatimCode
463 yyextra->yyColNr+=(int)yyleng;
465 yyextra->potentialDefine=yytext;
468<Start>^("%top{"|"%{") {
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
473<Start>^{Bopt}"cpp_quote"{Bopt}"("{Bopt}\" {
474 if (yyextra->insideIDL)
489<IDLquote>"\""{Bopt}")" {
503<Start>^{B}*[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]+{B}*"("[^\)\n]*")"/{BN}{1,10}*[:{] {
505 for (i=(
int)yyleng-1;i>=0;i--)
511<Start>^{B}*[_A-Z][_A-Z0-9]+{B}*"("[^\(\)\n]*"("[^\)\n]*")"[^\)\n]*")"{B}*\n |
512<Start>^{B}*[_A-Z][_A-Z0-9]+{B}*"("[^\)\n]*")"{B}*\n |
513<Start>^{B}*[_A-Z][_A-Z0-9]+{B}*"("[^\(\)\n]*"("[^\)\n]*")"[^\)\n]*")"/{B}*("//"|"/\*") |
514<Start>^{B}*[_A-Z][_A-Z0-9]+{B}*"("[^\)\n]*")"/{B}*("//"|"/\*") {
517 int pos = name.find(
'(');
519 name=name.left(pos).stripWhiteSpace();
522 if (skipFuncMacros && !yyextra->insideFtn &&
523 name!=
"Q_PROPERTY" &&
525 (yyextra->includeStack.empty() || yyextra->curlyCount>0) &&
526 yyextra->macroExpansion &&
534 if (yytext[yyleng-1] ==
'\n')
543 for (i=(
int)yyleng-1;i>=0;i--)
#define Config_getBool(name)
550<CopyLine,LexCopyLine>"extern"{BN}*"\""[^\"]+"\""{BN}*("{")? {
552 yyextra->yyLineNr+=text.
contains(
'\n');
int contains(char c, bool cs=TRUE) const
555<CopyLine,LexCopyLine>{RAWBEGIN} {
556 yyextra->delimiter = yytext+2;
557 yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1);
559 BEGIN(CopyRawString);
561<CopyLine,LexCopyLine>"{" {
562 if (yyextra->includeStack.empty())
564 yyextra->curlyCount++;
571<CopyLine,LexCopyLine>"}" {
572 if (yyextra->includeStack.empty() && yyextra->curlyCount>0)
574 yyextra->curlyCount--;
578<CopyLine,LexCopyLine>"'"\\[0-7]{1,3}"'" {
581<CopyLine,LexCopyLine>"'"\\."'" {
584<CopyLine,LexCopyLine>"'"."'" {
587<CopyLine,LexCopyLine>[$]?@\" {
590 BEGIN( CopyStringCs );
592<CopyLine,LexCopyLine>\" {
600 BEGIN( CopyStringFtnDouble );
603<CopyLine,LexCopyLine>\' {
606 BEGIN( CopyStringFtn );
608<CopyString>[^\"\\\r\n]+ {
611<CopyStringCs>[^\"\r\n]+ {
620<CopyString,CopyStringCs>\" {
624<CopyStringFtnDouble>[^\"\\\r\n]+ {
627<CopyStringFtnDouble>\\. {
630<CopyStringFtnDouble>\" {
634<CopyStringFtn>[^\'\\\r\n]+ {
644<CopyRawString>{RAWEND} {
647 delimiter=delimiter.
left(delimiter.
length()-1);
648 if (delimiter==yyextra->delimiter)
size_t length() const
Returns the length of the string, not counting the 0-terminator.
QCString left(size_t len) const
653<CopyRawString>[^)]+ {
659<CopyLine,LexCopyLine>{ID}/{BN}{0,80}"(" {
660 yyextra->expectGuard =
FALSE;
670 if ((yyextra->includeStack.empty() || yyextra->curlyCount>0) &&
671 yyextra->macroExpansion &&
677 yyextra->roundCount=0;
678 yyextra->defArgsStr=yytext;
688 yyextra->findDefArgContext = CopyLine;
689 BEGIN(FindDefineArgs);
697<CopyLine>{RulesDelim} {
699 yyextra->lexRulesPart = !yyextra->lexRulesPart;
703<CopyLine>{RulesSharp} {
704 if (!yyextra->lexRulesPart) REJECT;
705 if (yyextra->curlyCount) REJECT;
709<RulesPattern>{EscapeRulesChar} {
712<RulesPattern>{RulesCurly} {
715<RulesPattern>{StartDouble} {
717 yyextra->lastContext = YY_START;
720<RulesDouble,RulesRoundDouble>"\\\\" {
723<RulesDouble,RulesRoundDouble>"\\\"" {
728 BEGIN( yyextra->lastContext ) ;
730<RulesRoundDouble>"\"" {
734<RulesDouble,RulesRoundDouble>. {
737<RulesPattern>{StartSquare} {
739 yyextra->lastContext = YY_START;
742<RulesSquare,RulesRoundSquare>{CHARCE} {
745<RulesSquare,RulesRoundSquare>"\\[" |
746<RulesSquare,RulesRoundSquare>"\\]" {
753<RulesRoundSquare>"]" {
757<RulesSquare,RulesRoundSquare>"\\\\" {
760<RulesSquare,RulesRoundSquare>. {
763<RulesPattern>{StartRoundQuest} {
765 yyextra->lastContext = YY_START;
766 BEGIN(RulesRoundQuest);
768<RulesRoundQuest>{nl} {
771<RulesRoundQuest>[^)] {
774<RulesRoundQuest>")" {
776 BEGIN(yyextra->lastContext);
778<RulesPattern>{StartRound} {
779 yyextra->roundCount++;
781 yyextra->lastContext = YY_START;
784<RulesRound>{RulesCurly} {
787<RulesRound>{StartSquare} {
789 BEGIN(RulesRoundSquare);
791<RulesRound>{StartDouble} {
793 BEGIN(RulesRoundDouble);
795<RulesRound>{EscapeRulesChar} {
799 yyextra->roundCount++;
803 yyextra->roundCount--;
805 if (!yyextra->roundCount) BEGIN( yyextra->lastContext ) ;
824<CopyLine,LexCopyLine>{ID} {
826 if ((yyextra->includeStack.empty() || yyextra->curlyCount>0) &&
827 yyextra->macroExpansion &&
843<CopyLine,LexCopyLine>"\\"\r?/\n {
846<CopyLine,LexCopyLine>\\. {
849<CopyLine,LexCopyLine>. {
852<CopyLine,LexCopyLine>\n {
859 yyextra->defArgsStr+=
'(';
860 yyextra->roundCount++;
863 yyextra->defArgsStr+=
')';
864 yyextra->roundCount--;
865 if (yyextra->roundCount==0)
869 if (yyextra->findDefArgContext==CopyLine)
872 BEGIN(yyextra->findDefArgContext);
877 yyextra->nospaces=
FALSE;
887<FindDefineArgs>{CHARLIT} {
888 yyextra->defArgsStr+=yytext;
890<FindDefineArgs>{CCS}[*]? {
891 yyextra->defArgsStr+=yytext;
892 BEGIN(ArgCopyCComment);
894<FindDefineArgs>{CPPC}[/!].*\n/{B}*{CPPC}[/!] {
895 yyextra->defArgsStr+=
QCString(
"/**")+&yytext[3];
896 BEGIN(ArgCopyCppComment);
898<FindDefineArgs>{CPPC}[/!].*\n {
899 yyextra->defArgsStr+=
QCString(
"/**")+&yytext[3]+
" */";
902 yyextra->defArgsStr+=*yytext;
907 yyextra->defArgsStr+=*yytext;
911 yyextra->defArgsStr+=
' ';
916 yyextra->defArgsStr+=
"@@";
919 yyextra->defArgsStr+=*yytext;
921<ArgCopyCComment>[^*\n]+ {
922 yyextra->defArgsStr+=yytext;
924<ArgCopyCComment>{CCE} {
925 yyextra->defArgsStr+=yytext;
926 BEGIN(FindDefineArgs);
929 yyextra->defArgsStr+=
' ';
934 yyextra->defArgsStr+=yytext;
936<ArgCopyCppComment>^{B}*
937<ArgCopyCppComment>{CPPC}[/!].*\n/{B}*{CPPC}[/!] {
938 const char *startContent = &yytext[3];
939 if (startContent[0]==
'<') startContent++;
940 yyextra->defArgsStr+=startContent;
942<ArgCopyCppComment>{CPPC}[/!].*\n {
943 const char *startContent = &yytext[3];
944 if (startContent[0]==
'<') startContent++;
945 yyextra->defArgsStr+=
QCString(startContent)+
" */";
946 BEGIN(FindDefineArgs);
948<ArgCopyCppComment>. {
950 yyextra->defArgsStr+=
" */";
951 BEGIN(FindDefineArgs);
954 yyextra->defArgsStr+=*yytext;
955 BEGIN(FindDefineArgs);
959 yyextra->defArgsStr+=*yytext;
960 BEGIN(FindDefineArgs);
963<ReadString>{CPPC}|{CCS} {
964 yyextra->defArgsStr+=yytext;
966<ReadString>\\/\r?\n {
969 yyextra->defArgsStr+=yytext;
972 yyextra->defArgsStr+=*yytext;
974<Command>("include"|"import"){B}+/{ID} {
975 yyextra->isImported = yytext[1]==
'm';
976 if (yyextra->macroExpansion)
979<Command>("include"|"import"){B}*[<"] {
980 yyextra->isImported = yytext[1]==
'm';
982 c[0]=yytext[yyleng-1];c[1]=
'\0';
986<Command>("cmake")?"define"{B}+ {
987 yyextra->potentialDefine +=
substitute(yytext,
"cmake",
" ");
989 yyextra->yyColNr+=(int)yyleng;
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
992<Command>"cmakedefine01"{B}+ {
993 yyextra->potentialDefine +=
substitute(yytext,
"cmakedefine01",
" define ");
995 yyextra->yyColNr+=(int)yyleng;
996 BEGIN(CmakeDefName01);
998<Command>"ifdef"/{B}*"(" {
1000 yyextra->guardExpr.clear();
1001 BEGIN(DefinedExpr2);
1003<Command>"ifdef"/{B}+ {
1006 yyextra->guardExpr.clear();
1007 BEGIN(DefinedExpr1);
1009<Command>"ifndef"/{B}*"(" {
1011 yyextra->guardExpr=
"! ";
1012 BEGIN(DefinedExpr2);
1014<Command>"ifndef"/{B}+ {
1016 yyextra->guardExpr=
"! ";
1017 BEGIN(DefinedExpr1);
1019<Command>"if"/[ \t(!] {
1021 yyextra->guardExpr.clear();
1024<Command>("elif"|"else"{B}*"if")/[ \t(!] {
1027 yyextra->guardExpr.clear();
1033 BEGIN(SkipCPPBlock);
1036<Command>"else"/[^a-z_A-Z0-9\x80-\xFF] {
1040 BEGIN(SkipCPPBlock);
1047<Command>"undef"{B}+ {
1050<Command>("elif"|"else"{B}*"if")/[ \t(!] {
1053 yyextra->guardExpr.clear();
1057<Command>"endif"/[^a-z_A-Z0-9\x80-\xFF] {
1061<Command,IgnoreLine>\n {
1064 yyextra->yyLineNr++;
1066<Command>"pragma"{B}+"once" {
1067 yyextra->expectGuard =
FALSE;
1068 if (yyextra->pragmaSet.find(yyextra->fileName.str())!=yyextra->pragmaSet.end())
1075 yyextra->pragmaSet.insert(yyextra->fileName.data());
1080<PragmaOnce><<EOF>> {
1081 yyextra->expectGuard =
FALSE;
1087<IgnoreLine>\\[\r]?\n {
1089 yyextra->yyLineNr++;
1092<Command>. { yyextra->potentialDefine += yytext[0]==
'\t' ?
'\t' :
' ';
1093 yyextra->yyColNr+=(int)yyleng;
1109 yyextra->guardExpr+=
' ';
1110 yyextra->yyLineNr++;
1112<Guard>"defined"/{B}*"(" {
1113 BEGIN(DefinedExpr2);
1115<Guard>"defined"/{B}+ {
1116 BEGIN(DefinedExpr1);
1118<Guard>"true"/{B}|{B}*[\r]?\n { yyextra->guardExpr+=
"1L"; }
1119<Guard>"false"/{B}|{B}*[\r]?\n { yyextra->guardExpr+=
"0L"; }
1120<Guard>"not"/{B} { yyextra->guardExpr+=
'!'; }
1121<Guard>"not_eq"/{B} { yyextra->guardExpr+=
"!="; }
1122<Guard>"and"/{B} { yyextra->guardExpr+=
"&&"; }
1123<Guard>"or"/{B} { yyextra->guardExpr+=
"||"; }
1124<Guard>"bitand"/{B} { yyextra->guardExpr+=
"&"; }
1125<Guard>"bitor"/{B} { yyextra->guardExpr+=
"|"; }
1126<Guard>"xor"/{B} { yyextra->guardExpr+=
"^"; }
1127<Guard>"compl"/{B} { yyextra->guardExpr+=
"~"; }
1128<Guard>{ID} { yyextra->guardExpr+=yytext; }
1129<Guard>"@" { yyextra->guardExpr+=
"@@"; }
1130<Guard>. { yyextra->guardExpr+=*yytext; }
1144 BEGIN(SkipCPPBlock);
1147<DefinedExpr1,DefinedExpr2>\\\n { yyextra->yyLineNr++;
outputChar(yyscanner,
'\n'); }
1149 if (
isDefined(yyscanner,yytext) || yyextra->guardName==yytext)
1150 yyextra->guardExpr+=
" 1L ";
1152 yyextra->guardExpr+=
" 0L ";
1153 yyextra->lastGuardName=yytext;
1157 if (
isDefined(yyscanner,yytext) || yyextra->guardName==yytext)
1158 yyextra->guardExpr+=
" 1L ";
1160 yyextra->guardExpr+=
" 0L ";
1161 yyextra->lastGuardName=yytext;
1163<DefinedExpr1,DefinedExpr2>\n {
1164 yyextra->yyLineNr++;
1166 BEGIN(SkipCPPBlock);
1171<DefinedExpr1,DefinedExpr2>.
1172<SkipCPPBlock>^{B}*"#" { BEGIN(SkipCommand); }
1173<SkipCPPBlock>^{Bopt}/[^#] { BEGIN(SkipLine); }
1174<SkipCPPBlock>\n { yyextra->yyLineNr++;
outputChar(yyscanner,
'\n'); }
1176<SkipCommand>"if"(("n")?("def"))?/[ \t(!] {
1181<SkipCommand>"else" {
1190<SkipCommand>("elif"|"else"{B}*"if")/[ \t(!] {
1191 if (yyextra->ifcount==0)
1195 yyextra->guardExpr.clear();
1196 yyextra->lastGuardName.clear();
1201 BEGIN(SkipCPPBlock);
1205<SkipCommand>"endif" {
1206 yyextra->expectGuard =
FALSE;
1208 if (--yyextra->ifcount<0)
1216 yyextra->yyLineNr++;
1217 BEGIN(SkipCPPBlock);
1224<SkipLine>{CHARLIT} { }
1229<SkipString>{CPPC}/[^\n]* {
1231<SkipLine,SkipCommand,SkipCPPBlock>{CPPC}[^\n]* {
1232 yyextra->lastCPPContext=YY_START;
1233 BEGIN(RemoveCPPComment);
1235<SkipString>{CCS}/[^\n]* {
1237<SkipLine,SkipCommand,SkipCPPBlock>{CCS}/[^\n]* {
1238 yyextra->lastCContext=YY_START;
1239 BEGIN(RemoveCComment);
1243 yyextra->yyLineNr++;
1244 BEGIN(SkipCPPBlock);
1246<SkipString>[^"\\\n]+ { }
1252<IncludeID>{ID}{Bopt}/"(" {
1253 yyextra->nospaces=
TRUE;
1254 yyextra->roundCount=0;
1255 yyextra->defArgsStr=yytext;
1256 yyextra->findDefArgContext = IncludeID;
1257 BEGIN(FindDefineArgs);
1260 yyextra->nospaces=
TRUE;
1264<Include>[^\">\n]+[\">] {
1265 yyextra->incName+=yytext;
1266 if (yyextra->isImported)
1276<EndImport>{ENDIMPORTopt}/\n {
1280<EndImport>\\[\r]?"\n" {
1282 yyextra->yyLineNr++;
1286<DefName>{ID}/("\\\n")*"(" {
1288 yyextra->argMap.clear();
1289 yyextra->defArgs = 0;
1290 yyextra->defArgsStr.clear();
1291 yyextra->defText.clear();
1292 yyextra->defLitText.clear();
1293 yyextra->defName = yytext;
1294 yyextra->defVarArgs =
FALSE;
1295 yyextra->defExtraSpacing.clear();
1296 yyextra->defContinue =
false;
1299<DefName>{ID}{B}+"1"/[ \r\t\n] {
1301 yyextra->argMap.clear();
1302 yyextra->defArgs = -1;
1303 yyextra->defArgsStr.clear();
1305 yyextra->defVarArgs =
FALSE;
1308 if (yyextra->curlyCount>0 || yyextra->defName!=yyextra->lastGuardName || !yyextra->expectGuard)
1310 QCString def = yyextra->potentialDefine +
1313 outputSpaces(yyscanner,yytext+yyextra->defName.length());
1314 yyextra->quoteArg=
FALSE;
1315 yyextra->insideComment=
FALSE;
1316 yyextra->lastGuardName.clear();
1317 yyextra->defText=
"1";
1318 yyextra->defLitText=
"1";
1324 yyextra->defText.clear();
1325 yyextra->defLitText.clear();
1328 yyextra->expectGuard=
FALSE;
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
1330<DefName,CmakeDefName01>{ID}/{B}*"\n" {
1331 yyextra->argMap.clear();
1332 yyextra->defArgs = -1;
1333 yyextra->defName = yytext;
1334 yyextra->defArgsStr.clear();
1335 yyextra->defText.clear();
1336 yyextra->defLitText.clear();
1337 yyextra->defVarArgs =
FALSE;
1340 if (yyextra->curlyCount>0 || yyextra->defName!=yyextra->lastGuardName || !yyextra->expectGuard)
1342 QCString def = yyextra->potentialDefine + yyextra->defName;
1344 yyextra->quoteArg=
FALSE;
1345 yyextra->insideComment=
FALSE;
1346 if (YY_START == CmakeDefName01) yyextra->defText =
"0";
1347 else if (yyextra->insideCS) yyextra->defText=
"1";
1353 yyextra->guardName = yytext;
1354 yyextra->lastGuardName.clear();
1357 yyextra->expectGuard=
FALSE;
1361 yyextra->argMap.clear();
1362 yyextra->defArgs = -1;
1363 yyextra->defArgsStr.clear();
1364 yyextra->defText.clear();
1365 yyextra->defLitText.clear();
1366 yyextra->defName = yytext;
1367 yyextra->defVarArgs =
FALSE;
1368 QCString def = yyextra->potentialDefine +
1370 yyextra->defArgsStr ;
1372 yyextra->quoteArg=
FALSE;
1373 yyextra->insideComment=
FALSE;
1377 yyextra->defExtraSpacing+=
"\n";
1378 yyextra->defContinue =
true;
1379 yyextra->yyLineNr++;
1381<DefineArg>{B}* { yyextra->defExtraSpacing+=yytext; }
1382<DefineArg>","{B}* { yyextra->defArgsStr+=yytext; }
1383<DefineArg>"("{B}* { yyextra->defArgsStr+=yytext; }
1384<DefineArg>{B}*")"{B}* {
1386 yyextra->defArgsStr+=yytext;
1387 QCString def = yyextra->potentialDefine +
1389 yyextra->defArgsStr +
1390 yyextra->defExtraSpacing ;
1392 yyextra->quoteArg=
FALSE;
1393 yyextra->insideComment=
FALSE;
1397 yyextra->defVarArgs =
TRUE;
1398 yyextra->defArgsStr+=yytext;
1399 yyextra->argMap.emplace(std::string(
"__VA_ARGS__"),yyextra->defArgs);
1402<DefineArg>{ID}{B}*("..."?) {
1405 yyextra->defVarArgs = yytext[yyleng-1]==
'.';
1406 if (yyextra->defVarArgs)
1411 yyextra->defArgsStr+=yytext;
1412 yyextra->argMap.emplace(
toStdString(argName),yyextra->defArgs);
std::string toStdString(const QCString &s)
1428<DefineText>{CCS}[!*]? {
1429 yyextra->defText+=yytext;
1430 yyextra->defLitText+=yytext;
1431 yyextra->lastCContext=YY_START;
1432 yyextra->commentCount=1;
1433 BEGIN(CopyCComment);
1435<DefineText>{CPPC}[!/]? {
1437 yyextra->lastCPPContext=YY_START;
1438 yyextra->defLitText+=
' ';
1439 BEGIN(SkipCPPComment);
1441<SkipCComment>[/]?{CCE} {
1442 if (yytext[0]==
'/')
outputChar(yyscanner,
'/');
1444 if (--yyextra->commentCount<=0)
1446 if (yyextra->lastCContext==Start)
1450 YY_CURRENT_BUFFER->yy_at_bol=1;
1452 BEGIN(yyextra->lastCContext);
1455<SkipCComment>{CPPC}("/")* {
1458<SkipCComment>{CCS} {
1462<SkipCond>[\\@][\\@] { }
1463<SkipCond>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
1465 if (!markdownSupport || !yyextra->isSpecialComment)
1471 yyextra->fenceChar=
'~';
1473 BEGIN(SkipCondVerbatim);
1476<SkipCond>^({B}*"*"+)?{B}{0,3}"```"[`]* {
1478 if (!markdownSupport || !yyextra->isSpecialComment)
1484 yyextra->fenceChar=
'`';
1486 BEGIN(SkipCondVerbatim);
1489<SkipCComment>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
1491 if (!markdownSupport || !yyextra->isSpecialComment)
1498 yyextra->fenceChar=
'~';
1500 BEGIN(SkipVerbatim);
1503<SkipCComment>^({B}*"*"+)?{B}{0,3}"```"[`]* {
1505 if (!markdownSupport || !yyextra->isSpecialComment)
1512 yyextra->fenceChar=
'`';
1514 BEGIN(SkipVerbatim);
1517<SkipCComment>[\\@]{VERBATIM_LINE} |
1518<SkipCComment>[\\@]{LITERAL_BLOCK} {
1522<SkipCComment>{VERBATIM_LINE}.*/\n {
1525<SkipCComment>{LITERAL_BLOCK} {
1529 BEGIN(SkipVerbatim);
1531<SkipCond>[\\@][\\@]"cond"[ \t]+ {}
1532<SkipCond>[\\@]"cond"/\n |
1533<SkipCond>[\\@]"cond"[ \t]+ {
1537<SkipCComment>"{"[ \t]*"@code"/[ \t\n] {
1539 yyextra->javaBlock=1;
1540 BEGIN(JavaDocVerbatimCode);
1542<SkipCComment>"{"[ \t]*"@literal"/[ \t\n] {
1544 yyextra->javaBlock=1;
1545 BEGIN(JavaDocVerbatimCode);
1547<SkipCComment,SkipCPPComment>[\\@][\\@]"cond"[ \t\n]+ {
1550<SkipCPPComment>[\\@]"cond"[ \t]+ {
1551 yyextra->ccomment=
TRUE;
1552 yyextra->condCtx=YY_START;
1555<SkipCComment>[\\@]"cond"[ \t]+ {
1556 yyextra->ccomment=
FALSE;
1557 yyextra->condCtx=YY_START;
1560<CondLineC,CondLineCpp>[!()&| \ta-z_A-Z0-9\x80-\xFF.\-]+ {
1564 if (YY_START==CondLineC)
1568 yyextra->ccomment=
TRUE;
1572 yyextra->ccomment=
FALSE;
1578 BEGIN(yyextra->condCtx);
1581<CondLineC,CondLineCpp>. {
1586 if (YY_START==CondLineC)
1590 yyextra->ccomment=
TRUE;
1594 yyextra->ccomment=
FALSE;
1600 BEGIN(yyextra->condCtx);
1603<SkipCComment,SkipCPPComment>[\\@]"cond"{WSopt}/\n {
1604 if (YY_START==SkipCComment)
1606 yyextra->ccomment=
TRUE;
1612 yyextra->ccomment=
FALSE;
1614 yyextra->condCtx=YY_START;
1618<SkipCond>\n { yyextra->yyLineNr++;
outputChar(yyscanner,
'\n'); }
1619<SkipCond>{VERBATIM_LINE}.*/\n { }
1620<SkipCond>{LITERAL_BLOCK} {
1622 yyextra->yyLineNr+=numNLs;
1623 for (
int i = 0; i < numNLs; i++)
outputChar(yyscanner,
'\n');
1625 BEGIN(SkipCondVerbatim);
1629<SkipCond>[^\/\!*\\@\n]+ { }
1630<SkipCond>{CPPC}[/!] { yyextra->ccomment=
FALSE; }
1631<SkipCond>{CCS}[*!] { yyextra->ccomment=
TRUE; }
1632<SkipCond,SkipCComment,SkipCPPComment>[\\@][\\@]"endcond"/[^a-z_A-Z0-9\x80-\xFF] {
1638<SkipCond>[\\@]"endcond"/[^a-z_A-Z0-9\x80-\xFF] {
1639 bool oldSkip = yyextra->skip;
1641 if (oldSkip && !yyextra->skip)
1643 if (yyextra->ccomment)
1647 BEGIN(yyextra->condCtx);
1650<SkipCComment,SkipCPPComment>[\\@]"endcond"/[^a-z_A-Z0-9\x80-\xFF] {
1651 bool oldSkip = yyextra->skip;
1653 if (oldSkip && !yyextra->skip)
1655 BEGIN(yyextra->condCtx);
1658<SkipCondVerbatim>{LITERAL_BLOCK_END} {
1659 if (yytext[1]==
'f' && yyextra->blockName==&yytext[2])
1663 else if (&yytext[4]==yyextra->blockName)
1668<SkipVerbatim>{LITERAL_BLOCK_END} {
1670 if (yytext[1]==
'f' && yyextra->blockName==&yytext[2])
1672 BEGIN(SkipCComment);
1674 else if (&yytext[4]==yyextra->blockName)
1676 BEGIN(SkipCComment);
1679<SkipCondVerbatim>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
1680 if (yyextra->fenceSize==
getFenceSize(yytext,yyleng) && yyextra->fenceChar==
'~')
1685<SkipCondVerbatim>^({B}*"*"+)?{B}{0,3}"```"[`]* {
1686 if (yyextra->fenceSize==
getFenceSize(yytext,yyleng) && yyextra->fenceChar==
'`')
1691<SkipVerbatim>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
1693 if (yyextra->fenceSize==
getFenceSize(yytext,yyleng) && yyextra->fenceChar==
'~')
1695 BEGIN(SkipCComment);
1698<SkipVerbatim>^({B}*"*"+)?{B}{0,3}"```"[`]* {
1700 if (yyextra->fenceSize==
getFenceSize(yytext,yyleng) && yyextra->fenceChar==
'`')
1702 BEGIN(SkipCComment);
1705<SkipCondVerbatim>{CCE}|{CCS} { }
1706<SkipVerbatim>{CCE}|{CCS} {
1709<JavaDocVerbatimCode>"{" {
1710 if (yyextra->javaBlock==0)
1716 yyextra->javaBlock++;
1720<JavaDocVerbatimCode>"}" {
1721 if (yyextra->javaBlock==0)
1727 yyextra->javaBlock--;
1728 if (yyextra->javaBlock==0)
1731 BEGIN(SkipCComment);
1739<JavaDocVerbatimCode>\n {
1742<JavaDocVerbatimCode>. {
1745<SkipCondVerbatim>[^{*\\@\x06~`\n\/]+ { }
1746<SkipCComment,SkipVerbatim>[^{*\\@\x06~`\n\/]+ {
1749<SkipCComment,SkipVerbatim,SkipCondVerbatim>\n {
1750 yyextra->yyLineNr++;
1753<SkipCondVerbatim>. { }
1754<SkipCComment,SkipVerbatim>. {
1757<CopyCComment>[^*a-z_A-Z\x80-\xFF\n]*[^*a-z_A-Z\x80-\xFF\\\n] {
1758 yyextra->defLitText+=yytext;
1759 yyextra->defText+=
escapeAt(yytext);
1761<CopyCComment>\\[\r]?\n {
1762 yyextra->defLitText+=yytext;
1763 yyextra->defText+=
" ";
1764 yyextra->yyLineNr++;
1765 yyextra->yyMLines++;
1767<CopyCComment>{CCE} {
1768 yyextra->defLitText+=yytext;
1769 yyextra->defText+=yytext;
1770 BEGIN(yyextra->lastCContext);
1773 yyextra->yyLineNr++;
1774 yyextra->defLitText+=yytext;
1775 yyextra->defText+=
' ';
1777<RemoveCComment>{CCE}{B}*"#" {
1778 if (yyextra->lastCContext==SkipCPPBlock)
1787<RemoveCComment>{CCE} { BEGIN(yyextra->lastCContext); }
1788<RemoveCComment>{CPPC}
1789<RemoveCComment>{CCS}
1790<RemoveCComment>[^*\x06\n]+
1791<RemoveCComment>\n { yyextra->yyLineNr++;
outputChar(yyscanner,
'\n'); }
1793<SkipCPPComment>[^\n\/\\@]+ {
1796<SkipCPPComment,RemoveCPPComment>\n {
1798 BEGIN(yyextra->lastCPPContext);
1800<SkipCPPComment>{CCS} {
1803<SkipCPPComment>{CPPC} {
1806<SkipCPPComment>[^\x06\@\\\n]+ {
1812<RemoveCPPComment>{CCS}
1813<RemoveCPPComment>{CPPC}
1814<RemoveCPPComment>[^\x06\n]+
1816<DefineText>"#"/{IDSTART} {
1818 yyextra->quoteArg=
TRUE;
1819 yyextra->idStart=
true;
1820 yyextra->defLitText+=yytext;
1822<DefineText,CopyCComment>{ID} {
1823 yyextra->defLitText+=yytext;
1824 if (YY_START == DefineText)
outputSpaces(yyscanner,yytext);
1825 if (yyextra->quoteArg)
1827 yyextra->defText+=
"\"";
1829 if (yyextra->defArgs>0)
1831 auto it = yyextra->argMap.find(yytext);
1832 if (it!=yyextra->argMap.end())
1835 yyextra->defText+=
'@';
1840 if (yyextra->idStart)
1842 warn(yyextra->fileName,yyextra->yyLineNr,
1843 "'#' is not followed by a macro parameter '%s': '%s'",
1844 qPrint(yyextra->defName),
qPrint(yyextra->defLitText.stripWhiteSpace()));
1846 yyextra->defText+=yytext;
1851 yyextra->defText+=yytext;
1853 if (yyextra->quoteArg)
1855 yyextra->defText+=
"\"";
1857 yyextra->quoteArg=
FALSE;
1858 yyextra->idStart=
false;
QCString & setNum(short n)
#define warn(file, line, fmt,...)
const char * qPrint(const char *s)
1861 yyextra->defLitText+=yytext;
1862 yyextra->defText+=yytext;
1864<DefineText>\\[\r]?\n {
1865 yyextra->defLitText+=yytext;
1868 yyextra->defText +=
' ';
1869 yyextra->yyLineNr++;
1870 yyextra->yyMLines++;
1874 yyextra->defText = yyextra->defText.stripWhiteSpace();
1875 if (yyextra->defText.startsWith(
"##"))
1877 warn(yyextra->fileName,yyextra->yyLineNr,
1878 "'##' cannot occur at the beginning of a macro definition '%s': '%s'",
1879 qPrint(yyextra->defName),
qPrint(yyextra->defLitText.stripWhiteSpace()));
1881 else if (yyextra->defText.endsWith(
"##"))
1883 warn(yyextra->fileName,yyextra->yyLineNr,
1884 "'##' cannot occur at the end of a macro definition '%s': '%s'",
1885 qPrint(yyextra->defName),
qPrint(yyextra->defLitText.stripWhiteSpace()));
1887 else if (yyextra->defText.endsWith(
"#"))
1889 warn(yyextra->fileName,yyextra->yyLineNr,
1890 "expected formal parameter after # in macro definition '%s': '%s'",
1891 qPrint(yyextra->defName),
qPrint(yyextra->defLitText.stripWhiteSpace()));
1896 yyextra->defLitText=yyextra->defLitText.left(yyextra->defLitText.length()-
comment.length()-1);
1899 yyextra->defLitText+=yytext;
1902 if (yyextra->includeStack.empty() || yyextra->curlyCount>0)
1906 def=
isDefined(yyscanner,yyextra->defName);
1920 def->
name = yyextra->defName;
1922 def->
nargs = yyextra->defArgs;
1924 def->
lineNr = yyextra->yyLineNr-yyextra->yyMLines;
1932 yyextra->argMap.clear();
1933 yyextra->yyLineNr++;
1935 yyextra->lastGuardName.clear();
1939 yyextra->defText +=
' ';
1940 yyextra->defLitText+=yytext;
1943 yyextra->defText +=
"##";
1944 yyextra->defLitText+=yytext;
1947 yyextra->defText +=
"@@";
1948 yyextra->defLitText+=yytext;
1952 yyextra->defText += *yytext;
1953 yyextra->defLitText+=yytext;
1954 if (!yyextra->insideComment)
1956 BEGIN(SkipDoubleQuote);
1961 yyextra->defText += *yytext;
1962 yyextra->defLitText+=yytext;
1963 if (!yyextra->insideComment)
1965 BEGIN(SkipSingleQuote);
1968<SkipDoubleQuote>{CPPC}[/]? {
outputSpaces(yyscanner,yytext);
1969 yyextra->defText += yytext;
1970 yyextra->defLitText+=yytext;
1972<SkipDoubleQuote>{CCS}[*]? {
outputSpaces(yyscanner,yytext);
1973 yyextra->defText += yytext;
1974 yyextra->defLitText+=yytext;
1976<SkipDoubleQuote>\" {
1978 yyextra->defText += *yytext;
1979 yyextra->defLitText+=yytext;
1982<SkipSingleQuote,SkipDoubleQuote>\\. {
1984 yyextra->defText += yytext;
1985 yyextra->defLitText+=yytext;
1987<SkipSingleQuote>\' {
1989 yyextra->defText += *yytext;
1990 yyextra->defLitText+=yytext;
1993<SkipDoubleQuote,SkipSingleQuote>. {
outputSpace(yyscanner,yytext[0]);
1994 yyextra->defText += *yytext;
1995 yyextra->defLitText += *yytext;
1998 yyextra->defText += *yytext;
1999 yyextra->defLitText += *yytext;
2002 TRACE(
"End of include file");
2004 if (yyextra->includeStack.empty())
2006 TRACE(
"Terminating scanner");
2011 QCString toFileName = yyextra->fileName;
2012 const std::unique_ptr<FileState> &fs=yyextra->includeStack.back();
2014 YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
2015 yy_switch_to_buffer( fs->bufState, yyscanner );
2016 yy_delete_buffer( oldBuf, yyscanner );
2017 yyextra->yyLineNr = fs->lineNr;
2019 yyextra->inputBuf = fs->oldFileBuf;
2020 yyextra->inputBufPos = fs->oldFileBufPos;
2021 yyextra->curlyCount = fs->curlyCount;
2023 TRACE(
"switching to {}",yyextra->fileName);
2028 lineStr.sprintf(
"# %d \"%s\" 2",yyextra->yyLineNr,
qPrint(yyextra->fileName));
2031 yyextra->includeStack.pop_back();
2054 for (
const auto &kv : yyextra->localDefines)
2056 auto pair = yyextra->contextDefines.insert(kv);
2059 yyextra->contextDefines.erase(pair.first);
2060 yyextra->contextDefines.insert(kv);
2063 yyextra->localDefines.clear();
static void print(DebugMask mask, int prio, const char *fmt,...)
static bool isFlagSet(const DebugMask mask)
const std::string & str() const
2068 if (YY_START==SkipVerbatim || YY_START == SkipCondVerbatim || YY_START==SkipCond || YY_START==IDLquote || YY_START == PragmaOnce)
2075 yyextra->lastCContext=YY_START;
2076 yyextra->commentCount=1;
2079 yyextra->isSpecialComment =
true;
2080 yyextra->lastGuardName.clear();
2084 yyextra->isSpecialComment =
false;
2086 BEGIN(SkipCComment);
2094 else if (YY_START==RulesRoundDouble)
2101 yyextra->lastCPPContext=YY_START;
2104 yyextra->isSpecialComment =
true;
2105 yyextra->lastGuardName.clear();
2109 yyextra->isSpecialComment =
false;
2111 BEGIN(SkipCPPComment);
2116 yyextra->yyLineNr++;
2119 yyextra->expectGuard =
FALSE;
2129 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2130 int bytesInBuf =
static_cast<int>(state->inputBuf->size())-state->inputBufPos;
2131 int bytesToCopy = std::min(max_size,bytesInBuf);
2132 memcpy(buf,state->inputBuf->data()+state->inputBufPos,bytesToCopy);
2133 state->inputBufPos+=bytesToCopy;
2139 yy_size_t fenceSize = 0;
2140 for (
size_t i = 0; i < leng; i++)
2142 if (txt[i] !=
' ' && txt[i] !=
'*' && txt[i] !=
'\t')
break;
2145 return leng-fenceSize;
2150 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2155 if (state->yyFileDef==
nullptr)
2161 if (state->yyFileDef && state->yyFileDef->isReference()) state->yyFileDef=
nullptr;
2166 state->isSource = section.isHeader() || section.isSource();
2171 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2172 state->levelGuard.push(
false);
2178 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2180 if (!state->levelGuard.empty())
2182 state->levelGuard.pop();
2186 warn(state->fileName,state->yyLineNr,
"More #endif's than #if's found.");
2192 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2193 if (state->levelGuard.empty())
2195 warn(state->fileName,state->yyLineNr,
"Found an #else without a preceding #if.");
2200 return state->levelGuard.top();
2206 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2207 state->levelGuard.top()=value;
2213 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2214 alreadyProcessed =
FALSE;
2215 std::unique_ptr<FileState> fs;
2226 if (state->curlyCount==0)
2231 alreadyProcessed =
TRUE;
2238 alreadyProcessed = std::any_of(
2239 state->includeStack.begin(),
2240 state->includeStack.end(),
2241 [absName](
const std::unique_ptr<FileState> &lfs)
2242 { return lfs->fileName==absName; }
2245 if (alreadyProcessed)
2252 fs = std::make_unique<FileState>();
2260 fs->oldFileBuf = state->inputBuf;
2261 fs->oldFileBufPos = state->inputBufPos;
2269 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2280 else if (alreadyProcessed)
2285 if (localInclude && !state->fileName.isEmpty())
2287 FileInfo fi(state->fileName.str());
2298 else if (alreadyProcessed)
2304 if (state->pathList.empty())
2308 for (
auto path : state->pathList)
2310 std::string absName = (path+
"/"+fileName).str();
2320 else if (alreadyProcessed)
2353 if (i>=0 && s[i]==
'*')
2356 while (i>0 && !(s[i-1]==
'/' && s[i]==
'*')) i--;
2363 return ((s[i+1]==
'*' || s[i+1]==
'!') && s[i+2]==
'<') ? &s[i-1] :
"";
2395 bool inString=
FALSE;
2400 if (!inString && !inChar)
2402 while (i<s.
length() && !inString && !inChar)
2423 while (i<s.
length() && inChar)
2444 while (i<s.
length() && inString)
2473 std::string e = expr.
str();
2474 static const reg::Ex r(R
"(\s*##\s*)");
2483 const auto &match = *it;
2484 size_t n = match.position();
2485 size_t l = match.length();
2487 if (n+l+1<e.length() && e[
static_cast<int>(n+l)]==
'@' && expr[
static_cast<int>(n+l+1)]==
'-')
2494 e=e.substr(0,n)+e.substr(n+l);
2495 int k=
static_cast<int>(n)-1;
2496 while (k>=0 &&
isId(e[k])) k--;
2497 if (k>0 && e[k]==
'-' && e[k-1]==
'@')
2500 e=e.substr(0,k-1)+e.substr(k+1);
2518 struct yyguts_t * yyg = (
struct yyguts_t*)yyscanner;
2526 while ((cc=
getNextChar(yyscanner,expr,rest,pos))!=EOF && cc!=0)
2528 if (cc==
'\\') arg+=(char)cc,cc=
getNextChar(yyscanner,expr,rest,pos);
2529 else if (cc==
term)
return;
2535 int &cc, uint32_t &j,
int &len)
2537 bool changed =
false;
2542 while ((cc=
getCurrentChar(yyscanner,expr,rest,j))!=EOF && cc!=
'\n' && isspace(cc))
2550 int prevChar =
'\0';
2552 if ((cc=
getCurrentChar(yyscanner,expr,rest,j))!=EOF && cc ==
'*')
2554 while ((cc=
getNextChar(yyscanner,expr,rest,j))!=EOF && cc!=0)
2556 if (cc ==
'/' && prevChar ==
'*')
break;
2559 if (cc != EOF) changed =
true;
2592 std::map<std::string,std::string> argTable;
2600 while ((cc=
getNextChar(yyscanner,expr,rest,j))!=EOF && cc!=0)
2608 while (!done && (argCount<def->nargs || def->
varArgs) &&
2609 ((cc=
getNextChar(yyscanner,expr,rest,j))!=EOF && cc!=0)
2618 while ((cc=
getNextChar(yyscanner,expr,rest,j))!=EOF && cc!=0)
2622 if (c==
'\'' || c==
'\"')
2642 else if (c==
')' || c==
',')
2652 argKey.
sprintf(
"@%d",argCount++);
2674 if ((cc=
getNextChar(yyscanner,expr,rest,j))==EOF || cc==0)
break;
2691 if ((cc=
getNextChar(yyscanner,expr,rest,j))==EOF || cc==0)
break;
2699 char prevChar =
'\0';
2703 while ((cc=
getNextChar(yyscanner,expr,rest,j))!=EOF && cc!=0)
2707 if (c ==
'/' && prevChar ==
'*')
break;
2720 if (argCount==def->
nargs ||
2729 bool inString=
FALSE;
2739 else if (d.
at(k+1)==
'-')
2750 if (l>=0 && d.
at(l)==
'"') l--;
2751 while (l>=0 && d.
at(l)==
' ') l--;
2752 if (l>0 && d.
at(l)==
'#' && d.
at(l-1)==
'#') hash=
TRUE;
2755 while (k<d.
length() && d.
at(k)>=
'0' && d.
at(k)<=
'9') key+=d.
at(k++);
2760 if (l<(
int)d.
length() && d.
at(l)==
'"') l++;
2761 while (l<(
int)d.
length() && d.
at(l)==
' ') l++;
2762 if (l<(
int)d.
length()-1 && d.
at(l)==
'#' && d.
at(l+1)==
'#') hash=
TRUE;
2765 auto it = argTable.find(key.
str());
2766 if (it!=argTable.end())
2768 QCString substArg = it->second.c_str();
2786 if (hash && substArg.
isEmpty())
2797 if (!inString && d.
at(k)==
'\"')
2801 else if (k>2 && inString && d.
at(k)==
'\"' && (d.
at(k-1)!=
'\\' || d.
at(k-2)==
'\\'))
2825 while (p<(
int)expr.
length())
2827 char c=expr.
at(p++);
2832 else if (isalpha(c) || c==
'_')
2842 if (p<(
int)expr.
length()) c=expr.
at(p);
2843 while (p<(
int)expr.
length() && (c!=
'"' || (pc==
'\\' && ppc!=
'\\')))
2851 if (p<(
int)expr.
length()) ++p;
2857 if (p<(
int)expr.
length())
2863 while (p<(
int)expr.
length() && !(pc==
'*' && c==
'/'))
2876#define MAX_EXPANSION_DEPTH 50
2880 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2881 if (!state->nospaces)
2884 char ccPrev = pos==0 || (int)expr.
length()<pos ? state->prevChar : expr.
at(pos-1);
2885 QCString leftSpace = ccPrev!=
':' && ccPrev!=
' ' ?
" " :
"";
2890 uint32_t j=(uint32_t)resultExpr.
length();
2891 while ((ccNext=
getNextChar(yyscanner,resultExpr,
nullptr,j))!=EOF && ccNext==
' ') { }
2892 if (ccNext != EOF)
unputChar(yyscanner,resultExpr,
nullptr,j,(
char)ccNext);
2896 ccNext=restExpr.
at(0);
2899 QCString rightSpace = ccNext!=
':' && ccNext!=
' ' ?
" " :
"";
2902 resultExpr=leftSpace+resultExpr+rightSpace;
2912 struct yyguts_t * yyg = (
struct yyguts_t*)yyscanner;
2913 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
2920 if (state->expanded.find(expr.
str())!=state->expanded.end() &&
2928 state->expanded.insert(expr.
str());
2932 bool definedTest=
FALSE;
2933 int i=pos, l=0, p=0, len=0;
2938 bool replaced=
FALSE;
2939 macroName=expr.
mid(p,l);
2941 if (p<2 || !(expr.
at(p-2)==
'@' && expr.
at(p-1)==
'-'))
2943 if (state->expandedDict.find(macroName.
str())==state->expandedDict.end())
2948 if (yyextra->expandOnlyPredef && def && !def->
isPredefined) def=
nullptr;
2949 if (macroName==
"defined")
2954 else if (definedTest)
2956 if (def) expMacro =
" 1 ";
else expMacro =
" 0 ";
2961 else if (def && def->
nargs==-1)
2970 else if (def && def->
nargs>=0)
2987 bool expanded=
false;
2990 state->expandedDict.emplace(
toStdString(macroName),def);
2992 state->expandedDict.erase(
toStdString(macroName));
3001 expr=expr.
left(p)+resultExpr+restExpr;
3057 if (inputStr==
nullptr)
return inputStr;
3058 char term = *inputStr;
3059 if (
term!=
'\'' &&
term!=
'"')
return inputStr;
3064 while ((c=*inputStr))
3093 static const std::vector<std::string> signs = {
"signed",
"unsigned" };
3094 struct TypeInfo { std::string name;
size_t size; };
3095 static const std::vector<TypeInfo>
types = {
3096 {
"short int",
sizeof(
short int) },
3097 {
"long long int",
sizeof(
long long int) },
3098 {
"long int",
sizeof(
long int) },
3099 {
"long long",
sizeof(
long long) },
3100 {
"long double",
sizeof(
long double) },
3101 {
"int",
sizeof(int) },
3102 {
"short",
sizeof(short) },
3103 {
"bool",
sizeof(bool) },
3104 {
"long",
sizeof(long) },
3105 {
"char",
sizeof(char) },
3106 {
"float",
sizeof(float) },
3107 {
"double",
sizeof(double) },
3113 auto process_cast_or_sizeof = [](
const char *p) -> std::pair<const char *,size_t>
3116 while (*q==
' ' || *q==
'\t') q++;
3118 size_t size =
sizeof(int);
3119 for (
const auto &sgn : signs)
3121 if (
qstrncmp(q,sgn.c_str(),sgn.length())==0) { q+=sgn.length();
found=
true; }
3123 if (!
found || *q==
' ' || *q==
'\t' || *q==
')')
3125 while (*q==
' ' || *q==
'\t') q++;
3126 for (
const auto &t :
types)
3128 if (
qstrncmp(q,t.name.c_str(),t.name.length())==0)
3130 q += t.name.length();
3135 while (*q==
' ' || *q==
'\t') q++;
3136 if (*q==
')')
return std::make_pair(++q,size);
3138 return std::make_pair(
nullptr,0);
3143 const char *p=s.
data();
3153 const char *q = process_cast_or_sizeof(p+1).first;
3161 else if (c==
's' &&
qstrncmp(p,
"sizeof",6)==0)
3163 const char *q = p+6;
3164 while (*q==
' ' || *q==
'\t') q++;
3167 auto r = process_cast_or_sizeof(q+1);
3184 else if (*(p+1)==
'E')
3190 else if (isdigit(c))
3200 else if (c==
'd' && !inNum)
3211 while ((c=*p) &&
isId(c)) p++;
3214 else if ((isalpha(c) || c==
'_') && !inNum)
3218 while ((c=*p) &&
isId(c)) p++;
3219 while ((c=*p) && isspace((uint8_t)c)) p++;
3226 if (c==
'(') count++;
3230 if (count==0)
break;
3238 while (*p && !(pc==
'*' && c==
'/'))
3255 while (*p && !(pc==
'*' && c==
'/'))
3272 char lc=(char)tolower(c);
3289 const char *p=s.
data();
3314 while (*p && !(pc==
'*' && c==
'/'))
3316 if (*p==
'@' && *(p+1)==
'@')
3323 if (*p) result+=c,p++;
3350 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3354 state->expanded.clear();
3360 return state->constExpParser.parse(state->fileName.data(),state->yyLineNr,e.
str(),ee.
str());
3369 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
3370 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3371 state->prevChar = yyscanner->yytext_r > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ? *(yyscanner->yytext_r-1) : 0;
3373 state->expanded.
clear();
3383 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3385 def.
name = state->defName;
3387 def.
nargs = state->defArgs;
3389 def.
fileDef = state->yyFileDef;
3390 def.
lineNr = state->yyLineNr-state->yyMLines;
3392 def.
varArgs = state->defVarArgs;
3402 auto it = state->localDefines.find(def.
name.
str());
3403 if (it!=state->localDefines.end())
3405 state->localDefines.erase(it);
3407 state->localDefines.emplace(def.
name.
str(),def);
3412 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3413 if (state->skip)
return;
3418 define.
lineNr = state->yyLineNr - state->yyMLines;
3420 define.
name = state->defName;
3421 define.
args = state->defArgsStr;
3422 define.
fileDef = state->inputFileDef;
3424 QCString litText = state->defLitText;
3425 int l=litText.
find(
'\n');
3435 const char *p=litText.
data()+k;
3437 while ((c=*p++) && (c==
' ' || c==
'\t')) k++;
3441 if (litTextStripped.
contains(
'\n')>=1)
3450 state->macroDefinitions.push_back(define);
3456 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3457 if (state->includeStack.empty() || state->curlyCount>0) (*state->outputBuf)+=c;
3462 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3463 if (state->includeStack.empty() || state->curlyCount>0) (*state->outputBuf)+=std::string_view(a,len);
3468 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3469 if (state->includeStack.empty() || state->curlyCount>0) (*state->outputBuf)+=a.
str();
3491 struct yyguts_t * yyg = (
struct yyguts_t*)yyscanner;
3492 if (!yyextra->defContinue)
return;
3493 for (
int i=0; i< (int)yyleng; i++)
3495 if (yytext[i] ==
'\t')
3496 yyextra->defExtraSpacing+=
'\t';
3498 yyextra->defExtraSpacing+=
' ';
3504 struct yyguts_t * yyg = (
struct yyguts_t*)yyscanner;
3505 yyextra->fenceSize=0;
3507 if (yytext[1]==
'f' && ((c=yytext[2])==
'[' || c==
'{' || c==
'(' || c==
'$'))
3511 case '[': yyextra->blockName=
"]";
break;
3512 case '{': yyextra->blockName=
"}";
break;
3513 case '(': yyextra->blockName=
")";
break;
3514 case '$': yyextra->blockName=
"$";
break;
3517 yyextra->blockName=yyextra->blockName.stripWhiteSpace();
3524 yyextra->blockName=
"uml";
3528 int i = bn.
find(
'{');
3530 yyextra->blockName=bn;
3538 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3543 (inc.
at(i)==
' ' || inc.
at(i)==
'"' || inc.
at(i)==
'<')
3548 bool localInclude = s>0 && inc.
at(s-1)==
'"';
3551 while (i<inc.
length() && inc.
at(i)!=
'"' && inc.
at(i)!=
'>') i++;
3553 if (s<inc.
length() && i>s)
3563 QCString oldFileName = state->fileName;
3564 FileDef *oldFileDef = state->yyFileDef;
3565 int oldLineNr = state->yyLineNr;
3571 std::unique_ptr<FileState> fs;
3572 bool alreadyProcessed =
FALSE;
3574 fs=
findFile(yyscanner,absIncFileName,localInclude,alreadyProcessed);
3585 for (i=0;i<state->includeStack.size();i++)
3592 if (state->includeStack.empty() && oldFileDef)
3594 PreIncludeInfo *ii = state->includeRelations.find(absIncFileName);
3599 state->includeRelations.add(
3602 ambig ?
nullptr : incFd,
3610 struct yyguts_t * yyg = (
struct yyguts_t*)yyscanner;
3611 fs->bufState = YY_CURRENT_BUFFER;
3612 fs->lineNr = oldLineNr;
3613 fs->fileName = oldFileName;
3614 fs->curlyCount = state->curlyCount;
3616 fs->lexRulesPart = state->lexRulesPart;
3617 state->lexRulesPart =
false;
3620 state->includeStack.push_back(std::move(fs));
3630 state->expectGuard=
TRUE;
3631 state->inputBuf = &fs_ptr->
fileBuf;
3632 state->inputBufPos=0;
3633 yy_switch_to_buffer(yy_create_buffer(0,
YY_BUF_SIZE, yyscanner),yyscanner);
3637 if (alreadyProcessed)
3645 if (state->includeStack.empty() && oldFileDef)
3647 PreIncludeInfo *ii = state->includeRelations.find(absIncFileName);
3652 ii = state->includeRelations.add(absIncFileName,
3654 ambig ?
nullptr : incFd,
3664 for (i=0;i<state->includeStack.size();i++)
3668 if (alreadyProcessed)
3678 if (localInclude && !state->includeStack.empty() && state->curlyCount>0 && !alreadyProcessed)
3680 warn(state->fileName,state->yyLineNr,
"include file %s not found, perhaps you forgot to add its directory to INCLUDE_PATH?",
qPrint(incFileName));
3690 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3693 bool expResult = prs.
parse(state->fileName.data(),state->yyLineNr,sectId.
data());
3694 state->condStack.emplace(std::make_unique<preYY_CondCtx>(state->fileName,state->yyLineNr,sectId,state->skip));
3704 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3705 if (state->condStack.empty())
3707 warn(state->fileName,state->yyLineNr,
"the \\endcond does not have a corresponding \\cond in this file");
3712 const std::unique_ptr<preYY_CondCtx> &ctx = state->condStack.top();
3713 state->skip=ctx->skip;
3714 state->condStack.pop();
3721 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3722 while (!state->condStack.empty())
3724 state->condStack.pop();
3735 const char *p=text.
data();
3738 if (c==
'@') result+=
"@@";
else result+=c;
3748 case '=':
return '#';
3749 case '/':
return '\\';
3750 case '\'':
return '^';
3751 case '(':
return '[';
3752 case ')':
return ']';
3753 case '!':
return '|';
3754 case '<':
return '{';
3755 case '>':
return '}';
3756 case '-':
return '~';
3770 return expr.
at(pos++);
3772 else if (rest && !rest->
isEmpty())
3781 int cc=yyinput(yyscanner);
3793 return expr.
at(pos);
3795 else if (rest && !rest->
isEmpty())
3803 int cc=yyinput(yyscanner);
3820 char cs[2];cs[0]=c;cs[1]=
'\0';
3836 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3839 auto findDefine = [&undef,&name](
DefineMap &map)
3842 auto it = map.find(name.
str());
3855 Define *def = findDefine(state->localDefines);
3856 if (def==
nullptr && !undef)
3858 def = findDefine(state->contextDefines);
3865 YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
3869 for (
const auto &ds : predefList)
3871 size_t i_equals=ds.find(
'=');
3872 size_t i_obrace=ds.find(
'(');
3873 size_t i_cbrace=ds.find(
')');
3874 bool nonRecursive = i_equals!=std::string::npos && i_equals>0 && ds[i_equals-1]==
':';
3876 if ((i_obrace==0) || (i_equals==0) || (i_equals==1 && ds[i_equals-1]==
':'))
3881 if (i_obrace<i_equals && i_cbrace<i_equals &&
3882 i_obrace!=std::string::npos && i_cbrace!=std::string::npos &&
3886 static const reg::Ex reId(R
"(\a\w*)");
3887 std::map<std::string,int> argMap;
3888 std::string args = ds.substr(i_obrace+1,i_cbrace-i_obrace-1);
3889 bool hasVarArgs = args.find(
"...")!=std::string::npos;
3895 for (; arg_it!=arg_end; ++arg_it)
3897 argMap.emplace(arg_it->
str(),count++);
3901 argMap.emplace(
"__VA_ARGS__",count++);
3905 std::string definition;
3906 std::string in=ds.substr(i_equals+1);
3912 for (; re_it!=re_end; ++re_it)
3914 const auto &match = *re_it;
3915 size_t pi = match.position();
3916 size_t l = match.length();
3917 if (pi>i) definition+=in.substr(i,pi-i);
3919 auto it = argMap.find(match.str());
3920 if (it!=argMap.end())
3922 int argIndex = it->second;
3924 marker.
sprintf(
" @%d ",argIndex);
3925 definition+=marker.
str();
3929 definition+=match.str();
3933 definition+=in.substr(i);
3936 std::string dname = ds.substr(0,i_obrace);
3945 def.
fileDef = state->yyFileDef;
3948 state->contextDefines.emplace(def.
name.
str(),def);
3954 else if (!ds.empty())
3958 if (i_equals==std::string::npos)
3965 int ine=
static_cast<int>(i_equals) - (nonRecursive ? 1 : 0);
3966 def.
name = ds.substr(0,ine);
3974 def.
fileDef = state->yyFileDef;
3976 state->contextDefines.emplace(def.
name.
str(),def);
3992 YY_EXTRA_TYPE state = preYYget_extra(
p->yyscanner);
3993 FileInfo fi(dir.
str());
3999 preYYlex_init_extra(&
p->state,&
p->yyscanner);
4005 preYYlex_destroy(
p->yyscanner);
4012 YY_EXTRA_TYPE state = preYYget_extra(
p->yyscanner);
4013 struct yyguts_t *yyg = (
struct yyguts_t*)
p->yyscanner;
4026 state->curlyCount=0;
4027 state->lexRulesPart=
false;
4028 state->nospaces=
FALSE;
4029 state->inputBuf=&input;
4030 state->inputBufPos=0;
4031 state->outputBuf=&output;
4032 state->includeStack.clear();
4033 state->expandedDict.clear();
4034 state->contextDefines.clear();
4035 state->pragmaSet.clear();
4036 while (!state->condStack.empty()) state->condStack.pop();
4040 state->inputFileDef = state->yyFileDef;
4045 state->yyLineNr = 1;
4051 state->expectGuard =
guessSection(fileName).isHeader();
4052 state->guardName.clear();
4053 state->lastGuardName.clear();
4054 state->guardExpr.clear();
4056 preYYlex(yyscanner);
4058 while (!state->condStack.empty())
4060 const std::unique_ptr<preYY_CondCtx> &ctx = state->condStack.top();
4061 QCString sectionInfo =
" ";
4062 if (ctx->sectionId!=
" ") sectionInfo.
sprintf(
" with label '%s' ",
qPrint(ctx->sectionId.stripWhiteSpace()));
4063 warn(ctx->fileName,ctx->lineNr,
"Conditional section%sdoes not have "
4064 "a corresponding \\endcond command within this file.",
qPrint(sectionInfo));
4065 state->condStack.pop();
4074 std::string contents;
4082 bool startOfLine =
true;
4083 size_t content_size = output.size() +
4086 contents.reserve(content_size);
4088 while (pos<output.size())
4093 snprintf(lineNrStr,15,
"%05d ",line++);
4094 contents+=lineNrStr;
4096 contents += output[pos];
4097 startOfLine = output[pos]==
'\n';
4102 if (!contents.empty() && contents[contents.length()-1]!=
'\n')
4107 if (yyextra->contextDefines.size()>0)
4111 for (
auto &kv : yyextra->contextDefines)
4115 for (
auto &kv : yyextra->localDefines)
4129 for (
const auto &inc : state->includeRelations)
4131 auto toKind = [](
bool local,
bool imported) ->
IncludeKind
4147 if (inc->fromFileDef)
4149 inc->fromFileDef->addIncludeDependency(inc->toFileDef,inc->includeName,toKind(inc->local,inc->imported));
4151 if (inc->toFileDef && inc->fromFileDef)
4153 inc->toFileDef->addIncludedByDependency(inc->fromFileDef,inc->fromFileDef->docName(),toKind(inc->local,inc->imported));
Copyright (C) 1997-2015 by Dimitri van Heesch.
bool parse(const QCString &fileName, int lineNr, const QCString &expr)
Copyright (C) 1997-2015 by Dimitri van Heesch.
static StringUnorderedSet expandAsDefinedSet
static FileNameLinkedMap * inputNameLinkedMap
static DefinesPerFileList macroDefinitions
static FileNameLinkedMap * includeNameLinkedMap
Wrapper class for the Entry type.
A model of a file symbol.
virtual QCString absFilePath() const =0
Minimal replacement for QFileInfo.
std::string dirPath(bool absPath=true) const
std::string absFilePath() const
void processFile(const QCString &fileName, const std::string &input, std::string &output)
void addSearchDir(const QCString &dir)
std::unique_ptr< Private > p
int find(char c, int index=0, bool cs=TRUE) const
QCString & prepend(const char *s)
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
bool endsWith(const char *s) const
char & at(size_t i)
Returns a reference to the character at index i.
bool isEmpty() const
Returns TRUE iff the string is empty.
QCString right(size_t len) const
QCString & sprintf(const char *format,...)
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Class representing a regular expression.
Iterator class to iterator through matches.
std::string str() const
Return a string representing the matching part.
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
#define Config_getList(name)
static FILE * findFile(const QCString &fileName)
DirIterator end(const DirIterator &) noexcept
#define AUTO_TRACE_ADD(...)
static const char types[][NUM_HTML_LIST_TYPES]
bool isAbsolutePath(const QCString &fileName)
static QCString stringize(const QCString &s)
static int getCurrentChar(yyscan_t yyscanner, const QCString &expr, QCString *rest, uint32_t pos)
static bool expandExpression(yyscan_t yyscanner, QCString &expr, QCString *rest, int pos, int level)
#define MAX_EXPANSION_DEPTH
static int getNextChar(yyscan_t yyscanner, const QCString &expr, QCString *rest, uint32_t &pos)
static QCString removeIdsAndMarkers(const QCString &s)
static void initPredefined(yyscan_t yyscanner, const QCString &fileName)
static void addSeparatorsIfNeeded(yyscan_t yyscanner, const QCString &expr, QCString &resultExpr, QCString &restExpr, int pos)
static int getNextId(const QCString &expr, int p, int *l)
static void returnCharToStream(yyscan_t yyscanner, char c)
static void addTillEndOfString(yyscan_t yyscanner, const QCString &expr, QCString *rest, uint32_t &pos, char term, QCString &arg)
static void forceEndCondSection(yyscan_t yyscanner)
static std::unique_ptr< FileState > checkAndOpenFile(yyscan_t yyscanner, const QCString &fileName, bool &alreadyProcessed)
static const char * processUntilMatchingTerminator(const char *inputStr, QCString &result)
Process string or character literal.
static void unputChar(yyscan_t yyscanner, const QCString &expr, QCString *rest, uint32_t &pos, char c)
static void processConcatOperators(QCString &expr)
static QCString removeMarkers(const QCString &s)
static bool replaceFunctionMacro(yyscan_t yyscanner, const QCString &expr, QCString *rest, int pos, int &len, const Define *def, QCString &result, int level)
static void skipCommentMacroName(yyscan_t yyscanner, const QCString &expr, QCString *rest, int &cc, uint32_t &j, int &len)
int qstrncmp(const char *str1, const char *str2, size_t len)
bool readInputFile(const QCString &fileName, std::string &contents, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
bool patternMatch(const FileInfo &fi, const StringVector &patList)
QCString determineAbsoluteIncludeName(const QCString &curFile, const QCString &incFileName)
EntryType guessSection(const QCString &name)
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)