/***************************************************************************** * * * * Copyright (C) 1997-2001 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 #include //#include #include #include #include "qtbc.h" #include #include #include #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 #endif #define YY_NEVER_INTERACTIVE 1 /* ----------------------------------------------------------------- * * scanner's state variables */ static OutputDocInterface * outDoc; static bool insideArgumentList; static QCString className; static QCString memberName; 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 bool insideHtmlLink; static QCString sectionRef; static bool insideVerbatim = FALSE; static bool insidePre = FALSE; static int depthIf; static QCString curImageName; static QCString curImageCaption; static QCString curDotFileName; static QCString curDotFileCaption; static QCString internalRefFile; static QCString internalRefAnchor; static QStack currentListIndent; // indent stack of all list items static bool insideItemList = FALSE; //----------------------------------------------------------------------------- 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; insideHtmlLink = FALSE; } //----------------------------------------------------------------------------- void scanString(const char *s); void scanDoc(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; } OutputDocInterface *outputDocInterface() { return od; } private: OutputDocInterface *od; int row; int col; }; TableElem::TableElem(int r,int c) { //printf("TableElem::TableElem(%d,%d)\n",r,c); od=outDoc->clone(); outDoc=od; row=r; col=c; } TableElem::~TableElem() { //printf("TableElem::~TableElem(%d,%d)\n",row,col); delete od; od=0; } class Table { public: Table(); ~Table(); void newRow(); void newElem(); private: OutputDocInterface *parentDoc; QList *elemList; int curRow; int curCol; int rows; int cols; }; Table::Table() { parentDoc=outDoc; elemList=new QList; 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->append(e->outputDocInterface()); 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 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
tags found than
" "tags in documentation block in file %s!\n",yyFileName); while (!tableStack.isEmpty()) { endTable(); } } //----------------------------------------------------------------------------- static void includeFile(OutputDocInterface &od,const char *fileName,bool quiet) { bool ambig; FileDef *fd; if ((fd=findFileDef(Doxygen::exampleNameDict,fileName,ambig))) { currentIncludeFile=fileToString(fd->absFilePath()); includeFileOffset=0; includeFileLength=currentIncludeFile.length(); OutputDocInterface *codeFrag = od.clone(); parseCode(*codeFrag,0,currentIncludeFile,exampleDoc,exampleName); if (!quiet) { od.startCodeFragment(); od.append(codeFrag); od.endCodeFragment(); } delete codeFrag; } else if (ambig) { QCString text; text.sprintf("Include file name %s is ambigious.\n",fileName); text+="Possible candidates:\n"; text+=showFileDefMatches(Doxygen::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(OutputDocInterface &od,const char *name) { bool ambig; FileDef *fd; if ((fd=findFileDef(Doxygen::exampleNameDict,name,ambig))) { od.startCodeFragment(); od.codify(fileToString(fd->absFilePath())+"\n"); od.endCodeFragment(); } else if (ambig) { QCString text; text.sprintf("Include file name %s is ambigious.\n",name); text+=("Possible candidates:\n"); text+=showFileDefMatches(Doxygen::exampleNameDict,name); warn(yyFileName,yyLineNr,text); } else { warn(yyFileName,yyLineNr, "Warning: example file %s is not found. " "Check your EXAMPLE_PATH",name); } } static void rawIncludeFile(OutputDocInterface &od,const char *name) { bool ambig; FileDef *fd; if ((fd=findFileDef(Doxygen::exampleNameDict,name,ambig))) { od.writeString(fileToString(fd->absFilePath())); } else if (ambig) { QCString text; text.sprintf("Include file name %s is ambigious.\n",name); text+=("Possible candidates:\n"); text+=showFileDefMatches(Doxygen::exampleNameDict,name); warn(yyFileName,yyLineNr,text); } else { warn(yyFileName,yyLineNr, "Warning: include 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(OutputDocInterface &od,const char *key) { bool found=FALSE; while (!found) { QCString s; char c; while ( includeFileOffsetendDescTableData(); outDoc->endDescTable(); outDoc->endParamList(); } else { outDoc->endDescList(); } currentListIndent.pop(); inParamBlock=inRetValBlock=inSeeBlock=inReturnBlock=inAuthorBlock= inVersionBlock=inSinceBlock=inDateBlock=inBugBlock=inNoteBlock=inWarningBlock= inParBlock=inExceptionBlock=inDeprecatedBlock=inPreBlock=inPostBlock= inInvarBlock=inRemarkBlock=inAttentionBlock=FALSE; } //----------------------------------------------------------------- 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 listIndentStack; // indent stack of - items 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;istartList(); 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->indentstartList(); listIndentStack.top()->writeItem(); } else // end sub item list { while (pPrevInfo && pPrevInfo->indent>indent) { pPrevInfo->endList(); listIndentStack.pop(); currentListIndent.pop(); delete pPrevInfo; pPrevInfo = listIndentStack.top(); } // 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) { delete info; } while (!currentListIndent.isEmpty()) { char c=*currentListIndent.pop(); switch(c) { case 'O': outDoc->endEnumList(); break; case 'U': outDoc->endItemList(); break; case 'D': if (inBlock()) { currentListIndent.push("D"); // hack! endBlock(); } else { outDoc->endDescription(); } break; } } insideItemList=FALSE; } static void endArgumentList() { #if 0 IndentInfo *info; while ((info=listIndentStack.pop())!=0) { delete info; } while (!currentListIndent.isEmpty()) { char c=*currentListIndent.pop(); switch(c) { case 'O': outDoc->endEnumList(); break; case 'U': outDoc->endItemList(); break; case 'D': if (!inBlock()) outDoc->endDescription(); break; } } insideItemList=FALSE; #endif if (insideArgumentList) { insideArgumentList=FALSE; outDoc->endItemList(); } } //----------------------------------------------------------------- enum ImageTypes { IT_Html, IT_Latex, IT_RTF }; /*! 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; //printf("Search for %s\n",fileName); if ((fd=findFileDef(Doxygen::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_getString("HTML_OUTPUT"); break; case IT_Latex: outputDir = Config_getString("LATEX_OUTPUT"); break; case IT_RTF: outputDir = Config_getString("RTF_OUTPUT"); 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(Doxygen::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; case IT_RTF: { outDoc->disableAllBut(OutputGenerator::RTF); outDoc->startImage(curImageName,0,hasCaption); if (hasCaption) { scanString(curImageCaption); } outDoc->endImage(hasCaption); } } outDoc->popGeneratorState(); } // search for a dot file in the dotFileNameDict, and if found // generates the graph in the output directories. static void writeDotFile(const char *fileName, const char *captionText) { bool ambig; FileDef *fd; bool hasCaption = captionText!=0; if ((fd=findFileDef(Doxygen::dotFileNameDict,fileName,ambig))) { outDoc->startDotFile(fd->absFilePath(),hasCaption); if (hasCaption) { scanString(captionText); } outDoc->endDotFile(hasCaption); } else if (ambig) { QCString text; text.sprintf("Warning: dot file name %s is ambigious.\n",fileName); text+="Possible candidates:\n"; text+=showFileDefMatches(Doxygen::dotFileNameDict,fileName); warn(yyFileName,yyLineNr,text); } else { warn(yyFileName,yyLineNr, "Warning: dot file %s is not found in DOTFILE_DIRS! ",fileName ); } } /* ----------------------------------------------------------------- */ #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" BSEP [ \t\r]*([ \t\r]|"\n")({BL}{0,100}) 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})+ URLCHAR [a-z_A-Z0-9\~\:\?\@\&\%\#\.\-\+\/\=] URLMASK ([a-z_A-Z][^\>\"\n]*{URLCHAR})|({URLCHAR}+) NONTERM [\{\}\[\]\`\~\@\|\-\+\#\$\/\\\!\%\^\&\*()a-z_A-Z<>0-9\x80-\xff] 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] KBD [kK][bB][dD] 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] BLOCKQUOTE [bB][lL][oO][cC][kK][qQ][uU][oO][tT][eE] DOCPARAM ("#")?([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"") OPNEW {B}+"new"({B}*"[]")? OPDEL {B}+"delete"({B}*"[]")? OPARG "("[a-z_A-Z0-9,\<\> \t\*\&]*")" OPNORM {OPNEW}|{OPDEL}|"+"|"-"|"*"|"/"|"%"|"^"|"&"|"|"|"~"|"!"|"="|"<"|">"|"+="|"-="|"*="|"/="|"%="|"^="|"&="|"|="|"<<"|">>"|"<<="|">>="|"=="|"!="|"<="|">="|"&&"|"||"|"++"|"--"|","|"->*"|"->"|"[]"|"()" OPCAST {B}+[^(\r\n.,]+ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) %option noyywrap %x Text %x DocScan %x DocParam %x DocException %x DocHtmlScan %x DocLatexScan %x DocEmphasis %x DocBold %x DocCode %x DocCodeBlock %x DocInternal %x DocLink %x DocJavaLink %x DocLinkText %x DocJavaLinkText %x DocSkipWord %x DocInclude %x DocDontInclude %x DocHtmlLink %x DocHtmlAnchor %x DocHtmlHref %x DocSkiplineKey %x DocSkipKey %x DocLineKey %x DocUntilKey %x DocKeyEnd %x DocPar %x DocRefName %x DocVerbatim %x DocVerbInc %x DocHtmlInc %x DocIndexWord %x DocRefArg %x DocRefArgStart %x DocRefItem %x DocRefItemName %x DocInternalRef %x DocInternalRefText %x DocImage %x DocHtmlImageName %x DocHtmlImageOpt %x DocLatexImageName %x DocLatexImageOpt %x DocRtfImageName %x DocRtfImageOpt %x DocDotFile %x DocDotFileOpt %% <*>\x0d ^{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+1,isEnumerated); } \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); } "©" { outDoc->writeCopyright(); } "<" { outDoc->docify("<"); } ">" { outDoc->docify(">"); } "&" { outDoc->docify("&"); } "'" { outDoc->docify("'"); } """ { outDoc->docify("\""); } "&"[AEIOUYaeiouy]"uml;" { outDoc->writeUmlaut(yytext[1]); } "&"[AEIOUYaeiouy]"acute;" { outDoc->writeAcute(yytext[1]); } "&"[AEIOUaeiou]"grave;" { outDoc->writeGrave(yytext[1]); } "&"[AEIOUaeiou]"circ;" { outDoc->writeCirc(yytext[1]); } "&"[ANOano]"tilde;" { outDoc->writeTilde(yytext[1]); } "ß" { outDoc->writeSharpS(); } "&"[cC]"cedil;" { outDoc->writeCCedil(yytext[1]); } "&"[aA]"ring;" { outDoc->writeRing(yytext[1]); } " " { outDoc->writeNonBreakableSpace(1); } "$("[a-z_A-Z]+")" { QCString envvar=&yytext[2]; envvar=envvar.left(envvar.length()-1); outDoc->docify(getenv(envvar)); } {CMD}"htmlonly"/[^a-z_A-Z0-9] { outDoc->pushGeneratorState(); outDoc->disableAllBut(OutputGenerator::Html); BEGIN(DocHtmlScan); } {CMD}"endhtmlonly"/[^a-z_A-Z0-9] { outDoc->popGeneratorState(); BEGIN(DocScan); } {CMD}"latexonly"/[^a-z_A-Z0-9] { outDoc->pushGeneratorState(); outDoc->disableAllBut(OutputGenerator::Latex); BEGIN(DocLatexScan); } {CMD}"endlatexonly"/[^a-z_A-Z0-9] { outDoc->popGeneratorState(); BEGIN(DocScan); } "//"|"/*"|"*/" { outDoc->writeString(yytext); } .|\n { char c[2]; c[0]=*yytext;c[1]='\0'; outDoc->writeString(c); } "\\postheader"/{BN} "\\functionindex"/{BN} { /* writeMemberList(*outDoc,FALSE);*/ } "\\classhierarchy"/{BN} { /* writeClassHierarchy(*outDoc); */ } "\\annotatedclasslist"/{BN} { /* writeAnnotatedClassList(*outDoc); */ } "\\headerfilelist"/{BN} { /* writeHeaderFileList(*outDoc); */ } "\\header"/{BN} { BEGIN( DocSkipWord ); } "\\define"/{BN} { BEGIN( DocSkipWord ); } {CMD}"verbinclude"/{BN} { BEGIN( DocVerbInc ); } {FILE} { verbIncludeFile(*outDoc,stripQuotes(yytext)); BEGIN( DocScan ); } {CMD}"htmlinclude"/{BN} { BEGIN( DocHtmlInc ); } {FILE} { outDoc->pushGeneratorState(); outDoc->disableAllBut(OutputGenerator::Html); rawIncludeFile(*outDoc,stripQuotes(yytext)); outDoc->popGeneratorState(); BEGIN( DocScan ); } {CMD}"verbatim"/[^a-z_A-Z0-9] { outDoc->startCodeFragment(); insideVerbatim=TRUE; BEGIN(DocVerbatim); } {CMD}"endverbatim"/[^a-z_A-Z0-9] { outDoc->endCodeFragment(); insideVerbatim=FALSE; BEGIN(DocScan); } [^\n\\\@]*"\n" { //printf("docifying: %s\n",yytext); outDoc->codify(yytext); } "\n"|"//"|"/*"|"*/" { outDoc->codify(yytext); } . { //printf("char %c\n",*yytext); char c[2];c[0]=*yytext;c[1]='\0'; outDoc->codify(c); } {CMD}"internal"/{BN} { if (!Config_getBool("INTERNAL_DOCS")) { outDoc->newParagraph(); scanString(theTranslator->trForInternalUseOnly()+"\n"); //outDoc->writeString("For internal use only.\n"); BEGIN( DocInternal ); } } "\\reimp"/{BN} { outDoc->newParagraph(); scanString(theTranslator->trReimplementedForInternalReasons()+"\n"); } {CMD}"link"/{BN} { BEGIN( DocLink ); } "{"{CMD}"link"{BN}+ { BEGIN( DocJavaLink ); } [a-z_A-Z0-9.:()]+ { BEGIN( DocScan ); } [a-z_A-Z0-9:#.,~&*/\[\]<>()\-\+]+ { // TODO: support operators as well! linkRef = stripKnownExtensions(yytext); linkText = ""; BEGIN( DocLinkText ); } ([a-z_A-Z0-9]+".")+ { /* Skip scope prefix (TODO: fix) */ } ([a-z_A-Z0-9]*"#")?[a-z_A-Z0-9]+("("[a-z_A-Z0-9.,:~&*()\[\]]*")")? { // TODO: support operators as well! linkRef = yytext; linkText = ""; BEGIN( DocJavaLinkText ); } "}" { //printf("Trying to link `%s'\n",linkRef.data()); if (!generateLink(*outDoc,className,linkRef,inSeeBlock,linkText.stripWhiteSpace())) { warn(yyFileName,yyLineNr,"Warning: link to unknown entity `%s' in the documentation of this entity!",linkRef.data()); } BEGIN( DocScan ); } . { linkText += *yytext; } "\n" { linkText += " "; } {CMD}"endlink" { // <- needed for things like \endlink. //printf("GenerateLink className=`%s' linkRef=`%s' linkText=`%s'\n", // className.data(),linkRef.data(),linkText.data()); if (!generateLink(*outDoc,className,linkRef,inSeeBlock,linkText.stripWhiteSpace())) { warn(yyFileName,yyLineNr,"Warning: link to unknown entity `%s' in the documentation of this entity!",linkRef.data()); } BEGIN( DocScan ); } {CMD}"endlink"/[^a-z_A-Z0-9] { warn(yyFileName,yyLineNr, "Warning: \\endlink without \\link " "in documentation of this entity." ); } {CMD}"addindex"{B}+ { BEGIN(DocIndexWord); } "\\form#"[0-9]+ { Formula *formula=Doxygen::formulaNameDict[yytext]; if (formula) { QCString formName; formName.sprintf("form-%d.gif",formula->getId()); outDoc->writeFormula(formName,formula->getFormulaText()); } } [^\n]+ { //printf("Adding %s to index\n",yytext); outDoc->addIndexItem(yytext,0); BEGIN(DocScan); } {CMD}("arg"|"li")/{BN} { if (insideArgumentList) { outDoc->writeListItem(); } else { outDoc->startItemList(); outDoc->writeListItem(); insideArgumentList=TRUE; } } (({B}*"\n"){2,}{B}*)?{CMD}"par"{B}* { QCString t=yytext; if (/*t.contains('\n')>1 &&*/ insideItemList) { forceEndItemList(); } BEGIN(DocPar); } [^\n]*{BSEP} { QCString title=QCString(yytext).stripWhiteSpace(); bool b = inBlock(); if (!title.isEmpty()) { endArgumentList(); if (b) endBlock(); inParBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Par); outDoc->docify(title); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->newParagraph(); } BEGIN(DocScan); } {CMD}"warning"{BSEP} { endArgumentList(); if (!inWarningBlock) { if (inBlock()) endBlock(); inWarningBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Warning); scanString(theTranslator->trWarning()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->writeDescItem(); } } {CMD}"remark"[s]?{BSEP} { endArgumentList(); if (!inRemarkBlock) { if (inBlock()) endBlock(); inRemarkBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Remark); scanString(theTranslator->trRemarks()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->writeDescItem(); } } {CMD}"attention"{BSEP} { endArgumentList(); if (!inAttentionBlock) { if (inBlock()) endBlock(); inAttentionBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Attention); scanString(theTranslator->trAttention()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->writeDescItem(); } } {CMD}"note"[s]?{BSEP} { endArgumentList(); if (!inNoteBlock) { if (inBlock()) endBlock(); inNoteBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Note); scanString(theTranslator->trNote()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->writeDescItem(); } } {CMD}"pre"{BSEP} { endArgumentList(); if (!inPreBlock) { if (inBlock()) endBlock(); inPreBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Pre); scanString(theTranslator->trPrecondition()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->writeDescItem(); } } {CMD}"post"{BSEP} { endArgumentList(); if (!inPostBlock) { if (inBlock()) endBlock(); inPostBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Post); scanString(theTranslator->trPostcondition()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->writeDescItem(); } } {CMD}"invariant"{BSEP} { endArgumentList(); if (!inInvarBlock) { if (inBlock()) endBlock(); inInvarBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Invar); scanString(theTranslator->trInvariant()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->writeDescItem(); } } {CMD}"version"{BSEP} { endArgumentList(); if (!inVersionBlock) { if (inBlock()) endBlock(); inVersionBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Version); scanString(theTranslator->trVersion()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->writeDescItem(); } } {CMD}"since"{BSEP} { endArgumentList(); if (!inSinceBlock) { if (inBlock()) endBlock(); inSinceBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Since); scanString(theTranslator->trSince()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->writeDescItem(); } } {CMD}"date"{BSEP} { endArgumentList(); if (!inDateBlock) { if (inBlock()) endBlock(); inDateBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Date); scanString(theTranslator->trDate()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->writeDescItem(); } } "\\todo "[0-9]+ { // this tag is generated in an earlier pass if (Config_getBool("GENERATE_TODOLIST")) { 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(); currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Todo); outDoc->writeObjectLink(0,"todo",item->listAnchor,theTranslator->trTodo()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); internalParseDocument(item->text); outDoc->endDescList(); currentListIndent.pop(); } } "\\test "[0-9]+ { // this tag is generated in an earlier pass if (Config_getBool("GENERATE_TESTLIST")) { 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(); currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Test); outDoc->writeObjectLink(0,"test",item->listAnchor,theTranslator->trTest()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); internalParseDocument(item->text); outDoc->endDescList(); currentListIndent.pop(); } } "\\bug "[0-9]+ { // this tag is generated in an earlier pass if (Config_getBool("GENERATE_BUGLIST")) { QCString numStr=yytext; numStr=numStr.right(numStr.length()-5); bool ok; int num = numStr.toUInt(&ok); RefItem *item = bugList.getRefItem(num); ASSERT(item!=0); endArgumentList(); if (inBlock()) endBlock(); currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Bug); outDoc->writeObjectLink(0,"bug",item->listAnchor,theTranslator->trBug()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); internalParseDocument(item->text); outDoc->endDescList(); currentListIndent.pop(); } } {CMD}"deprecated"{BSEP} { endArgumentList(); if (!inDeprecatedBlock) { if (inBlock()) endBlock(); inDeprecatedBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Deprecated); scanString(theTranslator->trDeprecated()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->writeDescItem(); } } "$"[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(); currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::RCS); scanString(tagName+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); scanString(tagText); outDoc->endDescList(); currentListIndent.pop(); } {CMD}"author"[s]?{BSEP} { endArgumentList(); if (!inAuthorBlock) { if (inBlock()) endBlock(); inAuthorBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Author); bool singular = ((QString)yytext).find('s')==-1; scanString(theTranslator->trAuthor(TRUE,singular)+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->docify(", "); } } {CMD}("return"([s])?|"result"){BSEP} { endArgumentList(); if (!inReturnBlock) { if (inBlock()) endBlock(); inReturnBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::Return); scanString(theTranslator->trReturns()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } } {CMD}("sa"|"see"){BSEP} { endArgumentList(); if (!inSeeBlock) { if (inBlock()) endBlock(); inSeeBlock=TRUE; currentListIndent.push("D"); outDoc->startDescList(BaseOutputDocInterface::See); scanString(theTranslator->trSeeAlso()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); } else { outDoc->docify(", "); } } (({B}*"\n"){2,}{B}*)?{CMD}"param"{BSEP} { QCString t=yytext; if (/*t.contains('\n')>1 &&*/ insideItemList) { forceEndItemList(); } endArgumentList(); if (!inParamBlock) { if (inBlock()) endBlock(); inParamBlock=TRUE; currentListIndent.push("D"); outDoc->startParamList(BaseOutputDocInterface::Param); scanString(theTranslator->trParameters()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); outDoc->startDescTable(); } else { outDoc->endDescTableData(); } BEGIN(DocParam); } (({B}*"\n"){2,}{B}*)?{CMD}"retval"{BSEP} { QCString t=yytext; if (/*t.contains('\n')>1 &&*/ insideItemList) { forceEndItemList(); } endArgumentList(); if (!inRetValBlock) { if (inBlock()) endBlock(); inRetValBlock=TRUE; currentListIndent.push("D"); outDoc->startParamList(BaseOutputDocInterface::RetVal); scanString(theTranslator->trReturnValues()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); outDoc->startDescTable(); } else { outDoc->endDescTableData(); } BEGIN(DocParam); } (({B}*"\n"){2,}{B}*)?{CMD}("exception"|"throw")s?{BSEP} { QCString t=yytext; if (/*t.contains('\n')>1 &&*/ insideItemList) { forceEndItemList(); } endArgumentList(); if (!inExceptionBlock) { if (inBlock()) endBlock(); inExceptionBlock=TRUE; currentListIndent.push("D"); outDoc->startParamList(BaseOutputDocInterface::Exception); scanString(theTranslator->trExceptions()+": "); outDoc->endDescTitle(); outDoc->writeDescItem(); outDoc->startDescTable(); } else { outDoc->endDescTableData(); } BEGIN(DocException); } "\\capt".* ({DOCPARAM}{BN}*","{BN}*)*{DOCPARAM}{BSEP}* { outDoc->startDescTableTitle(); scanDoc(substitute(yytext,"\"","").stripWhiteSpace()); outDoc->endDescTableTitle(); outDoc->startDescTableData(); BEGIN(DocScan); } {SCOPENAME} { outDoc->startDescTableTitle(); generateRef(*outDoc,className,yytext,FALSE); outDoc->endDescTableTitle(); outDoc->startDescTableData(); BEGIN(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=Doxygen::sectionDict[secName])) { //printf("Title %s\n",sec->title.data()); outDoc->startSection(sec->label,sec->title, sec->type==SectionInfo::Subsection); scanString(sec->title); outDoc->endSection(sec->label, sec->type==SectionInfo::Subsection); } else { warn(yyFileName,yyLineNr,"Warning: reference to unknown section %s in the documentation of this entity!",yytext); } } {CMD}"anchor "{ID}"\n" { QCString secName=&yytext[8]; secName=secName.left(secName.length()-1); SectionInfo *sec; if ((sec=Doxygen::sectionDict[secName])) { //printf("writeAnchor %s_%s\n",sec->fileName.data(),sec->label.data()); outDoc->writeAnchor(sec->fileName,sec->label); } } "\\_internalref"{B}+ { // for internal use only! internalRefFile.resize(0); internalRefAnchor.resize(0); BEGIN(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); } \"[^\n\"]*\" { QCString text=substitute(yytext,"\"",""); outDoc->writeObjectLink(0,internalRefFile,internalRefAnchor,text); BEGIN(DocScan); } {CMD}"ref"/{BN} { BEGIN(DocRefName); } {CMD}"refitem"/{BN} { BEGIN(DocRefItem); } /* {CMD}"if"/{BN} { outDoc->pushGeneratorState(); depthIf++; BEGIN(DocIf); } {CMD}"endif"/[^a-z_A-Z0-9] { if (--depthIf<0) { warn(yyFileName,yyLineNr, "Warning: documentation block contains \\endif without " "matching \\if found in documentation of this entity." ); } else { outDoc->popGeneratorState(); } } [^\n\t ]+ { if (Config_getList("ENABLED_SECTIONS").find(yytext)==-1) { outDoc->disableAll(); } BEGIN(DocScan); } */ {SCOPENAME}|{FILE} { QCString ref=yytext; SectionInfo *sec; //printf(">>> ref `%s'\n",yytext); if ((sec=Doxygen::sectionDict[ref])) { //printf("Is a section!\n"); QCString text; if (sec->title.isEmpty()) text=sec->label; else text=sec->title; if (sec->type==SectionInfo::Anchor) { outDoc->writeObjectLink(sec->ref,sec->fileName,sec->label,text); if (sec->ref.isEmpty()) { 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->ref,sec->fileName,sec->label,text); } } else if (!generateLink(*outDoc,className,yytext,TRUE,0)) { warn(yyFileName,yyLineNr,"Warning: reference to unknown section %s in the documentation of this entity!",yytext); } BEGIN(DocScan); } ({SCOPENAME}|{FILE}){B}+/"\"" { //printf(">>> ref `%s'\n",yytext); sectionRef=yytext; sectionRef=sectionRef.stripWhiteSpace(); BEGIN(DocRefArgStart); } "\"" { BEGIN(DocRefArg); } [^\"\n]+[\n\"] { yytext[yyleng-1]='\0'; QCString text=substitute(yytext,"\\\\","\\"); SectionInfo *sec; if ((sec=Doxygen::sectionDict[sectionRef])) { //printf("Is a section!\n"); if (sec->type==SectionInfo::Anchor) { outDoc->writeObjectLink(sec->ref,sec->fileName,sec->label,text); if (sec->ref.isEmpty()) { writePageRef(*outDoc,sec->label,0); } } else { outDoc->writeSectionRef(sec->ref,sec->fileName,sec->label,text); } } else if (!generateLink(*outDoc,className,sectionRef,TRUE,text)) { warn(yyFileName,yyLineNr,"Warning: reference to unknown section %s in the documentation of this entity!",sectionRef.data()); outDoc->startBold(); outDoc->writeString(" unknown reference! "); outDoc->endBold(); } BEGIN(DocScan); } {ID} { sectionRef=yytext; BEGIN(DocRefItemName); } .*/"\n" { SectionInfo *sec; QCString text=yytext; if ((sec=Doxygen::sectionDict[sectionRef])) { outDoc->writeSectionRefItem(sec->fileName,sec->label,text.stripWhiteSpace()); } else { warn(yyFileName,yyLineNr,"Warning: reference to unknown section %s in the documentation of this entity!",sectionRef.data()); outDoc->startBold(); outDoc->writeString(" unknown reference! "); outDoc->endBold(); } BEGIN(DocScan); } {CMD}"image"{B}+ { BEGIN(DocImage); } [hH][tT][mM][lL] { BEGIN(DocHtmlImageName); } [lL][aA][tT][eE][xX] { BEGIN(DocLatexImageName); } [rR][tT][fF] { BEGIN(DocRtfImageName); } [^ \t\n]+ { curImageName = findAndCopyImage(stripQuotes(yytext),IT_Html); curImageCaption.resize(0); if (curImageName.isEmpty()) { BEGIN(DocScan); } else { BEGIN(DocHtmlImageOpt); } } \n { writeImage(IT_Html,0); BEGIN(DocScan); } \"[^\n"]*\" { curImageCaption=stripQuotes(yytext); } {FILE} { curImageName = findAndCopyImage(stripQuotes(yytext),IT_RTF); curImageCaption.resize(0); if (curImageName.isEmpty()) { BEGIN(DocScan); } else { BEGIN(DocRtfImageOpt); } } \n { writeImage(IT_RTF,0); } \"[^\n"]*\" { curImageCaption=stripQuotes(yytext); } {FILE} { curImageName = findAndCopyImage(stripQuotes(yytext),IT_Latex); curImageCaption.resize(0); if (curImageName.isEmpty()) BEGIN(DocScan); else BEGIN(DocLatexImageOpt); } \n { // no width specified writeImage(IT_Latex,0); BEGIN(DocScan); } \"[^\n"]*\" { curImageCaption=stripQuotes(yytext); } ("width"{B}*"="{B}*)(([0-9\.]+({B}*{ID})?)|("\\"{ID})) { writeImage(IT_Latex,yytext); BEGIN(DocScan); } ("height"{B}*"="{B}*)(([0-9\.]+({B}*{ID})?)|("\\"{ID})) { writeImage(IT_Latex,yytext); BEGIN(DocScan); } [a-z_A-Z0-9\.\-]+ { warn(yyFileName,yyLineNr,"Warning: %s is an unsupported output format for \\image in the documentation of the entity",yytext); } \n { warn(yyFileName,yyLineNr,"Warning: invalid \\image command found in the documentation of this entity!"); outDoc->enableAll(); BEGIN(DocScan); } {CMD}"dotfile"{B}* { BEGIN(DocDotFile); } {FILE} { curDotFileName = stripQuotes(yytext); curDotFileCaption.resize(0); if (curDotFileName.isEmpty()) { BEGIN(DocScan); } else { BEGIN(DocDotFileOpt); } } \n { writeDotFile(curDotFileName,curDotFileCaption); BEGIN(DocScan); } \"[^\n"]*\" { curDotFileCaption = stripQuotes(yytext); writeDotFile(curDotFileName,curDotFileCaption); BEGIN(DocScan); } {CMD}"code"({BN}*"\n"|{B}*) { outDoc->startCodeFragment(); codeBlock.resize(0); BEGIN( DocCodeBlock ); } {CMD}"endcode"/[^a-z_A-Z0-9] { warn(yyFileName,yyLineNr,"Warning: \\endcode without \\code " "in the documentation of this entity."); } {ID}"<"[^>\ \t\n]*">"("::"{ID})+"("?[a-z_A-Z0-9,:\<\> \t\*\&]*")"? { if (!insideHtmlLink) { generateRef(*outDoc,className,yytext,inSeeBlock); } else { outDoc->docify(yytext); } BEGIN(DocScan); } {SCOPEMASK}"("[a-z_A-Z0-9,:\<\> \t\*\&]+")" { if (!insideHtmlLink) { generateRef(*outDoc,className,yytext,inSeeBlock); } else { outDoc->docify(yytext); } BEGIN(DocScan); } {SCOPEMASK}("()")? { if (!insideHtmlLink) { generateRef(*outDoc,className,yytext,inSeeBlock); } else { outDoc->docify(yytext); } BEGIN(DocScan); } ({SCOPEMASK}"::")?"operator"{OPMASK} { QCString oName=yytext; if (!insideHtmlLink) { generateRef(*outDoc,className, removeRedundantWhiteSpace(oName),inSeeBlock); } else { outDoc->docify(yytext); } BEGIN(DocScan); } ("http:"|"https:"|"ftp:"|"file:"){URLMASK} { outDoc->startHtmlLink(yytext); outDoc->docify(yytext); outDoc->endHtmlLink(); } [a-zA-Z_0-9\.\-]+"@"[0-9a-z_A-Z\.\-]+ { outDoc->writeMailLink(yytext); } {FILESCHAR}*{FILEECHAR}+/".\\n" { // special exception that is otherwise matches by FILEMASK if (!insideHtmlLink) { generateRef(*outDoc,className,yytext,inSeeBlock); } else { outDoc->docify(yytext); } } {FILEMASK} { if (!insideHtmlLink) { generateFileRef(*outDoc,yytext); } else { outDoc->docify(yytext); } } {BN}*{CMD}"endcode"/[^a-z_A-Z0-9] { // needed to match things like \endcode. (note the dot) codeBlock+="\n"; parseCode(*outDoc,className,codeBlock,exampleDoc,exampleName); //printf("Code block\n-------------\n%s\n--------------\n",codeBlock.data()); outDoc->endCodeFragment(); BEGIN( DocScan ); } {CMD}("e"|"em"|"a"){BN}+ { BEGIN( DocEmphasis ); } {CMD}"b"{BN}+ { BEGIN( DocBold ); } {CMD}("c"|"p"){BN}+ { BEGIN( DocCode ); } {CMD}"l"{BN}+ "\\n"/[^a-z_A-Z0-9] { outDoc->lineBreak(); } {CMD}"include"{BN}+ { BEGIN( DocInclude ); } {CMD}"dontinclude"{BN}+ { BEGIN( DocDontInclude ); } {CMD}"skip"{BN}+ { BEGIN( DocSkipKey ); } {CMD}"skipline"{BN}+ { BEGIN( DocSkiplineKey ); firstLine=TRUE; } {CMD}"line"{BN}+ { BEGIN( DocLineKey ); firstLine=TRUE; } {CMD}"until"{BN}+ { BEGIN( DocUntilKey ); firstLine=TRUE; } [^ \t\r\n]+ { if (includeFileLength>0) skipUntil(yytext); BEGIN( DocScan ); } [^ \t\r\n]+ { if (includeFileLength>0) { if (firstLine) outDoc->startCodeFragment(); firstLine=FALSE; showLine(*outDoc,yytext); BEGIN( DocKeyEnd ); } else { BEGIN( DocScan ); } } [^ \t\r\n]+ { if (includeFileLength>0) { if (firstLine) outDoc->startCodeFragment(); firstLine=FALSE; skipLine(*outDoc,yytext); BEGIN( DocKeyEnd ); } else { BEGIN( DocScan ); } } [^ \t\r\n]+ { if (includeFileLength>0) { if (firstLine) outDoc->startCodeFragment(); firstLine=FALSE; showUntil(*outDoc,yytext); BEGIN( DocKeyEnd ); } else { BEGIN( DocScan ); } } {CMD}"line"{BN}+ { BEGIN(DocLineKey); } {CMD}"until"{BN}+ { BEGIN(DocUntilKey); } {CMD}"skipline"{BN}+ { BEGIN(DocSkiplineKey); } \n <> { if (!firstLine) outDoc->endCodeFragment(); yyterminate(); } . { unput(*yytext); if (!firstLine) outDoc->endCodeFragment(); BEGIN( DocScan ); } "<"{MULTICOL}{ATTR}">" "" "<"{STRONG}{ATTR}">" { outDoc->startBold(); } "" { outDoc->endBold(); } "<"{CENTER}{ATTR}">" { outDoc->startCenter(); } "" { outDoc->endCenter(); } "<"{TABLE}{ATTR}">" { startTable(); } "" { endTable(); } "<"{INPUT}{ATTR}">" "<"{SMALL}{ATTR}">" { outDoc->startSmall(); } "" { outDoc->endSmall(); } "<"{META}{ATTR}">" "<"{FORM}{ATTR}">" "" "<"{HEAD}{ATTR}">" "" "<"{BODY}{ATTR}">" "" "<"{BLOCKQUOTE}{ATTR}">" "" "<"{CODE}{ATTR}">" { outDoc->startTypewriter(); } "" { outDoc->endTypewriter(); } "<"{DFN}{ATTR}">" { outDoc->startTypewriter(); } "" { outDoc->endTypewriter(); } "<"{VAR}{ATTR}">" { outDoc->startEmphasis(); } "" { outDoc->endEmphasis(); } "<"{IMG}{ATTR}">" { /*storeOutputListState();*/ outDoc->pushGeneratorState(); outDoc->disableAllBut(OutputGenerator::Html); outDoc->writeString(yytext); /*restoreOutputListState();*/ outDoc->popGeneratorState(); } "<"{PRE}{ATTR}">" { if (insidePre) { warn(yyFileName,yyLineNr,"Warning in the documentation of this entity:\nNested
 found in the documentation of this entity!");
					  }
  					  outDoc->startPreFragment(); 
					  insidePre=TRUE;
					}
