17 #define YY_BUF_SIZE 10*1024*1024
20%option never-interactive
21%option prefix="commentcnvYY"
23%option extra-type="struct commentcnvYY_state *"
27#define YY_TYPEDEF_YY_SCANNER_T
57#define YY_NO_UNISTD_H 1
95 const std::string *
inBuf;
154static void replaceAliases(
yyscan_t yyscanner,std::string_view s,
bool replaceCppComment=
false,
bool replaceCComment=
false);
163#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
166static inline const char *
getLexerFILE() {
return __FILE__;}
This is an alternative implementation of QCString.
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
static const char * stateToString(int state)
static const char * getLexerFILE()
Token literal values and constants.
Some helper functions for std::string.
A bunch of utility functions.
171MAILADDR ("mailto:")?[a-z_A-Z0-9\x80-\xff.+-]+"@"[a-z_A-Z0-9\x80-\xff-]+("."[a-z_A-Z0-9\x80-\xff\-]+)+[a-z_A-Z0-9\x80-\xff\-]+
198DECIMAL_INTEGER [1-9][0-9']*[0-9]?[uU]?[lL]?[lL]?
199HEXADECIMAL_INTEGER "0"[xX][0-9a-zA-Z']+[0-9a-zA-Z]?
200OCTAL_INTEGER "0"[0-7][0-7']+[0-7]?
201BINARY_INTEGER "0"[bB][01][01']*[01]?
202INTEGER_NUMBER {DECIMAL_INTEGER}|{HEXADECIMAL_INTEGER}|{OCTAL_INTEGER}|{BINARY_INTEGER}
206DIGIT_SEQ [0-9][0-9']*[0-9]?
207FRAC_CONST {DIGIT_SEQ}"."|{DIGIT_SEQ}?"."{DIGIT_SEQ}
208FP_EXP [eE][+-]?{DIGIT_SEQ}
209DEC_FP1 {FRAC_CONST}{FP_EXP}?{FP_SUF}?
210DEC_FP2 {DIGIT_SEQ}{FP_EXP}{FP_SUF}
212HEX_DIGIT_SEQ [0-9a-fA-F][0-9a-fA-F']*[0-9a-fA-F]?
213HEX_FRAC_CONST {HEX_DIGIT_SEQ}"."|{HEX_DIGIT_SEQ}?"."{HEX_DIGIT_SEQ}
214BIN_EXP [pP][+-]?{DIGIT_SEQ}
215HEX_FP1 "0"[xX]{HEX_FRAC_CONST}{BIN_EXP}{FP_SUF}?
216HEX_FP2 "0"[xX]{HEX_DIGIT_SEQ}{BIN_EXP}{FP_SUF}?
218FLOAT_DECIMAL {DEC_FP1}|{DEC_FP2}
219FLOAT_HEXADECIMAL {HEX_FP1}|{HEX_FP2}
220FLOAT_NUMBER {FLOAT_DECIMAL}|{FLOAT_HEXADECIMAL}
221NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
223RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
224RAWEND ")"[^ \t\(\)\\]{0,16}\"
226FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@]
227FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@]
228FILECHARS {FILEICHAR}*{FILEECHAR}+
229HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}*
230VFILEMASK {FILECHARS}("."{FILECHARS})*
231FILEMASK {VFILEMASK}|{HFILEMASK}
259 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
263 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
267<Scan>[^"'!\/\n\\#,\-=; \t@$]* {
275 if (yyextra->lang!=SrcLangExt::Python)
281 yyextra->pythonDocString =
TRUE;
282 yyextra->pythonDocStringChar = yytext[0];
283 yyextra->nestingCount=1;
287 yyextra->commentStack.push(yyextra->lineNr);
292 if (yyextra->lang!=SrcLangExt::Python)
302 yyextra->pythonDocString =
TRUE;
303 yyextra->pythonDocStringChar = yytext[0];
304 yyextra->nestingCount=1;
308 yyextra->commentStack.push(yyextra->lineNr);
#define Config_getBool(name)
311<Scan>{B}*![><!]/.*\n {
312 if (yyextra->lang!=SrcLangExt::Fortran)
318 yyextra->nestingCount=0;
320 yyextra->specialComment=
true;
322 yyextra->blockHeadCol=yyextra->col-2;
324 yyextra->commentStack.push(yyextra->lineNr);
327<Scan>[Cc\*][><!]/.*\n {
328 if (yyextra->lang!=SrcLangExt::Fortran)
335 if (yyextra->isFixedForm && (yyextra->col == 0))
337 yyextra->nestingCount=0;
339 yyextra->specialComment=
true;
341 yyextra->blockHeadCol=yyextra->col-1;
343 yyextra->commentStack.push(yyextra->lineNr);
352 if (yyextra->lang!=SrcLangExt::Fortran)
362 if (yyextra->lang!=SrcLangExt::Fortran)
368 if (yyextra->col == 0)
379 if (yyextra->lang!=SrcLangExt::CSharp) REJECT
381 yyextra->stringContext = YY_START;
382 BEGIN(SkipVerbString);
386 yyextra->stringContext = YY_START;
391 yyextra->charContext = YY_START;
392 if (yyextra->lang!=SrcLangExt::VHDL)
400<Scan>{CPPC}[!/]/.*\n[ \t]*{CPPC}[!/][ \t]*{CMD}"}" {
402 yyextra->inSpecialComment=
true;
403 yyextra->blockHeadCol=yyextra->col+1;
404 yyextra->insertCppCommentMarker=
true;
406 yyextra->readLineCtx=YY_START;
409<Scan>{CPPC}"!"/.*\n[ \t]*{CPPC}[\/!][^\/] |
410<Scan>({CPPC}"/"[/]*)/[^/].*\n[ \t]*{CPPC}[\/!][^\/] {
411 if (yyextra->mlBrief)
420 while (i<(
int)yyleng && yytext[i]==
'/') i++;
422 yyextra->blockHeadCol=yyextra->col+1;
423 if (yytext[2] ==
'!')
432 yyextra->inSpecialComment=
TRUE;
434 yyextra->readLineCtx=SComment;
438<Scan>{CPPC}"##Documentation"{ANYopt}/\n {
439 if (yyextra->mlBrief) REJECT;
441 yyextra->blockHeadCol=yyextra->col+1;
444 yyextra->inRoseComment=
TRUE;
447<Scan>{CPPC}[!\/]/.*\n[ \t]*{CPPC}[|\/][ \t]*{CMD}"}" {
448 yyextra->inSpecialComment=yytext[2]==
'/' || yytext[2]==
'!';
449 if (yyextra->inSpecialComment)
451 yyextra->blockHeadCol=yyextra->col+1;
454 yyextra->readLineCtx=YY_START;
457<Scan>{CPPC}[!/]/.*\n {
458 yyextra->inSpecialComment=
true;
459 yyextra->blockHeadCol=yyextra->col+1;
460 yyextra->insertCppCommentMarker=
true;
462 yyextra->readLineCtx=YY_START;
466 yyextra->inSpecialComment=
false;
468 yyextra->readLineCtx=YY_START;
475 if (yyextra->lang==SrcLangExt::Python)
479 yyextra->specialComment=(int)yyleng==3;
480 yyextra->nestingCount=1;
483 if (yyextra->specialComment)
485 yyextra->blockHeadCol=0;
492 yyextra->commentStack.push(yyextra->lineNr);
495 if (yyextra->lang!=SrcLangExt::PHP)
502 if (yyextra->lang!=SrcLangExt::Python)
508 yyextra->nestingCount=0;
510 yyextra->specialComment=(int)yyleng==2;
511 if (yyextra->specialComment)
513 yyextra->blockHeadCol=yyextra->col;
515 yyextra->commentStack.push(yyextra->lineNr);
520<Scan>"--"[^!][^\n]* {
521 if (yyextra->lang!=SrcLangExt::VHDL)
531 if (yyextra->lang!=SrcLangExt::VHDL)
537 yyextra->specialComment=
true;
538 yyextra->blockHeadCol=yyextra->col;
539 yyextra->vhdl =
TRUE;
540 yyextra->nestingCount=0;
542 yyextra->commentStack.push(yyextra->lineNr);
548 if (yyextra->lang!=SrcLangExt::Fortran)
554 yyextra->nestingCount=0;
556 yyextra->specialComment=
true;
557 yyextra->blockHeadCol=yyextra->col;
558 yyextra->commentStack.push(yyextra->lineNr);
QCString extractEndRawStringDelimiter(const char *rawEnd)
570<RawString>[^)\n]+ {
copyToOutput(yyscanner,yytext,yyleng); }
574<CComment,CNComment,ReadLine,IncludeFile>{MAILADDR} |
575<CComment,CNComment,ReadLine,IncludeFile>"<"{MAILADDR}">" {
578<CComment,IncludeFile>"{"[ \t]*"@code"/[ \t\n] {
580 yyextra->lastCommentContext = YY_START;
581 yyextra->javaBlock=1;
582 yyextra->blockName=
QCString(
"end")+&yytext[1];
583 yyextra->inVerbatim=
true;
584 yyextra->verbatimLine=yyextra->lineNr;
587<CComment,IncludeFile>"{"[ \t]*"@literal"/[ \t\n] {
589 yyextra->lastCommentContext = YY_START;
590 yyextra->javaBlock=1;
591 yyextra->blockName=
QCString(
"end")+&yytext[1];
592 yyextra->inVerbatim=
true;
593 yyextra->verbatimLine=yyextra->lineNr;
596<CComment,ReadLine,IncludeFile>{CMD}"ilinebr"[ \t]+("```"[`]*|"~~~"[~]*) {
602 yyextra->lastCommentContext = YY_START;
603 yyextra->javaBlock=0;
605 yyextra->inVerbatim=
true;
606 yyextra->verbatimLine=yyextra->lineNr;
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
QCString right(size_t len) const
609<CComment,ReadLine,IncludeFile>^[ \t]*("```"[`]*|"~~~"[~]*) {
615 yyextra->lastCommentContext = YY_START;
616 yyextra->javaBlock=0;
618 yyextra->inVerbatim=
true;
619 yyextra->verbatimLine=yyextra->lineNr;
QCString left(size_t len) const
622<CComment,ReadLine,IncludeFile>{CMD}("dot"|"code"|"msc"|"startuml")/[^a-z_A-Z0-9] {
624 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
626 yyextra->lastCommentContext = YY_START;
627 yyextra->javaBlock=0;
628 if (
qstrcmp(&yytext[1],
"startuml")==0)
630 yyextra->blockName=
"enduml";
634 yyextra->blockName=
QCString(
"end")+&yytext[1];
636 yyextra->inVerbatim=
true;
637 yyextra->verbatimLine=yyextra->lineNr;
int qstrcmp(const char *str1, const char *str2)
641<CComment,ReadLine,IncludeFile>"\\`" {
644<CComment,ReadLine,IncludeFile>"```" {
647<CComment,ReadLine,IncludeFile>"`"{1,2} {
653 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
655 yyextra->lastCommentContext = YY_START;
656 yyextra->javaBlock=0;
657 yyextra->blockName=yytext;
658 yyextra->inVerbatim=
true;
659 yyextra->verbatimLine=yyextra->lineNr;
663<CComment,ReadLine,IncludeFile>{CMD}("f$"|"f["|"f{"|"f(") {
665 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
667 yyextra->blockName=&yytext[1];
668 if (yyextra->blockName.at(1)==
'[')
670 yyextra->blockName.at(1)=
']';
672 else if (yyextra->blockName.at(1)==
'{')
674 yyextra->blockName.at(1)=
'}';
676 else if (yyextra->blockName.at(1)==
'(')
678 yyextra->blockName.at(1)=
')';
680 yyextra->lastCommentContext = YY_START;
681 yyextra->inVerbatim=
true;
682 yyextra->verbatimLine=yyextra->lineNr;
686<CComment,ReadLine,IncludeFile>"<!--!" {
687 if (yyextra->inVerbatim) REJECT;
689 yyextra->inHtmlDoxygenCommand=
true;
691<CComment,ReadLine,IncludeFile>"-->" {
692 if (yyextra->inHtmlDoxygenCommand)
694 yyextra->inHtmlDoxygenCommand=
false;
701<CComment,ReadLine,IncludeFile>"<!--" {
703 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
705 yyextra->blockName=
"-->";
706 yyextra->lastCommentContext = YY_START;
707 yyextra->inVerbatim=
true;
708 yyextra->verbatimLine=yyextra->lineNr;
712<CComment,ReadLine,IncludeFile>{CMD}("verbatim"|"iliteral"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"rtfonly"|"manonly")/[^a-z_A-Z0-9] {
714 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
716 yyextra->blockName=
QCString(
"end")+&yytext[1];
717 yyextra->lastCommentContext = YY_START;
718 yyextra->inVerbatim=
true;
719 yyextra->verbatimLine=yyextra->lineNr;
732<Verbatim>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}"|"f)") {
734 if (&yytext[1]==yyextra->blockName)
736 yyextra->inVerbatim=
false;
737 BEGIN(yyextra->lastCommentContext);
742 if (yytext==yyextra->blockName)
744 yyextra->inVerbatim=
false;
745 BEGIN(yyextra->lastCommentContext);
749 if (yyextra->javaBlock==0)
755 yyextra->javaBlock++;
760 if (yyextra->javaBlock==0)
766 yyextra->javaBlock--;
767 if (yyextra->javaBlock==0)
770 yyextra->inVerbatim=
false;
771 BEGIN(yyextra->lastCommentContext);
779<VerbatimCode>("```"[`]*|"~~~"[~]*) {
780 if (yytext[0]==
'`' && (yyextra->blockName==
"`" || yyextra->blockName==
"``"))
788 if (yytext[0]==yyextra->blockName[0])
790 yyextra->inVerbatim=
false;
791 BEGIN(yyextra->lastCommentContext);
799 yyextra->inVerbatim=
false;
800 BEGIN(yyextra->lastCommentContext);
807 yyextra->inVerbatim=
false;
808 BEGIN(yyextra->lastCommentContext);
811<VerbatimCode>"`"{1,2} {
813 if (yytext==yyextra->blockName)
815 yyextra->inVerbatim=
false;
816 BEGIN(yyextra->lastCommentContext);
819<VerbatimCode>{CMD}("enddot"|"endcode"|"endmsc"|"enduml")/("{")? {
821 if (&yytext[1]==yyextra->blockName)
823 yyextra->inVerbatim=
false;
824 BEGIN(yyextra->lastCommentContext);
827<VerbatimCode>^[ \t]*{CPPC}[\!\/]? {
828 if (!yyextra->inSpecialComment || yyextra->mlBrief)
835 while (yytext[l]==
' ' || yytext[l]==
'\t')
850<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]* {
853<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]+/\n{B}*"//" {
854 if (yyextra->lastCommentContext!=ReadLine)
863<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]+/\n {
864 if (yyextra->lastCommentContext==ReadLine)
866 yyextra->inVerbatim=
false;
867 BEGIN(yyextra->lastCommentContext);
871<Verbatim,VerbatimCode>\n {
873 if (yyextra->lastCommentContext == IncludeFile)
878<Verbatim>^[ \t]*{CPPC}[/!] {
879 if (yyextra->blockName==
"enddot" || yyextra->blockName==
"endmsc" || yyextra->blockName==
"enduml" || yyextra->blockName.at(0)==
'f')
883 while (yytext[l]==
' ' || yytext[l]==
'\t')
895<Verbatim,VerbatimCode>. {
899 if (yyextra->lang==SrcLangExt::Fortran || yyextra->lang==SrcLangExt::VHDL)
911 BEGIN(yyextra->stringContext);
919<SkipVerbString>[^"\n]+ {
922<SkipVerbString>\"\" {
925<SkipVerbString>"\"" {
927 BEGIN(yyextra->stringContext);
936 if (yyextra->lang==SrcLangExt::Fortran || yyextra->lang==SrcLangExt::VHDL)
948 BEGIN(yyextra->charContext);
957<CComment,CNComment>[^ `~<\\!@*\n{\"'\/-`]* {
960<CComment,CNComment>^{B}*"*"+[^*\/<\\@\n{\"`]* {
961 if (yyextra->lang==SrcLangExt::Markdown) REJECT;
963 if (yyextra->col>yyextra->blockHeadCol)
966 yyextra->blockHeadCol=yyextra->col;
972 if (yyextra->lang!=SrcLangExt::Python)
976 else if (yyextra->pythonDocStringChar != yytext[0])
982 yyextra->nestingCount--;
983 yyextra->pythonDocString =
FALSE;
984 yyextra->pythonDocStringChar =
'\0';
989<CComment,CNComment>\n {
992 if (yyextra->lang==SrcLangExt::Fortran)
997<CComment,CNComment>"/""/"+/"*/" {
1001<CComment,CNComment>"/"+"*" {
1002 if (yyextra->lang==SrcLangExt::Python ||
1003 yyextra->lang==SrcLangExt::Markdown)
1007 yyextra->nestingCount++;
1008 yyextra->commentStack.push(yyextra->lineNr);
1011<CComment,CNComment>^{B}*"*"+"/" |
1012<CComment,CNComment>"*"+"/" {
1013 if (yyextra->lang==SrcLangExt::Python ||
1014 yyextra->lang==SrcLangExt::Markdown)
1021 yyextra->nestingCount--;
1022 if (yyextra->nestingCount<=0)
1029 yyextra->commentStack.pop();
1034<CComment,CNComment>"\n"/[ \t]*"#" {
1035 if (yyextra->lang!=SrcLangExt::VHDL)
1043 yyextra->vhdl =
FALSE;
1053<CComment,CNComment>"\n"/[ \t]*"-" {
1054 if (yyextra->lang!=SrcLangExt::Python || yyextra->pythonDocString)
1064<CComment,CNComment>"\n"/[ \t]*[^ \t#\-] {
1065 if (yyextra->lang==SrcLangExt::Python)
1067 if (yyextra->pythonDocString)
1077 else if (yyextra->lang==SrcLangExt::VHDL)
1081 yyextra->vhdl =
FALSE;
1107<CComment,CNComment>{CMD}"~"[a-z_A-Z-]* {
1108 if (yyextra->lang!=SrcLangExt::Markdown) REJECT;
1115 warn(yyextra->fileName,yyextra->lineNr,
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
bool isEmpty() const
Returns TRUE iff the string is empty.
#define Config_getEnumAsString(name)
#define Config_isAvailableEnum(name, value)
#define warn(file, line, fmt,...)
int qstricmp(const char *s1, const char *s2)
std::string_view stripWhiteSpace(std::string_view s)
Given a string view s, returns a new, narrower view on that string, skipping over any leading or trai...
1121<CComment,CNComment>{CMD}{CMD} |
1122<CComment,CNComment>. {
1125<SkipLang>{CMD}"~"[a-zA-Z-]* {
1129 warn(yyextra->fileName,yyextra->lineNr,
1138<SkipLang>[^*@\\\n]* {
1145<SComment>^[ \t]*{CPPC}"/"{SLASHopt}/\n {
1148<SComment>\n[ \t]*{CPPC}"/"{SLASHopt}/\n {
1151<SComment>^[ \t]*{CPPC}"/"[^\/\n]/.*\n {
1153 yyextra->readLineCtx=YY_START;
1154 YY_CURRENT_BUFFER->yy_at_bol=1;
1157<SComment>\n[ \t]*{CPPC}[\/!]("<")?[ \t]*{CMD}"}".*\n {
1161 yyextra->inSpecialComment=
false;
1162 yyextra->inRoseComment=
false;
1165<SComment>\n[ \t]*{CPPC}"/"[^\\@\/\n]/.*\n {
1167 yyextra->readLineCtx=YY_START;
1168 YY_CURRENT_BUFFER->yy_at_bol=1;
1171<SComment>^[ \t]*{CPPC}"!" |
1172<SComment>^[ \t]*{CPPC}"!<"/.*\n |
1173<SComment>^[ \t]*{CPPC}"!"[^<]/.*\n {
1175 yyextra->readLineCtx=YY_START;
1176 YY_CURRENT_BUFFER->yy_at_bol=1;
1179<SComment>\n[ \t]*{CPPC}"!" |
1180<SComment>\n[ \t]*{CPPC}"!<"/.*\n |
1181<SComment>\n[ \t]*{CPPC}"!"[^<\n]/.*\n {
1183 yyextra->readLineCtx=YY_START;
1184 YY_CURRENT_BUFFER->yy_at_bol=1;
1187<SComment>^[ \t]*{CPPC}"##"/.*\n {
1188 if (!yyextra->inRoseComment)
1195 yyextra->readLineCtx=YY_START;
1196 YY_CURRENT_BUFFER->yy_at_bol=1;
1200<SComment>\n[ \t]*{CPPC}"##"/.*\n {
1201 if (!yyextra->inRoseComment)
1208 yyextra->readLineCtx=YY_START;
1209 YY_CURRENT_BUFFER->yy_at_bol=1;
1216 yyextra->inSpecialComment=
FALSE;
1217 yyextra->inRoseComment=
FALSE;
1218 yyextra->insertCppCommentMarker=
false;
1219 yyextra->readLineCtx = Scan;
1229<ReadLine,CopyLine>"*" {
1232<ReadLine,CopyLine>{RL} {
1235<ReadLine,CopyLine>{RL}/{B}{CMD}"ilinebr"{B} {
1238<ReadLine,CopyLine>{RLopt}/\n {
1240 yyextra->insertCppCommentMarker=
false;
1241 BEGIN(yyextra->readLineCtx);
1243<CComment,CNComment,ReadLine>"\<" {
1246<CComment,CNComment,ReadLine>{CMD}{CMD}[~a-z_A-Z][a-z_A-Z0-9]*[ \t]* {
1250<CComment,ReadLine,IncludeFile>{CMD}("include"{OPTS}|"includedoc"{OPTS}*) {
1251 if (!
parseIncludeOptions(yyscanner,std::string_view{yytext,
static_cast<size_t>(yyleng)})) REJECT;
1252 yyextra->includeCtx = YY_START;
1253 yyextra->firstIncludeLine =
true;
1254 yyextra->insertCommentCol = yyextra->col;
1255 if (!yyextra->insertCppCommentMarker && (yyextra->includeCtx==ReadLine || yyextra->includeCtx==IncludeFile))
1257 yyextra->insertCppCommentMarker = yyextra->mlBrief;
1262<CComment,ReadLine,IncludeFile>{CMD}("snippet"{OPTS}|"snippetdoc"{OPTS}*) {
1263 if (!
parseIncludeOptions(yyscanner,std::string_view{yytext,
static_cast<size_t>(yyleng)})) REJECT;
1264 yyextra->includeCtx = YY_START;
1265 yyextra->firstIncludeLine =
true;
1266 yyextra->insertCommentCol = yyextra->col;
1267 if (!yyextra->insertCppCommentMarker && (yyextra->includeCtx==ReadLine || yyextra->includeCtx==IncludeFile))
1269 yyextra->insertCppCommentMarker = yyextra->mlBrief;
1274<IncludeDoc,SnippetDoc>{B}*
1275<IncludeDoc>{FILEMASK}|"\""[^\n\"]+"\"" {
1279 fileName=fileName.
mid(1,fileName.
length()-2);
1287 BEGIN(yyextra->includeCtx);
size_t length() const
Returns the length of the string, not counting the 0-terminator.
1290<SnippetDoc>({FILEMASK}|"\""[^\n\"]+"\""){B}+ {
1291 yyextra->snippetFileName=yytext;
1292 yyextra->snippetFileName=yyextra->snippetFileName.stripWhiteSpace();
1293 if (yyextra->snippetFileName ==
"this") yyextra->snippetFileName=yyextra->fileName;
1294 yyextra->snippetName =
"";
1295 BEGIN(SnippetDocTag);
1297<SnippetDocTag>[^\\@\n]+ {
1298 yyextra->snippetName += yytext;
1300<SnippetDocTag>{CMD} {
1301 yyextra->snippetName += yytext;
1303<SnippetDocTag>(\n|{CMD}"ilinebr") {
1304 for (
int i=(
int)yyleng-1;i>=0;i--) unput(yytext[i]);
1305 yyextra->snippetName = yyextra->snippetName.stripWhiteSpace();
1306 QCString blockId =
"["+yyextra->snippetName+
"]";
1313 BEGIN(yyextra->includeCtx);
1317<IncludeDoc,SnippetDoc>\n {
1322 BEGIN(yyextra->includeCtx);
1324<IncludeDoc,SnippetDoc>. {
1326 BEGIN(yyextra->includeCtx);
1328<CComment,ReadLine,IncludeFile>{CMD}"cond"/[^a-z_A-Z0-9] {
1329 yyextra->condCtx = YY_START;
1332<CComment,ReadLine,IncludeFile>{CMD}"endcond"/[^a-z_A-Z0-9] {
1333 bool oldSkip=yyextra->skip;
1335 if (YY_START==CComment && oldSkip && !yyextra->skip)
1338 if (yyextra->lang!=SrcLangExt::Python &&
1339 yyextra->lang!=SrcLangExt::VHDL &&
1340 yyextra->lang!=SrcLangExt::Markdown &&
1341 yyextra->lang!=SrcLangExt::Fortran)
1343 yyextra->outBuf+=
'/';
1344 yyextra->outBuf+=
'*';
1346 if (yyextra->specialComment)
1348 yyextra->outBuf+=
'*';
1354<CondLine>[!()&| \ta-z_A-Z0-9.\-]+ {
1357<CComment,ReadLine,IncludeFile>{CMD}"cond"{WSopt}/\n {
1358 yyextra->condCtx=YY_START;
1366<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{CMD}[a-z_A-Z][a-z_A-Z0-9-]* {
1367 bool inCppComment = YY_START==ReadLine && yyextra->readLineCtx==SComment;
1368 bool inCComment = YY_START==CComment && yyextra->blockHeadCol>0;
1371<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{B}?{CMD}"ilinebr"{B}{CMD}"ialias{" {
1372 yyextra->lastBlockContext=YY_START;
1373 yyextra->blockCount=1;
1374 int extraSpace = (yytext[0]==
' '? 1:0);
1375 yyextra->aliasString=yytext+9+extraSpace;
1376 yyextra->aliasCmd=yytext+9+extraSpace;
1377 yyextra->lastEscaped=0;
1378 BEGIN( ReadAliasArgs );
1380<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{CMD}[a-z_A-Z][a-z_A-Z0-9-]*"{" {
1381 yyextra->lastBlockContext=YY_START;
1382 yyextra->blockCount=1;
1383 yyextra->aliasString=yytext;
1384 yyextra->aliasCmd=yytext;
1385 yyextra->lastEscaped=0;
1386 BEGIN( ReadAliasArgs );
1388<ReadAliasArgs>^[ \t]*"*" {
1390 if (indent>yyextra->blockHeadCol)
1392 yyextra->aliasString+=yytext;
1399<ReadAliasArgs>^[ \t]*{CPPC}[/!]/[^\n]* {
1401<ReadAliasArgs>[^{}\n\\\*]+ {
1402 yyextra->aliasString+=yytext;
1403 yyextra->lastEscaped=
FALSE;
1405<ReadAliasArgs>"\\" {
1406 if (yyextra->lastEscaped) yyextra->lastEscaped=
FALSE;
1407 else yyextra->lastEscaped=
TRUE;
1408 yyextra->aliasString+=yytext;
1410<ReadAliasArgs>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}"|"f)") {
1411 yyextra->aliasString+=yytext;
1412 if (yyextra->inVerbatim && &yytext[1]==yyextra->blockName)
1421 yyextra->inVerbatim=
false;
1422 BEGIN(yyextra->lastCommentContext);
1426 yyextra->aliasString+=yytext;
1427 yyextra->lastEscaped=
FALSE;
1428 if (yyextra->inVerbatim)
1432 BEGIN( yyextra->lastBlockContext );
1436 yyextra->aliasString+=yytext;
1437 if (!yyextra->lastEscaped) yyextra->blockCount++;
1438 yyextra->lastEscaped=
FALSE;
1441 yyextra->aliasString+=yytext;
1442 if (!yyextra->lastEscaped) yyextra->blockCount--;
1443 if (yyextra->blockCount==0)
1445 bool inCppComment = yyextra->lastBlockContext==ReadLine && yyextra->readLineCtx==SComment;
1446 bool inCComment = yyextra->lastBlockContext==CComment && yyextra->blockHeadCol>0;
1447 replaceAliases(yyscanner,yyextra->aliasString.view(),inCppComment,inCComment);
1448 BEGIN( yyextra->lastBlockContext );
1450 yyextra->lastEscaped=
FALSE;
1453 yyextra->aliasString+=yytext;
1454 yyextra->lastEscaped=
FALSE;
1461 yyextra->insertCppCommentMarker=
false;
1462 BEGIN(yyextra->readLineCtx);
1464<ReadLine>{CMD}{CMD} |
1479 if (YY_START == ReadAliasArgs)
1481 warn(yyextra->fileName,yyextra->lineNr,
1482 "Reached end of file while still searching closing '}}' of an alias argument (probable start: '{}')",
1485 else if (YY_START==Verbatim || YY_START==VerbatimCode)
1487 warn(yyextra->fileName,yyextra->lineNr,
1488 "Reached end of file while still searching closing '{}' of a verbatim block starting at line {}",
1489 yyextra->blockName,yyextra->verbatimLine);
1491 if (yyextra->includeStack.empty())
1493 yyextra->insertCppCommentMarker=
false;
1498 std::unique_ptr<commentcnv_FileState> &fs = yyextra->includeStack.back();
1499 YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
1500 yy_switch_to_buffer(fs->bufState, yyscanner);
1501 yy_delete_buffer(oldBuf, yyscanner);
1502 BEGIN(fs->oldState);
1503 yyextra->fileName = fs->oldFileName;
1504 yyextra->lineNr = fs->oldLineNr;
1505 yyextra->inBuf = fs->oldFileBuf;
1506 yyextra->inBufPos = fs->oldFileBufPos;
1507 yyextra->includeCtx = fs->oldIncludeCtx;
1509 if (fs->oldRaiseLvl!=yyextra->raiseLevel)
1511 lineStr+=
"\\iraise " + std::to_string(fs->oldRaiseLvl)+
" ";
1513 if (fs->oldRaiseLbl!=yyextra->raiseLabel)
1515 lineStr+=
"\\iprefix \"" + fs->oldRaiseLbl +
"\" ";
1517 lineStr+=
"\\ilinebr ";
1518 yyextra->raiseLevel = fs->oldRaiseLvl;
1519 yyextra->raiseLabel = fs->oldRaiseLbl;
1521 yyextra->includeStack.pop_back();
QCString & setNum(short n)
std::string_view view() const
1533 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1536 size_t optIdxStart = s.find(
'{');
1537 size_t optIdxEnd = optIdxStart!=std::string::npos ? s.find(
"}",optIdxStart+1) : std::string::npos;
1538 std::string cmdName;
1540 if (optIdxStart == std::string::npos)
1547 optList =
split(std::string{s.substr(optIdxStart+1,optIdxEnd-optIdxStart-1)},
",");
1549 bool isDoc = cmdName==
"includedoc" || cmdName==
"snippetdoc";
1550 for (
const auto &opt : optList)
1561 for (
const auto &opt : optList)
1564 size_t posEqual = locOpt.find(
'=');
1565 std::string_view option = posEqual!=std::string::npos ?
stripWhiteSpace(locOpt.substr(0,posEqual)) : locOpt;
1566 std::string_view value = posEqual!=std::string::npos ?
stripWhiteSpace(locOpt.substr(posEqual+1)) : std::string_view();
1568 if (option==std::string_view{
"doc"} && value.empty())
1571 else if (option==std::string_view{
"raise"} && !value.empty())
1573 yyextra->raiseIncrement = atoi(value.data());
1576 warn(yyextra->fileName,yyextra->lineNr,
"Raising section level from {} to {}, exceeds allowed range [0-{}], adjusting",
1581 else if (option==std::string_view{
"prefix"} && !value.empty())
1583 yyextra->raisePrefix = value;
1587 warn(yyextra->fileName,yyextra->lineNr,
"Unsupported option '{}' for {} command",option, cmdName);
1598 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1599 if (s.empty())
return;
1601 size_t len = s.length();
1604 while (p<len && (c=s[p]) && (c==
' ' || c==
'\t' || c==
'\n'))
1607 if (c==
'\n') { yyextra->lineNr++; yyextra->col=0; }
else { yyextra->col++; }
1612 while (p<len && (c=s[p]) && (c==
'/' || c==
'!' || c==
'#'))
1616 if (p<len && s[p]==
'<')
1630 yyextra->outBuf+=
' ';
1634 if (blanks>1) { yyextra->outBuf+=
'*'; yyextra->col++; }
1635 yyextra->outBuf+=
' ';
1639 yyextra->outBuf+=s.substr(p);
1640 yyextra->col+=
static_cast<int>(s.substr(p).length());
1652 else if (c==
'\t') col+=tabSize-(col%tabSize);
1661 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1662 size_t len = s.length();
1665 for (
size_t i=0;i<len;i++)
1670 yyextra->outBuf+=
'\n';
1675 yyextra->col+=tabSize-(yyextra->col%tabSize);
1686 for (
size_t i=0;i<len;i++)
1690 case '\n': yyextra->col=0;
1692 yyextra->lineNr++;
break;
1693 case '\t': yyextra->col+=tabSize-(yyextra->col%tabSize);
break;
1694 default: yyextra->col++;
break;
1707 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1708 while (!yyextra->commentStack.empty()) yyextra->commentStack.pop();
1713 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1716 bool expResult = prs.
parse(yyextra->fileName,yyextra->lineNr,sectId);
1717 yyextra->condStack.emplace(yyextra->lineNr,sectId,yyextra->skip);
1726 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1727 if (yyextra->condStack.empty())
1729 warn(yyextra->fileName,yyextra->lineNr,
"Found \\endcond command without matching \\cond");
1730 yyextra->skip=
FALSE;
1736 yyextra->condStack.pop();
1743 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1744 bool oldSkip=yyextra->skip;
1746 if ((yyextra->condCtx==CComment || yyextra->readLineCtx==SComment) &&
1747 !oldSkip && yyextra->skip)
1749 if (yyextra->lang!=SrcLangExt::Python &&
1750 yyextra->lang!=SrcLangExt::VHDL &&
1751 yyextra->lang!=SrcLangExt::Markdown &&
1752 yyextra->lang!=SrcLangExt::Fortran)
1754 yyextra->outBuf+=
'*';
1755 yyextra->outBuf+=
'/';
1759 if (yyextra->readLineCtx==SComment)
1765 BEGIN(yyextra->condCtx);
1780 int m1 = text.
find(marker);
1781 if (m1==-1)
return result;
1782 int m2 = text.
find(marker,m1+
static_cast<int>(marker.
length()));
1783 if (m2==-1)
return result;
1787 while (!found && (i=text.
find(
'\n',p))!=-1)
1789 found = (p<=m1 && m1<i);
1797 while ((i=text.
find(
'\n',p))!=-1)
1817 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1818 int startCol=yyextra->blockHeadCol;
1819 int contentCol=yyextra->insertCommentCol;
1820 int markerSpace=contentCol-startCol;
1824 if (yyextra->lang==SrcLangExt::Python)
1826 if (yyextra->pythonDocString)
1835 else if (yyextra->lang==SrcLangExt::Fortran)
1839 else if (yyextra->lang==SrcLangExt::Markdown)
1843 else if (yyextra->insertCppCommentMarker)
1858 for (;i<startCol;i++)
1862 if (
static_cast<int>(marker.length())<=markerSpace && !yyextra->firstIncludeLine)
1865 i+=
static_cast<int>(marker.length());
1867 for (;i<contentCol;i++)
1871 yyextra->firstIncludeLine =
false;
1877 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1881 if (!absFileName.
isEmpty() && fi.exists() && fi.isFile())
1885 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"included file name '{}' is ambiguous"
1888 bool alreadyProcessed = std::any_of(
1889 yyextra->includeStack.begin(),
1890 yyextra->includeStack.end(),
1891 [&absFileName,&blockId](
const auto &lfs)
1892 { return lfs->fileName==absFileName && lfs->blockId==blockId; }
1895 if (alreadyProcessed)
1899 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"recursive usage of '\\snippet{{doc}}' block with name '{}' and file name '{}', skipping",
1900 blockId,absFileName);
1904 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"recursive usage of '\\include{{doc}}' with file name '{}', skipping", absFileName);
1909 auto fs = std::make_unique<commentcnv_FileState>();
1912 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"\\{}{{doc}} file '{}' could not be read",blockId.
isEmpty()?
"include":
"snippet",absFileName);
1923 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"block marked with {} for \\snippet{{doc}} should appear twice in file {}, found it {:d} times, skipping",
1924 blockId,absFileName,count);
1930 fs->fileBuf.clear();
1933 fs->fileBuf.append(incText.
str());
1936 int oldRaiseLevel = yyextra->raiseLevel;
1937 QCString oldRaiseLabel = yyextra->raiseLabel;
1938 yyextra->raiseLevel+=yyextra->raiseIncrement;
1939 yyextra->raiseLabel+=yyextra->raisePrefix;
1940 QCString lineStr=
" \\ifile \""+absFileName+
"\" \\iline " + std::to_string(lineNr)+
" ";
1941 if (yyextra->raiseLevel>0)
1943 lineStr+=
"\\iraise " + std::to_string(yyextra->raiseLevel)+
" ";
1945 if (!yyextra->raiseLabel.isEmpty())
1947 lineStr+=
"\\iprefix \"" + yyextra->raiseLabel +
"\" ";
1949 lineStr+=
"\\ilinebr ";
1952 fs->fileName = absFileName;
1953 fs->bufState = YY_CURRENT_BUFFER;
1954 fs->oldLineNr = yyextra->lineNr;
1955 fs->oldFileName = yyextra->fileName;
1956 fs->oldState = yyextra->includeCtx;
1957 fs->oldFileBuf = yyextra->inBuf;
1958 fs->oldFileBufPos = yyextra->inBufPos;
1959 fs->oldIncludeCtx = yyextra->includeCtx;
1960 fs->oldRaiseLvl = oldRaiseLevel;
1961 fs->oldRaiseLbl = oldRaiseLabel;
1962 fs->blockId = blockId;
1963 yy_switch_to_buffer(yy_create_buffer(
nullptr,
YY_BUF_SIZE, yyscanner),yyscanner);
1964 yyextra->fileName = absFileName;
1965 yyextra->lineNr = lineNr;
1966 yyextra->inBuf = &fs->fileBuf;
1967 yyextra->inBufPos = 0;
1968 yyextra->includeStack.push_back(std::move(fs));
1974 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"\\{}{{doc}} file '{}' not found",blockId.
isEmpty()?
"include":
"snippet",inc);
1983static void replaceAliases(
yyscan_t yyscanner,std::string_view s,
bool replaceCppComment,
bool replaceCComment)
1985 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1986 if (s.empty())
return;
1987 size_t pos = s.find(
'{');
1988 std::string cmd { s.substr(1, pos!=std::string::npos ? pos-1 : s.length()-1) };
1989 auto &expAlias = yyextra->expandedAliases;
1990 if (std::find(expAlias.begin(),expAlias.end(),cmd)!=std::end(expAlias))
1995 else if (cmd==
"ialias")
1997 if (s.length()>cmd.length()+3)
1999 std::string value { s.substr(cmd.length()+2,s.length()-cmd.length()-3) };
2001 expAlias.erase(std::remove(expAlias.begin(),expAlias.end(),value),expAlias.end());
2006 if (yyextra->inVerbatim)
2009 std::string blk = yyextra->blockName.str();
2010 assert(!blk.empty());
2011 bool isNamedCommand=
isId(blk[0]);
2014 while ((i=result.find(blk,p))!=std::string::npos && !found)
2016 found = !isNamedCommand ||
2017 (i>0 && (result[i-1]==
'\\' || result[i-1]==
'@') && !
isId(result[i+blk.length()]));
2018 p = i+yyextra->blockName.length();
2030 size_t numSpaces = yyextra->blockHeadCol>1 ? yyextra->blockHeadCol-1 : 0;
2031 std::string spaces(numSpaces,
' ');
2032 if (replaceCppComment)
2036 std::string replacement =
"\n"+spaces+
"///";
2039 else if (replaceCComment)
2041 std::string replacement =
"\n"+spaces+
" * ";
2044 expAlias.push_back(cmd);
2046 result +=
" \\ilinebr \\ialias{";
2049 for (
int i=(
int)result.length()-1; i>=0; i--)
2063 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2064 int bytesInBuf =
static_cast<int>(yyextra->inBuf->size())-yyextra->inBufPos;
2065 int bytesToCopy = std::min(max_size,bytesInBuf);
2066 memcpy(buf,yyextra->inBuf->data()+yyextra->inBufPos,bytesToCopy);
2067 yyextra->inBufPos+=bytesToCopy;
2073 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2074 if (yyextra->mlBrief || yyextra->skip)
2082 if (i==yyextra->blockHeadCol || i+1==yyextra->blockHeadCol)
2089 for (i=(
int)yyleng-1;i>=0;i--) unput(yytext[i]);
2090 yyextra->inSpecialComment=
FALSE;
2102void convertCppComments(
const std::string &inBuf,std::string &outBuf,
const std::string &fn)
2107 commentcnvYYlex_init_extra(&extra,&yyscanner);
2111 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2113 yyextra->inBufPos = 0;
2116 yyextra->skip =
FALSE;
2117 yyextra->fileName = fileName;
2119 yyextra->pythonDocString =
FALSE;
2120 yyextra->lineNr = 1;
2121 yyextra->raiseLevel = 0;
2122 yyextra->raiseLabel =
"";
2123 yyextra->raiseIncrement = 0;
2124 yyextra->raisePrefix =
"";
2125 yyextra->insertCppCommentMarker=
false;
2126 yyextra->expandedAliases.clear();
2127 while (!yyextra->condStack.empty()) yyextra->condStack.pop();
2129 yyextra->vhdl =
FALSE;
2132 yyextra->isFixedForm =
FALSE;
2133 if (yyextra->lang==SrcLangExt::Fortran)
2139 if (yyextra->lang==SrcLangExt::Markdown)
2141 yyextra->nestingCount=0;
2143 yyextra->commentStack.push(yyextra->lineNr);
2150 while (!yyextra->condStack.empty())
2155 warn(yyextra->fileName,ctx.
lineNr,
"Conditional section{}does not have "
2156 "a corresponding \\endcond command within this file.",sectionInfo.data());
2157 yyextra->condStack.pop();
2159 if (yyextra->nestingCount>0 && yyextra->lang!=SrcLangExt::Markdown && yyextra->lang!=SrcLangExt::Fortran)
2163 while (!yyextra->commentStack.empty())
2165 int lineNr = yyextra->commentStack.top();
2166 if (!first) lines +=
", ";
2169 yyextra->commentStack.pop();
2171 warn(yyextra->fileName,yyextra->lineNr,
"Reached end of file while still inside a (nested) comment. "
2172 "Nesting level {} (possible line reference(s): {})",yyextra->nestingCount,lines);
2174 yyextra->nestingCount = 0;
2178 "output=[\n{}]\n-----------\n",fileName,yyextra->outBuf
2181 commentcnvYYlex_destroy(yyscanner);
2187#include "commentcnv.l.h"
std::string resolveAliasCmd(std::string_view aliasCmd)
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 bool isFlagSet(const DebugMask mask)
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
static FileNameLinkedMap * exampleNameLinkedMap
Minimal replacement for QFileInfo.
int find(char c, int index=0, bool cs=TRUE) const
const std::string & str() const
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
int contains(char c, bool cs=TRUE) const
static constexpr int MaxLevel
#define Config_getInt(name)
std::vector< std::string > StringVector
#define warn_doc_error(file, line, fmt,...)
const char * qPrint(const char *s)
std::string substituteStringView(std::string_view s, std::string_view toReplace, std::string_view replaceWith)
Returns a new string where occurrences of substring toReplace in string s are replaced by string repl...
QCString findFilePath(const QCString &file, bool &ambig)
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
int lineBlock(const QCString &text, const QCString &marker)
Returns the line number of the line following the line with the marker.
bool readInputFile(const QCString &fileName, std::string &contents, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
bool recognizeFixedForm(const QCString &contents, FortranFormat format)
QCString showFileDefMatches(const FileNameLinkedMap *fnMap, const QCString &n)
StringVector split(const std::string &s, const std::string &delimiter)
split input string s by string delimiter delimiter.
FortranFormat convertFileNameFortranParserCode(QCString fn)