/***************************************************************************** * * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * */ %option never-interactive %option prefix="commentscanYY" %option reentrant %option extra-type="struct commentscanYY_state *" %top{ #include } %{ /* * includes */ #include #include #include #include #include #include #include #include #include #include "cite.h" #include "commentscan.h" #include "condparser.h" #include "config.h" #include "debug.h" #include "docgroup.h" #include "doxygen.h" #include "entry.h" #include "formula.h" #include "language.h" #include "message.h" #include "parserintf.h" #include "reflist.h" #include "section.h" #include "util.h" #include "reflist.h" #define USE_STATE2STRING 0 // forward declarations static bool handleBrief(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleFn(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleDef(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleOverload(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleEnum(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleDefGroup(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleAddToGroup(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleWeakGroup(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleNamespace(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handlePackage(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleClass(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleHeaderFile(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleProtocol(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleCategory(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleUnion(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleStruct(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleInterface(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleIdlException(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handlePage(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleMainpage(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleFile(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleDir(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleExample(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleDetails(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleNoop(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleName(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleTodo(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleTest(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleBug(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleSubpage(yyscan_t yyscanner,const QCString &s, const QCStringList &); static bool handleDeprecated(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleXRefItem(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleRelated(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleRelatedAlso(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleMemberOf(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleRefItem(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleSection(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleAnchor(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleCite(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleFormatBlock(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleAddIndex(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleIf(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleIfNot(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleElseIf(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleElse(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleEndIf(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleIngroup(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleNoSubGrouping(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleShowInitializer(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleHideInitializer(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleCallgraph(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleHideCallgraph(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleCallergraph(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleHideCallergraph(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleReferencedByRelation(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleHideReferencedByRelation(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleReferencesRelation(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleHideReferencesRelation(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleInternal(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleLineBr(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleStatic(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handlePure(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handlePrivate(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handlePrivateSection(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleProtected(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleProtectedSection(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handlePublic(yyscan_t yyscanner,const QCString &s, const QCStringList &); static bool handlePublicSection(yyscan_t yyscanner,const QCString &s, const QCStringList &); static bool handleToc(yyscan_t yyscanner,const QCString &s, const QCStringList &); static bool handleInherit(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleExtends(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleCopyDoc(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleCopyBrief(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleCopyDetails(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleParBlock(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleEndParBlock(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleParam(yyscan_t yyscanner,const QCString &, const QCStringList &); static bool handleRetval(yyscan_t yyscanner,const QCString &, const QCStringList &); #if USE_STATE2STRING static const char *stateToString(int state); #endif typedef bool (*DocCmdFunc)(yyscan_t yyscanner,const QCString &name, const QCStringList &optList); struct DocCmdMap { DocCmdMap(DocCmdFunc h,bool b) : handler(h), endsBrief(b) {} DocCmdFunc handler; bool endsBrief; }; // map of command to handler function static const std::map< std::string, DocCmdMap > docCmdMap = { // command name handler function ends brief description { "brief", { &handleBrief, FALSE }}, { "short", { &handleBrief, FALSE }}, { "fn", { &handleFn, TRUE }}, { "var", { &handleFn, TRUE }}, { "typedef", { &handleFn, TRUE }}, { "property", { &handleFn, TRUE }}, { "def", { &handleDef, TRUE }}, { "overload", { &handleOverload, FALSE }}, { "enum", { &handleEnum, TRUE }}, { "defgroup", { &handleDefGroup, TRUE }}, { "addtogroup", { &handleAddToGroup, TRUE }}, { "weakgroup", { &handleWeakGroup, TRUE }}, { "namespace", { &handleNamespace, TRUE }}, { "package", { &handlePackage, TRUE }}, { "class", { &handleClass, TRUE }}, { "headerfile", { &handleHeaderFile, FALSE }}, { "protocol", { &handleProtocol, TRUE }}, { "category", { &handleCategory, TRUE }}, { "union", { &handleUnion, TRUE }}, { "struct", { &handleStruct, TRUE }}, { "interface", { &handleInterface, TRUE }}, { "idlexcept", { &handleIdlException, TRUE }}, { "page", { &handlePage, TRUE }}, { "mainpage", { &handleMainpage, TRUE }}, { "file", { &handleFile, TRUE }}, { "dir", { &handleDir, TRUE }}, { "example", { &handleExample, FALSE }}, { "details", { &handleDetails, TRUE }}, { "name", { &handleName, FALSE }}, { "todo", { &handleTodo, FALSE }}, // end brief will be done differently { "test", { &handleTest, FALSE }}, // end brief will be done differently { "bug", { &handleBug, FALSE }}, // end brief will be done differently { "deprecated", { &handleDeprecated, FALSE }}, // end brief will be done differently { "xrefitem", { &handleXRefItem, FALSE }}, // end brief will be done differently { "related", { &handleRelated, TRUE }}, { "relates", { &handleRelated, TRUE }}, { "relatedalso", { &handleRelatedAlso, TRUE }}, { "relatesalso", { &handleRelatedAlso, TRUE }}, { "parblock", { &handleParBlock, TRUE }}, { "endparblock", { &handleEndParBlock, TRUE }}, { "refitem", { &handleRefItem, TRUE }}, { "cite", { &handleCite, FALSE }}, { "subpage", { &handleSubpage, TRUE }}, { "section", { &handleSection, TRUE }}, { "subsection", { &handleSection, TRUE }}, { "subsubsection", { &handleSection, TRUE }}, { "paragraph", { &handleSection, TRUE }}, { "anchor", { &handleAnchor, TRUE }}, { "verbatim", { &handleFormatBlock, TRUE }}, { "latexonly", { &handleFormatBlock, FALSE }}, { "htmlonly", { &handleFormatBlock, FALSE }}, { "xmlonly", { &handleFormatBlock, FALSE }}, { "docbookonly", { &handleFormatBlock, FALSE }}, { "rtfonly", { &handleFormatBlock, FALSE }}, { "manonly", { &handleFormatBlock, FALSE }}, { "dot", { &handleFormatBlock, TRUE }}, { "msc", { &handleFormatBlock, TRUE }}, { "startuml", { &handleFormatBlock, TRUE }}, { "code", { &handleFormatBlock, TRUE }}, { "addindex", { &handleAddIndex, FALSE }}, { "if", { &handleIf, FALSE }}, { "ifnot", { &handleIfNot, FALSE }}, { "elseif", { &handleElseIf, FALSE }}, { "else", { &handleElse, FALSE }}, { "endif", { &handleEndIf, FALSE }}, { "ingroup", { &handleIngroup, TRUE }}, { "nosubgrouping", { &handleNoSubGrouping, FALSE }}, { "showinitializer", { &handleShowInitializer, FALSE }}, { "hideinitializer", { &handleHideInitializer, FALSE }}, { "callgraph", { &handleCallgraph, FALSE }}, { "hidecallgraph", { &handleHideCallgraph, FALSE }}, { "callergraph", { &handleCallergraph, FALSE }}, { "hidecallergraph", { &handleHideCallergraph, FALSE }}, { "showrefby", { &handleReferencedByRelation, FALSE }}, { "hiderefby", { &handleHideReferencedByRelation, FALSE }}, { "showrefs", { &handleReferencesRelation, FALSE }}, { "hiderefs", { &handleHideReferencesRelation, FALSE }}, { "internal", { &handleInternal, TRUE }}, { "_linebr", { &handleLineBr, FALSE }}, { "static", { &handleStatic, FALSE }}, { "pure", { &handlePure, FALSE }}, { "private", { &handlePrivate, FALSE }}, { "privatesection", { &handlePrivateSection, FALSE }}, { "protected", { &handleProtected, FALSE }}, { "protectedsection",{ &handleProtectedSection, FALSE }}, { "public", { &handlePublic, FALSE }}, { "publicsection", { &handlePublicSection, FALSE }}, { "tableofcontents", { &handleToc, FALSE }}, { "inherit", { &handleInherit, TRUE }}, { "extends", { &handleExtends, TRUE }}, { "implements", { &handleExtends, TRUE }}, { "memberof", { &handleMemberOf, TRUE }}, { "arg", { 0, TRUE }}, { "attention", { 0, TRUE }}, { "author", { 0, TRUE }}, { "authors", { 0, TRUE }}, { "copydoc", { &handleCopyDoc, TRUE }}, { "copybrief", { &handleCopyBrief, FALSE }}, { "copydetails", { &handleCopyDetails, TRUE }}, { "copyright", { 0, TRUE }}, { "date", { 0, TRUE }}, { "dotfile", { 0, TRUE }}, { "htmlinclude", { 0, FALSE }}, { "image", { 0, TRUE }}, { "include", { 0, TRUE }}, { "includelineno", { 0, TRUE }}, { "invariant", { 0, TRUE }}, { "latexinclude", { 0, FALSE }}, { "li", { 0, TRUE }}, { "line", { 0, TRUE }}, { "note", { 0, TRUE }}, { "par", { 0, TRUE }}, { "param", { &handleParam, TRUE }}, { "tparam", { 0, TRUE }}, { "post", { 0, TRUE }}, { "pre", { 0, TRUE }}, { "remark", { 0, TRUE }}, { "remarks", { 0, TRUE }}, { "result", { 0, TRUE }}, { "return", { 0, TRUE }}, { "returns", { 0, TRUE }}, { "exception", { 0, TRUE }}, { "retval", { &handleRetval, TRUE }}, { "sa", { 0, TRUE }}, { "see", { 0, TRUE }}, { "since", { 0, TRUE }}, { "throw", { 0, TRUE }}, { "throws", { 0, TRUE }}, { "until", { 0, TRUE }}, { "verbinclude", { 0, FALSE }}, { "version", { 0, TRUE }}, { "warning", { 0, TRUE }}, { "snippet", { 0, TRUE }}, { "snippetlineno", { 0, TRUE }}, { "noop", { &handleNoop, TRUE }}, { "rtfinclude", { 0, FALSE }}, { "docbookinclude", { 0, FALSE }}, { "maninclude", { 0, FALSE }}, { "xmlinclude", { 0, FALSE }} }; #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 #define YY_NEVER_INTERACTIVE 1 enum XRefKind { XRef_Item, XRef_Todo, XRef_Test, XRef_Bug, XRef_Deprecated, XRef_None }; enum OutputContext { OutputDoc, OutputBrief, OutputXRef, OutputInbody }; enum GuardType { Guard_If, Guard_IfNot, Guard_Skip }; class GuardedSection { public: GuardedSection(bool enabled,bool parentVisible) : m_enabled(enabled),m_parentVisible(parentVisible) {} bool isEnabled() const { return m_enabled; } bool parentVisible() const { return m_parentVisible; } private: bool m_enabled; bool m_parentVisible; }; /* ----------------------------------------------------------------- * * statics */ struct commentscanYY_state { OutlineParserInterface *langParser = 0; // the language parser that is calling us QCString inputString; // input string int inputPosition = 0; // read pointer QCString fileName; // file name that is read from int lineNr = 0; // line number in the input bool inBody = FALSE; // was the comment found inside the body of a function? OutputContext inContext; // are we inside the brief, details or xref part bool briefEndsAtDot = FALSE; // does the brief description stop at a dot? QCString formulaText; // Running text of a formula QCString formulaEnv; // environment name int formulaNewLines = 0; // amount of new lines in the formula QCString *pOutputString = 0; // pointer to string to which the output is appended. QCString outputXRef; // temp argument of todo/test/../xrefitem commands QCString blockName; // preformatted block name (e.g. verbatim, latexonly,...) XRefKind xrefKind = XRef_Item; // kind of cross-reference command XRefKind newXRefKind = XRef_Item; // GuardType guardType = Guard_If; // kind of guards for conditional section bool enabledSectionFound = FALSE; QCString functionProto; // function prototype std::stack guards; // tracks nested conditional sections (if,ifnot,..) Entry *current = 0; // working entry bool needNewEntry = FALSE; QCString sectionLabel; QCString sectionTitle; int sectionLevel = 0; QCString xrefItemKey; QCString newXRefItemKey; QCString xrefItemTitle; QCString xrefListTitle; Protection protection = Public; bool xrefAppendFlag = FALSE; bool inGroupParamFound = FALSE; int braceCount = 0; bool insidePre = FALSE; bool parseMore = FALSE; int condCount = 0; int commentCount = 0; QCString spaceBeforeCmd; QCString spaceBeforeIf; QCString copyDocArg; QCString guardExpr; int roundCount = 0; bool insideParBlock = FALSE; bool inInternalDocs = FALSE; int prevPosition = 0; DocGroup docGroup; }; //----------------------------------------------------------------------------- static QCString stripQuotes(const char *s); static bool getDocSectionName(int s); static SectionType sectionLevelToType(int level); static void stripTrailingWhiteSpace(QCString &s); static void initParser(yyscan_t yyscanner); static bool makeStructuralIndicator(yyscan_t yyscanner,Entry::Sections s); static void lineCount(yyscan_t yyscanner); static void addXRefItem(yyscan_t yyscanner, const char *listName,const char *itemTitle, const char *listTitle,bool append); static QCString addFormula(yyscan_t yyscanner); static void checkFormula(yyscan_t yyscanner); static void addSection(yyscan_t yyscanner); static inline void setOutput(yyscan_t yyscanner,OutputContext ctx); static void addAnchor(yyscan_t yyscanner,const char *anchor); static inline void addOutput(yyscan_t yyscanner,const char *s); static inline void addOutput(yyscan_t yyscanner,char c); static void endBrief(yyscan_t yyscanner,bool addToOutput=TRUE); static void handleGuard(yyscan_t yyscanner,const QCString &expr); static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); static void addCite(yyscan_t yyscanner); //----------------------------------------------------------------------------- #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size); %} /* start command character */ CMD ("\\"|"@") XREFCMD {CMD}("bug"|"deprecated"|"test"|"todo"|"xrefitem") PRE [pP][rR][eE] TABLE [tT][aA][bB][lL][eE] P [pP] UL [uU][lL] OL [oO][lL] DL [dD][lL] IMG [iI][mM][gG] HR [hH][rR] PARA [pP][aA][rR][aA] CODE [cC][oO][dD][eE] CAPTION [cC][aA][pP][tT][iI][oO][nN] CENTER [cC][eE][nN][tT][eE][rR] DIV [dD][iI][vV] DETAILEDHTML {CENTER}|{DIV}|{PRE}|{UL}|{TABLE}|{OL}|{DL}|{P}|[Hh][1-6]|{IMG}|{HR}|{PARA} DETAILEDHTMLOPT {CODE} BN [ \t\n\r] BL [ \t\r]*"\n" B [ \t] BS ^(({B}*"//")?)(({B}*"*"+)?){B}* ATTR ({B}+[^>\n]*)? DOCNL "\n"|"\\_linebr" LC "\\"{B}*"\n" NW [^a-z_A-Z0-9] FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+@&#] FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+@&#] FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]*"\"") ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* LABELID [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF\-]* CITESCHAR [a-z_A-Z0-9\x80-\xFF\-\?] CITEECHAR [a-z_A-Z0-9\x80-\xFF\-\+:\/\?]* CITEID {CITESCHAR}{CITEECHAR}*("."{CITESCHAR}{CITEECHAR}*)*|"\""{CITESCHAR}{CITEECHAR}*("."{CITESCHAR}{CITEECHAR}*)*"\"" SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) SCOPENAME "$"?(({ID}?{BN}*("::"|"."){BN}*)*)((~{BN}*)?{ID}) TMPLSPEC "<"{BN}*[^>]+{BN}*">" MAILADDR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]+ RCSTAG "$"{ID}":"[^\n$]+"$" %option noyywrap /* comment parsing states. */ %x Comment %x PageDocArg1 %x PageDocArg2 %x RelatesParam1 %x ClassDocArg1 %x ClassDocArg2 %x ClassDocArg3 %x CategoryDocArg1 %x XRefItemParam1 %x XRefItemParam2 %x XRefItemParam3 %x FileDocArg1 %x ParamArg1 %x EnumDocArg1 %x NameSpaceDocArg1 %x PackageDocArg1 %x GroupDocArg1 %x GroupDocArg2 %x SectionLabel %x SectionTitle %x SubpageLabel %x SubpageTitle %x FormatBlock %x LineParam %x GuardParam %x GuardParamEnd %x SkipGuardedSection %x SkipInternal %x NameParam %x InGroupParam %x FnParam %x OverloadParam %x InheritParam %x ExtendsParam %x ReadFormulaShort %x ReadFormulaLong %x AnchorLabel %x HtmlComment %x SkipLang %x CiteLabel %x CopyDoc %x GuardExpr %x CdataSection %x Noop %% /* What can happen in while parsing a comment block: * commands (e.g. @page, or \page) * escaped commands (e.g. @@page or \\page). * formulas (e.g. \f$ \f[ \f{..) * directories (e.g. \doxygen\src\) * autolist end. (e.g. a dot on an otherwise empty line) * newlines. * end of brief description due to blank line. * end of brief description due to some command (@command, or ). * words and whitespace and other characters (#,?!, etc). * grouping commands (e.g. @{ and @}) * language switch (e.g. \~english or \~). * mail address (e.g. doxygen@gmail.com). * quoted text, such as "foo@bar" * XML commands, */ {CMD}{CMD}[a-z_A-Z]+{B}* { // escaped command addOutput(yyscanner,yytext); } {CMD}{CMD}"~"[a-z_A-Z]* { // escaped command addOutput(yyscanner,yytext); } {MAILADDR} { // mail address addOutput(yyscanner,yytext); } "\""[^"\n]*"\"" { // quoted text addOutput(yyscanner,yytext); } ("\\"[a-z_A-Z]+)+"\\" { // directory (or chain of commands!) addOutput(yyscanner,yytext); } "<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description setOutput(yyscanner,OutputDoc); // continue with the same input REJECT; } "<"{DETAILEDHTMLOPT}{ATTR}">" { // HTML command that ends a brief description if (yyextra->current->lang==SrcLangExt_CSharp) { setOutput(yyscanner,OutputDoc); } // continue with the same input REJECT; } "" { // start of a .NET XML style brief description setOutput(yyscanner,OutputBrief); addOutput(yyscanner,yytext); } "" { // start of a .NET XML style detailed description setOutput(yyscanner,OutputDoc); addOutput(yyscanner,yytext); } "" { // start of a .NET XML style detailed description setOutput(yyscanner,OutputBrief); addOutput(yyscanner,yytext); setOutput(yyscanner,OutputDoc); } "" { // end of a brief or detailed description setOutput(yyscanner,OutputDoc); addOutput(yyscanner,yytext); } "<"{CAPTION}{ATTR}">" { QCString tag=yytext; int s=tag.find("id="); if (s!=-1) // command has id attribute { char c=tag[s+3]; if (c=='\'' || c=='"') // valid start { int e=tag.find(c,s+4); if (e!=-1) // found matching end { QCString id=tag.mid(s+4,e-s-4); // extract id addAnchor(yyscanner,id); } } } addOutput(yyscanner,yytext); } "<"{PRE}{ATTR}">" { yyextra->insidePre=TRUE; addOutput(yyscanner,yytext); } "" { yyextra->insidePre=FALSE; addOutput(yyscanner,yytext); } {RCSTAG} { // RCS tag which end a brief description setOutput(yyscanner,OutputDoc); REJECT; } "