19 #define YY_BUF_SIZE 10*1024*1024
22%option never-interactive
23%option prefix="commentcnvYY"
25%option extra-type="struct commentcnvYY_state *"
29#define YY_TYPEDEF_YY_SCANNER_T
59#define YY_NO_UNISTD_H 1
156static void replaceAliases(
yyscan_t yyscanner,std::string_view s,
bool replaceCppComment=
false,
bool replaceCComment=
false);
165#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
This is an alternative implementation of QCString.
Token literal values and constants.
Some helper functions for std::string.
A bunch of utility functions.
173MAILADDR ("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\-]+
200DECIMAL_INTEGER [1-9][0-9']*[0-9]?[uU]?[lL]?[lL]?
201HEXADECIMAL_INTEGER "0"[xX][0-9a-zA-Z']+[0-9a-zA-Z]?
202OCTAL_INTEGER "0"[0-7][0-7']+[0-7]?
203BINARY_INTEGER "0"[bB][01][01']*[01]?
204INTEGER_NUMBER {DECIMAL_INTEGER}|{HEXADECIMAL_INTEGER}|{OCTAL_INTEGER}|{BINARY_INTEGER}
208DIGIT_SEQ [0-9][0-9']*[0-9]?
209FRAC_CONST {DIGIT_SEQ}"."|{DIGIT_SEQ}?"."{DIGIT_SEQ}
210FP_EXP [eE][+-]?{DIGIT_SEQ}
211DEC_FP1 {FRAC_CONST}{FP_EXP}?{FP_SUF}?
212DEC_FP2 {DIGIT_SEQ}{FP_EXP}{FP_SUF}
214HEX_DIGIT_SEQ [0-9a-fA-F][0-9a-fA-F']*[0-9a-fA-F]?
215HEX_FRAC_CONST {HEX_DIGIT_SEQ}"."|{HEX_DIGIT_SEQ}?"."{HEX_DIGIT_SEQ}
216BIN_EXP [pP][+-]?{DIGIT_SEQ}
217HEX_FP1 "0"[xX]{HEX_FRAC_CONST}{BIN_EXP}{FP_SUF}?
218HEX_FP2 "0"[xX]{HEX_DIGIT_SEQ}{BIN_EXP}{FP_SUF}?
220FLOAT_DECIMAL {DEC_FP1}|{DEC_FP2}
221FLOAT_HEXADECIMAL {HEX_FP1}|{HEX_FP2}
222FLOAT_NUMBER {FLOAT_DECIMAL}|{FLOAT_HEXADECIMAL}
223NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
225RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
226RAWEND ")"[^ \t\(\)\\]{0,16}\"
228FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@]
229FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@]
230FILECHARS {FILEICHAR}*{FILEECHAR}+
231HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}*
232VFILEMASK {FILECHARS}("."{FILECHARS})*
233FILEMASK {VFILEMASK}|{HFILEMASK}
261 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
265 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
269<Scan>[^"'!\/\n\\#,\-=; \t@$]* {
277 if (yyextra->lang!=SrcLangExt::Python)
283 yyextra->pythonDocString =
TRUE;
284 yyextra->pythonDocStringChar = yytext[0];
285 yyextra->nestingCount=1;
289 yyextra->commentStack.push(yyextra->lineNr);
294 if (yyextra->lang!=SrcLangExt::Python)
304 yyextra->pythonDocString =
TRUE;
305 yyextra->pythonDocStringChar = yytext[0];
306 yyextra->nestingCount=1;
310 yyextra->commentStack.push(yyextra->lineNr);
#define Config_getBool(name)
313<Scan>{B}*![><!]/.*\n {
314 if (yyextra->lang!=SrcLangExt::Fortran)
320 yyextra->nestingCount=0;
322 yyextra->specialComment=
true;
324 yyextra->blockHeadCol=yyextra->col-2;
326 yyextra->commentStack.push(yyextra->lineNr);
329<Scan>[Cc\*][><!]/.*\n {
330 if (yyextra->lang!=SrcLangExt::Fortran)
337 if (yyextra->isFixedForm && (yyextra->col == 0))
339 yyextra->nestingCount=0;
341 yyextra->specialComment=
true;
343 yyextra->blockHeadCol=yyextra->col-1;
345 yyextra->commentStack.push(yyextra->lineNr);
354 if (yyextra->lang!=SrcLangExt::Fortran)
364 if (yyextra->lang!=SrcLangExt::Fortran)
370 if (yyextra->col == 0)
381 if (yyextra->lang!=SrcLangExt::CSharp) REJECT
383 yyextra->stringContext = YY_START;
384 BEGIN(SkipVerbString);
388 yyextra->stringContext = YY_START;
393 yyextra->charContext = YY_START;
394 if (yyextra->lang!=SrcLangExt::VHDL)
402<Scan>{CPPC}[!/]/.*\n[ \t]*{CPPC}[!/][ \t]*{CMD}"}" {
404 yyextra->inSpecialComment=
true;
405 yyextra->blockHeadCol=yyextra->col+1;
406 yyextra->insertCppCommentMarker=
true;
408 yyextra->readLineCtx=YY_START;
411<Scan>{CPPC}"!"/.*\n[ \t]*{CPPC}[\/!][^\/] |
412<Scan>({CPPC}"/"[/]*)/[^/].*\n[ \t]*{CPPC}[\/!][^\/] {
413 if (yyextra->mlBrief)
422 while (i<(
int)yyleng && yytext[i]==
'/') i++;
424 yyextra->blockHeadCol=yyextra->col+1;
425 if (yytext[2] ==
'!')
434 yyextra->inSpecialComment=
TRUE;
436 yyextra->readLineCtx=SComment;
440<Scan>{CPPC}"##Documentation"{ANYopt}/\n {
441 if (yyextra->mlBrief) REJECT;
443 yyextra->blockHeadCol=yyextra->col+1;
446 yyextra->inRoseComment=
TRUE;
449<Scan>{CPPC}[!\/]/.*\n[ \t]*{CPPC}[|\/][ \t]*{CMD}"}" {
450 yyextra->inSpecialComment=yytext[2]==
'/' || yytext[2]==
'!';
451 if (yyextra->inSpecialComment)
453 yyextra->blockHeadCol=yyextra->col+1;
456 yyextra->readLineCtx=YY_START;
459<Scan>{CPPC}[!/]/.*\n {
460 yyextra->inSpecialComment=
true;
461 yyextra->blockHeadCol=yyextra->col+1;
462 yyextra->insertCppCommentMarker=
true;
464 yyextra->readLineCtx=YY_START;
468 yyextra->inSpecialComment=
false;
470 yyextra->readLineCtx=YY_START;
477 if (yyextra->lang==SrcLangExt::Python)
481 yyextra->specialComment=(int)yyleng==3;
482 yyextra->nestingCount=1;
485 if (yyextra->specialComment)
487 yyextra->blockHeadCol=0;
494 yyextra->commentStack.push(yyextra->lineNr);
497 if (yyextra->lang!=SrcLangExt::PHP)
504 if (yyextra->lang!=SrcLangExt::Python)
510 yyextra->nestingCount=0;
512 yyextra->specialComment=(int)yyleng==2;
513 if (yyextra->specialComment)
515 yyextra->blockHeadCol=yyextra->col;
517 yyextra->commentStack.push(yyextra->lineNr);
522<Scan>"--"[^!][^\n]* {
523 if (yyextra->lang!=SrcLangExt::VHDL)
533 if (yyextra->lang!=SrcLangExt::VHDL)
539 yyextra->specialComment=
true;
540 yyextra->blockHeadCol=yyextra->col;
541 yyextra->vhdl =
TRUE;
542 yyextra->nestingCount=0;
544 yyextra->commentStack.push(yyextra->lineNr);
550 if (yyextra->lang!=SrcLangExt::Fortran)
556 yyextra->nestingCount=0;
558 yyextra->specialComment=
true;
559 yyextra->blockHeadCol=yyextra->col;
560 yyextra->commentStack.push(yyextra->lineNr);
QCString extractEndRawStringDelimiter(const char *rawEnd)
572<RawString>[^)\n]+ {
copyToOutput(yyscanner,yytext,yyleng); }
576<CComment,CNComment,ReadLine,IncludeFile>{MAILADDR} |
577<CComment,CNComment,ReadLine,IncludeFile>"<"{MAILADDR}">" {
580<CComment,IncludeFile>"{"[ \t]*"@code"/[ \t\n] {
582 yyextra->lastCommentContext = YY_START;
583 yyextra->javaBlock=1;
584 yyextra->blockName=
QCString(
"end")+&yytext[1];
585 yyextra->inVerbatim=
true;
586 yyextra->verbatimLine=yyextra->lineNr;
589<CComment,IncludeFile>"{"[ \t]*"@literal"/[ \t\n] {
591 yyextra->lastCommentContext = YY_START;
592 yyextra->javaBlock=1;
593 yyextra->blockName=
QCString(
"end")+&yytext[1];
594 yyextra->inVerbatim=
true;
595 yyextra->verbatimLine=yyextra->lineNr;
598<CComment,ReadLine,IncludeFile>{CMD}"ilinebr"[ \t]+("```"[`]*|"~~~"[~]*) {
604 yyextra->lastCommentContext = YY_START;
605 yyextra->javaBlock=0;
607 yyextra->inVerbatim=
true;
608 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
611<CComment,ReadLine,IncludeFile>^[ \t]*("```"[`]*|"~~~"[~]*) {
617 yyextra->lastCommentContext = YY_START;
618 yyextra->javaBlock=0;
620 yyextra->inVerbatim=
true;
621 yyextra->verbatimLine=yyextra->lineNr;
QCString left(size_t len) const
624<CComment,ReadLine,IncludeFile>{CMD}("dot"|"code"|"msc"|"startuml")/[^a-z_A-Z0-9] {
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)
640<CComment,ReadLine,IncludeFile>"\\`" {
643<CComment,ReadLine,IncludeFile>"```" {
646<CComment,ReadLine,IncludeFile>"`"{1,2} {
652 yyextra->lastCommentContext = YY_START;
653 yyextra->javaBlock=0;
654 yyextra->blockName=yytext;
655 yyextra->inVerbatim=
true;
656 yyextra->verbatimLine=yyextra->lineNr;
659<CComment,ReadLine,IncludeFile>{CMD}("f$"|"f["|"f{"|"f(") {
661 yyextra->blockName=&yytext[1];
662 if (yyextra->blockName.at(1)==
'[')
664 yyextra->blockName.at(1)=
']';
666 else if (yyextra->blockName.at(1)==
'{')
668 yyextra->blockName.at(1)=
'}';
670 else if (yyextra->blockName.at(1)==
'(')
672 yyextra->blockName.at(1)=
')';
674 yyextra->lastCommentContext = YY_START;
675 yyextra->inVerbatim=
true;
676 yyextra->verbatimLine=yyextra->lineNr;
679<CComment,ReadLine,IncludeFile>"<!--!" {
680 if (yyextra->inVerbatim) REJECT;
682 yyextra->inHtmlDoxygenCommand=
true;
684<CComment,ReadLine,IncludeFile>"-->" {
685 if (yyextra->inHtmlDoxygenCommand)
687 yyextra->inHtmlDoxygenCommand=
false;
694<CComment,ReadLine,IncludeFile>"<!--" {
696 yyextra->blockName=
"-->";
697 yyextra->lastCommentContext = YY_START;
698 yyextra->inVerbatim=
true;
699 yyextra->verbatimLine=yyextra->lineNr;
702<CComment,ReadLine,IncludeFile>{CMD}("verbatim"|"iliteral"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"rtfonly"|"manonly")/[^a-z_A-Z0-9] {
704 yyextra->blockName=
QCString(
"end")+&yytext[1];
705 yyextra->lastCommentContext = YY_START;
706 yyextra->inVerbatim=
true;
707 yyextra->verbatimLine=yyextra->lineNr;
719<Verbatim>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}"|"f)") {
721 if (&yytext[1]==yyextra->blockName)
723 yyextra->inVerbatim=
false;
724 BEGIN(yyextra->lastCommentContext);
729 if (yytext==yyextra->blockName)
731 yyextra->inVerbatim=
false;
732 BEGIN(yyextra->lastCommentContext);
736 if (yyextra->javaBlock==0)
742 yyextra->javaBlock++;
747 if (yyextra->javaBlock==0)
753 yyextra->javaBlock--;
754 if (yyextra->javaBlock==0)
757 yyextra->inVerbatim=
false;
758 BEGIN(yyextra->lastCommentContext);
766<VerbatimCode>("```"[`]*|"~~~"[~]*) {
767 if (yytext[0]==
'`' && (yyextra->blockName==
"`" || yyextra->blockName==
"``"))
775 if (yytext[0]==yyextra->blockName[0])
777 yyextra->inVerbatim=
false;
778 BEGIN(yyextra->lastCommentContext);
786 yyextra->inVerbatim=
false;
787 BEGIN(yyextra->lastCommentContext);
794 yyextra->inVerbatim=
false;
795 BEGIN(yyextra->lastCommentContext);
798<VerbatimCode>"`"{1,2} {
800 if (yytext==yyextra->blockName)
802 yyextra->inVerbatim=
false;
803 BEGIN(yyextra->lastCommentContext);
806<VerbatimCode>{CMD}("enddot"|"endcode"|"endmsc"|"enduml")/("{")? {
808 if (&yytext[1]==yyextra->blockName)
810 yyextra->inVerbatim=
false;
811 BEGIN(yyextra->lastCommentContext);
814<VerbatimCode>^[ \t]*{CPPC}[\!\/]? {
815 if (!yyextra->inSpecialComment || yyextra->mlBrief)
822 while (yytext[l]==
' ' || yytext[l]==
'\t')
837<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]* {
840<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]+/\n{B}*"//" {
841 if (yyextra->lastCommentContext!=ReadLine)
850<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]+/\n {
851 if (yyextra->lastCommentContext==ReadLine)
853 yyextra->inVerbatim=
false;
854 BEGIN(yyextra->lastCommentContext);
858<Verbatim,VerbatimCode>\n {
860 if (yyextra->lastCommentContext == IncludeFile)
865<Verbatim>^[ \t]*{CPPC}[/!] {
866 if (yyextra->blockName==
"enddot" || yyextra->blockName==
"endmsc" || yyextra->blockName==
"enduml" || yyextra->blockName.at(0)==
'f')
870 while (yytext[l]==
' ' || yytext[l]==
'\t')
882<Verbatim,VerbatimCode>. {
886 if (yyextra->lang==SrcLangExt::Fortran || yyextra->lang==SrcLangExt::VHDL)
898 BEGIN(yyextra->stringContext);
906<SkipVerbString>[^"\n]+ {
909<SkipVerbString>\"\" {
912<SkipVerbString>"\"" {
914 BEGIN(yyextra->stringContext);
923 if (yyextra->lang==SrcLangExt::Fortran || yyextra->lang==SrcLangExt::VHDL)
935 BEGIN(yyextra->charContext);
944<CComment,CNComment>[^ `~<\\!@*\n{\"'\/-`]* {
947<CComment,CNComment>^{B}*"*"+[^*\/<\\@\n{\"`]* {
948 if (yyextra->lang==SrcLangExt::Markdown) REJECT;
950 if (yyextra->col>yyextra->blockHeadCol)
953 yyextra->blockHeadCol=yyextra->col;
959 if (yyextra->lang!=SrcLangExt::Python)
963 else if (yyextra->pythonDocStringChar != yytext[0])
969 yyextra->nestingCount--;
970 yyextra->pythonDocString =
FALSE;
971 yyextra->pythonDocStringChar =
'\0';
976<CComment,CNComment>\n {
979 if (yyextra->lang==SrcLangExt::Fortran)
984<CComment,CNComment>"/""/"+/"*/" {
988<CComment,CNComment>"/"+"*" {
989 if (yyextra->lang==SrcLangExt::Python ||
990 yyextra->lang==SrcLangExt::Markdown)
994 yyextra->nestingCount++;
995 yyextra->commentStack.push(yyextra->lineNr);
998<CComment,CNComment>^{B}*"*"+"/" |
999<CComment,CNComment>"*"+"/" {
1000 if (yyextra->lang==SrcLangExt::Python ||
1001 yyextra->lang==SrcLangExt::Markdown)
1008 yyextra->nestingCount--;
1009 if (yyextra->nestingCount<=0)
1016 yyextra->commentStack.pop();
1021<CComment,CNComment>"\n"/[ \t]*"#" {
1022 if (yyextra->lang!=SrcLangExt::VHDL)
1030 yyextra->vhdl =
FALSE;
1040<CComment,CNComment>"\n"/[ \t]*"-" {
1041 if (yyextra->lang!=SrcLangExt::Python || yyextra->pythonDocString)
1051<CComment,CNComment>"\n"/[ \t]*[^ \t#\-] {
1052 if (yyextra->lang==SrcLangExt::Python)
1054 if (yyextra->pythonDocString)
1064 else if (yyextra->lang==SrcLangExt::VHDL)
1068 yyextra->vhdl =
FALSE;
1094<CComment,CNComment>{CMD}"~"[a-z_A-Z-]* {
1095 if (yyextra->lang!=SrcLangExt::Markdown) REJECT;
1102 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...
1108<CComment,CNComment>{CMD}{CMD} |
1109<CComment,CNComment>. {
1112<SkipLang>{CMD}"~"[a-zA-Z-]* {
1116 warn(yyextra->fileName,yyextra->lineNr,
1125<SkipLang>[^*@\\\n]* {
1132<SComment>^[ \t]*{CPPC}"/"{SLASHopt}/\n {
1135<SComment>\n[ \t]*{CPPC}"/"{SLASHopt}/\n {
1138<SComment>^[ \t]*{CPPC}"/"[^\/\n]/.*\n {
1140 yyextra->readLineCtx=YY_START;
1141 YY_CURRENT_BUFFER->yy_at_bol=1;
1144<SComment>\n[ \t]*{CPPC}[\/!]("<")?[ \t]*{CMD}"}".*\n {
1148 yyextra->inSpecialComment=
false;
1149 yyextra->inRoseComment=
false;
1152<SComment>\n[ \t]*{CPPC}"/"[^\\@\/\n]/.*\n {
1154 yyextra->readLineCtx=YY_START;
1155 YY_CURRENT_BUFFER->yy_at_bol=1;
1158<SComment>^[ \t]*{CPPC}"!" |
1159<SComment>^[ \t]*{CPPC}"!<"/.*\n |
1160<SComment>^[ \t]*{CPPC}"!"[^<]/.*\n {
1162 yyextra->readLineCtx=YY_START;
1163 YY_CURRENT_BUFFER->yy_at_bol=1;
1166<SComment>\n[ \t]*{CPPC}"!" |
1167<SComment>\n[ \t]*{CPPC}"!<"/.*\n |
1168<SComment>\n[ \t]*{CPPC}"!"[^<\n]/.*\n {
1170 yyextra->readLineCtx=YY_START;
1171 YY_CURRENT_BUFFER->yy_at_bol=1;
1174<SComment>^[ \t]*{CPPC}"##"/.*\n {
1175 if (!yyextra->inRoseComment)
1182 yyextra->readLineCtx=YY_START;
1183 YY_CURRENT_BUFFER->yy_at_bol=1;
1187<SComment>\n[ \t]*{CPPC}"##"/.*\n {
1188 if (!yyextra->inRoseComment)
1195 yyextra->readLineCtx=YY_START;
1196 YY_CURRENT_BUFFER->yy_at_bol=1;
1203 yyextra->inSpecialComment=
FALSE;
1204 yyextra->inRoseComment=
FALSE;
1205 yyextra->insertCppCommentMarker=
false;
1206 yyextra->readLineCtx = Scan;
1216<ReadLine,CopyLine>"*" {
1219<ReadLine,CopyLine>{RL} {
1222<ReadLine,CopyLine>{RL}/{B}{CMD}"ilinebr"{B} {
1225<ReadLine,CopyLine>{RLopt}/\n {
1227 yyextra->insertCppCommentMarker=
false;
1228 BEGIN(yyextra->readLineCtx);
1230<CComment,CNComment,ReadLine>"\<" {
1233<CComment,CNComment,ReadLine>{CMD}{CMD}[~a-z_A-Z][a-z_A-Z0-9]*[ \t]* {
1237<CComment,ReadLine,IncludeFile>{CMD}("include"{OPTS}|"includedoc"{OPTS}*) {
1238 if (!
parseIncludeOptions(yyscanner,std::string_view{yytext,
static_cast<size_t>(yyleng)})) REJECT;
1239 yyextra->includeCtx = YY_START;
1240 yyextra->firstIncludeLine =
true;
1241 yyextra->insertCommentCol = yyextra->col;
1242 if (!yyextra->insertCppCommentMarker && (yyextra->includeCtx==ReadLine || yyextra->includeCtx==IncludeFile))
1244 yyextra->insertCppCommentMarker = yyextra->mlBrief;
1249<CComment,ReadLine,IncludeFile>{CMD}("snippet"{OPTS}|"snippetdoc"{OPTS}*) {
1250 if (!
parseIncludeOptions(yyscanner,std::string_view{yytext,
static_cast<size_t>(yyleng)})) REJECT;
1251 yyextra->includeCtx = YY_START;
1252 yyextra->firstIncludeLine =
true;
1253 yyextra->insertCommentCol = yyextra->col;
1254 if (!yyextra->insertCppCommentMarker && (yyextra->includeCtx==ReadLine || yyextra->includeCtx==IncludeFile))
1256 yyextra->insertCppCommentMarker = yyextra->mlBrief;
1261<IncludeDoc,SnippetDoc>{B}*
1262<IncludeDoc>{FILEMASK}|"\""[^\n\"]+"\"" {
1266 fileName=fileName.
mid(1,fileName.
length()-2);
1274 BEGIN(yyextra->includeCtx);
size_t length() const
Returns the length of the string, not counting the 0-terminator.
1277<SnippetDoc>({FILEMASK}|"\""[^\n\"]+"\""){B}+ {
1278 yyextra->snippetFileName=yytext;
1279 yyextra->snippetFileName=yyextra->snippetFileName.stripWhiteSpace();
1280 if (yyextra->snippetFileName ==
"this") yyextra->snippetFileName=yyextra->fileName;
1281 yyextra->snippetName =
"";
1282 BEGIN(SnippetDocTag);
1284<SnippetDocTag>[^\\@\n]+ {
1285 yyextra->snippetName += yytext;
1287<SnippetDocTag>{CMD} {
1288 yyextra->snippetName += yytext;
1290<SnippetDocTag>(\n|{CMD}"ilinebr") {
1291 for (
int i=(
int)yyleng-1;i>=0;i--) unput(yytext[i]);
1292 yyextra->snippetName = yyextra->snippetName.stripWhiteSpace();
1293 QCString blockId =
"["+yyextra->snippetName+
"]";
1300 BEGIN(yyextra->includeCtx);
1304<IncludeDoc,SnippetDoc>\n {
1309 BEGIN(yyextra->includeCtx);
1311<IncludeDoc,SnippetDoc>. {
1313 BEGIN(yyextra->includeCtx);
1315<CComment,ReadLine,IncludeFile>{CMD}"cond"/[^a-z_A-Z0-9] {
1316 yyextra->condCtx = YY_START;
1319<CComment,ReadLine,IncludeFile>{CMD}"endcond"/[^a-z_A-Z0-9] {
1320 bool oldSkip=yyextra->skip;
1322 if (YY_START==CComment && oldSkip && !yyextra->skip)
1325 if (yyextra->lang!=SrcLangExt::Python &&
1326 yyextra->lang!=SrcLangExt::VHDL &&
1327 yyextra->lang!=SrcLangExt::Markdown &&
1328 yyextra->lang!=SrcLangExt::Fortran)
1330 yyextra->outBuf+=
'/';
1331 yyextra->outBuf+=
'*';
1333 if (yyextra->specialComment)
1335 yyextra->outBuf+=
'*';
1341<CondLine>[!()&| \ta-z_A-Z0-9.\-]+ {
1344<CComment,ReadLine,IncludeFile>{CMD}"cond"{WSopt}/\n {
1345 yyextra->condCtx=YY_START;
1353<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{CMD}[a-z_A-Z][a-z_A-Z0-9-]* {
1354 bool inCppComment = YY_START==ReadLine && yyextra->readLineCtx==SComment;
1355 bool inCComment = YY_START==CComment && yyextra->blockHeadCol>0;
1358<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{B}?{CMD}"ilinebr"{B}{CMD}"ialias{" {
1359 yyextra->lastBlockContext=YY_START;
1360 yyextra->blockCount=1;
1361 int extraSpace = (yytext[0]==
' '? 1:0);
1362 yyextra->aliasString=yytext+9+extraSpace;
1363 yyextra->aliasCmd=yytext+9+extraSpace;
1364 yyextra->lastEscaped=0;
1365 BEGIN( ReadAliasArgs );
1367<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{CMD}[a-z_A-Z][a-z_A-Z0-9-]*"{" {
1368 yyextra->lastBlockContext=YY_START;
1369 yyextra->blockCount=1;
1370 yyextra->aliasString=yytext;
1371 yyextra->aliasCmd=yytext;
1372 yyextra->lastEscaped=0;
1373 BEGIN( ReadAliasArgs );
1375<ReadAliasArgs>^[ \t]*"*" {
1377 if (indent>yyextra->blockHeadCol)
1379 yyextra->aliasString+=yytext;
1386<ReadAliasArgs>^[ \t]*{CPPC}[/!]/[^\n]* {
1388<ReadAliasArgs>[^{}\n\\\*]+ {
1389 yyextra->aliasString+=yytext;
1390 yyextra->lastEscaped=
FALSE;
1392<ReadAliasArgs>"\\" {
1393 if (yyextra->lastEscaped) yyextra->lastEscaped=
FALSE;
1394 else yyextra->lastEscaped=
TRUE;
1395 yyextra->aliasString+=yytext;
1397<ReadAliasArgs>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}"|"f)") {
1398 yyextra->aliasString+=yytext;
1399 if (yyextra->inVerbatim && &yytext[1]==yyextra->blockName)
1408 yyextra->inVerbatim=
false;
1409 BEGIN(yyextra->lastCommentContext);
1413 yyextra->aliasString+=yytext;
1414 yyextra->lastEscaped=
FALSE;
1415 if (yyextra->inVerbatim)
1419 BEGIN( yyextra->lastBlockContext );
1423 yyextra->aliasString+=yytext;
1424 if (!yyextra->lastEscaped) yyextra->blockCount++;
1425 yyextra->lastEscaped=
FALSE;
1428 yyextra->aliasString+=yytext;
1429 if (!yyextra->lastEscaped) yyextra->blockCount--;
1430 if (yyextra->blockCount==0)
1432 bool inCppComment = yyextra->lastBlockContext==ReadLine && yyextra->readLineCtx==SComment;
1433 bool inCComment = yyextra->lastBlockContext==CComment && yyextra->blockHeadCol>0;
1434 replaceAliases(yyscanner,yyextra->aliasString.view(),inCppComment,inCComment);
1435 BEGIN( yyextra->lastBlockContext );
1437 yyextra->lastEscaped=
FALSE;
1440 yyextra->aliasString+=yytext;
1441 yyextra->lastEscaped=
FALSE;
1448 yyextra->insertCppCommentMarker=
false;
1449 BEGIN(yyextra->readLineCtx);
1451<ReadLine>{CMD}{CMD} |
1466 if (YY_START == ReadAliasArgs)
1468 warn(yyextra->fileName,yyextra->lineNr,
1469 "Reached end of file while still searching closing '}}' of an alias argument (probable start: '{}')",
1472 else if (YY_START==Verbatim || YY_START==VerbatimCode)
1474 warn(yyextra->fileName,yyextra->lineNr,
1475 "Reached end of file while still searching closing '{}' of a verbatim block starting at line {}",
1476 yyextra->blockName,yyextra->verbatimLine);
1478 if (yyextra->includeStack.empty())
1480 yyextra->insertCppCommentMarker=
false;
1485 std::unique_ptr<commentcnv_FileState> &fs = yyextra->includeStack.back();
1486 YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
1487 yy_switch_to_buffer(fs->bufState, yyscanner);
1488 yy_delete_buffer(oldBuf, yyscanner);
1489 BEGIN(fs->oldState);
1490 yyextra->fileName = fs->oldFileName;
1491 yyextra->lineNr = fs->oldLineNr;
1492 yyextra->inBuf = fs->oldFileBuf;
1493 yyextra->inBufPos = fs->oldFileBufPos;
1494 yyextra->includeCtx = fs->oldIncludeCtx;
1496 if (fs->oldRaiseLvl!=yyextra->raiseLevel)
1498 lineStr+=
"\\iraise " + std::to_string(fs->oldRaiseLvl)+
" ";
1500 if (fs->oldRaiseLbl!=yyextra->raiseLabel)
1502 lineStr+=
"\\iprefix \"" + fs->oldRaiseLbl +
"\" ";
1504 lineStr+=
"\\ilinebr ";
1505 yyextra->raiseLevel = fs->oldRaiseLvl;
1506 yyextra->raiseLabel = fs->oldRaiseLbl;
1508 yyextra->includeStack.pop_back();
QCString & setNum(short n)
std::string_view view() const
1520 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1523 size_t optIdxStart = s.find(
'{');
1524 size_t optIdxEnd = optIdxStart!=std::string::npos ? s.find(
"}",optIdxStart+1) : std::string::npos;
1525 std::string cmdName;
1527 if (optIdxStart == std::string::npos)
1534 optList =
split(std::string{s.substr(optIdxStart+1,optIdxEnd-optIdxStart-1)},
",");
1536 bool isDoc = cmdName==
"includedoc" || cmdName==
"snippetdoc";
1537 for (
const auto &opt : optList)
1548 for (
const auto &opt : optList)
1551 size_t posEqual = locOpt.find(
'=');
1552 std::string_view option = posEqual!=std::string::npos ?
stripWhiteSpace(locOpt.substr(0,posEqual)) : locOpt;
1553 std::string_view value = posEqual!=std::string::npos ?
stripWhiteSpace(locOpt.substr(posEqual+1)) : std::string_view();
1555 if (option==std::string_view{
"doc"} && value.empty())
1558 else if (option==std::string_view{
"raise"} && !value.empty())
1560 yyextra->raiseIncrement = atoi(value.data());
1563 warn(yyextra->fileName,yyextra->lineNr,
"Raising section level from {} to {}, exceeds allowed range [0-{}], adjusting",
1568 else if (option==std::string_view{
"prefix"} && !value.empty())
1570 yyextra->raisePrefix = value;
1574 warn(yyextra->fileName,yyextra->lineNr,
"Unsupported option '{}' for {} command",option, cmdName);
1585 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1586 if (s.empty())
return;
1588 size_t len = s.length();
1591 while (p<len && (c=s[p]) && (c==
' ' || c==
'\t' || c==
'\n'))
1594 if (c==
'\n') { yyextra->lineNr++; yyextra->col=0; }
else { yyextra->col++; }
1599 while (p<len && (c=s[p]) && (c==
'/' || c==
'!' || c==
'#'))
1603 if (p<len && s[p]==
'<')
1617 yyextra->outBuf+=
' ';
1621 if (blanks>1) { yyextra->outBuf+=
'*'; yyextra->col++; }
1622 yyextra->outBuf+=
' ';
1626 yyextra->outBuf+=s.substr(p);
1627 yyextra->col+=s.substr(p).length();
1639 else if (c==
'\t') col+=tabSize-(col%tabSize);
1648 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1649 size_t len = s.length();
1652 for (
size_t i=0;i<len;i++)
1657 yyextra->outBuf+=
'\n';
1662 yyextra->col+=tabSize-(yyextra->col%tabSize);
1673 for (
size_t i=0;i<len;i++)
1677 case '\n': yyextra->col=0;
1679 yyextra->lineNr++;
break;
1680 case '\t': yyextra->col+=tabSize-(yyextra->col%tabSize);
break;
1681 default: yyextra->col++;
break;
1689 copyToOutput(yyscanner,std::string_view{s,(size_t)len});
1694 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1695 while (!yyextra->commentStack.empty()) yyextra->commentStack.pop();
1700 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1703 bool expResult = prs.
parse(yyextra->fileName,yyextra->lineNr,sectId);
1704 yyextra->condStack.emplace(yyextra->lineNr,sectId,yyextra->skip);
1713 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1714 if (yyextra->condStack.empty())
1716 warn(yyextra->fileName,yyextra->lineNr,
"Found \\endcond command without matching \\cond");
1717 yyextra->skip=
FALSE;
1723 yyextra->condStack.pop();
1730 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1731 bool oldSkip=yyextra->skip;
1733 if ((yyextra->condCtx==CComment || yyextra->readLineCtx==SComment) &&
1734 !oldSkip && yyextra->skip)
1736 if (yyextra->lang!=SrcLangExt::Python &&
1737 yyextra->lang!=SrcLangExt::VHDL &&
1738 yyextra->lang!=SrcLangExt::Markdown &&
1739 yyextra->lang!=SrcLangExt::Fortran)
1741 yyextra->outBuf+=
'*';
1742 yyextra->outBuf+=
'/';
1746 if (yyextra->readLineCtx==SComment)
1752 BEGIN(yyextra->condCtx);
1767 int m1 = text.
find(marker);
1768 if (m1==-1)
return result;
1769 int m2 = text.
find(marker,m1+
static_cast<int>(marker.
length()));
1770 if (m2==-1)
return result;
1774 while (!found && (i=text.
find(
'\n',p))!=-1)
1776 found = (p<=m1 && m1<i);
1784 while ((i=text.
find(
'\n',p))!=-1)
1804 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1805 int startCol=yyextra->blockHeadCol;
1806 int contentCol=yyextra->insertCommentCol;
1807 int markerSpace=contentCol-startCol;
1811 if (yyextra->lang==SrcLangExt::Python)
1813 if (yyextra->pythonDocString)
1822 else if (yyextra->lang==SrcLangExt::Fortran)
1826 else if (yyextra->lang==SrcLangExt::Markdown)
1830 else if (yyextra->insertCppCommentMarker)
1845 for (;i<startCol;i++)
1849 if (
static_cast<int>(marker.length())<=markerSpace && !yyextra->firstIncludeLine)
1854 for (;i<contentCol;i++)
1858 yyextra->firstIncludeLine =
false;
1864 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1872 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"included file name '{}' is ambiguous"
1875 bool alreadyProcessed = std::any_of(
1876 yyextra->includeStack.begin(),
1877 yyextra->includeStack.end(),
1878 [&absFileName,&blockId](
const auto &lfs)
1879 { return lfs->fileName==absFileName && lfs->blockId==blockId; }
1882 if (alreadyProcessed)
1886 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"recursive usage of '\\snippet{{doc}}' block with name '{}' and file name '{}', skipping",
1887 blockId,absFileName);
1891 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"recursive usage of '\\include{{doc}}' with file name '{}', skipping", absFileName);
1896 auto fs = std::make_unique<commentcnv_FileState>();
1899 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"\\{}{{doc}} file '{}' could not be read",blockId.
isEmpty()?
"include":
"snippet",absFileName);
1910 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"block marked with {} for \\snippet{{doc}} should appear twice in file {}, found it {:d} times, skipping",
1911 blockId,absFileName,count);
1917 fs->fileBuf.clear();
1920 fs->fileBuf.append(incText.
str());
1923 int oldRaiseLevel = yyextra->raiseLevel;
1924 QCString oldRaiseLabel = yyextra->raiseLabel;
1925 yyextra->raiseLevel+=yyextra->raiseIncrement;
1926 yyextra->raiseLabel+=yyextra->raisePrefix;
1927 QCString lineStr=
" \\ifile \""+absFileName+
"\" \\iline " + std::to_string(lineNr)+
" ";
1928 if (yyextra->raiseLevel>0)
1930 lineStr+=
"\\iraise " + std::to_string(yyextra->raiseLevel)+
" ";
1932 if (!yyextra->raiseLabel.isEmpty())
1934 lineStr+=
"\\iprefix \"" + yyextra->raiseLabel +
"\" ";
1936 lineStr+=
"\\ilinebr ";
1939 fs->fileName = absFileName;
1940 fs->bufState = YY_CURRENT_BUFFER;
1941 fs->oldLineNr = yyextra->lineNr;
1942 fs->oldFileName = yyextra->fileName;
1943 fs->oldState = yyextra->includeCtx;
1944 fs->oldFileBuf = yyextra->inBuf;
1945 fs->oldFileBufPos = yyextra->inBufPos;
1946 fs->oldIncludeCtx = yyextra->includeCtx;
1947 fs->oldRaiseLvl = oldRaiseLevel;
1948 fs->oldRaiseLbl = oldRaiseLabel;
1949 fs->blockId = blockId;
1950 yy_switch_to_buffer(yy_create_buffer(
nullptr,
YY_BUF_SIZE, yyscanner),yyscanner);
1951 yyextra->fileName = absFileName;
1952 yyextra->lineNr = lineNr;
1953 yyextra->inBuf = &fs->fileBuf;
1954 yyextra->inBufPos = 0;
1955 yyextra->includeStack.push_back(std::move(fs));
1961 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"\\{}{{doc}} file '{}' not found",blockId.
isEmpty()?
"include":
"snippet",inc);
1972 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1973 if (s.empty())
return;
1974 size_t pos = s.find(
'{');
1975 std::string cmd { s.substr(1, pos!=std::string::npos ? pos-1 : s.length()-1) };
1976 auto &expAlias = yyextra->expandedAliases;
1977 if (std::find(expAlias.begin(),expAlias.end(),cmd)!=std::end(expAlias))
1982 else if (cmd==
"ialias")
1984 if (s.length()>cmd.length()+3)
1986 std::string value { s.substr(cmd.length()+2,s.length()-cmd.length()-3) };
1988 expAlias.erase(std::remove(expAlias.begin(),expAlias.end(),value),expAlias.end());
1993 if (yyextra->inVerbatim)
1996 std::string blk = yyextra->blockName.str();
1997 assert(!blk.empty());
1998 bool isNamedCommand=
isId(blk[0]);
2001 while ((i=result.find(blk,p))!=std::string::npos && !found)
2003 found = !isNamedCommand ||
2004 (i>0 && (result[i-1]==
'\\' || result[i-1]==
'@') && !
isId(result[i+blk.length()]));
2005 p = i+yyextra->blockName.length();
2017 size_t numSpaces = yyextra->blockHeadCol>1 ? yyextra->blockHeadCol-1 : 0;
2018 std::string spaces(numSpaces,
' ');
2019 if (replaceCppComment)
2023 std::string replacement =
"\n"+spaces+
"///";
2026 else if (replaceCComment)
2028 std::string replacement =
"\n"+spaces+
" * ";
2031 expAlias.push_back(cmd);
2033 result +=
" \\ilinebr \\ialias{";
2036 for (
int i=(
int)result.length()-1; i>=0; i--)
2050 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2051 int bytesInBuf =
static_cast<int>(yyextra->inBuf->size())-yyextra->inBufPos;
2052 int bytesToCopy = std::min(max_size,bytesInBuf);
2053 memcpy(buf,yyextra->inBuf->data()+yyextra->inBufPos,bytesToCopy);
2054 yyextra->inBufPos+=bytesToCopy;
2060 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2061 if (yyextra->mlBrief || yyextra->skip)
2069 if (i==yyextra->blockHeadCol || i+1==yyextra->blockHeadCol)
2076 for (i=(
int)yyleng-1;i>=0;i--) unput(yytext[i]);
2077 yyextra->inSpecialComment=
FALSE;
2094 commentcnvYYlex_init_extra(&extra,&yyscanner);
2098 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2100 yyextra->inBufPos = 0;
2103 yyextra->skip =
FALSE;
2104 yyextra->fileName = fileName;
2106 yyextra->pythonDocString =
FALSE;
2107 yyextra->lineNr = 1;
2108 yyextra->raiseLevel = 0;
2109 yyextra->raiseLabel =
"";
2110 yyextra->raiseIncrement = 0;
2111 yyextra->raisePrefix =
"";
2112 yyextra->insertCppCommentMarker=
false;
2113 yyextra->expandedAliases.clear();
2114 while (!yyextra->condStack.empty()) yyextra->condStack.pop();
2116 yyextra->vhdl =
FALSE;
2119 yyextra->isFixedForm =
FALSE;
2120 if (yyextra->lang==SrcLangExt::Fortran)
2126 if (yyextra->lang==SrcLangExt::Markdown)
2128 yyextra->nestingCount=0;
2130 yyextra->commentStack.push(yyextra->lineNr);
2137 while (!yyextra->condStack.empty())
2142 warn(yyextra->fileName,ctx.
lineNr,
"Conditional section{}does not have "
2143 "a corresponding \\endcond command within this file.",sectionInfo.
data());
2144 yyextra->condStack.pop();
2146 if (yyextra->nestingCount>0 && yyextra->lang!=SrcLangExt::Markdown && yyextra->lang!=SrcLangExt::Fortran)
2150 while (!yyextra->commentStack.empty())
2152 int lineNr = yyextra->commentStack.top();
2153 if (!first) lines +=
", ";
2156 yyextra->commentStack.pop();
2158 warn(yyextra->fileName,yyextra->lineNr,
"Reached end of file while still inside a (nested) comment. "
2159 "Nesting level {} (possible line reference(s): {})",yyextra->nestingCount,lines);
2161 yyextra->nestingCount = 0;
2165 "output=[\n{}]\n-----------\n",fileName,yyextra->outBuf
2168 commentcnvYYlex_destroy(yyscanner);
2174#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
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.
int contains(char c, bool cs=TRUE) const
static constexpr int MaxLevel
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
#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)