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
161static void replaceAliases(
yyscan_t yyscanner,std::string_view s,
bool replaceCppComment=
false,
bool replaceCComment=
false);
170#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.
178MAILADDR ("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\-]+
205DECIMAL_INTEGER [1-9][0-9']*[0-9]?[uU]?[lL]?[lL]?
206HEXADECIMAL_INTEGER "0"[xX][0-9a-zA-Z']+[0-9a-zA-Z]?
207OCTAL_INTEGER "0"[0-7][0-7']+[0-7]?
208BINARY_INTEGER "0"[bB][01][01']*[01]?
209INTEGER_NUMBER {DECIMAL_INTEGER}|{HEXADECIMAL_INTEGER}|{OCTAL_INTEGER}|{BINARY_INTEGER}
213DIGIT_SEQ [0-9][0-9']*[0-9]?
214FRAC_CONST {DIGIT_SEQ}"."|{DIGIT_SEQ}?"."{DIGIT_SEQ}
215FP_EXP [eE][+-]?{DIGIT_SEQ}
216DEC_FP1 {FRAC_CONST}{FP_EXP}?{FP_SUF}?
217DEC_FP2 {DIGIT_SEQ}{FP_EXP}{FP_SUF}
219HEX_DIGIT_SEQ [0-9a-fA-F][0-9a-fA-F']*[0-9a-fA-F]?
220HEX_FRAC_CONST {HEX_DIGIT_SEQ}"."|{HEX_DIGIT_SEQ}?"."{HEX_DIGIT_SEQ}
221BIN_EXP [pP][+-]?{DIGIT_SEQ}
222HEX_FP1 "0"[xX]{HEX_FRAC_CONST}{BIN_EXP}{FP_SUF}?
223HEX_FP2 "0"[xX]{HEX_DIGIT_SEQ}{BIN_EXP}{FP_SUF}?
225FLOAT_DECIMAL {DEC_FP1}|{DEC_FP2}
226FLOAT_HEXADECIMAL {HEX_FP1}|{HEX_FP2}
227FLOAT_NUMBER {FLOAT_DECIMAL}|{FLOAT_HEXADECIMAL}
228NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
230RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
231RAWEND ")"[^ \t\(\)\\]{0,16}\"
233FILEICHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+=&#@]
234FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+=&#@]
235FILECHARS {FILEICHAR}*{FILEECHAR}+
236HFILEMASK {FILEICHAR}*("."{FILEICHAR}+)+{FILECHARS}*
237VFILEMASK {FILECHARS}("."{FILECHARS})*
238FILEMASK {VFILEMASK}|{HFILEMASK}
240DOXYCFG [A-Z][A-Z_0-9]*
268 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
272 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
276<Scan>[^"'!\/\n\\#,\-=; \t@$]* {
284 if (yyextra->lang!=SrcLangExt::Python)
290 yyextra->pythonDocString =
true;
291 yyextra->pythonDocStringChar = yytext[0];
292 yyextra->nestingCount=1;
296 yyextra->commentStack.push(yyextra->lineNr);
301 if (yyextra->lang!=SrcLangExt::Python)
311 yyextra->pythonDocString =
true;
312 yyextra->pythonDocStringChar = yytext[0];
313 yyextra->nestingCount=1;
317 yyextra->commentStack.push(yyextra->lineNr);
#define Config_getBool(name)
320<Scan>{B}*![><!]/.*\n {
321 if (yyextra->lang!=SrcLangExt::Fortran)
327 yyextra->nestingCount=0;
329 yyextra->specialComment=
true;
331 yyextra->blockHeadCol=yyextra->col-2;
333 yyextra->commentStack.push(yyextra->lineNr);
336<Scan>[Cc\*][><!]/.*\n {
337 if (yyextra->lang!=SrcLangExt::Fortran)
344 if (yyextra->isFixedForm && (yyextra->col == 0))
346 yyextra->nestingCount=0;
348 yyextra->specialComment=
true;
350 yyextra->blockHeadCol=yyextra->col-1;
352 yyextra->commentStack.push(yyextra->lineNr);
361 if (yyextra->lang!=SrcLangExt::Fortran)
371 if (yyextra->lang!=SrcLangExt::Fortran)
377 if (yyextra->col == 0)
388 if (yyextra->lang!=SrcLangExt::CSharp) REJECT
390 yyextra->stringContext = YY_START;
391 BEGIN(SkipVerbString);
395 yyextra->stringContext = YY_START;
400 yyextra->charContext = YY_START;
401 if (yyextra->lang!=SrcLangExt::VHDL)
409<Scan>{CPPC}[!/]/.*\n[ \t]*{CPPC}[!/][ \t]*{CMD}"}" {
411 yyextra->inSpecialComment=
true;
412 yyextra->blockHeadCol=yyextra->col+1;
413 yyextra->insertCppCommentMarker=
true;
415 yyextra->readLineCtx=YY_START;
418<Scan>{CPPC}"!"/.*\n[ \t]*{CPPC}[\/!][^\/] |
419<Scan>({CPPC}"/"[/]*)/[^/].*\n[ \t]*{CPPC}[\/!][^\/] {
420 if (yyextra->mlBrief)
429 while (i<(
int)yyleng && yytext[i]==
'/') i++;
431 yyextra->blockHeadCol=yyextra->col+1;
432 yyextra->blockHeadPos=yyextra->skip ? std::string::npos : yyextra->outBuf.size();
433 if (yytext[2] ==
'!')
442 yyextra->inSpecialComment=
true;
444 yyextra->readLineCtx=SComment;
448<Scan>{CPPC}"##Documentation"{ANYopt}/\n {
449 if (yyextra->mlBrief) REJECT;
451 yyextra->blockHeadCol=yyextra->col+1;
452 yyextra->blockHeadPos=yyextra->skip ? std::string::npos : yyextra->outBuf.size();
455 yyextra->inRoseComment=
true;
458<Scan>{CPPC}[!\/]/.*\n[ \t]*{CPPC}[|\/][ \t]*{CMD}"}" {
459 yyextra->inSpecialComment=yytext[2]==
'/' || yytext[2]==
'!';
460 if (yyextra->inSpecialComment)
462 yyextra->blockHeadCol=yyextra->col+1;
465 yyextra->readLineCtx=YY_START;
468<Scan>{CPPC}[!/]/.*\n {
469 yyextra->inSpecialComment=
true;
470 yyextra->blockHeadCol=yyextra->col+1;
471 yyextra->insertCppCommentMarker=
true;
473 yyextra->readLineCtx=YY_START;
477 yyextra->inSpecialComment=
false;
479 yyextra->readLineCtx=YY_START;
486 if (yyextra->lang==SrcLangExt::Python)
490 yyextra->specialComment=(int)yyleng==3;
491 yyextra->nestingCount=1;
494 if (yyextra->specialComment)
496 yyextra->blockHeadCol=0;
503 yyextra->commentStack.push(yyextra->lineNr);
506 if (yyextra->lang!=SrcLangExt::PHP)
513 if (yyextra->lang!=SrcLangExt::Python)
519 yyextra->nestingCount=0;
521 yyextra->specialComment=(int)yyleng==2;
522 if (yyextra->specialComment)
524 yyextra->blockHeadCol=yyextra->col;
526 yyextra->commentStack.push(yyextra->lineNr);
531<Scan>"--"[^!][^\n]* {
532 if (yyextra->lang!=SrcLangExt::VHDL)
542 if (yyextra->lang!=SrcLangExt::VHDL)
548 yyextra->specialComment=
true;
549 yyextra->blockHeadCol=yyextra->col;
550 yyextra->vhdl =
true;
551 yyextra->nestingCount=0;
553 yyextra->commentStack.push(yyextra->lineNr);
559 if (yyextra->lang!=SrcLangExt::Fortran)
565 yyextra->nestingCount=0;
567 yyextra->specialComment=
true;
568 yyextra->blockHeadCol=yyextra->col;
569 yyextra->commentStack.push(yyextra->lineNr);
DString extractEndRawStringDelimiter(const char *rawEnd)
581<RawString>[^)\n]+ {
copyToOutput(yyscanner,yytext,yyleng); }
585<CComment,CNComment,ReadLine,IncludeFile>{MAILADDR} |
586<CComment,CNComment,ReadLine,IncludeFile>"<"{MAILADDR}">" {
589<CComment,IncludeFile>"{"[ \t]*"@code"/[ \t\n] {
591 yyextra->lastCommentContext = YY_START;
592 yyextra->javaBlock=1;
593 yyextra->blockName=
DString(
"end")+&yytext[1];
594 yyextra->inVerbatim=
true;
595 yyextra->verbatimLine=yyextra->lineNr;
598<CComment,IncludeFile>"{"[ \t]*"@literal"/[ \t\n] {
600 yyextra->lastCommentContext = YY_START;
601 yyextra->javaBlock=1;
602 yyextra->blockName=
DString(
"end")+&yytext[1];
603 yyextra->inVerbatim=
true;
604 yyextra->verbatimLine=yyextra->lineNr;
607<CComment,ReadLine,IncludeFile>{CMD}"ilinebr"[ \t]+("```"[`]*|"~~~"[~]*) {
613 yyextra->lastCommentContext = YY_START;
614 yyextra->javaBlock=0;
616 yyextra->inVerbatim=
true;
617 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
620<CComment,ReadLine,IncludeFile>^[ \t]*("```"[`]*|"~~~"[~]*) {
626 yyextra->lastCommentContext = YY_START;
627 yyextra->javaBlock=0;
629 yyextra->inVerbatim=
true;
630 yyextra->verbatimLine=yyextra->lineNr;
DString left(size_t len) const
633<CComment,ReadLine,IncludeFile>{CMD}("dot"|"code"|"msc"|"startuml"|"mermaid")/[^a-z_A-Z0-9] {
635 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
637 yyextra->lastCommentContext = YY_START;
638 yyextra->javaBlock=0;
639 if (
dstrcmp(&yytext[1],
"startuml")==0)
641 yyextra->blockName=
"enduml";
645 yyextra->blockName=
DString(
"end")+&yytext[1];
647 yyextra->inVerbatim=
true;
648 yyextra->verbatimLine=yyextra->lineNr;
int dstrcmp(const char *str1, const char *str2)
652<CComment,ReadLine,IncludeFile>"\\`" {
655<CComment,ReadLine,IncludeFile>"```" {
658<CComment,ReadLine,IncludeFile>"`"{1,2} {
664 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
666 yyextra->lastCommentContext = YY_START;
667 yyextra->javaBlock=0;
668 yyextra->blockName=yytext;
669 yyextra->inVerbatim=
true;
670 yyextra->verbatimLine=yyextra->lineNr;
674<CComment,ReadLine,IncludeFile>{CMD}("f$"|"f["|"f{"|"f(") {
676 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
678 yyextra->blockName=&yytext[1];
679 if (yyextra->blockName.at(1)==
'[')
681 yyextra->blockName.at(1)=
']';
683 else if (yyextra->blockName.at(1)==
'{')
685 yyextra->blockName.at(1)=
'}';
687 else if (yyextra->blockName.at(1)==
'(')
689 yyextra->blockName.at(1)=
')';
691 yyextra->lastCommentContext = YY_START;
692 yyextra->inVerbatim=
true;
693 yyextra->verbatimLine=yyextra->lineNr;
697<CComment,ReadLine,IncludeFile>"<!--!" {
698 if (yyextra->inVerbatim) REJECT;
700 yyextra->inHtmlDoxygenCommand=
true;
702<CComment,ReadLine,IncludeFile>"-->" {
703 if (yyextra->inHtmlDoxygenCommand)
705 yyextra->inHtmlDoxygenCommand=
false;
712<CComment,ReadLine,IncludeFile>"<!--" {
714 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
716 yyextra->blockName=
"-->";
717 yyextra->lastCommentContext = YY_START;
718 yyextra->inVerbatim=
true;
719 yyextra->verbatimLine=yyextra->lineNr;
723<CComment,ReadLine,IncludeFile>{CMD}("verbatim"|"iliteral"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"rtfonly"|"manonly")/[^a-z_A-Z0-9] {
725 if (yyextra->inSpecialComment || yyextra->specialComment || yyextra->lang==SrcLangExt::Markdown)
727 yyextra->blockName=
DString(
"end")+&yytext[1];
728 yyextra->lastCommentContext = YY_START;
729 yyextra->inVerbatim=
true;
730 yyextra->verbatimLine=yyextra->lineNr;
743<Verbatim>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}"|"f)") {
745 if (&yytext[1]==yyextra->blockName)
747 yyextra->inVerbatim=
false;
748 BEGIN(yyextra->lastCommentContext);
753 if (yytext==yyextra->blockName)
755 yyextra->inVerbatim=
false;
756 BEGIN(yyextra->lastCommentContext);
760 if (yyextra->javaBlock==0)
766 yyextra->javaBlock++;
771 if (yyextra->javaBlock==0)
777 yyextra->javaBlock--;
778 if (yyextra->javaBlock==0)
781 yyextra->inVerbatim=
false;
782 BEGIN(yyextra->lastCommentContext);
790<VerbatimCode>("```"[`]*|"~~~"[~]*) {
791 if (yytext[0]==
'`' && (yyextra->blockName==
"`" || yyextra->blockName==
"``"))
799 if (yytext[0]==yyextra->blockName[0])
801 yyextra->inVerbatim=
false;
802 BEGIN(yyextra->lastCommentContext);
810 yyextra->inVerbatim=
false;
811 BEGIN(yyextra->lastCommentContext);
818 yyextra->inVerbatim=
false;
819 BEGIN(yyextra->lastCommentContext);
822<VerbatimCode>"`"{1,2} {
824 if (yytext==yyextra->blockName)
826 yyextra->inVerbatim=
false;
827 BEGIN(yyextra->lastCommentContext);
830<VerbatimCode>{CMD}("enddot"|"endcode"|"endmsc"|"enduml"|"endmermaid")/("{")? {
832 if (&yytext[1]==yyextra->blockName)
834 yyextra->inVerbatim=
false;
835 BEGIN(yyextra->lastCommentContext);
838<VerbatimCode>^[ \t]*{CPPC}[\!\/]? {
839 if (!yyextra->inSpecialComment || yyextra->mlBrief)
846 while (yytext[l]==
' ' || yytext[l]==
'\t')
861<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]* {
864<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]+/\n{B}*"//" {
865 if (yyextra->lastCommentContext!=ReadLine)
874<Verbatim,VerbatimCode>[^`'~@\/\-\\\n{}]+/\n {
875 if (yyextra->lastCommentContext==ReadLine)
877 yyextra->inVerbatim=
false;
878 BEGIN(yyextra->lastCommentContext);
882<Verbatim,VerbatimCode>\n {
884 if (yyextra->lastCommentContext == IncludeFile)
889<Verbatim>^[ \t]*{CPPC}[/!] {
890 if (yyextra->blockName==
"enddot" || yyextra->blockName==
"endmsc" || yyextra->blockName==
"enduml" || yyextra->blockName.at(0)==
'f')
894 while (yytext[l]==
' ' || yytext[l]==
'\t')
906<Verbatim,VerbatimCode>. {
910 if (yyextra->lang==SrcLangExt::Fortran || yyextra->lang==SrcLangExt::VHDL)
922 BEGIN(yyextra->stringContext);
930<SkipVerbString>[^"\n]+ {
933<SkipVerbString>\"\" {
936<SkipVerbString>"\"" {
938 BEGIN(yyextra->stringContext);
947 if (yyextra->lang==SrcLangExt::Fortran || yyextra->lang==SrcLangExt::VHDL)
959 BEGIN(yyextra->charContext);
968<CComment,CNComment>[^ `~<\\!@*\n{\"'\/-`]* {
971<CComment,CNComment>^{B}*"*"+[^*\/<\\@\n{\"`]* {
972 if (yyextra->lang==SrcLangExt::Markdown) REJECT;
974 if (yyextra->col>yyextra->blockHeadCol)
977 yyextra->blockHeadCol=yyextra->col;
983 if (yyextra->lang!=SrcLangExt::Python)
987 else if (yyextra->pythonDocStringChar != yytext[0])
993 yyextra->nestingCount--;
994 yyextra->pythonDocString =
false;
995 yyextra->pythonDocStringChar =
'\0';
1000<CComment,CNComment>\n {
1003 if (yyextra->lang==SrcLangExt::Fortran)
1008<CComment,CNComment>"/""/"+/"*/" {
1012<CComment,CNComment>"/"+"*" {
1013 if (yyextra->lang==SrcLangExt::Python ||
1014 yyextra->lang==SrcLangExt::Markdown)
1018 yyextra->nestingCount++;
1019 yyextra->commentStack.push(yyextra->lineNr);
1022<CComment,CNComment>^{B}*"*"+"/" |
1023<CComment,CNComment>"*"+"/" {
1024 if (yyextra->lang==SrcLangExt::Python ||
1025 yyextra->lang==SrcLangExt::Markdown)
1032 yyextra->nestingCount--;
1033 if (yyextra->nestingCount<=0)
1040 yyextra->commentStack.pop();
1045<CComment,CNComment>"\n"/[ \t]*"#" {
1046 if (yyextra->lang!=SrcLangExt::VHDL)
1054 yyextra->vhdl =
false;
1064<CComment,CNComment>"\n"/[ \t]*"-" {
1065 if (yyextra->lang!=SrcLangExt::Python || yyextra->pythonDocString)
1075<CComment,CNComment>"\n"/[ \t]*[^ \t#\-] {
1076 if (yyextra->lang==SrcLangExt::Python)
1078 if (yyextra->pythonDocString)
1088 else if (yyextra->lang==SrcLangExt::VHDL)
1092 yyextra->vhdl =
false;
1118<CComment,CNComment>{CMD}"~"[a-z_A-Z-]* {
1119 if (yyextra->lang!=SrcLangExt::Markdown) REJECT;
1121 if (!langId.
empty() &&
1126 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...
1132<CComment,CNComment>{CMD}{CMD} |
1133<CComment,CNComment>. {
1136<SkipLang>{CMD}"~"[a-zA-Z-]* {
1140 warn(yyextra->fileName,yyextra->lineNr,
1143 else if (langId.
empty() ||
1149<SkipLang>[^*@\\\n]* {
1156<SComment>^[ \t]*{CPPC}"/"{SLASHopt}/\n {
1159<SComment>\n[ \t]*{CPPC}"/"{SLASHopt}/\n {
1162<SComment>^[ \t]*{CPPC}"/"[^\/\n]/.*\n {
1164 yyextra->readLineCtx=YY_START;
1165 YY_CURRENT_BUFFER->yy_at_bol=1;
1168<SComment>\n[ \t]*{CPPC}[\/!]("<")?[ \t]*{CMD}"}".*\n {
1172 yyextra->inSpecialComment=
false;
1173 yyextra->inRoseComment=
false;
1176<SComment>\n[ \t]*{CPPC}"/"[^\\@\/\n]/.*\n {
1178 yyextra->readLineCtx=YY_START;
1179 YY_CURRENT_BUFFER->yy_at_bol=1;
1182<SComment>^[ \t]*{CPPC}"!" |
1183<SComment>^[ \t]*{CPPC}"!<"/.*\n |
1184<SComment>^[ \t]*{CPPC}"!"[^<]/.*\n {
1186 yyextra->readLineCtx=YY_START;
1187 YY_CURRENT_BUFFER->yy_at_bol=1;
1190<SComment>\n[ \t]*{CPPC}"!" |
1191<SComment>\n[ \t]*{CPPC}"!<"/.*\n |
1192<SComment>\n[ \t]*{CPPC}"!"[^<\n]/.*\n {
1194 yyextra->readLineCtx=YY_START;
1195 YY_CURRENT_BUFFER->yy_at_bol=1;
1198<SComment>^[ \t]*{CPPC}"##"/.*\n {
1199 if (!yyextra->inRoseComment)
1206 yyextra->readLineCtx=YY_START;
1207 YY_CURRENT_BUFFER->yy_at_bol=1;
1211<SComment>\n[ \t]*{CPPC}"##"/.*\n {
1212 if (!yyextra->inRoseComment)
1219 yyextra->readLineCtx=YY_START;
1220 YY_CURRENT_BUFFER->yy_at_bol=1;
1227 yyextra->inSpecialComment=
false;
1228 yyextra->inRoseComment=
false;
1229 yyextra->insertCppCommentMarker=
false;
1230 yyextra->readLineCtx = Scan;
1234<ReadLine,CopyLine>{CCS}"*" {
1237<ReadLine,CopyLine>{CCE} {
1240<ReadLine,CopyLine>"*" {
1243<ReadLine,CopyLine>{RL} {
1246<ReadLine,CopyLine>{RL}/{B}{CMD}"ilinebr"{B} {
1249<ReadLine,CopyLine>{RLopt}/\n {
1251 yyextra->insertCppCommentMarker=
false;
1252 BEGIN(yyextra->readLineCtx);
1254<CComment,CNComment,ReadLine>"\<" {
1257<CComment,CNComment,ReadLine>{CMD}{CMD}[~a-z_A-Z][a-z_A-Z0-9]*[ \t]* {
1261<CComment,ReadLine,IncludeFile>{CMD}("include"{OPTS}|"includedoc"{OPTS}*) {
1262 if (!
parseIncludeOptions(yyscanner,std::string_view{yytext,
static_cast<size_t>(yyleng)})) REJECT;
1263 yyextra->includeCtx = YY_START;
1264 yyextra->firstIncludeLine =
true;
1265 yyextra->insertCommentCol = yyextra->col;
1266 if (!yyextra->insertCppCommentMarker && (yyextra->includeCtx==ReadLine || yyextra->includeCtx==IncludeFile))
1268 yyextra->insertCppCommentMarker = yyextra->mlBrief;
1273<CComment,ReadLine,IncludeFile>{CMD}("snippet"{OPTS}|"snippetdoc"{OPTS}*) {
1274 if (!
parseIncludeOptions(yyscanner,std::string_view{yytext,
static_cast<size_t>(yyleng)})) REJECT;
1275 yyextra->includeCtx = YY_START;
1276 yyextra->firstIncludeLine =
true;
1277 yyextra->insertCommentCol = yyextra->col;
1278 if (!yyextra->insertCppCommentMarker && (yyextra->includeCtx==ReadLine || yyextra->includeCtx==IncludeFile))
1280 yyextra->insertCppCommentMarker = yyextra->mlBrief;
1285<IncludeDoc,SnippetDoc>{B}*
1286<IncludeDoc>{FILEMASK}|"\""[^\n\"]+"\"" {
1290 fileName=fileName.
mid(1,fileName.
length()-2);
1298 BEGIN(yyextra->includeCtx);
size_t length() const
Returns the length of the string, not counting the 0-terminator.
1301<SnippetDoc>({FILEMASK}|"\""[^\n\"]+"\""){B}+ {
1302 yyextra->snippetFileName=yytext;
1303 yyextra->snippetFileName=yyextra->snippetFileName.stripWhiteSpace();
1304 if (yyextra->snippetFileName ==
"this") yyextra->snippetFileName=yyextra->fileName;
1305 yyextra->snippetName =
"";
1306 BEGIN(SnippetDocTag);
1308<SnippetDocTag>[^\\@\n]+ {
1309 yyextra->snippetName += yytext;
1311<SnippetDocTag>{CMD} {
1312 yyextra->snippetName += yytext;
1314<SnippetDocTag>(\n|{CMD}"ilinebr") {
1315 for (
int i=(
int)yyleng-1;i>=0;i--) unput(yytext[i]);
1316 yyextra->snippetName = yyextra->snippetName.stripWhiteSpace();
1317 DString blockId =
"["+yyextra->snippetName+
"]";
1324 BEGIN(yyextra->includeCtx);
1328<IncludeDoc,SnippetDoc>\n {
1333 BEGIN(yyextra->includeCtx);
1335<IncludeDoc,SnippetDoc>. {
1337 BEGIN(yyextra->includeCtx);
1339<CComment,ReadLine,IncludeFile>{CMD}"cond"/[^a-z_A-Z0-9] {
1340 yyextra->condCtx = YY_START;
1343<CComment,ReadLine,IncludeFile>{CMD}"endcond"/[^a-z_A-Z0-9] {
1344 bool oldSkip=yyextra->skip;
1346 if (YY_START==CComment && oldSkip && !yyextra->skip)
1349 if (yyextra->lang!=SrcLangExt::Python &&
1350 yyextra->lang!=SrcLangExt::VHDL &&
1351 yyextra->lang!=SrcLangExt::Markdown &&
1352 yyextra->lang!=SrcLangExt::Fortran)
1354 yyextra->outBuf+=
'/';
1355 yyextra->outBuf+=
'*';
1357 if (yyextra->specialComment)
1359 yyextra->outBuf+=
'*';
1365<CondLine>{B}*{CMD}doxyconfig{B}+{DOXYCFG} {
1368<CondLine>([!()&| \ta-z_A-Z0-9.\-]|{CMD}"doxyconfig")+ {
1371<CComment,ReadLine,IncludeFile>{CMD}"cond"{WSopt}/\n {
1372 yyextra->condCtx=YY_START;
1380<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{CMD}[a-z_A-Z][a-z_A-Z0-9-]* {
1381 bool inCppComment = YY_START==ReadLine && yyextra->readLineCtx==SComment;
1382 bool inCComment = YY_START==CComment && yyextra->blockHeadCol>0;
1385<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{B}?{CMD}"ilinebr"{B}{CMD}"ialias{" {
1386 yyextra->lastBlockContext=YY_START;
1387 yyextra->blockCount=1;
1388 int extraSpace = (yytext[0]==
' '? 1:0);
1389 yyextra->aliasString=yytext+9+extraSpace;
1390 yyextra->aliasCmd=yytext+9+extraSpace;
1391 yyextra->lastEscaped=0;
1392 BEGIN( ReadAliasArgs );
1394<CComment,ReadLine,IncludeFile,Verbatim,VerbatimCode>{CMD}[a-z_A-Z][a-z_A-Z0-9-]*"{" {
1395 yyextra->lastBlockContext=YY_START;
1396 yyextra->blockCount=1;
1397 yyextra->aliasString=yytext;
1398 yyextra->aliasCmd=yytext;
1399 yyextra->lastEscaped=0;
1400 BEGIN( ReadAliasArgs );
1402<ReadAliasArgs>^[ \t]*"*" {
1404 if (indent>yyextra->blockHeadCol)
1406 yyextra->aliasString+=yytext;
1413<ReadAliasArgs>^[ \t]*{CPPC}[/!]/[^\n]* {
1415<ReadAliasArgs>[^{}\n\\\*]+ {
1416 yyextra->aliasString+=yytext;
1417 yyextra->lastEscaped=
false;
1419<ReadAliasArgs>"\\" {
1420 if (yyextra->lastEscaped) yyextra->lastEscaped=
false;
1421 else yyextra->lastEscaped=
true;
1422 yyextra->aliasString+=yytext;
1424<ReadAliasArgs>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"f$"|"f]"|"f}"|"f)") {
1425 yyextra->aliasString+=yytext;
1426 if (yyextra->inVerbatim && &yytext[1]==yyextra->blockName)
1435 yyextra->inVerbatim=
false;
1436 BEGIN(yyextra->lastCommentContext);
1440 yyextra->aliasString+=yytext;
1441 yyextra->lastEscaped=
false;
1442 if (yyextra->inVerbatim)
1446 BEGIN( yyextra->lastBlockContext );
1450 yyextra->aliasString+=yytext;
1451 if (!yyextra->lastEscaped) yyextra->blockCount++;
1452 yyextra->lastEscaped=
false;
1455 yyextra->aliasString+=yytext;
1456 if (!yyextra->lastEscaped) yyextra->blockCount--;
1457 if (yyextra->blockCount==0)
1459 bool inCppComment = yyextra->lastBlockContext==ReadLine && yyextra->readLineCtx==SComment;
1460 bool inCComment = yyextra->lastBlockContext==CComment && yyextra->blockHeadCol>0;
1461 replaceAliases(yyscanner,yyextra->aliasString.view(),inCppComment,inCComment);
1462 BEGIN( yyextra->lastBlockContext );
1464 yyextra->lastEscaped=
false;
1467 yyextra->aliasString+=yytext;
1468 yyextra->lastEscaped=
false;
1475 yyextra->insertCppCommentMarker=
false;
1476 BEGIN(yyextra->readLineCtx);
1478<ReadLine>{CMD}{CMD} |
1493 if (YY_START == ReadAliasArgs)
1495 warn(yyextra->fileName,yyextra->lineNr,
1496 "Reached end of file while still searching closing '}}' of an alias argument (probable start: '{}')",
1499 else if (YY_START==Verbatim || YY_START==VerbatimCode)
1501 warn(yyextra->fileName,yyextra->lineNr,
1502 "Reached end of file while still searching closing '{}' of a verbatim block starting at line {}",
1503 yyextra->blockName,yyextra->verbatimLine);
1505 if (yyextra->includeStack.empty())
1507 yyextra->insertCppCommentMarker=
false;
1512 std::unique_ptr<commentcnv_FileState> &fs = yyextra->includeStack.back();
1513 YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
1514 yy_switch_to_buffer(fs->bufState, yyscanner);
1515 yy_delete_buffer(oldBuf, yyscanner);
1516 BEGIN(fs->oldState);
1517 yyextra->fileName = fs->oldFileName;
1518 yyextra->lineNr = fs->oldLineNr;
1519 yyextra->inBuf = fs->oldFileBuf;
1520 yyextra->inBufPos = fs->oldFileBufPos;
1521 yyextra->includeCtx = fs->oldIncludeCtx;
1522 DString lineStr=
" \\ifile \""+yyextra->fileName+
"\" \\iline "+
DString().
setNum(yyextra->lineNr)+
" ";
1523 if (fs->oldRaiseLvl!=yyextra->raiseLevel)
1525 lineStr+=
"\\iraise " + std::to_string(fs->oldRaiseLvl)+
" ";
1527 if (fs->oldRaiseLbl!=yyextra->raiseLabel)
1529 lineStr+=
"\\iprefix \"" + fs->oldRaiseLbl +
"\" ";
1531 lineStr+=
"\\ilinebr ";
1532 yyextra->raiseLevel = fs->oldRaiseLvl;
1533 yyextra->raiseLabel = fs->oldRaiseLbl;
1535 yyextra->includeStack.pop_back();
DString & setNum(short n)
std::string_view view() const
1547 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1550 size_t optIdxStart = s.find(
'{');
1551 size_t optIdxEnd = optIdxStart!=std::string::npos ? s.find(
"}",optIdxStart+1) : std::string::npos;
1552 std::string cmdName;
1554 if (optIdxStart == std::string::npos)
1561 optList =
split(std::string{s.substr(optIdxStart+1,optIdxEnd-optIdxStart-1)},
",");
1563 bool isDoc = cmdName==
"includedoc" || cmdName==
"snippetdoc";
1564 for (
const auto &opt : optList)
1575 for (
const auto &opt : optList)
1578 size_t posEqual = locOpt.find(
'=');
1579 std::string_view option = posEqual!=std::string::npos ?
stripWhiteSpace(locOpt.substr(0,posEqual)) : locOpt;
1580 std::string_view value = posEqual!=std::string::npos ?
stripWhiteSpace(locOpt.substr(posEqual+1)) : std::string_view();
1582 if (option==std::string_view{
"doc"} && value.empty())
1585 else if (option==std::string_view{
"raise"} && !value.empty())
1587 yyextra->raiseIncrement = atoi(value.data());
1590 warn(yyextra->fileName,yyextra->lineNr,
"Raising section level from {} to {}, exceeds allowed range [0-{}], adjusting",
1595 else if (option==std::string_view{
"prefix"} && !value.empty())
1597 yyextra->raisePrefix = value;
1601 warn(yyextra->fileName,yyextra->lineNr,
"Unsupported option '{}' for {} command",option, cmdName);
1612 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1613 if (s.empty())
return;
1615 size_t len = s.length();
1618 while (p<len && (c=s[p]) && (c==
' ' || c==
'\t' || c==
'\n'))
1621 if (c==
'\n') { yyextra->lineNr++; yyextra->col=0; }
else { yyextra->col++; }
1626 while (p<len && (c=s[p]) && (c==
'/' || c==
'!' || c==
'#'))
1630 if (p<len && s[p]==
'<')
1644 yyextra->outBuf+=
' ';
1648 if (blanks>1) { yyextra->outBuf+=
'*'; yyextra->col++; }
1649 yyextra->outBuf+=
' ';
1653 yyextra->outBuf+=s.substr(p);
1654 yyextra->col+=
static_cast<int>(s.substr(p).length());
1666 else if (c==
'\t') col+=tabSize-(col%tabSize);
1675 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1676 size_t len = s.length();
1679 for (
size_t i=0;i<len;i++)
1684 yyextra->outBuf+=
'\n';
1689 yyextra->col+=tabSize-(yyextra->col%tabSize);
1700 for (
size_t i=0;i<len;i++)
1704 case '\n': yyextra->col=0;
1706 yyextra->lineNr++;
break;
1707 case '\t': yyextra->col+=tabSize-(yyextra->col%tabSize);
break;
1708 default: yyextra->col++;
break;
1716 copyToOutput(yyscanner,std::string_view{s,(size_t)len});
1721 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1722 while (!yyextra->commentStack.empty()) yyextra->commentStack.pop();
1727 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1730 bool expResult = prs.
parse(yyextra->fileName,yyextra->lineNr,sectId);
1731 yyextra->condStack.emplace(yyextra->lineNr,sectId,yyextra->skip);
1740 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1741 if (yyextra->condStack.empty())
1743 warn(yyextra->fileName,yyextra->lineNr,
"Found \\endcond command without matching \\cond");
1744 yyextra->skip=
false;
1750 yyextra->condStack.pop();
1757 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1758 bool oldSkip=yyextra->skip;
1760 if ((yyextra->condCtx==CComment || yyextra->readLineCtx==SComment) &&
1761 !oldSkip && yyextra->skip)
1763 if (yyextra->lang!=SrcLangExt::Python &&
1764 yyextra->lang!=SrcLangExt::VHDL &&
1765 yyextra->lang!=SrcLangExt::Markdown &&
1766 yyextra->lang!=SrcLangExt::Fortran)
1768 yyextra->outBuf+=
'*';
1769 yyextra->outBuf+=
'/';
1773 if (yyextra->readLineCtx==SComment)
1779 BEGIN(yyextra->condCtx);
1791 size_t m1 = text.
find(marker);
1799 found = (p<=m1 && m1<i);
1818 size_t m1 = text.
find(marker);
1820 size_t m2 = text.
find(marker,m1+marker.
length());
1827 found = (p<=m1 && m1<i);
1855 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1856 size_t startCol=yyextra->blockHeadCol;
1857 size_t contentCol=yyextra->insertCommentCol;
1858 size_t markerSpace=contentCol-startCol;
1862 if (yyextra->lang==SrcLangExt::Python)
1864 if (yyextra->pythonDocString)
1873 else if (yyextra->lang==SrcLangExt::Fortran)
1877 else if (yyextra->lang==SrcLangExt::Markdown)
1881 else if (yyextra->insertCppCommentMarker)
1896 for (;i<startCol;i++)
1900 if (marker.length()<=markerSpace && !yyextra->firstIncludeLine)
1903 i+=
static_cast<int>(marker.length());
1905 for (;i<contentCol;i++)
1909 yyextra->firstIncludeLine =
false;
1915 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
1923 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"included file name '{}' is ambiguous"
1926 bool alreadyProcessed = std::any_of(
1927 yyextra->includeStack.begin(),
1928 yyextra->includeStack.end(),
1929 [&absFileName,&blockId](
const auto &lfs)
1930 { return lfs->fileName==absFileName && lfs->blockId==blockId; }
1933 if (alreadyProcessed)
1935 if (!blockId.
empty())
1937 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"recursive usage of '\\snippet{{doc}}' block with name '{}' and file name '{}', skipping",
1938 blockId,absFileName);
1942 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"recursive usage of '\\include{{doc}}' with file name '{}', skipping", absFileName);
1947 auto fs = std::make_unique<commentcnv_FileState>();
1950 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"\\{}{{doc}} file '{}' could not be read",blockId.
empty()?
"include":
"snippet",absFileName);
1955 if (!blockId.
empty())
1957 DString incText { fs->fileBuf };
1961 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"block marked with {} for \\snippet{{doc}} should appear twice in file {}, found it {:d} times, skipping",
1962 blockId,absFileName,count);
1966 size_t blockPos = 0;
1968 fs->fileBuf.clear();
1969 if (!incText.
empty())
1971 fs->fileBuf.append(incText.
str());
1974 int oldRaiseLevel = yyextra->raiseLevel;
1975 DString oldRaiseLabel = yyextra->raiseLabel;
1976 yyextra->raiseLevel+=yyextra->raiseIncrement;
1977 yyextra->raiseLabel+=yyextra->raisePrefix;
1978 DString lineStr=
" \\ifile \""+absFileName+
"\" \\iline " + std::to_string(lineNr)+
" ";
1979 if (yyextra->raiseLevel>0)
1981 lineStr+=
"\\iraise " + std::to_string(yyextra->raiseLevel)+
" ";
1983 if (!yyextra->raiseLabel.empty())
1985 lineStr+=
"\\iprefix \"" + yyextra->raiseLabel +
"\" ";
1987 lineStr+=
"\\ilinebr ";
1990 fs->fileName = absFileName;
1991 fs->bufState = YY_CURRENT_BUFFER;
1992 fs->oldLineNr = yyextra->lineNr;
1993 fs->oldFileName = yyextra->fileName;
1994 fs->oldState = yyextra->includeCtx;
1995 fs->oldFileBuf = yyextra->inBuf;
1996 fs->oldFileBufPos = yyextra->inBufPos;
1997 fs->oldIncludeCtx = yyextra->includeCtx;
1998 fs->oldRaiseLvl = oldRaiseLevel;
1999 fs->oldRaiseLbl = oldRaiseLabel;
2000 fs->blockId = blockId;
2001 yy_switch_to_buffer(yy_create_buffer(
nullptr,
YY_BUF_SIZE, yyscanner),yyscanner);
2002 yyextra->fileName = absFileName;
2003 yyextra->lineNr = lineNr;
2004 yyextra->inBuf = &fs->fileBuf;
2005 yyextra->inBufPos = 0;
2006 yyextra->includeStack.
push_back(std::move(fs));
2012 warn_doc_error(yyextra->fileName,yyextra->lineNr,
"\\{}{{doc}} file '{}' not found",blockId.
empty()?
"include":
"snippet",inc);
2023 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2024 if (s.empty())
return;
2025 size_t pos = s.find(
'{');
2026 std::string cmd { s.substr(1, pos!=std::string::npos ? pos-1 : s.length()-1) };
2027 auto &expAlias = yyextra->expandedAliases;
2028 if (std::find(expAlias.begin(),expAlias.end(),cmd)!=std::end(expAlias))
2033 else if (cmd==
"ialias")
2035 if (s.length()>cmd.length()+3)
2037 std::string value { s.substr(cmd.length()+2,s.length()-cmd.length()-3) };
2039 expAlias.erase(std::remove(expAlias.begin(),expAlias.end(),value),expAlias.end());
2044 if (yyextra->inVerbatim)
2047 std::string blk = yyextra->blockName.str();
2049 bool isNamedCommand=
isId(blk[0]);
2052 while ((i=result.find(blk,p))!=std::string::npos && !found)
2054 found = !isNamedCommand ||
2055 (i>0 && (result[i-1]==
'\\' || result[i-1]==
'@') && !
isId(result[i+blk.length()]));
2056 p = i+yyextra->blockName.length();
2068 size_t numSpaces = yyextra->blockHeadCol>1 ? yyextra->blockHeadCol-1 : 0;
2069 std::string spaces(numSpaces,
' ');
2070 if (replaceCppComment)
2074 std::string replacement =
"\n"+spaces+
"///";
2077 else if (replaceCComment)
2079 std::string replacement =
"\n"+spaces+
" * ";
2082 expAlias.push_back(cmd);
2084 result +=
" \\ilinebr \\ialias{";
2087 for (
int i=(
int)result.length()-1; i>=0; i--)
2101 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2102 int bytesInBuf =
static_cast<int>(yyextra->inBuf->size())-yyextra->inBufPos;
2103 int bytesToCopy = std::min(max_size,bytesInBuf);
2104 memcpy(buf,yyextra->inBuf->data()+yyextra->inBufPos,bytesToCopy);
2105 yyextra->inBufPos+=bytesToCopy;
2111 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2112 if (yyextra->mlBrief || yyextra->skip)
2125 bool afterMember = yyleng>0 && yytext[yyleng-1]==
'<';
2128 bool headAfterMember = yyextra->blockHeadPos!=std::string::npos &&
2129 yyextra->blockHeadPos+3<yyextra->outBuf.size() &&
2130 yyextra->outBuf[yyextra->blockHeadPos+3]==
'<';
2131 bool sameEntity = afterMember && headAfterMember;
2133 if (i==yyextra->blockHeadCol || i+1==yyextra->blockHeadCol)
2137 else if (sameEntity)
2141 while (p<(
size_t)yyleng && (yytext[p]==
' ' || yytext[p]==
'\t')) p++;
2142 bool javadoc = yytext[p+2]==
'/';
2145 yyextra->blockHeadCol=i+1;
2146 yyextra->blockHeadPos=yyextra->outBuf.size();
2151 if (javadoc && jdAuto && !qtAuto) javadoc=
false;
2152 else if (!javadoc && qtAuto && !jdAuto) javadoc=
true;
2158 for (i = yyleng; i>0; )
2163 yyextra->inSpecialComment=
false;
2180 commentcnvYYlex_init_extra(&extra,&yyscanner);
2184 struct yyguts_t *yyg = (
struct yyguts_t*)yyscanner;
2186 yyextra->inBufPos = 0;
2189 yyextra->skip =
false;
2190 yyextra->fileName = fileName;
2192 yyextra->pythonDocString =
false;
2193 yyextra->lineNr = 1;
2194 yyextra->raiseLevel = 0;
2195 yyextra->raiseLabel =
"";
2196 yyextra->raiseIncrement = 0;
2197 yyextra->raisePrefix =
"";
2198 yyextra->insertCppCommentMarker=
false;
2199 yyextra->expandedAliases.clear();
2200 while (!yyextra->condStack.empty()) yyextra->condStack.pop();
2202 yyextra->vhdl =
false;
2205 yyextra->isFixedForm =
false;
2206 if (yyextra->lang==SrcLangExt::Fortran)
2212 if (yyextra->lang==SrcLangExt::Markdown)
2214 yyextra->nestingCount=0;
2216 yyextra->commentStack.push(yyextra->lineNr);
2223 while (!yyextra->condStack.empty())
2228 warn(yyextra->fileName,ctx.
lineNr,
"Conditional section{}does not have "
2229 "a corresponding \\endcond command within this file.",sectionInfo.
data());
2230 yyextra->condStack.pop();
2232 if (yyextra->nestingCount>0 && yyextra->lang!=SrcLangExt::Markdown && yyextra->lang!=SrcLangExt::Fortran)
2236 while (!yyextra->commentStack.empty())
2238 int lineNr = yyextra->commentStack.top();
2239 if (!first) lines +=
", ";
2242 yyextra->commentStack.pop();
2244 warn(yyextra->fileName,yyextra->lineNr,
"Reached end of file while still inside a (nested) comment. "
2245 "Nesting level {} (possible line reference(s): {})",yyextra->nestingCount,lines);
2247 yyextra->nestingCount = 0;
2251 "output=[\n{}]\n-----------\n",fileName,yyextra->outBuf
2254 commentcnvYYlex_destroy(yyscanner);
2260#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
bool isId(char c)
Returns true if c is a valid character for an identifier.
const char * qPrint(const char *s)
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)