summaryrefslogtreecommitdiffstats
path: root/src/doc.l
diff options
context:
space:
mode:
authordimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2000-08-06 15:11:00 (GMT)
committerdimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2000-08-06 15:11:00 (GMT)
commitef99315d71b4b8e2c027033665bcc1244f43ca15 (patch)
treeaa501b0916e827fee6032245628509acc64efbba /src/doc.l
parente139c0246413d3803028572dcafe9f065f4c9eab (diff)
downloadDoxygen-ef99315d71b4b8e2c027033665bcc1244f43ca15.zip
Doxygen-ef99315d71b4b8e2c027033665bcc1244f43ca15.tar.gz
Doxygen-ef99315d71b4b8e2c027033665bcc1244f43ca15.tar.bz2
Release-1.2.0-20000806
Diffstat (limited to 'src/doc.l')
-rw-r--r--src/doc.l2214
1 files changed, 2214 insertions, 0 deletions
diff --git a/src/doc.l b/src/doc.l
new file mode 100644
index 0000000..4aa17c8
--- /dev/null
+++ b/src/doc.l
@@ -0,0 +1,2214 @@
+/*****************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2000 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 <iostream.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "qtbc.h"
+#include <qarray.h>
+#include <qstack.h>
+#include <qregexp.h>
+
+#include "doc.h"
+#include "code.h"
+#include "message.h"
+#include "doxygen.h"
+#include "config.h"
+#include "util.h"
+#include "language.h"
+#include "outputlist.h"
+#include "reflist.h"
+
+#ifndef WIN32
+#include <unistd.h>
+#endif
+
+#define YY_NEVER_INTERACTIVE 1
+
+/* -----------------------------------------------------------------
+ *
+ * scanner's state variables
+ */
+static bool insideArgumentList;
+static QCString className;
+static QCString memberName;
+static OutputList * outDoc;
+static QCString linkRef;
+static QCString linkText;
+static QCString codeBlock;
+static const char * inputString;
+static int inputPosition;
+static char yyFileName[4096] ;
+static int yyLineNr = 1 ;
+static bool exampleDoc;
+static QCString exampleName;
+static QCString htmlUrl,htmlText;
+static QCString currentIncludeFile;
+static int includeFileOffset = 0;
+static int includeFileLength = 0;
+static bool firstLine;
+static bool inParamBlock;
+static bool inRetValBlock;
+static bool inExceptionBlock;
+static bool inSeeBlock;
+static bool inReturnBlock;
+static bool inAuthorBlock;
+static bool inDeprecatedBlock;
+static bool inVersionBlock;
+static bool inSinceBlock;
+static bool inDateBlock;
+static bool inBugBlock;
+static bool inNoteBlock;
+static bool inPreBlock;
+static bool inPostBlock;
+static bool inInvarBlock;
+static bool inWarningBlock;
+static bool inRemarkBlock;
+static bool inAttentionBlock;
+static bool inParBlock;
+static QCString sectionRef;
+static bool insideVerbatim = FALSE;
+static int depthIf;
+//static int currentListIndentLevel;
+static QStack<char> currentListIndent;
+static QCString curImageName;
+static QCString curImageCaption;
+static QCString internalRefFile;
+static QCString internalRefAnchor;
+
+//-----------------------------------------------------------------------------
+
+static void initParser()
+{
+ insideArgumentList=FALSE;
+ className.resize(0);
+ memberName.resize(0);
+ linkRef.resize(0);
+ linkText.resize(0);
+ codeBlock.resize(0);
+ htmlUrl.resize(0);
+ htmlText.resize(0);
+ currentIncludeFile.resize(0);
+ includeFileOffset = 0;
+ includeFileLength = 0;
+ firstLine = TRUE;
+ inParamBlock = FALSE;
+ inRetValBlock = FALSE;
+ inExceptionBlock = FALSE;
+ inSeeBlock = FALSE;
+ inReturnBlock = FALSE;
+ inAuthorBlock = FALSE;
+ inDeprecatedBlock = FALSE;
+ inVersionBlock = FALSE;
+ inSinceBlock = FALSE;
+ inDateBlock = FALSE;
+ inBugBlock = FALSE;
+ inNoteBlock = FALSE;
+ inPreBlock = FALSE;
+ inPostBlock = FALSE;
+ inInvarBlock = FALSE;
+ inWarningBlock = FALSE;
+ inRemarkBlock = FALSE;
+ inAttentionBlock = FALSE;
+ inParBlock = FALSE;
+}
+
+//-----------------------------------------------------------------------------
+
+void scanString(const char *s);
+void internalParseDocument(const char *s);
+
+//-----------------------------------------------------------------------------
+
+class TableElem
+{
+ public:
+ TableElem(int r,int c);
+ ~TableElem();
+ int getRow() { return row; }
+ int getCol() { return col; }
+ OutputList *outputList() { return ol; }
+
+ private:
+ OutputList *ol;
+ int row;
+ int col;
+};
+
+TableElem::TableElem(int r,int c)
+{
+ //printf("TableElem::TableElem(%d,%d)\n",r,c);
+ ol=new OutputList(outDoc);
+ outDoc=ol;
+ row=r;
+ col=c;
+}
+
+TableElem::~TableElem()
+{
+ //printf("TableElem::~TableElem(%d,%d)\n",row,col);
+ delete ol; ol=0;
+}
+
+class Table
+{
+ public:
+ Table();
+ ~Table();
+ void newRow();
+ void newElem();
+
+ private:
+ OutputList *parentDoc;
+ QList<TableElem> *elemList;
+ int curRow;
+ int curCol;
+ int rows;
+ int cols;
+};
+
+Table::Table()
+{
+ parentDoc=outDoc;
+ elemList=new QList<TableElem>;
+ elemList->setAutoDelete(TRUE);
+ curRow=curCol=rows=cols=0;
+}
+
+Table::~Table()
+{
+ //printf("Table::~Table()\n");
+ // use elemList & cols & rows
+ if (cols>0 && rows>0)
+ {
+ parentDoc->startTable(cols);
+ TableElem *e=elemList->first();
+ while (e)
+ {
+ if (e->getRow()>0)
+ {
+ if (e->getCol()==0)
+ {
+ if (e->getRow()>1) parentDoc->endTableRow();
+ parentDoc->nextTableRow();
+ }
+ else
+ {
+ parentDoc->nextTableColumn();
+ }
+ *parentDoc+=*e->outputList();
+ parentDoc->endTableColumn();
+ }
+ e=elemList->next();
+ }
+ parentDoc->endTable();
+ }
+ delete elemList; elemList=0;
+ outDoc=parentDoc;
+}
+
+void Table::newRow()
+{
+ //printf("Table::newRow()\n");
+ curRow++;
+ if (curRow>rows) rows=curRow;
+ curCol=0;
+}
+
+void Table::newElem()
+{
+ //printf("Table::newElem(%d,%d)\n",curRow,curCol);
+ TableElem *te = new TableElem(curRow,curCol);
+ elemList->append(te);
+
+ curCol++;
+ if (curCol>cols) cols=curCol;
+}
+
+static QStack<Table> tableStack;
+static Table *curTable;
+
+static void startTable()
+{
+ //printf("startTable()\n");
+ curTable=new Table;
+ tableStack.push(curTable);
+}
+
+static void endTable()
+{
+ //printf("endTable()\n");
+ delete tableStack.pop(); // the destructor adds the table to the stream!
+ curTable=tableStack.top();
+}
+
+static void forceEndTable()
+{
+ err("Error: More <table> tags found than </table> "
+ "tags in documentation block in file %s!\n",yyFileName);
+ while (!tableStack.isEmpty())
+ {
+ endTable();
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+static void endArgumentList()
+{
+ if (insideArgumentList)
+ {
+ insideArgumentList=FALSE;
+ outDoc->endItemList();
+ }
+}
+
+static void includeFile(OutputList &ol,const char *fileName,bool quiet)
+{
+ bool ambig;
+ FileDef *fd;
+ if ((fd=findFileDef(exampleNameDict,fileName,ambig)))
+ {
+ currentIncludeFile=fileToString(fd->absFilePath());
+ includeFileOffset=0;
+ includeFileLength=currentIncludeFile.length();
+ OutputList codeFrag(&ol);
+ parseCode(codeFrag,0,currentIncludeFile,exampleDoc,exampleName);
+ if (!quiet)
+ {
+ ol.startCodeFragment();
+ ol+=codeFrag;
+ ol.endCodeFragment();
+ }
+ }
+ else if (ambig)
+ {
+ QCString text;
+ text.sprintf("Include file name %s is ambigious.\n",fileName);
+ text+="Possible candidates:\n";
+ text+=showFileDefMatches(exampleNameDict,fileName);
+ warn(yyFileName,yyLineNr,text);
+ }
+ else
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: example file %s is not found. "
+ "Check your EXAMPLE_PATH",fileName
+ );
+ }
+}
+
+static void verbIncludeFile(OutputList &ol,const char *name)
+{
+ bool ambig;
+ FileDef *fd;
+ if ((fd=findFileDef(exampleNameDict,name,ambig)))
+ {
+ ol.startCodeFragment();
+ ol.codify(fileToString(fd->absFilePath()));
+ ol.endCodeFragment();
+ }
+ else if (ambig)
+ {
+ QCString text;
+ text.sprintf("Include file name %s is ambigious.\n",name);
+ text+=("Possible candidates:\n");
+ text+=showFileDefMatches(exampleNameDict,name);
+ warn(yyFileName,yyLineNr,text);
+ }
+ else
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: example file %s is not found. "
+ "Check your EXAMPLE_PATH",name);
+ }
+}
+
+
+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 QCString stripKnownExtensions(const char *text)
+{
+ QCString result=text;
+ if (result.right(4)==".tex") result=result.left(result.length()-4);
+ else if (result.right(5)==".html") result=result.left(result.length()-5);
+ //printf("%s stripKnowExtensions(%s)\n",result.data(),text);
+ return result;
+}
+
+static void skipLine(OutputList &ol,const char *key)
+{
+ bool found=FALSE;
+ while (!found)
+ {
+ QCString s;
+ char c;
+ while ( includeFileOffset<includeFileLength &&
+ (c=currentIncludeFile[includeFileOffset++])!='\n' && c!=0
+ ) s+=c;
+ if (s.find(key)!=-1)
+ {
+ found=TRUE;
+ ol.writeString(" ");
+ parseCode(ol,className,s,exampleDoc,exampleName);
+ ol.writeString("\n");
+ }
+ else if (includeFileOffset==includeFileLength) found=TRUE;
+ }
+}
+
+static void skipUntil(const char *key)
+{
+ bool found=FALSE;
+ while (!found)
+ {
+ QCString s;
+ int i=includeFileOffset;
+ char c;
+ while ( i<includeFileLength &&
+ (c=currentIncludeFile[i++])!='\n' && c!=0
+ ) s+=c;
+ if (s.find(key)!=-1 || i==includeFileLength)
+ {
+ found=TRUE;
+ }
+ else
+ {
+ includeFileOffset=i;
+ }
+ }
+}
+
+static void showLine(OutputList &ol,const char *key)
+{
+ QCString s;
+ char c;
+ bool found=FALSE;
+ while (!found)
+ {
+ while ( includeFileOffset<includeFileLength &&
+ (c=currentIncludeFile[includeFileOffset++])!='\n' && c!=0
+ ) s+=c;
+ if (!s.stripWhiteSpace().isEmpty() ||
+ includeFileOffset==includeFileLength) found=TRUE;
+ }
+ if (s.find(key)!=-1)
+ {
+ ol.writeString(" ");
+ parseCode(ol,className,s,exampleDoc,exampleName);
+ ol.writeString("\n");
+ }
+}
+
+static void showUntil(OutputList &ol,const char *key)
+{
+ bool found=FALSE;
+ while (!found)
+ {
+ QCString s;
+ char c;
+ while ( includeFileOffset<includeFileLength &&
+ (c=currentIncludeFile[includeFileOffset++])!='\n' && c!=0
+ ) s+=c;
+ if (!s.stripWhiteSpace().isEmpty())
+ {
+ ol.writeString(" ");
+ parseCode(ol,className,s,exampleDoc,exampleName);
+ ol.writeString("\n");
+ if (s.find(key)!=-1) found=TRUE;
+ }
+ if (includeFileOffset==includeFileLength) found=TRUE;
+ }
+}
+
+//-----------------------------------------------------------------
+
+struct IndentInfo
+{
+ public:
+ IndentInfo(int i,bool e) : indent(i), enumerated(e) {};
+ ~IndentInfo() {}
+ void startList()
+ {
+ if (enumerated) outDoc->startEnumList(); else outDoc->startItemList();
+ }
+ void endList()
+ {
+ if (enumerated) outDoc->endEnumList(); else outDoc->endItemList();
+ }
+ void writeItem()
+ {
+ outDoc->writeListItem();
+ }
+ int indent;
+ bool enumerated;
+};
+
+static QStack<IndentInfo> listIndentStack;
+static bool insideItemList = FALSE;
+
+static void addListItemMarker(const char *marker,int dashPos,bool enumerated)
+{
+ // find the actual position at which the bullet was found
+ int i;
+ int indent=0;
+ for (i=0;i<dashPos;i++)
+ {
+ if (marker[i]=='\t')
+ {
+ indent+=Config::tabSize - (indent%Config::tabSize);
+ }
+ else
+ {
+ indent++;
+ }
+ }
+ //printf("list marker found at column %d enumerated %d\n",indent,enumerated);
+ if (!insideItemList)
+ {
+ listIndentStack.push(new IndentInfo(indent,enumerated));
+ listIndentStack.top()->startList();
+ listIndentStack.top()->writeItem();
+ insideItemList=TRUE;
+ }
+ else
+ {
+ IndentInfo *pPrevInfo = listIndentStack.top();
+ if (pPrevInfo->indent==indent && pPrevInfo->enumerated==enumerated)
+ // new item of same kind at the same indent level
+ {
+ pPrevInfo->writeItem();
+ }
+ else if (pPrevInfo->indent==indent)
+ // new item of diffent kind at the same indent level
+ {
+ // switch to a diffent list type
+ pPrevInfo->endList();
+ pPrevInfo->enumerated=enumerated;
+ pPrevInfo->startList();
+ pPrevInfo->writeItem();
+ }
+ else if (pPrevInfo->indent<indent) // start sub item list
+ {
+ listIndentStack.push(new IndentInfo(indent,enumerated));
+ listIndentStack.top()->startList();
+ listIndentStack.top()->writeItem();
+ }
+ else // end sub item list
+ {
+ pPrevInfo->endList();
+ listIndentStack.pop();
+ delete pPrevInfo;
+ // safe guard against wrong indenting
+ if (listIndentStack.isEmpty())
+ {
+ insideItemList=FALSE;
+ warn(yyFileName,yyLineNr,
+ "Warning: list item with invalid indent found!");
+ }
+ else
+ {
+ listIndentStack.top()->writeItem();
+ }
+ }
+ }
+}
+
+// end the current (nested) list regardless of the nesting level.
+static void forceEndItemList()
+{
+ IndentInfo *info;
+ while ((info=listIndentStack.pop())!=0)
+ {
+ info->endList();
+ delete info;
+ }
+ insideItemList=FALSE;
+}
+
+//-----------------------------------------------------------------
+
+static bool inBlock()
+{
+ return inParamBlock || inRetValBlock || inSeeBlock || inReturnBlock || inAuthorBlock ||
+ inVersionBlock || inSinceBlock || inDateBlock || inWarningBlock || inRemarkBlock ||
+ inAttentionBlock || inBugBlock || inNoteBlock ||
+ inParBlock || inExceptionBlock || inDeprecatedBlock || inPreBlock ||
+ inPostBlock || inInvarBlock;
+}
+
+static void endBlock()
+{
+ if (inParamBlock || inRetValBlock || inExceptionBlock)
+ {
+ outDoc->endDescTableData();
+ outDoc->endDescTable();
+ }
+ outDoc->endDescList();
+ inParamBlock=inRetValBlock=inSeeBlock=inReturnBlock=inAuthorBlock=
+ inVersionBlock=inSinceBlock=inDateBlock=inBugBlock=inNoteBlock=inWarningBlock=
+ inParBlock=inExceptionBlock=inDeprecatedBlock=inPreBlock=inPostBlock=
+ inInvarBlock=inRemarkBlock=inAttentionBlock=FALSE;
+}
+
+//-----------------------------------------------------------------
+
+enum ImageTypes
+{
+ IT_Html,
+ IT_Latex
+};
+
+// search for an image in the imageNameDict and if found
+// copies the image to the output directory (which is the
+// html directory if type==0 or the latex directory if type==1)
+static QCString findAndCopyImage(const char *fileName,ImageTypes type)
+{
+ QCString result;
+ bool ambig;
+ FileDef *fd;
+ if ((fd=findFileDef(imageNameDict,fileName,ambig)))
+ {
+ QFile inImage(QString(fd->absFilePath().data()));
+ if (inImage.open(IO_ReadOnly))
+ {
+ result = fileName;
+ int i;
+ if ((i=result.findRev('/'))!=-1 || (i=result.findRev('\\'))!=-1)
+ {
+ result.right(result.length()-i-1);
+ }
+ QCString outputDir;
+ switch(type)
+ {
+ case IT_Html:
+ outputDir = Config::htmlOutputDir;
+ break;
+ case IT_Latex:
+ outputDir = Config::latexOutputDir;
+ break;
+ }
+ QCString outputFile = outputDir+"/"+result;
+ QFile outImage(QString(outputFile.data()));
+ if (outImage.open(IO_WriteOnly)) // copy the image
+ {
+ char *buffer = new char[inImage.size()];
+ inImage.readBlock(buffer,inImage.size());
+ outImage.writeBlock(buffer,inImage.size());
+ outImage.flush();
+ delete buffer;
+ }
+ else
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: could not write output image %s",outputFile.data());
+ }
+ }
+ else
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: could not open image %s",fileName);
+ }
+ }
+ else if (ambig)
+ {
+ QCString text;
+ text.sprintf("Warning: image file name %s is ambigious.\n",fileName);
+ text+="Possible candidates:\n";
+ text+=showFileDefMatches(imageNameDict,fileName);
+ warn(yyFileName,yyLineNr,text);
+ }
+ else
+ {
+ result=fileName;
+ if (result.left(5)!="http:" && result.left(6)!="https:")
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: image file %s is not found in IMAGE_PATH: "
+ "assuming external image.",fileName
+ );
+ }
+ }
+ return result;
+}
+
+
+void writeImage(ImageTypes it,const char *size)
+{
+ bool hasCaption=!curImageCaption.isEmpty();
+ outDoc->pushGeneratorState();
+ switch(it)
+ {
+ case IT_Latex:
+ {
+ outDoc->disableAllBut(OutputGenerator::Latex);
+ outDoc->startImage(curImageName,size,hasCaption);
+ if (hasCaption)
+ {
+ scanString(curImageCaption);
+ }
+ outDoc->endImage(hasCaption);
+ }
+ break;
+ case IT_Html:
+ {
+ outDoc->disableAllBut(OutputGenerator::Html);
+ outDoc->startImage(curImageName,0,hasCaption);
+ if (hasCaption)
+ {
+ scanString(curImageCaption);
+ }
+ outDoc->endImage(hasCaption);
+ }
+ break;
+ }
+ outDoc->popGeneratorState();
+}
+
+
+/* ----------------------------------------------------------------- */
+#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;
+}
+
+//ATTR ((({BN}+[^\>]+)/">")?)
+%}
+
+CMD ("\\"|"@")
+BN [ \t\n\r]
+BL [ \t\r]*"\n"
+B [ \t]
+BS ^(({B}*"//")?)(({B}*"*"+)?){B}*
+FILESCHAR [a-z_A-Z0-9\\:\\\/\-\+]
+FILEECHAR [a-z_A-Z0-9\-\+]
+FILEMASK {FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)+
+FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]+"\"")
+ID [a-z_A-Z][a-z_A-Z0-9]*
+SCOPENAME (({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID})
+SCOPEMASK {ID}?(("::"|"#")?(~)?{ID})+
+URLMASK [a-z_A-Z0-9\~\:\?\@\#\.\-\+\/\=]+
+NONTERM [\{\}\[\]\`\~\@\|\-\+\#\$\/\\\!\%\^\&\*()a-z_A-Z<>0-9]
+WORD ({NONTERM}+([^\n\t ]*{NONTERM}+)?)|("\""[^\n\"]"\"")
+ATTR ({B}+[^>\n]*)?
+A [aA]
+BOLD [bB]
+BODY [bB][oO][dD][yY]
+BR [bB][rR]
+EM [eE][mM]
+CENTER [cC][eE][nN][tT][eE][rR]
+CODE [cC][oO][dD][eE]
+DL [dD][lL]
+DD [dD][dD]
+DT [dD][tT]
+DFN [dD][fF][nN]
+FORM [fF][oO][rR][mM]
+H1 [hH]1
+H2 [hH]2
+H3 [hH][3-6]
+HEAD [hH][eE][aA][dD]
+HR [hH][rR]
+HREF [hH][rR][eE][fF]
+I [iI]
+IMG [iI][mM][gG]
+INPUT [iI][nN][pP][uU][tT]
+LI [lL][iI]
+META [mM][eE][tT][aA]
+MULTICOL [mM][uU][lL][tT][iI][cC][oO][lL]
+NAME [nN][aA][mM][eE]
+OL [oO][lL]
+P [pP]
+PRE [pP][rR][eE]
+SMALL [sS][mM][aA][lL][lL]
+STRONG [sS][tT][rR][oO][nN][gG]
+SUB [sS][uU][bB]
+SUP [sS][uU][pP]
+SRC [sS][rR][cC]
+TABLE [tT][aA][bB][lL][eE]
+TITLE [tT][iI][tT][lL][eE]
+TD [tT][dD]
+TR [tT][rR]
+TT [tT][tT]
+UL [uU][lL]
+VAR [vV][aA][rR]
+DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
+
+%option noyywrap
+
+%x Text
+%x DocScan
+%x DocParam
+%x DocException
+%x DocHtmlScan
+%x DocLatexScan
+%x DocEmphasis
+%x DocBold
+%x DocCode
+%x DocIf
+%x DocCodeBlock
+%x DocInternal
+%x DocLink
+%x DocLinkText
+%x DocSkipWord
+%x DocInclude
+%x DocDontInclude
+%x DocHtmlLink
+%x DocHtmlAnchor
+%x DocHtmlHref1
+%x DocHtmlHref2
+%x DocSkiplineKey
+%x DocSkipKey
+%x DocLineKey
+%x DocUntilKey
+%x DocKeyEnd
+%x DocPar
+%x DocRefName
+%x DocVerbatim
+%x DocVerbInc
+%x DocIndexWord
+%x DocRefArg
+%x DocRefArgStart
+%x DocRefItem
+%x DocRefItemName
+%x DocInternalRef
+%x DocInternalRefText
+%x DocImage
+%x DocHtmlImageName
+%x DocHtmlImageOpt
+%x DocLatexImageName
+%x DocLatexImageOpt
+
+%%
+
+<*>\x0d
+<DocScan>^{B}*(("//"{B}*)?)"*"*{B}*"-"("#")?{B}+ { /* found list item marker */
+ QCString text=yytext;
+ int dashPos = text.findRev('-');
+ //printf("dashPos=%d char='%c'\n",dashPos,text.at(dashPos+1));
+ bool isEnumerated = text.at(dashPos+1)=='#';
+ addListItemMarker(yytext,dashPos,isEnumerated);
+ }
+<DocScan>\n{B}*(("//"{B}*)?)"*"*{B}*"-"("#")?{B}+ { /* found list item marker */
+ QCString text=yytext;
+ int dashPos = text.findRev('-');
+ //printf("dashPos=%d char='%c'\n",dashPos,text.at(dashPos+1));
+ bool isEnumerated = text.at(dashPos+1)=='#';
+ addListItemMarker(yytext+1,dashPos,isEnumerated);
+ }
+<DocScan,Text>"&copy;" { outDoc->writeCopyright(); }
+<DocScan,Text>"&quot;" { outDoc->writeQuote(); }
+<DocScan,Text>"&"[AEIOUYaeiouy]"uml;" { outDoc->writeUmlaut(yytext[1]); }
+<DocScan,Text>"&"[AEIOUYaeiouy]"acute;" { outDoc->writeAcute(yytext[1]); }
+<DocScan,Text>"&"[AEIOUaeiou]"grave;" { outDoc->writeGrave(yytext[1]); }
+<DocScan,Text>"&"[AEIOUaeiou]"circ;" { outDoc->writeCirc(yytext[1]); }
+<DocScan,Text>"&"[ANOano]"tilde;" { outDoc->writeTilde(yytext[1]); }
+<DocScan,Text>"&szlig;" { outDoc->writeSharpS(); }
+<DocScan,Text>"&[aA]ring;" { outDoc->writeRing(yytext[1]); }
+<DocScan,DocHtmlScan,DocLatexScan>"$("[a-z_A-Z]+")" {
+ QCString envvar=&yytext[2];
+ envvar=envvar.left(envvar.length()-1);
+ outDoc->docify(getenv(envvar));
+ }
+<DocScan>{CMD}"htmlonly"/[^a-z_A-Z0-9] {
+ outDoc->pushGeneratorState(); /*storeOutputListState();*/
+ outDoc->disableAllBut(OutputGenerator::Html);
+ BEGIN(DocHtmlScan);
+ }
+<DocHtmlScan>{CMD}"endhtmlonly"/[^a-z_A-Z0-9] {
+ /*restoreOutputListState();*/
+ outDoc->popGeneratorState();
+ BEGIN(DocScan);
+ }
+<DocScan>{CMD}"latexonly"/[^a-z_A-Z0-9] {
+ /*storeOutputListState();*/
+ outDoc->pushGeneratorState();
+ outDoc->disableAllBut(OutputGenerator::Latex);
+ BEGIN(DocLatexScan);
+ }
+<DocLatexScan>{CMD}"endlatexonly"/[^a-z_A-Z0-9] {
+ /*restoreOutputListState();*/
+ outDoc->popGeneratorState();
+ BEGIN(DocScan);
+ }
+<DocHtmlScan,DocLatexScan>"//"|"/*"|"*/" {
+ outDoc->writeString(yytext);
+ }
+<DocHtmlScan,DocLatexScan>.|\n {
+ char c[2];
+ c[0]=*yytext;c[1]='\0';
+ outDoc->writeString(c);
+ }
+<DocScan>"\\postheader"/{BN}
+<DocScan>"\\functionindex"/{BN} { writeMemberList(*outDoc); }
+<DocScan>"\\classhierarchy"/{BN} { writeClassHierarchy(*outDoc); }
+<DocScan>"\\annotatedclasslist"/{BN} { writeAnnotatedClassList(*outDoc); }
+<DocScan>"\\headerfilelist"/{BN} { /*TODO: fix this writeHeaderFileList(*outDoc); */ }
+<DocScan>"\\header"/{BN} { BEGIN( DocSkipWord ); }
+<DocScan>"\\define"/{BN} { BEGIN( DocSkipWord ); }
+<DocScan>{CMD}"verbinclude"/{BN} { BEGIN( DocVerbInc ); }
+<DocVerbInc>{FILE} {
+ verbIncludeFile(*outDoc,stripQuotes(yytext));
+ BEGIN( DocScan );
+ }
+<DocScan>{CMD}"verbatim"/[^a-z_A-Z0-9] {
+ outDoc->startCodeFragment();
+ insideVerbatim=TRUE;
+ BEGIN(DocVerbatim);
+ }
+<DocVerbatim>{CMD}"endverbatim"/[^a-z_A-Z0-9] {
+ outDoc->endCodeFragment();
+ insideVerbatim=FALSE;
+ BEGIN(DocScan);
+ }
+<DocVerbatim>[^\n\\\@]*"\n" {
+ //printf("docifying: %s\n",yytext);
+ outDoc->codify(yytext);
+ }
+<DocVerbatim>"\n"|"//"|"/*"|"*/" {
+ outDoc->codify(yytext);
+ }
+<DocVerbatim>. {
+ //printf("char %c\n",*yytext);
+ char c[2];c[0]=*yytext;c[1]='\0';
+ outDoc->codify(c);
+ }
+<DocScan>{CMD}"internal"/{BN} {
+ if (!Config::internalDocsFlag)
+ {
+ outDoc->newParagraph();
+ scanString(theTranslator->trForInternalUseOnly()+"\n");
+ //outDoc->writeString("For internal use only.\n");
+ BEGIN( DocInternal );
+ }
+ }
+<DocScan>"\\reimp"/{BN} {
+ outDoc->newParagraph();
+ scanString(theTranslator->trReimplementedForInternalReasons()+"\n");
+ }
+<DocScan>{CMD}"link"/{BN} { BEGIN( DocLink ); }
+<DocSkipWord>[a-z_A-Z0-9.:()]+ { BEGIN( DocScan ); }
+<DocLink>[a-z_A-Z0-9:#.,~&*/<>()\-\+]+ { // TODO: support operators as well!
+ linkRef = stripKnownExtensions(yytext);
+ linkText = "";
+ BEGIN( DocLinkText );
+ }
+<DocLinkText>. { linkText += *yytext; }
+<DocLinkText>"\n" { linkText += " "; }
+<DocLink,DocLinkText>{CMD}"endlink" { // <- needed for things like \endlink.
+ //printf("GenerateLink className=`%s' linkRef=`%s' linkText=`%s'\n",
+ // className.data(),linkRef.data(),linkText.data());
+ generateLink(*outDoc,className,linkRef,inSeeBlock,linkText.stripWhiteSpace());
+ BEGIN( DocScan );
+ }
+<DocScan>{CMD}"endlink"/[^a-z_A-Z0-9] { warn(yyFileName,yyLineNr,
+ "Warning: \\endlink without \\link "
+ "in documentation."
+ );
+ }
+<DocScan>{CMD}"addindex"{B}+ {
+ BEGIN(DocIndexWord);
+ }
+<DocScan>"\\form#"[0-9]+ {
+ Formula *formula=formulaNameDict[yytext];
+ if (formula)
+ {
+ QCString formName;
+ formName.sprintf("form-%d.gif",formula->getId());
+ outDoc->writeFormula(formName,formula->getFormulaText());
+ }
+ }
+<DocIndexWord>[^\n]+ {
+ //printf("Adding %s to index\n",yytext);
+ outDoc->addToIndex(yytext,0);
+ BEGIN(DocScan);
+ }
+<DocScan>{CMD}("arg"|"li")/{BN} {
+ if (insideArgumentList)
+ {
+ outDoc->writeListItem();
+ }
+ else
+ {
+ outDoc->startItemList();
+ outDoc->writeListItem();
+ insideArgumentList=TRUE;
+ }
+ }
+<DocScan>(({B}*"\n"){2,}{B}*)?{CMD}"par"{B}* {
+ BEGIN(DocPar);
+ }
+<DocPar>[^\n]*{BN} {
+ QCString title=QCString(yytext).stripWhiteSpace();
+ bool b = inBlock();
+ if (!title.isEmpty())
+ {
+ endArgumentList();
+ if (b) endBlock();
+ inParBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ outDoc->docify(title);
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->newParagraph();
+ }
+ BEGIN(DocScan);
+ }
+<DocScan>{CMD}"warning"/{BN} {
+ endArgumentList();
+ if (!inWarningBlock)
+ {
+ if (inBlock()) endBlock();
+ inWarningBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trWarning()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>{CMD}"remark"[s]?/{BN} {
+ endArgumentList();
+ if (!inRemarkBlock)
+ {
+ if (inBlock()) endBlock();
+ inRemarkBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trRemarks()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>{CMD}"attention"[s]?/{BN} {
+ endArgumentList();
+ if (!inAttentionBlock)
+ {
+ if (inBlock()) endBlock();
+ inAttentionBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trAttention()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>{CMD}"bug"[s]?/{BN} {
+ endArgumentList();
+ if (!inBugBlock)
+ {
+ if (inBlock()) endBlock();
+ inBugBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trBugsAndLimitations()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>{CMD}"note"[s]?/{BN} {
+ endArgumentList();
+ if (!inNoteBlock)
+ {
+ if (inBlock()) endBlock();
+ inNoteBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trNote()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>{CMD}"pre"/{BN} {
+ endArgumentList();
+ if (!inPreBlock)
+ {
+ if (inBlock()) endBlock();
+ inPreBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trPrecondition()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>{CMD}"post"/{BN} {
+ endArgumentList();
+ if (!inPostBlock)
+ {
+ if (inBlock()) endBlock();
+ inPostBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trPostcondition()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>{CMD}"invariant"/{BN} {
+ endArgumentList();
+ if (!inInvarBlock)
+ {
+ if (inBlock()) endBlock();
+ inInvarBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trInvariant()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>{CMD}"version"/{BN} {
+ endArgumentList();
+ if (!inVersionBlock)
+ {
+ if (inBlock()) endBlock();
+ inVersionBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trVersion()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>{CMD}"since"/{BN} {
+ endArgumentList();
+ if (!inSinceBlock)
+ {
+ if (inBlock()) endBlock();
+ inSinceBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trSince()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>{CMD}"date"/{BN} {
+ endArgumentList();
+ if (!inDateBlock)
+ {
+ if (inBlock()) endBlock();
+ inDateBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trDate()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>"\\todo "[0-9]+ { // this tag is generated in an earlier pass
+ if (Config::generateTodoList)
+ {
+ QCString numStr=yytext;
+ numStr=numStr.right(numStr.length()-6);
+ bool ok; int num = numStr.toUInt(&ok);
+ RefItem *item = todoList.getRefItem(num);
+ ASSERT(item!=0);
+ endArgumentList();
+ if (inBlock()) endBlock();
+ outDoc->startDescList();
+ outDoc->startBold();
+ outDoc->writeObjectLink(0,"todo",item->listAnchor,theTranslator->trTodo()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ internalParseDocument(item->text);
+ outDoc->endDescList();
+ }
+ }
+<DocScan>"\\test "[0-9]+ { // this tag is generated in an earlier pass
+ if (Config::generateTestList)
+ {
+ QCString numStr=yytext;
+ numStr=numStr.right(numStr.length()-6);
+ bool ok; int num = numStr.toUInt(&ok);
+ RefItem *item = testList.getRefItem(num);
+ ASSERT(item!=0);
+ endArgumentList();
+ if (inBlock()) endBlock();
+ outDoc->startDescList();
+ outDoc->startBold();
+ outDoc->writeObjectLink(0,"test",item->listAnchor,theTranslator->trTest()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ internalParseDocument(item->text);
+ outDoc->endDescList();
+ }
+ }
+<DocScan>{CMD}"deprecated"/{BN} {
+ endArgumentList();
+ if (!inDeprecatedBlock)
+ {
+ if (inBlock()) endBlock();
+ inDeprecatedBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trDeprecated()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>"$"[a-zA-Z_0-9]+":"[^\n\$]+"$" { // RCS tag
+ QCString tagName(&yytext[1]);
+ int i=tagName.find(':');
+ tagName=tagName.left(i);
+ QCString tagText=&yytext[i+2];
+ tagText=tagText.left(tagText.length()-1);
+ endArgumentList();
+ if (inBlock()) endBlock();
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(tagName+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ scanString(tagText);
+ outDoc->endDescList();
+ }
+<DocScan>{CMD}"author"/{BN} {
+ endArgumentList();
+ if (!inAuthorBlock)
+ {
+ if (inBlock()) endBlock();
+ inAuthorBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trAuthors()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->docify(", ");
+ }
+ }
+<DocScan>{CMD}("return"([s])?|"result")/{BN} {
+ endArgumentList();
+ if (!inReturnBlock)
+ {
+ if (inBlock()) endBlock();
+ inReturnBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trReturns()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ }
+<DocScan>{CMD}("sa"|"see")/{BN} {
+ endArgumentList();
+ if (!inSeeBlock)
+ {
+ if (inBlock()) endBlock();
+ inSeeBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trSeeAlso()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ }
+ else
+ {
+ outDoc->docify(", ");
+ }
+ }
+<DocScan>(({B}*"\n"){2,}{B}*)?{CMD}"param"/{BN} {
+ QCString t=yytext;
+ if (t.contains('\n')>1 && insideItemList)
+ {
+ forceEndItemList();
+ }
+ endArgumentList();
+ if (!inParamBlock)
+ {
+ if (inBlock()) endBlock();
+ inParamBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trParameters()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ outDoc->startDescTable();
+ }
+ else
+ {
+ outDoc->endDescTableData();
+ }
+ BEGIN(DocParam);
+ }
+<DocScan>(({B}*"\n"){2,}{B}*)?{CMD}"retval"/{BN} {
+ QCString t=yytext;
+ if (t.contains('\n')>1 && insideItemList)
+ {
+ forceEndItemList();
+ }
+ endArgumentList();
+ if (!inRetValBlock)
+ {
+ if (inBlock()) endBlock();
+ inRetValBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trReturnValues()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ outDoc->startDescTable();
+ }
+ else
+ {
+ outDoc->endDescTableData();
+ }
+ BEGIN(DocParam);
+ }
+<DocScan>(({B}*"\n"){2,}{B}*)?{CMD}("exception"|"throw")s?/{BN} {
+ QCString t=yytext;
+ if (t.contains('\n')>1 && insideItemList)
+ {
+ forceEndItemList();
+ }
+ endArgumentList();
+ if (!inExceptionBlock)
+ {
+ if (inBlock()) endBlock();
+ inExceptionBlock=TRUE;
+ outDoc->startDescList();
+ outDoc->startBold();
+ scanString(theTranslator->trExceptions()+": ");
+ outDoc->endBold();
+ outDoc->endDescTitle();
+ outDoc->writeDescItem();
+ outDoc->startDescTable();
+ }
+ else
+ {
+ outDoc->endDescTableData();
+ }
+ BEGIN(DocException);
+ }
+<DocScan>"\\capt".*
+<DocParam>({DOCPARAM}{BN}*","{BN}*)*{DOCPARAM} {
+ outDoc->startDescTableTitle();
+ outDoc->startEmphasis();
+ outDoc->docify(substitute(yytext,"\"",""));
+ outDoc->endEmphasis();
+ outDoc->endDescTableTitle();
+ outDoc->startDescTableData();
+ BEGIN(DocScan);
+ }
+<DocException>{SCOPENAME} {
+ outDoc->startDescTableTitle();
+ outDoc->startEmphasis();
+ outDoc->docify(yytext);
+ outDoc->endEmphasis();
+ outDoc->endDescTableTitle();
+ outDoc->startDescTableData();
+ BEGIN(DocScan);
+ }
+<DocScan>{CMD}"section "{ID}"\n" {
+ QCString secName=&yytext[9]; // skip "\section "
+ secName=secName.left(secName.length()-1); // remove \n
+ //printf("SectionName %s found\n",secName.data());
+ SectionInfo *sec;
+ if ((sec=sectionDict[secName]))
+ {
+ //printf("Title %s\n",sec->title.data());
+ outDoc->writeSection(sec->label,sec->title,
+ sec->type==SectionInfo::Subsection);
+ }
+ }
+<DocScan>{CMD}"anchor "{ID}"\n" {
+ QCString secName=&yytext[8];
+ secName=secName.left(secName.length()-1);
+ SectionInfo *sec;
+ if ((sec=sectionDict[secName]))
+ {
+ //printf("writeAnchor %s_%s\n",sec->fileName.data(),sec->label.data());
+ outDoc->writeAnchor(sec->fileName,sec->label);
+ }
+ }
+<DocScan>"\\_internalref"{B}+ { // for internal use only!
+ internalRefFile.resize(0);
+ internalRefAnchor.resize(0);
+ BEGIN(DocInternalRef);
+ }
+<DocInternalRef>[A-Z_a-z0-9.:\-\+]+ {
+ internalRefFile=yytext;
+ int i = internalRefFile.find(':');
+ if (i!=-1)
+ {
+ internalRefAnchor=internalRefFile.right(internalRefFile.length()-i-1);
+ internalRefFile=internalRefFile.left(i);
+ }
+ //printf("InternalRef yytext=`%s' file=`%s' anchor=`%s'\n",yytext,internalRefFile.data(),internalRefAnchor.data());
+ BEGIN(DocInternalRefText);
+ }
+<DocInternalRefText>\"[^\n\"]*\" {
+ QCString text=substitute(yytext,"\"","");
+ outDoc->writeObjectLink(0,internalRefFile,internalRefAnchor,text);
+ BEGIN(DocScan);
+ }
+<DocScan>{CMD}"ref" {
+ BEGIN(DocRefName);
+ }
+<DocScan>{CMD}"refitem" {
+ BEGIN(DocRefItem);
+ }
+<DocScan>{CMD}"if"/{BN} {
+ outDoc->pushGeneratorState();
+ depthIf++;
+ BEGIN(DocIf);
+ }
+<DocScan>{CMD}"endif"/[^a-z_A-Z0-9] {
+ if (--depthIf<0)
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: documentation block contains \\endif without "
+ "matching \\if found in documentation."
+ );
+ }
+ else
+ {
+ outDoc->popGeneratorState();
+ }
+ }
+<DocIf>[^\n\t ]+ {
+ if (Config::sectionFilterList.find(yytext)==-1)
+ {
+ outDoc->disableAll();
+ }
+ BEGIN(DocScan);
+ }
+<DocRefName>{SCOPENAME}|{FILE} {
+ QCString ref=yytext;
+ SectionInfo *sec;
+ if ((sec=sectionDict[ref]))
+ {
+ QCString text;
+ if (sec->title.isEmpty())
+ text=sec->label;
+ else
+ text=sec->title;
+ if (sec->type==SectionInfo::Anchor)
+ {
+ //outDoc->writeSectionRefAnchor(sec->fileName,sec->label,text);
+ outDoc->writeObjectLink(0,sec->fileName,sec->label,text);
+ writePageRef(*outDoc,sec->label,0);
+ }
+ else
+ {
+ //printf(" ref sec=%p sec->fileName=%s text=%s\n",sec,sec->fileName.data(),text.data());
+ outDoc->writeSectionRef(sec->fileName,sec->label,text);
+ }
+ }
+ else if (!generateLink(*outDoc,className,yytext,TRUE,0))
+ {
+ warn(yyFileName,yyLineNr,"Warning: reference to unknown section %s!",yytext);
+ //outDoc->writeBoldString(" unknown reference! ");
+ }
+ BEGIN(DocScan);
+ }
+<DocRefName>({SCOPENAME}|{FILE}){B}+/"\"" {
+ sectionRef=yytext;
+ sectionRef=sectionRef.stripWhiteSpace();
+ BEGIN(DocRefArgStart);
+ }
+<DocRefArgStart>"\"" {
+ BEGIN(DocRefArg);
+ }
+<DocRefArg>[^\"\n]+[\n\"] {
+ yytext[yyleng-1]='\0';
+ QCString text=substitute(yytext,"\\\\","\\");
+ SectionInfo *sec;
+ if ((sec=sectionDict[sectionRef]))
+ {
+ if (sec->type==SectionInfo::Anchor)
+ {
+ //outDoc->writeSectionRefAnchor(sec->fileName,sec->label,text);
+ outDoc->writeObjectLink(0,sec->fileName,sec->label,text);
+ //printf("Writing page ref `%s'\n",sec->label.data());
+ writePageRef(*outDoc,sec->label,0);
+ }
+ else
+ {
+ outDoc->writeSectionRef(sec->fileName,sec->label,text);
+ }
+ }
+ else if (!generateLink(*outDoc,className,sectionRef,TRUE,text))
+ {
+ warn(yyFileName,yyLineNr,"Warning: reference to unknown section %s!",sectionRef.data());
+ outDoc->writeBoldString(" unknown reference! ");
+ }
+ BEGIN(DocScan);
+ }
+<DocRefItem>{ID} {
+ sectionRef=yytext;
+ BEGIN(DocRefItemName);
+ }
+<DocRefItemName>.*/"\n" {
+ SectionInfo *sec;
+ QCString text=yytext;
+ if ((sec=sectionDict[sectionRef]))
+ {
+ outDoc->writeSectionRefItem(sec->fileName,sec->label,text.stripWhiteSpace());
+ }
+ else
+ {
+ warn(yyFileName,yyLineNr,"Warning: reference to unknown section %s!",sectionRef.data());
+ outDoc->writeBoldString(" unknown reference! ");
+ }
+ BEGIN(DocScan);
+ }
+<DocScan>{CMD}"image"{B}+ {
+ BEGIN(DocImage);
+ }
+<DocImage>[hH][tT][mM][lL] {
+ BEGIN(DocHtmlImageName);
+ }
+<DocImage>[lL][aA][tT][eE][xX] {
+ BEGIN(DocLatexImageName);
+ }
+<DocHtmlImageName>{FILE}|{URLMASK} {
+ curImageName = findAndCopyImage(stripQuotes(yytext),IT_Html);
+ curImageCaption.resize(0);
+ if (curImageName.isEmpty())
+ {
+ BEGIN(DocScan);
+ }
+ else
+ {
+ BEGIN(DocHtmlImageOpt);
+ }
+ }
+<DocHtmlImageOpt>\n {
+ writeImage(IT_Html,0);
+ BEGIN(DocScan);
+ }
+<DocHtmlImageOpt>\"[^\n"]*\" {
+ curImageCaption=stripQuotes(yytext);
+ }
+<DocLatexImageName>{FILE} {
+ curImageName = findAndCopyImage(stripQuotes(yytext),IT_Latex);
+ curImageCaption.resize(0);
+ if (curImageName.isEmpty())
+ BEGIN(DocScan);
+ else
+ BEGIN(DocLatexImageOpt);
+ }
+<DocLatexImageOpt>\n { // no width specified
+ writeImage(IT_Latex,0);
+ BEGIN(DocScan);
+ }
+<DocLatexImageOpt>\"[^\n"]*\" {
+ curImageCaption=stripQuotes(yytext);
+ }
+<DocLatexImageOpt>("width"{B}*"="{B}*)(([0-9\.]+({B}*{ID})?)|("\\"{ID})) {
+ writeImage(IT_Latex,yytext);
+ BEGIN(DocScan);
+ }
+<DocLatexImageOpt>("height"{B}*"="{B}*)(([0-9\.]+({B}*{ID})?)|("\\"{ID})) {
+ writeImage(IT_Latex,yytext);
+ BEGIN(DocScan);
+ }
+<DocImage>[a-z_A-Z0-9\.\-]+ {
+ warn(yyFileName,yyLineNr,"Warning: %s is an unsupported output format for \\image",yytext);
+ }
+<DocImage,DocHtmlImageName,DocLatexImageName>\n {
+ warn(yyFileName,yyLineNr,"Warning: invalid \\image command found!");
+ outDoc->enableAll();
+ BEGIN(DocScan);
+ }
+<DocScan>{CMD}"code"({BN}*"\n"|{B}*) {
+ outDoc->startCodeFragment();
+ codeBlock.resize(0);
+ BEGIN( DocCodeBlock );
+ }
+<DocScan>{CMD}"endcode"/[^a-z_A-Z0-9] {
+ warn(yyFileName,yyLineNr,"Warning: \\endcode without <PRE> or \\code "
+ "in the documentation.");
+ }
+
+<DocScan,DocRefName>{ID}"<"[^>\ \t\n]*">"("::"{ID})+"("?[a-z_A-Z0-9,:\<\> \t\*\&]*")"? {
+ generateRef(*outDoc,className,yytext,inSeeBlock);
+ BEGIN(DocScan);
+ }
+<DocScan,DocRefName>{SCOPEMASK}"("[a-z_A-Z0-9,:\<\> \t\*\&]+")" {
+ generateRef(*outDoc,className,yytext,inSeeBlock);
+ BEGIN(DocScan);
+ }
+<DocScan,DocRefName>{SCOPEMASK}("()")? {
+ generateRef(*outDoc,className,yytext,inSeeBlock);
+ BEGIN(DocScan);
+ }
+<DocScan,DocRefName>({SCOPEMASK}"::")?"operator()("[a-z_A-Z0-9,\<\> \t\*\&]*")" {
+ QCString oName=yytext;
+ generateRef(*outDoc,className,
+ removeRedundantWhiteSpace(oName),inSeeBlock);
+ BEGIN(DocScan);
+ }
+<DocScan,DocRefName>({SCOPEMASK}"::")?"operator"[^(\r\n.,]+"("[a-z_A-Z0-9,\<\> \t\*\&]*")" {
+ QCString oName=yytext;
+ generateRef(*outDoc,className,
+ removeRedundantWhiteSpace(oName),inSeeBlock);
+ BEGIN(DocScan);
+ }
+<DocScan>("http:"|"https:"|"ftp:"|"file:"){URLMASK} { outDoc->writeHtmlLink(yytext,yytext); }
+<DocScan>[a-zA-Z_0-9\.\-]+"@"[0-9a-z_A-Z\.\-]+ { outDoc->writeMailLink(yytext); }
+<DocScan>{FILEMASK} {
+ generateFileRef(*outDoc,yytext);
+ }
+<DocCodeBlock>{BN}*{CMD}"endcode"/[^a-z_A-Z0-9] { // needed to match things like \endcode. (note the dot)
+ parseCode(*outDoc,className,codeBlock,exampleDoc,exampleName);
+ //printf("Code block\n-------------\n%s\n--------------\n",codeBlock.data());
+ outDoc->endCodeFragment();
+ BEGIN( DocScan );
+ }
+<DocCodeBlock>"</"{PRE}{ATTR}">" {
+ parseCode(*outDoc,className,codeBlock,exampleDoc,exampleName);
+ //printf("Code block\n-------------\n%s\n--------------\n",codeBlock.data());
+ outDoc->endCodeFragment();
+ BEGIN( DocScan );
+ }
+<DocScan>{CMD}("e"|"em"|"a"){BN}+ { BEGIN( DocEmphasis ); }
+<DocScan>{CMD}"b"{BN}+ { BEGIN( DocBold ); }
+<DocScan>{CMD}("c"|"p"){BN}+ { BEGIN( DocCode ); }
+<DocScan>{CMD}"l"{BN}+
+<DocScan>"\\n"/[^a-z_A-Z0-9] { outDoc->lineBreak(); }
+<DocScan>{CMD}"include"{BN}+ { BEGIN( DocInclude ); }
+<DocScan>{CMD}"dontinclude"{BN}+ { BEGIN( DocDontInclude ); }
+<DocScan>{CMD}"skip"{BN}+ { BEGIN( DocSkipKey ); }
+<DocScan>{CMD}"skipline"{BN}+ { BEGIN( DocSkiplineKey ); firstLine=TRUE; }
+<DocScan>{CMD}"line"{BN}+ { BEGIN( DocLineKey ); firstLine=TRUE; }
+<DocScan>{CMD}"until"{BN}+ { BEGIN( DocUntilKey ); firstLine=TRUE; }
+<DocSkipKey>[^ \t\r\n]+ {
+ if (includeFileLength>0)
+ skipUntil(yytext);
+ BEGIN( DocScan );
+ }
+<DocLineKey>[^ \t\r\n]+ {
+ if (includeFileLength>0)
+ {
+ if (firstLine) outDoc->startCodeFragment();
+ firstLine=FALSE;
+ showLine(*outDoc,yytext);
+ BEGIN( DocKeyEnd );
+ }
+ else
+ {
+ BEGIN( DocScan );
+ }
+ }
+<DocSkiplineKey>[^ \t\r\n]+ {
+ if (includeFileLength>0)
+ {
+ if (firstLine) outDoc->startCodeFragment();
+ firstLine=FALSE;
+ skipLine(*outDoc,yytext);
+ BEGIN( DocKeyEnd );
+ }
+ else
+ {
+ BEGIN( DocScan );
+ }
+ }
+<DocUntilKey>[^ \t\r\n]+ {
+ if (includeFileLength>0)
+ {
+ if (firstLine) outDoc->startCodeFragment();
+ firstLine=FALSE;
+ showUntil(*outDoc,yytext);
+ BEGIN( DocKeyEnd );
+ }
+ else
+ {
+ BEGIN( DocScan );
+ }
+ }
+<DocKeyEnd>{CMD}"line"{BN}+ { BEGIN(DocLineKey); }
+<DocKeyEnd>{CMD}"until"{BN}+ { BEGIN(DocUntilKey); }
+<DocKeyEnd>{CMD}"skipline"{BN}+ { BEGIN(DocSkiplineKey); }
+<DocKeyEnd>\n
+<DocKeyEnd><<EOF>> {
+ if (!firstLine) outDoc->endCodeFragment();
+ yyterminate();
+ }
+<DocKeyEnd>. {
+ unput(*yytext);
+ if (!firstLine) outDoc->endCodeFragment();
+ BEGIN( DocScan );
+ }
+<DocScan>"<"{MULTICOL}{ATTR}">"
+<DocScan>"</"{MULTICOL}{ATTR}">"
+<DocScan>"<"{STRONG}{ATTR}">" { outDoc->startBold(); }
+<DocScan>"</"{STRONG}{ATTR}">" { outDoc->endBold(); }
+<DocScan>"<"{CENTER}{ATTR}">" { outDoc->startCenter(); }
+<DocScan>"</"{CENTER}{ATTR}">" { outDoc->endCenter(); }
+<DocScan>"<"{TABLE}{ATTR}">" { startTable(); }
+<DocScan>"</"{TABLE}{ATTR}">" { endTable(); }
+<DocScan>"<"{INPUT}{ATTR}">"
+<DocScan>"<"{SMALL}{ATTR}">" { outDoc->startSmall(); }
+<DocScan>"</"{SMALL}{ATTR}">" { outDoc->endSmall(); }
+<DocScan>"<"{META}{ATTR}">"
+<DocScan>"<"{FORM}{ATTR}">"
+<DocScan>"</"{FORM}{ATTR}">"
+<DocScan>"<"{HEAD}{ATTR}">"
+<DocScan>"</"{HEAD}{ATTR}">"
+<DocScan>"<"{BODY}{ATTR}">"
+<DocScan>"</"{BODY}{ATTR}">"
+<DocScan>"<"{CODE}{ATTR}">" { outDoc->startTypewriter(); }
+<DocScan>"</"{CODE}{ATTR}">" { outDoc->endTypewriter(); }
+<DocScan>"<"{DFN}{ATTR}">" { outDoc->startTypewriter(); }
+<DocScan>"</"{DFN}{ATTR}">" { outDoc->endTypewriter(); }
+<DocScan>"<"{VAR}{ATTR}">" { outDoc->startEmphasis(); }
+<DocScan>"</"{VAR}{ATTR}">" { outDoc->endEmphasis(); }
+<DocScan>"<"{IMG}{ATTR}">" {
+ /*storeOutputListState();*/
+ outDoc->pushGeneratorState();
+ outDoc->disableAllBut(OutputGenerator::Html);
+ outDoc->writeString(yytext);
+ /*restoreOutputListState();*/
+ outDoc->popGeneratorState();
+ }
+<DocScan>"<"{PRE}{ATTR}">" {
+ outDoc->startCodeFragment();
+ codeBlock.resize(0);
+ BEGIN( DocCodeBlock );
+ }
+<DocScan>"</"{PRE}{ATTR}">" {
+ warn(yyFileName,yyLineNr,
+ "Warning: </PRE> without <PRE> or \\code"
+ "in the documentation."
+ );
+ }
+<DocScan>"<"{SUB}{ATTR}">" { outDoc->startSubscript(); }
+<DocScan>"</"{SUB}{ATTR}">" { outDoc->endSubscript(); }
+<DocScan>"<"{SUP}{ATTR}">" { outDoc->startSuperscript(); }
+<DocScan>"</"{SUP}{ATTR}">" { outDoc->endSuperscript(); }
+<DocScan>"<"{TR}{ATTR}">" { if (curTable) curTable->newRow(); }
+<DocScan>"</"{TR}{ATTR}">"
+<DocScan>"<"{TD}{ATTR}">" { if (curTable) curTable->newElem(); }
+<DocScan>"</"{TD}{ATTR}">"
+<DocScan>"<"{OL}{ATTR}">" { outDoc->startEnumList();
+ currentListIndent.push("O");
+ }
+<DocScan>"</"{OL}{ATTR}">" {
+ if (currentListIndent.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: more </ol> tags than <ol> tags in the documentation."
+ );
+ }
+ else if (currentListIndent.top()!="O")
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: </ol> tag does not end a <ol> tag in the documentation."
+ );
+ }
+ else
+ {
+ outDoc->endEnumList();
+ currentListIndent.pop();
+ }
+ }
+<DocScan>"<"{UL}{ATTR}">" { outDoc->startItemList();
+ currentListIndent.push("U");
+ }
+<DocScan>"</"{UL}{ATTR}">" {
+ if (currentListIndent.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: more </ul> tags than <ul> tags in the documentation."
+ );
+ }
+ else if (currentListIndent.top()!="U")
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: </ul> tag does not end a <ul> tag in the documentation."
+ );
+ }
+ else
+ {
+ outDoc->endItemList();
+ currentListIndent.pop();
+ }
+ }
+<DocScan>"<"{LI}{ATTR}">" {
+ if (/*currentListIndent.isEmpty() ||*/ //DvH: I removed this check because I use this in the manual (the <ul> is in a \htmlonly block!)
+ currentListIndent.top()=="D")
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: The <li> tag can only be used inside a <ul> ... </ul> or a <ol> ... </ol> block."
+ );
+ }
+ else
+ {
+ outDoc->writeListItem();
+ }
+ }
+<DocScan>"</"{LI}{ATTR}">"
+<DocScan>"<"{TT}{ATTR}">" { outDoc->startTypewriter(); }
+<DocScan>"</"{TT}{ATTR}">" { outDoc->endTypewriter(); }
+<DocScan>"<"{EM}{ATTR}">" { outDoc->startEmphasis(); }
+<DocScan>"</"{EM}{ATTR}">" { outDoc->endEmphasis(); }
+<DocScan>"<"{HR}{ATTR}">" { outDoc->writeRuler(); }
+<DocScan>"<"{DL}{ATTR}">" { outDoc->startDescription();
+ currentListIndent.push("D");
+ }
+<DocScan>"</"{DL}{ATTR}">" {
+ if (currentListIndent.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: more </dl> tags than <dl> tags in the documentation."
+ );
+ }
+ else if (currentListIndent.top()!="D")
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: </dl> tag does not end a <dl> tag in the documentation."
+ );
+ }
+ else
+ {
+ outDoc->endDescription();
+ currentListIndent.pop();
+ }
+ }
+<DocScan>"<"{DT}{ATTR}">" {
+ if (currentListIndent.isEmpty() ||
+ currentListIndent.top()!="D")
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: The <dt> tag can only be used inside a <dl> ... </dl> block."
+ );
+ }
+ else
+ {
+ outDoc->startDescItem();
+ }
+ }
+<DocScan>"</"{DT}{ATTR}">"
+<DocScan>"<"{DD}{ATTR}">" {
+ if (currentListIndent.isEmpty() ||
+ currentListIndent.top()!="D")
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: The <dd> tag can only be used inside a <dl> ... </dl> block."
+ );
+ }
+ else
+ {
+ outDoc->endDescItem();
+ }
+ }
+<DocScan>"</"{DD}{ATTR}">"
+<DocScan>"<"{BR}{ATTR}">" { outDoc->lineBreak(); }
+<DocScan>"<"{I}{ATTR}">" { outDoc->startEmphasis(); }
+<DocScan>"</"{I}{ATTR}">" { outDoc->endEmphasis(); }
+<DocScan>"</"{A}{ATTR}">"
+<DocScan>"<"{A} { BEGIN(DocHtmlLink); }
+<DocScan>"<"{BOLD}{ATTR}">" { outDoc->startBold(); }
+<DocScan>"</"{BOLD}{ATTR}">" { outDoc->endBold(); }
+<DocScan>"<"{P}{ATTR}">" {
+ if (inBlock()) endBlock();
+ outDoc->newParagraph(); }
+<DocScan>"</"{P}{ATTR}">"
+<DocScan>"<"{H1}{ATTR}">" { outDoc->startTitle(); }
+<DocScan>"</"{H1}{ATTR}">" { outDoc->endTitle(); }
+<DocScan>"<"{H2}{ATTR}">" { outDoc->startSubsection(); }
+<DocScan>"</"{H2}{ATTR}">" { outDoc->endSubsection(); }
+<DocScan>"<"{H3}{ATTR}">" { outDoc->startSubsubsection(); }
+<DocScan>"</"{H3}{ATTR}">" { outDoc->endSubsubsection(); }
+<DocHtmlLink>{NAME}{BN}*"="{BN}*("\""?) { BEGIN(DocHtmlAnchor); }
+<DocHtmlAnchor>[a-z_A-Z0-9.\-\+\/]+ { outDoc->writeAnchor(0,yytext); }
+<DocHtmlLink>{HREF}{BN}*"="{BN}*("\""?) {
+ htmlUrl.resize(0);
+ htmlText.resize(0);
+ BEGIN(DocHtmlHref1); }
+<DocHtmlHref1>{URLMASK} {
+ htmlUrl=yytext;
+ }
+<DocHtmlHref1>">" { BEGIN(DocHtmlHref2); }
+<DocHtmlHref2>[^<]* { htmlText+=yytext; }
+<DocHtmlHref2>"<" {
+ outDoc->writeHtmlLink(htmlUrl,htmlText);
+ unput(*yytext);
+ BEGIN(DocScan);
+ }
+<DocHtmlLink,DocHtmlAnchor>">" { BEGIN(DocScan); }
+<DocScan>{CMD}("\\"|"@"|"<"|">"|"&"|"$"|"#"|"%") {
+ outDoc->docify(&yytext[1]);
+ }
+<DocScan>"%"[a-zA-Z_0-9\-]+ {
+ outDoc->docify(yytext+1);
+ }
+<DocEmphasis>[a-z_A-Z][a-z_A-Z:0-9<>&\-=^%~!\[\]()|\*/]*"("[a-z_A-Z0-9,:\<\> \t\*\&]*")" {
+ outDoc->startEmphasis();
+ generateRef(*outDoc,className,yytext,inSeeBlock);
+ outDoc->endEmphasis();
+ BEGIN( DocScan );
+ }
+<DocEmphasis>{WORD} {
+ outDoc->startEmphasis();
+ linkifyText(TextGeneratorOLImpl(*outDoc),className,0,yytext,FALSE,FALSE);
+ outDoc->endEmphasis();
+ BEGIN( DocScan );
+ }
+<DocBold>[a-z_A-Z][a-z_A-Z:0-9<>&\-=^%~!\[\]()|\*/]*"("[a-z_A-Z0-9,:\<\> \t\*\&]*")" {
+ outDoc->startBold();
+ generateRef(*outDoc,className,yytext,inSeeBlock);
+ outDoc->endBold();
+ BEGIN( DocScan );
+ }
+<DocBold>{WORD} {
+ outDoc->startBold();
+ linkifyText(TextGeneratorOLImpl(*outDoc),className,0,yytext,FALSE,FALSE);
+ outDoc->endBold();
+ BEGIN( DocScan );
+ }
+<DocCode>[a-z_A-Z][a-z_A-Z:0-9<>&\-=^%~!\[\]()!\*/]*"("[a-z_A-Z0-9,:\<\> \t\*\&]*")" {
+ outDoc->startTypewriter();
+ generateRef(*outDoc,className,yytext,inSeeBlock);
+ outDoc->endTypewriter();
+ BEGIN( DocScan );
+ }
+<DocCode>{WORD} {
+ outDoc->startTypewriter();
+ linkifyText(TextGeneratorOLImpl(*outDoc),className,0,yytext,FALSE,FALSE);
+ outDoc->endTypewriter();
+ BEGIN( DocScan );
+ }
+<DocInclude>{FILE} {
+ includeFile(*outDoc,stripQuotes(yytext),FALSE);
+ BEGIN( DocScan );
+ }
+<DocDontInclude>{FILE} {
+ includeFile(*outDoc,stripQuotes(yytext),TRUE);
+ BEGIN( DocScan );
+ }
+<DocCodeBlock>"//" { codeBlock += yytext; }
+<DocCodeBlock>"/*" { codeBlock += yytext; }
+<DocCodeBlock>\n { codeBlock += '\n'; }
+<DocCodeBlock>[^\/\\\<\n]* { codeBlock += yytext; }
+<DocCodeBlock>. { codeBlock += *yytext; }
+<DocCode,DocEmphasis,DocScan,DocBold>"//" {
+ outDoc->docify(yytext);
+ }
+<DocCode,DocEmphasis,DocScan,DocBold>"/*" {
+ outDoc->docify(yytext);
+ }
+<DocCode,DocEmphasis,DocBold>"\n" { outDoc->writeChar('\n'); }
+<DocScan>({B}*"\n"){2,}{B}*"*"*{B}*"-"("#")?{B}+ { // new paragraph & start of a list
+ QCString text=yytext;
+ int dashPos = text.findRev('-');
+ bool isEnumerated = text.at(dashPos+1)=='#';
+ if (insideArgumentList)
+ {
+ insideArgumentList=FALSE;
+ outDoc->endItemList();
+ }
+ else if (insideItemList)
+ {
+ forceEndItemList();
+ }
+ else
+ {
+ outDoc->newParagraph();
+ }
+ if (inBlock()) endBlock();
+ addListItemMarker(strrchr(yytext,'\n')+1,dashPos,isEnumerated);
+ }
+<DocScan>({B}*"\n"){2,}{B}* { // new paragraph
+ if (insideArgumentList)
+ {
+ insideArgumentList=FALSE;
+ outDoc->endItemList();
+ }
+ else if (insideItemList)
+ {
+ forceEndItemList();
+ }
+ else
+ {
+ outDoc->newParagraph();
+ }
+ if (inBlock()) endBlock();
+ }
+<DocScan>{BN}+/\n {
+ outDoc->writeChar(' ');
+ }
+<DocScan>\n?{B}* {
+ outDoc->writeChar(' ');
+ }
+<DocCode,DocEmphasis,DocBold,DocScan,Text>[a-z_A-Z0-9]+ {
+ outDoc->docify(yytext);
+ }
+<DocCode,DocEmphasis,DocBold,DocScan,Text>. {
+ outDoc->writeChar(*yytext);
+ }
+<*>\n { yyLineNr++ ; }
+<*>.
+
+%%
+
+//----------------------------------------------------------------------------
+
+void scanString(const char *s)
+{
+ const char *oldInputString = inputString;
+ int oldInputPosition = inputPosition;
+ int oldRule = YY_START;
+ YY_BUFFER_STATE oldBuffer = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_create_buffer(docYYin, YY_BUF_SIZE));
+ inputString = s;
+ inputPosition = 0;
+ BEGIN( Text );
+ docYYlex();
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(oldBuffer);
+ inputString = oldInputString;
+ inputPosition = oldInputPosition;
+ BEGIN( oldRule );
+}
+
+void internalParseDocument(const char *s)
+{
+ const char *oldInputString = inputString;
+ int oldInputPosition = inputPosition;
+ int oldRule = YY_START;
+ YY_BUFFER_STATE oldBuffer = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_create_buffer(docYYin, YY_BUF_SIZE));
+ inputString = s;
+ inputPosition = 0;
+ BEGIN( DocScan );
+ docYYlex();
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(oldBuffer);
+ inputString = oldInputString;
+ inputPosition = oldInputPosition;
+ BEGIN( oldRule );
+}
+
+//----------------------------------------------------------------------------
+
+void parseDocument(OutputList &ol,const QCString &docString)
+{
+ //inParamBlock=inSeeBlock=inReturnBlock=FALSE;
+ curTable = 0;
+ depthIf = 0;
+ outDoc = new OutputList(&ol);
+ currentIncludeFile.resize(0);
+ includeFileOffset=0;
+ includeFileLength=0;
+ currentListIndent.clear();
+ if (!docString) return;
+ linkRef = "";
+ linkText = "";
+ inputString = docString;
+ inputPosition = 0;
+ docYYrestart( docYYin );
+ BEGIN( DocScan );
+ insideArgumentList = FALSE;
+ insideVerbatim = FALSE;
+ docYYlex();
+ if (insideArgumentList) { insideArgumentList=FALSE; outDoc->endItemList(); }
+ if (insideItemList) { forceEndItemList(); }
+ if (inBlock()) endBlock();
+ if (!currentListIndent.isEmpty())
+ {
+ warn(yyFileName,yyLineNr,"Warning: Documentation ended in the middle "
+ "of a list!");
+ warn_cont("Missing: ");
+ while (!currentListIndent.isEmpty())
+ {
+ char c;
+ switch((c=*currentListIndent.pop()))
+ {
+ case 'O': warn_cont("</ol>"); break;
+ case 'U': warn_cont("</ul>"); break;
+ case 'D': warn_cont("</dl>"); break;
+ }
+ }
+ warn_cont("\n");
+ }
+ if (depthIf!=0)
+ {
+ warn(yyFileName,yyLineNr,"Warning: Documentation block contains \\if "
+ "without matching \\endif: nesting level is %d",depthIf);
+ }
+ if (!tableStack.isEmpty())
+ {
+ forceEndTable();
+ }
+ if (insideVerbatim)
+ {
+ warn(yyFileName,yyLineNr,
+ "Warning: file ended inside a \\verbatim block!"
+ );
+ }
+ ol+=*outDoc;
+ delete outDoc; outDoc=0;
+ return;
+}
+
+//----------------------------------------------------------------------------
+
+void parseDoc(OutputList &ol,const char *fileName,int startLine,
+ const char *clName,const char *memName,const QCString &docString)
+{
+ //printf("parseDoc(file=`%s',line=%d)\n",fileName,startLine);
+ initParser();
+ initParseCodeContext();
+ exampleDoc=FALSE; // do not cross reference with member docs
+ className=clName;
+ memberName=memName;
+ strcpy(yyFileName,fileName);
+ yyLineNr = startLine;
+ parseDocument(ol,docString);
+
+}
+
+//----------------------------------------------------------------------------
+
+void parseText(OutputList &ol,const QCString &txtString)
+{
+ if (txtString.isEmpty()) return;
+ inputString = txtString;
+ outDoc = new OutputList(&ol);
+ inputPosition = 0;
+ docYYrestart( docYYin );
+ BEGIN( Text );
+ docYYlex();
+ ol+=*outDoc;
+ delete outDoc; outDoc=0;
+ return;
+}
+
+//----------------------------------------------------------------------------
+
+void parseExample(OutputList &ol,const QCString &docString,
+ const char *fileName)
+{
+ initParser();
+ initParseCodeContext();
+ exampleDoc=TRUE; // cross reference with member docs
+ exampleName=fileName;
+ strcpy(yyFileName,fileName);
+ parseDocument(ol,docString);
+}
+
+//----------------------------------------------------------------------------
+extern "C" { // some bogus code to keep the compiler happy
+ void docYYdummy() { yy_flex_realloc(0,0); }
+}