summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authordimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2005-01-29 11:51:21 (GMT)
committerdimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2005-01-29 11:51:21 (GMT)
commitc635cffd1d8bcf5bcbe90ce2c3c5fc3371e01a1c (patch)
tree5d48c44b9a2f19b38592c2cb51a919ebd456c8fb /src
parent13feb604f3aa783f927ed47df8e4c561a8d8032a (diff)
downloadDoxygen-c635cffd1d8bcf5bcbe90ce2c3c5fc3371e01a1c.zip
Doxygen-c635cffd1d8bcf5bcbe90ce2c3c5fc3371e01a1c.tar.gz
Doxygen-c635cffd1d8bcf5bcbe90ce2c3c5fc3371e01a1c.tar.bz2
Release-1.4.1-20050129
Diffstat (limited to 'src')
-rw-r--r--src/code.l9
-rw-r--r--src/commentscan.h31
-rw-r--r--src/commentscan.l1915
-rw-r--r--src/doctokenizer.l6
-rw-r--r--src/dot.cpp9
-rw-r--r--src/doxygen.cpp4
-rw-r--r--src/htmldocvisitor.cpp2
-rw-r--r--src/index.xsd4
-rw-r--r--src/index_xsd.h4
-rw-r--r--src/language.cpp4
-rw-r--r--src/libdoxygen.pro.in5
-rw-r--r--src/pre.l6
-rw-r--r--src/scanner.h10
-rw-r--r--src/scanner.l302
14 files changed, 2289 insertions, 22 deletions
diff --git a/src/code.l b/src/code.l
index 249e180..cdcd53a 100644
--- a/src/code.l
+++ b/src/code.l
@@ -2395,7 +2395,14 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
g_code->codify(yytext);
if (--g_bracketCount<=0)
{
- BEGIN( CallEnd );
+ if (g_name.isEmpty())
+ {
+ BEGIN( Body );
+ }
+ else
+ {
+ BEGIN( CallEnd );
+ }
}
}
<CallEnd>[ \t\n]* { codifyLines(yytext); }
diff --git a/src/commentscan.h b/src/commentscan.h
new file mode 100644
index 0000000..d954a93
--- /dev/null
+++ b/src/commentscan.h
@@ -0,0 +1,31 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ */
+
+#ifndef COMMENTSCAN_H
+#define COMMENTSCAN_H
+
+#include "qtbc.h"
+#include "entry.h"
+
+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
+ );
+
+#endif
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
+
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 5b14d35..e77f1b2 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -308,9 +308,11 @@ OPMASK ({BLANK}*{OPNORM}{FUNCARG})|({OPCAST}{FUNCARG})
LNKWORD1 ("::"|"#")?{SCOPEMASK}
CVSPEC {BLANK}*("const"|"volatile")
LNKWORD2 {SCOPEPRE}*"operator"{OPMASK}
-WORD1 [^ \t\n\r\\@<>()\[\]:;\?{}&$#,.]+|"{"|"}"|("\""[^"\n]*"\"")
+CHARWORD [^ \t\n\r\\@<>()\[\]:;\?{}&%$#,.]
+CHARWORDQ [^ \t\n\r\\@<>()\[\]:;\?{}&%$#,."]
+WORD1 "%"?{CHARWORD}+|"{"|"}"|("\""[^"\n]*"\"")
WORD2 "."|","|"("|")"|"["|"]"|":"|";"|"\?"
-WORD1NQ [^ \t\n\r\\@<>()\[\]:;\?{}&$#,."]+
+WORD1NQ "%"?{CHARWORDQ}+
WORD2NQ "."|","|"("|")"|"["|"]"|":"|";"|"\?"
HTMLTAG "<"(("/")?){ID}({WS}+{ATTRIB})*{WS}*">"
HTMLKEYL "strong"|"center"|"table"|"caption"|"small"|"code"|"dfn"|"var"|"img"|"pre"|"sub"|"sup"|"tr"|"td"|"th"|"ol"|"ul"|"li"|"tt"|"kbd"|"em"|"hr"|"dl"|"dt"|"dd"|"br"|"i"|"a"|"b"|"p"
diff --git a/src/dot.cpp b/src/dot.cpp
index c2eb310..d13a7ff 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -566,10 +566,11 @@ static QCString convertLabel(const QCString &l)
switch(c)
{
case '\\': result+="\\\\"; break;
- case '<': result+="\\<"; break;
- case '>': result+="\\>"; break;
- case '|': result+="\\|"; break;
- default: result+=c; break;
+ case '<': result+="\\<"; break;
+ case '>': result+="\\>"; break;
+ case '|': result+="\\|"; break;
+ case '"': result+="\\\""; break;
+ default: result+=c; break;
}
}
return result;
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 03fdbfe..44c7796 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -7839,7 +7839,7 @@ static const char *getArg(int argc,char **argv,int &optind)
//----------------------------------------------------------------------------
-//extern void commentScanTest();
+extern void commentScanTest();
void initDoxygen()
{
@@ -7868,8 +7868,6 @@ void initDoxygen()
Doxygen::lookupCache.setAutoDelete(TRUE);
Doxygen::directories.setAutoDelete(TRUE);
Doxygen::dirRelations.setAutoDelete(TRUE);
-
- // commentScanTest();
}
void cleanUpDoxygen()
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index 542745d..33de0e3 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -722,7 +722,7 @@ void HtmlDocVisitor::visitPre(DocImage *img)
}
m_t << "<div align=\"center\">" << endl;
m_t << "<img src=\"" << img->relPath() << img->name() << "\" alt=\""
- << baseName << "\"" << htmlAttribsToString(img->attribs()) << ">" << endl;
+ << baseName << "\"" << ">" << endl;
if (img->hasCaption())
{
m_t << "<p><strong>";
diff --git a/src/index.xsd b/src/index.xsd
index 0e145c1..d7ab2a9 100644
--- a/src/index.xsd
+++ b/src/index.xsd
@@ -14,7 +14,7 @@
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="member" type="MemberType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
- <xsd:attribute name="refid" type="xsd:Name" use="required"/>
+ <xsd:attribute name="refid" type="xsd:string" use="required"/>
<xsd:attribute name="kind" type="CompoundKind" use="required"/>
</xsd:complexType>
@@ -22,7 +22,7 @@
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
</xsd:sequence>
- <xsd:attribute name="refid" type="xsd:Name" use="required"/>
+ <xsd:attribute name="refid" type="xsd:string" use="required"/>
<xsd:attribute name="kind" type="MemberKind" use="required"/>
</xsd:complexType>
diff --git a/src/index_xsd.h b/src/index_xsd.h
index 6a3b3da..2f5d0c5 100644
--- a/src/index_xsd.h
+++ b/src/index_xsd.h
@@ -14,7 +14,7 @@
" <xsd:element name=\"name\" type=\"xsd:string\"/>\n"
" <xsd:element name=\"member\" type=\"MemberType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n"
" </xsd:sequence>\n"
-" <xsd:attribute name=\"refid\" type=\"xsd:Name\" use=\"required\"/>\n"
+" <xsd:attribute name=\"refid\" type=\"xsd:string\" use=\"required\"/>\n"
" <xsd:attribute name=\"kind\" type=\"CompoundKind\" use=\"required\"/>\n"
" </xsd:complexType>\n"
"\n"
@@ -22,7 +22,7 @@
" <xsd:sequence>\n"
" <xsd:element name=\"name\" type=\"xsd:string\"/>\n"
" </xsd:sequence>\n"
-" <xsd:attribute name=\"refid\" type=\"xsd:Name\" use=\"required\"/>\n"
+" <xsd:attribute name=\"refid\" type=\"xsd:string\" use=\"required\"/>\n"
" <xsd:attribute name=\"kind\" type=\"MemberKind\" use=\"required\"/>\n"
" </xsd:complexType>\n"
" \n"
diff --git a/src/language.cpp b/src/language.cpp
index 8bb6b88..8b8f426 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -182,6 +182,8 @@ bool setTranslator(const char *langName)
{
theTranslator=new TranslatorJapanese;
}
+#endif
+#ifdef LANG_JE
else if (L_EQUAL("japanese-en"))
{
theTranslator=new TranslatorJapaneseEn;
@@ -236,6 +238,8 @@ bool setTranslator(const char *langName)
{
theTranslator=new TranslatorKorean;
}
+#endif
+#ifdef LANG_KE
else if (L_EQUAL("korean-en"))
{
theTranslator=new TranslatorKoreanEn;
diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in
index 4a1b5cd..55b97ab 100644
--- a/src/libdoxygen.pro.in
+++ b/src/libdoxygen.pro.in
@@ -22,6 +22,7 @@ HEADERS = bufstr.h \
cmdmapper.h \
code.h \
commentcnv.h \
+ commentscan.h \
compound_xsd.h \
config.h \
constexp.h \
@@ -183,8 +184,8 @@ SOURCES = ce_lex.cpp \
util.cpp \
version.cpp \
xmldocvisitor.cpp \
- xmlgen.cpp
-# commentscan.cpp
+ xmlgen.cpp \
+ commentscan.cpp
win32:TMAKE_CXXFLAGS += -DQT_NODLL
win32-msvc:TMAKE_CXXFLAGS += -Zm200
diff --git a/src/pre.l b/src/pre.l
index 8e6c7a8..fdf569d 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -402,12 +402,12 @@ static void returnCharToStream(char c)
static inline void addTillEndOfString(const QCString &expr,QCString *rest,
uint &pos,char term,QCString &arg)
{
- char cc;
+ int cc;
while ((cc=getNextChar(expr,rest,pos))!=EOF)
{
- if (cc=='\\') arg+=cc,cc=getNextChar(expr,rest,pos);
+ if (cc=='\\') arg+=(char)cc,cc=getNextChar(expr,rest,pos);
else if (cc==term) return;
- arg+=cc;
+ arg+=(char)cc;
}
}
diff --git a/src/scanner.h b/src/scanner.h
index 1fc6416..36abd4d 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -23,7 +23,13 @@
class OutputList;
class Entry;
-extern void parseMain(Entry *);
-extern void parseMain(Entry *,const char *fileName);
+// Public interface provided by the language scanner
+void parseMain(Entry *);
+void parseMain(Entry *,const char *fileName);
+
+// Internal callback interface for comment block scanner
+void parsePrototype(const QCString &text);
+void handleGroupStartCommand(const char *header);
+void handleGroupEndCommand();
#endif
diff --git a/src/scanner.l b/src/scanner.l
index a42e86d..0c04c87 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -45,7 +45,9 @@
#include "membergroup.h"
#include "reflist.h"
#include "code.h"
+#include "commentscan.h"
+#define COMMENTSCAN
#define YY_NEVER_INTERACTIVE 1
@@ -176,6 +178,12 @@ static QCString docBackup;
static QCString briefBackup;
static bool g_inputFromFile;
+static int docBlockContext;
+static QCString docBlock;
+static QCString docBlockName;
+static bool docBlockInBody;
+static bool docBlockJavaStyle;
+
//-----------------------------------------------------------------------------
@@ -257,7 +265,9 @@ static int newMemberGroupId()
}
// forward declarations
+#ifndef COMMENTSCAN
static void startGroup();
+#endif
static void startGroupInDoc();
static void endGroup();
@@ -305,6 +315,74 @@ static void newDocState();
//-----------------------------------------------------------------
+static void addMemberGroupDocs()
+{
+ memberGroupDocs=current->brief.stripWhiteSpace();
+ current->doc = current->doc.stripWhiteSpace();
+ if (!memberGroupDocs.isEmpty() && !current->doc.isEmpty())
+ {
+ memberGroupDocs+="\n\n";
+ }
+ memberGroupDocs+=current->doc;
+ MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(memberGroupId);
+ if (info)
+ {
+ info->doc = memberGroupDocs;
+ info->docFile = yyFileName;
+ }
+ current->doc.resize(0);
+ current->brief.resize(0);
+}
+
+//-----------------------------------------------------------------
+
+static void handleCommentBlock(const QCString &doc,bool brief)
+{
+ if (brief)
+ {
+ current->briefFile = yyFileName;
+ current->briefLine = yyLineNr;
+ }
+ else
+ {
+ current->docFile = yyFileName;
+ current->docLine = yyLineNr;
+ }
+ if (docBlockInBody)
+ {
+ if (previous==0)
+ {
+ ASSERT(previous!=0); // shouldn't happen
+ return;
+ }
+ if (!previous->doc.isEmpty())
+ { // start a new paragraph for the next piece of text found in the body
+ previous->doc=previous->doc.stripWhiteSpace()+"\n\n";
+ }
+ }
+ if (parseCommentBlock(
+ docBlockInBody ? previous : current,
+ doc, // text
+ yyFileName, // file
+ yyLineNr, // line
+ docBlockInBody ? FALSE : brief,
+ docBlockInBody ? FALSE : docBlockJavaStyle,
+ protection)
+ ) // need to start a new entry
+ {
+ if (current->section==Entry::MEMBERGRP_SEC)
+ {
+ addMemberGroupDocs();
+ }
+ current_root->addSubEntry(current);
+ previous = current;
+ current = new Entry ;
+ initEntry();
+ }
+}
+
+//-----------------------------------------------------------------
+
static void addXRefItem(bool inBody,const char *listName,const char *itemTitle,const char *listTitle)
{
Entry *docEntry = inBody && previous ? previous : current;
@@ -617,6 +695,7 @@ static void addKnRArgInfo(const QCString &type,const QCString &name,
}
}
+//-----------------------------------------------------------------------------
/* ----------------------------------------------------------------- */
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
@@ -849,6 +928,12 @@ IDLATTR ("["[^\]]*"]"){BN}*
%x ReadFormulaLong
%x AnchorLabel
+ /** new comment parsing states */
+
+%x DocLine
+%x DocBlock
+%x DocCopyBlock
+
%%
<*>\x06[^\x06]*\x06 { // new file
@@ -2036,7 +2121,11 @@ IDLATTR ("["[^\]]*"]"){BN}*
BEGIN(AfterDoc);
}
}
+
<FindMembers,FindFields>("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") {
+#ifdef COMMENTSCAN
+ REJECT;
+#else
startGroup();
tmpDocType=-1;
if (current_root->section & Entry::SCOPE_MASK)
@@ -2064,8 +2153,12 @@ IDLATTR ("["[^\]]*"]"){BN}*
removeSlashes=FALSE;
BEGIN( Doc );
}
+#endif
}
<FindMembers,FindFields,ReadInitializer>"//"([!/]?){B}*{CMD}"}".*|"/*"([!*]?){B}*{CMD}"}".*"*/" {
+#ifdef COMMENTSCAN
+ REJECT;
+#else
if (memberGroupId==DOX_NOGROUP && autoGroupStack.isEmpty())
{
warn(yyFileName,yyLineNr,
@@ -2074,6 +2167,7 @@ IDLATTR ("["[^\]]*"]"){BN}*
//printf("end of member group marker ends group %d\n",memberGroupId);
endGroup();
memberGroupHeader.resize(0);
+#endif
}
<FindMembers>"=" {
current->bodyLine = yyLineNr;
@@ -4043,7 +4137,15 @@ IDLATTR ("["[^\]]*"]"){BN}*
memberGroupInside = current->inside.copy();
}
}
+#ifdef COMMENTSCAN
+ docBlockContext = YY_START;
+ docBlockInBody = YY_START==SkipCurly;
+ docBlockJavaStyle = FALSE;
+ docBlock.resize(0);
+ BEGIN( DocBlock );
+#else
BEGIN( Doc );
+#endif
}
<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator,ClassVar,SkipInits,Bases,OldStyleArgs>("//"{B}*)?"/**"/[^/*] {
removeSlashes=(yytext[1]=='/');
@@ -4057,6 +4159,28 @@ IDLATTR ("["[^\]]*"]"){BN}*
memberGroupInside = current->inside.copy();
}
}
+#ifdef COMMENTSCAN
+ current->docLine = yyLineNr;
+ current->docFile = yyFileName;
+ docBlockContext = YY_START;
+ docBlockInBody = YY_START==SkipCurly;
+ docBlockJavaStyle = Config_getBool("JAVADOC_AUTOBRIEF");
+ docBlock.resize(0);
+ if (docBlockJavaStyle)
+ {
+ current->briefLine = yyLineNr;
+ current->briefFile = yyFileName;
+ }
+ if (!docBlockInBody)
+ {
+ current->doc.resize(0);
+ if (docBlockJavaStyle)
+ {
+ current->brief.resize(0);
+ }
+ }
+ BEGIN( DocBlock );
+#else
if (!Config_getBool("JAVADOC_AUTOBRIEF")) // use the Qt style
{
current->docLine = yyLineNr;
@@ -4095,6 +4219,7 @@ IDLATTR ("["[^\]]*"]"){BN}*
BEGIN( JavaDoc );
}
}
+#endif
}
<FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"//!" {
if (YY_START!=SkipCurly)
@@ -4113,7 +4238,15 @@ IDLATTR ("["[^\]]*"]"){BN}*
memberGroupInside = current->inside.copy();
}
}
+#ifdef COMMENTSCAN
+ docBlockContext = YY_START;
+ docBlockInBody = YY_START==SkipCurly;
+ docBlockJavaStyle = FALSE;
+ docBlock.resize(0);
+ BEGIN( DocLine );
+#else
BEGIN( LineDoc );
+#endif
}
<FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"///"/[^/] {
if (YY_START!=SkipCurly)
@@ -4132,7 +4265,15 @@ IDLATTR ("["[^\]]*"]"){BN}*
memberGroupInside = current->inside.copy();
}
}
+#ifdef COMMENTSCAN
+ docBlockContext = YY_START;
+ docBlockInBody = YY_START==SkipCurly;
+ docBlockJavaStyle = FALSE;
+ docBlock.resize(0);
+ BEGIN( DocLine );
+#else
BEGIN( LineDoc );
+#endif
}
<FindMembers>"extern"{BN}*"\"C"("++")?"\""{BN}*("{")? {
lineCount();
@@ -4200,6 +4341,91 @@ IDLATTR ("["[^\]]*"]"){BN}*
<CSAccessorDecl>"get" { if (curlyCount==0) current->memSpec |= Entry::Gettable; }
<CSAccessorDecl>. {}
<CSAccessorDecl>\n { yyLineNr++; }
+
+
+
+
+ /**********************************************************************************/
+ /******************** Documentation block related rules ***************************/
+ /**********************************************************************************/
+
+ /* ---- Single line comments ------ */
+
+<DocLine>[^\n]*"\n" { // whole line
+ yyLineNr++;
+ handleCommentBlock(yytext,TRUE);
+ BEGIN( docBlockContext );
+ }
+
+ /* ---- Comments blocks ------ */
+
+<DocBlock>"*/" { // end of comment block
+ handleCommentBlock(docBlock,FALSE);
+ BEGIN(docBlockContext);
+ }
+<DocBlock>^{B}*"*"+/{BN}+ { // start of a comment line
+ }
+<DocBlock>("@@"|"\\\\"){ID} { // escaped command
+ docBlock+=yytext;
+ }
+<DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"dot"|"code")/[^a-z_A-Z0-9] { // verbatim command (which could contain nested comments!)
+ docBlock+=yytext;
+ docBlockName=&yytext[1];
+ BEGIN(DocCopyBlock);
+ }
+<DocBlock>[^@*\\\n]+ { // any character that isn't special
+ docBlock+=yytext;
+ }
+<DocBlock>\n { // newline
+ yyLineNr++;
+ docBlock+=*yytext;
+ }
+<DocBlock>. { // command block
+ docBlock+=*yytext;
+ }
+
+ /* ---- Copy verbatim sections ------ */
+
+<DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddot"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
+ docBlock+=yytext;
+ if (&yytext[4]==docBlockName)
+ {
+ BEGIN(DocBlock);
+ }
+ }
+<DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
+ if (docBlockName=="verbatim")
+ {
+ REJECT;
+ }
+ }
+<DocCopyBlock>[^@\*\\\n]+ { // any character that is not special
+ docBlock+=yytext;
+ }
+<DocCopyBlock>\n { // newline
+ docBlock+=*yytext;
+ yyLineNr++;
+ }
+<DocCopyBlock>. { // any other character
+ docBlock+=*yytext;
+ }
+<DocCopyBlock><<EOF>> {
+ warn(yyFileName,yyLineNr,
+ "Warning: reached end of file while inside a %s block!\n",
+ docBlockName.data());
+ yyterminate();
+ }
+
+
+
+
+
+ /*************************************************************************/
+ /*** The next part is obsolete and will be removed */
+
+
+
+
<JavaDoc>{CMD}("brief"|"short"){B}+ {
lastBriefContext=tmpDocType;
BEGIN( ClassDocBrief );
@@ -4211,6 +4437,8 @@ IDLATTR ("["[^\]]*"]"){BN}*
BEGIN( tmpDocType );
}
}
+
+
/*
<JavaDoc>"@" {
unput(*yytext);
@@ -5863,6 +6091,12 @@ IDLATTR ("["[^\]]*"]"){BN}*
current->brief+=yytext;
}
<DefLineDoc,LineDoc,ClassDoc,PageDoc,Doc>"/*"|"//" { current->doc += yytext; }
+
+
+ /**** End of obsolete part */
+ /***********************************************************************/
+
+
<SkipCxxComment>.*/\n {
BEGIN( lastCContext ) ;
}
@@ -5908,6 +6142,7 @@ IDLATTR ("["[^\]]*"]"){BN}*
//----------------------------------------------------------------------------
+#ifndef COMMENTSCAN
static void startGroup()
{
if (!lastDefGroup.groupname.isEmpty())
@@ -5944,6 +6179,7 @@ static void startGroup()
lastMemberGroupLine = yyLineNr;
}
}
+#endif
static void startGroupInDoc()
{
@@ -6221,6 +6457,72 @@ void parseMain(Entry *rt)
#endif
+void parsePrototype(const QCString &text)
+{
+ //printf("**** parsePrototype(%s) begin\n",text.data());
+
+ const char *orgInputString;
+ int orgInputPosition;
+ YY_BUFFER_STATE orgState;
+ bool orgInputFromFile;
+
+ // save scanner state
+ orgState = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_create_buffer(scanYYin, YY_BUF_SIZE));
+ orgInputString = inputString;
+ orgInputPosition = inputPosition;
+ orgInputFromFile = g_inputFromFile;
+
+ // set new string
+ inputString = text;
+ inputPosition = 0;
+ g_inputFromFile = FALSE;
+ scanYYrestart( scanYYin );
+ BEGIN(ClassDocFunc);
+ scanYYlex();
+
+ // restore original scanner state
+ yy_switch_to_buffer(orgState);
+ inputString = orgInputString;
+ inputPosition = orgInputPosition;
+ g_inputFromFile = orgInputFromFile;
+
+ //printf("**** parsePrototype end\n");
+}
+
+Entry *startNewEntry()
+{
+ // make copy of documentation up till now
+ QCString doc = current->doc;
+ QCString brief = current->brief;
+ current->doc.resize(0);
+ current->brief.resize(0);
+
+ // create new entry
+ current_root->addSubEntry(current);
+ previous = current;
+ current = new Entry ;
+ initEntry();
+
+ // move documentation to this entry
+ current->doc = doc;
+ current->brief = brief;
+
+ return current;
+}
+
+void handleGroupStartCommand(const char *header)
+{
+ memberGroupHeader=header;
+ startGroupInDoc();
+}
+
+void handleGroupEndCommand()
+{
+ endGroup();
+}
+
+
//----------------------------------------------------------------------------
#if !defined(YY_FLEX_SUBMINOR_VERSION)