""	        { 
  					  outDoc->endPreFragment(); 
					  insidePre=FALSE;
					}
"<"{SUB}{ATTR}">"		{ outDoc->startSubscript(); }
""		{ outDoc->endSubscript(); }
"<"{SUP}{ATTR}">"		{ outDoc->startSuperscript(); }
""		{ outDoc->endSuperscript(); }
"<"{TR}{ATTR}">"		{ if (curTable) curTable->newRow(); }
""			
"<"{TD}{ATTR}">"		{ if (curTable) curTable->newElem(); }
""
"<"{OL}{ATTR}">"{BN}*		{ outDoc->startEnumList(); 
  					  currentListIndent.push("O");
					}
""{BN}*		{ 
					  if (currentListIndent.isEmpty())
					  {
					    warn(yyFileName,yyLineNr,
                                                 "Warning in the documentation of this entity:\nMore  tags than 
    tags in the documentation of this entity." ); } else if (*currentListIndent.top()!='O') { warn(yyFileName,yyLineNr, "Warning in the documentation of this entity:\nThe
tag does not end a
    tag." ); } else { outDoc->endEnumList(); currentListIndent.pop(); } } "<"{UL}{ATTR}">"{BN}* { outDoc->startItemList(); currentListIndent.push("U"); } ""{BN}* { if (currentListIndent.isEmpty()) { warn(yyFileName,yyLineNr, "Warning in the documentation of this entity:\nMore tags than
      tags." ); } else if (*currentListIndent.top()!='U') { warn(yyFileName,yyLineNr, "Warning in the documentation of this entity:\nThe
    tag does not end a
      tag." ); } else { outDoc->endItemList(); currentListIndent.pop(); } } "<"{LI}{ATTR}">" { if (/*currentListIndent.isEmpty() ||*/ //DvH: I removed this check because I use this in the manual (the
        is in a \htmlonly block!) !currentListIndent.isEmpty() && *currentListIndent.top()=='D') { warn(yyFileName,yyLineNr, "Warning in the documentation of this entity:\nThe
      • tag can only be used inside a
          ...
        or a
          ...
        block." ); } else { outDoc->writeListItem(); } } "" "<"{TT}{ATTR}">" { outDoc->startTypewriter(); } "" { outDoc->endTypewriter(); } "<"{KBD}{ATTR}">" { outDoc->startTypewriter(); } "" { outDoc->endTypewriter(); } "<"{EM}{ATTR}">" { outDoc->startEmphasis(); } "" { outDoc->endEmphasis(); } "<"{HR}{ATTR}">" { outDoc->writeRuler(); } "<"{DL}{ATTR}">" { outDoc->startDescription(); currentListIndent.push("D"); } "" { if (currentListIndent.isEmpty()) { warn(yyFileName,yyLineNr, "Warning in the documentation of this entity:\nMore tags than
        tags in the documentation." ); } else if (*currentListIndent.top()!='D') { warn(yyFileName,yyLineNr, "Warning in the documentation of this entity:\nThe
        tag does not end a
        tag in the documentation." ); } else { outDoc->endDescription(); currentListIndent.pop(); } } "<"{DT}{ATTR}">" { if (currentListIndent.isEmpty() || *currentListIndent.top()!='D') { warn(yyFileName,yyLineNr, "Warning in the documentation of this entity:\nThe
        tag can only be used inside a
        ...
        block." ); } else { outDoc->startDescItem(); } } "" "<"{DD}{ATTR}">" { if (currentListIndent.isEmpty() || *currentListIndent.top()!='D') { warn(yyFileName,yyLineNr, "Warning in the documentation of this entity:\nThe
        tag can only be used inside a
        ...
        block." ); } else { outDoc->endDescItem(); } } "" "<"{BR}{ATTR}">" { outDoc->lineBreak(); } "<"{I}{ATTR}">" { outDoc->startEmphasis(); } "" { outDoc->endEmphasis(); } "" { if (insideHtmlLink) { outDoc->endHtmlLink(); insideHtmlLink=FALSE; } } "<"{A}{BN}+ { BEGIN(DocHtmlLink); } "<"{BOLD}{ATTR}">" { outDoc->startBold(); } "" { outDoc->endBold(); } "<"{P}{ATTR}">" { if (inBlock()) endBlock(); outDoc->newParagraph(); } "" "<"{H1}{ATTR}">" { outDoc->startTitle(); } "" { outDoc->endTitle(); } "<"{H2}{ATTR}">" { outDoc->startSubsection(); } "" { outDoc->endSubsection(); } "<"{H3}{ATTR}">" { outDoc->startSubsubsection(); } "" { outDoc->endSubsubsection(); } {NAME}{BN}*"="{BN}*("\""?) { BEGIN(DocHtmlAnchor); } [a-z_A-Z0-9.\-\+\/]+ { outDoc->writeAnchor(0,yytext); } {HREF}{BN}*"="{BN}*("\""?) { htmlUrl.resize(0); htmlText.resize(0); BEGIN(DocHtmlHref); } {URLMASK} { htmlUrl=yytext; } ">" { outDoc->startHtmlLink(htmlUrl); insideHtmlLink=TRUE; BEGIN(DocScan); } ">" { BEGIN(DocScan); } {CMD}("\\"|"@"|"<"|">"|"&"|"$"|"#"|"%") { outDoc->docify(&yytext[1]); } "%"[a-z_A-Z][a-z_A-Z0-9:\-]* { outDoc->docify(yytext+1); } {FILEMASK} { outDoc->startEmphasis(); if (!insideHtmlLink) { generateFileRef(*outDoc,yytext); } else { outDoc->docify(yytext); } outDoc->endEmphasis(); BEGIN( DocScan ); } [a-z_A-Z][a-z_A-Z:0-9<>&\-=^%~!\[\]()|\*/]*"("[a-z_A-Z0-9,:\<\> \t\*\&]*")" { outDoc->startEmphasis(); if (!insideHtmlLink) { generateRef(*outDoc,className,yytext,inSeeBlock); } else { outDoc->docify(yytext); } outDoc->endEmphasis(); BEGIN( DocScan ); } {WORD} { outDoc->startEmphasis(); if (!insideHtmlLink) { linkifyText(TextGeneratorOLImpl(*outDoc),className,0,yytext,FALSE,FALSE); } else { outDoc->docify(yytext); } outDoc->endEmphasis(); BEGIN( DocScan ); } {FILEMASK} { outDoc->startBold(); if (!insideHtmlLink) { generateFileRef(*outDoc,yytext); } else { outDoc->docify(yytext); } outDoc->endBold(); BEGIN( DocScan ); } [a-z_A-Z][a-z_A-Z:0-9<>&\-=^%~!\[\]()|\*/]*"("[a-z_A-Z0-9,:\<\> \t\*\&]*")" { outDoc->startBold(); if (!insideHtmlLink) { generateRef(*outDoc,className,yytext,inSeeBlock); } else { outDoc->docify(yytext); } outDoc->endBold(); BEGIN( DocScan ); } {WORD} { outDoc->startBold(); if (!insideHtmlLink) { linkifyText(TextGeneratorOLImpl(*outDoc),className,0,yytext,FALSE,FALSE); } else { outDoc->docify(yytext); } outDoc->endBold(); BEGIN( DocScan ); } {FILEMASK} { outDoc->startTypewriter(); if (!insideHtmlLink) { generateFileRef(*outDoc,yytext); } else { outDoc->docify(yytext); } outDoc->endTypewriter(); BEGIN( DocScan ); } [a-z_A-Z][a-z_A-Z:0-9<>&\-=^%~!\[\]()!\*/]*"("[a-z_A-Z0-9,:\<\> \t\*\&]*")" { outDoc->startTypewriter(); if (!insideHtmlLink) { generateRef(*outDoc,className,yytext,inSeeBlock); } else { outDoc->docify(yytext); } outDoc->endTypewriter(); BEGIN( DocScan ); } {WORD} { outDoc->startTypewriter(); if (!insideHtmlLink) { linkifyText(TextGeneratorOLImpl(*outDoc),className,0,yytext,FALSE,FALSE); } else { outDoc->docify(yytext); } outDoc->endTypewriter(); BEGIN( DocScan ); } {FILE} { includeFile(*outDoc,stripQuotes(yytext),FALSE); BEGIN( DocScan ); } {FILE} { includeFile(*outDoc,stripQuotes(yytext),TRUE); BEGIN( DocScan ); } "//" { codeBlock += yytext; } "/*" { codeBlock += yytext; } \n { codeBlock += '\n'; } [^\/\\\<\n]* { codeBlock += yytext; } . { codeBlock += *yytext; } "//" { outDoc->docify(yytext); } "/*" { outDoc->docify(yytext); } "\n" { outDoc->writeChar('\n'); } ({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(yytext,dashPos+1,isEnumerated); } ({B}*"\n"){2,}{B}* { // new paragraph bool ib = inBlock(); if (insideArgumentList) { insideArgumentList=FALSE; outDoc->endItemList(); if (ib) endBlock(); } else if (insideItemList) { forceEndItemList(); } else { if (insidePre) { outDoc->docify(yytext); } else if (!ib) { outDoc->newParagraph(); } if (ib) endBlock(); } } {BN}+/\n { outDoc->writeChar(' '); } \n?{B}* { if (insidePre) { outDoc->docify(yytext); } else { outDoc->writeChar(' '); } } [a-z_A-Z0-9]+ { outDoc->docify(yytext); } . { 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 scanDoc(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 internalParseDocument(const char *s) { if (s==0) return; 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(OutputDocInterface &od,const QCString &docString) { //inParamBlock=inSeeBlock=inReturnBlock=FALSE; curTable = 0; depthIf = 0; outDoc = od.clone(); currentIncludeFile.resize(0); includeFileOffset=0; includeFileLength=0; currentListIndent.clear(); listIndentStack.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("
"); break; case 'U': warn_cont(""); break; case 'D': warn_cont(""); 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!" ); } od.append(outDoc); delete outDoc; outDoc=0; return; } //---------------------------------------------------------------------------- void parseDoc(OutputDocInterface &od,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(od,docString); } //---------------------------------------------------------------------------- void parseText(OutputDocInterface &od,const QCString &txtString) { if (txtString.isEmpty()) return; inputString = txtString; outDoc = od.clone(); inputPosition = 0; docYYrestart( docYYin ); BEGIN( Text ); docYYlex(); od.append(outDoc); delete outDoc; outDoc=0; return; } //---------------------------------------------------------------------------- void parseExample(OutputDocInterface &od,const QCString &docString, const char *fileName) { initParser(); initParseCodeContext(); exampleDoc=TRUE; // cross reference with member docs exampleName=fileName; strcpy(yyFileName,fileName); parseDocument(od,docString); } //---------------------------------------------------------------------------- extern "C" { // some bogus code to keep the compiler happy void docYYdummy() { yy_flex_realloc(0,0); } }