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
62#define YY_NO_UNISTD_H 1
159static void replaceAliases(
yyscan_t yyscanner,std::string_view s,
bool replaceCppComment=
false,
bool replaceCComment=
false);
168#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Token literal values and constants.
Some helper functions for std::string.
A bunch of utility functions.
176MAILADDR ("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\-]+
203DECIMAL_INTEGER [1-9][0-9']*[0-9]?[uU]?[lL]?[lL]?
204HEXADECIMAL_INTEGER "0"[xX][0-9a-zA-Z']+[0-9a-zA-Z]?
205OCTAL_INTEGER "0"[0-7][0-7']+[0-7]?
206BINARY_INTEGER "0"[bB][01][01']*[01]?
207INTEGER_NUMBER {DECIMAL_INTEGER}|{HEXADECIMAL_INTEGER}|{OCTAL_INTEGER}|{BINARY_INTEGER}
211DIGIT_SEQ [0-9][0-9']*[0-9]?
212FRAC_CONST {DIGIT_SEQ}"."|{DIGIT_SEQ}?"."{DIGIT_SEQ}
213FP_EXP [eE][+-]?{DIGIT_SEQ}
214DEC_FP1 {FRAC_CONST}{FP_EXP}?{FP_SUF}?
215DEC_FP2 {DIGIT_SEQ}{FP_EXP}{FP_SUF}
217HEX_DIGIT_SEQ [0-9a-fA-F][0-9a-fA-F']*[0-9a-fA-F]?
218HEX_FRAC_CONST {HEX_DIGIT_SEQ}"."|{HEX_DIGIT_SEQ}?"."{HEX_DIGIT_SEQ}
219BIN_EXP [pP][+-]?{DIGIT_SEQ}
220HEX_FP1 "0"[xX]{HEX_FRAC_CONST}{BIN_EXP}{FP_SUF}?
221HEX_FP2 "0"[xX]{HEX_DIGIT_SEQ}{BIN_EXP}{FP_SUF}?
223FLOAT_DECIMAL {DEC_FP1}|{DEC_FP2}
224FLOAT_HEXADECIMAL {HEX_FP1}|{HEX_FP2}
225FLOAT_NUMBER {FLOAT_DECIMAL}|{FLOAT_HEXADECIMAL}
226NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
228RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
229RAWEND ")"[^ \t\(\)\\]{0,16}\"
231FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@]
232FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@]
233FILECHARS {FILEICHAR}*{FILEECHAR}+
234HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}*
235VFILEMASK {FILECHARS}("."{FILECHARS})*
236FILEMASK {VFILEMASK}|{HFILEMASK}
238DOXYCFG [A-Z][A-Z_0-9]*
266 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
270 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
274<Scan>[^"'!\/\n\\#,\-=; \t@$]* {
282 if (yyextra->lang!=SrcLangExt::Python)
288 yyextra->pythonDocString =
true;
289 yyextra->pythonDocStringChar = yytext[0];
290 yyextra->nestingCount=1;
294 yyextra->commentStack.push(yyextra->lineNr);
299 if (yyextra->lang!=SrcLangExt::Python)
309 yyextra->pythonDocString =
true;
310 yyextra->pythonDocStringChar = yytext[0];
311 yyextra->nestingCount=1;
315 yyextra->commentStack.push(yyextra->lineNr);
#define Config_getBool(name)
318<Scan>{B}*![><!]/.*\n {
319 if (yyextra->lang!=SrcLangExt::Fortran)
325 yyextra->nestingCount=0;
327 yyextra->specialComment=
true;
329 yyextra->blockHeadCol=yyextra->col-2;
331 yyextra->commentStack.push(yyextra->lineNr);
334<Scan>[Cc\*][><!]/.*\n {
335 if (yyextra->lang!=SrcLangExt::Fortran)
342 if (yyextra->isFixedForm && (yyextra->col == 0))
344 yyextra->nestingCount=0;
346 yyextra->specialComment=
true;
348 yyextra->blockHeadCol=yyextra->col-1;
350 yyextra->commentStack.push(yyextra->lineNr);
359 if (yyextra->lang!=SrcLangExt::Fortran)
369 if (yyextra->lang!=SrcLangExt::Fortran)
375 if (yyextra->col == 0)
386 if (yyextra->lang!=SrcLangExt::CSharp) REJECT
388 yyextra->stringContext = YY_START;
389 BEGIN(SkipVerbString);
393 yyextra->stringContext = YY_START;
398 yyextra->charContext = YY_START;
399 if (yyextra->lang!=SrcLangExt::VHDL)
407<Scan>{CPPC}[!/]/.*\n[ \t]*{CPPC}[!/][ \t]*{CMD}"}" {
409 yyextra->inSpecialComment=
true;
410 yyextra->blockHeadCol=yyextra->col+1;
411 yyextra->insertCppCommentMarker=
true;
413 yyextra->readLineCtx=YY_START;
416<Scan>{CPPC}"!"/.*\n[ \t]*{CPPC}[\/!][^\/] |
417<Scan>({CPPC}"/"[/]*)/[^/].*\n[ \t]*{CPPC}[\/!][^\/] {
418 if (yyextra->mlBrief)
427 while (i<(
int)yyleng && yytext[i]==
'/') i++;
429 yyextra->blockHeadCol=yyextra->col+1;
430 if (yytext[2] ==
'!')
439 yyextra->inSpecialComment=
true;
441 yyextra->readLineCtx=SComment;
445<Scan>{CPPC}"##Documentation"{ANYopt}/\n {
446 if (yyextra->mlBrief) REJECT;
448 yyextra->blockHeadCol=yyextra->col+1;
451 yyextra->inRoseComment=
true;
454<Scan>{CPPC}[!\/]/.*\n[ \t]*{CPPC}[|\/][ \t]*{CMD}"}" {
455 yyextra->inSpecialComment=yytext[2]==
'/' || yytext[2]==
'!';
456 if (yyextra->inSpecialComment)
458 yyextra->blockHeadCol=yyextra->col+1;
461 yyextra->readLineCtx=YY_START;
464<Scan>{CPPC}[!/]/.*\n {
465 yyextra->inSpecialComment=
true;
466 yyextra->blockHeadCol=yyextra->col+1;
467 yyextra->insertCppCommentMarker=
true;
469 yyextra->readLineCtx=YY_START;
473 yyextra->inSpecialComment=
false;
475 yyextra->readLineCtx=YY_START;
482 if (yyextra->lang==SrcLangExt::Python)
486 yyextra->specialComment=(int)yyleng==3;
487 yyextra->nestingCount=1;
490 if (yyextra->specialComment)
492 yyextra->blockHeadCol=0;
499 yyextra->commentStack.push(yyextra->lineNr);
502 if (yyextra->lang!=SrcLangExt::PHP)
509 if (yyextra->lang!=SrcLangExt::Python)
515 yyextra->nestingCount=0;
517 yyextra->specialComment=(int)yyleng==2;
518 if (yyextra->specialComment)
520 yyextra->blockHeadCol=yyextra->col;
522 yyextra->commentStack.push(yyextra->lineNr);
527<Scan>"--"[^!][^\n]* {
528 if (yyextra->lang!=SrcLangExt::VHDL)
538 if (yyextra->lang!=SrcLangExt::VHDL)
544 yyextra->specialComment=
true;
545 yyextra->blockHeadCol=yyextra->col;
546 yyextra->vhdl =
true;
547 yyextra->nestingCount=0;
549 yyextra->commentStack.push(yyextra->lineNr);
555 if (yyextra->lang!=SrcLangExt::Fortran)
561 yyextra->nestingCount=0;
563 yyextra->specialComment=
true;
564 yyextra->blockHeadCol=yyextra->col;
565 yyextra->commentStack.push(yyextra->lineNr);
DString extractEndRawStringDelimiter(const char *rawEnd)
577<RawString>[^)\n]+ {
copyToOutput(yyscanner,yytext,yyleng); }
581<CComment,CNComment,ReadLine,IncludeFile>{MAILADDR} |
582<CComment,CNComment,ReadLine,IncludeFile>"<"{MAILADDR}">" {
585<CComment,IncludeFile>"{"[ \t]*"@code"/[ \t\n] {
587 yyextra->lastCommentContext = YY_START;
588 yyextra->javaBlock=1;
589 yyextra->blockName=
DString(
"end")+&yytext[1];
590 yyextra->inVerbatim=
true;
591 yyextra->verbatimLine=yyextra->lineNr;
594<CComment,IncludeFile>"{"[ \t]*"@literal"/[ \t\n] {
596 yyextra->lastCommentContext = YY_START;
597 yyextra->javaBlock=1;
598 yyextra->blockName=
DString(
"end")+&yytext[1];
599 yyextra->inVerbatim=
true;
600 yyextra->verbatimLine=yyextra->lineNr;
603<CComment,ReadLine,IncludeFile>{CMD}"ilinebr"[ \t]+("```"[`]*|"~~~"[~]*) {
609 yyextra->lastCommentContext = YY_START;
610 yyextra->javaBlock=0;
611 yyextra->blockName=
DString(yytext).stripWhiteSpace().right(3);
612 yyextra->inVerbatim=
true;
613 yyextra->verbatimLine=yyextra->lineNr;
616<CComment,ReadLine,IncludeFile>^[ \t]*("```"[`]*|"~~~"[~]*) {
622 yyextra->lastCommentContext = YY_START;
623 yyextra->javaBlock=0;
624 yyextra->blockName=
DString(yytext).stripWhiteSpace().left(3);
625 yyextra->inVerbatim=
true;
626 yyextra->verbatimLine=yyextra->lineNr;
629<CComment,ReadLine,IncludeFile>{CMD}("dot"|"code"|"msc"|"startuml"|"mermaid")/[^a-z_A-Z0-9] {
631 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
633 yyextra->lastCommentContext = YY_START;
634 yyextra->javaBlock=0;
635 if (
dstrcmp(&yytext[1],
"startuml")==0)
637 yyextra->blockName=
"enduml";
641 yyextra->blockName=
DString(
"end")+&yytext[1];
643 yyextra->inVerbatim=
true;
644 yyextra->verbatimLine=yyextra->lineNr;
int dstrcmp(const char *str1, const char *str2)
648<CComment,ReadLine,IncludeFile>"\\`" {
651<CComment,ReadLine,IncludeFile>"```" {
654<CComment,ReadLine,IncludeFile>"`"{1,2} {
660 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
662 yyextra->lastCommentContext = YY_START;
663 yyextra->javaBlock=0;
664 yyextra->blockName=yytext;
665 yyextra->inVerbatim=
true;
666 yyextra->verbatimLine=yyextra->lineNr;
670<CComment,ReadLine,IncludeFile>{CMD}("f$"|"f["|"f{"|"f(") {
672 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
674 yyextra->blockName=&yytext[1];
675 if (yyextra->blockName.at(1)==
'[')
677 yyextra->blockName.at(1)=
']';
679 else if (yyextra->blockName.at(1)==
'{')
681 yyextra->blockName.at(1)=
'}';
683 else if (yyextra->blockName.at(1)==
'(')
685 yyextra->blockName.at(1)=
')';
687 yyextra->lastCommentContext = YY_START;
688 yyextra->inVerbatim=
true;
689 yyextra->verbatimLine=yyextra->lineNr;
693<CComment,ReadLine,IncludeFile>"<!--!" {
694 if (yyextra->inVerbatim) REJECT;
696 yyextra->inHtmlDoxygenCommand=
true;
698<CComment,ReadLine,IncludeFile>"-->" {
699 if (yyextra->inHtmlDoxygenCommand)
701 yyextra->inHtmlDoxygenCommand=
false;
708<CComment,ReadLine,IncludeFile>"<!--" {
710 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
712 yyextra->blockName=
"-->";
713 yyextra->lastCommentContext = YY_START;
714 yyextra->inVerbatim=
true;
715 yyextra->verbatimLine=yyextra->lineNr;
719<CComment,ReadLine,IncludeFile>{CMD}("verbatim"|"iliteral"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"rtfonly"|"manonly")/[^a-z_A-Z0-9] {
721 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
723 yyextra->blockName=
DString(
"end")+&yytext[1];
724 yyextra->lastCommentContext = YY_START;
725 yyextra->inVerbatim=
true;
726 yyextra->verbatimLine=yyextra->lineNr;
739<Verbatim>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}"|"f)") {
741 if (&yytext[1]==yyextra->blockName)
743 yyextra->inVerbatim=
false;
744 BEGIN(yyextra->lastCommentContext);
749 if (yytext==yyextra->blockName)
751 yyextra->inVerbatim=
false;
752 BEGIN(yyextra->lastCommentContext);
756 if (yyextra->javaBlock==0)
762 yyextra->javaBlock++;
767 if (yyextra->javaBlock==0)
773 yyextra->javaBlock--;
774 if (yyextra->javaBlock==0)
777 yyextra->inVerbatim=
false;
778 BEGIN(yyextra->lastCommentContext);
786<VerbatimCode>("```"[`]*|"~~~"[~]*) {
787 if (yytext[0]==
'`' && (yyextra->blockName==
"`" || yyextra->blockName==
"``"))
795 if (yytext[0]==yyextra->blockName[0])
797 yyextra->inVerbatim=
false;
798 BEGIN(yyextra->lastCommentContext);
806 yyextra->inVerbatim=
false;
807 BEGIN(yyextra->lastCommentContext);
814 yyextra->inVerbatim=
false;
815 BEGIN(yyextra->lastCommentContext);
818<VerbatimCode>"`"{1,2} {
820 if (yytext==yyextra->blockName)
822 yyextra->inVerbatim=
false;
823 BEGIN(yyextra->lastCommentContext);
826<VerbatimCode>{CMD}("enddot"|"endcode"|"endmsc"|"enduml"|"endmermaid")/("{")? {
828 if (&yytext[1]==yyextra->blockName)
830 yyextra->inVerbatim=
false;
831 BEGIN(yyextra->lastCommentContext);
834<VerbatimCode>^[ \t]*{CPPC}[\!\/]? {
835 if (!yyextra->inSpecialComment || yyextra->mlBrief)
842 while (yytext[l]==
' ' || yytext[l]==
'\t')
857<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]* {
860<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]+/\n{B}*"//" {
861 if (yyextra->lastCommentContext!=ReadLine)
870<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]+/\n {
871 if (yyextra->lastCommentContext==ReadLine)
873 yyextra->inVerbatim=
false;
874 BEGIN(yyextra->lastCommentContext);
878<Verbatim,VerbatimCode>\n {
880 if (yyextra->lastCommentContext == IncludeFile)
885<Verbatim>^[ \t]*{CPPC}[/!] {
886 if (yyextra->blockName==
"enddot" || yyextra->blockName==
"endmsc" || yyextra->blockName==
"enduml" || yyextra->blockName.at(0)==
'f')
890 while (yytext[l]==
' ' || yytext[l]==
'\t')
902<Verbatim,VerbatimCode>. {
906 if (yyextra->lang==SrcLangExt::Fortran || yyextra->lang==SrcLangExt::VHDL)
918 BEGIN(yyextra->stringContext);
926<SkipVerbString>[^"\n]+ {
929<SkipVerbString>\"\" {
932<SkipVerbString>"\"" {
934 BEGIN(yyextra->stringContext);
943 if (yyextra->lang==SrcLangExt::Fortran || yyextra->lang==SrcLangExt::VHDL)
955 BEGIN(yyextra->charContext);
964<CComment,CNComment>[^ `~<\\!@*\n{\"'\/-`]* {
967<CComment,CNComment>^{B}*"*"+[^*\/<\\@\n{\"`]* {
968 if (yyextra->lang==SrcLangExt::Markdown) REJECT;
970 if (yyextra->col>yyextra->blockHeadCol)
973 yyextra->blockHeadCol=yyextra->col;
979 if (yyextra->lang!=SrcLangExt::Python)
983 else if (yyextra->pythonDocStringChar != yytext[0])
989 yyextra->nestingCount--;
990 yyextra->pythonDocString =
false;
991 yyextra->pythonDocStringChar =
'\0';
996<CComment,CNComment>\n {
999 if (yyextra->lang==SrcLangExt::Fortran)
1004<CComment,CNComment>"/""/"+/"*/" {
1008<CComment,CNComment>"/"+"*" {
1009 if (yyextra->lang==SrcLangExt::Python ||
1010 yyextra->lang==SrcLangExt::Markdown)
1014 yyextra->nestingCount++;
1015 yyextra->commentStack.push(yyextra->lineNr);
1018<CComment,CNComment>^{B}*"*"+"/" |
1019<CComment,CNComment>"*"+"/" {
1020 if (yyextra->lang==SrcLangExt::Python ||
1021 yyextra->lang==SrcLangExt::Markdown)
1028 yyextra->nestingCount--;
1029 if (yyextra->nestingCount<=0)
1036 yyextra->commentStack.pop();
1041<CComment,CNComment>"\n"/[ \t]*"#" {
1042 if (yyextra->lang!=SrcLangExt::VHDL)
1050 yyextra->vhdl =
false;
1060<CComment,CNComment>"\n"/[ \t]*"-" {
1061 if (yyextra->lang!=SrcLangExt::Python || yyextra->pythonDocString)
1071<CComment,CNComment>"\n"/[ \t]*[^ \t#\-] {
1072 if (yyextra->lang==SrcLangExt::Python)
1074 if (yyextra->pythonDocString)
1084 else if (yyextra->lang==SrcLangExt::VHDL)
1088 yyextra->vhdl =
false;
1114<CComment,CNComment>{CMD}"~"[a-z_A-Z-]* {
1115 if (yyextra->lang!=SrcLangExt::Markdown) REJECT;
1117 if (!langId.
empty() &&
1122 warn(yyextra->fileName,yyextra->lineNr,
DString mid(size_t index, size_t len=npos) const
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
#define Config_getEnumAsString(name)
#define Config_isAvailableEnum(name, value)
int dstricmp(const char *s1, const char *s2)
#define warn(file, line, fmt,...)
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...
1128<CComment,CNComment>{CMD}{CMD} |
1129<CComment,CNComment>. {
1132<SkipLang>{CMD}"~"[a-zA-Z-]* {
1136 warn(yyextra->fileName,yyextra->lineNr,
1139 else if (langId.
empty() ||
1145<SkipLang>[^*@\\\n]* {
1152<SComment>^[ \t]*{CPPC}"/"{SLASHopt}/\n {
1155<SComment>\n[ \t]*{CPPC}"/"{SLASHopt}/\n {
1158<SComment>^[ \t]*{CPPC}"/"[^\/\n]/.*\n {
1160 yyextra->readLineCtx=YY_START;
1161 YY_CURRENT_BUFFER->yy_at_bol=1;
1164<SComment>\n[ \t]*{CPPC}[\/!]("<")?[ \t]*{CMD}"}".*\n {
1168 yyextra->inSpecialComment=
false;
1169 yyextra->inRoseComment=
false;
1172<SComment>\n[ \t]*{CPPC}"/"[^\\@\/\n]/.*\n {
1174 yyextra->readLineCtx=YY_START;
1175 YY_CURRENT_BUFFER->yy_at_bol=1;
1178<SComment>^[ \t]*{CPPC}"!" |
1179<SComment>^[ \t]*{CPPC}"!<"/.*\n |
1180<SComment>^[ \t]*{CPPC}"!"[^<]/.*\n {
1182 yyextra->readLineCtx=YY_START;
1183 YY_CURRENT_BUFFER->yy_at_bol=1;
1186<SComment>\n[ \t]*{CPPC}"!" |
1187<SComment>\n[ \t]*{CPPC}"!<"/.*\n |
1188<SComment>\n[ \t]*{CPPC}"!"[^<\n]/.*\n {
1190 yyextra->readLineCtx=YY_START;
1191 YY_CURRENT_BUFFER->yy_at_bol=1;
1194<SComment>^[ \t]*{CPPC}"##"/.*\n {
1195 if (!yyextra->inRoseComment)
1202 yyextra->readLineCtx=YY_START;
1203 YY_CURRENT_BUFFER->yy_at_bol=1;
1207<SComment>\n[ \t]*{CPPC}"##"/.*\n {
1208 if (!yyextra->inRoseComment)
1215 yyextra->readLineCtx=YY_START;
1216 YY_CURRENT_BUFFER->yy_at_bol=1;
1223 yyextra->inSpecialComment=
false;
1224 yyextra->inRoseComment=
false;
1225 yyextra->insertCppCommentMarker=
false;
1226 yyextra->readLineCtx = Scan;
1230<ReadLine,CopyLine>{CCS}"*" {
1233<ReadLine,CopyLine>{CCE} {
1236<ReadLine,CopyLine>"*" {
1239<ReadLine,CopyLine>{RL} {
1242<ReadLine,CopyLine>{RL}/{B}{CMD}"ilinebr"{B} {
1245<ReadLine,CopyLine>{RLopt}/\n {
1247 yyextra->insertCppCommentMarker=
false;
1248 BEGIN(yyextra->readLineCtx);
1250<CComment,CNComment,ReadLine>"\<" {
1253<CComment,CNComment,ReadLine>{CMD}{CMD}[~a-z_A-Z][a-z_A-Z0-9]*[ \t]* {
1257<CComment,ReadLine,IncludeFile>{CMD}("include"{OPTS}|"includedoc"{OPTS}*) {
1258 if (!
parseIncludeOptions(yyscanner,std::string_view{yytext,
static_cast<size_t>(yyleng)})) REJECT;
1259 yyextra->includeCtx = YY_START;
1260 yyextra->firstIncludeLine =
true;
1261 yyextra->insertCommentCol = yyextra->col;
1262 if (!yyextra->insertCppCommentMarker && (yyextra->includeCtx==ReadLine || yyextra->includeCtx==IncludeFile))
1264 yyextra->insertCppCommentMarker = yyextra->mlBrief;
1269<CComment,ReadLine,IncludeFile>{CMD}("snippet"{OPTS}|"snippetdoc"{OPTS}*) {
1270 if (!
parseIncludeOptions(yyscanner,std::string_view{yytext,
static_cast<size_t>(yyleng)})) REJECT;
1271 yyextra->includeCtx = YY_START;
1272 yyextra->firstIncludeLine =
true;
1273 yyextra->insertCommentCol = yyextra->col;
1274 if (!yyextra->insertCppCommentMarker && (yyextra->includeCtx==ReadLine || yyextra->includeCtx==IncludeFile))
1276 yyextra->insertCppCommentMarker = yyextra->mlBrief;
1281<IncludeDoc,SnippetDoc>{B}*
1282<IncludeDoc>{FILEMASK}|"\""[^\n\"]+"\"" {
1286 fileName=fileName.
mid(1,fileName.
length()-2);
1294 BEGIN(yyextra->includeCtx);
size_t length() const
Returns the length of the string, not counting the 0-terminator.
1297<SnippetDoc>({FILEMASK}|"\""[^\n\"]+"\""){B}+ {
1298 yyextra->snippetFileName=yytext;
1299 yyextra->snippetFileName=yyextra->snippetFileName.stripWhiteSpace();
1300 if (yyextra->snippetFileName ==
"this") yyextra->snippetFileName=yyextra->fileName;
1301 yyextra->snippetName =
"";
1302 BEGIN(SnippetDocTag);
1304<SnippetDocTag>[^\\@\n]+ {
1305 yyextra->snippetName += yytext;
1307<SnippetDocTag>{CMD} {
1308 yyextra->snippetName += yytext;
1310<SnippetDocTag>(\n|{CMD}"ilinebr") {
1311 for (
int i=(
int)yyleng-1;i>=0;i--) unput(yytext[i]);
1312 yyextra->snippetName = yyextra->snippetName.stripWhiteSpace();
1313 DString blockId =
"["+yyextra->snippetName+
"]";
1320 BEGIN(yyextra->includeCtx);
1324<IncludeDoc,SnippetDoc>\n {
1329 BEGIN(yyextra->includeCtx);
1331<IncludeDoc,SnippetDoc>. {
1333 BEGIN(yyextra->includeCtx);
1335<CComment,ReadLine,IncludeFile>{CMD}"cond"/[^a-z_A-Z0-9] {
1336 yyextra->condCtx = YY_START;
1339<CComment,ReadLine,IncludeFile>{CMD}"endcond"/[^a-z_A-Z0-9] {
1340 bool oldSkip=yyextra->skip;
1342 if (YY_START==CComment && oldSkip && !yyextra->skip)
1345 if (yyextra->lang!=SrcLangExt::Python &&
1346 yyextra->lang!=SrcLangExt::VHDL &&
1347 yyextra->lang!=SrcLangExt::Markdown &&
1348 yyextra->lang!=SrcLangExt::Fortran)
1350 yyextra->outBuf+=
'/';
1351 yyextra->outBuf+=
'*';
1353 if (yyextra->specialComment)
1355 yyextra->outBuf+=
'*';
1361<CondLine>{B}*{CMD}doxyconfig{B}+{DOXYCFG} {
1364<CondLine>([!()&| \ta-z_A-Z0-9.\-]|{CMD}"doxyconfig")+ {
1367<CComment,ReadLine,IncludeFile>{CMD}"cond"{WSopt}/\n {
1368 yyextra->condCtx=YY_START;
1376<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{CMD}[a-z_A-Z][a-z_A-Z0-9-]* {
1377 bool inCppComment = YY_START==ReadLine && yyextra->readLineCtx==SComment;
1378 bool inCComment = YY_START==CComment && yyextra->blockHeadCol>0;
1381<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{B}?{CMD}"ilinebr"{B}{CMD}"ialias{" {
1382 yyextra->lastBlockContext=YY_START;
1383 yyextra->blockCount=1;
1384 int extraSpace = (yytext[0]==
' '? 1:0);
1385 yyextra->aliasString=yytext+9+extraSpace;
1386 yyextra->aliasCmd=yytext+9+extraSpace;
1387 yyextra->lastEscaped=0;
1388 BEGIN( ReadAliasArgs );
1390<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{CMD}[a-z_A-Z][a-z_A-Z0-9-]*"{" {
1391 yyextra->lastBlockContext=YY_START;
1392 yyextra->blockCount=1;
1393 yyextra->aliasString=yytext;
1394 yyextra->aliasCmd=yytext;
1395 yyextra->lastEscaped=0;
1396 BEGIN( ReadAliasArgs );
1398<ReadAliasArgs>^[ \t]*"*" {
1400 if (indent>yyextra->blockHeadCol)
1402 yyextra->aliasString+=yytext;
1409<ReadAliasArgs>^[ \t]*{CPPC}[/!]/[^\n]* {
1411<ReadAliasArgs>[^{}\n\\\*]+ {
1412 yyextra->aliasString+=yytext;
1413 yyextra->lastEscaped=
false;
1415<ReadAliasArgs>"\\" {
1416 if (yyextra->lastEscaped) yyextra->lastEscaped=
false;
1417 else yyextra->lastEscaped=
true;
1418 yyextra->aliasString+=yytext;
1420<ReadAliasArgs>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}"|"f)") {
1421 yyextra->aliasString+=yytext;
1422 if (yyextra->inVerbatim && &yytext[1]==yyextra->blockName)
1431 yyextra->inVerbatim=
false;
1432 BEGIN(yyextra->lastCommentContext);
1436 yyextra->aliasString+=yytext;
1437 yyextra->lastEscaped=
false;
1438 if (yyextra->inVerbatim)
1442 BEGIN( yyextra->lastBlockContext );
1446 yyextra->aliasString+=yytext;
1447 if (!yyextra->lastEscaped) yyextra->blockCount++;
1448 yyextra->lastEscaped=
false;
1451 yyextra->aliasString+=yytext;
1452 if (!yyextra->lastEscaped) yyextra->blockCount--;
1453 if (yyextra->blockCount==0)
1455 bool inCppComment = yyextra->lastBlockContext==ReadLine && yyextra->readLineCtx==SComment;
1456 bool inCComment = yyextra->lastBlockContext==CComment && yyextra->blockHeadCol>0;
1457 replaceAliases(yyscanner,yyextra->aliasString.view(),inCppComment,inCComment);
1458 BEGIN( yyextra->lastBlockContext );
1460 yyextra->lastEscaped=
false;
1463 yyextra->aliasString+=yytext;
1464 yyextra->lastEscaped=
false;
1471 yyextra->insertCppCommentMarker=
false;
1472 BEGIN(yyextra->readLineCtx);
1474<ReadLine>{CMD}{CMD} |
1489 if (YY_START == ReadAliasArgs)
1491 warn(yyextra->fileName,yyextra->lineNr,
1492 "Reached end of file while still searching closing '}}' of an alias argument (probable start: '{}')",
1495 else if (YY_START==Verbatim || YY_START==VerbatimCode)
1497 warn(yyextra->fileName,yyextra->lineNr,
1498 "Reached end of file while still searching closing '{}' of a verbatim block starting at line {}",
1499 yyextra->blockName,yyextra->verbatimLine);
1501 if (yyextra->includeStack.empty())
1503 yyextra->insertCppCommentMarker=
false;
1508 std::unique_ptr<commentcnv_FileState> &fs = yyextra->includeStack.back();
1509 YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
1510 yy_switch_to_buffer(fs->bufState, yyscanner);
1511 yy_delete_buffer(oldBuf, yyscanner);
1512 BEGIN(fs->oldState);
1513 yyextra->fileName = fs->oldFileName;
1514 yyextra->lineNr = fs->oldLineNr;
1515 yyextra->inBuf = fs->oldFileBuf;
1516 yyextra->inBufPos = fs->oldFileBufPos;
1517 yyextra->includeCtx = fs->oldIncludeCtx;
1518 DString lineStr=
" \\ifile \""+yyextra->fileName+
"\" \\iline "+
DString().
setNum(yyextra->lineNr)+
" ";
1519 if (fs->oldRaiseLvl!=yyextra->raiseLevel)
1521 lineStr+=
"\\iraise " + std::to_string(fs->oldRaiseLvl)+
" ";
1523 if (fs->oldRaiseLbl!=yyextra->raiseLabel)
1525 lineStr+=
"\\iprefix \"" + fs->oldRaiseLbl +
"\" ";
1527 lineStr+=
"\\ilinebr ";
1528 yyextra->raiseLevel = fs->oldRaiseLvl;
1529 yyextra->raiseLabel = fs->oldRaiseLbl;
1531 yyextra->includeStack.pop_back();
DString & setNum(short n)
std::string_view view() const
1543 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1546 size_t optIdxStart = s.find(
'{');
1547 size_t optIdxEnd = optIdxStart!=std::string::npos ? s.find(
"}",optIdxStart+1) : std::string::npos;
1548 std::string cmdName;
1550 if (optIdxStart == std::string::npos)
1557 optList =
split(std::string{s.substr(optIdxStart+1,optIdxEnd-optIdxStart-1)},
",");
1559 bool isDoc = cmdName==
"includedoc" || cmdName==
"snippetdoc";
1560 for (
const auto &opt : optList)
1571 for (
const auto &opt : optList)
1574 size_t posEqual = locOpt.find(
'=');
1575 std::string_view option = posEqual!=std::string::npos ?
stripWhiteSpace(locOpt.substr(0,posEqual)) : locOpt;
1576 std::string_view value = posEqual!=std::string::npos ?
stripWhiteSpace(locOpt.substr(posEqual+1)) : std::string_view();
1578 if (option==std::string_view{
"doc"} && value.empty())
1581 else if (option==std::string_view{
"raise"} && !value.empty())
1583 yyextra->raiseIncrement = atoi(value.data());
1586 warn(yyextra->fileName,yyextra->lineNr,
"Raising section level from {} to {}, exceeds allowed range [0-{}], adjusting",
1591 else if (option==std::string_view{
"prefix"} && !value.empty())
1593 yyextra->raisePrefix = value;
1597 warn(yyextra->fileName,yyextra->lineNr,
"Unsupported option '{}' for {} command",option, cmdName);
1608 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1609 if (s.empty())
return;
1611 size_t len = s.length();
1614 while (p<len && (c=s[p]) && (c==
' ' || c==
'\t' || c==
'\n'))
1617 if (c==
'\n') { yyextra->lineNr++; yyextra->col=0; }
else { yyextra->col++; }
1622 while (p<len && (c=s[p]) && (c==
'/' || c==
'!' || c==
'#'))
1626 if (p<len && s[p]==
'<')
1640 yyextra->outBuf+=
' ';
1644 if (blanks>1) { yyextra->outBuf+=
'*'; yyextra->col++; }
1645 yyextra->outBuf+=
' ';
1649 yyextra->outBuf+=s.substr(p);
1650 yyextra->col+=
static_cast<int>(s.substr(p).length());
1662 else if (c==
'\t') col+=tabSize-(col%tabSize);
1671 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1672 size_t len = s.length();
1675 for (
size_t i=0;i<len;i++)
1680 yyextra->outBuf+=
'\n';
1685 yyextra->col+=tabSize-(yyextra->col%tabSize);
1696 for (
size_t i=0;i<len;i++)
1700 case '\n': yyextra->col=0;
1702 yyextra->lineNr++;
break;
1703 case '\t': yyextra->col+=tabSize-(yyextra->col%tabSize);
break;
1704 default: yyextra->col++;
break;
1712 copyToOutput(yyscanner,std::string_view{s,(size_t)len});
1717 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1718 while (!yyextra->commentStack.empty()) yyextra->commentStack.pop();
1723 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1726 bool expResult = prs.
parse(yyextra->fileName,yyextra->lineNr,sectId);
1727 yyextra->condStack.emplace(yyextra->lineNr,sectId,yyextra->skip);
1736 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1737 if (yyextra->condStack.empty())
1739 warn(yyextra->fileName,yyextra->lineNr,
"Found \\endcond command without matching \\cond");
1740 yyextra->skip=
false;
1746 yyextra->condStack.pop();
1753 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1754 bool oldSkip=yyextra->skip;
1756 if ((yyextra->condCtx==CComment || yyextra->readLineCtx==SComment) &&
1757 !oldSkip && yyextra->skip)
1759 if (yyextra->lang!=SrcLangExt::Python &&
1760 yyextra->lang!=SrcLangExt::VHDL &&
1761 yyextra->lang!=SrcLangExt::Markdown &&
1762 yyextra->lang!=SrcLangExt::Fortran)
1764 yyextra->outBuf+=
'*';
1765 yyextra->outBuf+=
'/';
1769 if (yyextra->readLineCtx==SComment)
1775 BEGIN(yyextra->condCtx);
1787 size_t m1 = text.
find(marker);
1795 found = (p<=m1 && m1<i);
1814 size_t m1 = text.
find(marker);
1816 size_t m2 = text.
find(marker,m1+marker.
length());
1823 found = (p<=m1 && m1<i);
1851 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1852 size_t startCol=yyextra->blockHeadCol;
1853 size_t contentCol=yyextra->insertCommentCol;
1854 size_t markerSpace=contentCol-startCol;
1858 if (yyextra->lang==SrcLangExt::Python)
1860 if (yyextra->pythonDocString)
1869 else if (yyextra->lang==SrcLangExt::Fortran)
1873 else if (yyextra->lang==SrcLangExt::Markdown)
1877 else if (yyextra->insertCppCommentMarker)
1892 for (;i<startCol;i++)
1896 if (marker.length()<=markerSpace && !yyextra->firstIncludeLine)
1899 i+=
static_cast<int>(marker.length());
1901 for (;i<contentCol;i++)
1905 yyextra->firstIncludeLine =
false;
1911 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1919 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"included file name '{}' is ambiguous"
1922 bool alreadyProcessed = std::any_of(
1923 yyextra->includeStack.begin(),
1924 yyextra->includeStack.end(),
1925 [&absFileName,&blockId](
const auto &lfs)
1926 { return lfs->fileName==absFileName && lfs->blockId==blockId; }
1929 if (alreadyProcessed)
1931 if (!blockId.
empty())
1933 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"recursive usage of '\\snippet{{doc}}' block with name '{}' and file name '{}', skipping",
1934 blockId,absFileName);
1938 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"recursive usage of '\\include{{doc}}' with file name '{}', skipping", absFileName);
1943 auto fs = std::make_unique<commentcnv_FileState>();
1946 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"\\{}{{doc}} file '{}' could not be read",blockId.
empty()?
"include":
"snippet",absFileName);
1951 if (!blockId.
empty())
1953 DString incText { fs->fileBuf };
1957 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"block marked with {} for \\snippet{{doc}} should appear twice in file {}, found it {:d} times, skipping",
1958 blockId,absFileName,count);
1962 size_t blockPos = 0;
1964 fs->fileBuf.clear();
1965 if (!incText.
empty())
1967 fs->fileBuf.append(incText.
str());
1970 int oldRaiseLevel = yyextra->raiseLevel;
1971 DString oldRaiseLabel = yyextra->raiseLabel;
1972 yyextra->raiseLevel+=yyextra->raiseIncrement;
1973 yyextra->raiseLabel+=yyextra->raisePrefix;
1974 DString lineStr=
" \\ifile \""+absFileName+
"\" \\iline " + std::to_string(lineNr)+
" ";
1975 if (yyextra->raiseLevel>0)
1977 lineStr+=
"\\iraise " + std::to_string(yyextra->raiseLevel)+
" ";
1979 if (!yyextra->raiseLabel.empty())
1981 lineStr+=
"\\iprefix \"" + yyextra->raiseLabel +
"\" ";
1983 lineStr+=
"\\ilinebr ";
1986 fs->fileName = absFileName;
1987 fs->bufState = YY_CURRENT_BUFFER;
1988 fs->oldLineNr = yyextra->lineNr;
1989 fs->oldFileName = yyextra->fileName;
1990 fs->oldState = yyextra->includeCtx;
1991 fs->oldFileBuf = yyextra->inBuf;
1992 fs->oldFileBufPos = yyextra->inBufPos;
1993 fs->oldIncludeCtx = yyextra->includeCtx;
1994 fs->oldRaiseLvl = oldRaiseLevel;
1995 fs->oldRaiseLbl = oldRaiseLabel;
1996 fs->blockId = blockId;
1997 yy_switch_to_buffer(yy_create_buffer(
nullptr,
YY_BUF_SIZE, yyscanner),yyscanner);
1998 yyextra->fileName = absFileName;
1999 yyextra->lineNr = lineNr;
2000 yyextra->inBuf = &fs->fileBuf;
2001 yyextra->inBufPos = 0;
2002 yyextra->includeStack.
push_back(std::move(fs));
2008 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"\\{}{{doc}} file '{}' not found",blockId.
empty()?
"include":
"snippet",inc);
2019 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2020 if (s.empty())
return;
2021 size_t pos = s.find(
'{');
2022 std::string cmd { s.substr(1, pos!=std::string::npos ? pos-1 : s.length()-1) };
2023 auto &expAlias = yyextra->expandedAliases;
2024 if (std::find(expAlias.begin(),expAlias.end(),cmd)!=std::end(expAlias))
2029 else if (cmd==
"ialias")
2031 if (s.length()>cmd.length()+3)
2033 std::string value { s.substr(cmd.length()+2,s.length()-cmd.length()-3) };
2035 expAlias.erase(std::remove(expAlias.begin(),expAlias.end(),value),expAlias.end());
2040 if (yyextra->inVerbatim)
2043 std::string blk = yyextra->blockName.str();
2044 assert(!blk.empty());
2045 bool isNamedCommand=
isId(blk[0]);
2048 while ((i=result.find(blk,p))!=std::string::npos && !found)
2050 found = !isNamedCommand ||
2051 (i>0 && (result[i-1]==
'\\' || result[i-1]==
'@') && !
isId(result[i+blk.length()]));
2052 p = i+yyextra->blockName.length();
2064 size_t numSpaces = yyextra->blockHeadCol>1 ? yyextra->blockHeadCol-1 : 0;
2065 std::string spaces(numSpaces,
' ');
2066 if (replaceCppComment)
2070 std::string replacement =
"\n"+spaces+
"///";
2073 else if (replaceCComment)
2075 std::string replacement =
"\n"+spaces+
" * ";
2078 expAlias.push_back(cmd);
2080 result +=
" \\ilinebr \\ialias{";
2083 for (
int i=(
int)result.length()-1; i>=0; i--)
2097 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2098 int bytesInBuf =
static_cast<int>(yyextra->inBuf->size())-yyextra->inBufPos;
2099 int bytesToCopy = std::min(max_size,bytesInBuf);
2100 memcpy(buf,yyextra->inBuf->data()+yyextra->inBufPos,bytesToCopy);
2101 yyextra->inBufPos+=bytesToCopy;
2107 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2108 if (yyextra->mlBrief || yyextra->skip)
2116 if (i==yyextra->blockHeadCol || i+1==yyextra->blockHeadCol)
2123 for (i = yyleng; i>0; )
2128 yyextra->inSpecialComment=
false;
2145 commentcnvYYlex_init_extra(&extra,&yyscanner);
2149 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2151 yyextra->inBufPos = 0;
2154 yyextra->skip =
false;
2155 yyextra->fileName = fileName;
2157 yyextra->pythonDocString =
false;
2158 yyextra->lineNr = 1;
2159 yyextra->raiseLevel = 0;
2160 yyextra->raiseLabel =
"";
2161 yyextra->raiseIncrement = 0;
2162 yyextra->raisePrefix =
"";
2163 yyextra->insertCppCommentMarker=
false;
2164 yyextra->expandedAliases.clear();
2165 while (!yyextra->condStack.empty()) yyextra->condStack.pop();
2167 yyextra->vhdl =
false;
2170 yyextra->isFixedForm =
false;
2171 if (yyextra->lang==SrcLangExt::Fortran)
2177 if (yyextra->lang==SrcLangExt::Markdown)
2179 yyextra->nestingCount=0;
2181 yyextra->commentStack.push(yyextra->lineNr);
2188 while (!yyextra->condStack.empty())
2193 warn(yyextra->fileName,ctx.
lineNr,
"Conditional section{}does not have "
2194 "a corresponding \\endcond command within this file.",sectionInfo.
data());
2195 yyextra->condStack.pop();
2197 if (yyextra->nestingCount>0 && yyextra->lang!=SrcLangExt::Markdown && yyextra->lang!=SrcLangExt::Fortran)
2201 while (!yyextra->commentStack.empty())
2203 int lineNr = yyextra->commentStack.top();
2204 if (!first) lines +=
", ";
2207 yyextra->commentStack.pop();
2209 warn(yyextra->fileName,yyextra->lineNr,
"Reached end of file while still inside a (nested) comment. "
2210 "Nesting level {} (possible line reference(s): {})",yyextra->nestingCount,lines);
2212 yyextra->nestingCount = 0;
2216 "output=[\n{}]\n-----------\n",fileName,yyextra->outBuf
2219 commentcnvYYlex_destroy(yyscanner);
2225#include "commentcnv.l.h"
std::string resolveAliasCmd(std::string_view aliasCmd)
Copyright (C) 1997-2026 by Dimitri van Heesch.
bool parse(const DString &fileName, int lineNr, const DString &expr)
parses and evaluates the given expression.
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
int contains(char c, bool cs=true) const
size_t find(char c, size_t pos=0) const
DString & sprintf(const char *format,...)
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
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.
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.
DString showFileDefMatches(const DString &n) const
Returns a list of file definitions in fnMap that match the file name n.
static constexpr int MaxLevel
int yylex(yyscan_t yyscanner)
#define Config_getInt(name)
std::vector< std::string > StringVector
const char * qPrint(const char *s)
bool isId(int c)
Returns true if c is a valid character for an identifier.
bool recognizeFixedForm(const DString &contents, FortranFormat format)
FortranFormat convertFileNameFortranParserCode(const DString &fn)
#define warn_doc_error(file, line, fmt,...)
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...
StringVector split(const std::string &s, const std::string &delimiter)
split input string s by string delimiter delimiter.
bool readInputFile(const DString &fileName, std::string &contents, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
SrcLangExt getLanguageFromFileName(const DString &fileName, SrcLangExt defLang)
DString findExampleFilePath(const DString &file, bool &ambig)