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