737 {CMD}{CMD}[a-z_A-Z]+{B}* {
739 }
740<Comment>{CMD}{CMD}"~"[a-z_A-Z]* { // escaped command
742 }
743<Comment>{MAILADDR} { // mail address
745 }
746<Comment>"\""[^"\n]*"\"" { // quoted text
748 }
749<Comment>("\\"[a-z_A-Z]+)+"\\" { // directory (or chain of commands!)
751 }
752<Comment>"<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description
754 size_t spacePos = htmlOpenTag.find(' ');
756 DString htmlTagName = htmlOpenTag.
mid(1,spacePos-1);
757
758 yyextra->htmlContextStack.emplace_back(htmlTagName,yyextra->inContext);
760 {
762 }
763
764 REJECT;
765 }
766<Comment>"</"{DETAILEDHTML}">" { // HTML command that ends a brief description
768 DString htmlTagName = htmlCloseTag.
mid(2,htmlCloseTag.length()-3);
769
770 if (!yyextra->htmlContextStack.empty() &&
771 yyextra->htmlContextStack.back().tagName==htmlTagName)
772 {
774 {
775
777 }
778 yyextra->htmlContextStack.pop_back();
779 }
780 REJECT;
781 }
782<Comment>"<"{DETAILEDHTMLOPT}">" { // HTML <code> command that ends a brief description
783
784 if (yyextra->current->lang==SrcLangExt::CSharp)
785 {
786 yyextra->CScode=true;
789 }
790 else
791 {
792
793 REJECT;
794 }
795 }
796<Comment>"<"{DETAILEDHTMLOPTEND}">" { // HTML command that ends a brief description
797 if (yyextra->CScode)
798 {
800 yyextra->CScode=false;
801 }
802 else
803 {
804 yyextra->CScode=false;
805
806 REJECT;
807 }
808 }
809<Comment>"<"{DETAILEDHTMLOPT}{ATTR}">" { // HTML <code> command that ends a brief description
810
811 if (yyextra->current->lang==SrcLangExt::CSharp)
812 {
814 }
815
816 REJECT;
817 }
818<Comment>"<"{DETAILS}{ATTR}">" { // start of a HTML style details description
819 yyextra->htmlDetailsStack.push_back(0);
820 yyextra->htmlContextStack.emplace_back("details",yyextra->inContext);
822 {
824 }
826 }
827<Comment>"</"{DETAILS}">" { // end of a HTML style details description
828 if (!yyextra->htmlDetailsStack.empty())
829 {
830 yyextra->htmlDetailsStack.pop_back();
831 }
832 if (!yyextra->htmlContextStack.empty() &&
833 yyextra->htmlContextStack.back().tagName=="details")
834 {
836 {
837
839 }
840 yyextra->htmlContextStack.pop_back();
841 }
843 }
844<Comment>"<"{AHTML} { // potential start of HTML anchor, see issue 9200
845 yyextra->htmlAnchorStr = yytext;
846 yyextra->htmlAnchor = false;
847 BEGIN(HtmlA);
848 }
849<HtmlA>{ANCHTML} { // only labels that can be converted to doxygen anchor
850 yyextra->htmlAnchorStr += yytext;
852 size_t s=tag.find("=");
853 char c=tag[s+1];
855 if (c=='\'' || c=='"')
856 {
857 size_t e=tag.find(c,s+2);
859 {
860 id=tag.mid(s+2,e-s-2);
862 }
863 }
864 else
865 {
866 id=tag.mid(s+1);
868 }
869 if (!id.empty() && !yyextra->htmlAnchor)
870 {
871
875 yyextra->htmlAnchor = true;
876 }
877 }
878<HtmlA>("\""[^\n\"]*"\""|"'"[^\n']*"'") {
879 yyextra->htmlAnchorStr += yytext;
880 }
881<HtmlA>">"|"/>" {
882 if (!yyextra->htmlAnchor)
883 {
884 addOutput(yyscanner,yyextra->htmlAnchorStr);
886 }
887 else
888 {
889 if (yyleng == 1)
890 {
892 }
893 }
894 BEGIN(Comment);
895 }
896<HtmlA>{DOCNL} { // newline
897 yyextra->htmlAnchorStr += yytext;
898 if (*yytext == '\n') yyextra->lineNr++;
899 }
900<HtmlA>. { // catch-all for anything else
901 yyextra->htmlAnchorStr += yytext;
902 }
903<Comment>"<"{SUMMARY}">" { // start of a .NET XML style brief description
904 if (yyextra->htmlDetailsStack.empty())
905 {
907 }
908 else
909 {
911 }
912 }
913<Comment>"<"{REMARKS}">" { // start of a .NET XML style detailed description
916 }
917<Comment>"</"{SUMMARY}">" { // start of a .NET XML style detailed description
918 if (!yyextra->htmlDetailsStack.empty())
919 {
921 }
922 else
923 {
925 }
926 }
927<Comment>"</"{REMARKS}">" { // end of a brief or detailed description
930 }
931<Comment>"<"{CAPTION}{ATTR}">" {
933 size_t s=tag.find("id=");
935 {
936 char c=tag[s+3];
937 if (c=='\'' || c=='"')
938 {
939 size_t e=tag.find(c,s+4);
941 {
944 }
945 }
946 }
948 }
949<Comment>"<"{PRE}{ATTR}">" {
950 yyextra->insidePre=true;
952 }
953<Comment>"</"{PRE}">" {
954 yyextra->insidePre=false;
956 }
957<Comment>{RCSTAG} { // RCS tag which end a brief description
959 REJECT;
960 }
961<Comment>"<!--" {
962 BEGIN(HtmlComment);
963 }
964<Comment>"<!\[CDATA\[" {
965 BEGIN(CdataSection);
966 }
967<Comment>{B}*{CMD}"endinternal"{B}* {
969 if (!yyextra->inInternalDocs)
970 warn(yyextra->fileName,yyextra->lineNr,
971 "found \\endinternal without matching \\internal"
972 );
973 yyextra->inInternalDocs = false;
974 }
975<Comment>{B}*"\\ilinebr "{B}* { // preserve spacing around \\ilinebr
977 }
978<Comment>(\n|"\\ilinebr ")/({B}*(\n|{IFILELINE}?"\\ilinebr "))+ { // at least one blank line (or blank line command)
980 {
982 }
983 else
984 {
985 REJECT;
986 }
987 }
988<Comment>{B}*{CMD}[a-z_A-Z]+"{"[^}]*"}"{B}* |
989<Comment>{B}*{CMD}[a-z_A-Z]+{B}* { // potentially interesting command
990
992 size_t idx = fullMatch.
find(
'{');
993
994 if ((idx !=
DString::npos) && (idx > 1) && (yytext[idx-1] ==
'f') && (yytext[idx-2] ==
'\\' || yytext[idx-2] ==
'@')) REJECT;
1000 {
1002 }
1003 else
1004 {
1008 }
1010
1012 {
1013 int i=0;
1014 while (yytext[i]==' ' || yytext[i]=='\t') i++;
1015 yyextra->spaceBeforeCmd = fullMatch.
left(i);
1018 !(yyextra->inContext==
OutputXRef && cmdName==
"parblock"))
1019 {
1020 yyextra->briefEndsAtDot=false;
1022
1024 }
1025
1026 if (it->second.handler && it->second.handler(yyscanner, cmdName, optList))
1027 {
1028
1029
1030
1031 yyextra->parseMore=true;
std::vector< std::string > StringVector
StringVector split(const std::string &s, const std::string &delimiter)
split input string s by string delimiter delimiter.
1032
1033 yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);
1035 }
1036 else if (it->second.handler==nullptr)
1037 {
1038
1039
1041 }
1042 }
1043 else
1044 {
1046 }
1047 }
1048<Comment>{B}*({CMD}{CMD})"f"[$\[{] { // escaped formula command
1050 }
1051<Comment>{B}*{CMD}"~"[a-z_A-Z-]* { // language switch command
1053 if (!langId.
empty() &&
1055 {
1057 {
1058 warn(yyextra->fileName,yyextra->lineNr,
1060 }
1061 BEGIN(SkipLang);
1062 }
1063 }
#define Config_getEnumAsString(name)
#define Config_isAvailableEnum(name, value)
int dstricmp(const char *s1, const char *s2)
1064<Comment>{B}*{CMD}"f{"[^}\n]+"}"("{"?) { // start of a formula with custom environment
1066 yyextra->formulaText="";
1067 yyextra->formulaPreText="\\begin";
1068 yyextra->formulaPostText="";
1070 if (yyextra->formulaEnv.at(yyextra->formulaEnv.length()-1)=='{')
1071 {
1072
1073 yyextra->formulaEnv=yyextra->formulaEnv.left(yyextra->formulaEnv.length()-1);
1074 }
1075 yyextra->formulaPreText+=yyextra->formulaEnv;
1076 yyextra->formulaNewLines=0;
1077 BEGIN(ReadFormulaLong);
1078 }
1079<Comment>{B}*{CMD}"f$" { // start of a inline formula
1080 yyextra->formulaText="";
1081 yyextra->formulaPreText="$";
1082 yyextra->formulaPostText="";
1083 yyextra->formulaNewLines=0;
1084 BEGIN(ReadFormulaShort);
1085 }
1086<Comment>{B}*{CMD}"f(" { // start of a inline formula
1087 yyextra->formulaText="";
1088 yyextra->formulaPreText="";
1089 yyextra->formulaPostText="";
1090 yyextra->formulaNewLines=0;
1091 BEGIN(ReadFormulaRound);
1092 }
1093<Comment>{B}*{CMD}"f[" { // start of a block formula
1095 yyextra->formulaText="";
1096 yyextra->formulaPreText="\\[";
1097 yyextra->formulaPostText="";
1098 yyextra->formulaNewLines=0;
1099 BEGIN(ReadFormulaLong);
1100 }
1101<Comment>{B}*{CMD}"{" { // begin of a group
1102
1103 yyextra->docGroup.open(yyextra->current,yyextra->fileName,yyextra->lineNr);
1104 }
1105<Comment>{B}*{CMD}"}" { // end of a group
1106
1107 yyextra->docGroup.close(yyextra->current,yyextra->fileName,yyextra->lineNr,true);
1108 yyextra->docGroup.clearHeader();
1109 yyextra->parseMore=true;
1110 yyextra->needNewEntry = true;
1111 yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + (int)strlen(yytext);
1113 }
1114<Comment>{B}*{CMD}[$@\\&~<>#%] { // escaped character
1116 }
1117<Comment>[a-z_A-Z]+ { // normal word
1119 }
1120<Comment>^{B}*"."{Bopt}/\n { // explicit end autolist: e.g " ."
1122 }
1123<Comment>^{B}*[1-9][0-9]*"."{B}+ |
1124<Comment>^{B}*[*+]{B}+ { // start of autolist
1125 if (!yyextra->markdownSupport)
1126 {
1127 REJECT;
1128 }
1129 else
1130 {
1132 {
1133 yyextra->briefEndsAtDot=false;
1135 }
1137 }
1138 }
1139<Comment>^{B}*"-"{B}+ { // start of autolist
1141 {
1142 yyextra->briefEndsAtDot=false;
1144 }
1146 }
1147<Comment>^{B}*([\-:|]{B}*)*("--"|"---")({B}*[\-:|])*{Bopt}/\n { // horizontal line (dashed)
1149 }
1150<Comment>{CMD}"---" { // escaped mdash
1152 }
1153<Comment>{CMD}"--" { // escaped ndash
1155 }
1156<Comment>"---" { // mdash
1157 addOutput(yyscanner,yyextra->insidePre || yyextra->markdownSupport ? yytext :
"—");
1158 }
1159<Comment>"--" { // ndash
1160 addOutput(yyscanner,yyextra->insidePre || yyextra->markdownSupport ? yytext :
"–");
1161 }
1162<Comment>"-#"{B}+ { // numbered item
1164 {
1165 yyextra->briefEndsAtDot=false;
1167 }
1169 }
1170<Comment>[?!][a-z_A-Z0-9\(\)=<] |
1171<Comment>("."+)[a-z_A-Z0-9\)] { // . at start or in the middle of a word, or ellipsis
1172
1174 }
1175<Comment>{CMD}[\.?!] { // we have to be a bit careful with the special commands
1176
1178 }
1179<Comment>".\\"[ \t] { // . with escaped space.
1182 }
1183<Comment>"."[,:;] { // . with some puntuations such as "e.g.," or "e.g.:"
1185 }
1186<Comment>"...\\"[ \t] { // ellipsis with escaped space.
1188 }
1189<Comment>"..."/[^\.] { // ellipsis
1191 }
1192<Comment>".."[\.]?/[^ \t\n] { // internal ellipsis
1194 }
1195<Comment>(\n|"\\ilinebr ")({B}*(\n|"\\ilinebr "))+ { // at least one blank line (or blank line command)
1197 {
1198
1200 yy_size_t i;
1201 for (i=0;i<(yy_size_t)yyleng;)
1202 {
1203 if (yytext[i]==
'\n')
addOutput(yyscanner,
'\n'),i++;
1204 else if (strncmp(yytext+i,
"\\ilinebr ",9)==0)
addOutput(yyscanner,
"\\ilinebr "),i+=9;
1205 else i++;
1206 }
1207 }
1209 {
1210 yy_size_t i;
1211 for (i=0;i<(yy_size_t)yyleng;)
1212 {
1213 if (yytext[i]==
'\n')
addOutput(yyscanner,
'\n'),i++;
1214 else if (strncmp(yytext+i,
"\\ilinebr ",9)==0)
addOutput(yyscanner,
"\\ilinebr "),i+=9;
1215 else i++;
1216 }
1218 }
1219 else
1220 {
1221
1223 }
1225 }
1226<Comment>"."[?!] |
1227<Comment>[\.?!] { // potential end of a JavaDoc style comment
1229 if (yyextra->briefEndsAtDot)
1230 {
1232 yyextra->briefEndsAtDot=false;
1233 }
1234 }
1235<Comment>{DOCNL} { // newline
1237 if (*yytext == '\n') yyextra->lineNr++;
1238 }
1239<Comment>"<"[/]?{TABLEDEL}">" { // In case in xrefitem type some special handling is required
1241 {
1244 }
1245 else
1246 {
1247 REJECT;
1248 }
1249 }
1250<Comment>. { // catch-all for anything else
1252 }
1253
1254
1255
1256
1257<HtmlComment>"---"[!]?">"{B}* {
1258 warn(yyextra->fileName,yyextra->lineNr,
1259 "incorrect HTML end comment --->"
1260 );
1261 }
1262<HtmlComment>"--"[!]?">"{B}* { BEGIN( Comment ); }
1263<HtmlComment>{DOCNL} {
1264 if (*yytext=='\n')
1265 {
1266 yyextra->lineNr++;
1268 }
1269 }
1270<HtmlComment>[^\\\n\-]+ { // ignore unimportant characters
1271 }
1272<HtmlComment>. { // ignore every else
1273 }
1274
1275<CdataSection>"\]\]>" {
1276 BEGIN( Comment );
1277 }
1278<CdataSection>{DOCNL} {
1280 if (*yytext=='\n') yyextra->lineNr++;
1281 }
1282<CdataSection>[<>&] { // the special XML characters for iwhich the CDATA section is especially used
1285 }
1286<CdataSection>[^\\\n\]<>&]+ {
1288 }
1289<CdataSection>. {
1291 }
1292
1293
1294
1295<ReadFormulaShort,ReadFormulaShortSection>{CMD}"f$" { // end of inline formula
1296 yyextra->formulaPostText+="$";
1299 if (YY_START == ReadFormulaShort)
1300 {
1301 BEGIN(Comment);
1302 }
1303 else
1304 {
1305 yyextra->sectionTitle+= " "+form;
1306 BEGIN(SectionTitle);
1307 }
1308 }
1309<ReadFormulaRound,ReadFormulaRoundSection>{CMD}"f)" { // end of inline formula
1312 if (YY_START == ReadFormulaRound)
1313 {
1314 BEGIN(Comment);
1315 }
1316 else
1317 {
1318 yyextra->sectionTitle+= " "+form;
1319 BEGIN(SectionTitle);
1320 }
1321 }
1322<ReadFormulaLong>{CMD}"f]" { // end of block formula
1323 yyextra->formulaPostText+="\\]";
1325 BEGIN(Comment);
1326 }
1327<ReadFormulaLong>{CMD}"f}" { // end of custom env formula
1328 yyextra->formulaPostText+="\\end";
1329 yyextra->formulaPostText+=yyextra->formulaEnv;
1331 BEGIN(Comment);
1332 }
1333<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>[^\\@\n]+ { // any non-special character
1334 yyextra->formulaText+=yytext;
1335 }
1336<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>\n { // new line
1337 yyextra->formulaNewLines++;
1338 yyextra->formulaText+=*yytext;
1339 yyextra->lineNr++;
1340 addIline(yyscanner,yyextra->lineNr);
1341 }
1342<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>. { // any other character
1343 yyextra->formulaText+=*yytext;
1344 }
1345
1346
1347
1348<EnumDocArg1>{SCOPEID} { // handle argument
1350 yyextra->current->name = yytext;
1351 BEGIN( Comment );
1352 }
1353<EnumDocArg1>{LC} { // line continuation
1354 yyextra->lineNr++;
1356 }
1357<EnumDocArg1>{DOCNL} { // missing argument
1358 warn(yyextra->fileName,yyextra->lineNr,
1359 "missing argument after '\\enum'."
1360 );
1362 BEGIN( Comment );
1363 }
1364<EnumDocArg1>. { // ignore other stuff
1365 }
1366
1367
1368
1369<NameSpaceDocArg1>{SCOPENAME} { // handle argument
1373 BEGIN( Comment );
1374 }
DString removeRedundantWhiteSpace(const DString &s)
1375<NameSpaceDocArg1>{LC} { // line continuation
1376 yyextra->lineNr++;
1378 }
1379<NameSpaceDocArg1>{DOCNL} { // missing argument
1380 warn(yyextra->fileName,yyextra->lineNr,
1381 "missing argument after '\\namespace'."
1382 );
1384 BEGIN( Comment );
1385 }
1386<NameSpaceDocArg1>. { // ignore other stuff
1387 }
1388
1389
1390
1391<PackageDocArg1>{ID}("."{ID})* { // handle argument
1392 yyextra->current->name = yytext;
1393 BEGIN( Comment );
1394 }
1395<PackageDocArg1>{LC} { // line continuation
1396 yyextra->lineNr++;
1398 }
1399<PackageDocArg1>{DOCNL} { // missing argument
1400 warn(yyextra->fileName,yyextra->lineNr,
1401 "missing argument after \\package."
1402 );
1404
1405
1406 BEGIN( Comment );
1407 }
1408<PackageDocArg1>. { // ignore other stuff
1409 }
1410
1411
1412
1413<ConceptDocArg1>{SCOPEID} { // handle argument
1415 yyextra->current->name = yytext;
1416 BEGIN( Comment );
1417 }
1418<ConceptDocArg1>{LC} { // line continuation
1419 yyextra->lineNr++;
1421 }
1422<ConceptDocArg1>{DOCNL} { // missing argument
1423 warn(yyextra->fileName,yyextra->lineNr,
1424 "missing argument after '\\concept'."
1425 );
1427 BEGIN( Comment );
1428 }
1429<ConceptDocArg1>. { // ignore other stuff
1430 }
1431
1432
1433<ModuleDocArg1>{MODULE_ID} { // handle argument
1435 yyextra->current->name = yytext;
1436 BEGIN( Comment );
1437 }
1438<ModuleDocArg1>{LC} { // line continuation
1439 yyextra->lineNr++;
1441 }
1442<ModuleDocArg1>{DOCNL} { // missing argument
1443 warn(yyextra->fileName,yyextra->lineNr,
1444 "missing argument after '\\module'."
1445 );
1447 BEGIN( Comment );
1448 }
1449<ModuleDocArg1>. { // ignore other stuff
1450 }
1451
1452
1453
1454<ClassDocArg1>{SCOPENAME}{TMPLSPEC} {
1458 BEGIN( ClassDocArg2 );
1459 }
1460<ClassDocArg1>{SCOPENAME} { // first argument
1463 yyextra->current->name =
substitute(yytext,
".",
"::");
1464 if (yyextra->current->section.isProtocolDoc())
1465 {
1466 yyextra->current->name+="-p";
1467 }
1468
1469 BEGIN( ClassDocArg2 );
1470 }
1471<CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" {
1474 yyextra->current->name =
substitute(yytext,
".",
"::");
1475 BEGIN( ClassDocArg2 );
1476 }
1477<ClassDocArg1,CategoryDocArg1>{LC} { // line continuation
1478 yyextra->lineNr++;
1480 }
1481<ClassDocArg1,CategoryDocArg1>{DOCNL} {
1482 warn(yyextra->fileName,yyextra->lineNr,
1483 "missing argument after '\\{}'.",yyextra->currentCmd
1484 );
1486 BEGIN( Comment );
1487 }
1488<ClassDocArg1,CategoryDocArg1>. { // ignore other stuff
1489 }
1490
1491<ClassDocArg2>{DOCNL} {
1493 BEGIN( Comment );
1494 }
1495<ClassDocArg2>{FILE}|"<>" { // second argument; include file
1496 yyextra->current->includeFile = yytext;
1497 BEGIN( ClassDocArg3 );
1498 }
1499<ClassDocArg2>{LC} { // line continuation
1500 yyextra->lineNr++;
1502 }
1503<ClassDocArg2>. { // ignore other stuff
1504 }
1505
1506<ClassDocArg3>[<"]?{FILE}?[">]? { // third argument; include file name
1507 yyextra->current->includeName = yytext;
1508 BEGIN( Comment );
1509 }
1510<ClassDocArg3>{LC} { // line continuation
1511 yyextra->lineNr++;
1513 }
1514<ClassDocArg3>{DOCNL} {
1515
1516 if (yyextra->current->includeFile!="<>")
1517 {
1518 yyextra->current->includeName = yyextra->current->includeFile;
1519 }
1521 BEGIN( Comment );
1522 }
1523<ClassDocArg3>. { // ignore other stuff
1524 }
1525
1526
1527
1528<GroupDocArg1>{LABELID}(".html"|".xhtml")? { // group name
1529 yyextra->current->name = yytext;
1530
1531
1532
1533 if (yyextra->current->name.endsWith(".html"))
1534 {
1535 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-5);
1536 }
1537 else if (yyextra->current->name.endsWith(".xhtml"))
1538 {
1539 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-6);
1540 }
1541 yyextra->current->type.clear();
1542 BEGIN(GroupDocArg2);
1543 }
1544<GroupDocArg1>"\\"{B}*"\n" { // line continuation
1545 yyextra->lineNr++;
1547 }
1548<GroupDocArg1>{DOCNL} { // missing argument!
1549 warn(yyextra->fileName,yyextra->lineNr,
1550 "missing group name after {}",
1551 yyextra->current->groupDocCmd()
1552 );
1553
1554
1556 BEGIN( Comment );
1557 }
1558<GroupDocArg1>. { // ignore other stuff
1559 }
1560<GroupDocArg2>"\\"{B}*"\n" { // line continuation
1561 yyextra->lineNr++;
1563 }
1564<GroupDocArg2>[^\n\\]+ { // title (stored in type)
1565 yyextra->current->type += yytext;
1566 }
1567<GroupDocArg2>{DOCNL}+ {
1568 yyextra->current->type = yyextra->current->type.stripWhiteSpace();
1570 yyextra->current->type.empty()
1571 )
1572 {
1573 warn(yyextra->fileName,yyextra->lineNr,
1574 "missing title after "
1575 "\\defgroup {}", yyextra->current->name
1576 );
1577 }
1579 int extraLineNr = 0;
1581 {
1582 for (int i = 0; i < yyleng; i++)
1583 {
1584 if (yytext[i]=='\n') extraLineNr++;
1585 }
1586 }
1587
1588
1590 {
1591 addOutput(yyscanner,
" \\ifile \""+ yyextra->fileName);
1592 addOutput(yyscanner,
"\" \\iline " +
DString().setNum(yyextra->lineNr + extraLineNr) +
" \\ilinebr ");
1593 }
1594 BEGIN( Comment );
1595 }
1596<GroupDocArg2>. { // title (stored in type)
1597 yyextra->current->type += yytext;
1598 }
1599
1600
1601
1602<PageDocArg1>[^\n]*"\\ilinebr @ianchor"\{[^\]\n]*\}{B}{FILE} { // special case where the Markdown processor has rewritten
1603
1604
1606 size_t start = text.
find(
'{');
1607 size_t end = text.
find(
'}',start+1);
1608 yyextra->current->name = text.
mid(
end+2);
1609 size_t istart = yyextra->current->name.
find(
"\\ilinebr");
1611 {
1612 DString rest = yyextra->current->name.
mid(istart);
1614 yyextra->current->name = yyextra->current->name.left(istart);
1615 }
1616 yyextra->current->args = text.
mid(start+1,
end-start-1);
1617
1618 BEGIN( PageDocArg2 );
1619 }
DirIterator end(const DirIterator &) noexcept
1620<PageDocArg1>{FILE} { // first argument; page name
1622 yyextra->current->args = "";
1623 BEGIN( PageDocArg2 );
1624 }
1625<PageDocArg1>{LC} { yyextra->lineNr++;
1627 }
1628<PageDocArg1>{DOCNL} {
1629 warn(yyextra->fileName,yyextra->lineNr,
1630 "missing argument after \\page."
1631 );
1633
1634
1635 BEGIN( Comment );
1636 }
1637<PageDocArg1>. { // ignore other stuff
1638 }
1639<PageDocArg2>{DOCNL} { // second argument; page title
1641
1642
1643 addOutput(yyscanner,
" \\ifile \""+ yyextra->fileName);
1644 addOutput(yyscanner,
"\" \\iline " +
DString().setNum(yyextra->lineNr) +
" \\ilinebr ");
1645 BEGIN( Comment );
1646 }
1647<PageDocArg2>{CMD}[<>] {
1648
1652 yyextra->current->args += tmp;
1653 }
1654<PageDocArg2>. {
1655 yyextra->current->args += yytext;
1656 }
1657
1658<ParamArg1>{ID}/{B}*"," {
1660 }
1661<ParamArg1>"," {
1663 }
1664<ParamArg1>{DOCNL} {
1665 if (*yytext=='\n') yyextra->lineNr++;
1667 }
1668<ParamArg1>{ID} {
1670 BEGIN( Comment );
1671 }
1672<ParamArg1>. {
1673 unput(yytext[0]);
1674 BEGIN( Comment );
1675 }
1676
1677
1678
1679<FileDocArg1>{DOCNL} { // no file name specified
1681
1682
1683 BEGIN( Comment );
1684 }
1685<FileDocArg1>{FILE} { // first argument; name
1687 BEGIN( Comment );
1688 }
1689<FileDocArg1>{LC} { yyextra->lineNr++;
1691 }
1692<FileDocArg1>. { // ignore other stuff
1693 }
1694
1695
1696
1697<XRefItemParam1>{LABELID} { // first argument
1698 yyextra->newXRefItemKey=yytext;
1700 BEGIN(XRefItemParam2);
1701 }
1702<XRefItemParam1>{LC} { // line continuation
1703 yyextra->lineNr++;
1705 }
1706<XRefItemParam1>{DOCNL} { // missing arguments
1707 warn(yyextra->fileName,yyextra->lineNr,
1708 "Missing first argument of \\xrefitem"
1709 );
1710 if (*yytext=='\n') yyextra->lineNr++;
1713 BEGIN( Comment );
1714 }
1715<XRefItemParam1>. { // ignore other stuff
1716 }
1717
1718<XRefItemParam2>"\""[^\n\"]*"\"" { // second argument
1720 BEGIN(XRefItemParam3);
1721 }
1722<XRefItemParam2>{LC} { // line continuation
1723 yyextra->lineNr++;
1725 }
1726<XRefItemParam2>{DOCNL} { // missing argument
1727 warn(yyextra->fileName,yyextra->lineNr,
1728 "Missing second argument of \\xrefitem"
1729 );
1730 if (*yytext=='\n') yyextra->lineNr++;
1733 BEGIN( Comment );
1734 }
1735<XRefItemParam2>. { // ignore other stuff
1736 }
1737
1738<XRefItemParam3>"\""[^\n\"]*"\"" { // third argument
1741 BEGIN( Comment );
1742 }
1743<XRefItemParam2,XRefItemParam3>{LC} { // line continuation
1744 yyextra->lineNr++;
1746 }
1747<XRefItemParam3>{DOCNL} { // missing argument
1748 warn(yyextra->fileName,yyextra->lineNr,
1749 "Missing third argument of \\xrefitem"
1750 );
1751 if (*yytext=='\n') yyextra->lineNr++;
1754 BEGIN( Comment );
1755 }
1756<XRefItemParam3>. { // ignore other stuff
1757 }
1758
1759
1760
1761
1762<RelatesParam1>({ID}("::"|"."))*{ID} { // argument
1763 yyextra->current->relates = yytext;
1764
1765
1766
1767
1768 BEGIN( Comment );
1769 }
1770<RelatesParam1>{LC} { // line continuation
1771 yyextra->lineNr++;
1773 }
1774<RelatesParam1>{DOCNL} { // missing argument
1775 warn(yyextra->fileName,yyextra->lineNr,
1776 "Missing argument of '\\{}' command",yyextra->currentCmd
1777 );
1779
1780
1781 BEGIN( Comment );
1782 }
1783<RelatesParam1>. { // ignore other stuff
1784 }
1785
1786
1787
1788<Qualifier>{LABELID} { // unquoted version, simple label
1789 yyextra->current->qualifiers.emplace_back(yytext);
1790 BEGIN( Comment );
1791 }
1792<Qualifier>"\""[^\"]*"\"" { // quotes version, add without quotes
1793 std::string inp(yytext);
1794 yyextra->current->qualifiers.push_back(inp.substr(1,yyleng-2));
1795 BEGIN( Comment );
1796 }
1797<Qualifier>{DOCNL} { // missing argument
1798 warn(yyextra->fileName,yyextra->lineNr,
1799 "Missing argument of '\\{}' command",yyextra->currentCmd
1800 );
1802 BEGIN( Comment );
1803 }
1804<Qualifier>. {
1805 warn(yyextra->fileName,yyextra->lineNr,
1806 "Argument of '\\{}' command should be quoted",yyextra->currentCmd
1807 );
1809 BEGIN( Comment );
1810 }
1811
1812<ILine>{LINENR}/[\\@\n\.] |
1813<ILine>{LINENR}{B} {
1814 bool ok = false;
1816 if (!ok)
1817 {
1818 warn(yyextra->fileName,yyextra->lineNr,
"Invalid line number '{}' for iline command",yytext);
1819 }
1820 else
1821 {
1822 yyextra->lineNr = nr;
1823 }
1825 if (YY_START == ILine)
1826 {
1827 BEGIN(Comment);
1828 }
1829 else
1830 {
1831 yyextra->sectionTitle+=yytext;
1832 BEGIN(SectionTitle);
1833 }
1834 }
int toInt(bool *ok=nullptr, int base=10) const
1835<ILine,ILineSection>. {
1837 if (YY_START == ILine)
1838 {
1839 BEGIN(Comment);
1840 }
1841 else
1842 {
1843 yyextra->sectionTitle+=yytext;
1844 BEGIN(SectionTitle);
1845 }
1846 }
1847
1848
1849<IRaise>{B}*[0-9]+/[\\@\n\.] |
1850<IRaise>{B}*[0-9]+{B} {
1851 bool ok = false;
1853 if (!ok)
1854 {
1855 warn(yyextra->fileName,yyextra->lineNr,
"Invalid level '{}' for iraise command",yytext);
1856 }
1857 else
1858 {
1859 yyextra->raiseLevel = nr;
1860 }
1861 BEGIN(Comment);
1862 }
1863<IRaise>. {
1864 unput(yytext[0]);
1865 BEGIN(Comment);
1866 }
1867
1868
1869<IRaisePrefix>{B}*"\""({LABELID})?"\"" {
1871 yyextra->raisePrefix = text.stripWhiteSpace().mid(1,text.length()-2);
1873 BEGIN(Comment);
1874 }
1875<IRaisePrefix>. {
1876 unput(yytext[0]);
1877 BEGIN(Comment);
1878 }
1879
1880
1881
1882
1883<IFile,IFileSection>{FILE} {
1886 if (yytext[0] == '\"') yyextra->fileName = text.mid(1,text.length()-2);
1887 else yyextra->fileName = yytext;
1888 if (YY_START == IFile)
1889 {
1890 BEGIN(Comment);
1891 }
1892 else
1893 {
1894 yyextra->sectionTitle+=yytext;
1895 BEGIN(SectionTitle);
1896 }
1897 }
1898
1899<LinkSection>[^\\@\n]* {
1900 yyextra->sectionTitle+=yytext;
1901 }
1902<LinkSection>{CMD}{CMD} {
1903 yyextra->sectionTitle+=yytext;
1904 }
1905<LinkSection>{DOCNL} {
1907 if (*yytext == '\n') yyextra->lineNr++;
1908 yyextra->sectionTitle+=yytext;
1909 }
1910<LinkSection>{CMD}"endlink" {
1911 yyextra->sectionTitle+=yytext;
1912 BEGIN(SectionTitle);
1913 }
1914<LinkSection>. {
1915 yyextra->sectionTitle+=yytext;
1916 }
1917<LinkSection><<EOF>> {
1918 warn(yyextra->fileName,yyextra->lineNr,
1919 "reached end of comment while inside a '\\link' command, missing '\\endlink' command"
1920 );
1922 }
1923
1924
1925<LineParam>{CMD}{CMD} { // escaped command
1927 }
1928<LineParam>{DOCNL} { // end of argument
1929
1930
1932 BEGIN( Comment );
1933 }
1934<LineParam>{LC} { // line continuation
1935 yyextra->lineNr++;
1937 }
1938<LineParam>({CMD}{CMD}){ID} { // escaped command
1940 }
1941<LineParam>. { // ignore other stuff
1943 }
1944
1945
1946
1947<SectionLabel>{LABELID} {
1948 yyextra->sectionLabel+=yytext;
1949 }
1950<SectionLabel>{CMD}"lineinfo"("{}")? {
1952 }
1953<SectionLabel>{CMD}"fileinfo"("{"[^}]*"}")? {
1954 FileInfo fi(yyextra->fileName.str());
1955 bool hasOption = false;
1957 if (yytext[yyleng-1] == '}')
1958 {
1963 for (const auto &opt_ : optList)
1964 {
1966 std::string opt = optStripped.
lower().
str();
1968 if (!result.
empty())
1969 {
1970 if (hasOption)
1971 {
1972 warn(yyextra->fileName,yyextra->lineNr,
"Multiple options specified with \\fileinfo, discarding '{}'", optStripped);
1973 }
1974 else
1975 {
1976 label = result;
1977 }
1978 hasOption = true;
1979 }
1980 else
1981 {
1982 warn(yyextra->fileName,yyextra->lineNr,
"Unknown option specified with \\fileinfo: '{}'", optStripped);
1983 }
1984 }
1985 }
1986 if (!hasOption)
1987 {
1989 {
1991 }
1992 else
1993 {
1994 label=yyextra->fileName;
1995 }
1996 }
1998 yyextra->sectionLabel+=label;
1999 }
2000<SectionLabel>{DOCNL} {
2001 yyextra->sectionTitle.clear();
2002 if (yyextra->sectionLabel.empty())
2003 {
2004 warn(yyextra->fileName,yyextra->lineNr,
2005 "\\section command has no label"
2006 );
2007 }
2008 else
2009 {
2010 yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
2011 addOutput(yyscanner,yyextra->sectionLabel.data());
2013 }
2014 if (*yytext=='\n') yyextra->lineNr++;
2016 BEGIN( Comment );
2017 }
2018<SectionLabel>. { // invalid character for section label
2019 if (yyextra->sectionLabel.empty())
2020 {
2021 warn(yyextra->fileName,yyextra->lineNr,
2022 "Invalid or missing section label"
2023 );
2024 BEGIN(Comment);
2025 }
2026 else
2027 {
2028 yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
2029 addOutput(yyscanner,yyextra->sectionLabel.data());
2030 yyextra->sectionTitle.clear();
2032 BEGIN(SectionTitle);
2033 }
2034 }
2035<SectionTitle>{STAopt}/"\n" { // end of section title
2038 BEGIN( Comment );
2039 }
2040<SectionTitle>{STopt}"\\\\ilinebr" { // escaped end of section title
2041 yyextra->sectionTitle+=
substitute(yytext,
"#",
"@#");
2042 }
2043<SectionTitle>{STopt}/"\\ilinebr" { // end of section title
2046 BEGIN( Comment );
2047 }
2048<SectionTitle>{B}*{CMD}"f$" {
2049 yyextra->formulaText="";
2050 yyextra->formulaPreText="$";
2051 yyextra->formulaPostText="";
2052 yyextra->formulaNewLines=0;
2053 BEGIN(ReadFormulaShortSection);
2054 }
2055<SectionTitle>{B}*{CMD}"f(" { // start of a inline formula
2056 yyextra->formulaText="";
2057 yyextra->formulaPreText="";
2058 yyextra->formulaPostText="";
2059 yyextra->formulaNewLines=0;
2060 BEGIN(ReadFormulaRoundSection);
2061 }
2062<SectionTitle>{B}*{CMD}"~"[a-z_A-Z-]* | // language switch command
2063<SectionTitle>{B}*{CMD}"f"[\[{] { // block formula
2067 warn(yyextra->fileName,yyextra->lineNr,
2068 "'\\{}' command is not allowed in section title, ending section title.",
2070 );
2072 BEGIN(Comment);
2073 }
2074<SectionTitle>{LC} { // line continuation
2075 yyextra->lineNr++;
2077 }
2078<SectionTitle>[^\n@\\]* { // any character without special meaning
2079 yyextra->sectionTitle+=
substitute(yytext,
"#",
"@#");
2081 }
2082<SectionTitle>{B}*{CMD}{CMD} {
2083 yyextra->sectionTitle+=yytext;
2085 }
2086<SectionTitle>{CMD}# { // escaped hash
2087 yyextra->sectionTitle+=yytext;
2089 }
2090<SectionTitle>{B}*{CMD}[a-z_A-Z]+"{"[^}]*"}"{B}* |
2091<SectionTitle>{B}*{CMD}[a-z_A-Z]+{B}* { // handling command in section title
2093 size_t idx = fullMatch.
find(
'{');
2094
2095 if ((idx !=
DString::npos) && (idx > 1) && (yytext[idx-1] ==
'f') && (yytext[idx-2] ==
'\\' || yytext[idx-2] ==
'@')) REJECT;
2101 {
2103 }
2104 else
2105 {
2109 }
2112 {
2113 switch (it->second.sectionHandling)
2114 {
2116 {
2117 int i=0;
2118 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2119 yyextra->sectionTitle+=fullMatch.
left(i);
2120 yyextra->sectionTitle+='@';
2121 yyextra->sectionTitle+=fullMatch.
mid(i);
2125 warn(yyextra->fileName,yyextra->lineNr,
2126 "'\\{}' command is not allowed in section title, escaping command.",cmdName
2127 );
2128 }
2129 break;
2131 {
2134 warn(yyextra->fileName,yyextra->lineNr,
2135 "'\\{}' command is not allowed in section title, ending section title.",cmdName
2136 );
2138 BEGIN(Comment);
2139 }
2140 break;
2142 {
2143 if (cmdName == "fileinfo")
2144 {
2145 int i=0;
2146 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2147 yyextra->sectionTitle+=fullMatch.
left(i);
2150 }
2151 else if (cmdName == "lineinfo")
2152 {
2153 int i=0;
2154 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2155 yyextra->sectionTitle+=fullMatch.
left(i);
2159 }
2160 else if (cmdName == "raisewarning")
2161 {
2162 yyextra->raiseWarning = "";
2163 BEGIN(RaiseWarningSection);
2164 }
2165 else if (cmdName == "noop")
2166 {
2168 BEGIN(Noop);
2169 }
2170 else if (cmdName == "cite")
2171 {
2172 yyextra->sectionTitle+=yytext;
2174 BEGIN(CiteLabelSection);
2175 }
2176 else if (cmdName == "iline")
2177 {
2178 yyextra->sectionTitle+=yytext;
2180 BEGIN(ILineSection);
2181 }
2182 else if (cmdName == "ifile")
2183 {
2184 yyextra->sectionTitle+=yytext;
2186 BEGIN(IFileSection);
2187 }
2188 else if ((cmdName == "anchor") || (cmdName == "ianchor"))
2189 {
2191 if (optList.empty())
2192 {
2193 yyextra -> anchorTitle = "";
2194 }
2195 else
2196 {
2198 yyextra -> anchorTitle =
join(optList,
" ");
2199 }
2201 BEGIN(AnchorLabelSection);
2202 }
2203 else if (cmdName == "link")
2204 {
2205 yyextra->sectionTitle+=yytext;
2206 BEGIN(LinkSection);
2207 }
2208 else
2209 {
2210 yyextra->sectionTitle+=yytext;
2211 warn(yyextra->fileName,yyextra->lineNr,
2212 "internal error '\\{}' command is to be replaced in section title.",cmdName
2213 );
2214 }
2215 }
2216 break;
2218 {
2219 yyextra->sectionTitle+=yytext;
2221 }
2222 break;
2223 }
2224 }
2225 else
2226 {
2227 yyextra->sectionTitle+=yytext;
2229 }
2230 }
2231<SectionTitle>. { // anything else
2232 yyextra->sectionTitle+=yytext;
2234 }
2235
2236
2237
2238<SubpageLabel>{FILE} { // first argument
2240
2241
2242 yyextra->current->extends.emplace_back(yytext,Protection::Public,Specifier::Normal);
2243 BEGIN(SubpageTitle);
2244 }
2245<SubpageLabel>{DOCNL} { // missing argument
2246 warn(yyextra->fileName,yyextra->lineNr,
2247 "\\subpage command has no label"
2248 );
2249 if (*yytext=='\n') yyextra->lineNr++;
2251 BEGIN( Comment );
2252 }
2253<SubpageLabel>. {
2254 unput(yytext[0]);
2255 BEGIN( Comment );
2256 }
2257<SubpageTitle>{DOCNL} { // no title, end command
2259 BEGIN( Comment );
2260 }
2261<SubpageTitle>[ \t]*"\""[^\"\n]*"\"" { // add title, end of command
2263 BEGIN( Comment );
2264 }
2265<SubpageTitle>. { // no title, end of command
2266 unput(*yytext);
2267 BEGIN( Comment );
2268 }
2269
2270
2271
2272<AnchorLabel,AnchorLabelSection>{LABELID} { // found argument
2273 DString lbl = yyextra->raisePrefix+yytext;
2274 addAnchor(yyscanner,lbl, yyextra->anchorTitle);
2276 if (YY_START == AnchorLabel)
2277 {
2278 BEGIN(Comment);
2279 }
2280 else
2281 {
2282 BEGIN(SectionTitle);
2283 }
2284 }
2285<AnchorLabel,AnchorLabelSection>{DOCNL} { // missing argument
2286 warn(yyextra->fileName,yyextra->lineNr,
2287 "\\anchor command has no label"
2288 );
2289 if (*yytext=='\n') yyextra->lineNr++;
2291 if (YY_START == AnchorLabel)
2292 {
2293 BEGIN(Comment);
2294 }
2295 else
2296 {
2297 BEGIN(SectionTitle);
2298 }
2299 }
2300<AnchorLabel,AnchorLabelSection>. { // invalid character for anchor label
2301 warn(yyextra->fileName,yyextra->lineNr,
2302 "Invalid or missing anchor label"
2303 );
2305 if (YY_START == AnchorLabel)
2306 {
2307 BEGIN(Comment);
2308 }
2309 else
2310 {
2311 BEGIN(SectionTitle);
2312 }
2313 }
2314
2315
2316
2317<RequirementLabel>{REQID} { // found argument
2318 yyextra->current->name = yytext;
2319 yyextra->current->type.clear();
2320 BEGIN( RequirementTitle );
2321 }
2322<SatisfiesLabel>{REQID} { // found argument
2323 yyextra->reqId = yytext;
2324 yyextra->reqTitle.clear();
2325 BEGIN( SatisfiesTitle );
2326 }
2327<VerifiesLabel>{REQID} { // found argument
2328 yyextra->reqId = yytext;
2329 yyextra->reqTitle.clear();
2330 BEGIN( VerifiesTitle );
2331 }
2332<RequirementLabel,SatisfiesLabel,VerifiesLabel>"\\"{B}*"\n" { // line continuation
2333 yyextra->lineNr++;
2335 }
2336<RequirementLabel,SatisfiesLabel,VerifiesLabel>{DOCNL} { // missing argument
2337 warn(yyextra->fileName,yyextra->lineNr,
2338 "missing requirement ID after \\requirement command"
2339 );
2341 BEGIN( Comment );
2342 }
2343<RequirementLabel,SatisfiesLabel,VerifiesLabel>. { // invalid character for requirement label
2344 }
2345
2346<RequirementTitle,SatisfiesTitle,VerifiesTitle>"\\"{B}*"\n" { // line continuation
2347 yyextra->lineNr++;
2349 }
2350<RequirementTitle>[^\n\\]+ { // title (stored in type)
2351 yyextra->current->type += yytext;
2352 }
2353<SatisfiesTitle,VerifiesTitle>[^\n\\@]+ { // title (stored in type)
2354 yyextra->reqTitle += yytext;
2355 }
2356<RequirementTitle>({CMD}("verifies"|"satisfies"|"requirement"){B}+)|{DOCNL}+ {
2357 yyextra->current->type = yyextra->current->type.stripWhiteSpace();
2360 BEGIN( Comment );
2361 }
2362<SatisfiesTitle>({CMD}("verifies"|"satisfies"|"requirement"){B}+)|{DOCNL}+ {
2363 yyextra->reqTitle = yyextra->reqTitle.stripWhiteSpace();
2365 if (yyextra->current->section.isRequirementDoc())
2366 {
2367 warn(yyextra->fileName,yyextra->lineNr,
2368 "@satisfies command is not allowed in documentation of a requirement. Put in at the place where the requirement is implemented."
2369 );
2370 }
2371 else
2372 {
2374 yyextra->reqId,
2375 yyextra->reqTitle,
2376 yyextra->fileName,
2377 yyextra->lineNr);
2378 }
2379 BEGIN( Comment );
2380 }
2381<VerifiesTitle>({CMD}("verifies"|"satisfies"|"requirement"){B}+)|{DOCNL}+ {
2382 yyextra->reqTitle = yyextra->reqTitle.stripWhiteSpace();
2384 if (yyextra->current->section.isRequirementDoc())
2385 {
2386 warn(yyextra->fileName,yyextra->lineNr,
2387 "@verifies command is not allowed in documentation of a requirement. Put in at the place where the requirement is tested."
2388 );
2389 }
2390 else
2391 {
2393 yyextra->reqId,
2394 yyextra->reqTitle,
2395 yyextra->fileName,
2396 yyextra->lineNr);
2397 }
2398 BEGIN( Comment );
2399 }
2400<RequirementTitle>. { // title (stored in type)
2401 yyextra->current->type += yytext;
2402 }
2403<SatisfiesTitle,VerifiesTitle>. { // title (stored in reqTitle)
2404 yyextra->reqTitle += yytext;
2405 }
2406
2407
2408
2409
2410<FormatBlock>{CMD}("endverbatim"|"endiverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode"|"endicode"|"endmsc"|"endmermaid")/{NW} { // possible ends
2412 if (&yytext[4]==yyextra->blockName)
2413 {
2414 BEGIN(Comment);
2415 }
2416 }
2417<FormatBlock>{CMD}"enduml" {
2419 if (yyextra->blockName=="startuml")
2420 {
2421 BEGIN(Comment);
2422 }
2423 }
2424<FormatBlock>[^ \@\*\/\\\n]* { // some word
2426 }
2427<FormatBlock>{DOCNL} { // new line
2428 if (*yytext=='\n') yyextra->lineNr++;
2430 }
2431<FormatBlock>{CCS} { // start of a C-comment
2432 if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim" ||
2433 yyextra->blockName=="icode" || yyextra->blockName=="iverbatim"||
2434 yyextra->blockName=="iliteral"
2435 )
2436 ) yyextra->commentCount++;
2438 }
2439<FormatBlock>{CCE} { // end of a C-comment
2441 if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim" ||
2442 yyextra->blockName=="icode" || yyextra->blockName=="iverbatim"||
2443 yyextra->blockName=="iliteral"
2444 )
2445 )
2446 {
2447 yyextra->commentCount--;
2448 if (yyextra->commentCount<0)
2449 {
2450 DString endTag =
"end"+yyextra->blockName;
2451 if (yyextra->blockName=="startuml") endTag="enduml";
2452 warn(yyextra->fileName,yyextra->lineNr,
2453 "found */ without matching /* while inside a \\{} block! Perhaps a missing \\{}?",
2454 yyextra->blockName,endTag);
2455 }
2456 }
2457 }
2458<FormatBlock>. {
2460 }
2461<FormatBlock><<EOF>> {
2462 DString endTag =
"end"+yyextra->blockName;
2463 if (yyextra->blockName=="startuml") endTag="enduml";
2464 warn(yyextra->fileName,yyextra->lineNr,
2465 "reached end of comment while inside a \\{} block; check for missing \\{} tag!",
2466 yyextra->blockName,endTag
2467 );
2469 }
2470
2471
2472
2473<GuardParam>{B}*"(" {
2474 yyextra->guardExpr=yytext;
2475 yyextra->roundCount=1;
2476 BEGIN(GuardExpr);
2477 }
2478<GuardExpr>[^()]* {
2479 yyextra->guardExpr+=yytext;
2481 }
2482<GuardExpr>"(" {
2483 yyextra->guardExpr+=yytext;
2484 yyextra->roundCount++;
2485 }
2486<GuardExpr>")" {
2487 yyextra->guardExpr+=yytext;
2488 yyextra->roundCount--;
2489 if (yyextra->roundCount==0)
2490 {
2492 }
2493 }
2494<GuardExpr>\n {
2495 warn(yyextra->fileName,yyextra->lineNr,
2496 "invalid expression '{}' for yyextra->guards",yyextra->guardExpr);
2497 unput(*yytext);
2498 BEGIN(GuardParam);
2499 }
2500<GuardParam>{B}*{CMD}doxyconfig{B}+{DOXYCFG} {
2502 }
2503<GuardParam>{B}*[a-z_A-Z0-9.\-]+({B}*{CMD}doxyconfig{B}+{DOXYCFG})? { // parameter of if/ifnot yyextra->guards
2505 }
2506<GuardParam>{DOCNL} { // end of argument
2507
2508
2512 }
2513<GuardParam>{LC} { // line continuation
2514 yyextra->lineNr++;
2516 }
2517<GuardParam>. { // empty condition
2518 unput(*yytext);
2520 }
2521<GuardParamEnd>{B}*{DOCNL} {
2523 yyextra->spaceBeforeIf.clear();
2525 BEGIN(Comment);
2526 }
2527<GuardParamEnd>{B}* {
2528 if (!yyextra->spaceBeforeIf.empty())
2529 {
2530 addOutput(yyscanner,yyextra->spaceBeforeIf);
2531 }
2532 yyextra->spaceBeforeIf.clear();
2534 BEGIN(Comment);
2535 }
2536<GuardParamEnd>. {
2537 unput(*yytext);
2539 BEGIN(Comment);
2540 }
2541
2542
2543
2544<SkipGuardedSection>{CMD}"ifnot"/{NW} {
2546 yyextra->guards->emplace(false);
2547 BEGIN( GuardParam );
2548 }
2549<SkipGuardedSection>{CMD}"if"/{NW} {
2551 yyextra->guards->emplace(false);
2552 BEGIN( GuardParam );
2553 }
2554<SkipGuardedSection>{CMD}"endif"/{NW} {
2555 if (yyextra->guards->empty())
2556 {
2557 warn(yyextra->fileName,yyextra->lineNr,
2558 "found \\endif without matching start command");
2559 BEGIN( Comment );
2560 }
2561 else
2562 {
2563 yyextra->guards->pop();
2564 if (yyextra->guards->empty())
2565 {
2566 BEGIN( GuardParamEnd );
2567 }
2568 else
2569 {
2570 if (yyextra->guards->top().isEnabled())
2571 {
2572 BEGIN( GuardParamEnd );
2573 }
2574 else
2575 {
2576 BEGIN( SkipGuardedSection );
2577 }
2578 }
2579 }
2580 }
2581<SkipGuardedSection>{CMD}"else"/{NW} {
2582 if (yyextra->guards->empty())
2583 {
2584 warn(yyextra->fileName,yyextra->lineNr,
2585 "found \\else without matching start command");
2586 }
2587 else if (yyextra->guards->top().hasElse())
2588 {
2589 warn(yyextra->fileName,yyextra->lineNr,
2590 "found multiple \\else commands in same \\if construct");
2591 yyextra->guards->top().setEnabled(false);
2592 BEGIN( SkipGuardedSection );
2593 }
2594 else if (!yyextra->guards->top().parentVisible())
2595 {
2596 yyextra->guards->top().setEnabled(false);
2597 BEGIN( SkipGuardedSection );
2598 }
2599 else
2600 {
2601 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2602 yyextra->guards->top().setElse();
2603 if (!yyextra->guards->top().parentVisible())
2604 {
2605 yyextra->guards->top().setEnabled(false);
2606 BEGIN( SkipGuardedSection );
2607 }
2608 else if (yyextra->guards->top().isEnabledFound())
2609 {
2610 yyextra->guards->top().setEnabled(false);
2611 BEGIN( SkipGuardedSection );
2612 }
2613 else
2614 {
2615 yyextra->guards->top().setEnabled(true);
2616 BEGIN( GuardParamEnd );
2617 }
2618 }
2619 }
2620<SkipGuardedSection>{CMD}"elseif"/{NW} {
2621 if (yyextra->guards->empty())
2622 {
2623 warn(yyextra->fileName,yyextra->lineNr,
2624 "found \\elseif without matching start command");
2625 }
2626 else if (yyextra->guards->top().hasElse())
2627 {
2628 warn(yyextra->fileName,yyextra->lineNr,
2629 "found \\elseif command after \\else command was given in \\if construct");
2631 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2632 yyextra->guards->top().setEnabled(false);
2633 BEGIN( GuardParam );
2634 }
2635 else
2636 {
2638 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2639 yyextra->guards->top().setEnabled(false);
2640 BEGIN( GuardParam );
2641 }
2642 }
2643<SkipGuardedSection>{DOCNL} { // skip line
2644 if (*yytext=='\n') yyextra->lineNr++;
2645
2646 }
2647<SkipGuardedSection>[^ \\@\n]+ { // skip non-special characters
2648 }
2649<SkipGuardedSection>{CMD}{CMD} |
2650<SkipGuardedSection>. { // any other character
2651 }
2652
2653
2654
2655
2656<SkipInternal>{DOCNL} { // skip line
2657 if (*yytext=='\n') yyextra->lineNr++;
2659 }
2660<SkipInternal>{CMD}"if"/[ \t] {
2661 yyextra->condCount++;
2662 }
2663<SkipInternal>{CMD}"ifnot"/[ \t] {
2664 yyextra->condCount++;
2665 }
2666<SkipInternal>{CMD}/"endif" {
2667 yyextra->condCount--;
2668 if (yyextra->condCount<0)
2669 {
2670 unput('\\');
2671 BEGIN(Comment);
2672 }
2673 }
2674<SkipInternal>{CMD}/"section"[ \t] {
2675 if (yyextra->sectionLevel>0)
2676 {
2677 unput('\\');
2678 BEGIN(Comment);
2679 }
2680 }
2681<SkipInternal>{CMD}/"subsection"[ \t] {
2682 if (yyextra->sectionLevel>1)
2683 {
2684 unput('\\');
2685 BEGIN(Comment);
2686 }
2687 }
2688<SkipInternal>{CMD}/"subsubsection"[ \t] {
2689 if (yyextra->sectionLevel>2)
2690 {
2691 unput('\\');
2692 BEGIN(Comment);
2693 }
2694 }
2695<SkipInternal>{CMD}/"paragraph"[ \t] {
2696 if (yyextra->sectionLevel>3)
2697 {
2698 unput('\\');
2699 BEGIN(Comment);
2700 }
2701 }
2702<SkipInternal>{CMD}/"subparagraph"[ \t] {
2703 if (yyextra->sectionLevel>4)
2704 {
2705 unput('\\');
2706 BEGIN(Comment);
2707 }
2708 }
2709<SkipInternal>{CMD}/"subsubparagraph"[ \t] {
2710 if (yyextra->sectionLevel>5)
2711 {
2712 unput('\\');
2713 BEGIN(Comment);
2714 }
2715 }
2716<SkipInternal>{CMD}"endinternal"[ \t]* {
2717 BEGIN(Comment);
2718 }
2719<SkipInternal>[^ \\@\n]+ { // skip non-special characters
2720 }
2721<SkipInternal>. { // any other character
2722 }
2723
2724
2725
2726
2727<NameParam>{DOCNL} { // end of argument
2728
2729
2731 BEGIN( Comment );
2732 }
2733<NameParam>{LC} { // line continuation
2734 yyextra->lineNr++;
2736 yyextra->docGroup.appendHeader(' ');
2737 }
2738<NameParam>. { // ignore other stuff
2739 yyextra->docGroup.appendHeader(*yytext);
2740 yyextra->current->name+=*yytext;
2741 }
2742
2743
2744<Noop>{DOCNL} { // end of argument
2745 if (*yytext=='\n')
2746 {
2747 yyextra->lineNr++;
2749 }
2750 BEGIN( Comment );
2751 }
2752<Noop>. { // ignore other stuff
2753 }
2754
2755<RaiseWarning,RaiseWarningSection>{DOCNL} { // end of argument
2757 "{}",yyextra->raiseWarning);
2758 yyextra->raiseWarning = "";
2759 if (*yytext=='\n') yyextra->lineNr++;
2761 if (YY_START == RaiseWarning)
2762 {
2763 BEGIN(Comment);
2764 }
2765 else
2766 {
2767 yyextra->sectionTitle+=yytext;
2768 BEGIN(SectionTitle);
2769 }
2770 }
#define warn_doc_error(file, line, fmt,...)
2771<RaiseWarning,RaiseWarningSection>. { // ignore other stuff
2772 yyextra->raiseWarning += yytext;
2773 }
2774
2775
2776<InGroupParam>{LABELID} { // group id
2777 yyextra->current->groups.emplace_back(
2779 );
2780 yyextra->inGroupParamFound=true;
2781 }
@ GROUPING_INGROUP
membership in group was defined by @ingroup
2782<InGroupParam>{DOCNL} { // missing argument
2783 if (!yyextra->inGroupParamFound)
2784 {
2785 warn(yyextra->fileName,yyextra->lineNr,
2786 "Missing group name for \\ingroup command"
2787 );
2788 }
2789
2790
2792 BEGIN( Comment );
2793 }
2794<InGroupParam>{LC} { // line continuation
2795 yyextra->lineNr++;
2797 }
2798<InGroupParam>. { // ignore other stuff
2800 }
2801
2802
2803
2804<FnParam>{DOCNL} { // end of argument
2805 if (yyextra->braceCount==0)
2806 {
2807 if (yyextra->functionProto.stripWhiteSpace().empty())
2808 {
2809 warn(yyextra->fileName,yyextra->lineNr,
2810 "missing argument after '\\{}'.",yyextra->currentCmd
2811 );
2812 }
2813 else
2814 {
2816 yyextra->langParser->parsePrototype(yyextra->functionProto);
2817 }
2819 BEGIN( Comment );
2820 }
2821 }
2822<FnParam>{LC} { // line continuation
2823 yyextra->lineNr++;
2824 yyextra->functionProto+=' ';
2825 }
2826<FnParam>[^@\\\n()]+ { // non-special characters
2827 yyextra->functionProto+=yytext;
2828 }
2829<FnParam>"(" {
2830 yyextra->functionProto+=yytext;
2831 yyextra->braceCount++;
2832 }
2833<FnParam>")" {
2834 yyextra->functionProto+=yytext;
2835 yyextra->braceCount--;
2836 }
2837<FnParam>. { // add other stuff
2838 yyextra->functionProto+=*yytext;
2839 }
2840
2841
2842
2843
2844
2845<OverloadParam>{DOCNL} { // end of argument
2846 if (*yytext=='\n') yyextra->lineNr++;
2847 if (yyextra->functionProto.stripWhiteSpace().empty())
2848 {
2851 }
2852 else
2853 {
2855 yyextra->langParser->parsePrototype(yyextra->functionProto);
2856 }
2857 BEGIN( Comment );
2858 }
virtual DString trOverloadText()=0
2859<OverloadParam>{LC} { // line continuation
2860 yyextra->lineNr++;
2861 yyextra->functionProto+=' ';
2862 }
2863<OverloadParam>. { // add other stuff
2864 yyextra->functionProto+=*yytext;
2865 }
2866
2867
2868
2869<InheritParam>({ID}("::"|"."))*{ID} { // found argument
2870 yyextra->current->extends.emplace_back(
2872 );
2873 BEGIN( Comment );
2874 }
2875<InheritParam>{DOCNL} { // missing argument
2876 warn(yyextra->fileName,yyextra->lineNr,
2877 "\\inherit command has no argument"
2878 );
2879 if (*yytext=='\n') yyextra->lineNr++;
2881 BEGIN( Comment );
2882 }
2883<InheritParam>. { // invalid character for anchor label
2884 warn(yyextra->fileName,yyextra->lineNr,
2885 "Invalid or missing name for \\inherit command"
2886 );
2887 BEGIN(Comment);
2888 }
2889
2890
2891
2892<ExtendsParam>({ID}("::"|"."))*{ID} { // found argument
2893 yyextra->current->extends.emplace_back(
2895 );
2896 BEGIN( Comment );
2897 }
2898<ExtendsParam>{DOCNL} { // missing argument
2899 warn(yyextra->fileName,yyextra->lineNr,
2900 "'\\{}' command has no argument",yyextra->currentCmd
2901 );
2902
2903
2905 BEGIN( Comment );
2906 }
2907<ExtendsParam>. { // ignore other stuff
2908 }
2909
2910
2911
2912<SkipLang>{CMD}"~"[a-zA-Z-]* { /* language switch */
2915 {
2916 warn(yyextra->fileName,yyextra->lineNr,
2918 }
2919 else if (langId.empty() ||
2921 {
2922 BEGIN(Comment);
2923 }
2924 }
2925<SkipLang>[^*@\\\n]* { /* any character not a *, @, backslash or new line */
2926 }
2927<SkipLang>{DOCNL} { /* new line in verbatim block */
2928 if (*yytext=='\n') yyextra->lineNr++;
2929 }
2930<SkipLang>. { /* any other character */
2931 }
2932
2933
2934
2935<CiteLabel,CiteLabelSection>{CITEID} { // found argument
2938 if (YY_START == CiteLabel)
2939 {
2940 BEGIN(Comment);
2941 }
2942 else
2943 {
2944 yyextra->sectionTitle+=yytext;
2945 BEGIN(SectionTitle);
2946 }
2947 }
2948<CiteLabel,CiteLabelSection>{DOCNL} { // missing argument
2949 warn(yyextra->fileName,yyextra->lineNr,
2950 "\\cite command has no label"
2951 );
2952
2953
2954 if (YY_START == CiteLabel)
2955 {
2957 BEGIN(Comment);
2958 }
2959 else
2960 {
2961 yyextra->sectionTitle+=yytext;
2963 BEGIN(SectionTitle);
2964 }
2965 }
2966<CiteLabel,CiteLabelSection>. { // invalid character for cite label
2967 warn(yyextra->fileName,yyextra->lineNr,
2968 "Invalid or missing cite label"
2969 );
2970 if (YY_START == CiteLabel)
2971 {
2972 BEGIN(Comment);
2973 }
2974 else
2975 {
2976 yyextra->sectionTitle+=yytext;
2977 BEGIN(SectionTitle);
2978 }
2979 }
2980
2981
2982
2983<CopyDoc><<EOF>> {
2985 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
2986 addOutput(yyscanner,yyextra->copyDocArg);
2988 BEGIN(Comment);
2989 }
2990<CopyDoc>"<"[/]?{TABLEDEL}">" {
2991 if (yyextra->braceCount==0)
2992 {
2994 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
2995 addOutput(yyscanner,yyextra->copyDocArg);
2997 BEGIN(Comment);
2998 }
2999 }
3000<CopyDoc>{DOCNL} {
3001 if (*yytext=='\n') yyextra->lineNr++;
3002 if (yyextra->braceCount==0)
3003 {
3005 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
3006 addOutput(yyscanner,yyextra->copyDocArg);
3008 BEGIN(Comment);
3009 }
3010 }
3011<CopyDoc>{LC} { // line continuation
3012 yyextra->lineNr++;
3013 }
3014<CopyDoc>[^@\\\n()<]+ { // non-special characters
3015 yyextra->copyDocArg+=yytext;
3017 }
3018<CopyDoc>"(" {
3019 yyextra->copyDocArg+=yytext;
3021 yyextra->braceCount++;
3022 }
3023<CopyDoc>")" {
3024 yyextra->copyDocArg+=yytext;
3026 yyextra->braceCount--;
3027 }
3028<CopyDoc>. {
3029 yyextra->copyDocArg+=yytext;
3031 }
3032
3033
3034<*>. { fprintf(stderr,"Lex scanner %s %sdefault rule for state %s: #%s#\n", __FILE__,!yyextra->fileName.empty() ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START),yytext);}
3035<*>\n { fprintf(stderr,"Lex scanner %s %sdefault rule newline for state %s.\n", __FILE__, !yyextra->fileName.empty() ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START));}
3036 */
3037
3038%%