735 {CMD}{CMD}[a-z_A-Z]+{B}* {
737 }
738<Comment>{CMD}{CMD}"~"[a-z_A-Z]* { // escaped command
740 }
741<Comment>{MAILADDR} { // mail address
743 }
744<Comment>"\""[^"\n]*"\"" { // quoted text
746 }
747<Comment>("\\"[a-z_A-Z]+)+"\\" { // directory (or chain of commands!)
749 }
750<Comment>"<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description
752 int spacePos = htmlOpenTag.find(' ');
753 if (spacePos==-1) spacePos=yyleng-1;
754 QCString htmlTagName = htmlOpenTag.
mid(1,spacePos-1);
755
756 yyextra->htmlContextStack.emplace_back(htmlTagName,yyextra->inContext);
758 {
760 }
761
762 REJECT;
763 }
764<Comment>"</"{DETAILEDHTML}">" { // HTML command that ends a brief description
766 QCString htmlTagName = htmlCloseTag.
mid(2,htmlCloseTag.length()-3);
767
768 if (!yyextra->htmlContextStack.empty() &&
769 yyextra->htmlContextStack.back().tagName==htmlTagName)
770 {
772 {
773
775 }
776 yyextra->htmlContextStack.pop_back();
777 }
778 REJECT;
779 }
780<Comment>"<"{DETAILEDHTMLOPT}">" { // HTML <code> command that ends a brief description
781
782 if (yyextra->current->lang==SrcLangExt::CSharp)
783 {
784 yyextra->CScode=true;
787 }
788 else
789 {
790
791 REJECT;
792 }
793 }
794<Comment>"<"{DETAILEDHTMLOPTEND}">" { // HTML command that ends a brief description
795 if (yyextra->CScode)
796 {
798 yyextra->CScode=false;
799 }
800 else
801 {
802 yyextra->CScode=false;
803
804 REJECT;
805 }
806 }
807<Comment>"<"{DETAILEDHTMLOPT}{ATTR}">" { // HTML <code> command that ends a brief description
808
809 if (yyextra->current->lang==SrcLangExt::CSharp)
810 {
812 }
813
814 REJECT;
815 }
816<Comment>"<"{DETAILS}{ATTR}">" { // start of a HTML style details description
817 yyextra->htmlDetailsStack.push_back(0);
818 yyextra->htmlContextStack.emplace_back("details",yyextra->inContext);
820 {
822 }
824 }
825<Comment>"</"{DETAILS}">" { // end of a HTML style details description
826 if (!yyextra->htmlDetailsStack.empty())
827 {
828 yyextra->htmlDetailsStack.pop_back();
829 }
830 if (!yyextra->htmlContextStack.empty() &&
831 yyextra->htmlContextStack.back().tagName=="details")
832 {
834 {
835
837 }
838 yyextra->htmlContextStack.pop_back();
839 }
841 }
842<Comment>"<"{AHTML} { // potential start of HTML anchor, see issue 9200
843 yyextra->htmlAnchorStr = yytext;
844 yyextra->htmlAnchor = false;
845 BEGIN(HtmlA);
846 }
847<HtmlA>{ANCHTML} { // only labels that can be converted to doxygen anchor
848 yyextra->htmlAnchorStr += yytext;
850 int s=tag.find("=");
851 char c=tag[s+1];
853 if (c=='\'' || c=='"')
854 {
855 int e=tag.find(c,s+2);
856 if (e!=-1)
857 {
858 id=tag.mid(s+2,e-s-2);
860 }
861 }
862 else
863 {
864 id=tag.mid(s+1);
866 }
867 if (!id.isEmpty() && !yyextra->htmlAnchor)
868 {
869
873 yyextra->htmlAnchor = true;
874 }
875 }
876<HtmlA>("\""[^\n\"]*"\""|"'"[^\n']*"'") {
877 yyextra->htmlAnchorStr += yytext;
878 }
879<HtmlA>">"|"/>" {
880 if (!yyextra->htmlAnchor)
881 {
882 addOutput(yyscanner,yyextra->htmlAnchorStr);
884 }
885 else
886 {
887 if (yyleng == 1)
888 {
890 }
891 }
892 BEGIN(Comment);
893 }
894<HtmlA>{DOCNL} { // newline
895 yyextra->htmlAnchorStr += yytext;
896 if (*yytext == '\n') yyextra->lineNr++;
897 }
898<HtmlA>. { // catch-all for anything else
899 yyextra->htmlAnchorStr += yytext;
900 }
901<Comment>"<"{SUMMARY}">" { // start of a .NET XML style brief description
902 if (yyextra->htmlDetailsStack.empty())
903 {
905 }
906 else
907 {
909 }
910 }
911<Comment>"<"{REMARKS}">" { // start of a .NET XML style detailed description
914 }
915<Comment>"</"{SUMMARY}">" { // start of a .NET XML style detailed description
916 if (!yyextra->htmlDetailsStack.empty())
917 {
919 }
920 else
921 {
923 }
924 }
925<Comment>"</"{REMARKS}">" { // end of a brief or detailed description
928 }
929<Comment>"<"{CAPTION}{ATTR}">" {
931 int s=tag.find("id=");
932 if (s!=-1)
933 {
934 char c=tag[s+3];
935 if (c=='\'' || c=='"')
936 {
937 int e=tag.find(c,s+4);
938 if (e!=-1)
939 {
942 }
943 }
944 }
946 }
947<Comment>"<"{PRE}{ATTR}">" {
948 yyextra->insidePre=
TRUE;
950 }
951<Comment>"</"{PRE}">" {
952 yyextra->insidePre=
FALSE;
954 }
955<Comment>{RCSTAG} { // RCS tag which end a brief description
957 REJECT;
958 }
959<Comment>"<!--" {
960 BEGIN(HtmlComment);
961 }
962<Comment>"<!\[CDATA\[" {
963 BEGIN(CdataSection);
964 }
965<Comment>{B}*{CMD}"endinternal"{B}* {
967 if (!yyextra->inInternalDocs)
968 warn(yyextra->fileName,yyextra->lineNr,
969 "found \\endinternal without matching \\internal"
970 );
971 yyextra->inInternalDocs =
FALSE;
972 }
973<Comment>{B}*"\\ilinebr "{B}* { // preserve spacing around \\ilinebr
975 }
976<Comment>(\n|"\\ilinebr ")/({B}*(\n|{IFILELINE}?"\\ilinebr "))+ { // at least one blank line (or blank line command)
978 {
980 }
981 else
982 {
983 REJECT;
984 }
985 }
986<Comment>{B}*{CMD}[a-z_A-Z]+"{"[^}]*"}"{B}* |
987<Comment>{B}*{CMD}[a-z_A-Z]+{B}* { // potentially interesting command
988
990 int idx = fullMatch.
find(
'{');
991
992 if ((idx > 1) && (yytext[idx-1] == 'f') && (yytext[idx-2] == '\\' || yytext[idx-2] =='@')) REJECT;
993 int idxEnd = fullMatch.
find(
"}",idx+1);
996 if (idx == -1)
997 {
999 }
1000 else
1001 {
1005 }
1007
1009 {
1010 int i=0;
1011 while (yytext[i]==' ' || yytext[i]=='\t') i++;
1012 yyextra->spaceBeforeCmd = fullMatch.
left(i);
1015 !(yyextra->inContext==
OutputXRef && cmdName==
"parblock"))
1016 {
1017 yyextra->briefEndsAtDot=
FALSE;
1019
1021 }
1022
1023 if (it->second.handler && it->second.handler(yyscanner, cmdName, optList))
1024 {
1025
1026
1027
1028 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.
1029
1030 yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);
1032 }
1033 else if (it->second.handler==nullptr)
1034 {
1035
1036
1038 }
1039 }
1040 else
1041 {
1043 }
1044 }
1045<Comment>{B}*({CMD}{CMD})"f"[$\[{] { // escaped formula command
1047 }
1048<Comment>{B}*{CMD}"~"[a-z_A-Z-]* { // language switch command
1052 {
1054 {
1055 warn(yyextra->fileName,yyextra->lineNr,
1057 }
1058 BEGIN(SkipLang);
1059 }
1060 }
#define Config_getEnumAsString(name)
#define Config_isAvailableEnum(name, value)
int qstricmp(const char *s1, const char *s2)
1061<Comment>{B}*{CMD}"f{"[^}\n]+"}"("{"?) { // start of a formula with custom environment
1063 yyextra->formulaText="";
1064 yyextra->formulaPreText="\\begin";
1065 yyextra->formulaPostText="";
1067 if (yyextra->formulaEnv.at(yyextra->formulaEnv.length()-1)=='{')
1068 {
1069
1070 yyextra->formulaEnv=yyextra->formulaEnv.left(yyextra->formulaEnv.length()-1);
1071 }
1072 yyextra->formulaPreText+=yyextra->formulaEnv;
1073 yyextra->formulaNewLines=0;
1074 BEGIN(ReadFormulaLong);
1075 }
1076<Comment>{B}*{CMD}"f$" { // start of a inline formula
1077 yyextra->formulaText="";
1078 yyextra->formulaPreText="$";
1079 yyextra->formulaPostText="";
1080 yyextra->formulaNewLines=0;
1081 BEGIN(ReadFormulaShort);
1082 }
1083<Comment>{B}*{CMD}"f(" { // start of a inline formula
1084 yyextra->formulaText="";
1085 yyextra->formulaPreText="";
1086 yyextra->formulaPostText="";
1087 yyextra->formulaNewLines=0;
1088 BEGIN(ReadFormulaRound);
1089 }
1090<Comment>{B}*{CMD}"f[" { // start of a block formula
1092 yyextra->formulaText="";
1093 yyextra->formulaPreText="\\[";
1094 yyextra->formulaPostText="";
1095 yyextra->formulaNewLines=0;
1096 BEGIN(ReadFormulaLong);
1097 }
1098<Comment>{B}*{CMD}"{" { // begin of a group
1099
1100 yyextra->docGroup.open(yyextra->current,yyextra->fileName,yyextra->lineNr);
1101 }
1102<Comment>{B}*{CMD}"}" { // end of a group
1103
1104 yyextra->docGroup.close(yyextra->current,yyextra->fileName,yyextra->lineNr,
TRUE);
1105 yyextra->docGroup.clearHeader();
1106 yyextra->parseMore=
TRUE;
1107 yyextra->needNewEntry =
TRUE;
1108 yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + (int)strlen(yytext);
1110 }
1111<Comment>{B}*{CMD}[$@\\&~<>#%] { // escaped character
1113 }
1114<Comment>[a-z_A-Z]+ { // normal word
1116 }
1117<Comment>^{B}*"."{Bopt}/\n { // explicit end autolist: e.g " ."
1119 }
1120<Comment>^{B}*[1-9][0-9]*"."{B}+ |
1121<Comment>^{B}*[*+]{B}+ { // start of autolist
1122 if (!yyextra->markdownSupport)
1123 {
1124 REJECT;
1125 }
1126 else
1127 {
1129 {
1130 yyextra->briefEndsAtDot=
FALSE;
1132 }
1134 }
1135 }
1136<Comment>^{B}*"-"{B}+ { // start of autolist
1138 {
1139 yyextra->briefEndsAtDot=
FALSE;
1141 }
1143 }
1144<Comment>^{B}*([\-:|]{B}*)*("--"|"---")({B}*[\-:|])*{Bopt}/\n { // horizontal line (dashed)
1146 }
1147<Comment>{CMD}"---" { // escaped mdash
1149 }
1150<Comment>{CMD}"--" { // escaped mdash
1152 }
1153<Comment>"---" { // mdash
1154 addOutput(yyscanner,yyextra->insidePre || yyextra->markdownSupport ? yytext :
"—");
1155 }
1156<Comment>"--" { // ndash
1157 addOutput(yyscanner,yyextra->insidePre || yyextra->markdownSupport ? yytext :
"–");
1158 }
1159<Comment>"-#"{B}+ { // numbered item
1161 {
1162 yyextra->briefEndsAtDot=
FALSE;
1164 }
1166 }
1167<Comment>[?!][a-z_A-Z0-9\(\)=<] |
1168<Comment>("."+)[a-z_A-Z0-9\)] { // . at start or in the middle of a word, or ellipsis
1169
1171 }
1172<Comment>{CMD}[\.?!] { // we have to be a bit careful with the special commands
1173
1175 }
1176<Comment>".\\"[ \t] { // . with escaped space.
1179 }
1180<Comment>"."[,:;] { // . with some puntuations such as "e.g.," or "e.g.:"
1182 }
1183<Comment>"...\\"[ \t] { // ellipsis with escaped space.
1185 }
1186<Comment>"..."/[^\.] { // ellipsis
1188 }
1189<Comment>".."[\.]?/[^ \t\n] { // internal ellipsis
1191 }
1192<Comment>(\n|"\\ilinebr ")({B}*(\n|"\\ilinebr "))+ { // at least one blank line (or blank line command)
1194 {
1195
1197 yy_size_t i;
1198 for (i=0;i<(yy_size_t)yyleng;)
1199 {
1200 if (yytext[i]==
'\n')
addOutput(yyscanner,
'\n'),i++;
1201 else if (strncmp(yytext+i,
"\\ilinebr ",9)==0)
addOutput(yyscanner,
"\\ilinebr "),i+=9;
1202 else i++;
1203 }
1204 }
1206 {
1207 yy_size_t i;
1208 for (i=0;i<(yy_size_t)yyleng;)
1209 {
1210 if (yytext[i]==
'\n')
addOutput(yyscanner,
'\n'),i++;
1211 else if (strncmp(yytext+i,
"\\ilinebr ",9)==0)
addOutput(yyscanner,
"\\ilinebr "),i+=9;
1212 else i++;
1213 }
1215 }
1216 else
1217 {
1218
1220 }
1222 }
1223<Comment>"."[?!] |
1224<Comment>[\.?!] { // potential end of a JavaDoc style comment
1226 if (yyextra->briefEndsAtDot)
1227 {
1229 yyextra->briefEndsAtDot=
FALSE;
1230 }
1231 }
1232<Comment>{DOCNL} { // newline
1234 if (*yytext == '\n') yyextra->lineNr++;
1235 }
1236<Comment>"<"[/]?{TABLEDEL}">" { // In case in xrefitem type some special handling is required
1238 {
1241 }
1242 else
1243 {
1244 REJECT;
1245 }
1246 }
1247<Comment>. { // catch-all for anything else
1249 }
1250
1251
1252
1253
1254<HtmlComment>"---"[!]?">"{B}* {
1255 warn(yyextra->fileName,yyextra->lineNr,
1256 "incorrect HTML end comment --->"
1257 );
1258 }
1259<HtmlComment>"--"[!]?">"{B}* { BEGIN( Comment ); }
1260<HtmlComment>{DOCNL} {
1261 if (*yytext=='\n')
1262 {
1263 yyextra->lineNr++;
1265 }
1266 }
1267<HtmlComment>[^\\\n\-]+ { // ignore unimportant characters
1268 }
1269<HtmlComment>. { // ignore every else
1270 }
1271
1272<CdataSection>"\]\]>" {
1273 BEGIN( Comment );
1274 }
1275<CdataSection>{DOCNL} {
1277 if (*yytext=='\n') yyextra->lineNr++;
1278 }
1279<CdataSection>[<>&] { // the special XML characters for iwhich the CDATA section is especially used
1282 }
1283<CdataSection>[^\\\n\]<>&]+ {
1285 }
1286<CdataSection>. {
1288 }
1289
1290
1291
1292<ReadFormulaShort,ReadFormulaShortSection>{CMD}"f$" { // end of inline formula
1293 yyextra->formulaPostText+="$";
1296 if (YY_START == ReadFormulaShort)
1297 {
1298 BEGIN(Comment);
1299 }
1300 else
1301 {
1302 yyextra->sectionTitle+= " "+form;
1303 BEGIN(SectionTitle);
1304 }
1305 }
1306<ReadFormulaRound,ReadFormulaRoundSection>{CMD}"f)" { // end of inline formula
1309 if (YY_START == ReadFormulaRound)
1310 {
1311 BEGIN(Comment);
1312 }
1313 else
1314 {
1315 yyextra->sectionTitle+= " "+form;
1316 BEGIN(SectionTitle);
1317 }
1318 }
1319<ReadFormulaLong>{CMD}"f]" { // end of block formula
1320 yyextra->formulaPostText+="\\]";
1322 BEGIN(Comment);
1323 }
1324<ReadFormulaLong>{CMD}"f}" { // end of custom env formula
1325 yyextra->formulaPostText+="\\end";
1326 yyextra->formulaPostText+=yyextra->formulaEnv;
1328 BEGIN(Comment);
1329 }
1330<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>[^\\@\n]+ { // any non-special character
1331 yyextra->formulaText+=yytext;
1332 }
1333<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>\n { // new line
1334 yyextra->formulaNewLines++;
1335 yyextra->formulaText+=*yytext;
1336 yyextra->lineNr++;
1337 addIline(yyscanner,yyextra->lineNr);
1338 }
1339<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>. { // any other character
1340 yyextra->formulaText+=*yytext;
1341 }
1342
1343
1344
1345<EnumDocArg1>{SCOPEID} { // handle argument
1347 yyextra->current->name = yytext;
1348 BEGIN( Comment );
1349 }
1350<EnumDocArg1>{LC} { // line continuation
1351 yyextra->lineNr++;
1353 }
1354<EnumDocArg1>{DOCNL} { // missing argument
1355 warn(yyextra->fileName,yyextra->lineNr,
1356 "missing argument after '\\enum'."
1357 );
1359 BEGIN( Comment );
1360 }
1361<EnumDocArg1>. { // ignore other stuff
1362 }
1363
1364
1365
1366<NameSpaceDocArg1>{SCOPENAME} { // handle argument
1370 BEGIN( Comment );
1371 }
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
QCString removeRedundantWhiteSpace(const QCString &s)
1372<NameSpaceDocArg1>{LC} { // line continuation
1373 yyextra->lineNr++;
1375 }
1376<NameSpaceDocArg1>{DOCNL} { // missing argument
1377 warn(yyextra->fileName,yyextra->lineNr,
1378 "missing argument after '\\namespace'."
1379 );
1381 BEGIN( Comment );
1382 }
1383<NameSpaceDocArg1>. { // ignore other stuff
1384 }
1385
1386
1387
1388<PackageDocArg1>{ID}("."{ID})* { // handle argument
1389 yyextra->current->name = yytext;
1390 BEGIN( Comment );
1391 }
1392<PackageDocArg1>{LC} { // line continuation
1393 yyextra->lineNr++;
1395 }
1396<PackageDocArg1>{DOCNL} { // missing argument
1397 warn(yyextra->fileName,yyextra->lineNr,
1398 "missing argument after \\package."
1399 );
1401
1402
1403 BEGIN( Comment );
1404 }
1405<PackageDocArg1>. { // ignore other stuff
1406 }
1407
1408
1409
1410<ConceptDocArg1>{SCOPEID} { // handle argument
1412 yyextra->current->name = yytext;
1413 BEGIN( Comment );
1414 }
1415<ConceptDocArg1>{LC} { // line continuation
1416 yyextra->lineNr++;
1418 }
1419<ConceptDocArg1>{DOCNL} { // missing argument
1420 warn(yyextra->fileName,yyextra->lineNr,
1421 "missing argument after '\\concept'."
1422 );
1424 BEGIN( Comment );
1425 }
1426<ConceptDocArg1>. { // ignore other stuff
1427 }
1428
1429
1430<ModuleDocArg1>{MODULE_ID} { // handle argument
1432 yyextra->current->name = yytext;
1433 BEGIN( Comment );
1434 }
1435<ModuleDocArg1>{LC} { // line continuation
1436 yyextra->lineNr++;
1438 }
1439<ModuleDocArg1>{DOCNL} { // missing argument
1440 warn(yyextra->fileName,yyextra->lineNr,
1441 "missing argument after '\\module'."
1442 );
1444 BEGIN( Comment );
1445 }
1446<ModuleDocArg1>. { // ignore other stuff
1447 }
1448
1449
1450
1451<ClassDocArg1>{SCOPENAME}{TMPLSPEC} {
1455 BEGIN( ClassDocArg2 );
1456 }
1457<ClassDocArg1>{SCOPENAME} { // first argument
1460 yyextra->current->name =
substitute(yytext,
".",
"::");
1461 if (yyextra->current->section.isProtocolDoc())
1462 {
1463 yyextra->current->name+="-p";
1464 }
1465
1466 BEGIN( ClassDocArg2 );
1467 }
1468<CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" {
1471 yyextra->current->name =
substitute(yytext,
".",
"::");
1472 BEGIN( ClassDocArg2 );
1473 }
1474<ClassDocArg1,CategoryDocArg1>{LC} { // line continuation
1475 yyextra->lineNr++;
1477 }
1478<ClassDocArg1,CategoryDocArg1>{DOCNL} {
1479 warn(yyextra->fileName,yyextra->lineNr,
1480 "missing argument after '\\{}'.",yyextra->currentCmd
1481 );
1483 BEGIN( Comment );
1484 }
1485<ClassDocArg1,CategoryDocArg1>. { // ignore other stuff
1486 }
1487
1488<ClassDocArg2>{DOCNL} {
1490 BEGIN( Comment );
1491 }
1492<ClassDocArg2>{FILE}|"<>" { // second argument; include file
1493 yyextra->current->includeFile = yytext;
1494 BEGIN( ClassDocArg3 );
1495 }
1496<ClassDocArg2>{LC} { // line continuation
1497 yyextra->lineNr++;
1499 }
1500<ClassDocArg2>. { // ignore other stuff
1501 }
1502
1503<ClassDocArg3>[<"]?{FILE}?[">]? { // third argument; include file name
1504 yyextra->current->includeName = yytext;
1505 BEGIN( Comment );
1506 }
1507<ClassDocArg3>{LC} { // line continuation
1508 yyextra->lineNr++;
1510 }
1511<ClassDocArg3>{DOCNL} {
1512
1514 BEGIN( Comment );
1515 }
1516<ClassDocArg3>. { // ignore other stuff
1517 }
1518
1519
1520
1521<GroupDocArg1>{LABELID}(".html"|".xhtml")? { // group name
1522 yyextra->current->name = yytext;
1523
1524
1525
1526 if (yyextra->current->name.endsWith(".html"))
1527 {
1528 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-5);
1529 }
1530 else if (yyextra->current->name.endsWith(".xhtml"))
1531 {
1532 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-6);
1533 }
1534 yyextra->current->type.clear();
1535 BEGIN(GroupDocArg2);
1536 }
1537<GroupDocArg1>"\\"{B}*"\n" { // line continuation
1538 yyextra->lineNr++;
1540 }
1541<GroupDocArg1>{DOCNL} { // missing argument!
1542 warn(yyextra->fileName,yyextra->lineNr,
1543 "missing group name after {}",
1544 yyextra->current->groupDocCmd()
1545 );
1546
1547
1549 BEGIN( Comment );
1550 }
1551<GroupDocArg1>. { // ignore other stuff
1552 }
1553<GroupDocArg2>"\\"{B}*"\n" { // line continuation
1554 yyextra->lineNr++;
1556 }
1557<GroupDocArg2>[^\n\\]+ { // title (stored in type)
1558 yyextra->current->type += yytext;
1559 }
1560<GroupDocArg2>{DOCNL}+ {
1561 yyextra->current->type = yyextra->current->type.stripWhiteSpace();
1563 yyextra->current->type.isEmpty()
1564 )
1565 {
1566 warn(yyextra->fileName,yyextra->lineNr,
1567 "missing title after "
1568 "\\defgroup {}", yyextra->current->name
1569 );
1570 }
1572 int extraLineNr = 0;
1574 {
1575 for (int i = 0; i < yyleng; i++)
1576 {
1577 if (yytext[i]=='\n') extraLineNr++;
1578 }
1579 }
1580
1581
1583 {
1584 addOutput(yyscanner,
" \\ifile \""+ yyextra->fileName);
1585 addOutput(yyscanner,
"\" \\iline " +
QCString().setNum(yyextra->lineNr + extraLineNr) +
" \\ilinebr ");
1586 }
1587 BEGIN( Comment );
1588 }
1589<GroupDocArg2>. { // title (stored in type)
1590 yyextra->current->type += yytext;
1591 }
1592
1593
1594
1595<PageDocArg1>[^\n]*"\\ilinebr @ianchor"\{[^\]\n]*\}{B}{FILE} { // special case where the Markdown processor has rewritten
1596
1597
1599 int start = text.
find(
'{');
1600 int end = text.
find(
'}',start+1);
1601 yyextra->current->name = text.
mid(
end+2);
1602 int istart = yyextra->current->name.
find(
"\\ilinebr");
1603 if (istart != -1)
1604 {
1605 QCString rest = yyextra->current->name.
mid(istart);
1607 yyextra->current->name = yyextra->current->name.mid(0,istart);
1608 }
1609 yyextra->current->args = text.
mid(start+1,
end-start-1);
1610
1611 BEGIN( PageDocArg2 );
1612 }
DirIterator end(const DirIterator &) noexcept
1613<PageDocArg1>{FILE} { // first argument; page name
1615 yyextra->current->args = "";
1616 BEGIN( PageDocArg2 );
1617 }
1618<PageDocArg1>{LC} { yyextra->lineNr++;
1620 }
1621<PageDocArg1>{DOCNL} {
1622 warn(yyextra->fileName,yyextra->lineNr,
1623 "missing argument after \\page."
1624 );
1626
1627
1628 BEGIN( Comment );
1629 }
1630<PageDocArg1>. { // ignore other stuff
1631 }
1632<PageDocArg2>{DOCNL} { // second argument; page title
1634
1635
1636 addOutput(yyscanner,
" \\ifile \""+ yyextra->fileName);
1637 addOutput(yyscanner,
"\" \\iline " +
QCString().setNum(yyextra->lineNr) +
" \\ilinebr ");
1638 BEGIN( Comment );
1639 }
1640<PageDocArg2>{CMD}[<>] {
1641
1645 yyextra->current->args += tmp;
1646 }
1647<PageDocArg2>. {
1648 yyextra->current->args += yytext;
1649 }
1650
1651<ParamArg1>{ID}/{B}*"," {
1653 }
1654<ParamArg1>"," {
1656 }
1657<ParamArg1>{DOCNL} {
1658 if (*yytext=='\n') yyextra->lineNr++;
1660 }
1661<ParamArg1>{ID} {
1663 BEGIN( Comment );
1664 }
1665<ParamArg1>. {
1666 unput(yytext[0]);
1667 BEGIN( Comment );
1668 }
1669
1670
1671
1672<FileDocArg1>{DOCNL} { // no file name specified
1674
1675
1676 BEGIN( Comment );
1677 }
1678<FileDocArg1>{FILE} { // first argument; name
1680 BEGIN( Comment );
1681 }
1682<FileDocArg1>{LC} { yyextra->lineNr++;
1684 }
1685<FileDocArg1>. { // ignore other stuff
1686 }
1687
1688
1689
1690<XRefItemParam1>{LABELID} { // first argument
1691 yyextra->newXRefItemKey=yytext;
1693 BEGIN(XRefItemParam2);
1694 }
1695<XRefItemParam1>{LC} { // line continuation
1696 yyextra->lineNr++;
1698 }
1699<XRefItemParam1>{DOCNL} { // missing arguments
1700 warn(yyextra->fileName,yyextra->lineNr,
1701 "Missing first argument of \\xrefitem"
1702 );
1703 if (*yytext=='\n') yyextra->lineNr++;
1706 BEGIN( Comment );
1707 }
1708<XRefItemParam1>. { // ignore other stuff
1709 }
1710
1711<XRefItemParam2>"\""[^\n\"]*"\"" { // second argument
1713 BEGIN(XRefItemParam3);
1714 }
1715<XRefItemParam2>{LC} { // line continuation
1716 yyextra->lineNr++;
1718 }
1719<XRefItemParam2>{DOCNL} { // missing argument
1720 warn(yyextra->fileName,yyextra->lineNr,
1721 "Missing second argument of \\xrefitem"
1722 );
1723 if (*yytext=='\n') yyextra->lineNr++;
1726 BEGIN( Comment );
1727 }
1728<XRefItemParam2>. { // ignore other stuff
1729 }
1730
1731<XRefItemParam3>"\""[^\n\"]*"\"" { // third argument
1734 BEGIN( Comment );
1735 }
1736<XRefItemParam2,XRefItemParam3>{LC} { // line continuation
1737 yyextra->lineNr++;
1739 }
1740<XRefItemParam3>{DOCNL} { // missing argument
1741 warn(yyextra->fileName,yyextra->lineNr,
1742 "Missing third argument of \\xrefitem"
1743 );
1744 if (*yytext=='\n') yyextra->lineNr++;
1747 BEGIN( Comment );
1748 }
1749<XRefItemParam3>. { // ignore other stuff
1750 }
1751
1752
1753
1754
1755<RelatesParam1>({ID}("::"|"."))*{ID} { // argument
1756 yyextra->current->relates = yytext;
1757
1758
1759
1760
1761 BEGIN( Comment );
1762 }
1763<RelatesParam1>{LC} { // line continuation
1764 yyextra->lineNr++;
1766 }
1767<RelatesParam1>{DOCNL} { // missing argument
1768 warn(yyextra->fileName,yyextra->lineNr,
1769 "Missing argument of '\\{}' command",yyextra->currentCmd
1770 );
1772
1773
1774 BEGIN( Comment );
1775 }
1776<RelatesParam1>. { // ignore other stuff
1777 }
1778
1779
1780
1781<Qualifier>{LABELID} { // unquoted version, simple label
1782 yyextra->current->qualifiers.emplace_back(yytext);
1783 BEGIN( Comment );
1784 }
1785<Qualifier>"\""[^\"]*"\"" { // quotes version, add without quotes
1786 std::string inp(yytext);
1787 yyextra->current->qualifiers.push_back(inp.substr(1,yyleng-2));
1788 BEGIN( Comment );
1789 }
1790<Qualifier>{DOCNL} { // missing argument
1791 warn(yyextra->fileName,yyextra->lineNr,
1792 "Missing argument of '\\{}' command",yyextra->currentCmd
1793 );
1795 BEGIN( Comment );
1796 }
1797<Qualifier>. {
1798 warn(yyextra->fileName,yyextra->lineNr,
1799 "Argument of '\\{}' command should be quoted",yyextra->currentCmd
1800 );
1802 BEGIN( Comment );
1803 }
1804
1805<ILine>{LINENR}/[\\@\n\.] |
1806<ILine>{LINENR}{B} {
1807 bool ok = false;
1809 if (!ok)
1810 {
1811 warn(yyextra->fileName,yyextra->lineNr,
"Invalid line number '{}' for iline command",yytext);
1812 }
1813 else
1814 {
1815 yyextra->lineNr = nr;
1816 }
1818 if (YY_START == ILine)
1819 {
1820 BEGIN(Comment);
1821 }
1822 else
1823 {
1824 yyextra->sectionTitle+=yytext;
1825 BEGIN(SectionTitle);
1826 }
1827 }
int toInt(bool *ok=nullptr, int base=10) const
1828<ILine,ILineSection>. {
1830 if (YY_START == ILine)
1831 {
1832 BEGIN(Comment);
1833 }
1834 else
1835 {
1836 yyextra->sectionTitle+=yytext;
1837 BEGIN(SectionTitle);
1838 }
1839 }
1840
1841
1842<IRaise>{B}*[0-9]+/[\\@\n\.] |
1843<IRaise>{B}*[0-9]+{B} {
1844 bool ok = false;
1846 if (!ok)
1847 {
1848 warn(yyextra->fileName,yyextra->lineNr,
"Invalid level '{}' for iraise command",yytext);
1849 }
1850 else
1851 {
1852 yyextra->raiseLevel = nr;
1853 }
1854 BEGIN(Comment);
1855 }
1856<IRaise>. {
1857 unput(yytext[0]);
1858 BEGIN(Comment);
1859 }
1860
1861
1862<IRaisePrefix>{B}*"\""({LABELID})?"\"" {
1864 yyextra->raisePrefix = text.stripWhiteSpace().mid(1,text.length()-2);
1866 BEGIN(Comment);
1867 }
1868<IRaisePrefix>. {
1869 unput(yytext[0]);
1870 BEGIN(Comment);
1871 }
1872
1873
1874
1875
1876<IFile,IFileSection>{FILE} {
1879 if (yytext[0] == '\"') yyextra->fileName = text.mid(1,text.length()-2);
1880 else yyextra->fileName = yytext;
1881 if (YY_START == IFile)
1882 {
1883 BEGIN(Comment);
1884 }
1885 else
1886 {
1887 yyextra->sectionTitle+=yytext;
1888 BEGIN(SectionTitle);
1889 }
1890 }
1891
1892<LinkSection>[^\\@\n]* {
1893 yyextra->sectionTitle+=yytext;
1894 }
1895<LinkSection>{CMD}{CMD} {
1896 yyextra->sectionTitle+=yytext;
1897 }
1898<LinkSection>{DOCNL} {
1900 if (*yytext == '\n') yyextra->lineNr++;
1901 yyextra->sectionTitle+=yytext;
1902 }
1903<LinkSection>{CMD}"endlink" {
1904 yyextra->sectionTitle+=yytext;
1905 BEGIN(SectionTitle);
1906 }
1907<LinkSection>. {
1908 yyextra->sectionTitle+=yytext;
1909 }
1910<LinkSection><<EOF>> {
1911 warn(yyextra->fileName,yyextra->lineNr,
1912 "reached end of comment while inside a '\\link' command, missing '\\endlink' command"
1913 );
1915 }
1916
1917
1918<LineParam>{CMD}{CMD} { // escaped command
1920 }
1921<LineParam>{DOCNL} { // end of argument
1922
1923
1925 BEGIN( Comment );
1926 }
1927<LineParam>{LC} { // line continuation
1928 yyextra->lineNr++;
1930 }
1931<LineParam>({CMD}{CMD}){ID} { // escaped command
1933 }
1934<LineParam>. { // ignore other stuff
1936 }
1937
1938
1939
1940<SectionLabel>{LABELID} {
1941 yyextra->sectionLabel+=yytext;
1942 }
1943<SectionLabel>{CMD}"lineinfo"("{}")? {
1945 }
1946<SectionLabel>{CMD}"fileinfo"("{"[^}]*"}")? {
1947 FileInfo fi(yyextra->fileName.str());
1948 bool hasOption = false;
1950 if (yytext[yyleng-1] == '}')
1951 {
1956 for (const auto &opt_ : optList)
1957 {
1959 std::string opt = optStripped.
lower().
str();
1962 {
1963 if (hasOption)
1964 {
1965 warn(yyextra->fileName,yyextra->lineNr,
"Multiple options specified with \\fileinfo, discarding '{}'", optStripped);
1966 }
1967 else
1968 {
1969 label = result;
1970 }
1971 hasOption = true;
1972 }
1973 else
1974 {
1975 warn(yyextra->fileName,yyextra->lineNr,
"Unknown option specified with \\fileinfo: '{}'", optStripped);
1976 }
1977 }
1978 }
1979 if (!hasOption)
1980 {
1982 {
1984 }
1985 else
1986 {
1987 label=yyextra->fileName;
1988 }
1989 }
1991 yyextra->sectionLabel+=label;
1992 }
1993<SectionLabel>{DOCNL} {
1994 yyextra->sectionTitle.clear();
1995 if (yyextra->sectionLabel.isEmpty())
1996 {
1997 warn(yyextra->fileName,yyextra->lineNr,
1998 "\\section command has no label"
1999 );
2000 }
2001 else
2002 {
2003 yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
2004 addOutput(yyscanner,yyextra->sectionLabel.data());
2006 }
2007 if (*yytext=='\n') yyextra->lineNr++;
2009 BEGIN( Comment );
2010 }
2011<SectionLabel>. { // invalid character for section label
2012 if (yyextra->sectionLabel.isEmpty())
2013 {
2014 warn(yyextra->fileName,yyextra->lineNr,
2015 "Invalid or missing section label"
2016 );
2017 BEGIN(Comment);
2018 }
2019 else
2020 {
2021 yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
2022 addOutput(yyscanner,yyextra->sectionLabel.data());
2023 yyextra->sectionTitle.clear();
2025 BEGIN(SectionTitle);
2026 }
2027 }
2028<SectionTitle>{STAopt}/"\n" { // end of section title
2031 BEGIN( Comment );
2032 }
2033<SectionTitle>{STopt}"\\\\ilinebr" { // escaped end of section title
2034 yyextra->sectionTitle+=yytext;
2035 }
2036<SectionTitle>{STopt}/"\\ilinebr" { // end of section title
2039 BEGIN( Comment );
2040 }
2041<SectionTitle>{B}*{CMD}"f$" {
2042 yyextra->formulaText="";
2043 yyextra->formulaPreText="$";
2044 yyextra->formulaPostText="";
2045 yyextra->formulaNewLines=0;
2046 BEGIN(ReadFormulaShortSection);
2047 }
2048<SectionTitle>{B}*{CMD}"f(" { // start of a inline formula
2049 yyextra->formulaText="";
2050 yyextra->formulaPreText="";
2051 yyextra->formulaPostText="";
2052 yyextra->formulaNewLines=0;
2053 BEGIN(ReadFormulaRoundSection);
2054 }
2055<SectionTitle>{B}*{CMD}"~"[a-z_A-Z-]* | // language switch command
2056<SectionTitle>{B}*{CMD}"f"[\[{] { // block formula
2060 warn(yyextra->fileName,yyextra->lineNr,
2061 "'\\{}' command is not allowed in section title, ending section title.",
2063 );
2065 BEGIN(Comment);
2066 }
2067<SectionTitle>{LC} { // line continuation
2068 yyextra->lineNr++;
2070 }
2071<SectionTitle>[^\n@\\]* { // any character without special meaning
2072 yyextra->sectionTitle+=yytext;
2074 }
2075<SectionTitle>{B}*{CMD}{CMD} {
2076 yyextra->sectionTitle+=yytext;
2078 }
2079<SectionTitle>{B}*{CMD}[a-z_A-Z]+"{"[^}]*"}"{B}* |
2080<SectionTitle>{B}*{CMD}[a-z_A-Z]+{B}* { // handling command in section title
2082 int idx = fullMatch.
find(
'{');
2083
2084 if ((idx > 1) && (yytext[idx-1] == 'f') && (yytext[idx-2] == '\\' || yytext[idx-2] =='@')) REJECT;
2085 int idxEnd = fullMatch.
find(
"}",idx+1);
2088 if (idx == -1)
2089 {
2091 }
2092 else
2093 {
2097 }
2100 {
2101 switch (it->second.sectionHandling)
2102 {
2104 {
2105 int i=0;
2106 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2107 yyextra->sectionTitle+=fullMatch.
left(i);
2108 yyextra->sectionTitle+='@';
2109 yyextra->sectionTitle+=fullMatch.
mid(i);
2113 warn(yyextra->fileName,yyextra->lineNr,
2114 "'\\{}' command is not allowed in section title, escaping command.",cmdName
2115 );
2116 }
2117 break;
2119 {
2122 warn(yyextra->fileName,yyextra->lineNr,
2123 "'\\{}' command is not allowed in section title, ending section title.",cmdName
2124 );
2126 BEGIN(Comment);
2127 }
2128 break;
2130 {
2131 if (cmdName == "fileinfo")
2132 {
2133 int i=0;
2134 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2135 yyextra->sectionTitle+=fullMatch.
left(i);
2138 if (idxEnd == -1)
2139 {
2140 yyextra->sectionTitle+=fullMatch.
mid(i+9);
2142 }
2143 else
2144 {
2145 yyextra->sectionTitle+=fullMatch.
mid(idxEnd+1);
2147 }
2148 }
2149 else if (cmdName == "lineinfo")
2150 {
2151 int i=0;
2152 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2153 yyextra->sectionTitle+=fullMatch.
left(i);
2155 yyextra->sectionTitle+=' ';
2156 yyextra->sectionTitle+=fullMatch.
mid(i+9);
2161 }
2162 else if (cmdName == "raisewarning")
2163 {
2164 yyextra->raiseWarning = "";
2165 BEGIN(RaiseWarningSection);
2166 }
2167 else if (cmdName == "noop")
2168 {
2170 BEGIN(Noop);
2171 }
2172 else if (cmdName == "cite")
2173 {
2174 yyextra->sectionTitle+=yytext;
2176 BEGIN(CiteLabelSection);
2177 }
2178 else if (cmdName == "iline")
2179 {
2180 yyextra->sectionTitle+=yytext;
2182 BEGIN(ILineSection);
2183 }
2184 else if (cmdName == "ifile")
2185 {
2186 yyextra->sectionTitle+=yytext;
2188 BEGIN(IFileSection);
2189 }
2190 else if ((cmdName == "anchor") || (cmdName == "ianchor"))
2191 {
2193 if (optList.empty())
2194 {
2195 yyextra -> anchorTitle = "";
2196 }
2197 else
2198 {
2200 yyextra -> anchorTitle =
join(optList,
" ");
2201 }
2203 BEGIN(AnchorLabelSection);
2204 }
2205 else if (cmdName == "link")
2206 {
2207 yyextra->sectionTitle+=yytext;
2208 BEGIN(LinkSection);
2209 }
2210 else
2211 {
2212 yyextra->sectionTitle+=yytext;
2213 warn(yyextra->fileName,yyextra->lineNr,
2214 "internal error '\\{}' command is to be replaced in section title.",cmdName
2215 );
2216 }
2217 }
2218 break;
2220 {
2221 yyextra->sectionTitle+=yytext;
2223 }
2224 break;
2225 }
2226 }
2227 else
2228 {
2229 yyextra->sectionTitle+=yytext;
2231 }
2232 }
2233<SectionTitle>. { // anything else
2234 yyextra->sectionTitle+=yytext;
2236 }
2237
2238
2239
2240<SubpageLabel>{FILE} { // first argument
2242
2243
2244 yyextra->current->extends.emplace_back(yytext,Protection::Public,Specifier::Normal);
2245 BEGIN(SubpageTitle);
2246 }
2247<SubpageLabel>{DOCNL} { // missing argument
2248 warn(yyextra->fileName,yyextra->lineNr,
2249 "\\subpage command has no label"
2250 );
2251 if (*yytext=='\n') yyextra->lineNr++;
2253 BEGIN( Comment );
2254 }
2255<SubpageLabel>. {
2256 unput(yytext[0]);
2257 BEGIN( Comment );
2258 }
2259<SubpageTitle>{DOCNL} { // no title, end command
2261 BEGIN( Comment );
2262 }
2263<SubpageTitle>[ \t]*"\""[^\"\n]*"\"" { // add title, end of command
2265 BEGIN( Comment );
2266 }
2267<SubpageTitle>. { // no title, end of command
2268 unput(*yytext);
2269 BEGIN( Comment );
2270 }
2271
2272
2273
2274<AnchorLabel,AnchorLabelSection>{LABELID} { // found argument
2275 QCString lbl = yyextra->raisePrefix+yytext;
2276 addAnchor(yyscanner,lbl, yyextra->anchorTitle);
2278 if (YY_START == AnchorLabel)
2279 {
2280 BEGIN(Comment);
2281 }
2282 else
2283 {
2284 BEGIN(SectionTitle);
2285 }
2286 }
2287<AnchorLabel,AnchorLabelSection>{DOCNL} { // missing argument
2288 warn(yyextra->fileName,yyextra->lineNr,
2289 "\\anchor command has no label"
2290 );
2291 if (*yytext=='\n') yyextra->lineNr++;
2293 if (YY_START == AnchorLabel)
2294 {
2295 BEGIN(Comment);
2296 }
2297 else
2298 {
2299 BEGIN(SectionTitle);
2300 }
2301 }
2302<AnchorLabel,AnchorLabelSection>. { // invalid character for anchor label
2303 warn(yyextra->fileName,yyextra->lineNr,
2304 "Invalid or missing anchor label"
2305 );
2307 if (YY_START == AnchorLabel)
2308 {
2309 BEGIN(Comment);
2310 }
2311 else
2312 {
2313 BEGIN(SectionTitle);
2314 }
2315 }
2316
2317
2318
2319<RequirementLabel>{REQID} { // found argument
2320 yyextra->current->name = yytext;
2321 yyextra->current->type.clear();
2322 BEGIN( RequirementTitle );
2323 }
2324<SatisfiesLabel>{REQID} { // found argument
2325 yyextra->reqId = yytext;
2326 yyextra->reqTitle.clear();
2327 BEGIN( SatisfiesTitle );
2328 }
2329<VerifiesLabel>{REQID} { // found argument
2330 yyextra->reqId = yytext;
2331 yyextra->reqTitle.clear();
2332 BEGIN( VerifiesTitle );
2333 }
2334<RequirementLabel,SatisfiesLabel,VerifiesLabel>"\\"{B}*"\n" { // line continuation
2335 yyextra->lineNr++;
2337 }
2338<RequirementLabel,SatisfiesLabel,VerifiesLabel>{DOCNL} { // missing argument
2339 warn(yyextra->fileName,yyextra->lineNr,
2340 "missing requirement ID after \\requirement command"
2341 );
2343 BEGIN( Comment );
2344 }
2345<RequirementLabel,SatisfiesLabel,VerifiesLabel>. { // invalid character for requirement label
2346 }
2347
2348<RequirementTitle,SatisfiesTitle,VerifiesTitle>"\\"{B}*"\n" { // line continuation
2349 yyextra->lineNr++;
2351 }
2352<RequirementTitle>[^\n\\]+ { // title (stored in type)
2353 yyextra->current->type += yytext;
2354 }
2355<SatisfiesTitle,VerifiesTitle>[^\n\\@]+ { // title (stored in type)
2356 yyextra->reqTitle += yytext;
2357 }
2358<RequirementTitle>({CMD}("verifies"|"satisfies"|"requirement"){B}+)|{DOCNL}+ {
2359 yyextra->current->type = yyextra->current->type.stripWhiteSpace();
2362 BEGIN( Comment );
2363 }
2364<SatisfiesTitle>({CMD}("verifies"|"satisfies"|"requirement"){B}+)|{DOCNL}+ {
2365 yyextra->reqTitle = yyextra->reqTitle.stripWhiteSpace();
2367 if (yyextra->current->section.isRequirementDoc())
2368 {
2369 warn(yyextra->fileName,yyextra->lineNr,
2370 "@satisfies command is not allowed in documentation of a requirement. Put in at the place where the requirement is implemented."
2371 );
2372 }
2373 else
2374 {
2376 yyextra->reqId,
2377 yyextra->reqTitle,
2378 yyextra->fileName,
2379 yyextra->lineNr);
2380 }
2381 BEGIN( Comment );
2382 }
2383<VerifiesTitle>({CMD}("verifies"|"satisfies"|"requirement"){B}+)|{DOCNL}+ {
2384 yyextra->reqTitle = yyextra->reqTitle.stripWhiteSpace();
2386 if (yyextra->current->section.isRequirementDoc())
2387 {
2388 warn(yyextra->fileName,yyextra->lineNr,
2389 "@verifies command is not allowed in documentation of a requirement. Put in at the place where the requirement is tested."
2390 );
2391 }
2392 else
2393 {
2395 yyextra->reqId,
2396 yyextra->reqTitle,
2397 yyextra->fileName,
2398 yyextra->lineNr);
2399 }
2400 BEGIN( Comment );
2401 }
2402<RequirementTitle>. { // title (stored in type)
2403 yyextra->current->type += yytext;
2404 }
2405<SatisfiesTitle,VerifiesTitle>. { // title (stored in reqTitle)
2406 yyextra->reqTitle += yytext;
2407 }
2408
2409
2410
2411
2412<FormatBlock>{CMD}("endverbatim"|"endiverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode"|"endicode"|"endmsc")/{NW} { // possible ends
2414 if (&yytext[4]==yyextra->blockName)
2415 {
2416 BEGIN(Comment);
2417 }
2418 }
2419<FormatBlock>{CMD}"enduml" {
2421 if (yyextra->blockName=="startuml")
2422 {
2423 BEGIN(Comment);
2424 }
2425 }
2426<FormatBlock>[^ \@\*\/\\\n]* { // some word
2428 }
2429<FormatBlock>{DOCNL} { // new line
2430 if (*yytext=='\n') yyextra->lineNr++;
2432 }
2433<FormatBlock>{CCS} { // start of a C-comment
2434 if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim" ||
2435 yyextra->blockName=="icode" || yyextra->blockName=="iverbatim"||
2436 yyextra->blockName=="iliteral"
2437 )
2438 ) yyextra->commentCount++;
2440 }
2441<FormatBlock>{CCE} { // end of a C-comment
2443 if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim" ||
2444 yyextra->blockName=="icode" || yyextra->blockName=="iverbatim"||
2445 yyextra->blockName=="iliteral"
2446 )
2447 )
2448 {
2449 yyextra->commentCount--;
2450 if (yyextra->commentCount<0)
2451 {
2452 QCString endTag =
"end"+yyextra->blockName;
2453 if (yyextra->blockName=="startuml") endTag="enduml";
2454 warn(yyextra->fileName,yyextra->lineNr,
2455 "found */ without matching /* while inside a \\{} block! Perhaps a missing \\{}?",
2456 yyextra->blockName,endTag);
2457 }
2458 }
2459 }
2460<FormatBlock>. {
2462 }
2463<FormatBlock><<EOF>> {
2464 QCString endTag =
"end"+yyextra->blockName;
2465 if (yyextra->blockName=="startuml") endTag="enduml";
2466 warn(yyextra->fileName,yyextra->lineNr,
2467 "reached end of comment while inside a \\{} block; check for missing \\{} tag!",
2468 yyextra->blockName,endTag
2469 );
2471 }
2472
2473
2474
2475<GuardParam>{B}*"(" {
2476 yyextra->guardExpr=yytext;
2477 yyextra->roundCount=1;
2478 BEGIN(GuardExpr);
2479 }
2480<GuardExpr>[^()]* {
2481 yyextra->guardExpr+=yytext;
2483 }
2484<GuardExpr>"(" {
2485 yyextra->guardExpr+=yytext;
2486 yyextra->roundCount++;
2487 }
2488<GuardExpr>")" {
2489 yyextra->guardExpr+=yytext;
2490 yyextra->roundCount--;
2491 if (yyextra->roundCount==0)
2492 {
2494 }
2495 }
2496<GuardExpr>\n {
2497 warn(yyextra->fileName,yyextra->lineNr,
2498 "invalid expression '{}' for yyextra->guards",yyextra->guardExpr);
2499 unput(*yytext);
2500 BEGIN(GuardParam);
2501 }
2502<GuardParam>{B}*[a-z_A-Z0-9.\-]+ { // parameter of if/ifnot yyextra->guards
2504 }
2505<GuardParam>{DOCNL} { // end of argument
2506
2507
2511 }
2512<GuardParam>{LC} { // line continuation
2513 yyextra->lineNr++;
2515 }
2516<GuardParam>. { // empty condition
2517 unput(*yytext);
2519 }
2520<GuardParamEnd>{B}*{DOCNL} {
2522 yyextra->spaceBeforeIf.clear();
2524 BEGIN(Comment);
2525 }
2526<GuardParamEnd>{B}* {
2527 if (!yyextra->spaceBeforeIf.isEmpty())
2528 {
2529 addOutput(yyscanner,yyextra->spaceBeforeIf);
2530 }
2531 yyextra->spaceBeforeIf.clear();
2533 BEGIN(Comment);
2534 }
2535<GuardParamEnd>. {
2536 unput(*yytext);
2538 BEGIN(Comment);
2539 }
2540
2541
2542
2543<SkipGuardedSection>{CMD}"ifnot"/{NW} {
2545 yyextra->guards->emplace(false);
2546 BEGIN( GuardParam );
2547 }
2548<SkipGuardedSection>{CMD}"if"/{NW} {
2550 yyextra->guards->emplace(false);
2551 BEGIN( GuardParam );
2552 }
2553<SkipGuardedSection>{CMD}"endif"/{NW} {
2554 if (yyextra->guards->empty())
2555 {
2556 warn(yyextra->fileName,yyextra->lineNr,
2557 "found \\endif without matching start command");
2558 BEGIN( Comment );
2559 }
2560 else
2561 {
2562 yyextra->guards->pop();
2563 if (yyextra->guards->empty())
2564 {
2565 BEGIN( GuardParamEnd );
2566 }
2567 else
2568 {
2569 if (yyextra->guards->top().isEnabled())
2570 {
2571 BEGIN( GuardParamEnd );
2572 }
2573 else
2574 {
2575 BEGIN( SkipGuardedSection );
2576 }
2577 }
2578 }
2579 }
2580<SkipGuardedSection>{CMD}"else"/{NW} {
2581 if (yyextra->guards->empty())
2582 {
2583 warn(yyextra->fileName,yyextra->lineNr,
2584 "found \\else without matching start command");
2585 }
2586 else if (yyextra->guards->top().hasElse())
2587 {
2588 warn(yyextra->fileName,yyextra->lineNr,
2589 "found multiple \\else commands in same \\if construct");
2590 yyextra->guards->top().setEnabled(false);
2591 BEGIN( SkipGuardedSection );
2592 }
2593 else if (!yyextra->guards->top().parentVisible())
2594 {
2595 yyextra->guards->top().setEnabled(false);
2596 BEGIN( SkipGuardedSection );
2597 }
2598 else
2599 {
2600 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2601 yyextra->guards->top().setElse();
2602 if (!yyextra->guards->top().parentVisible())
2603 {
2604 yyextra->guards->top().setEnabled(false);
2605 BEGIN( SkipGuardedSection );
2606 }
2607 else if (yyextra->guards->top().isEnabledFound())
2608 {
2609 yyextra->guards->top().setEnabled(false);
2610 BEGIN( SkipGuardedSection );
2611 }
2612 else
2613 {
2614 yyextra->guards->top().setEnabled(true);
2615 BEGIN( GuardParamEnd );
2616 }
2617 }
2618 }
2619<SkipGuardedSection>{CMD}"elseif"/{NW} {
2620 if (yyextra->guards->empty())
2621 {
2622 warn(yyextra->fileName,yyextra->lineNr,
2623 "found \\elseif without matching start command");
2624 }
2625 else if (yyextra->guards->top().hasElse())
2626 {
2627 warn(yyextra->fileName,yyextra->lineNr,
2628 "found \\elseif command after \\else command was given in \\if construct");
2630 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2631 yyextra->guards->top().setEnabled(false);
2632 BEGIN( GuardParam );
2633 }
2634 else
2635 {
2637 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2638 yyextra->guards->top().setEnabled(false);
2639 BEGIN( GuardParam );
2640 }
2641 }
2642<SkipGuardedSection>{DOCNL} { // skip line
2643 if (*yytext=='\n') yyextra->lineNr++;
2644
2645 }
2646<SkipGuardedSection>[^ \\@\n]+ { // skip non-special characters
2647 }
2648<SkipGuardedSection>{CMD}{CMD} |
2649<SkipGuardedSection>. { // any other character
2650 }
2651
2652
2653
2654
2655<SkipInternal>{DOCNL} { // skip line
2656 if (*yytext=='\n') yyextra->lineNr++;
2658 }
2659<SkipInternal>{CMD}"if"/[ \t] {
2660 yyextra->condCount++;
2661 }
2662<SkipInternal>{CMD}"ifnot"/[ \t] {
2663 yyextra->condCount++;
2664 }
2665<SkipInternal>{CMD}/"endif" {
2666 yyextra->condCount--;
2667 if (yyextra->condCount<0)
2668 {
2669 unput('\\');
2670 BEGIN(Comment);
2671 }
2672 }
2673<SkipInternal>{CMD}/"section"[ \t] {
2674 if (yyextra->sectionLevel>0)
2675 {
2676 unput('\\');
2677 BEGIN(Comment);
2678 }
2679 }
2680<SkipInternal>{CMD}/"subsection"[ \t] {
2681 if (yyextra->sectionLevel>1)
2682 {
2683 unput('\\');
2684 BEGIN(Comment);
2685 }
2686 }
2687<SkipInternal>{CMD}/"subsubsection"[ \t] {
2688 if (yyextra->sectionLevel>2)
2689 {
2690 unput('\\');
2691 BEGIN(Comment);
2692 }
2693 }
2694<SkipInternal>{CMD}/"paragraph"[ \t] {
2695 if (yyextra->sectionLevel>3)
2696 {
2697 unput('\\');
2698 BEGIN(Comment);
2699 }
2700 }
2701<SkipInternal>{CMD}/"subparagraph"[ \t] {
2702 if (yyextra->sectionLevel>4)
2703 {
2704 unput('\\');
2705 BEGIN(Comment);
2706 }
2707 }
2708<SkipInternal>{CMD}/"subsubparagraph"[ \t] {
2709 if (yyextra->sectionLevel>5)
2710 {
2711 unput('\\');
2712 BEGIN(Comment);
2713 }
2714 }
2715<SkipInternal>{CMD}"endinternal"[ \t]* {
2716 BEGIN(Comment);
2717 }
2718<SkipInternal>[^ \\@\n]+ { // skip non-special characters
2719 }
2720<SkipInternal>. { // any other character
2721 }
2722
2723
2724
2725
2726<NameParam>{DOCNL} { // end of argument
2727
2728
2730 BEGIN( Comment );
2731 }
2732<NameParam>{LC} { // line continuation
2733 yyextra->lineNr++;
2735 yyextra->docGroup.appendHeader(' ');
2736 }
2737<NameParam>. { // ignore other stuff
2738 yyextra->docGroup.appendHeader(*yytext);
2739 yyextra->current->name+=*yytext;
2740 }
2741
2742
2743<Noop>{DOCNL} { // end of argument
2744 if (*yytext=='\n')
2745 {
2746 yyextra->lineNr++;
2748 }
2749 BEGIN( Comment );
2750 }
2751<Noop>. { // ignore other stuff
2752 }
2753
2754<RaiseWarning,RaiseWarningSection>{DOCNL} { // end of argument
2756 "{}",yyextra->raiseWarning);
2757 yyextra->raiseWarning = "";
2758 if (*yytext=='\n') yyextra->lineNr++;
2760 if (YY_START == RaiseWarning)
2761 {
2762 BEGIN(Comment);
2763 }
2764 else
2765 {
2766 yyextra->sectionTitle+=yytext;
2767 BEGIN(SectionTitle);
2768 }
2769 }
#define warn_doc_error(file, line, fmt,...)
2770<RaiseWarning,RaiseWarningSection>. { // ignore other stuff
2771 yyextra->raiseWarning += yytext;
2772 }
2773
2774
2775<InGroupParam>{LABELID} { // group id
2776 yyextra->current->groups.emplace_back(
2778 );
2779 yyextra->inGroupParamFound=
TRUE;
2780 }
@ GROUPING_INGROUP
membership in group was defined by @ingroup
2781<InGroupParam>{DOCNL} { // missing argument
2782 if (!yyextra->inGroupParamFound)
2783 {
2784 warn(yyextra->fileName,yyextra->lineNr,
2785 "Missing group name for \\ingroup command"
2786 );
2787 }
2788
2789
2791 BEGIN( Comment );
2792 }
2793<InGroupParam>{LC} { // line continuation
2794 yyextra->lineNr++;
2796 }
2797<InGroupParam>. { // ignore other stuff
2799 }
2800
2801
2802
2803<FnParam>{DOCNL} { // end of argument
2804 if (yyextra->braceCount==0)
2805 {
2806 if (yyextra->functionProto.stripWhiteSpace().isEmpty())
2807 {
2808 warn(yyextra->fileName,yyextra->lineNr,
2809 "missing argument after '\\{}'.",yyextra->currentCmd
2810 );
2811 }
2812 else
2813 {
2815 yyextra->langParser->parsePrototype(yyextra->functionProto);
2816 }
2818 BEGIN( Comment );
2819 }
2820 }
2821<FnParam>{LC} { // line continuation
2822 yyextra->lineNr++;
2823 yyextra->functionProto+=' ';
2824 }
2825<FnParam>[^@\\\n()]+ { // non-special characters
2826 yyextra->functionProto+=yytext;
2827 }
2828<FnParam>"(" {
2829 yyextra->functionProto+=yytext;
2830 yyextra->braceCount++;
2831 }
2832<FnParam>")" {
2833 yyextra->functionProto+=yytext;
2834 yyextra->braceCount--;
2835 }
2836<FnParam>. { // add other stuff
2837 yyextra->functionProto+=*yytext;
2838 }
2839
2840
2841
2842
2843
2844<OverloadParam>{DOCNL} { // end of argument
2845 if (*yytext=='\n') yyextra->lineNr++;
2846 if (yyextra->functionProto.stripWhiteSpace().isEmpty())
2847 {
2850 }
2851 else
2852 {
2854 yyextra->langParser->parsePrototype(yyextra->functionProto);
2855 }
2856 BEGIN( Comment );
2857 }
QCString getOverloadDocs()
2858<OverloadParam>{LC} { // line continuation
2859 yyextra->lineNr++;
2860 yyextra->functionProto+=' ';
2861 }
2862<OverloadParam>. { // add other stuff
2863 yyextra->functionProto+=*yytext;
2864 }
2865
2866
2867
2868<InheritParam>({ID}("::"|"."))*{ID} { // found argument
2869 yyextra->current->extends.emplace_back(
2871 );
2872 BEGIN( Comment );
2873 }
2874<InheritParam>{DOCNL} { // missing argument
2875 warn(yyextra->fileName,yyextra->lineNr,
2876 "\\inherit command has no argument"
2877 );
2878 if (*yytext=='\n') yyextra->lineNr++;
2880 BEGIN( Comment );
2881 }
2882<InheritParam>. { // invalid character for anchor label
2883 warn(yyextra->fileName,yyextra->lineNr,
2884 "Invalid or missing name for \\inherit command"
2885 );
2886 BEGIN(Comment);
2887 }
2888
2889
2890
2891<ExtendsParam>({ID}("::"|"."))*{ID} { // found argument
2892 yyextra->current->extends.emplace_back(
2894 );
2895 BEGIN( Comment );
2896 }
2897<ExtendsParam>{DOCNL} { // missing argument
2898 warn(yyextra->fileName,yyextra->lineNr,
2899 "'\\{}' command has no argument",yyextra->currentCmd
2900 );
2901
2902
2904 BEGIN( Comment );
2905 }
2906<ExtendsParam>. { // ignore other stuff
2907 }
2908
2909
2910
2911<SkipLang>{CMD}"~"[a-zA-Z-]* { /* language switch */
2914 {
2915 warn(yyextra->fileName,yyextra->lineNr,
2917 }
2918 else if (langId.isEmpty() ||
2920 {
2921 BEGIN(Comment);
2922 }
2923 }
2924<SkipLang>[^*@\\\n]* { /* any character not a *, @, backslash or new line */
2925 }
2926<SkipLang>{DOCNL} { /* new line in verbatim block */
2927 if (*yytext=='\n') yyextra->lineNr++;
2928 }
2929<SkipLang>. { /* any other character */
2930 }
2931
2932
2933
2934<CiteLabel,CiteLabelSection>{CITEID} { // found argument
2937 if (YY_START == CiteLabel)
2938 {
2939 BEGIN(Comment);
2940 }
2941 else
2942 {
2943 yyextra->sectionTitle+=yytext;
2944 BEGIN(SectionTitle);
2945 }
2946 }
2947<CiteLabel,CiteLabelSection>{DOCNL} { // missing argument
2948 warn(yyextra->fileName,yyextra->lineNr,
2949 "\\cite command has no label"
2950 );
2951
2952
2953 if (YY_START == CiteLabel)
2954 {
2956 BEGIN(Comment);
2957 }
2958 else
2959 {
2960 yyextra->sectionTitle+=yytext;
2962 BEGIN(SectionTitle);
2963 }
2964 }
2965<CiteLabel,CiteLabelSection>. { // invalid character for cite label
2966 warn(yyextra->fileName,yyextra->lineNr,
2967 "Invalid or missing cite label"
2968 );
2969 if (YY_START == CiteLabel)
2970 {
2971 BEGIN(Comment);
2972 }
2973 else
2974 {
2975 yyextra->sectionTitle+=yytext;
2976 BEGIN(SectionTitle);
2977 }
2978 }
2979
2980
2981
2982<CopyDoc><<EOF>> {
2984 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
2985 addOutput(yyscanner,yyextra->copyDocArg);
2987 BEGIN(Comment);
2988 }
2989<CopyDoc>"<"[/]?{TABLEDEL}">" {
2990 if (yyextra->braceCount==0)
2991 {
2993 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
2994 addOutput(yyscanner,yyextra->copyDocArg);
2996 BEGIN(Comment);
2997 }
2998 }
2999<CopyDoc>{DOCNL} {
3000 if (*yytext=='\n') yyextra->lineNr++;
3001 if (yyextra->braceCount==0)
3002 {
3004 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
3005 addOutput(yyscanner,yyextra->copyDocArg);
3007 BEGIN(Comment);
3008 }
3009 }
3010<CopyDoc>{LC} { // line continuation
3011 yyextra->lineNr++;
3012 }
3013<CopyDoc>[^@\\\n()<]+ { // non-special characters
3014 yyextra->copyDocArg+=yytext;
3016 }
3017<CopyDoc>"(" {
3018 yyextra->copyDocArg+=yytext;
3020 yyextra->braceCount++;
3021 }
3022<CopyDoc>")" {
3023 yyextra->copyDocArg+=yytext;
3025 yyextra->braceCount--;
3026 }
3027<CopyDoc>. {
3028 yyextra->copyDocArg+=yytext;
3030 }
3031
3032
3033<*>. { fprintf(stderr,"Lex scanner %s %sdefault rule for state %s: #%s#\n", __FILE__,!yyextra->fileName.isEmpty() ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START),yytext);}
3034<*>\n { fprintf(stderr,"Lex scanner %s %sdefault rule newline for state %s.\n", __FILE__, !yyextra->fileName.isEmpty() ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START));}
3035 */
3036
3037%%