summaryrefslogtreecommitdiffstats
path: root/src/commentscan.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/commentscan.l')
-rw-r--r--src/commentscan.l1915
1 files changed, 1915 insertions, 0 deletions
diff --git a/src/commentscan.l b/src/commentscan.l
new file mode 100644
index 0000000..e31eda3
--- /dev/null
+++ b/src/commentscan.l
@@ -0,0 +1,1915 @@
+/*****************************************************************************
+ *
+ * Copyright (C) 1997-2005 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.
+ *
+ */
+
+%{
+
+/*
+ * includes
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "qtbc.h"
+#include <qarray.h>
+#include <qstack.h>
+#include <qregexp.h>
+#include <unistd.h>
+#include <qfile.h>
+
+#include "scanner.h"
+#include "entry.h"
+#include "doxygen.h"
+#include "message.h"
+#include "config.h"
+#include "util.h"
+#include "index.h"
+#include "defargs.h"
+#include "language.h"
+#include "outputlist.h"
+#include "membergroup.h"
+#include "reflist.h"
+#include "code.h"
+
+// forward declarations
+static void handleBrief(const QCString &);
+static void handleFn(const QCString &);
+static void handleDef(const QCString &);
+static void handleOverload(const QCString &);
+static void handleEnum(const QCString &);
+static void handleDefGroup(const QCString &);
+static void handleAddToGroup(const QCString &);
+static void handleWeakGroup(const QCString &);
+static void handleNamespace(const QCString &);
+static void handlePackage(const QCString &);
+static void handleClass(const QCString &);
+static void handleProtocol(const QCString &);
+static void handleCategory(const QCString &);
+static void handleUnion(const QCString &);
+static void handleStruct(const QCString &);
+static void handleInterface(const QCString &);
+static void handleIdlException(const QCString &);
+static void handlePage(const QCString &);
+static void handleMainpage(const QCString &);
+static void handleFile(const QCString &);
+static void handleDir(const QCString &);
+static void handleExample(const QCString &);
+static void handleDetails(const QCString &);
+static void handleName(const QCString &);
+static void handleTodo(const QCString &);
+static void handleTest(const QCString &);
+static void handleBug(const QCString &);
+static void handleDeprecated(const QCString &);
+static void handleXRefItem(const QCString &);
+static void handleRelated(const QCString &);
+static void handleRelatedAlso(const QCString &);
+static void handleRefItem(const QCString &);
+static void handleSection(const QCString &);
+static void handleAnchor(const QCString &);
+static void handleFormatBlock(const QCString &);
+static void handleAddIndex(const QCString &);
+static void handleIf(const QCString &);
+static void handleIfNot(const QCString &);
+static void handleElseIf(const QCString &);
+static void handleElse(const QCString &);
+static void handleEndIf(const QCString &);
+static void handleIngroup(const QCString &);
+static void handleNoSubGrouping(const QCString &);
+static void handleShowInitializer(const QCString &);
+static void handleHideInitializer(const QCString &);
+static void handleCallgraph(const QCString &);
+static void handleInternal(const QCString &);
+static void handleLineBr(const QCString &);
+static void handleStatic(const QCString &);
+static void handlePure(const QCString &);
+static void handlePrivate(const QCString &);
+static void handlePrivateSection(const QCString &);
+static void handleProtected(const QCString &);
+static void handleProtectedSection(const QCString &);
+static void handlePublic(const QCString &s);
+static void handlePublicSection(const QCString &s);
+static void handleInherit(const QCString &);
+
+
+typedef void (*DocCmdFunc)(const QCString &name);
+
+struct DocCmdMap
+{
+ const char *cmdName;
+ DocCmdFunc handler;
+};
+
+static DocCmdMap docCmdMap[] =
+{
+ { "brief", &handleBrief },
+ { "short", &handleBrief },
+ { "fn", &handleFn },
+ { "var", &handleFn },
+ { "typedef", &handleFn },
+ { "property", &handleFn },
+ { "def", &handleDef },
+ { "overload", &handleOverload },
+ { "enum", &handleEnum },
+ { "defgroup", &handleDefGroup },
+ { "addtogroup", &handleAddToGroup },
+ { "weakgroup", &handleWeakGroup },
+ { "namespace", &handleNamespace },
+ { "package", &handlePackage },
+ { "class", &handleClass },
+ { "protocol", &handleProtocol },
+ { "category", &handleCategory },
+ { "union", &handleUnion },
+ { "struct", &handleStruct },
+ { "interface", &handleInterface },
+ { "idlexcept", &handleIdlException },
+ { "page", &handlePage },
+ { "mainpage", &handleMainpage },
+ { "file", &handleFile },
+ { "dir", &handleDir },
+ { "example", &handleExample },
+ { "details", &handleDetails },
+ { "name", &handleName },
+ { "todo", &handleTodo },
+ { "test", &handleTest },
+ { "bug", &handleBug },
+ { "deprecated", &handleDeprecated },
+ { "xrefitem", &handleXRefItem },
+ { "related", &handleRelated },
+ { "relates", &handleRelated },
+ { "relatedalso", &handleRelatedAlso },
+ { "relatesalso", &handleRelatedAlso },
+ { "refitem", &handleRefItem },
+ { "section", &handleSection },
+ { "subsection", &handleSection },
+ { "subsubsection", &handleSection },
+ { "paragraph", &handleSection },
+ { "anchor", &handleAnchor },
+ { "verbatim", &handleFormatBlock },
+ { "latexonly", &handleFormatBlock },
+ { "htmlonly", &handleFormatBlock },
+ { "rtfonly", &handleFormatBlock },
+ { "dot", &handleFormatBlock },
+ { "code", &handleFormatBlock },
+ { "addindex", &handleAddIndex },
+ { "if", &handleIf },
+ { "ifnot", &handleIfNot },
+ { "elseif", &handleElseIf },
+ { "else", &handleElse },
+ { "endif", &handleEndIf },
+ { "ingroup", &handleIngroup },
+ { "nosubgrouping", &handleNoSubGrouping },
+ { "showinitializer", &handleShowInitializer },
+ { "hideinitializer", &handleHideInitializer },
+ { "callgraph", &handleCallgraph },
+ { "internal", &handleInternal },
+ { "_linebr", &handleLineBr },
+ { "static", &handleStatic },
+ { "pure", &handlePure },
+ { "private", &handlePrivate},
+ { "privatesection", &handlePrivateSection },
+ { "protected", &handleProtected },
+ { "protectedsection",&handleProtectedSection },
+ { "public", &handlePublic },
+ { "publicsection", &handlePublicSection },
+ { "inherit", &handleInherit },
+ { 0, 0 }
+};
+
+
+
+/** @brief Command mapper.
+ *
+ * Maps a command name (as found in a comment block) onto a
+ * specific handler function.
+ */
+class DocCmdMapper
+{
+ public:
+ /** maps a command name to a handler function */
+ static DocCmdFunc *map(const char *name)
+ {
+ return instance()->find(name);
+ }
+
+ /** release the singleton */
+ static void freeInstance()
+ {
+ delete s_instance; s_instance=0;
+ }
+
+ private:
+ static DocCmdMapper *instance()
+ {
+ if (s_instance==0) s_instance = new DocCmdMapper;
+ return s_instance;
+ }
+
+ DocCmdMapper() : m_map(89)
+ {
+ DocCmdMap *p = docCmdMap;
+ while (p->cmdName)
+ {
+ m_map.insert(p->cmdName,&p->handler);
+ p++;
+ }
+ }
+
+ DocCmdFunc *find(const char *name)
+ {
+ return m_map.find(name);
+ }
+ QDict<DocCmdFunc> m_map;
+ static DocCmdMapper *s_instance;
+};
+
+DocCmdMapper *DocCmdMapper::s_instance=0;
+
+
+#define YY_NEVER_INTERACTIVE 1
+
+enum XRefKind
+{
+ XRef_Item,
+ XRef_Todo,
+ XRef_Test,
+ XRef_Bug,
+ XRef_Deprecated
+};
+
+enum OutputContext
+{
+ OutputDoc,
+ OutputBrief,
+ OutputXRef
+};
+
+enum GuardType
+{
+ Guard_If,
+ Guard_IfNot
+};
+
+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
+ */
+
+static const char * inputString; // input string
+static int inputPosition; // read pointer
+static QCString yyFileName; // file name that is read from
+static int yyLineNr; // line number in the input
+//static bool inBody; // was the comment found inside the body of a function?
+static OutputContext inContext; // are we inside the brief, details or xref part
+static bool briefEndsAtDot; // does the brief description stop at a dot?
+static QCString formulaText; // Running text of a formula
+static QCString formulaEnv; // environment name
+static QCString *pOutputString; // pointer to string to which the output is appended.
+static QCString outputXRef; // temp argument of todo/test/../xrefitem commands
+static QCString blockName; // preformatted block name (e.g. verbatim, latexonly,...)
+static XRefKind xrefKind; // kind of cross-reference command
+static GuardType guardType; // kind of guard for conditional section
+static QCString nameHeader; // heading of the @name command
+static QCString functionProto; // function prototype
+static QStack<GuardedSection> guards; // tracks nested conditional sections (if,ifnot,..)
+static Entry* current = 0 ; // working entry
+//static Entry* current_root = 0 ; // parent of working entry
+
+
+//static Entry* previous = 0 ; // TODO: remove need for this
+static bool needNewEntry;
+
+static QCString sectionLabel;
+static QCString sectionTitle;
+static QCString xrefItemKey;
+static QCString xrefItemTitle;
+static QCString xrefListTitle;
+static Protection protection;
+
+//-----------------------------------------------------------------------------
+
+static void initParser()
+{
+ sectionLabel.resize(0);
+ sectionTitle.resize(0);
+ nameHeader.resize(0);
+}
+
+//-----------------------------------------------------------------------------
+
+static void makeStructuralIndicator(Entry::Sections s)
+{
+ needNewEntry = TRUE;
+ current->section = s;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+}
+
+static void lineCount()
+{
+ for( const char* c = yytext ; *c ; ++c )
+ yyLineNr += (*c == '\n') ;
+}
+
+
+static QCString stripQuotes(const char *s)
+{
+ QCString name;
+ if (s==0 || *s==0) return name;
+ name=s;
+ if (name.at(0)=='"' && name.at(name.length()-1)=='"')
+ {
+ name=name.mid(1,name.length()-2);
+ }
+ return name;
+}
+
+//-----------------------------------------------------------------
+
+static void addXRefItem(const char *listName,const char *itemTitle,const char *listTitle)
+{
+ Entry *docEntry = current; // inBody && previous ? previous : current;
+ //printf("docEntry=%p\n",docEntry);
+ if (listName==0) return;
+
+ //printf("addXRefItem(%s,%s,%s)\n",listName,itemTitle,listTitle);
+ ListItemInfo *lii=0;
+ RefList *refList = Doxygen::xrefLists->find(listName);
+ if (refList==0) // new list
+ {
+ refList = new RefList(listName,listTitle,itemTitle);
+ Doxygen::xrefLists->insert(listName,refList);
+ //printf("new list!\n");
+ }
+ if (docEntry->sli)
+ {
+ QListIterator<ListItemInfo> slii(*docEntry->sli);
+ for (slii.toFirst();(lii=slii.current());++slii)
+ {
+ if (strcmp(lii->type,listName)==0)
+ {
+ //printf("found %s lii->type=%s\n",listName,lii->type);
+ break;
+ }
+ }
+ }
+#if 0 // with this code multiple @todo items can be put under the same
+ // heading, I removed it because it changes the text flow.
+ if (lii) // already found item of same type before
+ {
+ //printf("listName=%s item id = %d existing\n",listName,lii->itemId);
+ RefItem *item = refList->getRefItem(lii->itemId);
+ ASSERT(item!=0);
+ item->text += " <p>";
+ item->text += outputXRef;
+ //printf("%s: text +=%s\n",listName,item->text.data());
+ }
+ else // new item
+#endif
+ {
+ int itemId = refList->addRefItem();
+ //printf("listName=%s item id = %d new current=%p\n",listName,itemId,current);
+
+ // if we have already an item from the same list type (e.g. a second @todo)
+ // in the same Entry (i.e. lii!=0) then we reuse its link anchor.
+ char anchorLabel[1024];
+ sprintf(anchorLabel,"_%s%06d",listName,lii ? lii->itemId : itemId);
+ RefItem *item = refList->getRefItem(itemId);
+ ASSERT(item!=0);
+ item->text = outputXRef;
+ item->listAnchor = anchorLabel;
+ docEntry->addSpecialListItem(listName,itemId);
+ QCString cmdString;
+ cmdString.sprintf("\\xrefitem %s %d\n",listName,itemId);
+ docEntry->doc += cmdString;
+ SectionInfo *si=new SectionInfo(listName,anchorLabel,
+ sectionTitle,SectionInfo::Anchor);
+ Doxygen::sectionDict.insert(anchorLabel,si);
+ docEntry->anchors->append(si);
+ }
+ //current->brief = slString; // restore orginial brief desc.
+}
+
+//-----------------------------------------------------------------------------
+
+// Adds a formula text to the list/dictionary of formulas if it was
+// not already added. Returns the label of the formula.
+static QCString addFormula()
+{
+ QCString formLabel;
+ QCString fText=formulaText.simplifyWhiteSpace();
+ Formula *f=0;
+ if ((f=Doxygen::formulaDict[fText])==0)
+ {
+ f = new Formula(fText);
+ Doxygen::formulaList.append(f);
+ Doxygen::formulaDict.insert(fText,f);
+ formLabel.sprintf("\\form#%d",f->getId());
+ Doxygen::formulaNameDict.insert(formLabel,f);
+ }
+ else
+ {
+ formLabel.sprintf("\\form#%d",f->getId());
+ }
+ return formLabel;
+}
+
+//-----------------------------------------------------------------------------
+
+static void checkFormula();
+//-----------------------------------------------------------------------------
+
+static void prependScope()
+{
+ Entry *current_root = current->parent;
+ if (current_root && current_root->section & Entry::SCOPE_MASK)
+ {
+ //printf("--- prependScope %s to %s\n",current_root->name.data(),current->name.data());
+ current->name.prepend(current_root->name+"::");
+ if (current_root->tArgLists)
+ {
+ if (current->tArgLists==0)
+ {
+ current->tArgLists = new QList<ArgumentList>;
+ current->tArgLists->setAutoDelete(TRUE);
+ }
+ //printf("prependScope #=%d #current=%d\n",current_root->tArgLists->count(),current->tArgLists->count());
+ QListIterator<ArgumentList> talsi(*current_root->tArgLists);
+ ArgumentList *srcAl=0;
+ for (talsi.toLast();(srcAl=talsi.current());--talsi)
+ {
+ ArgumentList *dstAl = new ArgumentList;
+ dstAl->setAutoDelete(TRUE);
+ QListIterator<Argument> tali(*srcAl);
+ Argument *a;
+ for (;(a=tali.current());++tali)
+ {
+ dstAl->append(new Argument(*a));
+ //printf("appending argument %s %s\n",a->type.data(),a->name.data());
+ }
+ current->tArgLists->insert(0,dstAl);
+ }
+ }
+ }
+}
+
+static void addSection()
+{
+ sectionTitle+=yytext;
+ sectionTitle=sectionTitle.stripWhiteSpace();
+ //printf("Adding new section file=%s label=%s title=%s\n",yyFileName,sectionLabel.data(),sectionTitle.data());
+ SectionInfo *si = new SectionInfo(yyFileName,sectionLabel,sectionTitle,SectionInfo::Anchor);
+ current->anchors->append(si);
+ Doxygen::sectionDict.insert(yytext,si);
+}
+
+//-----------------------------------------------------------------------------
+
+// determines the string to write to
+static inline void setOutput(OutputContext ctx)
+{
+ if (inContext==OutputXRef) // end of XRef section => add the item
+ {
+ switch(xrefKind)
+ {
+ case XRef_Todo:
+ addXRefItem("todo",theTranslator->trTodo(),theTranslator->trTodoList());
+ break;
+ case XRef_Test:
+ addXRefItem("test",theTranslator->trTest(),theTranslator->trTestList());
+ break;
+ case XRef_Bug:
+ addXRefItem("bug",theTranslator->trBug(),theTranslator->trBugList());
+ break;
+ case XRef_Deprecated:
+ addXRefItem("deprecated",theTranslator->trDeprecated(),theTranslator->trDeprecatedList());
+ break;
+ case XRef_Item:
+ addXRefItem(xrefItemKey,xrefItemTitle,xrefListTitle);
+ break;
+ }
+ }
+ inContext = ctx;
+ switch(inContext)
+ {
+ case OutputDoc:
+ pOutputString = &current->doc;
+ break;
+ case OutputBrief:
+ pOutputString = &current->brief;
+ break;
+ case OutputXRef:
+ pOutputString = &outputXRef;
+ break;
+ }
+}
+
+// add a string to the output
+static inline void addOutput(const char *s)
+{
+ *pOutputString+=s;
+}
+
+// add a character to the output
+static inline void addOutput(char c)
+{
+ *pOutputString+=c;
+}
+
+/* ----------------------------------------------------------------- */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ while( c < max_size && inputString[inputPosition] )
+ {
+ *buf = inputString[inputPosition++] ;
+ //printf("%d (%c)\n",*buf,*buf);
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+ /* start command character */
+CMD ("\\"|"@")
+DETAILEDCMD {CMD}("arg"|"attention"|"author"|"bug"|"code"|"date"|"deprecated"|"dot"|"dotfile"|"example"|"htmlinclude"|"htmlonly"|"image"|"include"|"includelineno"|"internal"|"invariant"|"latexonly"|"li"|"line"|manonly"|"name"|"note"|"par"|"paragraph"|"param"|"post"|"pre"|"remarks"|"relate"[sd]"("also")?|"remarks"|"return"[s]?|"retval"|"sa"|"section"|"see"|"since"|"subsection"|"subsubsection"|"test"|"throw"|"todo"|"until"|"verbatim"|"verbinclude"|"version"|"warning"|"xmlonly"|"xrefitem")
+ /* ("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note"|"remark"[s]?|"todo"|"test"|"xrefitem"|"ingroup"|"callgraph"|"latexonly"|"htmlonly"|"xmlonly"|"{"|"verbatim"|"dotfile"|"dot"|"defgroup"|"addtogroup"|"weakgroup"|"class"|"namespace"|"union"|"struct"|"fn"|"var"|"details"|"typedef"|"def"|"overload")|("<"{PRE}">") */
+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]
+CODE [cC][oO][dD][eE]
+DETAILEDHTML {PRE}|{UL}|{TABLE}|{OL}|{DL}|{P}|[Hh][1-6]|{IMG}|{HR}|{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\\:\\\/\-\+]
+FILEECHAR [a-z_A-Z0-9\-\+]
+FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]+"\"")
+ID "$"?[a-z_A-Z][a-z_A-Z0-9]*
+LABELID [a-z_A-Z][a-z_A-Z0-9\-]*
+SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
+SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID})
+
+%option nounput
+%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 EnumDocArg1
+%x NameSpaceDocArg1
+%x PackageDocArg1
+%x GroupDocArg1
+%x GroupDocArg2
+%x SectionLabel
+%x SectionTitle
+%x FormatBlock
+%x LineParam
+%x GuardParam
+%x SkipGuardedSection
+%x SkipInternal
+%x NameParam
+%x InGroupParam
+%x FnParam
+%x OverloadParam
+%x InheritParam
+%x ReadFormulaShort
+%x ReadFormulaLong
+%x AnchorLabel
+%x HtmlComment
+
+%%
+
+ /* 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 due to blank line.
+ * end of brief due to some command (@command, or <command>).
+ * words and whitespace and other characters (#,?!, etc).
+ * grouping commands (e.g. @{ and @})
+ */
+
+<Comment>{CMD}{CMD}[a-z_A-Z]*{B}* { // escaped command
+ addOutput(yytext);
+ }
+<Comment>("\\"[a-z_A-Z]+)+"\\" { // directory (or chain of commands!)
+ addOutput(yytext);
+ }
+<Comment>{DETAILEDCMD}/[^a-z_A-Z] { // command that can end a brief description
+ setOutput(OutputDoc);
+ // continue with the same input
+ REJECT;
+ }
+<Comment>"<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description
+ setOutput(OutputDoc);
+ // continue with the same input
+ REJECT;
+ }
+<Comment>"<!--" {
+ BEGIN(HtmlComment);
+ }
+<Comment>{CMD}[a-z_A-Z]+{B}* { // potentially interesting command
+ QCString cmdName = QCString(&yytext[1]).stripWhiteSpace();
+ DocCmdFunc *funcPtr = DocCmdMapper::map(cmdName);
+ if (funcPtr) // special action is required
+ {
+ //printf("Special command %s\n",yytext);
+ (*funcPtr)(cmdName);
+ }
+ else // command not relevant
+ {
+ addOutput(yytext);
+ }
+ }
+<Comment>("\\\\"|"@@")"f"[$\[{] { // escaped formula command
+ addOutput(yytext);
+ }
+<Comment>{CMD}"f{"[^}\n]+"}" { // start of a formula with custom environment
+ formulaText="\\begin";
+ formulaEnv=&yytext[2];
+ formulaText+=formulaEnv;
+ BEGIN(ReadFormulaLong);
+ }
+<Comment>{CMD}"f$" { // start of a inline formula
+ formulaText="$";
+ BEGIN(ReadFormulaShort);
+ }
+<Comment>{CMD}"f[" { // start of a block formula
+ formulaText="\\[";
+ BEGIN(ReadFormulaLong);
+ }
+<Comment>{CMD}"{" { // begin of a group
+ handleGroupStartCommand(nameHeader);
+ }
+<Comment>{CMD}"}" { // end of a group
+ handleGroupEndCommand();
+ }
+<Comment>{CMD}[$@\\&~<>#%] { // escaped character
+ addOutput(yytext);
+ }
+<Comment>[a-z_A-Z]+ { // normal word
+ addOutput(yytext);
+ }
+<Comment>^{B}*"."{B}*/\n { // explicit end autolist: e.g " ."
+ addOutput(yytext);
+ }
+<Comment>"."[a-z_A-Z0-9] { // . at start or in the middle of a word
+ addOutput(yytext);
+ }
+<Comment>".\\"[ \t] { // . with escaped space.
+ addOutput(yytext[0]);
+ addOutput(yytext[2]);
+ }
+<Comment>\n({B}*\n)+ { // at least one blank line
+ if (inContext)
+ {
+ setOutput(OutputDoc);
+ }
+ else
+ {
+ addOutput(yytext);
+ }
+ lineCount();
+ }
+<Comment>"." { // potential end of a JavaDoc style comment
+ addOutput(*yytext);
+ if (briefEndsAtDot)
+ {
+ setOutput(OutputDoc);
+ }
+ }
+<Comment>\n { // newline
+ addOutput(*yytext);
+ yyLineNr++;
+ }
+<Comment>. { // catch-all for anything else
+ addOutput(*yytext);
+ }
+
+
+ /* -------------- Rules for handling HTML comments ----------- */
+
+<HtmlComment>"--"[!]?">"{B}* { BEGIN( Comment ); }
+<HtmlComment>{DOCNL} {
+ if (*yytext=='\n') yyLineNr++;
+ }
+<HtmlComment>[^\\\n\-]+ { // ignore unimportant characters
+ }
+<HtmlComment>. { // ignore every else
+ }
+
+ /* -------------- Rules for handling formulas ---------------- */
+
+<ReadFormulaShort>{CMD}"f$" { // end of inline formula
+ formulaText+="$";
+ addOutput(addFormula());
+ addOutput(' ');
+ BEGIN(Comment);
+ }
+<ReadFormulaLong>{CMD}"f]" { // end of block formula
+ formulaText+="\\]";
+ addOutput(addFormula());
+ addOutput(' ');
+ BEGIN(Comment);
+ }
+<ReadFormulaLong>{CMD}"f}" { // end of custom env formula
+ formulaText+="\\end";
+ formulaText+=formulaEnv;
+ addOutput(addFormula());
+ addOutput(' ');
+ BEGIN(Comment);
+ }
+<ReadFormulaLong,ReadFormulaShort>[^\\@\n]+ { // any non-special character
+ formulaText+=yytext;
+ }
+<ReadFormulaLong,ReadFormulaShort>\n { // new line
+ formulaText+=*yytext;
+ yyLineNr++;
+ }
+<ReadFormulaLong,ReadFormulaShort>. { // any othe character
+ formulaText+=*yytext;
+ }
+
+ /* ------------ handle argument of enum command --------------- */
+
+<EnumDocArg1>{SCOPEID} { // handle argument
+ current->name = yytext;
+ prependScope();
+ BEGIN( Comment );
+ }
+<EnumDocArg1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<EnumDocArg1>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Warning: missing argument after \\enum."
+ );
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<EnumDocArg1>. { // ignore other stuff
+ }
+
+ /* ------------ handle argument of namespace command --------------- */
+
+<NameSpaceDocArg1>{SCOPENAME} { // handle argument
+ current->name = yytext;
+ BEGIN( Comment );
+ }
+<NameSpaceDocArg1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<NameSpaceDocArg1>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Warning: missing argument after "
+ "\\namespace."
+ );
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<NameSpaceDocArg1>. { // ignore other stuff
+ }
+
+ /* ------------ handle argument of package command --------------- */
+
+<PackageDocArg1>{ID}("."{ID})* { // handle argument
+ current->name = yytext;
+ BEGIN( Comment );
+ }
+<PackageDocArg1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<PackageDocArg1>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Warning: missing argument after "
+ "\\package."
+ );
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<PackageDocArg1>. { // ignore other stuff
+ }
+
+ /* ------ handle argument of class/struct/union command --------------- */
+
+<ClassDocArg1>{SCOPENAME} { // first argument
+ current->name = yytext;
+ if (current->section==Entry::PROTOCOLDOC_SEC)
+ {
+ current->name+="-p";
+ }
+ // prepend outer scope name
+ prependScope();
+ BEGIN( ClassDocArg2 );
+ }
+<CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" {
+ current->name = yytext;
+ prependScope();
+ BEGIN( ClassDocArg2 );
+ }
+<ClassDocArg1,CategoryDocArg1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<ClassDocArg1,CategoryDocArg1>{DOCNL} {
+ warn(yyFileName,yyLineNr,
+ "Warning: missing argument after "
+ "\\%s.",YY_START==ClassDocArg1?"class":"category"
+ );
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<ClassDocArg1,CategoryDocArg1>. { // ignore other stuff
+ }
+
+<ClassDocArg2>{FILE} { // second argument; include file
+ current->includeFile = stripQuotes(yytext);
+ BEGIN( ClassDocArg3 );
+ }
+<ClassDocArg2>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<ClassDocArg2>{DOCNL} {
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<ClassDocArg2>. { // ignore other stuff
+ }
+
+<ClassDocArg3>[<]?{FILE}[>]? { // third argument; include file name
+ current->includeName = yytext;
+ BEGIN( Comment );
+ }
+<ClassDocArg3>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<ClassDocArg3>{DOCNL} {
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<ClassDocArg3>. { // ignore other stuff
+ }
+
+ /* --------- handle arguments of {def,add,weak}group commands --------- */
+
+<GroupDocArg1>{ID}(".html"?) { // group name
+ current->name = yytext;
+ //lastDefGroup.groupname = yytext;
+ //lastDefGroup.pri = current->groupingPri();
+ // the .html stuff is for Qt compatibility
+ if (current->name.right(5)==".html")
+ {
+ current->name=current->name.left(current->name.length()-5);
+ }
+ BEGIN(GroupDocArg2);
+ }
+<GroupDocArg1>"\\"{B}*"\n" { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<GroupDocArg1>{DOCNL} { // missing argument!
+ warn(yyFileName,yyLineNr,
+ "Warning: missing group name after %s",
+ current->groupDocCmd()
+ );
+ addOutput('\n');
+ if (*yytext=='\n') yyLineNr++;
+ BEGIN( Comment );
+ }
+<GroupDocArg2>"\\"{B}*"\n" { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<GroupDocArg2>[^\n\\\*]+ { // title (stored in type)
+ current->type += yytext;
+ current->type = current->type.stripWhiteSpace();
+ }
+<GroupDocArg2>{DOCNL} {
+ if ( current->groupDocType==Entry::GROUPDOC_NORMAL &&
+ current->type.isEmpty()
+ ) // defgroup requires second argument
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: missing title after "
+ "\\defgroup %s", current->name.data()
+ );
+ }
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+
+ /* --------- handle arguments of page/mainpage command ------------------- */
+
+<PageDocArg1>{FILE} { // first argument; page name
+ current->name = stripQuotes(yytext);
+ BEGIN( PageDocArg2 );
+ }
+<PageDocArg1>{LC} { yyLineNr++;
+ addOutput('\n');
+ }
+<PageDocArg1>{DOCNL} {
+ warn(yyFileName,yyLineNr,
+ "Warning: missing argument after "
+ "\\page."
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<PageDocArg1>. { // ignore other stuff
+ }
+<PageDocArg2>.*"\n" { // second argument; page title
+ yyLineNr++;
+ current->args = yytext;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+
+ /* --------- handle arguments of the file/dir/example command ------------ */
+
+<FileDocArg1>{FILE} { // first argument; name
+ current->name = stripQuotes(yytext);
+ BEGIN( Comment );
+ }
+<FileDocArg1>{LC} { yyLineNr++;
+ addOutput('\n');
+ }
+<FileDocArg1>{DOCNL} { // no file name specfied
+ current->name = yyFileName;
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<FileDocArg1>. { // ignore other stuff
+ }
+
+ /* --------- handle arguments of the xrefitem command ------------ */
+
+<XRefItemParam1>{ID} { // first argument
+ xrefItemKey=yytext;
+ BEGIN(XRefItemParam2);
+ }
+<XRefItemParam1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<XRefItemParam1>{DOCNL} { // missing arguments
+ warn(yyFileName,yyLineNr,
+ "Warning: Missing first argument of \\xrefitem"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ inContext = OutputDoc;
+ BEGIN( Comment );
+ }
+<XRefItemParam1>. { // ignore other stuff
+ }
+
+<XRefItemParam2>"\""[^\n\"]*"\"" { // second argument
+ xrefItemTitle = stripQuotes(yytext);
+ BEGIN(XRefItemParam3);
+ }
+<XRefItemParam2>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<XRefItemParam2>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Warning: Missing second argument of \\xrefitem"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ inContext = OutputDoc;
+ BEGIN( Comment );
+ }
+<XRefItemParam2>. { // ignore other stuff
+ }
+
+<XRefItemParam3>"\""[^\n\"]*"\"" { // third argument
+ xrefListTitle = stripQuotes(yytext);
+ BEGIN( Comment );
+ }
+<XRefItemParam2>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<XRefItemParam3>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Warning: Missing third argument of \\xrefitem"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ inContext = OutputDoc;
+ BEGIN( Comment );
+ }
+<XRefItemParam3>. { // ignore other stuff
+ }
+
+
+ /* --------- handle arguments of the relates(also) command ------------ */
+
+<RelatesParam1>({ID}("::"|"."))*{ID} { // argument
+ current->relates = yytext;
+ //if (current->mGrpId!=DOX_NOGROUP)
+ //{
+ // memberGroupRelates = yytext;
+ //}
+ BEGIN( Comment );
+ }
+<RelatesParam1>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<RelatesParam1>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Warning: Missing argument of \\relates command"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<RelatesParam1>. { // ignore other stuff
+ }
+
+
+ /* ----- handle arguments of the relates(also)/addindex commands ----- */
+
+<LineParam>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<LineParam>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<LineParam>. { // ignore other stuff
+ addOutput(*yytext);
+ }
+
+ /* ----- handle arguments of the section/subsection/.. commands ------- */
+
+<SectionLabel>{LABELID} { // first argyment
+ sectionLabel=yytext;
+ sectionTitle.resize(0);
+ current->doc+=yytext;
+ BEGIN(SectionTitle);
+ }
+<SectionLabel>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Warning: \\section command has no label"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<SectionLabel>. { // invalid character for section label
+ warn(yyFileName,yyLineNr,
+ "Warning: Invalid or missing section label"
+ );
+ BEGIN(Comment);
+ }
+
+<SectionTitle>[^\n@\\*]*/"\n" { // end of section title
+ addSection();
+ addOutput(yytext);
+ BEGIN( Comment );
+ }
+<SectionTitle>[^\n@\\]*/"\\_linebr" { // end of section title
+ addSection();
+ addOutput(yytext);
+ BEGIN( Comment );
+ }
+<SectionTitle>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<SectionTitle>[^\n@\\]* { // any character without special meaning
+ sectionTitle+=yytext;
+ current->doc+=yytext;
+ }
+<SectionTitle>("\\\\"|"@@") { // unescape escaped command
+ sectionTitle+=*yytext;
+ current->doc+=*yytext;
+ }
+<SectionTitle>. { // anything else
+ sectionTitle+=yytext;
+ current->doc+=yytext;
+ }
+
+ /* ----- handle arguments of the anchor command ------- */
+
+<AnchorLabel>{LABELID} { // found argument
+ SectionInfo *si = new SectionInfo(yyFileName,yytext,0,SectionInfo::Anchor);
+ Doxygen::sectionDict.insert(yytext,si);
+ current->anchors->append(si);
+ addOutput(yytext);
+ BEGIN( Comment );
+ }
+<AnchorLabel>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Warning: \\anchor command has no label"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<AnchorLabel>. { // invalid character for anchor label
+ warn(yyFileName,yyLineNr,
+ "Warning: Invalid or missing anchor label"
+ );
+ BEGIN(Comment);
+ }
+
+
+ /* ----- handle arguments of the preformatted block commands ------- */
+
+<FormatBlock>{CMD}("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddot"|"endcode")/{NW} { // possible ends
+ addOutput(yytext);
+ if (&yytext[4]==blockName) // found end of the block
+ {
+ BEGIN(Comment);
+ }
+ }
+<FormatBlock>[^ \@\\\n]* { // some word
+ addOutput(yytext);
+ }
+<FormatBlock>{DOCNL} { // new line
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ }
+<FormatBlock>. {
+ addOutput(*yytext);
+ }
+<FormatBlock><<EOF>> {
+ warn(yyFileName,yyLineNr,
+ "Warning: reached end of comment while inside a @%s block; check for missing @end%s tag!",
+ blockName.data(),blockName.data()
+ );
+ yyterminate();
+ }
+
+ /* ----- handle arguments of if/ifnot commands ------- */
+
+<GuardParam>{LABELID} { // parameter of if/ifnot guard
+ bool sectionEnabled = Config_getList("ENABLED_SECTIONS").find(yytext)!=-1;
+ bool parentEnabled = TRUE;
+ if (!guards.isEmpty()) parentEnabled = guards.top()->isEnabled();
+ if (parentEnabled)
+ {
+ if (
+ (sectionEnabled && guardType==Guard_If) ||
+ (!sectionEnabled && guardType==Guard_IfNot)
+ ) // section is visible
+ {
+ guards.push(new GuardedSection(TRUE,TRUE));
+ BEGIN( Comment );
+ }
+ else // section is invisible
+ {
+ guards.push(new GuardedSection(FALSE,TRUE));
+ BEGIN( SkipGuardedSection );
+ }
+ }
+ else // invisible because of parent
+ {
+ guards.push(new GuardedSection(FALSE,FALSE));
+ BEGIN( SkipGuardedSection );
+ }
+ }
+<GuardParam>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<GuardParam>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<GuardParam>. { // ignore other stuff
+ addOutput(*yytext);
+ }
+
+ /* ----- handle skipping of conditional sections ------- */
+
+<SkipGuardedSection>{CMD}"ifnot"/{NW} {
+ guardType = Guard_IfNot;
+ BEGIN( GuardParam );
+ }
+<SkipGuardedSection>{CMD}"if"/{NW} {
+ guardType = Guard_If;
+ BEGIN( GuardParam );
+ }
+<SkipGuardedSection>{CMD}"endif"/{NW} {
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: found @endif without matching start command");
+ }
+ else
+ {
+ delete guards.pop();
+ BEGIN( Comment );
+ }
+ }
+<SkipGuardedSection>{CMD}"else"/{NW}] {
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: found @else without matching start command");
+ }
+ else
+ {
+ if (guards.top()->parentVisible())
+ {
+ delete guards.pop();
+ guards.push(new GuardedSection(TRUE,TRUE));
+ BEGIN( Comment );
+ }
+ }
+ }
+<SkipGuardedSection>{CMD}"elseif"/{NW} {
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: found @elseif without matching start command");
+ }
+ else
+ {
+ if (guards.top()->parentVisible())
+ {
+ delete guards.pop();
+ BEGIN( GuardParam );
+ }
+ }
+ }
+<SkipGuardedSection>{DOCNL} { // skip line
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ }
+<SkipGuardedSection>[^ \\@\n]+ { // skip non-special characters
+ }
+<SkipGuardedSection>. { // any other character
+ }
+
+
+ /* ----- handle skipping of internal section ------- */
+
+<SkipInternal>{DOCNL} { // skip line
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ }
+<SkipInternal>[^ \\@\n]+ { // skip non-special characters
+ }
+<SkipInternal>. { // any other character
+ }
+
+
+ /* ----- handle argument of name command ------- */
+
+<NameParam>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<NameParam>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ nameHeader+=' ';
+ }
+<NameParam>. { // ignore other stuff
+ nameHeader+=*yytext;
+ }
+
+ /* ----- handle argument of ingroup command ------- */
+
+<InGroupParam>{ID} { // group id
+ current->groups->append(
+ new Grouping(yytext, Grouping::GROUPING_INGROUP)
+ );
+ BEGIN( Comment );
+ }
+<InGroupParam>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Warning: Missing group name for \\ingroup command"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<InGroupParam>{LC} { // line continuation
+ yyLineNr++;
+ addOutput('\n');
+ }
+<InGroupParam>. { // ignore other stuff
+ addOutput(*yytext);
+ }
+
+ /* ----- handle argument of fn command ------- */
+
+<FnParam>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ parsePrototype(functionProto);
+ BEGIN( Comment );
+ }
+<FnParam>{LC} { // line continuation
+ yyLineNr++;
+ functionProto+=' ';
+ }
+<FnParam>[^@\\\n]+ { // non-special characters
+ functionProto+=yytext;
+ }
+<FnParam>. { // add other stuff
+ functionProto+=*yytext;
+ }
+
+
+ /* ----- handle argument of overload command ------- */
+
+
+<OverloadParam>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ if (functionProto.stripWhiteSpace().isEmpty())
+ { // plain overload command
+ addOutput(getOverloadDocs());
+ }
+ else // overload declaration
+ {
+ makeStructuralIndicator(Entry::OVERLOADDOC_SEC);
+ parsePrototype(functionProto);
+ }
+ BEGIN( Comment );
+ }
+<OverloadParam>{LC} { // line continuation
+ yyLineNr++;
+ functionProto+=' ';
+ }
+<OverloadParam>. { // add other stuff
+ functionProto+=*yytext;
+ }
+
+ /* ----- handle argument of inherit command ------- */
+
+<InheritParam>({ID}("::"|"."))*{ID} { // found argument
+ current->extends->append(
+ new BaseInfo(removeRedundantWhiteSpace(yytext),Public,Normal)
+ );
+ BEGIN( Comment );
+ }
+<InheritParam>{DOCNL} { // missing argument
+ warn(yyFileName,yyLineNr,
+ "Warning: \\inherit command has no argument"
+ );
+ if (*yytext=='\n') yyLineNr++;
+ addOutput('\n');
+ BEGIN( Comment );
+ }
+<InheritParam>. { // invalid character for anchor label
+ warn(yyFileName,yyLineNr,
+ "Warning: Invalid or missing name for \\inherit command"
+ );
+ BEGIN(Comment);
+ }
+
+%%
+
+//----------------------------------------------------------------------------
+
+static void handleBrief(const QCString &)
+{
+ //printf("handleBrief\n");
+ setOutput(OutputBrief);
+}
+
+static void handleFn(const QCString &)
+{
+ makeStructuralIndicator(Entry::MEMBERDOC_SEC);
+ functionProto.resize(0);
+ BEGIN(FnParam);
+}
+
+static void handleDef(const QCString &)
+{
+ makeStructuralIndicator(Entry::DEFINEDOC_SEC);
+ functionProto.resize(0);
+ BEGIN(FnParam);
+}
+
+static void handleOverload(const QCString &)
+{
+ functionProto.resize(0);
+ BEGIN(OverloadParam);
+}
+
+static void handleEnum(const QCString &)
+{
+ makeStructuralIndicator(Entry::ENUMDOC_SEC);
+ BEGIN(EnumDocArg1);
+}
+
+static void handleDefGroup(const QCString &)
+{
+ makeStructuralIndicator(Entry::GROUPDOC_SEC);
+ current->groupDocType = Entry::GROUPDOC_NORMAL;
+ BEGIN( GroupDocArg1 );
+}
+
+static void handleAddToGroup(const QCString &)
+{
+ makeStructuralIndicator(Entry::GROUPDOC_SEC);
+ current->groupDocType = Entry::GROUPDOC_ADD;
+ BEGIN( GroupDocArg1 );
+}
+
+static void handleWeakGroup(const QCString &)
+{
+ makeStructuralIndicator(Entry::GROUPDOC_SEC);
+ current->groupDocType = Entry::GROUPDOC_WEAK;
+ BEGIN( GroupDocArg1 );
+}
+
+static void handleNamespace(const QCString &)
+{
+ makeStructuralIndicator(Entry::NAMESPACEDOC_SEC);
+ BEGIN( NameSpaceDocArg1 );
+}
+
+static void handlePackage(const QCString &)
+{
+ makeStructuralIndicator(Entry::PACKAGEDOC_SEC);
+ BEGIN( PackageDocArg1 );
+}
+
+static void handleClass(const QCString &)
+{
+ makeStructuralIndicator(Entry::CLASSDOC_SEC);
+ BEGIN( ClassDocArg1 );
+}
+
+static void handleProtocol(const QCString &)
+{ // Obj-C protocol
+ makeStructuralIndicator(Entry::PROTOCOLDOC_SEC);
+ BEGIN( ClassDocArg1 );
+}
+
+static void handleCategory(const QCString &)
+{ // Obj-C category
+ makeStructuralIndicator(Entry::CATEGORYDOC_SEC);
+ BEGIN( CategoryDocArg1 );
+}
+
+static void handleUnion(const QCString &)
+{
+ makeStructuralIndicator(Entry::UNIONDOC_SEC);
+ BEGIN( ClassDocArg1 );
+}
+
+static void handleStruct(const QCString &)
+{
+ makeStructuralIndicator(Entry::STRUCTDOC_SEC);
+ BEGIN( ClassDocArg1 );
+}
+
+static void handleInterface(const QCString &)
+{
+ makeStructuralIndicator(Entry::INTERFACEDOC_SEC);
+ BEGIN( ClassDocArg1 );
+}
+
+static void handleIdlException(const QCString &)
+{
+ makeStructuralIndicator(Entry::EXCEPTIONDOC_SEC);
+ BEGIN( ClassDocArg1 );
+}
+
+static void handlePage(const QCString &)
+{
+ makeStructuralIndicator(Entry::PAGEDOC_SEC);
+ BEGIN( PageDocArg1 );
+}
+
+static void handleMainpage(const QCString &)
+{
+ makeStructuralIndicator(Entry::MAINPAGEDOC_SEC);
+ current->name = "mainpage";
+ BEGIN( PageDocArg2 );
+}
+
+static void handleFile(const QCString &)
+{
+ makeStructuralIndicator(Entry::FILEDOC_SEC);
+ BEGIN( FileDocArg1 );
+}
+
+static void handleDir(const QCString &)
+{
+ makeStructuralIndicator(Entry::DIRDOC_SEC);
+ BEGIN( FileDocArg1 );
+}
+
+static void handleExample(const QCString &)
+{
+ makeStructuralIndicator(Entry::EXAMPLE_SEC);
+ BEGIN( FileDocArg1 );
+}
+
+static void handleDetails(const QCString &)
+{
+ setOutput(OutputDoc);
+}
+
+static void handleName(const QCString &)
+{
+ makeStructuralIndicator(Entry::MEMBERGRP_SEC);
+ nameHeader.resize(0);
+ BEGIN( NameParam );
+}
+
+static void handleTodo(const QCString &)
+{
+ xrefKind = XRef_Todo;
+ setOutput(OutputXRef);
+}
+
+static void handleTest(const QCString &)
+{
+ xrefKind = XRef_Test;
+ setOutput(OutputXRef);
+}
+
+static void handleBug(const QCString &)
+{
+ xrefKind = XRef_Bug;
+ setOutput(OutputXRef);
+}
+
+static void handleDeprecated(const QCString &)
+{
+ xrefKind = XRef_Deprecated;
+ setOutput(OutputXRef);
+}
+
+static void handleXRefItem(const QCString &)
+{
+ xrefKind = XRef_Item;
+ setOutput(OutputXRef);
+ BEGIN(XRefItemParam1);
+}
+
+static void handleRelated(const QCString &)
+{
+ BEGIN(RelatesParam1);
+}
+
+static void handleRelatedAlso(const QCString &)
+{
+ current->relatesDup = TRUE;
+ BEGIN(RelatesParam1);
+}
+
+static void handleRefItem(const QCString &)
+{
+ addOutput("@refitem ");
+ BEGIN(LineParam);
+}
+
+static void handleSection(const QCString &s)
+{
+ addOutput("@"+s+" ");
+ BEGIN(SectionLabel);
+}
+
+static void handleAnchor(const QCString &)
+{
+ BEGIN(AnchorLabel);
+}
+
+static void handleFormatBlock(const QCString &s)
+{
+ addOutput("@"+s+" ");
+ //printf("handleFormatBlock(%s)\n",s.data());
+ blockName=s;
+ BEGIN(FormatBlock);
+}
+
+static void handleAddIndex(const QCString &)
+{
+ addOutput("@addindex ");
+ BEGIN(LineParam);
+}
+
+static void handleIf(const QCString &)
+{
+ guardType = Guard_If;
+ BEGIN(GuardParam);
+}
+
+static void handleIfNot(const QCString &)
+{
+ guardType = Guard_IfNot;
+ BEGIN(GuardParam);
+}
+
+static void handleElseIf(const QCString &)
+{
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: found @else without matching start command");
+ }
+ else
+ {
+ guardType = Guard_If;
+ BEGIN(GuardParam);
+ }
+}
+
+static void handleElse(const QCString &)
+{
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: found @else without matching start command");
+ }
+ else
+ {
+ BEGIN( SkipGuardedSection );
+ }
+}
+
+static void handleEndIf(const QCString &)
+{
+ if (guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: found @endif without matching start command");
+ }
+ else
+ {
+ delete guards.pop();
+ }
+}
+
+static void handleIngroup(const QCString &)
+{
+ BEGIN( InGroupParam );
+}
+
+static void handleNoSubGrouping(const QCString &)
+{
+ current->subGrouping = FALSE;
+}
+
+static void handleShowInitializer(const QCString &)
+{
+ current->initLines = 100000; // ON
+}
+
+static void handleHideInitializer(const QCString &)
+{
+ current->initLines = 0; // OFF
+}
+
+static void handleCallgraph(const QCString &)
+{
+ current->callGraph = TRUE; // ON
+}
+
+static void handleInternal(const QCString &)
+{
+ if (!Config_getBool("INTERNAL_DOCS"))
+ {
+ BEGIN( SkipInternal );
+ }
+ else
+ {
+ addOutput("\\internal ");
+ }
+}
+
+static void handleLineBr(const QCString &)
+{
+ addOutput('\n');
+}
+
+static void handleStatic(const QCString &)
+{
+ current->stat = TRUE;
+}
+
+static void handlePure(const QCString &)
+{
+ current->virt = Pure;
+}
+
+static void handlePrivate(const QCString &)
+{
+ current->protection = Private;
+}
+
+static void handlePrivateSection(const QCString &)
+{
+ current->protection = protection = Private;
+}
+
+static void handleProtected(const QCString &)
+{
+ current->protection = Protected;
+}
+
+static void handleProtectedSection(const QCString &)
+{
+ current->protection = protection = Protected ;
+}
+
+static void handlePublic(const QCString &)
+{
+ current->protection = Public;
+}
+
+static void handlePublicSection(const QCString &)
+{
+ current->protection = protection = Public;
+}
+
+static void handleInherit(const QCString &)
+{
+ BEGIN(InheritParam);
+}
+
+//----------------------------------------------------------------------------
+
+static void checkFormula()
+{
+ if (YY_START==ReadFormulaShort || YY_START==ReadFormulaLong)
+ {
+ warn(yyFileName,yyLineNr,"Warning: End of comment block while inside formula.");
+ }
+}
+
+//----------------------------------------------------------------------------
+
+bool parseCommentBlock(/* in,out */ Entry *curEntry,
+ /* in */ const QCString &comment,
+ /* in */ const QCString &fileName,
+ /* in */ int lineNr,
+ /* in */ bool isBrief,
+ /* in */ bool isJavaDocStyle,
+ /* in,out */ Protection &prot
+ )
+{
+ //fprintf(stderr,"isBrief=%d isJavaDocStyle=%d\n",
+ // isBrief,isJavaDocStyle);
+ initParser();
+ guards.setAutoDelete(TRUE);
+ guards.clear();
+ //current_root = rootEntry;
+ current = curEntry;
+ //previous = prevEntry;
+ inputString = comment;
+ inputPosition = 0;
+ yyLineNr = lineNr;
+ yyFileName = fileName;
+ //inBody = foundInBody;
+ protection = prot;
+ needNewEntry = FALSE;
+ setOutput( isBrief || isJavaDocStyle ? OutputBrief : OutputDoc );
+ briefEndsAtDot = isJavaDocStyle;
+ commentScanYYrestart( commentScanYYin );
+ BEGIN( Comment );
+ commentScanYYlex();
+ setOutput( OutputDoc );
+
+ if (!guards.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!");
+ }
+
+ if (current->section==Entry::FILEDOC_SEC && current->doc.isEmpty())
+ {
+ // to allow a comment block with just a @file command.
+ current->doc="\n\n";
+ }
+
+ checkFormula();
+ prot = protection;
+
+ return needNewEntry;
+}
+
+#if 0
+//----------------------------------------------------------------------------
+void commentScanTest()
+{
+ Entry *ce = new Entry;
+ Entry *pe = new Entry;
+ Entry *re = new Entry;
+ Protection prot=Public;
+
+ ce->doc.resize(0);ce->brief.resize(0);
+ parseCommentBlock(ce,pe,re,"@brief A brief description.\n\n"
+ "This is a @e simple test!\n","test.dox",
+ 1,FALSE,FALSE,FALSE,prot);
+ printf("---------\nbrief test: result: brief=[%s] doc=[%s]\n",ce->brief.data(),ce->doc.data());
+
+ ce->doc.resize(0);ce->brief.resize(0);
+ parseCommentBlock(ce,pe,re,"@defgroup grp A group\n"
+ "This is a @c group definition.","test.dox",
+ 1,FALSE,FALSE,FALSE,prot);
+ printf("---------\ndefgroup test: result: brief=[%s] doc=[%s]\n",ce->brief.data(),ce->doc.data());
+
+ ce->doc.resize(0);ce->brief.resize(0);
+ parseCommentBlock(ce,pe,re,"A code example:\n"
+ "@code\n"
+ "void main()\n"
+ "{\n"
+ " printf(\"Hello world\");\n"
+ "}\n"
+ "@endcode\n"
+ "More text follows.","test.dox",
+ 1,FALSE,FALSE,FALSE,prot);
+ printf("---------\ncode test: result: brief=[%s] doc=[%s]\n",ce->brief.data(),ce->doc.data());
+
+ ce->doc.resize(0);ce->brief.resize(0);
+ parseCommentBlock(ce,pe,re,"Some text <!-- A comment --> and more.\n"
+ ,"test.dox",
+ 1,FALSE,FALSE,FALSE,prot);
+ printf("---------\nhtml comment test: result: brief=[%s] doc=[%s]\n",ce->brief.data(),ce->doc.data());
+
+}
+#endif
+
+#if !defined(YY_FLEX_SUBMINOR_VERSION)
+//----------------------------------------------------------------------------
+extern "C" { // some bogus code to keep the compiler happy
+ void commentScanYYdummy() { yy_flex_realloc(0,0); }
+}
+#endif
+