719 {CMD}{CMD}[a-z_A-Z]+{B}* {
721 }
722<Comment>{CMD}{CMD}"~"[a-z_A-Z]* { // escaped command
724 }
725<Comment>{MAILADDR} { // mail address
727 }
728<Comment>"\""[^"\n]*"\"" { // quoted text
730 }
731<Comment>("\\"[a-z_A-Z]+)+"\\" { // directory (or chain of commands!)
733 }
734<Comment>"<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description
736 int spacePos = htmlOpenTag.find(' ');
737 if (spacePos==-1) spacePos=yyleng-1;
738 QCString htmlTagName = htmlOpenTag.
mid(1,spacePos-1);
739
740 yyextra->htmlContextStack.emplace_back(htmlTagName,yyextra->inContext);
742 {
744 }
745
746 REJECT;
747 }
748<Comment>"</"{DETAILEDHTML}">" { // HTML command that ends a brief description
750 QCString htmlTagName = htmlCloseTag.
mid(2,htmlCloseTag.length()-3);
751
752 if (!yyextra->htmlContextStack.empty() &&
753 yyextra->htmlContextStack.back().tagName==htmlTagName)
754 {
756 {
757
759 }
760 yyextra->htmlContextStack.pop_back();
761 }
762 REJECT;
763 }
764<Comment>"<"{DETAILEDHTMLOPT}">" { // HTML <code> command that ends a brief description
765
766 if (yyextra->current->lang==SrcLangExt::CSharp)
767 {
768 yyextra->CScode=true;
771 }
772 else
773 {
774
775 REJECT;
776 }
777 }
778<Comment>"<"{DETAILEDHTMLOPTEND}">" { // HTML command that ends a brief description
779 if (yyextra->CScode)
780 {
782 yyextra->CScode=false;
783 }
784 else
785 {
786 yyextra->CScode=false;
787
788 REJECT;
789 }
790 }
791<Comment>"<"{DETAILEDHTMLOPT}{ATTR}">" { // HTML <code> command that ends a brief description
792
793 if (yyextra->current->lang==SrcLangExt::CSharp)
794 {
796 }
797
798 REJECT;
799 }
800<Comment>"<"{DETAILS}{ATTR}">" { // start of a HTML style details description
801 yyextra->htmlDetailsStack.push_back(0);
802 yyextra->htmlContextStack.emplace_back("details",yyextra->inContext);
804 {
806 }
808 }
809<Comment>"</"{DETAILS}">" { // end of a HTML style details description
810 if (!yyextra->htmlDetailsStack.empty())
811 {
812 yyextra->htmlDetailsStack.pop_back();
813 }
814 if (!yyextra->htmlContextStack.empty() &&
815 yyextra->htmlContextStack.back().tagName=="details")
816 {
818 {
819
821 }
822 yyextra->htmlContextStack.pop_back();
823 }
825 }
826<Comment>"<"{AHTML} { // potential start of HTML anchor, see issue 9200
827 yyextra->htmlAnchorStr = yytext;
828 yyextra->htmlAnchor = false;
829 BEGIN(HtmlA);
830 }
831<HtmlA>{ANCHTML} { // only labels that can be converted to doxygen anchor
832 yyextra->htmlAnchorStr += yytext;
834 int s=tag.find("=");
835 char c=tag[s+1];
837 if (c=='\'' || c=='"')
838 {
839 int e=tag.find(c,s+2);
840 if (e!=-1)
841 {
842 id=tag.mid(s+2,e-s-2);
844 }
845 }
846 else
847 {
848 id=tag.mid(s+1);
850 }
851 if (!id.isEmpty() && !yyextra->htmlAnchor)
852 {
853
857 yyextra->htmlAnchor = true;
858 }
859 }
860<HtmlA>("\""[^\n\"]*"\""|"'"[^\n']*"'") {
861 yyextra->htmlAnchorStr += yytext;
862 }
863<HtmlA>">"|"/>" {
864 if (!yyextra->htmlAnchor)
865 {
866 addOutput(yyscanner,yyextra->htmlAnchorStr);
868 }
869 else
870 {
871 if (yyleng == 1)
872 {
874 }
875 }
876 BEGIN(Comment);
877 }
878<HtmlA>{DOCNL} { // newline
879 yyextra->htmlAnchorStr += yytext;
880 if (*yytext == '\n') yyextra->lineNr++;
881 }
882<HtmlA>. { // catch-all for anything else
883 yyextra->htmlAnchorStr += yytext;
884 }
885<Comment>"<"{SUMMARY}">" { // start of a .NET XML style brief description
886 if (yyextra->htmlDetailsStack.empty())
887 {
889 }
890 else
891 {
893 }
894 }
895<Comment>"<"{REMARKS}">" { // start of a .NET XML style detailed description
898 }
899<Comment>"</"{SUMMARY}">" { // start of a .NET XML style detailed description
900 if (!yyextra->htmlDetailsStack.empty())
901 {
903 }
904 else
905 {
907 }
908 }
909<Comment>"</"{REMARKS}">" { // end of a brief or detailed description
912 }
913<Comment>"<"{CAPTION}{ATTR}">" {
915 int s=tag.find("id=");
916 if (s!=-1)
917 {
918 char c=tag[s+3];
919 if (c=='\'' || c=='"')
920 {
921 int e=tag.find(c,s+4);
922 if (e!=-1)
923 {
926 }
927 }
928 }
930 }
931<Comment>"<"{PRE}{ATTR}">" {
932 yyextra->insidePre=
TRUE;
934 }
935<Comment>"</"{PRE}">" {
936 yyextra->insidePre=
FALSE;
938 }
939<Comment>{RCSTAG} { // RCS tag which end a brief description
941 REJECT;
942 }
943<Comment>"<!--" {
944 BEGIN(HtmlComment);
945 }
946<Comment>"<!\[CDATA\[" {
947 BEGIN(CdataSection);
948 }
949<Comment>{B}*{CMD}"endinternal"{B}* {
951 if (!yyextra->inInternalDocs)
952 warn(yyextra->fileName,yyextra->lineNr,
953 "found \\endinternal without matching \\internal"
954 );
955 yyextra->inInternalDocs =
FALSE;
956 }
957<Comment>{B}*"\\ilinebr "{B}* { // preserve spacing around \\ilinebr
959 }
960<Comment>(\n|"\\ilinebr ")/({B}*(\n|{IFILELINE}?"\\ilinebr "))+ { // at least one blank line (or blank line command)
962 {
964 }
965 else
966 {
967 REJECT;
968 }
969 }
970<Comment>{B}*{CMD}[a-z_A-Z]+"{"[^}]*"}"{B}* |
971<Comment>{B}*{CMD}[a-z_A-Z]+{B}* { // potentially interesting command
972
974 int idx = fullMatch.
find(
'{');
975
976 if ((idx > 1) && (yytext[idx-1] == 'f') && (yytext[idx-2] == '\\' || yytext[idx-2] =='@')) REJECT;
977 int idxEnd = fullMatch.
find(
"}",idx+1);
980 if (idx == -1)
981 {
983 }
984 else
985 {
989 }
991
993 {
994 int i=0;
995 while (yytext[i]==' ' || yytext[i]=='\t') i++;
996 yyextra->spaceBeforeCmd = fullMatch.
left(i);
999 !(yyextra->inContext==
OutputXRef && cmdName==
"parblock"))
1000 {
1001 yyextra->briefEndsAtDot=
FALSE;
1003
1005 }
1006
1007 if (it->second.handler && it->second.handler(yyscanner, cmdName, optList))
1008 {
1009
1010
1011
1012 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.
1013
1014 yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);
1016 }
1017 else if (it->second.handler==nullptr)
1018 {
1019
1020
1022 }
1023 }
1024 else
1025 {
1027 }
1028 }
1029<Comment>{B}*({CMD}{CMD})"f"[$\[{] { // escaped formula command
1031 }
1032<Comment>{B}*{CMD}"~"[a-z_A-Z-]* { // language switch command
1036 {
1038 {
1039 warn(yyextra->fileName,yyextra->lineNr,
1041 }
1042 BEGIN(SkipLang);
1043 }
1044 }
#define Config_getEnumAsString(name)
#define Config_isAvailableEnum(name, value)
int qstricmp(const char *s1, const char *s2)
1045<Comment>{B}*{CMD}"f{"[^}\n]+"}"("{"?) { // start of a formula with custom environment
1047 yyextra->formulaText="";
1048 yyextra->formulaPreText="\\begin";
1049 yyextra->formulaPostText="";
1051 if (yyextra->formulaEnv.at(yyextra->formulaEnv.length()-1)=='{')
1052 {
1053
1054 yyextra->formulaEnv=yyextra->formulaEnv.left(yyextra->formulaEnv.length()-1);
1055 }
1056 yyextra->formulaPreText+=yyextra->formulaEnv;
1057 yyextra->formulaNewLines=0;
1058 BEGIN(ReadFormulaLong);
1059 }
1060<Comment>{B}*{CMD}"f$" { // start of a inline formula
1061 yyextra->formulaText="";
1062 yyextra->formulaPreText="$";
1063 yyextra->formulaPostText="";
1064 yyextra->formulaNewLines=0;
1065 BEGIN(ReadFormulaShort);
1066 }
1067<Comment>{B}*{CMD}"f(" { // start of a inline formula
1068 yyextra->formulaText="";
1069 yyextra->formulaPreText="";
1070 yyextra->formulaPostText="";
1071 yyextra->formulaNewLines=0;
1072 BEGIN(ReadFormulaRound);
1073 }
1074<Comment>{B}*{CMD}"f[" { // start of a block formula
1076 yyextra->formulaText="";
1077 yyextra->formulaPreText="\\[";
1078 yyextra->formulaPostText="";
1079 yyextra->formulaNewLines=0;
1080 BEGIN(ReadFormulaLong);
1081 }
1082<Comment>{B}*{CMD}"{" { // begin of a group
1083
1084 yyextra->docGroup.open(yyextra->current,yyextra->fileName,yyextra->lineNr);
1085 }
1086<Comment>{B}*{CMD}"}" { // end of a group
1087
1088 yyextra->docGroup.close(yyextra->current,yyextra->fileName,yyextra->lineNr,
TRUE);
1089 yyextra->docGroup.clearHeader();
1090 yyextra->parseMore=
TRUE;
1091 yyextra->needNewEntry =
TRUE;
1092 yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + (int)strlen(yytext);
1094 }
1095<Comment>{B}*{CMD}[$@\\&~<>#%] { // escaped character
1097 }
1098<Comment>[a-z_A-Z]+ { // normal word
1100 }
1101<Comment>^{B}*"."{Bopt}/\n { // explicit end autolist: e.g " ."
1103 }
1104<Comment>^{B}*[1-9][0-9]*"."{B}+ |
1105<Comment>^{B}*[*+]{B}+ { // start of autolist
1106 if (!yyextra->markdownSupport)
1107 {
1108 REJECT;
1109 }
1110 else
1111 {
1113 {
1114 yyextra->briefEndsAtDot=
FALSE;
1116 }
1118 }
1119 }
1120<Comment>^{B}*"-"{B}+ { // start of autolist
1122 {
1123 yyextra->briefEndsAtDot=
FALSE;
1125 }
1127 }
1128<Comment>^{B}*([\-:|]{B}*)*("--"|"---")({B}*[\-:|])*{Bopt}/\n { // horizontal line (dashed)
1130 }
1131<Comment>{CMD}"---" { // escaped mdash
1133 }
1134<Comment>{CMD}"--" { // escaped mdash
1136 }
1137<Comment>"---" { // mdash
1138 addOutput(yyscanner,yyextra->insidePre || yyextra->markdownSupport ? yytext :
"—");
1139 }
1140<Comment>"--" { // ndash
1141 addOutput(yyscanner,yyextra->insidePre || yyextra->markdownSupport ? yytext :
"–");
1142 }
1143<Comment>"-#"{B}+ { // numbered item
1145 {
1146 yyextra->briefEndsAtDot=
FALSE;
1148 }
1150 }
1151<Comment>[?!][a-z_A-Z0-9\(\)=<] |
1152<Comment>("."+)[a-z_A-Z0-9\)] { // . at start or in the middle of a word, or ellipsis
1153
1155 }
1156<Comment>{CMD}[\.?!] { // we have to be a bit careful with the special commands
1157
1159 }
1160<Comment>".\\"[ \t] { // . with escaped space.
1163 }
1164<Comment>"."[,:;] { // . with some puntuations such as "e.g.," or "e.g.:"
1166 }
1167<Comment>"...\\"[ \t] { // ellipsis with escaped space.
1169 }
1170<Comment>"..."/[^\.] { // ellipsis
1172 }
1173<Comment>".."[\.]?/[^ \t\n] { // internal ellipsis
1175 }
1176<Comment>(\n|"\\ilinebr ")({B}*(\n|"\\ilinebr "))+ { // at least one blank line (or blank line command)
1178 {
1179
1181 yy_size_t i;
1182 for (i=0;i<(yy_size_t)yyleng;)
1183 {
1184 if (yytext[i]==
'\n')
addOutput(yyscanner,
'\n'),i++;
1185 else if (strncmp(yytext+i,
"\\ilinebr ",9)==0)
addOutput(yyscanner,
"\\ilinebr "),i+=9;
1186 else i++;
1187 }
1188 }
1190 {
1191 yy_size_t i;
1192 for (i=0;i<(yy_size_t)yyleng;)
1193 {
1194 if (yytext[i]==
'\n')
addOutput(yyscanner,
'\n'),i++;
1195 else if (strncmp(yytext+i,
"\\ilinebr ",9)==0)
addOutput(yyscanner,
"\\ilinebr "),i+=9;
1196 else i++;
1197 }
1199 }
1200 else
1201 {
1202
1204 }
1206 }
1207<Comment>"."[?!] |
1208<Comment>[\.?!] { // potential end of a JavaDoc style comment
1210 if (yyextra->briefEndsAtDot)
1211 {
1213 yyextra->briefEndsAtDot=
FALSE;
1214 }
1215 }
1216<Comment>{DOCNL} { // newline
1218 if (*yytext == '\n') yyextra->lineNr++;
1219 }
1220<Comment>"<"[/]?{TABLEDEL}">" { // In case in xrefitem type some special handling is required
1222 {
1225 }
1226 else
1227 {
1228 REJECT;
1229 }
1230 }
1231<Comment>. { // catch-all for anything else
1233 }
1234
1235
1236
1237
1238<HtmlComment>"---"[!]?">"{B}* {
1239 warn(yyextra->fileName,yyextra->lineNr,
1240 "incorrect HTML end comment --->"
1241 );
1242 }
1243<HtmlComment>"--"[!]?">"{B}* { BEGIN( Comment ); }
1244<HtmlComment>{DOCNL} {
1245 if (*yytext=='\n')
1246 {
1247 yyextra->lineNr++;
1249 }
1250 }
1251<HtmlComment>[^\\\n\-]+ { // ignore unimportant characters
1252 }
1253<HtmlComment>. { // ignore every else
1254 }
1255
1256<CdataSection>"\]\]>" {
1257 BEGIN( Comment );
1258 }
1259<CdataSection>{DOCNL} {
1261 if (*yytext=='\n') yyextra->lineNr++;
1262 }
1263<CdataSection>[<>&] { // the special XML characters for iwhich the CDATA section is especially used
1266 }
1267<CdataSection>[^\\\n\]<>&]+ {
1269 }
1270<CdataSection>. {
1272 }
1273
1274
1275
1276<ReadFormulaShort,ReadFormulaShortSection>{CMD}"f$" { // end of inline formula
1277 yyextra->formulaPostText+="$";
1280 if (YY_START == ReadFormulaShort)
1281 {
1282 BEGIN(Comment);
1283 }
1284 else
1285 {
1286 yyextra->sectionTitle+= " "+form;
1287 BEGIN(SectionTitle);
1288 }
1289 }
1290<ReadFormulaRound,ReadFormulaRoundSection>{CMD}"f)" { // end of inline formula
1293 if (YY_START == ReadFormulaRound)
1294 {
1295 BEGIN(Comment);
1296 }
1297 else
1298 {
1299 yyextra->sectionTitle+= " "+form;
1300 BEGIN(SectionTitle);
1301 }
1302 }
1303<ReadFormulaLong>{CMD}"f]" { // end of block formula
1304 yyextra->formulaPostText+="\\]";
1306 BEGIN(Comment);
1307 }
1308<ReadFormulaLong>{CMD}"f}" { // end of custom env formula
1309 yyextra->formulaPostText+="\\end";
1310 yyextra->formulaPostText+=yyextra->formulaEnv;
1312 BEGIN(Comment);
1313 }
1314<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>[^\\@\n]+ { // any non-special character
1315 yyextra->formulaText+=yytext;
1316 }
1317<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>\n { // new line
1318 yyextra->formulaNewLines++;
1319 yyextra->formulaText+=*yytext;
1320 yyextra->lineNr++;
1321 addIline(yyscanner,yyextra->lineNr);
1322 }
1323<ReadFormulaLong,ReadFormulaShort,ReadFormulaShortSection,ReadFormulaRound,ReadFormulaRoundSection>. { // any other character
1324 yyextra->formulaText+=*yytext;
1325 }
1326
1327
1328
1329<EnumDocArg1>{SCOPEID} { // handle argument
1331 yyextra->current->name = yytext;
1332 BEGIN( Comment );
1333 }
1334<EnumDocArg1>{LC} { // line continuation
1335 yyextra->lineNr++;
1337 }
1338<EnumDocArg1>{DOCNL} { // missing argument
1339 warn(yyextra->fileName,yyextra->lineNr,
1340 "missing argument after '\\enum'."
1341 );
1343 BEGIN( Comment );
1344 }
1345<EnumDocArg1>. { // ignore other stuff
1346 }
1347
1348
1349
1350<NameSpaceDocArg1>{SCOPENAME} { // handle argument
1354 BEGIN( Comment );
1355 }
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)
1356<NameSpaceDocArg1>{LC} { // line continuation
1357 yyextra->lineNr++;
1359 }
1360<NameSpaceDocArg1>{DOCNL} { // missing argument
1361 warn(yyextra->fileName,yyextra->lineNr,
1362 "missing argument after '\\namespace'."
1363 );
1365 BEGIN( Comment );
1366 }
1367<NameSpaceDocArg1>. { // ignore other stuff
1368 }
1369
1370
1371
1372<PackageDocArg1>{ID}("."{ID})* { // handle argument
1373 yyextra->current->name = yytext;
1374 BEGIN( Comment );
1375 }
1376<PackageDocArg1>{LC} { // line continuation
1377 yyextra->lineNr++;
1379 }
1380<PackageDocArg1>{DOCNL} { // missing argument
1381 warn(yyextra->fileName,yyextra->lineNr,
1382 "missing argument after \\package."
1383 );
1385
1386
1387 BEGIN( Comment );
1388 }
1389<PackageDocArg1>. { // ignore other stuff
1390 }
1391
1392
1393
1394<ConceptDocArg1>{SCOPEID} { // handle argument
1396 yyextra->current->name = yytext;
1397 BEGIN( Comment );
1398 }
1399<ConceptDocArg1>{LC} { // line continuation
1400 yyextra->lineNr++;
1402 }
1403<ConceptDocArg1>{DOCNL} { // missing argument
1404 warn(yyextra->fileName,yyextra->lineNr,
1405 "missing argument after '\\concept'."
1406 );
1408 BEGIN( Comment );
1409 }
1410<ConceptDocArg1>. { // ignore other stuff
1411 }
1412
1413
1414<ModuleDocArg1>{MODULE_ID} { // handle argument
1416 yyextra->current->name = yytext;
1417 BEGIN( Comment );
1418 }
1419<ModuleDocArg1>{LC} { // line continuation
1420 yyextra->lineNr++;
1422 }
1423<ModuleDocArg1>{DOCNL} { // missing argument
1424 warn(yyextra->fileName,yyextra->lineNr,
1425 "missing argument after '\\module'."
1426 );
1428 BEGIN( Comment );
1429 }
1430<ModuleDocArg1>. { // ignore other stuff
1431 }
1432
1433
1434
1435<ClassDocArg1>{SCOPENAME}{TMPLSPEC} {
1439 BEGIN( ClassDocArg2 );
1440 }
1441<ClassDocArg1>{SCOPENAME} { // first argument
1444 yyextra->current->name =
substitute(yytext,
".",
"::");
1445 if (yyextra->current->section.isProtocolDoc())
1446 {
1447 yyextra->current->name+="-p";
1448 }
1449
1450 BEGIN( ClassDocArg2 );
1451 }
1452<CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" {
1455 yyextra->current->name =
substitute(yytext,
".",
"::");
1456 BEGIN( ClassDocArg2 );
1457 }
1458<ClassDocArg1,CategoryDocArg1>{LC} { // line continuation
1459 yyextra->lineNr++;
1461 }
1462<ClassDocArg1,CategoryDocArg1>{DOCNL} {
1463 warn(yyextra->fileName,yyextra->lineNr,
1464 "missing argument after '\\{}'.",yyextra->currentCmd
1465 );
1467 BEGIN( Comment );
1468 }
1469<ClassDocArg1,CategoryDocArg1>. { // ignore other stuff
1470 }
1471
1472<ClassDocArg2>{DOCNL} {
1474 BEGIN( Comment );
1475 }
1476<ClassDocArg2>{FILE}|"<>" { // second argument; include file
1477 yyextra->current->includeFile = yytext;
1478 BEGIN( ClassDocArg3 );
1479 }
1480<ClassDocArg2>{LC} { // line continuation
1481 yyextra->lineNr++;
1483 }
1484<ClassDocArg2>. { // ignore other stuff
1485 }
1486
1487<ClassDocArg3>[<"]?{FILE}?[">]? { // third argument; include file name
1488 yyextra->current->includeName = yytext;
1489 BEGIN( Comment );
1490 }
1491<ClassDocArg3>{LC} { // line continuation
1492 yyextra->lineNr++;
1494 }
1495<ClassDocArg3>{DOCNL} {
1496
1498 BEGIN( Comment );
1499 }
1500<ClassDocArg3>. { // ignore other stuff
1501 }
1502
1503
1504
1505<GroupDocArg1>{LABELID}(".html"|".xhtml")? { // group name
1506 yyextra->current->name = yytext;
1507
1508
1509
1510 if (yyextra->current->name.endsWith(".html"))
1511 {
1512 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-5);
1513 }
1514 else if (yyextra->current->name.endsWith(".xhtml"))
1515 {
1516 yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-6);
1517 }
1518 yyextra->current->type.clear();
1519 BEGIN(GroupDocArg2);
1520 }
1521<GroupDocArg1>"\\"{B}*"\n" { // line continuation
1522 yyextra->lineNr++;
1524 }
1525<GroupDocArg1>{DOCNL} { // missing argument!
1526 warn(yyextra->fileName,yyextra->lineNr,
1527 "missing group name after {}",
1528 yyextra->current->groupDocCmd()
1529 );
1530
1531
1533 BEGIN( Comment );
1534 }
1535<GroupDocArg1>. { // ignore other stuff
1536 }
1537<GroupDocArg2>"\\"{B}*"\n" { // line continuation
1538 yyextra->lineNr++;
1540 }
1541<GroupDocArg2>[^\n\\]+ { // title (stored in type)
1542 yyextra->current->type += yytext;
1543 }
1544<GroupDocArg2>{DOCNL}+ {
1545 yyextra->current->type = yyextra->current->type.stripWhiteSpace();
1547 yyextra->current->type.isEmpty()
1548 )
1549 {
1550 warn(yyextra->fileName,yyextra->lineNr,
1551 "missing title after "
1552 "\\defgroup {}", yyextra->current->name
1553 );
1554 }
1556 int extraLineNr = 0;
1558 {
1559 for (int i = 0; i < yyleng; i++)
1560 {
1561 if (yytext[i]=='\n') extraLineNr++;
1562 }
1563 }
1564
1565
1567 {
1568 addOutput(yyscanner,
" \\ifile \""+ yyextra->fileName);
1569 addOutput(yyscanner,
"\" \\iline " +
QCString().setNum(yyextra->lineNr + extraLineNr) +
" \\ilinebr ");
1570 }
1571 BEGIN( Comment );
1572 }
1573<GroupDocArg2>. { // title (stored in type)
1574 yyextra->current->type += yytext;
1575 }
1576
1577
1578
1579<PageDocArg1>[^\n]*"\\ilinebr @ianchor"\{[^\]\n]*\}{B}{FILE} { // special case where the Markdown processor has rewritten
1580
1581
1583 int start = text.
find(
'{');
1584 int end = text.
find(
'}',start+1);
1585 yyextra->current->name = text.
mid(
end+2);
1586 int istart = yyextra->current->name.
find(
"\\ilinebr");
1587 if (istart != -1)
1588 {
1589 QCString rest = yyextra->current->name.
mid(istart);
1591 yyextra->current->name = yyextra->current->name.mid(0,istart);
1592 }
1593 yyextra->current->args = text.
mid(start+1,
end-start-1);
1594
1595 BEGIN( PageDocArg2 );
1596 }
DirIterator end(const DirIterator &) noexcept
1597<PageDocArg1>{FILE} { // first argument; page name
1599 yyextra->current->args = "";
1600 BEGIN( PageDocArg2 );
1601 }
1602<PageDocArg1>{LC} { yyextra->lineNr++;
1604 }
1605<PageDocArg1>{DOCNL} {
1606 warn(yyextra->fileName,yyextra->lineNr,
1607 "missing argument after \\page."
1608 );
1610
1611
1612 BEGIN( Comment );
1613 }
1614<PageDocArg1>. { // ignore other stuff
1615 }
1616<PageDocArg2>{DOCNL} { // second argument; page title
1618
1619
1620 addOutput(yyscanner,
" \\ifile \""+ yyextra->fileName);
1621 addOutput(yyscanner,
"\" \\iline " +
QCString().setNum(yyextra->lineNr) +
" \\ilinebr ");
1622 BEGIN( Comment );
1623 }
1624<PageDocArg2>{CMD}[<>] {
1625
1629 yyextra->current->args += tmp;
1630 }
1631<PageDocArg2>. {
1632 yyextra->current->args += yytext;
1633 }
1634
1635<ParamArg1>{ID}/{B}*"," {
1637 }
1638<ParamArg1>"," {
1640 }
1641<ParamArg1>{DOCNL} {
1642 if (*yytext=='\n') yyextra->lineNr++;
1644 }
1645<ParamArg1>{ID} {
1647 BEGIN( Comment );
1648 }
1649<ParamArg1>. {
1650 unput(yytext[0]);
1651 BEGIN( Comment );
1652 }
1653
1654
1655
1656<FileDocArg1>{DOCNL} { // no file name specified
1658
1659
1660 BEGIN( Comment );
1661 }
1662<FileDocArg1>{FILE} { // first argument; name
1664 BEGIN( Comment );
1665 }
1666<FileDocArg1>{LC} { yyextra->lineNr++;
1668 }
1669<FileDocArg1>. { // ignore other stuff
1670 }
1671
1672
1673
1674<XRefItemParam1>{LABELID} { // first argument
1675 yyextra->newXRefItemKey=yytext;
1677 BEGIN(XRefItemParam2);
1678 }
1679<XRefItemParam1>{LC} { // line continuation
1680 yyextra->lineNr++;
1682 }
1683<XRefItemParam1>{DOCNL} { // missing arguments
1684 warn(yyextra->fileName,yyextra->lineNr,
1685 "Missing first argument of \\xrefitem"
1686 );
1687 if (*yytext=='\n') yyextra->lineNr++;
1690 BEGIN( Comment );
1691 }
1692<XRefItemParam1>. { // ignore other stuff
1693 }
1694
1695<XRefItemParam2>"\""[^\n\"]*"\"" { // second argument
1697 BEGIN(XRefItemParam3);
1698 }
1699<XRefItemParam2>{LC} { // line continuation
1700 yyextra->lineNr++;
1702 }
1703<XRefItemParam2>{DOCNL} { // missing argument
1704 warn(yyextra->fileName,yyextra->lineNr,
1705 "Missing second argument of \\xrefitem"
1706 );
1707 if (*yytext=='\n') yyextra->lineNr++;
1710 BEGIN( Comment );
1711 }
1712<XRefItemParam2>. { // ignore other stuff
1713 }
1714
1715<XRefItemParam3>"\""[^\n\"]*"\"" { // third argument
1718 BEGIN( Comment );
1719 }
1720<XRefItemParam2,XRefItemParam3>{LC} { // line continuation
1721 yyextra->lineNr++;
1723 }
1724<XRefItemParam3>{DOCNL} { // missing argument
1725 warn(yyextra->fileName,yyextra->lineNr,
1726 "Missing third argument of \\xrefitem"
1727 );
1728 if (*yytext=='\n') yyextra->lineNr++;
1731 BEGIN( Comment );
1732 }
1733<XRefItemParam3>. { // ignore other stuff
1734 }
1735
1736
1737
1738
1739<RelatesParam1>({ID}("::"|"."))*{ID} { // argument
1740 yyextra->current->relates = yytext;
1741
1742
1743
1744
1745 BEGIN( Comment );
1746 }
1747<RelatesParam1>{LC} { // line continuation
1748 yyextra->lineNr++;
1750 }
1751<RelatesParam1>{DOCNL} { // missing argument
1752 warn(yyextra->fileName,yyextra->lineNr,
1753 "Missing argument of '\\{}' command",yyextra->currentCmd
1754 );
1756
1757
1758 BEGIN( Comment );
1759 }
1760<RelatesParam1>. { // ignore other stuff
1761 }
1762
1763
1764
1765<Qualifier>{LABELID} { // unquoted version, simple label
1766 yyextra->current->qualifiers.emplace_back(yytext);
1767 BEGIN( Comment );
1768 }
1769<Qualifier>"\""[^\"]*"\"" { // quotes version, add without quotes
1770 std::string inp(yytext);
1771 yyextra->current->qualifiers.push_back(inp.substr(1,yyleng-2));
1772 BEGIN( Comment );
1773 }
1774<Qualifier>{DOCNL} { // missing argument
1775 warn(yyextra->fileName,yyextra->lineNr,
1776 "Missing argument of '\\{}' command",yyextra->currentCmd
1777 );
1779 BEGIN( Comment );
1780 }
1781<Qualifier>. {
1782 warn(yyextra->fileName,yyextra->lineNr,
1783 "Argument of '\\{}' command should be quoted",yyextra->currentCmd
1784 );
1786 BEGIN( Comment );
1787 }
1788
1789<ILine>{LINENR}/[\\@\n\.] |
1790<ILine>{LINENR}{B} {
1791 bool ok = false;
1793 if (!ok)
1794 {
1795 warn(yyextra->fileName,yyextra->lineNr,
"Invalid line number '{}' for iline command",yytext);
1796 }
1797 else
1798 {
1799 yyextra->lineNr = nr;
1800 }
1802 if (YY_START == ILine)
1803 {
1804 BEGIN(Comment);
1805 }
1806 else
1807 {
1808 yyextra->sectionTitle+=yytext;
1809 BEGIN(SectionTitle);
1810 }
1811 }
int toInt(bool *ok=nullptr, int base=10) const
1812<ILine,ILineSection>. {
1814 if (YY_START == ILine)
1815 {
1816 BEGIN(Comment);
1817 }
1818 else
1819 {
1820 yyextra->sectionTitle+=yytext;
1821 BEGIN(SectionTitle);
1822 }
1823 }
1824
1825
1826<IRaise>{B}*[0-9]+/[\\@\n\.] |
1827<IRaise>{B}*[0-9]+{B} {
1828 bool ok = false;
1830 if (!ok)
1831 {
1832 warn(yyextra->fileName,yyextra->lineNr,
"Invalid level '{}' for iraise command",yytext);
1833 }
1834 else
1835 {
1836 yyextra->raiseLevel = nr;
1837 }
1838 BEGIN(Comment);
1839 }
1840<IRaise>. {
1841 unput(yytext[0]);
1842 BEGIN(Comment);
1843 }
1844
1845
1846<IRaisePrefix>{B}*"\""({LABELID})?"\"" {
1848 yyextra->raisePrefix = text.stripWhiteSpace().mid(1,text.length()-2);
1850 BEGIN(Comment);
1851 }
1852<IRaisePrefix>. {
1853 unput(yytext[0]);
1854 BEGIN(Comment);
1855 }
1856
1857
1858
1859
1860<IFile,IFileSection>{FILE} {
1863 if (yytext[0] == '\"') yyextra->fileName = text.mid(1,text.length()-2);
1864 else yyextra->fileName = yytext;
1865 if (YY_START == IFile)
1866 {
1867 BEGIN(Comment);
1868 }
1869 else
1870 {
1871 yyextra->sectionTitle+=yytext;
1872 BEGIN(SectionTitle);
1873 }
1874 }
1875
1876<LinkSection>[^\\@\n]* {
1877 yyextra->sectionTitle+=yytext;
1878 }
1879<LinkSection>{CMD}{CMD} {
1880 yyextra->sectionTitle+=yytext;
1881 }
1882<LinkSection>{DOCNL} {
1884 if (*yytext == '\n') yyextra->lineNr++;
1885 yyextra->sectionTitle+=yytext;
1886 }
1887<LinkSection>{CMD}"endlink" {
1888 yyextra->sectionTitle+=yytext;
1889 BEGIN(SectionTitle);
1890 }
1891<LinkSection>. {
1892 yyextra->sectionTitle+=yytext;
1893 }
1894<LinkSection><<EOF>> {
1895 warn(yyextra->fileName,yyextra->lineNr,
1896 "reached end of comment while inside a '\\link' command, missing '\\endlink' command"
1897 );
1899 }
1900
1901
1902<LineParam>{CMD}{CMD} { // escaped command
1904 }
1905<LineParam>{DOCNL} { // end of argument
1906
1907
1909 BEGIN( Comment );
1910 }
1911<LineParam>{LC} { // line continuation
1912 yyextra->lineNr++;
1914 }
1915<LineParam>({CMD}{CMD}){ID} { // escaped command
1917 }
1918<LineParam>. { // ignore other stuff
1920 }
1921
1922
1923
1924<SectionLabel>{LABELID} {
1925 yyextra->sectionLabel+=yytext;
1926 }
1927<SectionLabel>{CMD}"lineinfo"("{}")? {
1929 }
1930<SectionLabel>{CMD}"fileinfo"("{"[^}]*"}")? {
1931 FileInfo fi(yyextra->fileName.str());
1932 bool hasOption = false;
1934 if (yytext[yyleng-1] == '}')
1935 {
1940 for (const auto &opt_ : optList)
1941 {
1943 std::string opt = optStripped.
lower().
str();
1946 {
1947 if (hasOption)
1948 {
1949 warn(yyextra->fileName,yyextra->lineNr,
"Multiple options specified with \\fileinfo, discarding '{}'", optStripped);
1950 }
1951 else
1952 {
1953 label = result;
1954 }
1955 hasOption = true;
1956 }
1957 else
1958 {
1959 warn(yyextra->fileName,yyextra->lineNr,
"Unknown option specified with \\fileinfo: '{}'", optStripped);
1960 }
1961 }
1962 }
1963 if (!hasOption)
1964 {
1966 {
1968 }
1969 else
1970 {
1971 label=yyextra->fileName;
1972 }
1973 }
1975 yyextra->sectionLabel+=label;
1976 }
1977<SectionLabel>{DOCNL} {
1978 yyextra->sectionTitle.clear();
1979 if (yyextra->sectionLabel.isEmpty())
1980 {
1981 warn(yyextra->fileName,yyextra->lineNr,
1982 "\\section command has no label"
1983 );
1984 }
1985 else
1986 {
1987 yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
1988 addOutput(yyscanner,yyextra->sectionLabel.data());
1990 }
1991 if (*yytext=='\n') yyextra->lineNr++;
1993 BEGIN( Comment );
1994 }
1995<SectionLabel>. { // invalid character for section label
1996 if (yyextra->sectionLabel.isEmpty())
1997 {
1998 warn(yyextra->fileName,yyextra->lineNr,
1999 "Invalid or missing section label"
2000 );
2001 BEGIN(Comment);
2002 }
2003 else
2004 {
2005 yyextra->sectionLabel=yyextra->raisePrefix+yyextra->sectionLabel;
2006 addOutput(yyscanner,yyextra->sectionLabel.data());
2007 yyextra->sectionTitle.clear();
2009 BEGIN(SectionTitle);
2010 }
2011 }
2012<SectionTitle>{STAopt}/"\n" { // end of section title
2015 BEGIN( Comment );
2016 }
2017<SectionTitle>{STopt}"\\\\ilinebr" { // escaped end of section title
2018 yyextra->sectionTitle+=yytext;
2019 }
2020<SectionTitle>{STopt}/"\\ilinebr" { // end of section title
2023 BEGIN( Comment );
2024 }
2025<SectionTitle>{B}*{CMD}"f$" {
2026 yyextra->formulaText="";
2027 yyextra->formulaPreText="$";
2028 yyextra->formulaPostText="";
2029 yyextra->formulaNewLines=0;
2030 BEGIN(ReadFormulaShortSection);
2031 }
2032<SectionTitle>{B}*{CMD}"f(" { // start of a inline formula
2033 yyextra->formulaText="";
2034 yyextra->formulaPreText="";
2035 yyextra->formulaPostText="";
2036 yyextra->formulaNewLines=0;
2037 BEGIN(ReadFormulaRoundSection);
2038 }
2039<SectionTitle>{B}*{CMD}"~"[a-z_A-Z-]* | // language switch command
2040<SectionTitle>{B}*{CMD}"f"[\[{] { // block formula
2044 warn(yyextra->fileName,yyextra->lineNr,
2045 "'\\{}' command is not allowed in section title, ending section title.",
2047 );
2049 BEGIN(Comment);
2050 }
2051<SectionTitle>{LC} { // line continuation
2052 yyextra->lineNr++;
2054 }
2055<SectionTitle>[^\n@\\]* { // any character without special meaning
2056 yyextra->sectionTitle+=yytext;
2058 }
2059<SectionTitle>{B}*{CMD}{CMD} {
2060 yyextra->sectionTitle+=yytext;
2062 }
2063<SectionTitle>{B}*{CMD}[a-z_A-Z]+"{"[^}]*"}"{B}* |
2064<SectionTitle>{B}*{CMD}[a-z_A-Z]+{B}* { // handling command in section title
2066 int idx = fullMatch.
find(
'{');
2067
2068 if ((idx > 1) && (yytext[idx-1] == 'f') && (yytext[idx-2] == '\\' || yytext[idx-2] =='@')) REJECT;
2069 int idxEnd = fullMatch.
find(
"}",idx+1);
2072 if (idx == -1)
2073 {
2075 }
2076 else
2077 {
2081 }
2084 {
2085 switch (it->second.sectionHandling)
2086 {
2088 {
2089 int i=0;
2090 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2091 yyextra->sectionTitle+=fullMatch.
left(i);
2092 yyextra->sectionTitle+='@';
2093 yyextra->sectionTitle+=fullMatch.
mid(i);
2097 warn(yyextra->fileName,yyextra->lineNr,
2098 "'\\{}' command is not allowed in section title, escaping command.",cmdName
2099 );
2100 }
2101 break;
2103 {
2106 warn(yyextra->fileName,yyextra->lineNr,
2107 "'\\{}' command is not allowed in section title, ending section title.",cmdName
2108 );
2110 BEGIN(Comment);
2111 }
2112 break;
2114 {
2115 if (cmdName == "fileinfo")
2116 {
2117 int i=0;
2118 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2119 yyextra->sectionTitle+=fullMatch.
left(i);
2122 if (idxEnd == -1)
2123 {
2124 yyextra->sectionTitle+=fullMatch.
mid(i+9);
2126 }
2127 else
2128 {
2129 yyextra->sectionTitle+=fullMatch.
mid(idxEnd+1);
2131 }
2132 }
2133 else if (cmdName == "lineinfo")
2134 {
2135 int i=0;
2136 while (yytext[i]==' ' || yytext[i]=='\t') i++;
2137 yyextra->sectionTitle+=fullMatch.
left(i);
2139 yyextra->sectionTitle+=' ';
2140 yyextra->sectionTitle+=fullMatch.
mid(i+9);
2145 }
2146 else if (cmdName == "raisewarning")
2147 {
2148 yyextra->raiseWarning = "";
2149 BEGIN(RaiseWarningSection);
2150 }
2151 else if (cmdName == "noop")
2152 {
2154 BEGIN(Noop);
2155 }
2156 else if (cmdName == "cite")
2157 {
2158 yyextra->sectionTitle+=yytext;
2160 BEGIN(CiteLabelSection);
2161 }
2162 else if (cmdName == "iline")
2163 {
2164 yyextra->sectionTitle+=yytext;
2166 BEGIN(ILineSection);
2167 }
2168 else if (cmdName == "ifile")
2169 {
2170 yyextra->sectionTitle+=yytext;
2172 BEGIN(IFileSection);
2173 }
2174 else if ((cmdName == "anchor") || (cmdName == "ianchor"))
2175 {
2177 if (optList.empty())
2178 {
2179 yyextra -> anchorTitle = "";
2180 }
2181 else
2182 {
2184 yyextra -> anchorTitle =
join(optList,
" ");
2185 }
2187 BEGIN(AnchorLabelSection);
2188 }
2189 else if (cmdName == "link")
2190 {
2191 yyextra->sectionTitle+=yytext;
2192 BEGIN(LinkSection);
2193 }
2194 else
2195 {
2196 yyextra->sectionTitle+=yytext;
2197 warn(yyextra->fileName,yyextra->lineNr,
2198 "internal error '\\{}' command is to be replaced in section title.",cmdName
2199 );
2200 }
2201 }
2202 break;
2204 {
2205 yyextra->sectionTitle+=yytext;
2207 }
2208 break;
2209 }
2210 }
2211 else
2212 {
2213 yyextra->sectionTitle+=yytext;
2215 }
2216 }
2217<SectionTitle>. { // anything else
2218 yyextra->sectionTitle+=yytext;
2220 }
2221
2222
2223
2224<SubpageLabel>{FILE} { // first argument
2226
2227
2228 yyextra->current->extends.emplace_back(yytext,Protection::Public,Specifier::Normal);
2229 BEGIN(SubpageTitle);
2230 }
2231<SubpageLabel>{DOCNL} { // missing argument
2232 warn(yyextra->fileName,yyextra->lineNr,
2233 "\\subpage command has no label"
2234 );
2235 if (*yytext=='\n') yyextra->lineNr++;
2237 BEGIN( Comment );
2238 }
2239<SubpageLabel>. {
2240 unput(yytext[0]);
2241 BEGIN( Comment );
2242 }
2243<SubpageTitle>{DOCNL} { // no title, end command
2245 BEGIN( Comment );
2246 }
2247<SubpageTitle>[ \t]*"\""[^\"\n]*"\"" { // add title, end of command
2249 BEGIN( Comment );
2250 }
2251<SubpageTitle>. { // no title, end of command
2252 unput(*yytext);
2253 BEGIN( Comment );
2254 }
2255
2256
2257
2258<AnchorLabel,AnchorLabelSection>{LABELID} { // found argument
2259 QCString lbl = yyextra->raisePrefix+yytext;
2260 addAnchor(yyscanner,lbl, yyextra->anchorTitle);
2262 if (YY_START == AnchorLabel)
2263 {
2264 BEGIN(Comment);
2265 }
2266 else
2267 {
2268 BEGIN(SectionTitle);
2269 }
2270 }
2271<AnchorLabel,AnchorLabelSection>{DOCNL} { // missing argument
2272 warn(yyextra->fileName,yyextra->lineNr,
2273 "\\anchor command has no label"
2274 );
2275 if (*yytext=='\n') yyextra->lineNr++;
2277 if (YY_START == AnchorLabel)
2278 {
2279 BEGIN(Comment);
2280 }
2281 else
2282 {
2283 BEGIN(SectionTitle);
2284 }
2285 }
2286<AnchorLabel,AnchorLabelSection>. { // invalid character for anchor label
2287 warn(yyextra->fileName,yyextra->lineNr,
2288 "Invalid or missing anchor label"
2289 );
2291 if (YY_START == AnchorLabel)
2292 {
2293 BEGIN(Comment);
2294 }
2295 else
2296 {
2297 BEGIN(SectionTitle);
2298 }
2299 }
2300
2301
2302
2303
2304<FormatBlock>{CMD}("endverbatim"|"endiverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode"|"endicode"|"endmsc")/{NW} { // possible ends
2306 if (&yytext[4]==yyextra->blockName)
2307 {
2308 BEGIN(Comment);
2309 }
2310 }
2311<FormatBlock>{CMD}"enduml" {
2313 if (yyextra->blockName=="startuml")
2314 {
2315 BEGIN(Comment);
2316 }
2317 }
2318<FormatBlock>[^ \@\*\/\\\n]* { // some word
2320 }
2321<FormatBlock>{DOCNL} { // new line
2322 if (*yytext=='\n') yyextra->lineNr++;
2324 }
2325<FormatBlock>{CCS} { // start of a C-comment
2326 if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim" ||
2327 yyextra->blockName=="icode" || yyextra->blockName=="iverbatim"||
2328 yyextra->blockName=="iliteral"
2329 )
2330 ) yyextra->commentCount++;
2332 }
2333<FormatBlock>{CCE} { // end of a C-comment
2335 if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim" ||
2336 yyextra->blockName=="icode" || yyextra->blockName=="iverbatim"||
2337 yyextra->blockName=="iliteral"
2338 )
2339 )
2340 {
2341 yyextra->commentCount--;
2342 if (yyextra->commentCount<0)
2343 {
2344 QCString endTag =
"end"+yyextra->blockName;
2345 if (yyextra->blockName=="startuml") endTag="enduml";
2346 warn(yyextra->fileName,yyextra->lineNr,
2347 "found */ without matching /* while inside a \\{} block! Perhaps a missing \\{}?",
2348 yyextra->blockName,endTag);
2349 }
2350 }
2351 }
2352<FormatBlock>. {
2354 }
2355<FormatBlock><<EOF>> {
2356 QCString endTag =
"end"+yyextra->blockName;
2357 if (yyextra->blockName=="startuml") endTag="enduml";
2358 warn(yyextra->fileName,yyextra->lineNr,
2359 "reached end of comment while inside a \\{} block; check for missing \\{} tag!",
2360 yyextra->blockName,endTag
2361 );
2363 }
2364
2365
2366
2367<GuardParam>{B}*"(" {
2368 yyextra->guardExpr=yytext;
2369 yyextra->roundCount=1;
2370 BEGIN(GuardExpr);
2371 }
2372<GuardExpr>[^()]* {
2373 yyextra->guardExpr+=yytext;
2375 }
2376<GuardExpr>"(" {
2377 yyextra->guardExpr+=yytext;
2378 yyextra->roundCount++;
2379 }
2380<GuardExpr>")" {
2381 yyextra->guardExpr+=yytext;
2382 yyextra->roundCount--;
2383 if (yyextra->roundCount==0)
2384 {
2386 }
2387 }
2388<GuardExpr>\n {
2389 warn(yyextra->fileName,yyextra->lineNr,
2390 "invalid expression '{}' for yyextra->guards",yyextra->guardExpr);
2391 unput(*yytext);
2392 BEGIN(GuardParam);
2393 }
2394<GuardParam>{B}*[a-z_A-Z0-9.\-]+ { // parameter of if/ifnot yyextra->guards
2396 }
2397<GuardParam>{DOCNL} { // end of argument
2398
2399
2403 }
2404<GuardParam>{LC} { // line continuation
2405 yyextra->lineNr++;
2407 }
2408<GuardParam>. { // empty condition
2409 unput(*yytext);
2411 }
2412<GuardParamEnd>{B}*{DOCNL} {
2414 yyextra->spaceBeforeIf.clear();
2416 BEGIN(Comment);
2417 }
2418<GuardParamEnd>{B}* {
2419 if (!yyextra->spaceBeforeIf.isEmpty())
2420 {
2421 addOutput(yyscanner,yyextra->spaceBeforeIf);
2422 }
2423 yyextra->spaceBeforeIf.clear();
2425 BEGIN(Comment);
2426 }
2427<GuardParamEnd>. {
2428 unput(*yytext);
2430 BEGIN(Comment);
2431 }
2432
2433
2434
2435<SkipGuardedSection>{CMD}"ifnot"/{NW} {
2437 yyextra->guards->emplace(false);
2438 BEGIN( GuardParam );
2439 }
2440<SkipGuardedSection>{CMD}"if"/{NW} {
2442 yyextra->guards->emplace(false);
2443 BEGIN( GuardParam );
2444 }
2445<SkipGuardedSection>{CMD}"endif"/{NW} {
2446 if (yyextra->guards->empty())
2447 {
2448 warn(yyextra->fileName,yyextra->lineNr,
2449 "found \\endif without matching start command");
2450 BEGIN( Comment );
2451 }
2452 else
2453 {
2454 yyextra->guards->pop();
2455 if (yyextra->guards->empty())
2456 {
2457 BEGIN( GuardParamEnd );
2458 }
2459 else
2460 {
2461 if (yyextra->guards->top().isEnabled())
2462 {
2463 BEGIN( GuardParamEnd );
2464 }
2465 else
2466 {
2467 BEGIN( SkipGuardedSection );
2468 }
2469 }
2470 }
2471 }
2472<SkipGuardedSection>{CMD}"else"/{NW} {
2473 if (yyextra->guards->empty())
2474 {
2475 warn(yyextra->fileName,yyextra->lineNr,
2476 "found \\else without matching start command");
2477 }
2478 else if (yyextra->guards->top().hasElse())
2479 {
2480 warn(yyextra->fileName,yyextra->lineNr,
2481 "found multiple \\else commands in same \\if construct");
2482 yyextra->guards->top().setEnabled(false);
2483 BEGIN( SkipGuardedSection );
2484 }
2485 else if (!yyextra->guards->top().parentVisible())
2486 {
2487 yyextra->guards->top().setEnabled(false);
2488 BEGIN( SkipGuardedSection );
2489 }
2490 else
2491 {
2492 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2493 yyextra->guards->top().setElse();
2494 if (!yyextra->guards->top().parentVisible())
2495 {
2496 yyextra->guards->top().setEnabled(false);
2497 BEGIN( SkipGuardedSection );
2498 }
2499 else if (yyextra->guards->top().isEnabledFound())
2500 {
2501 yyextra->guards->top().setEnabled(false);
2502 BEGIN( SkipGuardedSection );
2503 }
2504 else
2505 {
2506 yyextra->guards->top().setEnabled(true);
2507 BEGIN( GuardParamEnd );
2508 }
2509 }
2510 }
2511<SkipGuardedSection>{CMD}"elseif"/{NW} {
2512 if (yyextra->guards->empty())
2513 {
2514 warn(yyextra->fileName,yyextra->lineNr,
2515 "found \\elseif without matching start command");
2516 }
2517 else if (yyextra->guards->top().hasElse())
2518 {
2519 warn(yyextra->fileName,yyextra->lineNr,
2520 "found \\elseif command after \\else command was given in \\if construct");
2522 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2523 yyextra->guards->top().setEnabled(false);
2524 BEGIN( GuardParam );
2525 }
2526 else
2527 {
2529 yyextra->spaceBeforeIf = yyextra->spaceBeforeCmd;
2530 yyextra->guards->top().setEnabled(false);
2531 BEGIN( GuardParam );
2532 }
2533 }
2534<SkipGuardedSection>{DOCNL} { // skip line
2535 if (*yytext=='\n') yyextra->lineNr++;
2536
2537 }
2538<SkipGuardedSection>[^ \\@\n]+ { // skip non-special characters
2539 }
2540<SkipGuardedSection>{CMD}{CMD} |
2541<SkipGuardedSection>. { // any other character
2542 }
2543
2544
2545
2546
2547<SkipInternal>{DOCNL} { // skip line
2548 if (*yytext=='\n') yyextra->lineNr++;
2550 }
2551<SkipInternal>{CMD}"if"/[ \t] {
2552 yyextra->condCount++;
2553 }
2554<SkipInternal>{CMD}"ifnot"/[ \t] {
2555 yyextra->condCount++;
2556 }
2557<SkipInternal>{CMD}/"endif" {
2558 yyextra->condCount--;
2559 if (yyextra->condCount<0)
2560 {
2561 unput('\\');
2562 BEGIN(Comment);
2563 }
2564 }
2565<SkipInternal>{CMD}/"section"[ \t] {
2566 if (yyextra->sectionLevel>0)
2567 {
2568 unput('\\');
2569 BEGIN(Comment);
2570 }
2571 }
2572<SkipInternal>{CMD}/"subsection"[ \t] {
2573 if (yyextra->sectionLevel>1)
2574 {
2575 unput('\\');
2576 BEGIN(Comment);
2577 }
2578 }
2579<SkipInternal>{CMD}/"subsubsection"[ \t] {
2580 if (yyextra->sectionLevel>2)
2581 {
2582 unput('\\');
2583 BEGIN(Comment);
2584 }
2585 }
2586<SkipInternal>{CMD}/"paragraph"[ \t] {
2587 if (yyextra->sectionLevel>3)
2588 {
2589 unput('\\');
2590 BEGIN(Comment);
2591 }
2592 }
2593<SkipInternal>{CMD}/"subparagraph"[ \t] {
2594 if (yyextra->sectionLevel>4)
2595 {
2596 unput('\\');
2597 BEGIN(Comment);
2598 }
2599 }
2600<SkipInternal>{CMD}/"subsubparagraph"[ \t] {
2601 if (yyextra->sectionLevel>5)
2602 {
2603 unput('\\');
2604 BEGIN(Comment);
2605 }
2606 }
2607<SkipInternal>{CMD}"endinternal"[ \t]* {
2608 BEGIN(Comment);
2609 }
2610<SkipInternal>[^ \\@\n]+ { // skip non-special characters
2611 }
2612<SkipInternal>. { // any other character
2613 }
2614
2615
2616
2617
2618<NameParam>{DOCNL} { // end of argument
2619
2620
2622 BEGIN( Comment );
2623 }
2624<NameParam>{LC} { // line continuation
2625 yyextra->lineNr++;
2627 yyextra->docGroup.appendHeader(' ');
2628 }
2629<NameParam>. { // ignore other stuff
2630 yyextra->docGroup.appendHeader(*yytext);
2631 yyextra->current->name+=*yytext;
2632 }
2633
2634
2635<Noop>{DOCNL} { // end of argument
2636 if (*yytext=='\n')
2637 {
2638 yyextra->lineNr++;
2640 }
2641 BEGIN( Comment );
2642 }
2643<Noop>. { // ignore other stuff
2644 }
2645
2646<RaiseWarning,RaiseWarningSection>{DOCNL} { // end of argument
2648 "{}",yyextra->raiseWarning);
2649 yyextra->raiseWarning = "";
2650 if (*yytext=='\n') yyextra->lineNr++;
2652 if (YY_START == RaiseWarning)
2653 {
2654 BEGIN(Comment);
2655 }
2656 else
2657 {
2658 yyextra->sectionTitle+=yytext;
2659 BEGIN(SectionTitle);
2660 }
2661 }
#define warn_doc_error(file, line, fmt,...)
2662<RaiseWarning,RaiseWarningSection>. { // ignore other stuff
2663 yyextra->raiseWarning += yytext;
2664 }
2665
2666
2667<InGroupParam>{LABELID} { // group id
2668 yyextra->current->groups.emplace_back(
2670 );
2671 yyextra->inGroupParamFound=
TRUE;
2672 }
@ GROUPING_INGROUP
membership in group was defined by @ingroup
2673<InGroupParam>{DOCNL} { // missing argument
2674 if (!yyextra->inGroupParamFound)
2675 {
2676 warn(yyextra->fileName,yyextra->lineNr,
2677 "Missing group name for \\ingroup command"
2678 );
2679 }
2680
2681
2683 BEGIN( Comment );
2684 }
2685<InGroupParam>{LC} { // line continuation
2686 yyextra->lineNr++;
2688 }
2689<InGroupParam>. { // ignore other stuff
2691 }
2692
2693
2694
2695<FnParam>{DOCNL} { // end of argument
2696 if (yyextra->braceCount==0)
2697 {
2698 if (yyextra->functionProto.stripWhiteSpace().isEmpty())
2699 {
2700 warn(yyextra->fileName,yyextra->lineNr,
2701 "missing argument after '\\{}'.",yyextra->currentCmd
2702 );
2703 }
2704 else
2705 {
2707 yyextra->langParser->parsePrototype(yyextra->functionProto);
2708 }
2710 BEGIN( Comment );
2711 }
2712 }
2713<FnParam>{LC} { // line continuation
2714 yyextra->lineNr++;
2715 yyextra->functionProto+=' ';
2716 }
2717<FnParam>[^@\\\n()]+ { // non-special characters
2718 yyextra->functionProto+=yytext;
2719 }
2720<FnParam>"(" {
2721 yyextra->functionProto+=yytext;
2722 yyextra->braceCount++;
2723 }
2724<FnParam>")" {
2725 yyextra->functionProto+=yytext;
2726 yyextra->braceCount--;
2727 }
2728<FnParam>. { // add other stuff
2729 yyextra->functionProto+=*yytext;
2730 }
2731
2732
2733
2734
2735
2736<OverloadParam>{DOCNL} { // end of argument
2737 if (*yytext=='\n') yyextra->lineNr++;
2738 if (yyextra->functionProto.stripWhiteSpace().isEmpty())
2739 {
2742 }
2743 else
2744 {
2746 yyextra->langParser->parsePrototype(yyextra->functionProto);
2747 }
2748 BEGIN( Comment );
2749 }
QCString getOverloadDocs()
2750<OverloadParam>{LC} { // line continuation
2751 yyextra->lineNr++;
2752 yyextra->functionProto+=' ';
2753 }
2754<OverloadParam>. { // add other stuff
2755 yyextra->functionProto+=*yytext;
2756 }
2757
2758
2759
2760<InheritParam>({ID}("::"|"."))*{ID} { // found argument
2761 yyextra->current->extends.emplace_back(
2763 );
2764 BEGIN( Comment );
2765 }
2766<InheritParam>{DOCNL} { // missing argument
2767 warn(yyextra->fileName,yyextra->lineNr,
2768 "\\inherit command has no argument"
2769 );
2770 if (*yytext=='\n') yyextra->lineNr++;
2772 BEGIN( Comment );
2773 }
2774<InheritParam>. { // invalid character for anchor label
2775 warn(yyextra->fileName,yyextra->lineNr,
2776 "Invalid or missing name for \\inherit command"
2777 );
2778 BEGIN(Comment);
2779 }
2780
2781
2782
2783<ExtendsParam>({ID}("::"|"."))*{ID} { // found argument
2784 yyextra->current->extends.emplace_back(
2786 );
2787 BEGIN( Comment );
2788 }
2789<ExtendsParam>{DOCNL} { // missing argument
2790 warn(yyextra->fileName,yyextra->lineNr,
2791 "'\\{}' command has no argument",yyextra->currentCmd
2792 );
2793
2794
2796 BEGIN( Comment );
2797 }
2798<ExtendsParam>. { // ignore other stuff
2799 }
2800
2801
2802
2803<SkipLang>{CMD}"~"[a-zA-Z-]* { /* language switch */
2806 {
2807 warn(yyextra->fileName,yyextra->lineNr,
2809 }
2810 else if (langId.isEmpty() ||
2812 {
2813 BEGIN(Comment);
2814 }
2815 }
2816<SkipLang>[^*@\\\n]* { /* any character not a *, @, backslash or new line */
2817 }
2818<SkipLang>{DOCNL} { /* new line in verbatim block */
2819 if (*yytext=='\n') yyextra->lineNr++;
2820 }
2821<SkipLang>. { /* any other character */
2822 }
2823
2824
2825
2826<CiteLabel,CiteLabelSection>{CITEID} { // found argument
2829 if (YY_START == CiteLabel)
2830 {
2831 BEGIN(Comment);
2832 }
2833 else
2834 {
2835 yyextra->sectionTitle+=yytext;
2836 BEGIN(SectionTitle);
2837 }
2838 }
2839<CiteLabel,CiteLabelSection>{DOCNL} { // missing argument
2840 warn(yyextra->fileName,yyextra->lineNr,
2841 "\\cite command has no label"
2842 );
2843
2844
2845 if (YY_START == CiteLabel)
2846 {
2848 BEGIN(Comment);
2849 }
2850 else
2851 {
2852 yyextra->sectionTitle+=yytext;
2854 BEGIN(SectionTitle);
2855 }
2856 }
2857<CiteLabel,CiteLabelSection>. { // invalid character for cite label
2858 warn(yyextra->fileName,yyextra->lineNr,
2859 "Invalid or missing cite label"
2860 );
2861 if (YY_START == CiteLabel)
2862 {
2863 BEGIN(Comment);
2864 }
2865 else
2866 {
2867 yyextra->sectionTitle+=yytext;
2868 BEGIN(SectionTitle);
2869 }
2870 }
2871
2872
2873
2874<CopyDoc><<EOF>> {
2876 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
2877 addOutput(yyscanner,yyextra->copyDocArg);
2879 BEGIN(Comment);
2880 }
2881<CopyDoc>"<"[/]?{TABLEDEL}">" {
2882 if (yyextra->braceCount==0)
2883 {
2885 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
2886 addOutput(yyscanner,yyextra->copyDocArg);
2888 BEGIN(Comment);
2889 }
2890 }
2891<CopyDoc>{DOCNL} {
2892 if (*yytext=='\n') yyextra->lineNr++;
2893 if (yyextra->braceCount==0)
2894 {
2896 addOutput(yyscanner,
" \\ilinebr\\ilinebr\\copydetails ");
2897 addOutput(yyscanner,yyextra->copyDocArg);
2899 BEGIN(Comment);
2900 }
2901 }
2902<CopyDoc>{LC} { // line continuation
2903 yyextra->lineNr++;
2904 }
2905<CopyDoc>[^@\\\n()<]+ { // non-special characters
2906 yyextra->copyDocArg+=yytext;
2908 }
2909<CopyDoc>"(" {
2910 yyextra->copyDocArg+=yytext;
2912 yyextra->braceCount++;
2913 }
2914<CopyDoc>")" {
2915 yyextra->copyDocArg+=yytext;
2917 yyextra->braceCount--;
2918 }
2919<CopyDoc>. {
2920 yyextra->copyDocArg+=yytext;
2922 }
2923
2924
2925<*>. { fprintf(stderr,"Lex scanner %s %sdefault rule for state %s: #%s#\n", __FILE__,!yyextra->fileName.isEmpty() ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START),yytext);}
2926<*>\n { fprintf(stderr,"Lex scanner %s %sdefault rule newline for state %s.\n", __FILE__, !yyextra->fileName.isEmpty() ? ("(" + yyextra->fileName +") ").data(): "",stateToString(YY_START));}
2927 */
2928
2929%%