739 {CMD}{CMD}[a-z_A-Z]+{B}* {
741 }
742<Comment>{CMD}{CMD}"~"[a-z_A-Z]* { // escaped command
744 }
745<Comment>{MAILADDR} { // mail address
747 }
748<Comment>"\""[^"\n]*"\"" { // quoted text
750 }
751<Comment>("\\"[a-z_A-Z]+)+"\\" { // directory (or chain of commands!)
753 }
754<Comment>"<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description
756 int spacePos = htmlOpenTag.find(' ');
757 if (spacePos==-1) spacePos=yyleng-1;
758 QCString htmlTagName = htmlOpenTag.
mid(1,spacePos-1);
759
760 yyextra->htmlContextStack.emplace_back(htmlTagName,yyextra->inContext);
762 {
764 }
765
766 REJECT;
767 }
768<Comment>"</"{DETAILEDHTML}">" { // HTML command that ends a brief description
770 QCString htmlTagName = htmlCloseTag.
mid(2,htmlCloseTag.length()-3);
771
772 if (!yyextra->htmlContextStack.empty() &&
773 yyextra->htmlContextStack.back().tagName==htmlTagName)
774 {
776 {
777
779 }
780 yyextra->htmlContextStack.pop_back();
781 }
782 REJECT;
783 }
784<Comment>"<"{DETAILEDHTMLOPT}">" { // HTML <code> command that ends a brief description
785
786 if (yyextra->current->lang==SrcLangExt::CSharp)
787 {
788 yyextra->CScode=true;
791 }
792 else
793 {
794
795 REJECT;
796 }
797 }
798<Comment>"<"{DETAILEDHTMLOPTEND}">" { // HTML command that ends a brief description
799 if (yyextra->CScode)
800 {
802 yyextra->CScode=false;
803 }
804 else
805 {
806 yyextra->CScode=false;
807
808 REJECT;
809 }
810 }
811<Comment>"<"{DETAILEDHTMLOPT}{ATTR}">" { // HTML <code> command that ends a brief description
812
813 if (yyextra->current->lang==SrcLangExt::CSharp)
814 {
816 }
817
818 REJECT;
819 }
820<Comment>"<"{DETAILS}{ATTR}">" { // start of a HTML style details description
821 yyextra->htmlDetailsStack.push_back(0);
822 yyextra->htmlContextStack.emplace_back("details",yyextra->inContext);
824 {
826 }
828 }
829<Comment>"</"{DETAILS}">" { // end of a HTML style details description
830 if (!yyextra->htmlDetailsStack.empty())
831 {
832 yyextra->htmlDetailsStack.pop_back();
833 }
834 if (!yyextra->htmlContextStack.empty() &&
835 yyextra->htmlContextStack.back().tagName=="details")
836 {
838 {
839
841 }
842 yyextra->htmlContextStack.pop_back();
843 }
845 }
846<Comment>"<"{AHTML} { // potential start of HTML anchor, see issue 9200
847 yyextra->htmlAnchorStr = yytext;
848 yyextra->htmlAnchor = false;
849 BEGIN(HtmlA);
850 }
851<HtmlA>{ANCHTML} { // only labels that can be converted to doxygen anchor
852 yyextra->htmlAnchorStr += yytext;
854 int s=tag.find("=");
855 char c=tag[s+1];
857 if (c=='\'' || c=='"')
858 {
859 int e=tag.find(c,s+2);
860 if (e!=-1)
861 {
862 id=tag.mid(s+2,e-s-2);
864 }
865 }
866 else
867 {
868 id=tag.mid(s+1);
870 }
871 if (!id.isEmpty() && !yyextra->htmlAnchor)
872 {
873
877 yyextra->htmlAnchor = true;
878 }
879 }
880<HtmlA>("\""[^\n\"]*"\""|"'"[^\n']*"'") {
881 yyextra->htmlAnchorStr += yytext;
882 }
883<HtmlA>">"|"/>" {
884 if (!yyextra->htmlAnchor)
885 {
886 addOutput(yyscanner,yyextra->htmlAnchorStr);
888 }
889 else
890 {
891 if (yyleng == 1)
892 {
894 }
895 }
896 BEGIN(Comment);
897 }
898<HtmlA>{DOCNL} { // newline
899 yyextra->htmlAnchorStr += yytext;
900 if (*yytext == '\n') yyextra->lineNr++;
901 }
902<HtmlA>. { // catch-all for anything else
903 yyextra->htmlAnchorStr += yytext;
904 }
905<Comment>"<"{SUMMARY}">" { // start of a .NET XML style brief description
906 if (yyextra->htmlDetailsStack.empty())
907 {
909 }
910 else
911 {
913 }
914 }
915<Comment>"<"{REMARKS}">" { // start of a .NET XML style detailed description
918 }
919<Comment>"</"{SUMMARY}">" { // start of a .NET XML style detailed description
920 if (!yyextra->htmlDetailsStack.empty())
921 {
923 }
924 else
925 {
927 }
928 }
929<Comment>"</"{REMARKS}">" { // end of a brief or detailed description
932 }
933<Comment>"<"{CAPTION}{ATTR}">" {
935 int s=tag.find("id=");
936 if (s!=-1)
937 {
938 char c=tag[s+3];
939 if (c=='\'' || c=='"')
940 {
941 int e=tag.find(c,s+4);
942 if (e!=-1)
943 {
946 }
947 }
948 }
950 }
951<Comment>"<"{PRE}{ATTR}">" {
952 yyextra->insidePre=true;
954 }
955<Comment>"</"{PRE}">" {
956 yyextra->insidePre=false;
958 }
959<Comment>{RCSTAG} { // RCS tag which end a brief description
961 REJECT;
962 }
963<Comment>"<!--" {
964 BEGIN(HtmlComment);
965 }
966<Comment>"<!\[CDATA\[" {
967 BEGIN(CdataSection);
968 }
969<Comment>{B}*{CMD}"endinternal"{B}* {
971 if (!yyextra->inInternalDocs)
972 warn(yyextra->fileName,yyextra->lineNr,
973 "found \\endinternal without matching \\internal"
974 );
975 yyextra->inInternalDocs = false;
976 }
977<Comment>{B}*"\\ilinebr "{B}* { // preserve spacing around \\ilinebr
979 }
980<Comment>(\n|"\\ilinebr ")/({B}*(\n|{IFILELINE}?"\\ilinebr "))+ { // at least one blank line (or blank line command)
982 {
984 }
985 else
986 {
987 REJECT;
988 }
989 }
990<Comment>{B}*{CMD}[a-z_A-Z]+"{"[^}]*"}"{B}* |
991<Comment>{B}*{CMD}[a-z_A-Z]+{B}* { // potentially interesting command
992
994 int idx = fullMatch.
find(
'{');
995
996 if ((idx > 1) && (yytext[idx-1] == 'f') && (yytext[idx-2] == '\\' || yytext[idx-2] =='@')) REJECT;
997 int idxEnd = fullMatch.
find(
"}",idx+1);
1000 if (idx == -1)
1001 {
1003 }
1004 else
1005 {
1009 }
1011
1013 {
1014 int i=0;
1015 while (yytext[i]==' ' || yytext[i]=='\t') i++;
1016 yyextra->spaceBeforeCmd = fullMatch.
left(i);
1019 !(yyextra->inContext==
OutputXRef && cmdName==
"parblock"))
1020 {
1021 yyextra->briefEndsAtDot=false;
1023
1025 }
1026
1027 if (it->second.handler && it->second.handler(yyscanner, cmdName, optList))
1028 {
1029
1030
1031
1032 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.
1033
1034 yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);
1036 }
1037 else if (it->second.handler==nullptr)
1038 {
1039
1040
1042 }
1043 }
1044 else
1045 {
1047 }
1048 }
1049<Comment>{B}*({CMD}{CMD})"f"[$\[{] { // escaped formula command
1051 }
1052<Comment>{B}*{CMD}"~"[a-z_A-Z-]* { // language switch command
1056 {
1058 {
1059 warn(yyextra->fileName,yyextra->lineNr,
1061 }
1062 BEGIN(SkipLang);
1063 }
1064 }
#define Config_getEnumAsString(name)
#define Config_isAvailableEnum(name, value)
int qstricmp(const char *s1, const char *s2)
1065<Comment>{B}*{CMD}"f{"[^}\n]+"}"("{"?) { // start of a formula with custom environment
1067 yyextra->formulaText="";
1068 yyextra->formulaPreText="\\begin";
1069 yyextra->formulaPostText="";
1071 if (yyextra->formulaEnv.at(yyextra->formulaEnv.length()-1)=='{')
1072 {
1073
1074 yyextra->formulaEnv=yyextra->formulaEnv.left(yyextra->formulaEnv.length()-1);
1075 }
1076 yyextra->formulaPreText+=yyextra->formulaEnv;
1077 yyextra->formulaNewLines=0;
1078 BEGIN(ReadFormulaLong);
1079 }
1080<Comment>{B}*{CMD}"f$" { // start of a inline formula
1081 yyextra->formulaText="";
1082 yyextra->formulaPreText="$";
1083 yyextra->formulaPostText="";
1084 yyextra->formulaNewLines=0;
1085 BEGIN(ReadFormulaShort);
1086 }
1087<Comment>{B}*{CMD}"f(" { // start of a inline formula
1088 yyextra->formulaText="";
1089 yyextra->formulaPreText="";
1090 yyextra->formulaPostText="";
1091 yyextra->formulaNewLines=0;
1092 BEGIN(ReadFormulaRound);
1093 }
1094<Comment>{B}*{CMD}"f[" { // start of a block formula
1096 yyextra->formulaText="";
1097 yyextra->formulaPreText="\\[";
1098 yyextra->formulaPostText="";
1099 yyextra->formulaNewLines=0;
1100 BEGIN(ReadFormulaLong);
1101 }
1102<Comment>{B}*{CMD}"{" { // begin of a group
1103
1104 yyextra->docGroup.open(yyextra->current,yyextra->fileName,yyextra->lineNr);
1105 }
1106<Comment>{B}*{CMD}"}" { // end of a group
1107
1108 yyextra->docGroup.close(yyextra->current,yyextra->fileName,yyextra->lineNr,true);
1109 yyextra->docGroup.clearHeader();
1110 yyextra->parseMore=true;
1111 yyextra->needNewEntry = true;
1112 yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + (int)strlen(yytext);
1114 }
1115<Comment>{B}*{CMD}[$@\\&~<>#%] { // escaped character
1117 }
1118<Comment>[a-z_A-Z]+ { // normal word
1120 }
1121<Comment>^{B}*"."{Bopt}/\n { // explicit end autolist: e.g " ."
1123 }
1124<Comment>^{B}*[1-9][0-9]*"."{B}+ |
1125<Comment>^{B}*[*+]{B}+ { // start of autolist
1126 if (!yyextra->markdownSupport)
1127 {
1128 REJECT;
1129 }
1130 else
1131 {
1133 {
1134 yyextra->briefEndsAtDot=false;
1136 }
1138 }
1139 }
1140<Comment>^{B}*"-"{B}+ { // start of autolist
1142 {
1143 yyextra->briefEndsAtDot=false;
1145 }
1147 }
1148<Comment>^{B}*([\-:|]{B}*)*("--"|"---")({B}*[\-:|])*{Bopt}/\n { // horizontal line (dashed)
1150 }
1151<Comment>{CMD}"---" { // escaped mdash
1153 }
1154<Comment>{CMD}"--" { // escaped ndash
1156 }
1157<Comment>"---" { // mdash
1158 addOutput(yyscanner,yyextra->insidePre || yyextra->markdownSupport ? yytext :
"—");
1159 }
1160<Comment>"--" { // ndash
1161 addOutput(yyscanner,yyextra->insidePre || yyextra->markdownSupport ? yytext :
"–");
1162 }
1163<Comment>"-#"{B}+ { // numbered item
1165 {
1166 yyextra->briefEndsAtDot=false;
1168 }
1170 }
1171<Comment>[?!][a-z_A-Z0-9\(\)=<] |
1172<Comment>("."+)[a-z_A-Z0-9\)] { // . at start or in the middle of a word, or ellipsis
1173
1175 }
1176<Comment>{CMD}[\.?!] { // we have to be a bit careful with the special commands
1177
1179 }
1180<Comment>".\\"[ \t] { // . with escaped space.
1183 }
1184<Comment>"."[,:;] { // . with some puntuations such as "e.g.," or "e.g.:"
1186 }
1187<Comment>"...\\"[ \t] { // ellipsis with escaped space.
1189 }
1190<Comment>"..."/[^\.] { // ellipsis
1192 }
1193<Comment>".."[\.]?/[^ \t\n] { // internal ellipsis
1195 }
1196<Comment>(\n|"\\ilinebr ")({B}*(\n|"\\ilinebr "))+ { // at least one blank line (or blank line command)
1198 {
1199
1201 yy_size_t i;
1202 for (i=0;i<(yy_size_t)yyleng;)
1203 {
1204 if (yytext[i]==
'\n')
addOutput(yyscanner,
'\n'),i++;
1205 else if (strncmp(yytext+i,
"\\ilinebr ",9)==0)
addOutput(yyscanner,
"\\ilinebr "),i+=9;
1206 else i++;
1207 }
1208 }
1210 {
1211 yy_size_t i;
1212 for (i=0;i<(yy_size_t)yyleng;)
1213 {
1214 if (yytext[i]==
'\n')
addOutput(yyscanner,
'\n'),i++;
1215 else if (strncmp(yytext+i,
"\\ilinebr ",9)==0)
addOutput(yyscanner,
"\\ilinebr "),i+=9;
1216 else i++;
1217 }
1219 }
1220 else
1221 {
1222
1224 }
1226 }
1227<Comment>"."[?!] |
1228<Comment>[\.?!] { // potential end of a JavaDoc style comment
1230 if (yyextra->briefEndsAtDot)
1231 {
1233 yyextra->briefEndsAtDot=false;
1234 }
1235 }
1236<Comment>{DOCNL} { // newline
1238 if (*yytext == '\n') yyextra->lineNr++;
1239 }
1240<Comment>"<"[/]?{TABLEDEL}">" { // In case in xrefitem type some special handling is required
1242 {
1245 }
1246 else
1247 {
1248 REJECT;
1249 }
1250 }
1251<Comment>. { // catch-all for anything else
1253 }
1254
1255
1256
1257
1258<HtmlComment>"---"[!]?">"{B}* {
1259 warn(yyextra->fileName,yyextra->lineNr,
1260 "incorrect HTML end comment --->"
1261 );
1262 }
1263<HtmlComment>"--"[!]?">"{B}* { BEGIN( Comment ); }
1264<HtmlComment>{DOCNL} {
1265 if (*yytext=='\n')
1266 {
1267 yyextra->lineNr++;
1269 }
1270 }
1271<HtmlComment>[^\\\n\-]+ { // ignore unimportant characters
1272 }
1273<HtmlComment>. { // ignore every else
1274 }
1275
1276<CdataSection>"\]\]>" {
1277 BEGIN( Comment );
1278 }
1279<CdataSection>{DOCNL} {
1281 if (*yytext=='\n') yyextra->lineNr++;
1282 }
1283<CdataSection>[<>&] { // the special XML characters for iwhich the CDATA section is especially used
1286 }
1287<CdataSection>[^\\\n\]<>&]+ {
1289 }
1290<CdataSection>. {
1292 }
1293
1294
1295
1296<ReadFormulaShort,ReadFormulaShortSection>{CMD}"f$" { // end of inline formula
1297 yyextra->formulaPostText+="$";
1300 if (YY_START == ReadFormulaShort)
1301 {
1302 BEGIN(Comment);
1303 }
1304 else
1305 {
1306 yyextra->sectionTitle+= " "+form;
1307 BEGIN(SectionTitle);
1308 }
1309 }
1310<ReadFormulaRound,ReadFormulaRoundSection>{CMD}"f)" { // end of inline formula
1313 if (YY_START == ReadFormulaRound)
1314 {
1315 BEGIN(Comment);
1316 }
1317 else
1318 {
1319 yyextra->sectionTitle+= " "+form;
1320 BEGIN(SectionTitle);
1321 }
1322 }
1323<ReadFormulaLong>{CMD}"f]" { // end of block formula
1324 yyextra->formulaPostText+="\\]";
1326 BEGIN(Comment);
1327 }
1328<ReadFormulaLong>{CMD}"f}" { // end of custom env formula
1329 yyextra->formulaPostText+="\\end";
1330 yyextra->formulaPostText+=yyextra->formulaEnv;
1332 BEGIN(Comment);
1333 }
1334<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>[^\\@\n]+ { // any non-special character
1335 yyextra->formulaText+=yytext;
1336 }
1337<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>\n { // new line
1338 yyextra->formulaNewLines++;
1339 yyextra->formulaText+=*yytext;
1340 yyextra->lineNr++;
1341 addIline(yyscanner,yyextra->lineNr);
1342 }
1343<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>. { // any other character
1344 yyextra->formulaText+=*yytext;
1345 }
1346
1347
1348
1349<EnumDocArg1>{SCOPEID} { // handle argument
1351 yyextra->current->name = yytext;
1352 BEGIN( Comment );
1353 }
1354<EnumDocArg1>{LC} { // line continuation
1355 yyextra->lineNr++;
1357 }
1358<EnumDocArg1>{DOCNL} { // missing argument
1359 warn(yyextra->fileName,yyextra->lineNr,
1360 "missing argument after '\\enum'."
1361 );
1363 BEGIN( Comment );
1364 }
1365<EnumDocArg1>. { // ignore other stuff
1366 }
1367
1368
1369
1370<NameSpaceDocArg1>{SCOPENAME} { // handle argument
1374 BEGIN( Comment );
1375 }
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)
1376<NameSpaceDocArg1>{LC} { // line continuation
1377 yyextra->lineNr++;
1379 }
1380<NameSpaceDocArg1>{DOCNL} { // missing argument
1381 warn(yyextra->fileName,yyextra->lineNr,
1382 "missing argument after '\\namespace'."
1383 );
1385 BEGIN( Comment );
1386 }
1387<NameSpaceDocArg1>. { // ignore other stuff
1388 }
1389
1390
1391
1392<PackageDocArg1>{ID}("."{ID})* { // handle argument
1393 yyextra->current->name = yytext;
1394 BEGIN( Comment );
1395 }
1396<PackageDocArg1>{LC} { // line continuation
1397 yyextra->lineNr++;
1399 }
1400<PackageDocArg1>{DOCNL} { // missing argument
1401 warn(yyextra->fileName,yyextra->lineNr,
1402 "missing argument after \\package."
1403 );
1405
1406
1407 BEGIN( Comment );
1408 }
1409<PackageDocArg1>. { // ignore other stuff
1410 }
1411
1412
1413
1414<ConceptDocArg1>{SCOPEID} { // handle argument
1416 yyextra->current->name = yytext;
1417 BEGIN( Comment );
1418 }
1419<ConceptDocArg1>{LC} { // line continuation
1420 yyextra->lineNr++;
1422 }
1423<ConceptDocArg1>{DOCNL} { // missing argument
1424 warn(yyextra->fileName,yyextra->lineNr,
1425 "missing argument after '\\concept'."
1426 );
1428 BEGIN( Comment );
1429 }
1430<ConceptDocArg1>. { // ignore other stuff
1431 }
1432
1433
1434<ModuleDocArg1>{MODULE_ID} { // handle argument
1436 yyextra->current->name = yytext;
1437 BEGIN( Comment );
1438 }
1439<ModuleDocArg1>{LC} { // line continuation
1440 yyextra->lineNr++;
1442 }
1443<ModuleDocArg1>{DOCNL} { // missing argument
1444 warn(yyextra->fileName,yyextra->lineNr,
1445 "missing argument after '\\module'."
1446 );
1448 BEGIN( Comment );
1449 }
1450<ModuleDocArg1>. { // ignore other stuff
1451 }
1452
1453
1454
1455<ClassDocArg1>{SCOPENAME}{TMPLSPEC} {
1459 BEGIN( ClassDocArg2 );
1460 }
1461<ClassDocArg1>{SCOPENAME} { // first argument
1464 yyextra->current->name =
substitute(yytext,
".",
"::");
1465 if (yyextra->current->section.isProtocolDoc())
1466 {
1467 yyextra->current->name+="-p";
1468 }
1469
1470 BEGIN( ClassDocArg2 );
1471 }
1472<CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" {
1475 yyextra->current->name =
substitute(yytext,
".",
"::");
1476 BEGIN( ClassDocArg2 );
1477 }
1478<ClassDocArg1,CategoryDocArg1>{LC} { // line continuation
1479 yyextra->lineNr++;
1481 }
1482<ClassDocArg1,CategoryDocArg1>{DOCNL} {
1483 warn(yyextra->fileName,yyextra->lineNr,
1484 "missing argument after '\\{}'.",yyextra->currentCmd
1485 );
1487 BEGIN( Comment );
1488 }
1489<ClassDocArg1,CategoryDocArg1>. { // ignore other stuff
1490 }
1491
1492<ClassDocArg2>{DOCNL} {
1494 BEGIN( Comment );
1495 }
1496<ClassDocArg2>{FILE}|"<>" { // second argument; include file
1497 yyextra->current->includeFile = yytext;
1498 BEGIN( ClassDocArg3 );
1499 }
1500<ClassDocArg2>{LC} { // line continuation
1501 yyextra->lineNr++;
1503 }
1504<ClassDocArg2>. { // ignore other stuff
1505 }
1506
1507<ClassDocArg3>[<"]?{FILE}?[">]? { // third argument; include file name
1508 yyextra->current->includeName = yytext;
1509 BEGIN( Comment );
1510 }
1511<ClassDocArg3>{LC} { // line continuation
1512 yyextra->lineNr++;
1514 }
1515<ClassDocArg3>{DOCNL} {
1516
1518 BEGIN( Comment );
1519 }
1520<ClassDocArg3>. { // ignore other stuff
1521 }
1522
1523
1524
1525<GroupDocArg1>{LABELID}(".html"|".xhtml")? { // group name
1526 yyextra->current->name = yytext;
1527
1528
1529
1530 if (yyextra->current->name.endsWith(".html"))
1531 {
1532 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-5);
1533 }
1534 else if (yyextra->current->name.endsWith(".xhtml"))
1535 {
1536 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-6);
1537 }
1538 yyextra->current->type.clear();
1539 BEGIN(GroupDocArg2);
1540 }
1541<GroupDocArg1>"\\"{B}*"\n" { // line continuation
1542 yyextra->lineNr++;
1544 }
1545<GroupDocArg1>{DOCNL} { // missing argument!
1546 warn(yyextra->fileName,yyextra->lineNr,
1547 "missing group name after {}",
1548 yyextra->current->groupDocCmd()
1549 );
1550
1551
1553 BEGIN( Comment );
1554 }
1555<GroupDocArg1>. { // ignore other stuff
1556 }
1557<GroupDocArg2>"\\"{B}*"\n" { // line continuation
1558 yyextra->lineNr++;
1560 }
1561<GroupDocArg2>[^\n\\]+ { // title (stored in type)
1562 yyextra->current->type += yytext;
1563 }
1564<GroupDocArg2>{DOCNL}+ {
1565 yyextra->current->type = yyextra->current->type.stripWhiteSpace();
1567 yyextra->current->type.isEmpty()
1568 )
1569 {
1570 warn(yyextra->fileName,yyextra->lineNr,
1571 "missing title after "
1572 "\\defgroup {}", yyextra->current->name
1573 );
1574 }
1576 int extraLineNr = 0;
1578 {
1579 for (int i = 0; i < yyleng; i++)
1580 {
1581 if (yytext[i]=='\n') extraLineNr++;
1582 }
1583 }
1584
1585
1587 {
1588 addOutput(yyscanner,
" \\ifile \""+ yyextra->fileName);
1589 addOutput(yyscanner,
"\" \\iline " +
QCString().setNum(yyextra->lineNr + extraLineNr) +
" \\ilinebr ");
1590 }
1591 BEGIN( Comment );
1592 }
1593<GroupDocArg2>. { // title (stored in type)
1594 yyextra->current->type += yytext;
1595 }
1596
1597
1598
1599<PageDocArg1>[^\n]*"\\ilinebr @ianchor"\{[^\]\n]*\}{B}{FILE} { // special case where the Markdown processor has rewritten
1600
1601
1603 int start = text.
find(
'{');
1604 int end = text.
find(
'}',start+1);
1605 yyextra->current->name = text.
mid(
end+2);
1606 int istart = yyextra->current->name.
find(
"\\ilinebr");
1607 if (istart != -1)
1608 {
1609 QCString rest = yyextra->current->name.
mid(istart);
1611 yyextra->current->name = yyextra->current->name.mid(0,istart);
1612 }
1613 yyextra->current->args = text.
mid(start+1,
end-start-1);
1614
1615 BEGIN( PageDocArg2 );
1616 }
DirIterator end(const DirIterator &) noexcept
1617<PageDocArg1>{FILE} { // first argument; page name
1619 yyextra->current->args = "";
1620 BEGIN( PageDocArg2 );
1621 }
1622<PageDocArg1>{LC} { yyextra->lineNr++;
1624 }
1625<PageDocArg1>{DOCNL} {
1626 warn(yyextra->fileName,yyextra->lineNr,
1627 "missing argument after \\page."
1628 );
1630
1631
1632 BEGIN( Comment );
1633 }
1634<PageDocArg1>. { // ignore other stuff
1635 }
1636<PageDocArg2>{DOCNL} { // second argument; page title
1638
1639
1640 addOutput(yyscanner,
" \\ifile \""+ yyextra->fileName);
1641 addOutput(yyscanner,
"\" \\iline " +
QCString().setNum(yyextra->lineNr) +
" \\ilinebr ");
1642 BEGIN( Comment );
1643 }
1644<PageDocArg2>{CMD}[<>] {
1645
1649 yyextra->current->args += tmp;
1650 }
1651<PageDocArg2>. {
1652 yyextra->current->args += yytext;
1653 }
1654
1655<ParamArg1>{ID}/{B}*"," {
1657 }
1658<ParamArg1>"," {
1660 }
1661<ParamArg1>{DOCNL} {
1662 if (*yytext=='\n') yyextra->lineNr++;
1664 }
1665<ParamArg1>{ID} {
1667 BEGIN( Comment );
1668 }
1669<ParamArg1>. {
1670 unput(yytext[0]);
1671 BEGIN( Comment );
1672 }
1673
1674
1675
1676<FileDocArg1>{DOCNL} { // no file name specified
1678
1679
1680 BEGIN( Comment );
1681 }
1682<FileDocArg1>{FILE} { // first argument; name
1684 BEGIN( Comment );
1685 }
1686<FileDocArg1>{LC} { yyextra->lineNr++;
1688 }
1689<FileDocArg1>. { // ignore other stuff
1690 }
1691
1692
1693
1694<XRefItemParam1>{LABELID} { // first argument
1695 yyextra->newXRefItemKey=yytext;
1697 BEGIN(XRefItemParam2);
1698 }
1699<XRefItemParam1>{LC} { // line continuation
1700 yyextra->lineNr++;
1702 }
1703<XRefItemParam1>{DOCNL} { // missing arguments
1704 warn(yyextra->fileName,yyextra->lineNr,
1705 "Missing first argument of \\xrefitem"
1706 );
1707 if (*yytext=='\n') yyextra->lineNr++;
1710 BEGIN( Comment );
1711 }
1712<XRefItemParam1>. { // ignore other stuff
1713 }
1714
1715<XRefItemParam2>"\""[^\n\"]*"\"" { // second argument
1717 BEGIN(XRefItemParam3);
1718 }
1719<XRefItemParam2>{LC} { // line continuation
1720 yyextra->lineNr++;
1722 }
1723<XRefItemParam2>{DOCNL} { // missing argument
1724 warn(yyextra->fileName,yyextra->lineNr,
1725 "Missing second argument of \\xrefitem"
1726 );
1727 if (*yytext=='\n') yyextra->lineNr++;
1730 BEGIN( Comment );
1731 }
1732<XRefItemParam2>. { // ignore other stuff
1733 }
1734
1735<XRefItemParam3>"\""[^\n\"]*"\"" { // third argument
1738 BEGIN( Comment );
1739 }
1740<XRefItemParam2,XRefItemParam3>{LC} { // line continuation
1741 yyextra->lineNr++;
1743 }
1744<XRefItemParam3>{DOCNL} { // missing argument
1745 warn(yyextra->fileName,yyextra->lineNr,
1746 "Missing third argument of \\xrefitem"
1747 );
1748 if (*yytext=='\n') yyextra->lineNr++;
1751 BEGIN( Comment );
1752 }
1753<XRefItemParam3>. { // ignore other stuff
1754 }
1755
1756
1757
1758
1759<RelatesParam1>({ID}("::"|"."))*{ID} { // argument
1760 yyextra->current->relates = yytext;
1761
1762
1763
1764
1765 BEGIN( Comment );
1766 }
1767<RelatesParam1>{LC} { // line continuation
1768 yyextra->lineNr++;
1770 }
1771<RelatesParam1>{DOCNL} { // missing argument
1772 warn(yyextra->fileName,yyextra->lineNr,
1773 "Missing argument of '\\{}' command",yyextra->currentCmd
1774 );
1776
1777
1778 BEGIN( Comment );
1779 }
1780<RelatesParam1>. { // ignore other stuff
1781 }
1782
1783
1784
1785<Qualifier>{LABELID} { // unquoted version, simple label
1786 yyextra->current->qualifiers.emplace_back(yytext);
1787 BEGIN( Comment );
1788 }
1789<Qualifier>"\""[^\"]*"\"" { // quotes version, add without quotes
1790 std::string inp(yytext);
1791 yyextra->current->qualifiers.push_back(inp.substr(1,yyleng-2));
1792 BEGIN( Comment );
1793 }
1794<Qualifier>{DOCNL} { // missing argument
1795 warn(yyextra->fileName,yyextra->lineNr,
1796 "Missing argument of '\\{}' command",yyextra->currentCmd
1797 );
1799 BEGIN( Comment );
1800 }
1801<Qualifier>. {
1802 warn(yyextra->fileName,yyextra->lineNr,
1803 "Argument of '\\{}' command should be quoted",yyextra->currentCmd
1804 );
1806 BEGIN( Comment );
1807 }
1808
1809<ILine>{LINENR}/[\\@\n\.] |
1810<ILine>{LINENR}{B} {
1811 bool ok = false;
1813 if (!ok)
1814 {
1815 warn(yyextra->fileName,yyextra->lineNr,
"Invalid line number '{}' for iline command",yytext);
1816 }
1817 else
1818 {
1819 yyextra->lineNr = nr;
1820 }
1822 if (YY_START == ILine)
1823 {
1824 BEGIN(Comment);
1825 }
1826 else
1827 {
1828 yyextra->sectionTitle+=yytext;
1829 BEGIN(SectionTitle);
1830 }
1831 }
int toInt(bool *ok=nullptr, int base=10) const
1832<ILine,ILineSection>. {
1834 if (YY_START == ILine)
1835 {
1836 BEGIN(Comment);
1837 }
1838 else
1839 {
1840 yyextra->sectionTitle+=yytext;
1841 BEGIN(SectionTitle);
1842 }
1843 }
1844
1845
1846<IRaise>{B}*[0-9]+/[\\@\n\.] |
1847<IRaise>{B}*[0-9]+{B} {
1848 bool ok = false;
1850 if (!ok)
1851 {
1852 warn(yyextra->fileName,yyextra->lineNr,
"Invalid level '{}' for iraise command",yytext);
1853 }
1854 else
1855 {
1856 yyextra->raiseLevel = nr;
1857 }
1858 BEGIN(Comment);
1859 }
1860<IRaise>. {
1861 unput(yytext[0]);
1862 BEGIN(Comment);
1863 }
1864
1865
1866<IRaisePrefix>{B}*"\""({LABELID})?"\"" {
1868 yyextra->raisePrefix = text.stripWhiteSpace().mid(1,text.length()-2);
1870 BEGIN(Comment);
1871 }
1872<IRaisePrefix>. {
1873 unput(yytext[0]);
1874 BEGIN(Comment);
1875 }
1876
1877
1878
1879
1880<IFile,IFileSection>{FILE} {
1883 if (yytext[0] == '\"') yyextra->fileName = text.mid(1,text.length()-2);
1884 else yyextra->fileName = yytext;
1885 if (YY_START == IFile)
1886 {
1887 BEGIN(Comment);
1888 }
1889 else
1890 {
1891 yyextra->sectionTitle+=yytext;
1892 BEGIN(SectionTitle);
1893 }
1894 }
1895
1896<LinkSection>[^\\@\n]* {
1897 yyextra->sectionTitle+=yytext;
1898 }
1899<LinkSection>{CMD}{CMD} {
1900 yyextra->sectionTitle+=yytext;
1901 }
1902<LinkSection>{DOCNL} {
1904 if (*yytext == '\n') yyextra->lineNr++;
1905 yyextra->sectionTitle+=yytext;
1906 }
1907<LinkSection>{CMD}"endlink" {
1908 yyextra->sectionTitle+=yytext;
1909 BEGIN(SectionTitle);
1910 }
1911<LinkSection>. {
1912 yyextra->sectionTitle+=yytext;
1913 }
1914<LinkSection><<EOF>> {
1915 warn(yyextra->fileName,yyextra->lineNr,
1916 "reached end of comment while inside a '\\link' command, missing '\\endlink' command"
1917 );
1919 }
1920
1921
1922<LineParam>{CMD}{CMD} { // escaped command
1924 }
1925<LineParam>{DOCNL} { // end of argument
1926
1927
1929 BEGIN( Comment );
1930 }
1931<LineParam>{LC} { // line continuation
1932 yyextra->lineNr++;
1934 }
1935<LineParam>({CMD}{CMD}){ID} { // escaped command
1937 }
1938<LineParam>. { // ignore other stuff
1940 }
1941
1942
1943
1944<SectionLabel>{LABELID} {
1945 yyextra->sectionLabel+=yytext;
1946 }
1947<SectionLabel>{CMD}"lineinfo"("{}")? {
1949 }
1950<SectionLabel>{CMD}"fileinfo"("{"[^}]*"}")? {
1951 FileInfo fi(yyextra->fileName.str());
1952 bool hasOption = false;
1954 if (yytext[yyleng-1] == '}')
1955 {
1960 for (const auto &opt_ : optList)
1961 {
1963 std::string opt = optStripped.
lower().
str();
1966 {
1967 if (hasOption)
1968 {
1969 warn(yyextra->fileName,yyextra->lineNr,
"Multiple options specified with \\fileinfo, discarding '{}'", optStripped);
1970 }
1971 else
1972 {
1973 label = result;
1974 }
1975 hasOption = true;
1976 }
1977 else
1978 {
1979 warn(yyextra->fileName,yyextra->lineNr,
"Unknown option specified with \\fileinfo: '{}'", optStripped);
1980 }
1981 }
1982 }
1983 if (!hasOption)
1984 {
1986 {
1988 }
1989 else
1990 {
1991 label=yyextra->fileName;
1992 }
1993 }
1995 yyextra->sectionLabel+=label;
1996 }
1997<SectionLabel>{DOCNL} {
1998 yyextra->sectionTitle.clear();
1999 if (yyextra->sectionLabel.isEmpty())
2000 {
2001 warn(yyextra->fileName,yyextra->lineNr,
2002 "\\section command has no label"
2003 );
2004 }
2005 else
2006 {
2007 yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
2008 addOutput(yyscanner,yyextra->sectionLabel.data());
2010 }
2011 if (*yytext=='\n') yyextra->lineNr++;
2013 BEGIN( Comment );
2014 }
2015<SectionLabel>. { // invalid character for section label
2016 if (yyextra->sectionLabel.isEmpty())
2017 {
2018 warn(yyextra->fileName,yyextra->lineNr,
2019 "Invalid or missing section label"
2020 );
2021 BEGIN(Comment);
2022 }
2023 else
2024 {
2025 yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
2026 addOutput(yyscanner,yyextra->sectionLabel.data());
2027 yyextra->sectionTitle.clear();
2029 BEGIN(SectionTitle);
2030 }
2031 }
2032<SectionTitle>{STAopt}/"\n" { // end of section title
2035 BEGIN( Comment );
2036 }
2037<SectionTitle>{STopt}"\\\\ilinebr" { // escaped end of section title
2038 yyextra->sectionTitle+=yytext;
2039 }
2040<SectionTitle>{STopt}/"\\ilinebr" { // end of section title
2043 BEGIN( Comment );
2044 }
2045<SectionTitle>{B}*{CMD}"f$" {
2046 yyextra->formulaText="";
2047 yyextra->formulaPreText="$";
2048 yyextra->formulaPostText="";
2049 yyextra->formulaNewLines=0;
2050 BEGIN(ReadFormulaShortSection);
2051 }
2052<SectionTitle>{B}*{CMD}"f(" { // start of a inline formula
2053 yyextra->formulaText="";
2054 yyextra->formulaPreText="";
2055 yyextra->formulaPostText="";
2056 yyextra->formulaNewLines=0;
2057 BEGIN(ReadFormulaRoundSection);
2058 }
2059<SectionTitle>{B}*{CMD}"~"[a-z_A-Z-]* | // language switch command
2060<SectionTitle>{B}*{CMD}"f"[\[{] { // block formula
2064 warn(yyextra->fileName,yyextra->lineNr,
2065 "'\\{}' command is not allowed in section title, ending section title.",
2067 );
2069 BEGIN(Comment);
2070 }
2071<SectionTitle>{LC} { // line continuation
2072 yyextra->lineNr++;
2074 }
2075<SectionTitle>[^\n@\\]* { // any character without special meaning
2076 yyextra->sectionTitle+=yytext;
2078 }
2079<SectionTitle>{B}*{CMD}{CMD} {
2080 yyextra->sectionTitle+=yytext;
2082 }
2083<SectionTitle>{B}*{CMD}[a-z_A-Z]+"{"[^}]*"}"{B}* |
2084<SectionTitle>{B}*{CMD}[a-z_A-Z]+{B}* { // handling command in section title
2086 int idx = fullMatch.
find(
'{');
2087
2088 if ((idx > 1) && (yytext[idx-1] == 'f') && (yytext[idx-2] == '\\' || yytext[idx-2] =='@')) REJECT;
2089 int idxEnd = fullMatch.
find(
"}",idx+1);
2092 if (idx == -1)
2093 {
2095 }
2096 else
2097 {
2101 }
2104 {
2105 switch (it->second.sectionHandling)
2106 {
2108 {
2109 int i=0;
2110 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2111 yyextra->sectionTitle+=fullMatch.
left(i);
2112 yyextra->sectionTitle+='@';
2113 yyextra->sectionTitle+=fullMatch.
mid(i);
2117 warn(yyextra->fileName,yyextra->lineNr,
2118 "'\\{}' command is not allowed in section title, escaping command.",cmdName
2119 );
2120 }
2121 break;
2123 {
2126 warn(yyextra->fileName,yyextra->lineNr,
2127 "'\\{}' command is not allowed in section title, ending section title.",cmdName
2128 );
2130 BEGIN(Comment);
2131 }
2132 break;
2134 {
2135 if (cmdName == "fileinfo")
2136 {
2137 int i=0;
2138 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2139 yyextra->sectionTitle+=fullMatch.
left(i);
2142 if (idxEnd == -1)
2143 {
2144 yyextra->sectionTitle+=fullMatch.
mid(i+9);
2146 }
2147 else
2148 {
2149 yyextra->sectionTitle+=fullMatch.
mid(idxEnd+1);
2151 }
2152 }
2153 else if (cmdName == "lineinfo")
2154 {
2155 int i=0;
2156 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2157 yyextra->sectionTitle+=fullMatch.
left(i);
2159 yyextra->sectionTitle+=' ';
2160 yyextra->sectionTitle+=fullMatch.
mid(i+9);
2165 }
2166 else if (cmdName == "raisewarning")
2167 {
2168 yyextra->raiseWarning = "";
2169 BEGIN(RaiseWarningSection);
2170 }
2171 else if (cmdName == "noop")
2172 {
2174 BEGIN(Noop);
2175 }
2176 else if (cmdName == "cite")
2177 {
2178 yyextra->sectionTitle+=yytext;
2180 BEGIN(CiteLabelSection);
2181 }
2182 else if (cmdName == "iline")
2183 {
2184 yyextra->sectionTitle+=yytext;
2186 BEGIN(ILineSection);
2187 }
2188 else if (cmdName == "ifile")
2189 {
2190 yyextra->sectionTitle+=yytext;
2192 BEGIN(IFileSection);
2193 }
2194 else if ((cmdName == "anchor") || (cmdName == "ianchor"))
2195 {
2197 if (optList.empty())
2198 {
2199 yyextra -> anchorTitle = "";
2200 }
2201 else
2202 {
2204 yyextra -> anchorTitle =
join(optList,
" ");
2205 }
2207 BEGIN(AnchorLabelSection);
2208 }
2209 else if (cmdName == "link")
2210 {
2211 yyextra->sectionTitle+=yytext;
2212 BEGIN(LinkSection);
2213 }
2214 else
2215 {
2216 yyextra->sectionTitle+=yytext;
2217 warn(yyextra->fileName,yyextra->lineNr,
2218 "internal error '\\{}' command is to be replaced in section title.",cmdName
2219 );
2220 }
2221 }
2222 break;
2224 {
2225 yyextra->sectionTitle+=yytext;
2227 }
2228 break;
2229 }
2230 }
2231 else
2232 {
2233 yyextra->sectionTitle+=yytext;
2235 }
2236 }
2237<SectionTitle>. { // anything else
2238 yyextra->sectionTitle+=yytext;
2240 }
2241
2242
2243
2244<SubpageLabel>{FILE} { // first argument
2246
2247
2248 yyextra->current->extends.emplace_back(yytext,Protection::Public,Specifier::Normal);
2249 BEGIN(SubpageTitle);
2250 }
2251<SubpageLabel>{DOCNL} { // missing argument
2252 warn(yyextra->fileName,yyextra->lineNr,
2253 "\\subpage command has no label"
2254 );
2255 if (*yytext=='\n') yyextra->lineNr++;
2257 BEGIN( Comment );
2258 }
2259<SubpageLabel>. {
2260 unput(yytext[0]);
2261 BEGIN( Comment );
2262 }
2263<SubpageTitle>{DOCNL} { // no title, end command
2265 BEGIN( Comment );
2266 }
2267<SubpageTitle>[ \t]*"\""[^\"\n]*"\"" { // add title, end of command
2269 BEGIN( Comment );
2270 }
2271<SubpageTitle>. { // no title, end of command
2272 unput(*yytext);
2273 BEGIN( Comment );
2274 }
2275
2276
2277
2278<AnchorLabel,AnchorLabelSection>{LABELID} { // found argument
2279 QCString lbl = yyextra->raisePrefix+yytext;
2280 addAnchor(yyscanner,lbl, yyextra->anchorTitle);
2282 if (YY_START == AnchorLabel)
2283 {
2284 BEGIN(Comment);
2285 }
2286 else
2287 {
2288 BEGIN(SectionTitle);
2289 }
2290 }
2291<AnchorLabel,AnchorLabelSection>{DOCNL} { // missing argument
2292 warn(yyextra->fileName,yyextra->lineNr,
2293 "\\anchor command has no label"
2294 );
2295 if (*yytext=='\n') yyextra->lineNr++;
2297 if (YY_START == AnchorLabel)
2298 {
2299 BEGIN(Comment);
2300 }
2301 else
2302 {
2303 BEGIN(SectionTitle);
2304 }
2305 }
2306<AnchorLabel,AnchorLabelSection>. { // invalid character for anchor label
2307 warn(yyextra->fileName,yyextra->lineNr,
2308 "Invalid or missing anchor label"
2309 );
2311 if (YY_START == AnchorLabel)
2312 {
2313 BEGIN(Comment);
2314 }
2315 else
2316 {
2317 BEGIN(SectionTitle);
2318 }
2319 }
2320
2321
2322
2323<RequirementLabel>{REQID} { // found argument
2324 yyextra->current->name = yytext;
2325 yyextra->current->type.clear();
2326 BEGIN( RequirementTitle );
2327 }
2328<SatisfiesLabel>{REQID} { // found argument
2329 yyextra->reqId = yytext;
2330 yyextra->reqTitle.clear();
2331 BEGIN( SatisfiesTitle );
2332 }
2333<VerifiesLabel>{REQID} { // found argument
2334 yyextra->reqId = yytext;
2335 yyextra->reqTitle.clear();
2336 BEGIN( VerifiesTitle );
2337 }
2338<RequirementLabel,SatisfiesLabel,VerifiesLabel>"\\"{B}*"\n" { // line continuation
2339 yyextra->lineNr++;
2341 }
2342<RequirementLabel,SatisfiesLabel,VerifiesLabel>{DOCNL} { // missing argument
2343 warn(yyextra->fileName,yyextra->lineNr,
2344 "missing requirement ID after \\requirement command"
2345 );
2347 BEGIN( Comment );
2348 }
2349<RequirementLabel,SatisfiesLabel,VerifiesLabel>. { // invalid character for requirement label
2350 }
2351
2352<RequirementTitle,SatisfiesTitle,VerifiesTitle>"\\"{B}*"\n" { // line continuation
2353 yyextra->lineNr++;
2355 }
2356<RequirementTitle>[^\n\\]+ { // title (stored in type)
2357 yyextra->current->type += yytext;
2358 }
2359<SatisfiesTitle,VerifiesTitle>[^\n\\@]+ { // title (stored in type)
2360 yyextra->reqTitle += yytext;
2361 }
2362<RequirementTitle>({CMD}("verifies"|"satisfies"|"requirement"){B}+)|{DOCNL}+ {
2363 yyextra->current->type = yyextra->current->type.stripWhiteSpace();
2366 BEGIN( Comment );
2367 }
2368<SatisfiesTitle>({CMD}("verifies"|"satisfies"|"requirement"){B}+)|{DOCNL}+ {
2369 yyextra->reqTitle = yyextra->reqTitle.stripWhiteSpace();
2371 if (yyextra->current->section.isRequirementDoc())
2372 {
2373 warn(yyextra->fileName,yyextra->lineNr,
2374 "@satisfies command is not allowed in documentation of a requirement. Put in at the place where the requirement is implemented."
2375 );
2376 }
2377 else
2378 {
2380 yyextra->reqId,
2381 yyextra->reqTitle,
2382 yyextra->fileName,
2383 yyextra->lineNr);
2384 }
2385 BEGIN( Comment );
2386 }
2387<VerifiesTitle>({CMD}("verifies"|"satisfies"|"requirement"){B}+)|{DOCNL}+ {
2388 yyextra->reqTitle = yyextra->reqTitle.stripWhiteSpace();
2390 if (yyextra->current->section.isRequirementDoc())
2391 {
2392 warn(yyextra->fileName,yyextra->lineNr,
2393 "@verifies command is not allowed in documentation of a requirement. Put in at the place where the requirement is tested."
2394 );
2395 }
2396 else
2397 {
2399 yyextra->reqId,
2400 yyextra->reqTitle,
2401 yyextra->fileName,
2402 yyextra->lineNr);
2403 }
2404 BEGIN( Comment );
2405 }
2406<RequirementTitle>. { // title (stored in type)
2407 yyextra->current->type += yytext;
2408 }
2409<SatisfiesTitle,VerifiesTitle>. { // title (stored in reqTitle)
2410 yyextra->reqTitle += yytext;
2411 }
2412
2413
2414
2415
2416<FormatBlock>{CMD}("endverbatim"|"endiverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode"|"endicode"|"endmsc"|"endmermaid")/{NW} { // possible ends
2418 if (&yytext[4]==yyextra->blockName)
2419 {
2420 BEGIN(Comment);
2421 }
2422 }
2423<FormatBlock>{CMD}"enduml" {
2425 if (yyextra->blockName=="startuml")
2426 {
2427 BEGIN(Comment);
2428 }
2429 }
2430<FormatBlock>[^ \@\*\/\\\n]* { // some word
2432 }
2433<FormatBlock>{DOCNL} { // new line
2434 if (*yytext=='\n') yyextra->lineNr++;
2436 }
2437<FormatBlock>{CCS} { // start of a C-comment
2438 if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim" ||
2439 yyextra->blockName=="icode" || yyextra->blockName=="iverbatim"||
2440 yyextra->blockName=="iliteral"
2441 )
2442 ) yyextra->commentCount++;
2444 }
2445<FormatBlock>{CCE} { // end of a C-comment
2447 if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim" ||
2448 yyextra->blockName=="icode" || yyextra->blockName=="iverbatim"||
2449 yyextra->blockName=="iliteral"
2450 )
2451 )
2452 {
2453 yyextra->commentCount--;
2454 if (yyextra->commentCount<0)
2455 {
2456 QCString endTag =
"end"+yyextra->blockName;
2457 if (yyextra->blockName=="startuml") endTag="enduml";
2458 warn(yyextra->fileName,yyextra->lineNr,
2459 "found */ without matching /* while inside a \\{} block! Perhaps a missing \\{}?",
2460 yyextra->blockName,endTag);
2461 }
2462 }
2463 }
2464<FormatBlock>. {
2466 }
2467<FormatBlock><<EOF>> {
2468 QCString endTag =
"end"+yyextra->blockName;
2469 if (yyextra->blockName=="startuml") endTag="enduml";
2470 warn(yyextra->fileName,yyextra->lineNr,
2471 "reached end of comment while inside a \\{} block; check for missing \\{} tag!",
2472 yyextra->blockName,endTag
2473 );
2475 }
2476
2477
2478
2479<GuardParam>{B}*"(" {
2480 yyextra->guardExpr=yytext;
2481 yyextra->roundCount=1;
2482 BEGIN(GuardExpr);
2483 }
2484<GuardExpr>[^()]* {
2485 yyextra->guardExpr+=yytext;
2487 }
2488<GuardExpr>"(" {
2489 yyextra->guardExpr+=yytext;
2490 yyextra->roundCount++;
2491 }
2492<GuardExpr>")" {
2493 yyextra->guardExpr+=yytext;
2494 yyextra->roundCount--;
2495 if (yyextra->roundCount==0)
2496 {
2498 }
2499 }
2500<GuardExpr>\n {
2501 warn(yyextra->fileName,yyextra->lineNr,
2502 "invalid expression '{}' for yyextra->guards",yyextra->guardExpr);
2503 unput(*yytext);
2504 BEGIN(GuardParam);
2505 }
2506<GuardParam>{B}*[a-z_A-Z0-9.\-]+ { // parameter of if/ifnot yyextra->guards
2508 }
2509<GuardParam>{DOCNL} { // end of argument
2510
2511
2515 }
2516<GuardParam>{LC} { // line continuation
2517 yyextra->lineNr++;
2519 }
2520<GuardParam>. { // empty condition
2521 unput(*yytext);
2523 }
2524<GuardParamEnd>{B}*{DOCNL} {
2526 yyextra->spaceBeforeIf.clear();
2528 BEGIN(Comment);
2529 }
2530<GuardParamEnd>{B}* {
2531 if (!yyextra->spaceBeforeIf.isEmpty())
2532 {
2533 addOutput(yyscanner,yyextra->spaceBeforeIf);
2534 }
2535 yyextra->spaceBeforeIf.clear();
2537 BEGIN(Comment);
2538 }
2539<GuardParamEnd>. {
2540 unput(*yytext);
2542 BEGIN(Comment);
2543 }
2544
2545
2546
2547<SkipGuardedSection>{CMD}"ifnot"/{NW} {
2549 yyextra->guards->emplace(false);
2550 BEGIN( GuardParam );
2551 }
2552<SkipGuardedSection>{CMD}"if"/{NW} {
2554 yyextra->guards->emplace(false);
2555 BEGIN( GuardParam );
2556 }
2557<SkipGuardedSection>{CMD}"endif"/{NW} {
2558 if (yyextra->guards->empty())
2559 {
2560 warn(yyextra->fileName,yyextra->lineNr,
2561 "found \\endif without matching start command");
2562 BEGIN( Comment );
2563 }
2564 else
2565 {
2566 yyextra->guards->pop();
2567 if (yyextra->guards->empty())
2568 {
2569 BEGIN( GuardParamEnd );
2570 }
2571 else
2572 {
2573 if (yyextra->guards->top().isEnabled())
2574 {
2575 BEGIN( GuardParamEnd );
2576 }
2577 else
2578 {
2579 BEGIN( SkipGuardedSection );
2580 }
2581 }
2582 }
2583 }
2584<SkipGuardedSection>{CMD}"else"/{NW} {
2585 if (yyextra->guards->empty())
2586 {
2587 warn(yyextra->fileName,yyextra->lineNr,
2588 "found \\else without matching start command");
2589 }
2590 else if (yyextra->guards->top().hasElse())
2591 {
2592 warn(yyextra->fileName,yyextra->lineNr,
2593 "found multiple \\else commands in same \\if construct");
2594 yyextra->guards->top().setEnabled(false);
2595 BEGIN( SkipGuardedSection );
2596 }
2597 else if (!yyextra->guards->top().parentVisible())
2598 {
2599 yyextra->guards->top().setEnabled(false);
2600 BEGIN( SkipGuardedSection );
2601 }
2602 else
2603 {
2604 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2605 yyextra->guards->top().setElse();
2606 if (!yyextra->guards->top().parentVisible())
2607 {
2608 yyextra->guards->top().setEnabled(false);
2609 BEGIN( SkipGuardedSection );
2610 }
2611 else if (yyextra->guards->top().isEnabledFound())
2612 {
2613 yyextra->guards->top().setEnabled(false);
2614 BEGIN( SkipGuardedSection );
2615 }
2616 else
2617 {
2618 yyextra->guards->top().setEnabled(true);
2619 BEGIN( GuardParamEnd );
2620 }
2621 }
2622 }
2623<SkipGuardedSection>{CMD}"elseif"/{NW} {
2624 if (yyextra->guards->empty())
2625 {
2626 warn(yyextra->fileName,yyextra->lineNr,
2627 "found \\elseif without matching start command");
2628 }
2629 else if (yyextra->guards->top().hasElse())
2630 {
2631 warn(yyextra->fileName,yyextra->lineNr,
2632 "found \\elseif command after \\else command was given in \\if construct");
2634 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2635 yyextra->guards->top().setEnabled(false);
2636 BEGIN( GuardParam );
2637 }
2638 else
2639 {
2641 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2642 yyextra->guards->top().setEnabled(false);
2643 BEGIN( GuardParam );
2644 }
2645 }
2646<SkipGuardedSection>{DOCNL} { // skip line
2647 if (*yytext=='\n') yyextra->lineNr++;
2648
2649 }
2650<SkipGuardedSection>[^ \\@\n]+ { // skip non-special characters
2651 }
2652<SkipGuardedSection>{CMD}{CMD} |
2653<SkipGuardedSection>. { // any other character
2654 }
2655
2656
2657
2658
2659<SkipInternal>{DOCNL} { // skip line
2660 if (*yytext=='\n') yyextra->lineNr++;
2662 }
2663<SkipInternal>{CMD}"if"/[ \t] {
2664 yyextra->condCount++;
2665 }
2666<SkipInternal>{CMD}"ifnot"/[ \t] {
2667 yyextra->condCount++;
2668 }
2669<SkipInternal>{CMD}/"endif" {
2670 yyextra->condCount--;
2671 if (yyextra->condCount<0)
2672 {
2673 unput('\\');
2674 BEGIN(Comment);
2675 }
2676 }
2677<SkipInternal>{CMD}/"section"[ \t] {
2678 if (yyextra->sectionLevel>0)
2679 {
2680 unput('\\');
2681 BEGIN(Comment);
2682 }
2683 }
2684<SkipInternal>{CMD}/"subsection"[ \t] {
2685 if (yyextra->sectionLevel>1)
2686 {
2687 unput('\\');
2688 BEGIN(Comment);
2689 }
2690 }
2691<SkipInternal>{CMD}/"subsubsection"[ \t] {
2692 if (yyextra->sectionLevel>2)
2693 {
2694 unput('\\');
2695 BEGIN(Comment);
2696 }
2697 }
2698<SkipInternal>{CMD}/"paragraph"[ \t] {
2699 if (yyextra->sectionLevel>3)
2700 {
2701 unput('\\');
2702 BEGIN(Comment);
2703 }
2704 }
2705<SkipInternal>{CMD}/"subparagraph"[ \t] {
2706 if (yyextra->sectionLevel>4)
2707 {
2708 unput('\\');
2709 BEGIN(Comment);
2710 }
2711 }
2712<SkipInternal>{CMD}/"subsubparagraph"[ \t] {
2713 if (yyextra->sectionLevel>5)
2714 {
2715 unput('\\');
2716 BEGIN(Comment);
2717 }
2718 }
2719<SkipInternal>{CMD}"endinternal"[ \t]* {
2720 BEGIN(Comment);
2721 }
2722<SkipInternal>[^ \\@\n]+ { // skip non-special characters
2723 }
2724<SkipInternal>. { // any other character
2725 }
2726
2727
2728
2729
2730<NameParam>{DOCNL} { // end of argument
2731
2732
2734 BEGIN( Comment );
2735 }
2736<NameParam>{LC} { // line continuation
2737 yyextra->lineNr++;
2739 yyextra->docGroup.appendHeader(' ');
2740 }
2741<NameParam>. { // ignore other stuff
2742 yyextra->docGroup.appendHeader(*yytext);
2743 yyextra->current->name+=*yytext;
2744 }
2745
2746
2747<Noop>{DOCNL} { // end of argument
2748 if (*yytext=='\n')
2749 {
2750 yyextra->lineNr++;
2752 }
2753 BEGIN( Comment );
2754 }
2755<Noop>. { // ignore other stuff
2756 }
2757
2758<RaiseWarning,RaiseWarningSection>{DOCNL} { // end of argument
2760 "{}",yyextra->raiseWarning);
2761 yyextra->raiseWarning = "";
2762 if (*yytext=='\n') yyextra->lineNr++;
2764 if (YY_START == RaiseWarning)
2765 {
2766 BEGIN(Comment);
2767 }
2768 else
2769 {
2770 yyextra->sectionTitle+=yytext;
2771 BEGIN(SectionTitle);
2772 }
2773 }
#define warn_doc_error(file, line, fmt,...)
2774<RaiseWarning,RaiseWarningSection>. { // ignore other stuff
2775 yyextra->raiseWarning += yytext;
2776 }
2777
2778
2779<InGroupParam>{LABELID} { // group id
2780 yyextra->current->groups.emplace_back(
2782 );
2783 yyextra->inGroupParamFound=true;
2784 }
@ GROUPING_INGROUP
membership in group was defined by @ingroup
2785<InGroupParam>{DOCNL} { // missing argument
2786 if (!yyextra->inGroupParamFound)
2787 {
2788 warn(yyextra->fileName,yyextra->lineNr,
2789 "Missing group name for \\ingroup command"
2790 );
2791 }
2792
2793
2795 BEGIN( Comment );
2796 }
2797<InGroupParam>{LC} { // line continuation
2798 yyextra->lineNr++;
2800 }
2801<InGroupParam>. { // ignore other stuff
2803 }
2804
2805
2806
2807<FnParam>{DOCNL} { // end of argument
2808 if (yyextra->braceCount==0)
2809 {
2810 if (yyextra->functionProto.stripWhiteSpace().isEmpty())
2811 {
2812 warn(yyextra->fileName,yyextra->lineNr,
2813 "missing argument after '\\{}'.",yyextra->currentCmd
2814 );
2815 }
2816 else
2817 {
2819 yyextra->langParser->parsePrototype(yyextra->functionProto);
2820 }
2822 BEGIN( Comment );
2823 }
2824 }
2825<FnParam>{LC} { // line continuation
2826 yyextra->lineNr++;
2827 yyextra->functionProto+=' ';
2828 }
2829<FnParam>[^@\\\n()]+ { // non-special characters
2830 yyextra->functionProto+=yytext;
2831 }
2832<FnParam>"(" {
2833 yyextra->functionProto+=yytext;
2834 yyextra->braceCount++;
2835 }
2836<FnParam>")" {
2837 yyextra->functionProto+=yytext;
2838 yyextra->braceCount--;
2839 }
2840<FnParam>. { // add other stuff
2841 yyextra->functionProto+=*yytext;
2842 }
2843
2844
2845
2846
2847
2848<OverloadParam>{DOCNL} { // end of argument
2849 if (*yytext=='\n') yyextra->lineNr++;
2850 if (yyextra->functionProto.stripWhiteSpace().isEmpty())
2851 {
2854 }
2855 else
2856 {
2858 yyextra->langParser->parsePrototype(yyextra->functionProto);
2859 }
2860 BEGIN( Comment );
2861 }
QCString getOverloadDocs()
2862<OverloadParam>{LC} { // line continuation
2863 yyextra->lineNr++;
2864 yyextra->functionProto+=' ';
2865 }
2866<OverloadParam>. { // add other stuff
2867 yyextra->functionProto+=*yytext;
2868 }
2869
2870
2871
2872<InheritParam>({ID}("::"|"."))*{ID} { // found argument
2873 yyextra->current->extends.emplace_back(
2875 );
2876 BEGIN( Comment );
2877 }
2878<InheritParam>{DOCNL} { // missing argument
2879 warn(yyextra->fileName,yyextra->lineNr,
2880 "\\inherit command has no argument"
2881 );
2882 if (*yytext=='\n') yyextra->lineNr++;
2884 BEGIN( Comment );
2885 }
2886<InheritParam>. { // invalid character for anchor label
2887 warn(yyextra->fileName,yyextra->lineNr,
2888 "Invalid or missing name for \\inherit command"
2889 );
2890 BEGIN(Comment);
2891 }
2892
2893
2894
2895<ExtendsParam>({ID}("::"|"."))*{ID} { // found argument
2896 yyextra->current->extends.emplace_back(
2898 );
2899 BEGIN( Comment );
2900 }
2901<ExtendsParam>{DOCNL} { // missing argument
2902 warn(yyextra->fileName,yyextra->lineNr,
2903 "'\\{}' command has no argument",yyextra->currentCmd
2904 );
2905
2906
2908 BEGIN( Comment );
2909 }
2910<ExtendsParam>. { // ignore other stuff
2911 }
2912
2913
2914
2915<SkipLang>{CMD}"~"[a-zA-Z-]* { /* language switch */
2918 {
2919 warn(yyextra->fileName,yyextra->lineNr,
2921 }
2922 else if (langId.isEmpty() ||
2924 {
2925 BEGIN(Comment);
2926 }
2927 }
2928<SkipLang>[^*@\\\n]* { /* any character not a *, @, backslash or new line */
2929 }
2930<SkipLang>{DOCNL} { /* new line in verbatim block */
2931 if (*yytext=='\n') yyextra->lineNr++;
2932 }
2933<SkipLang>. { /* any other character */
2934 }
2935
2936
2937
2938<CiteLabel,CiteLabelSection>{CITEID} { // found argument
2941 if (YY_START == CiteLabel)
2942 {
2943 BEGIN(Comment);
2944 }
2945 else
2946 {
2947 yyextra->sectionTitle+=yytext;
2948 BEGIN(SectionTitle);
2949 }
2950 }
2951<CiteLabel,CiteLabelSection>{DOCNL} { // missing argument
2952 warn(yyextra->fileName,yyextra->lineNr,
2953 "\\cite command has no label"
2954 );
2955
2956
2957 if (YY_START == CiteLabel)
2958 {
2960 BEGIN(Comment);
2961 }
2962 else
2963 {
2964 yyextra->sectionTitle+=yytext;
2966 BEGIN(SectionTitle);
2967 }
2968 }
2969<CiteLabel,CiteLabelSection>. { // invalid character for cite label
2970 warn(yyextra->fileName,yyextra->lineNr,
2971 "Invalid or missing cite label"
2972 );
2973 if (YY_START == CiteLabel)
2974 {
2975 BEGIN(Comment);
2976 }
2977 else
2978 {
2979 yyextra->sectionTitle+=yytext;
2980 BEGIN(SectionTitle);
2981 }
2982 }
2983
2984
2985
2986<CopyDoc><<EOF>> {
2988 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
2989 addOutput(yyscanner,yyextra->copyDocArg);
2991 BEGIN(Comment);
2992 }
2993<CopyDoc>"<"[/]?{TABLEDEL}">" {
2994 if (yyextra->braceCount==0)
2995 {
2997 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
2998 addOutput(yyscanner,yyextra->copyDocArg);
3000 BEGIN(Comment);
3001 }
3002 }
3003<CopyDoc>{DOCNL} {
3004 if (*yytext=='\n') yyextra->lineNr++;
3005 if (yyextra->braceCount==0)
3006 {
3008 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
3009 addOutput(yyscanner,yyextra->copyDocArg);
3011 BEGIN(Comment);
3012 }
3013 }
3014<CopyDoc>{LC} { // line continuation
3015 yyextra->lineNr++;
3016 }
3017<CopyDoc>[^@\\\n()<]+ { // non-special characters
3018 yyextra->copyDocArg+=yytext;
3020 }
3021<CopyDoc>"(" {
3022 yyextra->copyDocArg+=yytext;
3024 yyextra->braceCount++;
3025 }
3026<CopyDoc>")" {
3027 yyextra->copyDocArg+=yytext;
3029 yyextra->braceCount--;
3030 }
3031<CopyDoc>. {
3032 yyextra->copyDocArg+=yytext;
3034 }
3035
3036
3037<*>. { fprintf(stderr,"Lex scanner %s %sdefault rule for state %s: #%s#\n", __FILE__,!yyextra->fileName.isEmpty() ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START),yytext);}
3038<*>\n { fprintf(stderr,"Lex scanner %s %sdefault rule newline for state %s.\n", __FILE__, !yyextra->fileName.isEmpty() ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START));}
3039 */
3040
3041%%