From 76e39987363c93fdd3f2d99ffdb9f87743d6af7c Mon Sep 17 00:00:00 2001 From: dimitri Date: Sun, 10 Apr 2005 18:36:52 +0000 Subject: Release-1.4.2-20050410 --- INSTALL | 4 +- Makefile.in | 13 +- README | 4 +- VERSION | 2 +- addon/doxywizard/doxywizard.cpp | 7 +- configure | 13 +- doc/doxygen_usage.doc | 3 + doc/language.doc | 16 +- doc/maintainers.txt | 3 + doc/translator_report.txt | 32 +- packages/rpm/doxygen.spec | 2 +- src/commentcnv.l | 5 +- src/commentscan.h | 5 +- src/commentscan.l | 28 +- src/compound.xsd | 1 + src/compound_xsd.h | 1 + src/definition.cpp | 2 +- src/docparser.cpp | 10 +- src/doxygen.cpp | 240 ++-- src/doxygen.h | 3 - src/filedef.cpp | 13 +- src/filedef.h | 2 +- src/groupdef.cpp | 4 +- src/htmlgen.cpp | 2 + src/index.cpp | 2 +- src/lang_cfg.h | 1 + src/language.cpp | 9 + src/libdoxygen.pro.in | 1 + src/memberdef.cpp | 50 +- src/memberdef.h | 8 +- src/memberlist.cpp | 3 +- src/memberlist.h | 6 +- src/parserintf.h | 106 ++ src/pre.l | 8 +- src/scanner.h | 22 +- src/scanner.l | 2454 +++------------------------------------ src/search.php | 21 +- src/search_php.h | 21 +- src/searchindex.cpp | 23 +- src/translator.cpp | 75 +- src/translator.h | 4 +- src/translator_ca.h | 272 ++--- src/translator_de.h | 6 +- src/translator_id.h | 1597 +++++++++++++++++++++++++ src/translator_kr.h | 381 +++--- src/util.cpp | 3 +- src/xmlgen.cpp | 13 +- 47 files changed, 2600 insertions(+), 2901 deletions(-) create mode 100644 src/parserintf.h create mode 100644 src/translator_id.h diff --git a/INSTALL b/INSTALL index 545fd51..21b9011 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,7 @@ -DOXYGEN Version 1.4.2 +DOXYGEN Version 1.4.2-20050410 Please read the installation section of the manual (http://www.doxygen.org/install.html) for instructions. -------- -Dimitri van Heesch (28 March 2005) +Dimitri van Heesch (10 April 2005) diff --git a/Makefile.in b/Makefile.in index 149bef7..4b89e6d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -46,17 +46,18 @@ distclean: clean DATE=$(shell date "+%B %Y") +MAN1DIR = man/man1 + install: doxywizard_install $(INSTTOOL) -d $(INSTALL)/bin $(INSTTOOL) -m 755 bin/doxygen $(INSTALL)/bin $(INSTTOOL) -m 755 bin/doxytag $(INSTALL)/bin - $(INSTTOOL) -d $(INSTALL)/man/man1 - cat doc/doxygen.1 | sed -e "s/DATE/\$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > $(INSTALL)/man/man1/doxygen.1 ; \ - cat doc/doxytag.1 | sed -e "s/DATE/\$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > $(INSTALL)/man/man1/doxytag.1 ; \ - cat doc/doxywizard.1 | sed -e "s/DATE/\$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > $(INSTALL)/man/man1/doxywizard.1 ; - + $(INSTTOOL) -d $(INSTALL)/$(MAN1DIR) + cat doc/doxygen.1 | sed -e "s/DATE/\$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > $(INSTALL)/$(MAN1DIR)/doxygen.1 ; \ + cat doc/doxytag.1 | sed -e "s/DATE/\$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > $(INSTALL)/$(MAN1DIR)/doxytag.1 ; \ + cat doc/doxywizard.1 | sed -e "s/DATE/\$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > $(INSTALL)/$(MAN1DIR)/doxywizard.1 ; -install_docs: install +install_docs: $(INSTTOOL) -d $(DOCDIR) cp -r doc $(DOCDIR) cp -r examples $(DOCDIR) diff --git a/README b/README index 616363c..c82b69a 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOXYGEN Version 1.4.2 +DOXYGEN Version 1.4.2_20050410 Please read INSTALL for compilation instructions. @@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives. Enjoy, -Dimitri van Heesch (dimitri@stack.nl) (28 March 2005) +Dimitri van Heesch (dimitri@stack.nl) (10 April 2005) diff --git a/VERSION b/VERSION index 9df886c..147880e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.4.2 +1.4.2-20050410 diff --git a/addon/doxywizard/doxywizard.cpp b/addon/doxywizard/doxywizard.cpp index 2d3556b..b221530 100644 --- a/addon/doxywizard/doxywizard.cpp +++ b/addon/doxywizard/doxywizard.cpp @@ -31,6 +31,7 @@ #include "doxywizard.h" #include "expert.h" #include "config.h" +#include "version.h" const int messageTimeout = 5000; //!< status bar message timeout in millisec. @@ -1310,9 +1311,9 @@ void MainWidget::about() { QString msg; QTextStream t(&msg,IO_WriteOnly); - t << "
A tool to configure and run doxygen " - "on your source files.


" - "

Written by
Dimitri van Heesch
© 2000-2004

" + t << QString("

A tool to configure and run doxygen version ")+versionString+ + " on your source files.


" + "

Written by
Dimitri van Heesch
© 2000-2005

" ""; QMessageBox::about(this,"Doxygen GUI",msg); } diff --git a/configure b/configure index 6a53fa3..0781e41 100755 --- a/configure +++ b/configure @@ -28,7 +28,7 @@ f_insttool=NO f_english=NO f_wizard=NO f_thread=NO -f_langs=nl,se,cz,fr,it,de,jp,je,es,fi,ru,hr,pl,pt,hu,kr,ke,ro,si,cn,no,br,dk,sk,ua,gr,tw,sr,ca,lt,za +f_langs=nl,se,cz,fr,id,it,de,jp,je,es,fi,ru,hr,pl,pt,hu,kr,ke,ro,si,cn,no,br,dk,sk,ua,gr,tw,sr,ca,lt,za while test -n "$1"; do case $1 in @@ -145,12 +145,18 @@ if test -z "$f_platform"; then ;; Darwin:*) f_platform=macosx-c++ + if test "$f_insttool" = NO; then + f_insttool=/usr/bin/install + fi ;; FreeBSD:*) f_platform=freebsd-g++ ;; HP-UX:*) f_platform=hpux-g++ + if test "$f_insttool" = NO; then + f_insttool=/usr/bin/install + fi ;; IRIX64:*) f_platform=irix-64 @@ -181,6 +187,9 @@ if test -z "$f_platform"; then ;; SunOS:5*) f_platform=solaris-g++ + if test "$f_insttool" = NO; then + f_insttool=/usr/bin/install + fi ;; ULTRIX:*) f_platform=ultrix-g++ @@ -523,7 +532,7 @@ fi echo -n " Generating src/lang_cfg.h..." echo $f_langs | $f_perl -e '@l=split(/,/,); chomp @l; - @allowed=(split(/,/,"NL,SE,CZ,FR,IT,DE,JP,JE,ES,FI,RU,HR,PL,PT,HU,KR,KE,RO,SI,CN,NO,BR,DK,SK,UA,GR,TW,SR,CA,LT,ZA")); + @allowed=(split(/,/,"NL,SE,CZ,FR,ID,IT,DE,JP,JE,ES,FI,RU,HR,PL,PT,HU,KR,KE,RO,SI,CN,NO,BR,DK,SK,UA,GR,TW,SR,CA,LT,ZA")); foreach my $elem (@l){ $elem =~ tr/a-z/A-Z/; $r=0; diff --git a/doc/doxygen_usage.doc b/doc/doxygen_usage.doc index fa57ea4..18773e5 100644 --- a/doc/doxygen_usage.doc +++ b/doc/doxygen_usage.doc @@ -72,6 +72,9 @@ doxygen -w html header.html footer.html stylesheet.css \verbatim doxygen -w latex header.tex doxygen.sty \endverbatim +If you need non-default options (for instance to use pdflatex) you need +to make a config file with those options set correctly and then specify +that config file as the forth argument.

  • For RTF output, you can generate the default style sheet file (see \ref cfg_rtf_stylesheet_file "RTF_STYLESHEET_FILE") using: \verbatim diff --git a/doc/language.doc b/doc/language.doc index cbe7d25..cf80d6a 100644 --- a/doc/language.doc +++ b/doc/language.doc @@ -23,13 +23,13 @@ text fragments, generated by doxygen, can be produced in languages other than English (the default). The output language is chosen through the configuration file (with default name and known as Doxyfile). -Currently (version 1.4.1-20050315), 30 languages +Currently (version 1.4.2), 31 languages are supported (sorted alphabetically): Afrikaans, Brazilian Portuguese, Catalan, Chinese, Chinese Traditional, Croatian, Czech, Danish, Dutch, English, Finnish, French, -German, Greek, Hungarian, Italian, Japanese (+En), Korean (+En), -Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, Serbian, -Slovak, Slovene, Spanish, Swedish, and Ukrainian.. +German, Greek, Hungarian, Indonesian, Italian, Japanese (+En), Korean +(+En), Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.. The table of information related to the supported languages follows. It is sorted by language alphabetically. The Status column @@ -141,6 +141,12 @@ when the translator was updated. 1.4.1 + Indonesian + Hendy Irawan + ceefour at gauldong dot net + up-to-date + + Italian Alessandro Falappa
    Ahmed Aldo Faisal alessandro at falappa dot net
    aaf23 at cam dot ac dot uk @@ -291,6 +297,8 @@ when the translator was updated. Hungarian & \'{A}kos Kiss & {\tt\tiny akiss@users.sourceforge.net} & 1.4.1 \\ ~ & F\"{o}ldv\'{a}ri Gy\"{o}rgy & {\tt\tiny foldvari lost@cyberspace} & ~ \\ \hline + Indonesian & Hendy Irawan & {\tt\tiny ceefour@gauldong.net} & up-to-date \\ + \hline Italian & Alessandro Falappa & {\tt\tiny alessandro@falappa.net} & up-to-date \\ ~ & Ahmed Aldo Faisal & {\tt\tiny aaf23@cam.ac.uk} & ~ \\ \hline diff --git a/doc/maintainers.txt b/doc/maintainers.txt index 5140334..bbb36f2 100644 --- a/doc/maintainers.txt +++ b/doc/maintainers.txt @@ -58,6 +58,9 @@ TranslatorHungarian Ákos Kiss: akiss@users.sourceforge.net Földvári György: foldvari lost@cyberspace +TranslatorIndonesian +Hendy Irawan: ceefour@gauldong.net + TranslatorItalian Alessandro Falappa: alessandro@falappa.net Ahmed Aldo Faisal: aaf23@cam.ac.uk diff --git a/doc/translator_report.txt b/doc/translator_report.txt index bbec1bd..ef5e72e 100644 --- a/doc/translator_report.txt +++ b/doc/translator_report.txt @@ -1,14 +1,14 @@ -(1.4.1-20050315) +(1.4.2) -Doxygen supports the following 30 languages (sorted alphabetically): +Doxygen supports the following 31 languages (sorted alphabetically): Afrikaans, Brazilian Portuguese, Catalan, Chinese, Chinese Traditional, Croatian, Czech, Danish, Dutch, English, Finnish, French, -German, Greek, Hungarian, Italian, Japanese (+En), Korean (+En), -Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, Serbian, -Slovak, Slovene, Spanish, Swedish, and Ukrainian. +German, Greek, Hungarian, Indonesian, Italian, Japanese (+En), Korean +(+En), Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. -Of them, 9 translators are up-to-date, 21 translators are based on +Of them, 10 translators are up-to-date, 21 translators are based on some adapter class, and 2 are English based. ---------------------------------------------------------------------- @@ -23,6 +23,7 @@ still may be some details listed even for them: TranslatorDutch -- Remove the obsolete methods (never used). TranslatorEnglish -- Remove the obsolete methods (never used). TranslatorGerman -- Remove the obsolete methods (never used). + TranslatorIndonesian -- Remove the obsolete methods (never used). TranslatorItalian TranslatorRussian TranslatorSwedish @@ -476,6 +477,25 @@ TranslatorHungarian (TranslatorAdapter_1_4_1) 1 method to implement QCString trNoDescriptionAvailable() +TranslatorIndonesian (Translator) +-------------------- + + Implements 192 of the required methods. + + Obsolete methods (should be removed, never used): + + virtual QCString trHeaderFilesDescription() + virtual QCString trField(bool first_capital, bool singular) + virtual QCString trPackageDocumentation() + virtual QCString trSources() + virtual QCString trReimplementedForInternalReasons() + virtual QCString trInterfaces() + virtual QCString trHeaderFiles() + virtual QCString trBugsAndLimitations() + virtual QCString trEnumerationValueDocumentation() + virtual QCString trNoDescriptionAvailable() + + TranslatorJapanese (TranslatorAdapter_1_3_9) 7 methods to implement ------------------ diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec index 666ffbd..e6d8ada 100644 --- a/packages/rpm/doxygen.spec +++ b/packages/rpm/doxygen.spec @@ -1,6 +1,6 @@ Summary: A documentation system for C/C++. Name: doxygen -Version: 1.4.2 +Version: 1.4.2_20050410 Release: 1 Epoch: 1 Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz diff --git a/src/commentcnv.l b/src/commentcnv.l index 10973aa..c93b0c0 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -320,7 +320,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) copyToOutput(yytext,yyleng); BEGIN(CComment); } -[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly"|"dot"|"code") { /* start of a verbatim block */ +[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly"|"dot"|"code")/[ \r\t\n] { /* start of a verbatim block */ copyToOutput(yytext,yyleng); g_blockName=&yytext[1]; g_lastCommentContext = YY_START; @@ -423,7 +423,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) copyToOutput(yytext,yyleng); BEGIN(g_readLineCtx); } -("\\\\"|"@@")[~a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command +[\\@][\\@][~a-z_A-Z][a-z_A-Z0-9]*[ \t]* { // escaped command copyToOutput(yytext,yyleng); } [\\@]"cond"[ \t]+ { // conditional section @@ -507,6 +507,7 @@ void replaceComment(int offset) */ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) { + //printf("convertCppComments(%s)\n",fileName); g_inBuf = inBuf; g_outBuf = outBuf; g_inBufPos = 0; diff --git a/src/commentscan.h b/src/commentscan.h index d954a93..9d7fe7b 100644 --- a/src/commentscan.h +++ b/src/commentscan.h @@ -19,7 +19,10 @@ #include "qtbc.h" #include "entry.h" -bool parseCommentBlock(/* in,out */ Entry *curEntry, +class ParserInterface; + +bool parseCommentBlock(/* in */ ParserInterface *parser, + /* in,out */ Entry *curEntry, /* in */ const QCString &comment, /* in */ const QCString &fileName, /* in */ int lineNr, diff --git a/src/commentscan.l b/src/commentscan.l index 225706b..bcbd296 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -44,6 +44,7 @@ #include "reflist.h" #include "code.h" #include "debug.h" +#include "parserintf.h" // forward declarations static void handleBrief(const QCString &); @@ -288,6 +289,7 @@ class GuardedSection * statics */ +static ParserInterface *langParser; // the language parser that is calling us static const char * inputString; // input string static int inputPosition; // read pointer static QCString yyFileName; // file name that is read from @@ -322,6 +324,7 @@ static QCString xrefListTitle; static Protection protection; static bool xrefAppendFlag; +static bool inGroupParamFound; //----------------------------------------------------------------------------- @@ -812,10 +815,11 @@ SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) BEGIN(ReadFormulaLong); } {CMD}"{" { // begin of a group - handleGroupStartCommand(nameHeader); + langParser->handleGroupStartCommand(nameHeader); } {CMD}"}" { // end of a group - handleGroupEndCommand(); + langParser->handleGroupEndCommand(); + nameHeader.resize(0); } {CMD}[$@\\&~<>#%] { // escaped character addOutput(yytext); @@ -1507,12 +1511,15 @@ SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) current->groups->append( new Grouping(yytext, Grouping::GROUPING_INGROUP) ); - BEGIN( Comment ); + inGroupParamFound=TRUE; } {DOCNL} { // missing argument - warn(yyFileName,yyLineNr, - "Warning: Missing group name for \\ingroup command" - ); + if (!inGroupParamFound) + { + warn(yyFileName,yyLineNr, + "Warning: Missing group name for \\ingroup command" + ); + } if (*yytext=='\n') yyLineNr++; addOutput('\n'); BEGIN( Comment ); @@ -1530,7 +1537,7 @@ SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) {DOCNL} { // end of argument if (*yytext=='\n') yyLineNr++; addOutput('\n'); - parsePrototype(functionProto); + langParser->parsePrototype(functionProto); BEGIN( Comment ); } {LC} { // line continuation @@ -1558,7 +1565,7 @@ SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) else // overload declaration { makeStructuralIndicator(Entry::OVERLOADDOC_SEC); - parsePrototype(functionProto); + langParser->parsePrototype(functionProto); } BEGIN( Comment ); } @@ -1913,6 +1920,7 @@ static void handleEndIf(const QCString &) static void handleIngroup(const QCString &) { + inGroupParamFound=FALSE; BEGIN( InGroupParam ); } @@ -2010,7 +2018,8 @@ static void checkFormula() //---------------------------------------------------------------------------- -bool parseCommentBlock(/* in,out */ Entry *curEntry, +bool parseCommentBlock(/* in */ ParserInterface *parser, + /* in,out */ Entry *curEntry, /* in */ const QCString &comment, /* in */ const QCString &fileName, /* in */ int lineNr, @@ -2025,6 +2034,7 @@ bool parseCommentBlock(/* in,out */ Entry *curEntry, initParser(); guards.setAutoDelete(TRUE); guards.clear(); + langParser = parser; current = curEntry; inputString = comment; if (inputString==0) return FALSE; // avoid empty strings diff --git a/src/compound.xsd b/src/compound.xsd index 367fdd0..561ab94 100644 --- a/src/compound.xsd +++ b/src/compound.xsd @@ -253,6 +253,7 @@ + diff --git a/src/compound_xsd.h b/src/compound_xsd.h index 7766410..2d93a57 100644 --- a/src/compound_xsd.h +++ b/src/compound_xsd.h @@ -253,6 +253,7 @@ " \n" " \n" " \n" +" \n" " \n" " \n" " \n" diff --git a/src/definition.cpp b/src/definition.cpp index 5fb5092..64db73d 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -249,7 +249,7 @@ static bool readCodeFragment(const char *fileName, { //printf("readCodeFragment(%s,%d,%d)\n",fileName,startLine,endLine); if (fileName==0 || fileName[0]==0) return FALSE; // not a valid file name - QCString cmd=getFileFilter(fileName)+" \""+fileName+"\""; + QCString cmd="\"" + getFileFilter(fileName)+"\" \""+fileName+"\""; FILE *f = Config_getBool("FILTER_SOURCE_FILES") ? popen(cmd,"r") : fopen(fileName,"r"); bool found=FALSE; if (f) diff --git a/src/docparser.cpp b/src/docparser.cpp index 66b0203..c3208eb 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -864,7 +864,7 @@ static void handleLinkedWord(DocNode *parent,QList &children) resolveRef(g_context,g_token->name,g_inSeeBlock,&compound,&member)) { //printf("resolveRef %s = %p (linkable?=%d)\n",g_token->name.data(),member,member ? member->isLinkable() : FALSE); - if (member) // member link + if (member && member->isLinkable()) // member link { children.append(new DocLinkedWord(parent,name, @@ -874,7 +874,7 @@ static void handleLinkedWord(DocNode *parent,QList &children) ) ); } - else // compound link + else if (compound->isLinkable()) // compound link { if (compound->definitionType()==Definition::TypeFile) { @@ -892,8 +892,12 @@ static void handleLinkedWord(DocNode *parent,QList &children) ) ); } + else // not linkable + { + children.append(new DocWord(parent,name)); + } } - else if (!g_insideHtmlLink && g_token->name.at(len-1)==':') + else if (!g_insideHtmlLink && len>1 && g_token->name.at(len-1)==':') { // special case, where matching Foo: fails to be an Obj-C reference, // but Foo itself might be linkable. diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 7a0ab82..5a6b965 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -65,6 +65,7 @@ #include "commentcnv.h" #include "cmdmapper.h" #include "searchindex.h" +#include "parserintf.h" #if defined(_MSC_VER) || defined(__BORLANDC__) #define popen _popen @@ -214,7 +215,16 @@ static void addRelatedPage(Entry *root) if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict[g->groupname])) break; } //printf("---> addRelatedPage() %s gd=%p\n",root->name.data(),gd); - PageDef *pd = addRelatedPage(root->name,root->args,root->doc,root->anchors, + QCString doc; + if (root->brief.isEmpty()) + { + doc=root->doc; + } + else + { + doc=root->brief+"\n\n"+root->doc; + } + PageDef *pd = addRelatedPage(root->name,root->args,doc,root->anchors, root->fileName,root->startLine, root->sli, gd,root->tagInfo @@ -2261,16 +2271,23 @@ static void buildFunctionList(Entry *root) rname=rname.right(rname.length()-root->parent->name.length()-2); } + NamespaceDef *nd = 0; bool isMember=FALSE; - int memIndex=rname.find("::"); + int memIndex=rname.findRev("::"); if (memIndex!=-1) { int ts=rname.find('<'); int te=rname.find('>'); if (ts==-1 || te==-1) { - NamespaceDef *nd = Doxygen::namespaceSDict.find(rname.left(memIndex)); - isMember=nd==0; + nd = Doxygen::namespaceSDict.find(rname.left(memIndex)); + isMember = nd==0; + if (nd) + { + // strip namespace scope from name + scope=rname.left(memIndex); + rname=rname.right(rname.length()-memIndex-2); + } } else { @@ -2288,7 +2305,7 @@ static void buildFunctionList(Entry *root) ) ) { - Debug::print(Debug::Functions,0,"--> member %s of class %s!\n", + Debug::print(Debug::Functions,0," --> member %s of class %s!\n", rname.data(),cd->name().data()); addMethodToClass(root,cd,rname,isFriend); } @@ -2308,26 +2325,25 @@ static void buildFunctionList(Entry *root) */ bool found=FALSE; MemberName *mn; - //MemberDef *fmd; + MemberDef *md=0; if ((mn=Doxygen::functionNameSDict[rname])) { - Debug::print(Debug::Functions,0,"--> function %s already found!\n",rname.data()); + Debug::print(Debug::Functions,0," --> function %s already found!\n",rname.data()); MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst();((md=mni.current()) && !found);++mni) + for (mni.toFirst();(!found && (md=mni.current()));++mni) { - NamespaceDef *nd = md->getNamespaceDef(); + NamespaceDef *mnd = md->getNamespaceDef(); NamespaceDef *rnd = 0; if (!root->parent->name.isEmpty()) { rnd = getResolvedNamespace(root->parent->name); } - FileDef *fd = md->getFileDef(); + FileDef *mfd = md->getFileDef(); QCString nsName,rnsName; - if (nd) nsName = nd->name().copy(); + if (mnd) nsName = mnd->name().copy(); if (rnd) rnsName = rnd->name().copy(); - NamespaceSDict *unl = fd ? fd->getUsedNamespaces() : 0; - SDict *ucl = fd ? fd->getUsedClasses() : 0; + NamespaceSDict *unl = mfd ? mfd->getUsedNamespaces() : 0; + SDict *ucl = mfd ? mfd->getUsedClasses() : 0; //printf("matching arguments for %s%s %s%s\n", // md->name().data(),md->argsString(),rname.data(),argListToString(root->argList).data()); if ( @@ -2341,9 +2357,9 @@ static void buildFunctionList(Entry *root) } //printf("match!\n"); // see if we need to create a new member - found=(nd && rnd && nsName==rnsName) || // members are in the same namespace - ((nd==0 && rnd==0 && fd!=0 && // no external reference and - fd->absFilePath()==root->fileName // prototype in the same file + found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace + ((mnd==0 && rnd==0 && mfd!=0 && // no external reference and + mfd->absFilePath()==root->fileName // prototype in the same file ) ); // otherwise, allow a duplicate global member with the same argument list @@ -2378,7 +2394,7 @@ static void buildFunctionList(Entry *root) md->setArgumentList(argList); } } - else if (!md->documentation().isEmpty() && !root->doc.isEmpty() && nd==rnd) + else if (!md->documentation().isEmpty() && !root->doc.isEmpty() && mnd==rnd) { warn(root->docFile,root->docLine,"Warning: member %s: ignoring the detailed description found here, since another one was found at line %d of file %s!",md->name().data(),md->docLine(),md->docFile().data()); } @@ -2387,7 +2403,7 @@ static void buildFunctionList(Entry *root) { md->setBriefDescription(root->brief,root->briefFile,root->briefLine); } - else if (!md->briefDescription().isEmpty() && !root->brief.isEmpty() && nd==rnd) + else if (!md->briefDescription().isEmpty() && !root->brief.isEmpty() && mnd==rnd) { warn(root->briefFile,root->briefLine,"Warning: member %s: ignoring the brief description found here, since another one was found at line %d of file %s!",md->name().data(),md->briefLine(),md->briefFile().data()); } @@ -2416,19 +2432,19 @@ static void buildFunctionList(Entry *root) } if (!found) /* global function is unique with respect to the file */ { + Debug::print(Debug::Functions,0," --> new function %s found!\n",rname.data()); //printf("New function type=`%s' name=`%s' args=`%s' bodyLine=%d\n", // root->type.data(),rname.data(),root->args.data(),root->bodyLine); // new global function ArgumentList *tArgList = root->tArgLists ? root->tArgLists->last() : 0; QCString name=removeRedundantWhiteSpace(rname); - MemberDef *md=new MemberDef( + md=new MemberDef( root->fileName,root->startLine, root->type,name,root->args,root->exception, root->protection,root->virt,root->stat,FALSE, MemberDef::Function,tArgList,root->argList); - md->setTagInfo(root->tagInfo); //md->setDefFile(root->fileName); //md->setDefLine(root->startLine); @@ -2446,27 +2462,26 @@ static void buildFunctionList(Entry *root) md->setMemberSpecifiers(root->memSpec); md->setMemberGroupId(root->mGrpId); - // see if the function is inside a namespace - NamespaceDef *nd = 0; - QCString scope; - if (root->parent->section == Entry::NAMESPACE_SEC ) + // see if the function is inside a namespace that was not part of + // the name already (in that case nd should be non-zero already) + if (nd==0 && root->parent->section == Entry::NAMESPACE_SEC ) { QCString nscope=removeAnonymousScopes(root->parent->name); if (!nscope.isEmpty()) { nd = getResolvedNamespace(nscope); - if (nd) - { - scope+=nd->name(); - if (Config_getBool("OPTIMIZE_OUTPUT_JAVA")) - { - scope+="."; - } - else - { - scope+="::"; - } - } + } + } + + if (!scope.isEmpty()) + { + if (Config_getBool("OPTIMIZE_OUTPUT_JAVA")) + { + scope = substitute(scope,"::",".")+"."; + } + else + { + scope+="::"; } } @@ -2518,7 +2533,6 @@ static void buildFunctionList(Entry *root) nd->insertMember(md); md->setNamespace(nd); } - if (fd) { // add member to the file (we do this even if we have already @@ -2551,7 +2565,14 @@ static void buildFunctionList(Entry *root) } else { - //printf("Function already found!\n"); + bool ambig; + FileDef *fd=findFileDef(Doxygen::inputNameDict,root->fileName,ambig); + if (fd) + { + // add member to the file (we do this even if we have already + // inserted it into the namespace) + fd->insertMember(md); + } } //printf("unrelated function %d `%s' `%s' `%s'\n", @@ -4215,7 +4236,7 @@ static bool findGlobalMember(Entry *root, } } } - if (!found) // no match + if (!found && !root->relatesDup) // no match { QCString fullFuncDecl=decl; if (root->argList) fullFuncDecl+=argListToString(root->argList); @@ -5297,6 +5318,15 @@ static void findMemberDocumentation(Entry *root) root->type.data(),root->inside.data(),root->name.data(),root->args.data(),root->section,root->memSpec,root->mGrpId ); bool isFunc=TRUE; + + if (root->relatesDup && !root->relates.isEmpty()) + { + QCString tmp = root->relates; + root->relates.resize(0); + findMemberDocumentation(root); + root->relates = tmp; + } + if ( // detect func variable/typedef to func ptr (i=findFunctionPtr(root->type,&l))!=-1 ) @@ -5669,27 +5699,30 @@ static void findEnumDocumentation(Entry *root) && root->name[0]!='@' // skip anonymous enums ) { - //printf("Found docs for enum with name `%s'\n",root->name.data()); + //printf("Found docs for enum with name `%s' in context %s\n", + // root->name.data(),root->parent->name.data()); int i; - ClassDef *cd=0; QCString name; - if ((i=root->name.findRev("::"))!=-1) // scope is specified + QCString scope; + if ((i=root->name.findRev("::"))!=-1) // scope is specified as part of the name { - QCString scope=root->name.left(i); // extract scope name=root->name.right(root->name.length()-i-2); // extract name - cd=getClass(scope); + scope=root->name.left(i); // extract scope //printf("Scope=`%s' Name=`%s'\n",scope.data(),name.data()); } - else // no scope, check the scope in which the docs where found + else // just the name { - if (( root->parent->section & Entry::COMPOUND_MASK ) - && !root->parent->name.isEmpty() - ) // found enum docs inside a compound - { - cd=getClass(root->parent->name); - } - name=root->name.copy(); + name=root->name; + } + if (( root->parent->section & Entry::SCOPE_MASK ) + && !root->parent->name.isEmpty() + ) // found enum docs inside a compound + { + if (!scope.isEmpty()) scope.prepend("::"); + scope.prepend(root->parent->name); } + ClassDef *cd=getClass(scope); + if (!name.isEmpty()) { bool found=FALSE; @@ -7270,7 +7303,7 @@ static void copyAndFilterFile(const char *fileName,BufStr &dest) } else { - QCString cmd=filterName+" \""+fileName+"\""; + QCString cmd="\""+filterName+"\" \""+fileName+"\""; FILE *f=popen(cmd,"r"); if (!f) { @@ -7339,8 +7372,7 @@ static void copyStyleSheet() } } -#ifdef USE_TMP_FILE - +#if 0 static void readFiles(const QCString &tmpFile) { QFile outFile(tmpFile); @@ -7386,36 +7418,27 @@ static void readFiles(const QCString &tmpFile) } } } +#endif -#else -//---------------------------------------------------------------------------- -// Reads a file to a string. -// The name of the file is written in front of the file's contents and -// between 0x06 markers - -static void readFiles(BufStr &output) +static void parseFiles(Entry *root) { + ParserInterface *defaultParser = new CLanguageScanner; + ParserManager *parserManager = new ParserManager(defaultParser); + + // register any additional parsers here... + QCString *s=inputFiles.first(); while (s) { QCString fileName=*s; + QCString extension; + int ei = fileName.findRev('.'); + if (ei!=-1) extension=fileName.right(fileName.length()-ei); - int fileNameSize=fileName.length(); - - //bool multiLineIsBrief = Config_getBool("MULTILINE_CPP_IS_BRIEF"); - - BufStr tempBuf(20000); - //BufStr *bufPtr = multiLineIsBrief ? &output : &tempBuf; - BufStr *bufPtr = &tempBuf; + QFileInfo fi(fileName); + BufStr preBuf(fi.size()+4096); + BufStr *bufPtr = &preBuf; - // add begin filename marker - bufPtr->addChar(0x06); - // copy filename - bufPtr->addArray(fileName.data(),fileNameSize); - - // add end filename marker - bufPtr->addChar(0x06); - bufPtr->addChar('\n'); if (Config_getBool("ENABLE_PREPROCESSING")) { msg("Preprocessing %s...\n",s->data()); @@ -7429,14 +7452,18 @@ static void readFiles(BufStr &output) bufPtr->addChar('\n'); /* to prevent problems under Windows ? */ - convertCppComments(&tempBuf,&output,fileName); + BufStr convBuf(bufPtr->curPos()+1024); + + convertCppComments(&preBuf,&convBuf,fileName); + + convBuf.addChar('\0'); + + ParserInterface *parser = parserManager->getParser(extension); + parser->parse(fileName,convBuf.data(),root); s=inputFiles.next(); - //printf("-------> adding new line\n"); } - output.addChar(0); } -#endif //---------------------------------------------------------------------------- // Read all files matching at least one pattern in `patList' in the @@ -8285,14 +8312,15 @@ void parseInput() // strip trailing slashes if (path.at(l-1)=='\\' || path.at(l-1)=='/') path=path.left(l-1); - inputSize+=readFileOrDirectory(path,&Doxygen::inputNameList, + inputSize+=readFileOrDirectory( + path,&Doxygen::inputNameList, Doxygen::inputNameDict,&excludeNameDict, - &Config_getList("FILE_PATTERNS"), - &Config_getList("EXCLUDE_PATTERNS"), - &inputFiles,0, - alwaysRecursive, - TRUE, - killDict); + &Config_getList("FILE_PATTERNS"), + &Config_getList("EXCLUDE_PATTERNS"), + &inputFiles,0, + alwaysRecursive, + TRUE, + killDict); s=inputList.next(); } delete killDict; @@ -8466,8 +8494,7 @@ void parseInput() * Read Input Files * **************************************************************************/ -#ifdef USE_TMP_FILE - +#if 0 QCString tmpName = Config_getString("OUTPUT_DIRECTORY")+ "/doxygen_scratchfile.tmp"; @@ -8493,36 +8520,9 @@ void parseInput() // remove temp file QDir().remove(tmpName); - -#else // use memory to store intermediate results - - BufStr input(inputSize+1); // Add one byte extra for \0 termination - - // read and preprocess all input files - readFiles(input); - - if (input.isEmpty()) - { - err("No input read, no output generated!\n"); - delete root; - cleanUpDoxygen(); - exit(1); - } - else - { - msg("Read %d bytes\n",input.curPos()); - } - - root->program=input; - - msg("Parsing input...\n"); - parseMain(root); // build a tree of entries - - msg("Freeing input...\n"); - input.resize(0); - #endif - + parseFiles(root); + /************************************************************************** * Gather information * **************************************************************************/ diff --git a/src/doxygen.h b/src/doxygen.h index 418a680..78067ae 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -123,7 +123,4 @@ void readConfiguration(int argc, char **argv); void parseInput(); void generateOutput(); -//#undef USE_TMP_FILE -#define USE_TMP_FILE - #endif diff --git a/src/filedef.cpp b/src/filedef.cpp index fba0573..3895db4 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -97,6 +97,15 @@ FileDef::FileDef(const char *p,const char *nm, memberGroupSDict = new MemberGroupSDict; memberGroupSDict->setAutoDelete(TRUE); acquireFileVersion(); + + // members in the detailed part of the documentation + docDefineMembers.setInFile(TRUE); + docProtoMembers.setInFile(TRUE); + docTypedefMembers.setInFile(TRUE); + docEnumMembers.setInFile(TRUE); + docFuncMembers.setInFile(TRUE); + docVarMembers.setInFile(TRUE); + } /*! destroy the file definition */ @@ -675,6 +684,8 @@ void FileDef::addMembersToMemberGroup() void FileDef::insertMember(MemberDef *md) { //printf("%s:FileDef::insertMember(%s)\n",name().data(),md->name().data()); + if (allMemberList.find(md)!=-1) return; + allMemberList.append(md); bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS"); bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS"); @@ -1220,7 +1231,7 @@ void FileDef::acquireFileVersion() if (!vercmd.isEmpty()) { msg("Version of %s : ",filepath.data()); - FILE *f=popen(vercmd+" "+filepath,"r"); + FILE *f=popen("\""+vercmd+"\" \""+filepath+"\"","r"); if (!f) { err("Error: could not execute %s\n",vercmd.data()); diff --git a/src/filedef.h b/src/filedef.h index 6dcd726..0550074 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -178,7 +178,7 @@ class FileDef : public Definition MemberList decFuncMembers; MemberList decVarMembers; - // members in the documentation part of the documentation + // members in the detailed part of the documentation MemberList docDefineMembers; MemberList docProtoMembers; MemberList docTypedefMembers; diff --git a/src/groupdef.cpp b/src/groupdef.cpp index b3af64c..aa0f727 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -327,8 +327,8 @@ bool GroupDef::insertMember(MemberDef *md,bool docOnly) break; default: err("GroupDef::insertMembers(): " - "member `%s' with class scope `%s' inserted in group scope `%s'!\n", - md->name().data(), + "member `%s' (typeid=%d) with scope `%s' inserted in group scope `%s'!\n", + md->name().data(),md->memberType(), md->getClassDef() ? md->getClassDef()->name().data() : "", name().data()); } diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index a435d61..21b656b 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -1368,7 +1368,9 @@ void HtmlGenerator::writeLineNumber(const char *ref,const char *file, } else { + startCodeAnchor(lineAnchor); codify(lineNumber); + endCodeAnchor(); } codify(" "); } diff --git a/src/index.cpp b/src/index.cpp index a270a1b..07c77f6 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -2704,7 +2704,7 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,int level) MemberDef *md=members->first(); while (md) { - if (md->isDetailedSectionVisible(TRUE)) + if (md->isDetailedSectionVisible(TRUE,FALSE)) { if (first) { diff --git a/src/lang_cfg.h b/src/lang_cfg.h index e44d5f5..d99d747 100644 --- a/src/lang_cfg.h +++ b/src/lang_cfg.h @@ -2,6 +2,7 @@ #define LANG_SE #define LANG_CZ #define LANG_FR +#define LANG_ID #define LANG_IT #define LANG_DE #define LANG_JP diff --git a/src/language.cpp b/src/language.cpp index 8b8f426..b6e12f2 100644 --- a/src/language.cpp +++ b/src/language.cpp @@ -34,6 +34,9 @@ #ifdef LANG_FR #include "translator_fr.h" #endif +#ifdef LANG_ID +#include "translator_id.h" +#endif #ifdef LANG_IT #include "translator_it.h" #endif @@ -165,6 +168,12 @@ bool setTranslator(const char *langName) theTranslator=new TranslatorFrench; } #endif +#ifdef LANG_ID + else if (L_EQUAL("indonesian")) + { + theTranslator=new TranslatorIndonesian; + } +#endif #ifdef LANG_IT else if (L_EQUAL("italian")) { diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in index 55b97ab..58b135f 100644 --- a/src/libdoxygen.pro.in +++ b/src/libdoxygen.pro.in @@ -100,6 +100,7 @@ HEADERS = bufstr.h \ translator_gr.h \ translator_hr.h \ translator_hu.h \ + translator_id.h \ translator_it.h \ translator_je.h \ translator_jp.h \ diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 0377bb7..7449569 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -676,13 +676,22 @@ void MemberDef::setDefinitionTemplateParameterLists(QList *lists) } void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *, - FileDef *,GroupDef *gd) + FileDef *fd,GroupDef *gd,bool onlyText) { QCString sep = Config_getBool("OPTIMIZE_OUTPUT_JAVA") ? "." : "::"; QCString n = name(); if (classDef && gd) n.prepend(classDef->name()+sep); - else if (nspace && gd) n.prepend(nspace->name()+sep); - ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),n); + else if (nspace && (gd || fd)) n.prepend(nspace->name()+sep); + if (!onlyText) // write link + { + ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),n); + } + else // write only text + { + ol.startBold(); + ol.docify(n); + ol.endBold(); + } } /*! If this member has an anonymous class/struct/union as its type, then @@ -901,10 +910,10 @@ void MemberDef::writeDeclaration(OutputList &ol, QCString cname = d->name(); QCString cfname = getOutputFileBase(); - QCString osname = cname; + //QCString osname = cname; // in case of class members that are put in a group the name of the outerscope // differs from the cname. - if (getOuterScope()) osname=getOuterScope()->name(); + //if (getOuterScope()) osname=getOuterScope()->name(); HtmlHelp *htmlHelp=0; bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP"); @@ -942,6 +951,7 @@ void MemberDef::writeDeclaration(OutputList &ol, } } + // *** write template lists if (tArgList) { if (!isAnonymous) ol.startMemberTemplateParams(); @@ -949,10 +959,9 @@ void MemberDef::writeDeclaration(OutputList &ol, if (!isAnonymous) ol.endMemberTemplateParams(); } + // *** write type QCString ltype(type); if (mtype==Typedef) ltype.prepend("typedef "); - // strip `static' keyword from ltype - //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7); // strip `friend' keyword from ltype if (ltype.left(7)=="friend ") ltype=ltype.right(ltype.length()-7); static QRegExp r("@[0-9]+"); @@ -1034,7 +1043,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ol.insertMemberAlign(tArgList!=0); } - // write name + // *** write name if (!name().isEmpty() && name().at(0)!='@') // hide annonymous stuff { //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable()); @@ -1074,12 +1083,13 @@ void MemberDef::writeDeclaration(OutputList &ol, // descriptions are enabled or there is no detailed description. { if (annMemb) annMemb->annUsed=annUsed=TRUE; - ol.startBold(); - ol.docify(name()); - ol.endBold(); + ClassDef *rcd = cd; + if (isReference() && classDef) rcd = classDef; + writeLink(ol,rcd,nd,fd,gd,TRUE); } } + // *** write arguments if (argsString() && !isObjCMethod()) { if (!isDefine()) ol.writeString(" "); @@ -1087,12 +1097,14 @@ void MemberDef::writeDeclaration(OutputList &ol, linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),argsString()); } + // *** write exceptions if (excpString()) { ol.writeString(" "); ol.docify(excpString()); } + // *** write bitfields if (!bitfields.isEmpty()) // add bitfields { linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),bitfields.simplifyWhiteSpace()); @@ -1113,6 +1125,7 @@ void MemberDef::writeDeclaration(OutputList &ol, linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),init); } } + if (isObjCMethod() && isImplementation()) { ol.startTypewriter(); @@ -1217,11 +1230,13 @@ bool MemberDef::isDetailedSectionLinkable() const return ((docFilter && staticFilter && privateFilter && friendCompoundFilter) /*|| inAnonymousScope*/); } -bool MemberDef::isDetailedSectionVisible(bool inGroup) const +bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const { bool groupFilter = getGroupDef()==0 || inGroup; + bool fileFilter = getNamespaceDef()==0 || !inFile; - bool visible = isDetailedSectionLinkable() && groupFilter && !isReference(); + bool visible = isDetailedSectionLinkable() && groupFilter && fileFilter && + !isReference(); //printf("MemberDef::isDetailedSectionVisible() %d\n",visible); return visible; } @@ -1237,7 +1252,8 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, { // if this member is in a group find the real scope name. bool hasParameterList = FALSE; - bool hasDocs = isDetailedSectionVisible(inGroup); + bool inFile = container->definitionType()==Definition::TypeFile; + bool hasDocs = isDetailedSectionVisible(inGroup,inFile); //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d\n", // name().data(),hasDocs,container->definitionType(),inGroup); if ( !hasDocs ) return; @@ -1287,6 +1303,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, int i=0,l; static QRegExp r("@[0-9]+"); + //---------------------------------------- ol.pushGeneratorState(); @@ -1398,6 +1415,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, } } } + ol.startMemberDocName(isObjCMethod()); if (cd && cd->isObjectiveC()) { @@ -1431,7 +1449,9 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, //printf("end >%s< i=%d\n",ldef.data(),i); if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- "); } + linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef); + hasParameterList=writeDefArgumentList(ol,cd,scopeName,this); if (hasOneLineInitializer()) // add initializer { @@ -1865,6 +1885,8 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, //if (Config_getBool("EXTRACT_ALL") && !hasDocs) ol.enable(OutputGenerator::Latex); ol.popGeneratorState(); + //------------------------------------------------ + if (!Config_getBool("EXTRACT_ALL") && Config_getBool("WARN_IF_UNDOCUMENTED") && Config_getBool("WARN_NO_PARAMDOC")) diff --git a/src/memberdef.h b/src/memberdef.h index d40fff2..545bf7f 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -153,7 +153,7 @@ class MemberDef : public Definition bool isLinkable() const; bool hasDocumentation() const; // overrides hasDocumentation in definition.h bool isBriefSectionVisible() const; - bool isDetailedSectionVisible(bool inGroup=FALSE) const; + bool isDetailedSectionVisible(bool inGroup,bool inFile) const; bool isDetailedSectionLinkable() const; bool isDocumentedFriendClass() const; @@ -185,8 +185,6 @@ class MemberDef : public Definition void setTagInfo(TagInfo *i); // output generation - void writeLink(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd); void writeDeclaration(OutputList &ol, ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, bool inGroup); @@ -308,6 +306,10 @@ class MemberDef : public Definition bool visited; private: + void writeLink(OutputList &ol, + ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, + bool onlyText=FALSE); + ClassDef *classDef; // member of or related to FileDef *fileDef; // member of file definition MemberDef *enumScope; // the enclosing scope, if this is an enum field diff --git a/src/memberlist.cpp b/src/memberlist.cpp index 87a3974..97022d5 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -32,6 +32,7 @@ MemberList::MemberList() : QList() m_numDecMembers=-1; // special value indicating that computation is needed m_numDocMembers=-1; // special value indicating that computation is needed m_inGroup=FALSE; + m_inFile=FALSE; } MemberList::~MemberList() @@ -124,7 +125,7 @@ void MemberList::countDocMembers() MemberDef *md; for (mli.toFirst();(md=mli.current());++mli) { - if (md->isDetailedSectionVisible(m_inGroup)) + if (md->isDetailedSectionVisible(m_inGroup,m_inFile)) { // do not count enum values, since they do not produce entries of their own if (md->memberType()!=MemberDef::EnumValue) m_numDocMembers++; diff --git a/src/memberlist.h b/src/memberlist.h index c834fdc..1089224 100644 --- a/src/memberlist.h +++ b/src/memberlist.h @@ -57,7 +57,8 @@ class MemberList : public QList void writeDocumentationPage(OutputList &ol, const char *scopeName, Definition *container); void addMemberGroup(MemberGroup *mg); - void setInGroup(bool group) { m_inGroup=group; } + void setInGroup(bool inGroup) { m_inGroup=inGroup; } + void setInFile(bool inFile) { m_inFile=inFile; } void addListReferences(Definition *def); void findSectionsInDocumentation(); MemberGroupList *getMemberGroupList() const { return memberGroupList; } @@ -68,7 +69,8 @@ class MemberList : public QList int m_numDecMembers; // number of members in the brief part of the memberlist int m_numDocMembers; // number of members in the detailed part of the memberlist MemberGroupList *memberGroupList; - bool m_inGroup; // is this list part of a group + bool m_inGroup; // is this list part of a group definition + bool m_inFile; // is this list part of a file definition }; class MemberListIterator : public QListIterator diff --git a/src/parserintf.h b/src/parserintf.h new file mode 100644 index 0000000..39ff310 --- /dev/null +++ b/src/parserintf.h @@ -0,0 +1,106 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2005 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef PARSERINTF_H +#define PARSERINTF_H + +#include + +class Entry; + +/** \brief Abstract interface for programming language parsers. + * + * By implementing the methods of this interface one can add + * a new language parser to doxygen. The parser can make use of the + * comment block parser to parse the contents of special comment blocks. + */ +class ParserInterface +{ + public: + /** Parses a single file. + * @param[in] fileName The full name of the file. + * @param[in] fileBuf The contents of the file (zero terminated). + * @param[in,out] root The root of the tree of Entry *nodes + * representing the information extracted from the file. + */ + virtual void parse(const char *fileName,const char *fileBuf,Entry *root) = 0; + + /** Callback function called by the comment block scanner. + * It provides a string \a text containing the prototype of a function + * or variable. The parser should parse this and store the information + * in the Entry node that corresponds with the node for which the + * comment block parser was invoked. + */ + virtual void parsePrototype(const char *text) = 0; + + /** Callback function called by the comment block scanner upon encountering + * a group block start command (@@{). If the group has a header + * specified via the @@name command, this will be passed via + * the \a header parameter, if not the \a header parameter will be 0. + */ + virtual void handleGroupStartCommand(const char *header) = 0; + + /** Callback function called by the comment block scanner upon encountering + * a group block end command (@@}). + */ + virtual void handleGroupEndCommand() = 0; +}; + +/** \brief Manages programming language parsers. + * + * This class manages the language parsers in the system. One can + * register parsers, and obtain a parser given a file extension. + */ +class ParserManager +{ + public: + /** Creates the parser manager object. + * @param defaultParser The default parser that is used when + * no explicit extension has been register for + * a given input file. + */ + ParserManager(ParserInterface *defaultParser) + : m_defaultParser(defaultParser) {} + + /** Registers a new parser. + * @param[in] extension The file extension that will trigger + * the use of this parser (e.g. ".py", or ".bas"). + * @param[in] parser The parser that is to be used for the + * given extension. + */ + void registerParser(const char *extension,ParserInterface *parser) + { + m_parsers.insert(extension,parser); + } + + /** Gets the interface to the parser associated with given \a extension, + * if there is no parser explicitly registered for the supplied extension, + * the interface to the default parser will be returned. + */ + ParserInterface *getParser(const char *extension) + { + if (extension==0) return m_defaultParser; + ParserInterface *intf = m_parsers.find(extension); + return intf ? intf : m_defaultParser; + } + + private: + QDict m_parsers; + ParserInterface *m_defaultParser; +}; + +#endif diff --git a/src/pre.l b/src/pre.l index cb23bb8..8ce3d76 100644 --- a/src/pre.l +++ b/src/pre.l @@ -195,7 +195,7 @@ static FILE *checkAndOpenFile(const QCString &absName) QCString filterName = getFileFilter(absName); if (!filterName.isEmpty()) { - QCString cmd = filterName+" \""+absName+"\""; + QCString cmd = "\"" + filterName+"\" \""+absName+"\""; f=popen(cmd,"r"); if (!f) err("Error: could not execute filter %s\n",cmd.data()); } @@ -1779,7 +1779,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) } [\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly"|"dot"|"code"){BN}+ { outputArray(yytext,yyleng); - g_blockName=&yytext[1]; + g_blockName=QCString(&yytext[1]).stripWhiteSpace(); BEGIN(SkipVerbatim); } [\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode") { /* end of verbatim block */ @@ -1789,7 +1789,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) BEGIN(SkipCComment); } } -[^*\x06\n\/]+ { +[^*\\@\x06\n\/]+ { outputArray(yytext,yyleng); } \n { @@ -2235,7 +2235,7 @@ void preprocessFile(const char *fileName,BufStr &output) } else { - QCString cmd = inputFilter+" \""+fileName+"\""; + QCString cmd = "\"" + inputFilter+"\" \""+fileName+"\""; preYYin = popen(cmd,"r"); if (!preYYin) { diff --git a/src/scanner.h b/src/scanner.h index 36abd4d..2dbbf4e 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -18,13 +18,31 @@ #ifndef SCANNER_H #define SCANNER_H +#include "parserintf.h" + +/** \brief C-like language parser using state-based lexical scanning. + * + * This is the language parser for doxygen. It is somewhat fuzzy and + * supports C++ and various languages that are closely related to C++, + * such as C,C#,Objective-C,Java,PHP,and IDL. + */ +class CLanguageScanner : public ParserInterface +{ + public: + void parse(const char *fileName,const char *fileBuf,Entry *root); + void parsePrototype(const char *text); + void handleGroupStartCommand(const char *header); + void handleGroupEndCommand(); +}; + +#if 0 + #include "qtbc.h" class OutputList; class Entry; // Public interface provided by the language scanner -void parseMain(Entry *); void parseMain(Entry *,const char *fileName); // Internal callback interface for comment block scanner @@ -33,3 +51,5 @@ void handleGroupStartCommand(const char *header); void handleGroupEndCommand(); #endif + +#endif diff --git a/src/scanner.l b/src/scanner.l index c68e351..6f12f8a 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -34,61 +34,40 @@ #include "scanner.h" #include "entry.h" -#include "doxygen.h" #include "message.h" #include "config.h" +#include "doxygen.h" #include "util.h" -#include "index.h" #include "defargs.h" #include "language.h" -#include "outputlist.h" -#include "membergroup.h" -#include "reflist.h" -#include "code.h" #include "commentscan.h" -#define COMMENTSCAN - #define YY_NEVER_INTERACTIVE 1 /* ----------------------------------------------------------------- * * statics */ +static ParserInterface *g_thisParser; static const char * inputString; static int inputPosition; static QFile inputFile; static int lastContext; static int lastCContext; static int lastDocContext; -static int lastDocRelContext; -static int lastDocRelAlsoContext; static int lastCPPContext; static int lastSkipSharpContext; static int lastSkipRoundContext; -static int lastBriefContext; -static int lastVerbState; static int lastStringContext; static int lastCurlyContext; static int lastRoundContext; static int lastSquareContext; -static int lastCodeState; -static int lastAfterDocContext; -static int lastGroupContext; -static int lastFormulaContext; -static int lastAnchorContext; +//static int lastAfterDocContext; static int lastInitializerContext; static int lastClassTemplSpecContext; -static int lastSkipHtmlCommentContext; -static int lastIfContext; -static int lastInternalDocContext; static int lastPreLineCtrlContext; static int lastSkipVerbStringContext; static int lastCommentInArgContext; -static int lastFileDocContext; -static int lastSectionContext; -static int nextDefContext; -static int overloadContext; static Protection protection; static Protection baseProt; static int sharpCount = 0 ; @@ -96,7 +75,6 @@ static int roundCount = 0 ; static int curlyCount = 0 ; static int squareCount = 0 ; static int padCount = 0 ; -static int slStartContext = 0; static QCString slString; static Entry* current_root = 0 ; static Entry* global_root = 0 ; @@ -105,7 +83,7 @@ static Entry* previous = 0 ; static Entry* tempEntry = 0 ; static int yyLineNr = 1 ; static int anonCount = 0 ; -static char yyFileName[4096] ; +static QCString yyFileName; static int lastMemberGroupLine; static MethodTypes mtype; static bool gstat; @@ -117,7 +95,7 @@ static int memberGroupId = DOX_NOGROUP; static QCString memberGroupHeader; static QCString memberGroupDocs; static bool isTypedef; -static char afterDocTerminator; +//static char afterDocTerminator; static int tmpDocType; static QCString sectionLabel; static QCString sectionTitle; @@ -154,7 +132,6 @@ static char lastCopyArgChar; static QCString *pCopyRoundString; static QCString *pCopyCurlyString; static QCString *pCopyQuotedString; -static QCString *pSkipDoc; static QCString *pSkipVerbString; static QStack autoGroupStack; static Grouping lastDefGroup( "", Grouping::GROUPING_LOWEST ); @@ -188,6 +165,12 @@ static char docBlockTerm; //----------------------------------------------------------------------------- +// forward declarations +static void handleGroupStartCommand(const char *header); +static void handleGroupEndCommand(); + +//----------------------------------------------------------------------------- + static void initParser() { sectionLabel.resize(0); @@ -218,7 +201,10 @@ static void initParser() static void initEntry() { - if (insideJava) protection = Package; + if (insideJava) + { + protection = current_root->section==Entry::INTERFACE_SEC ? Public : Package; + } current->protection = protection ; current->mtype = mtype; current->virt = virt; @@ -268,9 +254,6 @@ static int newMemberGroupId() } // forward declarations -#ifndef COMMENTSCAN -static void startGroup(); -#endif static void startGroupInDoc(); static void endGroup(); @@ -314,8 +297,6 @@ static QCString stripQuotes(const char *s) return name; } -static void newDocState(); - //----------------------------------------------------------------- static void addMemberGroupDocs() @@ -343,96 +324,6 @@ static void startCommentBlock(bool); static void handleCommentBlock(const QCString &doc,bool brief); //----------------------------------------------------------------- -static void addXRefItem(bool inBody,const char *listName,const char *itemTitle,const char *listTitle) -{ - Entry *docEntry = inBody && previous ? previous : current; - //printf("docEntry=%p\n",docEntry); - if (listName==0) return; - - //printf("addXRefItem(%s,%s,%s)\n",listName,itemTitle,listTitle); - ListItemInfo *lii=0; - RefList *refList = Doxygen::xrefLists->find(listName); - if (refList==0) // new list - { - refList = new RefList(listName,listTitle,itemTitle); - Doxygen::xrefLists->insert(listName,refList); - //printf("new list!\n"); - } - if (docEntry->sli) - { - QListIterator slii(*docEntry->sli); - for (slii.toFirst();(lii=slii.current());++slii) - { - if (strcmp(lii->type,listName)==0) - { - //printf("found %s lii->type=%s\n",listName,lii->type); - break; - } - } - } -#if 0 // with this code multiple @todo items can be put under the same - // heading, I removed it because it changes the text flow. - if (lii) // already found item of same type before - { - //printf("listName=%s item id = %d existing\n",listName,lii->itemId); - RefItem *item = refList->getRefItem(lii->itemId); - ASSERT(item!=0); - item->text += "

    "; - item->text += current->brief; - //printf("%s: text +=%s\n",listName,item->text.data()); - } - else // new item -#endif - { - int itemId = refList->addRefItem(); - //printf("listName=%s item id = %d new current=%p\n",listName,itemId,current); - - // if we have already an item from the same list type (e.g. a second @todo) - // in the same Entry (i.e. lii!=0) then we reuse its link anchor. - char anchorLabel[1024]; - sprintf(anchorLabel,"_%s%06d",listName,lii ? lii->itemId : itemId); - RefItem *item = refList->getRefItem(itemId); - ASSERT(item!=0); - item->text = current->brief; - item->listAnchor = anchorLabel; - docEntry->addSpecialListItem(listName,itemId); - QCString cmdString; - cmdString.sprintf("\\xrefitem %s %d\n",listName,itemId); - docEntry->doc += cmdString; - SectionInfo *si=new SectionInfo(listName,anchorLabel, - sectionTitle,SectionInfo::Anchor); - Doxygen::sectionDict.insert(anchorLabel,si); - docEntry->anchors->append(si); - } - current->brief = slString; // restore orginial brief desc. -} - -//----------------------------------------------------------------------------- - -// Adds a formula text to the list/dictionary of formulas if it was -// not already added. Returns the label of the formula. -static QCString addFormula() -{ - QCString formLabel; - QCString fText=formulaText.simplifyWhiteSpace(); - Formula *f=0; - if ((f=Doxygen::formulaDict[fText])==0) - { - f = new Formula(fText); - Doxygen::formulaList.append(f); - Doxygen::formulaDict.insert(fText,f); - formLabel.sprintf("\\form#%d",f->getId()); - Doxygen::formulaNameDict.insert(formLabel,f); - } - else - { - formLabel.sprintf("\\form#%d",f->getId()); - } - return formLabel; -} - -//----------------------------------------------------------------------------- - static bool nameIsOperator(QCString &name) { int i=name.find("operator"); @@ -444,32 +335,6 @@ static bool nameIsOperator(QCString &name) //----------------------------------------------------------------------------- -static void checkFormula() -{ - if (insideFormula) - { - warn(yyFileName,yyLineNr,"Warning: End of comment block while inside formula."); - } -} - -//----------------------------------------------------------------------------- - -static void checkDocs() -{ - checkFormula(); - if ((current->brief.length()>2 && - current->brief.at(0)=='<' && current->brief.at(1)==' ') || - (current->doc.length()>2 && - current->doc.at(0)=='<' && current->doc.at(1)==' ') - ) - { - warn(yyFileName,yyLineNr,"Warning: Found lonely '<' symbol at the start of the documentation."); - - } -} - -//----------------------------------------------------------------------------- - static void setContext() { QCString fileName = yyFileName; @@ -486,7 +351,10 @@ static void setContext() { useOverrideCommands = TRUE; } - //printf("setContext(%s) insideIDL=%d\n",yyFileName,insideIDL); + //printf("setContext(%s) insideIDL=%d insideJava=%d insideCS=%d " + // "insideD=%d insidePHP=%d insideObjC=%d\n", + // yyFileName.data(),insideIDL,insideJava,insideCS,insideD,insidePHP,insideObjC + // ); } //----------------------------------------------------------------------------- @@ -663,14 +531,12 @@ static void addKnRArgInfo(const QCString &type,const QCString &name, static int yyread(char *buf,int max_size) { int c=0; -#ifdef USE_TMP_FILE if (g_inputFromFile) { c = inputFile.readBlock(buf,max_size); if (c==-1) yy_fatal_error("input in flex scanner failed"); } else -#endif { while( c < max_size && inputString[inputPosition] ) { @@ -717,6 +583,7 @@ IDLATTR ("["[^\]]*"]"){BN}* %option noyywrap /* language parsing states */ + %x Define %x DefineEnd %x CompoundName @@ -806,88 +673,20 @@ IDLATTR ("["[^\]]*"]"){BN}* %x FuncFunc %x FuncFuncEnd %x FuncFuncType - - - /* comment parsing states. - * What can happen in while parsing a comment block: - * commands (e.g. @page, or \page) - * escaped commands (e.g. @@page or \\page). - * directories (e.g. \doxygen\src\) - * HTML commands (e.g.

    ...
    ) - * autolists. - * newlines. - * words and whitespace and other characters (#,?!, etc). - */ - /* start states. TODO: reduce to one state */ -%x Doc -%x JavaDoc -%x LineDoc -%x AfterDoc -%x AfterDocBrief -%x AfterDocLine - /* internal states */ - /* page related */ -%x PageDoc -%x PageDocTitle -%x PageDocArg1 -%x PageDocArg2 -%x ExampleDocArg1 - -%x ClassDoc -%x DefLineDoc -%x SkipSection -%x IfGuard -%x IfNotGuard -%x NameSpaceDocArg1 -%x PackageDocArg1 -%x SkipCode -%x ClassDocArg1 -%x CategoryDocArg1 -%x ClassDocArg2 -%x ClassDocArg3 -%x ClassDocFunc -%x ClassDocFuncPtr -%x ClassDocFuncQual -%x ClassDocFuncSkipLine -%x ClassDocFuncExc -%x ClassDocDefine -%x ClassDocRelates -%x ClassDocRelatesAlso -%x ClassDocBrief -%x ClassDocOverload -%x ClassDefineArgs -%x DocInternal -%x DocInternalLine -%x DocBaseClass -%x GroupDocArg1 -%x GroupDocArg2 -%x GroupName -%x GroupHeader -%x StoreGroupDocs -%x FileDocArg1 -%x FileDocArg2 -%x EnumDocArg1 -%x SkipVerbatim -%x TodoParam -%x TestParam -%x BugParam -%x DeprecatedParam -%x XRefItemParam1 -%x XRefItemParam2 -%x XRefItemParam3 -%x XRefItemParam4 -%x SectionLabel -%x SectionTitle %x CopyArgString %x CopyArgPHPString %x CopyArgRound %x CopyArgSharp %x CopyArgComment %x CopyArgCommentLine -%x SkipHtmlComment -%x ReadFormulaShort -%x ReadFormulaLong -%x AnchorLabel + + /** Prototype scanner states */ + +%x Prototype +%x PrototypePtr +%x PrototypeQual +%x PrototypeExc +%x PrototypeSkipLine /** new comment parsing states */ @@ -897,43 +696,6 @@ IDLATTR ("["[^\]]*"]"){BN}* %% -<*>\x06[^\x06]*\x06 { // new file - if (YY_START==Comment) - { - warn(yyFileName,yyLineNr,"File ended in the middle of a comment block! Perhaps a missing \\endcode?"); - } - if (memberGroupId!=DOX_NOGROUP) - { - warn(yyFileName,yyLineNr,"Warning: Missing //@}"); - memberGroupId=DOX_NOGROUP; - } - yyLineNr= 0 ; // there is always an extra newline at the start of the file - int i; - for( i = 0 ; yytext[i+1] != 6 ; i++ ) - yyFileName[i] = yytext[i+1] ; - yyFileName[i] = 0 ; - setContext(); - msg("Parsing file %s...\n",yyFileName); - current_root = global_root ; - initParser(); - current->reset(); - int sec=guessSection(yyFileName); - if (sec) - { - current->name = yyFileName; - current->section = sec; - current_root->addSubEntry(current); - current = new Entry; - } - if ( insidePHP ) - { - BEGIN( FindMembersPHP ); - } - else - { - BEGIN( FindMembers ); - } - } "{" { curlyCount=0; needsSemi = TRUE; @@ -1224,7 +986,8 @@ IDLATTR ("["[^\]]*"]"){BN}* unput(';'); BEGIN( Function ); } -"{" { // start of a method body +(";"{BN}+)?"{" { // start of a method body + lineCount(); //printf("Type=%s Name=%s args=%s\n", // current->type.data(),current->name.data(),argListToString(current->argList).data() // ); @@ -1618,7 +1381,7 @@ IDLATTR ("["[^\]]*"]"){BN}* initEntry(); BEGIN(Using); } -{SCOPENAME} { current->name=yytext; +{SCOPENAME} { current->name=removeRedundantWhiteSpace(yytext); current->fileName = yyFileName; current->section=Entry::USINGDIR_SEC; current_root->addSubEntry(current); @@ -1915,7 +1678,7 @@ IDLATTR ("["[^\]]*"]"){BN}* BEGIN( PreLineCtrl ); } "\""[^\n\"]*"\"" { - strncpy(yyFileName,stripQuotes(yytext),4096); + yyFileName = stripQuotes(yytext); } . {} \n { @@ -2018,7 +1781,6 @@ IDLATTR ("["[^\]]*"]"){BN}* { current->bodyLine=yyLineNr; } -#ifdef COMMENTSCAN docBlockContext = YY_START; docBlockInBody = FALSE; docBlockJavaStyle = yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF"); @@ -2034,37 +1796,9 @@ IDLATTR ("["[^\]]*"]"){BN}* startCommentBlock(FALSE); BEGIN( DocBlock ); } -#else - lastAfterDocContext = YY_START; - afterDocTerminator = ';'; - if (yytext[yyleng-3]=='/') - { - current->brief.resize(0); - current->briefLine = yyLineNr; - current->briefFile = yyFileName; - BEGIN(AfterDocLine); - } - else if (yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF")) - { - current->brief.resize(0); - current->briefLine = yyLineNr; - current->briefFile = yyLineNr; - current->docLine = yyLineNr; - current->docFile = yyFileName; - BEGIN(AfterDocBrief); - } - else - { - current->doc.resize(0); - current->docLine = yyLineNr; - current->docFile = yyFileName; - BEGIN(AfterDoc); - } -#endif } ","{BN}*("/**"|"//!"|"/*!"|"///")"<" { lineCount(); -#ifdef COMMENTSCAN docBlockContext = YY_START; docBlockInBody = FALSE; docBlockJavaStyle = yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF"); @@ -2080,69 +1814,31 @@ IDLATTR ("["[^\]]*"]"){BN}* startCommentBlock(FALSE); BEGIN( DocBlock ); } -#else - lastAfterDocContext = YY_START; - afterDocTerminator = ','; - if (yytext[yyleng-3]=='/') - { - current->brief.resize(0); - current->briefLine = yyLineNr; - current->briefFile = yyLineNr; - BEGIN(AfterDocLine); - } - else if (yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF")) - { - current->brief.resize(0); - current->briefLine = yyLineNr; - current->briefFile = yyLineNr; - current->docLine = yyLineNr; - current->docFile = yyFileName; - BEGIN(AfterDocBrief); - } - else - { - current->doc.resize(0); - current->docLine = yyLineNr; - current->docFile = yyFileName; - BEGIN(AfterDoc); - } -#endif } {BN}*("/**"|"//!"|"/*!"|"///")"<" { lineCount(); - lastAfterDocContext = YY_START; - if (YY_START==DefineEnd) + if (current->bodyLine==-1) { - afterDocTerminator = '\n'; - yyLineNr--; + current->bodyLine=yyLineNr; } - else - afterDocTerminator = 0; + docBlockContext = YY_START; + docBlockInBody = FALSE; + docBlockJavaStyle = yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF"); + docBlock.resize(0); + docBlockTerm = 0; if (yytext[yyleng-3]=='/') { - current->brief.resize(0); - current->briefLine = yyLineNr; - current->briefFile = yyFileName; - BEGIN(AfterDocLine); - } - else if (yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF")) - { - current->brief.resize(0); - current->briefLine = yyLineNr; - current->briefFile = yyFileName; - BEGIN(AfterDocBrief); + startCommentBlock(TRUE); + BEGIN( DocLine ); } else { - current->doc.resize(0); - current->docLine = yyLineNr; - current->docFile = yyFileName; - BEGIN(AfterDoc); + startCommentBlock(FALSE); + BEGIN( DocBlock ); } } ("//"([!/]?){B}*{CMD}"{")|("/*"([!*]?){B}*{CMD}"{") { -#ifdef COMMENTSCAN Entry *tmp = current; if (previous) { @@ -2151,50 +1847,9 @@ IDLATTR ("["[^\]]*"]"){BN}* handleGroupStartCommand(current->name); current = tmp; initEntry(); - -#else - startGroup(); - tmpDocType=-1; - if (current_root->section & Entry::SCOPE_MASK) - { - current->inside = current_root->name+"::"; - if (current->mGrpId!=DOX_NOGROUP) - { - memberGroupInside = current->inside.copy(); - } - } - if (yytext[1]=='/') // C++ style comment - { - current->brief.resize(0); - current->briefLine = yyLineNr; - current->briefFile = yyFileName; - lastDocContext = YY_START; - BEGIN( LineDoc ); - } - else // C style comment - { - current->doc.resize(0); - current->docLine = yyLineNr; - current->docFile = yyFileName; - lastDocContext = YY_START; - removeSlashes=FALSE; - BEGIN( Doc ); - } -#endif } "//"([!/]?){B}*{CMD}"}".*|"/*"([!*]?){B}*{CMD}"}".*"*/" { -#ifdef COMMENTSCAN handleGroupEndCommand(); -#else - if (memberGroupId==DOX_NOGROUP && autoGroupStack.isEmpty()) - { - warn(yyFileName,yyLineNr, - "Warning: end of group without matching begin."); - } - //printf("end of member group marker ends group %d\n",memberGroupId); - endGroup(); - memberGroupHeader.resize(0); -#endif } "=" { current->bodyLine = yyLineNr; @@ -3631,31 +3286,24 @@ IDLATTR ("["[^\]]*"]"){BN}* { current->endBodyLine=yyLineNr; lineCount(); + tempEntry = current; // temporarily switch to the previous entry current = previous; - current->doc.resize(0); - current->brief.resize(0); - lastAfterDocContext = SkipCurlyEndDoc; - afterDocTerminator = '}'; + + docBlockContext = SkipCurlyEndDoc; + docBlockInBody = FALSE; + docBlockJavaStyle = yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF"); + docBlock.resize(0); + docBlockTerm = '}'; if (yytext[yyleng-3]=='/') { - current->briefLine = yyLineNr; - current->briefFile = yyFileName; - BEGIN(AfterDocLine); - } - else if (yytext[yyleng-2]=='*' && Config_getBool("JAVADOC_AUTOBRIEF")) - { - current->briefLine = yyLineNr; - current->briefFile = yyFileName; - current->docLine = yyLineNr; - current->docFile = yyFileName; - BEGIN(AfterDocBrief); + startCommentBlock(TRUE); + BEGIN( DocLine ); } else { - current->docLine = yyLineNr; - current->docFile = yyFileName; - BEGIN(AfterDoc); + startCommentBlock(FALSE); + BEGIN( DocBlock ); } } } @@ -4183,16 +3831,12 @@ IDLATTR ("["[^\]]*"]"){BN}* memberGroupInside = current->inside.copy(); } } -#ifdef COMMENTSCAN docBlockContext = YY_START; docBlockInBody = YY_START==SkipCurly; docBlockJavaStyle = FALSE; docBlock.resize(0); startCommentBlock(FALSE); BEGIN( DocBlock ); -#else - BEGIN( Doc ); -#endif } ("//"{B}*)?"/**"/[^/*] { removeSlashes=(yytext[1]=='/'); @@ -4206,7 +3850,6 @@ IDLATTR ("["[^\]]*"]"){BN}* memberGroupInside = current->inside.copy(); } } -#ifdef COMMENTSCAN current->docLine = yyLineNr; current->docFile = yyFileName; docBlockContext = YY_START; @@ -4228,46 +3871,6 @@ IDLATTR ("["[^\]]*"]"){BN}* } startCommentBlock(FALSE); BEGIN( DocBlock ); -#else - if (!Config_getBool("JAVADOC_AUTOBRIEF")) // use the Qt style - { - current->docLine = yyLineNr; - current->docFile = yyFileName; - tmpDocType=-1; - if (!Config_getBool("HIDE_IN_BODY_DOCS") && - YY_START==SkipCurly) // inside body - { - current->doc+="\n\n"; - } - else - { - current->doc.resize(0); - } - BEGIN( Doc ); - } - else // Use the javadoc style - { - current->docLine = yyLineNr; - current->docFile = yyFileName; - current->briefLine = yyLineNr; - current->briefFile = yyFileName; - if (!Config_getBool("HIDE_IN_BODY_DOCS") && - YY_START==SkipCurly) // inside body - { - tmpDocType=-1; - current->doc+="\n\n"; - lastDocContext = SkipCurly; - BEGIN( Doc ); - } - else - { - tmpDocType=Doc; - current->doc.resize(0); - current->brief.resize(0); - BEGIN( JavaDoc ); - } - } -#endif } "//!" { if (YY_START!=SkipCurly) @@ -4286,16 +3889,12 @@ IDLATTR ("["[^\]]*"]"){BN}* memberGroupInside = current->inside.copy(); } } -#ifdef COMMENTSCAN docBlockContext = YY_START; docBlockInBody = YY_START==SkipCurly; docBlockJavaStyle = FALSE; docBlock.resize(0); startCommentBlock(TRUE); BEGIN( DocLine ); -#else - BEGIN( LineDoc ); -#endif } "///"/[^/] { if (YY_START!=SkipCurly) @@ -4314,16 +3913,12 @@ IDLATTR ("["[^\]]*"]"){BN}* memberGroupInside = current->inside.copy(); } } -#ifdef COMMENTSCAN docBlockContext = YY_START; docBlockInBody = YY_START==SkipCurly; docBlockJavaStyle = FALSE; docBlock.resize(0); startCommentBlock(TRUE); BEGIN( DocLine ); -#else - BEGIN( LineDoc ); -#endif } "extern"{BN}*"\"C"("++")?"\""{BN}*("{")? { lineCount(); @@ -4413,7 +4008,12 @@ IDLATTR ("["[^\]]*"]"){BN}* handleCommentBlock(docBlock,FALSE); BEGIN(docBlockContext); } -^{B}*"*"+/[^//] { // start of a comment line +^{B}*("//")?{B}*"*"+/[^//] { // start of a comment line + } +^{B}*("//"){B}* { // strip embedded C++ comments if at the start of a line + } +"//" { // slashes in the middle of a comment block + docBlock+=yytext; } ("@@"|"\\\\"){ID}/[^a-z_A-Z0-9] { // escaped command docBlock+=yytext; @@ -4423,7 +4023,7 @@ IDLATTR ("["[^\]]*"]"){BN}* docBlockName=&yytext[1]; BEGIN(DocCopyBlock); } -[^@*\\\n]+ { // any character that isn't special +[^@*\/\\\n]+ { // any character that isn't special docBlock+=yytext; } \n { // newline @@ -4470,1686 +4070,69 @@ IDLATTR ("["[^\]]*"]"){BN}* } + /* ------------- Prototype parser -------------- */ - - - /*************************************************************************/ - /*** The next part is obsolete and will be removed ***/ - - -{CMD}("brief"|"short"){B}+ { - lastBriefContext=tmpDocType; - BEGIN( ClassDocBrief ); - } -^(({B}*"*"+)?){BL} { - lineCount(); - if (!current->brief.stripWhiteSpace().isEmpty()) - { - BEGIN( tmpDocType ); - } - } - - - /* -"@" { - unput(*yytext); - BEGIN(ClassDoc); - } - */ -^{B}*"*"+/[^/] { - //printf("---> removing %s\n",yytext); +"operator"{B}*"("{B}*")" { + current->name+=yytext; } - /* -[^\n\@\*\.\\]+ { - current->brief+=yytext; +"(" { + current->args+=*yytext; + currentArgumentContext = PrototypeQual; + fullArgString = current->args.copy(); + copyArgString = ¤t->args; + BEGIN( ReadFuncArgType ) ; } - */ -. { - //printf("---> copy %c\n",*yytext); - current->brief+=*yytext; +"("({ID}"::")*({B}*"*")+ { + current->type+=current->name+yytext; + current->name.resize(0); + BEGIN( PrototypePtr ); } -\n { - current->brief+=' '; - lineCount(); +{SCOPENAME} { + current->name+=yytext; } -".\\"/[ \t\r\n] { - current->brief+="."; - } -"."[ \t\r\n] { - lineCount(); - current->brief+="."; - BEGIN( tmpDocType ); - } -{B}*/{SECTIONCMD} { - current->doc+=yytext; - BEGIN( tmpDocType ); +")" { + current->type+=')'; + BEGIN( Prototype ); } -"<"({TABLE}|{UL}|{OL}|{DL}|{P}){ATTR}">" { // end brief upon encountering any of these - int i; - for (i=yyleng-1;i>=0;i--) - { - unput(yytext[i]); - } - BEGIN( tmpDocType ); +"{" { + BEGIN( PrototypeSkipLine); } -{B}*{CMD}("fn"|"var"|"typedef"|"property"){B}+ { - current->section = Entry::MEMBERDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( ClassDocFunc ); +{B}*"const"{B}* { + current->args += " const "; + current->argList->constSpecifier=TRUE; } -{B}*{CMD}"def"{B}+ { - nextDefContext = YY_START==LineDoc ? DefLineDoc : ClassDoc; - current->section = Entry::DEFINEDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( ClassDocDefine ); - } -{B}*{CMD}"overload"{B}* { - overloadContext = YY_START; - BEGIN( ClassDocOverload ); - } -{B}*/"\n" { - QCString orgDoc = current->doc; - current->doc = getOverloadDocs(); - current->doc += "\n\n"; - current->doc += orgDoc; - BEGIN( overloadContext ); - } -{B}*/"*/" { - QCString orgDoc = current->doc; - current->doc = getOverloadDocs(); - current->doc += "\n\n"; - current->doc += orgDoc; - BEGIN( overloadContext ); - } -. { unput(*yytext); - current->section = Entry::OVERLOADDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( ClassDocFunc ); +{B}*"volatile"{B}* { + current->args += " volatile "; + current->argList->volatileSpecifier=TRUE; } -{B}*{CMD}"enum"{B}+ { - current->section = Entry::ENUMDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( EnumDocArg1 ); - } -{B}*{CMD}"defgroup"{B}+ { - current->section = Entry::GROUPDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->groupDocType = Entry::GROUPDOC_NORMAL; - BEGIN( GroupDocArg1 ); +{B}*"="{B}*"0"{B}* { + current->args += " = 0"; + current->virt = Pure; + current->argList->pureSpecifier=TRUE; + } +"throw"{B}*"(" { + current->exception = "throw("; + BEGIN(PrototypeExc); } -{B}*{CMD}"addtogroup"{B}+ { - current->section = Entry::GROUPDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->groupDocType = Entry::GROUPDOC_ADD; - BEGIN( GroupDocArg1 ); +")" { + current->exception += ')'; + BEGIN(PrototypeQual); } -{B}*{CMD}"weakgroup"{B}+ { - current->section = Entry::GROUPDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->groupDocType = Entry::GROUPDOC_WEAK; - BEGIN( GroupDocArg1 ); +. { + current->exception += *yytext; } -{B}*{CMD}"namespace"{B}+ { - current->section = Entry::NAMESPACEDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( NameSpaceDocArg1 ); +. { + current->name += *yytext; } -{B}*{CMD}"package"{B}+ { - current->section = Entry::PACKAGEDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( PackageDocArg1 ); +. { } -{B}*{CMD}"class"{B}+ { - current->section = Entry::CLASSDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( ClassDocArg1 ); - } -{B}*{CMD}"protocol"{B}+ { // ObjC protocol - current->section = Entry::PROTOCOLDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( ClassDocArg1 ); - } -{B}*{CMD}"category"{B}+ { // ObjC category - current->section = Entry::CATEGORYDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( CategoryDocArg1 ); - } -{B}*{CMD}"union"{B}+ { - current->section = Entry::UNIONDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( ClassDocArg1 ); - } -{B}*{CMD}"struct"{B}+ { - current->section = Entry::STRUCTDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( ClassDocArg1 ); - } -{B}*{CMD}"interface"{B}+ { - current->section = Entry::INTERFACEDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( ClassDocArg1 ); - } -{B}*{CMD}"idlexcept"{B}+ { - current->section = Entry::EXCEPTIONDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( ClassDocArg1 ); - } -{B}*{CMD}"page"{B}+ { - current->section = Entry::PAGEDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( PageDocArg1 ); - } -{B}*{CMD}"mainpage"{B}* { - current->section = Entry::MAINPAGEDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - current->name = "mainpage"; - BEGIN( PageDocArg2 ); - } -{B}*{CMD}"file"{B}* { - current->section = Entry::FILEDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - lastFileDocContext = YY_START; - BEGIN( FileDocArg1 ); - } -{B}*{CMD}"dir"{B}* { - current->section = Entry::DIRDOC_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( FileDocArg1 ); - } -{B}*{CMD}"example"{B}+ { - current->section = Entry::EXAMPLE_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - BEGIN( ExampleDocArg1 ); - } -{B}*{CMD}"details"{B}+ { /* nop */ - } -{CMD}"name"[^\n]*\n { - lastDefGroup.groupname.resize(0); - memberGroupHeader=&yytext[5]; - memberGroupHeader=memberGroupHeader.stripWhiteSpace(); - current->section = Entry::MEMBERGRP_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - yyLineNr++; - startGroupInDoc(); - BEGIN( lastDocContext ); - } -{CMD}"name"{B}+ { - lastDefGroup.groupname.resize(0); - current->section = Entry::MEMBERGRP_SEC; - current->fileName = yyFileName; - current->startLine = yyLineNr; - memberGroupHeader.resize(0); - memberGroupDocs.resize(0); - BEGIN(GroupHeader); - } -"