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
63#define YY_NO_UNISTD_H 1
160static void replaceAliases(
yyscan_t yyscanner,std::string_view s,
bool replaceCppComment=
false,
bool replaceCComment=
false);
169#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.
177MAILADDR ("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\-]+
204DECIMAL_INTEGER [1-9][0-9']*[0-9]?[uU]?[lL]?[lL]?
205HEXADECIMAL_INTEGER "0"[xX][0-9a-zA-Z']+[0-9a-zA-Z]?
206OCTAL_INTEGER "0"[0-7][0-7']+[0-7]?
207BINARY_INTEGER "0"[bB][01][01']*[01]?
208INTEGER_NUMBER {DECIMAL_INTEGER}|{HEXADECIMAL_INTEGER}|{OCTAL_INTEGER}|{BINARY_INTEGER}
212DIGIT_SEQ [0-9][0-9']*[0-9]?
213FRAC_CONST {DIGIT_SEQ}"."|{DIGIT_SEQ}?"."{DIGIT_SEQ}
214FP_EXP [eE][+-]?{DIGIT_SEQ}
215DEC_FP1 {FRAC_CONST}{FP_EXP}?{FP_SUF}?
216DEC_FP2 {DIGIT_SEQ}{FP_EXP}{FP_SUF}
218HEX_DIGIT_SEQ [0-9a-fA-F][0-9a-fA-F']*[0-9a-fA-F]?
219HEX_FRAC_CONST {HEX_DIGIT_SEQ}"."|{HEX_DIGIT_SEQ}?"."{HEX_DIGIT_SEQ}
220BIN_EXP [pP][+-]?{DIGIT_SEQ}
221HEX_FP1 "0"[xX]{HEX_FRAC_CONST}{BIN_EXP}{FP_SUF}?
222HEX_FP2 "0"[xX]{HEX_DIGIT_SEQ}{BIN_EXP}{FP_SUF}?
224FLOAT_DECIMAL {DEC_FP1}|{DEC_FP2}
225FLOAT_HEXADECIMAL {HEX_FP1}|{HEX_FP2}
226FLOAT_NUMBER {FLOAT_DECIMAL}|{FLOAT_HEXADECIMAL}
227NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
229RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
230RAWEND ")"[^ \t\(\)\\]{0,16}\"
232FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@]
233FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@]
234FILECHARS {FILEICHAR}*{FILEECHAR}+
235HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}*
236VFILEMASK {FILECHARS}("."{FILECHARS})*
237FILEMASK {VFILEMASK}|{HFILEMASK}
239DOXYCFG [A-Z][A-Z_0-9]*
267 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
271 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
275<Scan>[^"'!\/\n\\#,\-=; \t@$]* {
283 if (yyextra->lang!=SrcLangExt::Python)
289 yyextra->pythonDocString =
true;
290 yyextra->pythonDocStringChar = yytext[0];
291 yyextra->nestingCount=1;
295 yyextra->commentStack.push(yyextra->lineNr);
300 if (yyextra->lang!=SrcLangExt::Python)
310 yyextra->pythonDocString =
true;
311 yyextra->pythonDocStringChar = yytext[0];
312 yyextra->nestingCount=1;
316 yyextra->commentStack.push(yyextra->lineNr);
#define Config_getBool(name)
319<Scan>{B}*![><!]/.*\n {
320 if (yyextra->lang!=SrcLangExt::Fortran)
326 yyextra->nestingCount=0;
328 yyextra->specialComment=
true;
330 yyextra->blockHeadCol=yyextra->col-2;
332 yyextra->commentStack.push(yyextra->lineNr);
335<Scan>[Cc\*][><!]/.*\n {
336 if (yyextra->lang!=SrcLangExt::Fortran)
343 if (yyextra->isFixedForm && (yyextra->col == 0))
345 yyextra->nestingCount=0;
347 yyextra->specialComment=
true;
349 yyextra->blockHeadCol=yyextra->col-1;
351 yyextra->commentStack.push(yyextra->lineNr);
360 if (yyextra->lang!=SrcLangExt::Fortran)
370 if (yyextra->lang!=SrcLangExt::Fortran)
376 if (yyextra->col == 0)
387 if (yyextra->lang!=SrcLangExt::CSharp) REJECT
389 yyextra->stringContext = YY_START;
390 BEGIN(SkipVerbString);
394 yyextra->stringContext = YY_START;
399 yyextra->charContext = YY_START;
400 if (yyextra->lang!=SrcLangExt::VHDL)
408<Scan>{CPPC}[!/]/.*\n[ \t]*{CPPC}[!/][ \t]*{CMD}"}" {
410 yyextra->inSpecialComment=
true;
411 yyextra->blockHeadCol=yyextra->col+1;
412 yyextra->insertCppCommentMarker=
true;
414 yyextra->readLineCtx=YY_START;
417<Scan>{CPPC}"!"/.*\n[ \t]*{CPPC}[\/!][^\/] |
418<Scan>({CPPC}"/"[/]*)/[^/].*\n[ \t]*{CPPC}[\/!][^\/] {
419 if (yyextra->mlBrief)
428 while (i<(
int)yyleng && yytext[i]==
'/') i++;
430 yyextra->blockHeadCol=yyextra->col+1;
431 if (yytext[2] ==
'!')
440 yyextra->inSpecialComment=
true;
442 yyextra->readLineCtx=SComment;
446<Scan>{CPPC}"##Documentation"{ANYopt}/\n {
447 if (yyextra->mlBrief) REJECT;
449 yyextra->blockHeadCol=yyextra->col+1;
452 yyextra->inRoseComment=
true;
455<Scan>{CPPC}[!\/]/.*\n[ \t]*{CPPC}[|\/][ \t]*{CMD}"}" {
456 yyextra->inSpecialComment=yytext[2]==
'/' || yytext[2]==
'!';
457 if (yyextra->inSpecialComment)
459 yyextra->blockHeadCol=yyextra->col+1;
462 yyextra->readLineCtx=YY_START;
465<Scan>{CPPC}[!/]/.*\n {
466 yyextra->inSpecialComment=
true;
467 yyextra->blockHeadCol=yyextra->col+1;
468 yyextra->insertCppCommentMarker=
true;
470 yyextra->readLineCtx=YY_START;
474 yyextra->inSpecialComment=
false;
476 yyextra->readLineCtx=YY_START;
483 if (yyextra->lang==SrcLangExt::Python)
487 yyextra->specialComment=(int)yyleng==3;
488 yyextra->nestingCount=1;
491 if (yyextra->specialComment)
493 yyextra->blockHeadCol=0;
500 yyextra->commentStack.push(yyextra->lineNr);
503 if (yyextra->lang!=SrcLangExt::PHP)
510 if (yyextra->lang!=SrcLangExt::Python)
516 yyextra->nestingCount=0;
518 yyextra->specialComment=(int)yyleng==2;
519 if (yyextra->specialComment)
521 yyextra->blockHeadCol=yyextra->col;
523 yyextra->commentStack.push(yyextra->lineNr);
528<Scan>"--"[^!][^\n]* {
529 if (yyextra->lang!=SrcLangExt::VHDL)
539 if (yyextra->lang!=SrcLangExt::VHDL)
545 yyextra->specialComment=
true;
546 yyextra->blockHeadCol=yyextra->col;
547 yyextra->vhdl =
true;
548 yyextra->nestingCount=0;
550 yyextra->commentStack.push(yyextra->lineNr);
556 if (yyextra->lang!=SrcLangExt::Fortran)
562 yyextra->nestingCount=0;
564 yyextra->specialComment=
true;
565 yyextra->blockHeadCol=yyextra->col;
566 yyextra->commentStack.push(yyextra->lineNr);
DString extractEndRawStringDelimiter(const char *rawEnd)
578<RawString>[^)\n]+ {
copyToOutput(yyscanner,yytext,yyleng); }
582<CComment,CNComment,ReadLine,IncludeFile>{MAILADDR} |
583<CComment,CNComment,ReadLine,IncludeFile>"<"{MAILADDR}">" {
586<CComment,IncludeFile>"{"[ \t]*"@code"/[ \t\n] {
588 yyextra->lastCommentContext = YY_START;
589 yyextra->javaBlock=1;
590 yyextra->blockName=
DString(
"end")+&yytext[1];
591 yyextra->inVerbatim=
true;
592 yyextra->verbatimLine=yyextra->lineNr;
595<CComment,IncludeFile>"{"[ \t]*"@literal"/[ \t\n] {
597 yyextra->lastCommentContext = YY_START;
598 yyextra->javaBlock=1;
599 yyextra->blockName=
DString(
"end")+&yytext[1];
600 yyextra->inVerbatim=
true;
601 yyextra->verbatimLine=yyextra->lineNr;
604<CComment,ReadLine,IncludeFile>{CMD}"ilinebr"[ \t]+("```"[`]*|"~~~"[~]*) {
610 yyextra->lastCommentContext = YY_START;
611 yyextra->javaBlock=0;
613 yyextra->inVerbatim=
true;
614 yyextra->verbatimLine=yyextra->lineNr;
DString right(size_t len) const
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
617<CComment,ReadLine,IncludeFile>^[ \t]*("```"[`]*|"~~~"[~]*) {
623 yyextra->lastCommentContext = YY_START;
624 yyextra->javaBlock=0;
626 yyextra->inVerbatim=
true;
627 yyextra->verbatimLine=yyextra->lineNr;
DString left(size_t len) const
630<CComment,ReadLine,IncludeFile>{CMD}("dot"|"code"|"msc"|"startuml"|"mermaid")/[^a-z_A-Z0-9] {
632 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
634 yyextra->lastCommentContext = YY_START;
635 yyextra->javaBlock=0;
636 if (
dstrcmp(&yytext[1],
"startuml")==0)
638 yyextra->blockName=
"enduml";
642 yyextra->blockName=
DString(
"end")+&yytext[1];
644 yyextra->inVerbatim=
true;
645 yyextra->verbatimLine=yyextra->lineNr;
int dstrcmp(const char *str1, const char *str2)
649<CComment,ReadLine,IncludeFile>"\\`" {
652<CComment,ReadLine,IncludeFile>"```" {
655<CComment,ReadLine,IncludeFile>"`"{1,2} {
661 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
663 yyextra->lastCommentContext = YY_START;
664 yyextra->javaBlock=0;
665 yyextra->blockName=yytext;
666 yyextra->inVerbatim=
true;
667 yyextra->verbatimLine=yyextra->lineNr;
671<CComment,ReadLine,IncludeFile>{CMD}("f$"|"f["|"f{"|"f(") {
673 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
675 yyextra->blockName=&yytext[1];
676 if (yyextra->blockName.at(1)==
'[')
678 yyextra->blockName.at(1)=
']';
680 else if (yyextra->blockName.at(1)==
'{')
682 yyextra->blockName.at(1)=
'}';
684 else if (yyextra->blockName.at(1)==
'(')
686 yyextra->blockName.at(1)=
')';
688 yyextra->lastCommentContext = YY_START;
689 yyextra->inVerbatim=
true;
690 yyextra->verbatimLine=yyextra->lineNr;
694<CComment,ReadLine,IncludeFile>"<!--!" {
695 if (yyextra->inVerbatim) REJECT;
697 yyextra->inHtmlDoxygenCommand=
true;
699<CComment,ReadLine,IncludeFile>"-->" {
700 if (yyextra->inHtmlDoxygenCommand)
702 yyextra->inHtmlDoxygenCommand=
false;
709<CComment,ReadLine,IncludeFile>"<!--" {
711 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
713 yyextra->blockName=
"-->";
714 yyextra->lastCommentContext = YY_START;
715 yyextra->inVerbatim=
true;
716 yyextra->verbatimLine=yyextra->lineNr;
720<CComment,ReadLine,IncludeFile>{CMD}("verbatim"|"iliteral"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"rtfonly"|"manonly")/[^a-z_A-Z0-9] {
722 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
724 yyextra->blockName=
DString(
"end")+&yytext[1];
725 yyextra->lastCommentContext = YY_START;
726 yyextra->inVerbatim=
true;
727 yyextra->verbatimLine=yyextra->lineNr;
740<Verbatim>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}"|"f)") {
742 if (&yytext[1]==yyextra->blockName)
744 yyextra->inVerbatim=
false;
745 BEGIN(yyextra->lastCommentContext);
750 if (yytext==yyextra->blockName)
752 yyextra->inVerbatim=
false;
753 BEGIN(yyextra->lastCommentContext);
757 if (yyextra->javaBlock==0)
763 yyextra->javaBlock++;
768 if (yyextra->javaBlock==0)
774 yyextra->javaBlock--;
775 if (yyextra->javaBlock==0)
778 yyextra->inVerbatim=
false;
779 BEGIN(yyextra->lastCommentContext);
787<VerbatimCode>("```"[`]*|"~~~"[~]*) {
788 if (yytext[0]==
'`' && (yyextra->blockName==
"`" || yyextra->blockName==
"``"))
796 if (yytext[0]==yyextra->blockName[0])
798 yyextra->inVerbatim=
false;
799 BEGIN(yyextra->lastCommentContext);
807 yyextra->inVerbatim=
false;
808 BEGIN(yyextra->lastCommentContext);
815 yyextra->inVerbatim=
false;
816 BEGIN(yyextra->lastCommentContext);
819<VerbatimCode>"`"{1,2} {
821 if (yytext==yyextra->blockName)
823 yyextra->inVerbatim=
false;
824 BEGIN(yyextra->lastCommentContext);
827<VerbatimCode>{CMD}("enddot"|"endcode"|"endmsc"|"enduml"|"endmermaid")/("{")? {
829 if (&yytext[1]==yyextra->blockName)
831 yyextra->inVerbatim=
false;
832 BEGIN(yyextra->lastCommentContext);
835<VerbatimCode>^[ \t]*{CPPC}[\!\/]? {
836 if (!yyextra->inSpecialComment || yyextra->mlBrief)
843 while (yytext[l]==
' ' || yytext[l]==
'\t')
858<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]* {
861<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]+/\n{B}*"//" {
862 if (yyextra->lastCommentContext!=ReadLine)
871<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]+/\n {
872 if (yyextra->lastCommentContext==ReadLine)
874 yyextra->inVerbatim=
false;
875 BEGIN(yyextra->lastCommentContext);
879<Verbatim,VerbatimCode>\n {
881 if (yyextra->lastCommentContext == IncludeFile)
886<Verbatim>^[ \t]*{CPPC}[/!] {
887 if (yyextra->blockName==
"enddot" || yyextra->blockName==
"endmsc" || yyextra->blockName==
"enduml" || yyextra->blockName.at(0)==
'f')
891 while (yytext[l]==
' ' || yytext[l]==
'\t')
903<Verbatim,VerbatimCode>. {
907 if (yyextra->lang==SrcLangExt::Fortran || yyextra->lang==SrcLangExt::VHDL)
919 BEGIN(yyextra->stringContext);
927<SkipVerbString>[^"\n]+ {
930<SkipVerbString>\"\" {
933<SkipVerbString>"\"" {
935 BEGIN(yyextra->stringContext);
944 if (yyextra->lang==SrcLangExt::Fortran || yyextra->lang==SrcLangExt::VHDL)
956 BEGIN(yyextra->charContext);
965<CComment,CNComment>[^ `~<\\!@*\n{\"'\/-`]* {
968<CComment,CNComment>^{B}*"*"+[^*\/<\\@\n{\"`]* {
969 if (yyextra->lang==SrcLangExt::Markdown) REJECT;
971 if (yyextra->col>yyextra->blockHeadCol)
974 yyextra->blockHeadCol=yyextra->col;
980 if (yyextra->lang!=SrcLangExt::Python)
984 else if (yyextra->pythonDocStringChar != yytext[0])
990 yyextra->nestingCount--;
991 yyextra->pythonDocString =
false;
992 yyextra->pythonDocStringChar =
'\0';
997<CComment,CNComment>\n {
1000 if (yyextra->lang==SrcLangExt::Fortran)
1005<CComment,CNComment>"/""/"+/"*/" {
1009<CComment,CNComment>"/"+"*" {
1010 if (yyextra->lang==SrcLangExt::Python ||
1011 yyextra->lang==SrcLangExt::Markdown)
1015 yyextra->nestingCount++;
1016 yyextra->commentStack.push(yyextra->lineNr);
1019<CComment,CNComment>^{B}*"*"+"/" |
1020<CComment,CNComment>"*"+"/" {
1021 if (yyextra->lang==SrcLangExt::Python ||
1022 yyextra->lang==SrcLangExt::Markdown)
1029 yyextra->nestingCount--;
1030 if (yyextra->nestingCount<=0)
1037 yyextra->commentStack.pop();
1042<CComment,CNComment>"\n"/[ \t]*"#" {
1043 if (yyextra->lang!=SrcLangExt::VHDL)
1051 yyextra->vhdl =
false;
1061<CComment,CNComment>"\n"/[ \t]*"-" {
1062 if (yyextra->lang!=SrcLangExt::Python || yyextra->pythonDocString)
1072<CComment,CNComment>"\n"/[ \t]*[^ \t#\-] {
1073 if (yyextra->lang==SrcLangExt::Python)
1075 if (yyextra->pythonDocString)
1085 else if (yyextra->lang==SrcLangExt::VHDL)
1089 yyextra->vhdl =
false;
1115<CComment,CNComment>{CMD}"~"[a-z_A-Z-]* {
1116 if (yyextra->lang!=SrcLangExt::Markdown) REJECT;
1118 if (!langId.
empty() &&
1123 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...
1129<CComment,CNComment>{CMD}{CMD} |
1130<CComment,CNComment>. {
1133<SkipLang>{CMD}"~"[a-zA-Z-]* {
1137 warn(yyextra->fileName,yyextra->lineNr,
1140 else if (langId.
empty() ||
1146<SkipLang>[^*@\\\n]* {
1153<SComment>^[ \t]*{CPPC}"/"{SLASHopt}/\n {
1156<SComment>\n[ \t]*{CPPC}"/"{SLASHopt}/\n {
1159<SComment>^[ \t]*{CPPC}"/"[^\/\n]/.*\n {
1161 yyextra->readLineCtx=YY_START;
1162 YY_CURRENT_BUFFER->yy_at_bol=1;
1165<SComment>\n[ \t]*{CPPC}[\/!]("<")?[ \t]*{CMD}"}".*\n {
1169 yyextra->inSpecialComment=
false;
1170 yyextra->inRoseComment=
false;
1173<SComment>\n[ \t]*{CPPC}"/"[^\\@\/\n]/.*\n {
1175 yyextra->readLineCtx=YY_START;
1176 YY_CURRENT_BUFFER->yy_at_bol=1;
1179<SComment>^[ \t]*{CPPC}"!" |
1180<SComment>^[ \t]*{CPPC}"!<"/.*\n |
1181<SComment>^[ \t]*{CPPC}"!"[^<]/.*\n {
1183 yyextra->readLineCtx=YY_START;
1184 YY_CURRENT_BUFFER->yy_at_bol=1;
1187<SComment>\n[ \t]*{CPPC}"!" |
1188<SComment>\n[ \t]*{CPPC}"!<"/.*\n |
1189<SComment>\n[ \t]*{CPPC}"!"[^<\n]/.*\n {
1191 yyextra->readLineCtx=YY_START;
1192 YY_CURRENT_BUFFER->yy_at_bol=1;
1195<SComment>^[ \t]*{CPPC}"##"/.*\n {
1196 if (!yyextra->inRoseComment)
1203 yyextra->readLineCtx=YY_START;
1204 YY_CURRENT_BUFFER->yy_at_bol=1;
1208<SComment>\n[ \t]*{CPPC}"##"/.*\n {
1209 if (!yyextra->inRoseComment)
1216 yyextra->readLineCtx=YY_START;
1217 YY_CURRENT_BUFFER->yy_at_bol=1;
1224 yyextra->inSpecialComment=
false;
1225 yyextra->inRoseComment=
false;
1226 yyextra->insertCppCommentMarker=
false;
1227 yyextra->readLineCtx = Scan;
1231<ReadLine,CopyLine>{CCS}"*" {
1234<ReadLine,CopyLine>{CCE} {
1237<ReadLine,CopyLine>"*" {
1240<ReadLine,CopyLine>{RL} {
1243<ReadLine,CopyLine>{RL}/{B}{CMD}"ilinebr"{B} {
1246<ReadLine,CopyLine>{RLopt}/\n {
1248 yyextra->insertCppCommentMarker=
false;
1249 BEGIN(yyextra->readLineCtx);
1251<CComment,CNComment,ReadLine>"\<" {
1254<CComment,CNComment,ReadLine>{CMD}{CMD}[~a-z_A-Z][a-z_A-Z0-9]*[ \t]* {
1258<CComment,ReadLine,IncludeFile>{CMD}("include"{OPTS}|"includedoc"{OPTS}*) {
1259 if (!
parseIncludeOptions(yyscanner,std::string_view{yytext,
static_cast<size_t>(yyleng)})) REJECT;
1260 yyextra->includeCtx = YY_START;
1261 yyextra->firstIncludeLine =
true;
1262 yyextra->insertCommentCol = yyextra->col;
1263 if (!yyextra->insertCppCommentMarker && (yyextra->includeCtx==ReadLine || yyextra->includeCtx==IncludeFile))
1265 yyextra->insertCppCommentMarker = yyextra->mlBrief;
1270<CComment,ReadLine,IncludeFile>{CMD}("snippet"{OPTS}|"snippetdoc"{OPTS}*) {
1271 if (!
parseIncludeOptions(yyscanner,std::string_view{yytext,
static_cast<size_t>(yyleng)})) REJECT;
1272 yyextra->includeCtx = YY_START;
1273 yyextra->firstIncludeLine =
true;
1274 yyextra->insertCommentCol = yyextra->col;
1275 if (!yyextra->insertCppCommentMarker && (yyextra->includeCtx==ReadLine || yyextra->includeCtx==IncludeFile))
1277 yyextra->insertCppCommentMarker = yyextra->mlBrief;
1282<IncludeDoc,SnippetDoc>{B}*
1283<IncludeDoc>{FILEMASK}|"\""[^\n\"]+"\"" {
1287 fileName=fileName.
mid(1,fileName.
length()-2);
1295 BEGIN(yyextra->includeCtx);
size_t length() const
Returns the length of the string, not counting the 0-terminator.
1298<SnippetDoc>({FILEMASK}|"\""[^\n\"]+"\""){B}+ {
1299 yyextra->snippetFileName=yytext;
1300 yyextra->snippetFileName=yyextra->snippetFileName.stripWhiteSpace();
1301 if (yyextra->snippetFileName ==
"this") yyextra->snippetFileName=yyextra->fileName;
1302 yyextra->snippetName =
"";
1303 BEGIN(SnippetDocTag);
1305<SnippetDocTag>[^\\@\n]+ {
1306 yyextra->snippetName += yytext;
1308<SnippetDocTag>{CMD} {
1309 yyextra->snippetName += yytext;
1311<SnippetDocTag>(\n|{CMD}"ilinebr") {
1312 for (
int i=(
int)yyleng-1;i>=0;i--) unput(yytext[i]);
1313 yyextra->snippetName = yyextra->snippetName.stripWhiteSpace();
1314 DString blockId =
"["+yyextra->snippetName+
"]";
1321 BEGIN(yyextra->includeCtx);
1325<IncludeDoc,SnippetDoc>\n {
1330 BEGIN(yyextra->includeCtx);
1332<IncludeDoc,SnippetDoc>. {
1334 BEGIN(yyextra->includeCtx);
1336<CComment,ReadLine,IncludeFile>{CMD}"cond"/[^a-z_A-Z0-9] {
1337 yyextra->condCtx = YY_START;
1340<CComment,ReadLine,IncludeFile>{CMD}"endcond"/[^a-z_A-Z0-9] {
1341 bool oldSkip=yyextra->skip;
1343 if (YY_START==CComment && oldSkip && !yyextra->skip)
1346 if (yyextra->lang!=SrcLangExt::Python &&
1347 yyextra->lang!=SrcLangExt::VHDL &&
1348 yyextra->lang!=SrcLangExt::Markdown &&
1349 yyextra->lang!=SrcLangExt::Fortran)
1351 yyextra->outBuf+=
'/';
1352 yyextra->outBuf+=
'*';
1354 if (yyextra->specialComment)
1356 yyextra->outBuf+=
'*';
1362<CondLine>{B}*{CMD}doxyconfig{B}+{DOXYCFG} {
1365<CondLine>([!()&| \ta-z_A-Z0-9.\-]|{CMD}"doxyconfig")+ {
1368<CComment,ReadLine,IncludeFile>{CMD}"cond"{WSopt}/\n {
1369 yyextra->condCtx=YY_START;
1377<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{CMD}[a-z_A-Z][a-z_A-Z0-9-]* {
1378 bool inCppComment = YY_START==ReadLine && yyextra->readLineCtx==SComment;
1379 bool inCComment = YY_START==CComment && yyextra->blockHeadCol>0;
1382<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{B}?{CMD}"ilinebr"{B}{CMD}"ialias{" {
1383 yyextra->lastBlockContext=YY_START;
1384 yyextra->blockCount=1;
1385 int extraSpace = (yytext[0]==
' '? 1:0);
1386 yyextra->aliasString=yytext+9+extraSpace;
1387 yyextra->aliasCmd=yytext+9+extraSpace;
1388 yyextra->lastEscaped=0;
1389 BEGIN( ReadAliasArgs );
1391<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{CMD}[a-z_A-Z][a-z_A-Z0-9-]*"{" {
1392 yyextra->lastBlockContext=YY_START;
1393 yyextra->blockCount=1;
1394 yyextra->aliasString=yytext;
1395 yyextra->aliasCmd=yytext;
1396 yyextra->lastEscaped=0;
1397 BEGIN( ReadAliasArgs );
1399<ReadAliasArgs>^[ \t]*"*" {
1401 if (indent>yyextra->blockHeadCol)
1403 yyextra->aliasString+=yytext;
1410<ReadAliasArgs>^[ \t]*{CPPC}[/!]/[^\n]* {
1412<ReadAliasArgs>[^{}\n\\\*]+ {
1413 yyextra->aliasString+=yytext;
1414 yyextra->lastEscaped=
false;
1416<ReadAliasArgs>"\\" {
1417 if (yyextra->lastEscaped) yyextra->lastEscaped=
false;
1418 else yyextra->lastEscaped=
true;
1419 yyextra->aliasString+=yytext;
1421<ReadAliasArgs>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}"|"f)") {
1422 yyextra->aliasString+=yytext;
1423 if (yyextra->inVerbatim && &yytext[1]==yyextra->blockName)
1432 yyextra->inVerbatim=
false;
1433 BEGIN(yyextra->lastCommentContext);
1437 yyextra->aliasString+=yytext;
1438 yyextra->lastEscaped=
false;
1439 if (yyextra->inVerbatim)
1443 BEGIN( yyextra->lastBlockContext );
1447 yyextra->aliasString+=yytext;
1448 if (!yyextra->lastEscaped) yyextra->blockCount++;
1449 yyextra->lastEscaped=
false;
1452 yyextra->aliasString+=yytext;
1453 if (!yyextra->lastEscaped) yyextra->blockCount--;
1454 if (yyextra->blockCount==0)
1456 bool inCppComment = yyextra->lastBlockContext==ReadLine && yyextra->readLineCtx==SComment;
1457 bool inCComment = yyextra->lastBlockContext==CComment && yyextra->blockHeadCol>0;
1458 replaceAliases(yyscanner,yyextra->aliasString.view(),inCppComment,inCComment);
1459 BEGIN( yyextra->lastBlockContext );
1461 yyextra->lastEscaped=
false;
1464 yyextra->aliasString+=yytext;
1465 yyextra->lastEscaped=
false;
1472 yyextra->insertCppCommentMarker=
false;
1473 BEGIN(yyextra->readLineCtx);
1475<ReadLine>{CMD}{CMD} |
1490 if (YY_START == ReadAliasArgs)
1492 warn(yyextra->fileName,yyextra->lineNr,
1493 "Reached end of file while still searching closing '}}' of an alias argument (probable start: '{}')",
1496 else if (YY_START==Verbatim || YY_START==VerbatimCode)
1498 warn(yyextra->fileName,yyextra->lineNr,
1499 "Reached end of file while still searching closing '{}' of a verbatim block starting at line {}",
1500 yyextra->blockName,yyextra->verbatimLine);
1502 if (yyextra->includeStack.empty())
1504 yyextra->insertCppCommentMarker=
false;
1509 std::unique_ptr<commentcnv_FileState> &fs = yyextra->includeStack.back();
1510 YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
1511 yy_switch_to_buffer(fs->bufState, yyscanner);
1512 yy_delete_buffer(oldBuf, yyscanner);
1513 BEGIN(fs->oldState);
1514 yyextra->fileName = fs->oldFileName;
1515 yyextra->lineNr = fs->oldLineNr;
1516 yyextra->inBuf = fs->oldFileBuf;
1517 yyextra->inBufPos = fs->oldFileBufPos;
1518 yyextra->includeCtx = fs->oldIncludeCtx;
1519 DString lineStr=
" \\ifile \""+yyextra->fileName+
"\" \\iline "+
DString().
setNum(yyextra->lineNr)+
" ";
1520 if (fs->oldRaiseLvl!=yyextra->raiseLevel)
1522 lineStr+=
"\\iraise " + std::to_string(fs->oldRaiseLvl)+
" ";
1524 if (fs->oldRaiseLbl!=yyextra->raiseLabel)
1526 lineStr+=
"\\iprefix \"" + fs->oldRaiseLbl +
"\" ";
1528 lineStr+=
"\\ilinebr ";
1529 yyextra->raiseLevel = fs->oldRaiseLvl;
1530 yyextra->raiseLabel = fs->oldRaiseLbl;
1532 yyextra->includeStack.pop_back();
DString & setNum(short n)
std::string_view view() const
1544 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1547 size_t optIdxStart = s.find(
'{');
1548 size_t optIdxEnd = optIdxStart!=std::string::npos ? s.find(
"}",optIdxStart+1) : std::string::npos;
1549 std::string cmdName;
1551 if (optIdxStart == std::string::npos)
1558 optList =
split(std::string{s.substr(optIdxStart+1,optIdxEnd-optIdxStart-1)},
",");
1560 bool isDoc = cmdName==
"includedoc" || cmdName==
"snippetdoc";
1561 for (
const auto &opt : optList)
1572 for (
const auto &opt : optList)
1575 size_t posEqual = locOpt.find(
'=');
1576 std::string_view option = posEqual!=std::string::npos ?
stripWhiteSpace(locOpt.substr(0,posEqual)) : locOpt;
1577 std::string_view value = posEqual!=std::string::npos ?
stripWhiteSpace(locOpt.substr(posEqual+1)) : std::string_view();
1579 if (option==std::string_view{
"doc"} && value.empty())
1582 else if (option==std::string_view{
"raise"} && !value.empty())
1584 yyextra->raiseIncrement = atoi(value.data());
1587 warn(yyextra->fileName,yyextra->lineNr,
"Raising section level from {} to {}, exceeds allowed range [0-{}], adjusting",
1592 else if (option==std::string_view{
"prefix"} && !value.empty())
1594 yyextra->raisePrefix = value;
1598 warn(yyextra->fileName,yyextra->lineNr,
"Unsupported option '{}' for {} command",option, cmdName);
1609 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1610 if (s.empty())
return;
1612 size_t len = s.length();
1615 while (p<len && (c=s[p]) && (c==
' ' || c==
'\t' || c==
'\n'))
1618 if (c==
'\n') { yyextra->lineNr++; yyextra->col=0; }
else { yyextra->col++; }
1623 while (p<len && (c=s[p]) && (c==
'/' || c==
'!' || c==
'#'))
1627 if (p<len && s[p]==
'<')
1641 yyextra->outBuf+=
' ';
1645 if (blanks>1) { yyextra->outBuf+=
'*'; yyextra->col++; }
1646 yyextra->outBuf+=
' ';
1650 yyextra->outBuf+=s.substr(p);
1651 yyextra->col+=
static_cast<int>(s.substr(p).length());
1663 else if (c==
'\t') col+=tabSize-(col%tabSize);
1672 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1673 size_t len = s.length();
1676 for (
size_t i=0;i<len;i++)
1681 yyextra->outBuf+=
'\n';
1686 yyextra->col+=tabSize-(yyextra->col%tabSize);
1697 for (
size_t i=0;i<len;i++)
1701 case '\n': yyextra->col=0;
1703 yyextra->lineNr++;
break;
1704 case '\t': yyextra->col+=tabSize-(yyextra->col%tabSize);
break;
1705 default: yyextra->col++;
break;
1713 copyToOutput(yyscanner,std::string_view{s,(size_t)len});
1718 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1719 while (!yyextra->commentStack.empty()) yyextra->commentStack.pop();
1724 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1727 bool expResult = prs.
parse(yyextra->fileName,yyextra->lineNr,sectId);
1728 yyextra->condStack.emplace(yyextra->lineNr,sectId,yyextra->skip);
1737 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1738 if (yyextra->condStack.empty())
1740 warn(yyextra->fileName,yyextra->lineNr,
"Found \\endcond command without matching \\cond");
1741 yyextra->skip=
false;
1747 yyextra->condStack.pop();
1754 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1755 bool oldSkip=yyextra->skip;
1757 if ((yyextra->condCtx==CComment || yyextra->readLineCtx==SComment) &&
1758 !oldSkip && yyextra->skip)
1760 if (yyextra->lang!=SrcLangExt::Python &&
1761 yyextra->lang!=SrcLangExt::VHDL &&
1762 yyextra->lang!=SrcLangExt::Markdown &&
1763 yyextra->lang!=SrcLangExt::Fortran)
1765 yyextra->outBuf+=
'*';
1766 yyextra->outBuf+=
'/';
1770 if (yyextra->readLineCtx==SComment)
1776 BEGIN(yyextra->condCtx);
1788 size_t m1 = text.
find(marker);
1796 found = (p<=m1 && m1<i);
1815 size_t m1 = text.
find(marker);
1817 size_t m2 = text.
find(marker,m1+marker.
length());
1824 found = (p<=m1 && m1<i);
1852 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1853 size_t startCol=yyextra->blockHeadCol;
1854 size_t contentCol=yyextra->insertCommentCol;
1855 size_t markerSpace=contentCol-startCol;
1859 if (yyextra->lang==SrcLangExt::Python)
1861 if (yyextra->pythonDocString)
1870 else if (yyextra->lang==SrcLangExt::Fortran)
1874 else if (yyextra->lang==SrcLangExt::Markdown)
1878 else if (yyextra->insertCppCommentMarker)
1893 for (;i<startCol;i++)
1897 if (marker.length()<=markerSpace && !yyextra->firstIncludeLine)
1900 i+=
static_cast<int>(marker.length());
1902 for (;i<contentCol;i++)
1906 yyextra->firstIncludeLine =
false;
1912 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1920 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"included file name '{}' is ambiguous"
1923 bool alreadyProcessed = std::any_of(
1924 yyextra->includeStack.begin(),
1925 yyextra->includeStack.end(),
1926 [&absFileName,&blockId](
const auto &lfs)
1927 { return lfs->fileName==absFileName && lfs->blockId==blockId; }
1930 if (alreadyProcessed)
1932 if (!blockId.
empty())
1934 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"recursive usage of '\\snippet{{doc}}' block with name '{}' and file name '{}', skipping",
1935 blockId,absFileName);
1939 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"recursive usage of '\\include{{doc}}' with file name '{}', skipping", absFileName);
1944 auto fs = std::make_unique<commentcnv_FileState>();
1947 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"\\{}{{doc}} file '{}' could not be read",blockId.
empty()?
"include":
"snippet",absFileName);
1952 if (!blockId.
empty())
1954 DString incText { fs->fileBuf };
1958 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"block marked with {} for \\snippet{{doc}} should appear twice in file {}, found it {:d} times, skipping",
1959 blockId,absFileName,count);
1963 size_t blockPos = 0;
1965 fs->fileBuf.clear();
1966 if (!incText.
empty())
1968 fs->fileBuf.append(incText.
str());
1971 int oldRaiseLevel = yyextra->raiseLevel;
1972 DString oldRaiseLabel = yyextra->raiseLabel;
1973 yyextra->raiseLevel+=yyextra->raiseIncrement;
1974 yyextra->raiseLabel+=yyextra->raisePrefix;
1975 DString lineStr=
" \\ifile \""+absFileName+
"\" \\iline " + std::to_string(lineNr)+
" ";
1976 if (yyextra->raiseLevel>0)
1978 lineStr+=
"\\iraise " + std::to_string(yyextra->raiseLevel)+
" ";
1980 if (!yyextra->raiseLabel.empty())
1982 lineStr+=
"\\iprefix \"" + yyextra->raiseLabel +
"\" ";
1984 lineStr+=
"\\ilinebr ";
1987 fs->fileName = absFileName;
1988 fs->bufState = YY_CURRENT_BUFFER;
1989 fs->oldLineNr = yyextra->lineNr;
1990 fs->oldFileName = yyextra->fileName;
1991 fs->oldState = yyextra->includeCtx;
1992 fs->oldFileBuf = yyextra->inBuf;
1993 fs->oldFileBufPos = yyextra->inBufPos;
1994 fs->oldIncludeCtx = yyextra->includeCtx;
1995 fs->oldRaiseLvl = oldRaiseLevel;
1996 fs->oldRaiseLbl = oldRaiseLabel;
1997 fs->blockId = blockId;
1998 yy_switch_to_buffer(yy_create_buffer(
nullptr,
YY_BUF_SIZE, yyscanner),yyscanner);
1999 yyextra->fileName = absFileName;
2000 yyextra->lineNr = lineNr;
2001 yyextra->inBuf = &fs->fileBuf;
2002 yyextra->inBufPos = 0;
2003 yyextra->includeStack.
push_back(std::move(fs));
2009 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"\\{}{{doc}} file '{}' not found",blockId.
empty()?
"include":
"snippet",inc);
2020 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2021 if (s.empty())
return;
2022 size_t pos = s.find(
'{');
2023 std::string cmd { s.substr(1, pos!=std::string::npos ? pos-1 : s.length()-1) };
2024 auto &expAlias = yyextra->expandedAliases;
2025 if (std::find(expAlias.begin(),expAlias.end(),cmd)!=std::end(expAlias))
2030 else if (cmd==
"ialias")
2032 if (s.length()>cmd.length()+3)
2034 std::string value { s.substr(cmd.length()+2,s.length()-cmd.length()-3) };
2036 expAlias.erase(std::remove(expAlias.begin(),expAlias.end(),value),expAlias.end());
2041 if (yyextra->inVerbatim)
2044 std::string blk = yyextra->blockName.str();
2046 bool isNamedCommand=
isId(blk[0]);
2049 while ((i=result.find(blk,p))!=std::string::npos && !found)
2051 found = !isNamedCommand ||
2052 (i>0 && (result[i-1]==
'\\' || result[i-1]==
'@') && !
isId(result[i+blk.length()]));
2053 p = i+yyextra->blockName.length();
2065 size_t numSpaces = yyextra->blockHeadCol>1 ? yyextra->blockHeadCol-1 : 0;
2066 std::string spaces(numSpaces,
' ');
2067 if (replaceCppComment)
2071 std::string replacement =
"\n"+spaces+
"///";
2074 else if (replaceCComment)
2076 std::string replacement =
"\n"+spaces+
" * ";
2079 expAlias.push_back(cmd);
2081 result +=
" \\ilinebr \\ialias{";
2084 for (
int i=(
int)result.length()-1; i>=0; i--)
2098 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2099 int bytesInBuf =
static_cast<int>(yyextra->inBuf->size())-yyextra->inBufPos;
2100 int bytesToCopy = std::min(max_size,bytesInBuf);
2101 memcpy(buf,yyextra->inBuf->data()+yyextra->inBufPos,bytesToCopy);
2102 yyextra->inBufPos+=bytesToCopy;
2108 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2109 if (yyextra->mlBrief || yyextra->skip)
2117 if (i==yyextra->blockHeadCol || i+1==yyextra->blockHeadCol)
2124 for (i = yyleng; i>0; )
2129 yyextra->inSpecialComment=
false;
2146 commentcnvYYlex_init_extra(&extra,&yyscanner);
2150 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2152 yyextra->inBufPos = 0;
2155 yyextra->skip =
false;
2156 yyextra->fileName = fileName;
2158 yyextra->pythonDocString =
false;
2159 yyextra->lineNr = 1;
2160 yyextra->raiseLevel = 0;
2161 yyextra->raiseLabel =
"";
2162 yyextra->raiseIncrement = 0;
2163 yyextra->raisePrefix =
"";
2164 yyextra->insertCppCommentMarker=
false;
2165 yyextra->expandedAliases.clear();
2166 while (!yyextra->condStack.empty()) yyextra->condStack.pop();
2168 yyextra->vhdl =
false;
2171 yyextra->isFixedForm =
false;
2172 if (yyextra->lang==SrcLangExt::Fortran)
2178 if (yyextra->lang==SrcLangExt::Markdown)
2180 yyextra->nestingCount=0;
2182 yyextra->commentStack.push(yyextra->lineNr);
2189 while (!yyextra->condStack.empty())
2194 warn(yyextra->fileName,ctx.
lineNr,
"Conditional section{}does not have "
2195 "a corresponding \\endcond command within this file.",sectionInfo.
data());
2196 yyextra->condStack.pop();
2198 if (yyextra->nestingCount>0 && yyextra->lang!=SrcLangExt::Markdown && yyextra->lang!=SrcLangExt::Fortran)
2202 while (!yyextra->commentStack.empty())
2204 int lineNr = yyextra->commentStack.top();
2205 if (!first) lines +=
", ";
2208 yyextra->commentStack.pop();
2210 warn(yyextra->fileName,yyextra->lineNr,
"Reached end of file while still inside a (nested) comment. "
2211 "Nesting level {} (possible line reference(s): {})",yyextra->nestingCount,lines);
2213 yyextra->nestingCount = 0;
2217 "output=[\n{}]\n-----------\n",fileName,yyextra->outBuf
2220 commentcnvYYlex_destroy(yyscanner);
2226#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,...)
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
#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)