/***************************************************************************** * * * * 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>"©" { outDoc->writeCopyright(); } <DocScan,Text>""" { 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>"ß" { 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); } }