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