From 9b0cf1e08f786c5fbc0583fdeecd9b6fefda2b76 Mon Sep 17 00:00:00 2001 From: dimitri Date: Tue, 27 Apr 2004 19:44:46 +0000 Subject: Release-1.3.6-20040427 --- INSTALL | 4 +- README | 4 +- VERSION | 2 +- addon/doxywizard/inputbool.cpp | 10 +- configure | 4 + doc/Makefile.in | 2 +- doc/commands.doc | 25 ++++- doc/index.doc | 4 +- doc/translator.py | 8 +- packages/rpm/doxygen.spec | 2 +- qtools/qgdict.cpp | 5 +- src/classdef.cpp | 16 +++- src/classdef.h | 2 +- src/code.l | 29 +++++- src/compound.xsd | 108 ++++++++++++++------- src/compound_xsd.h | 108 ++++++++++++++------- src/definition.cpp | 46 +++++++-- src/definition.h | 19 +++- src/docparser.cpp | 12 ++- src/docparser.h | 31 +++--- src/doctokenizer.h | 4 + src/doctokenizer.l | 32 +++++++ src/doxygen.cpp | 127 ++++++++++++------------- src/filedef.cpp | 12 +-- src/filedef.h | 6 +- src/htmldocvisitor.cpp | 34 +++++-- src/latexdocvisitor.cpp | 20 +++- src/memberdef.cpp | 2 +- src/memberdef.h | 2 +- src/namespacedef.cpp | 14 +-- src/namespacedef.h | 6 +- src/perlmodgen.cpp | 2 +- src/scanner.l | 10 +- src/util.cpp | 211 +++++++++++++++++++---------------------- src/util.h | 7 +- src/xmldocvisitor.cpp | 20 +++- 36 files changed, 612 insertions(+), 338 deletions(-) diff --git a/INSTALL b/INSTALL index 62e0e4c..3a2d0f3 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,7 @@ -DOXYGEN Version 1.3.6-20040413 +DOXYGEN Version 1.3.6-20040427 Please read the installation section of the manual (http://www.doxygen.org/install.html) for instructions. -------- -Dimitri van Heesch (13 April 2004) +Dimitri van Heesch (27 April 2004) diff --git a/README b/README index b57a95f..14c7e64 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOXYGEN Version 1.3.6_20040413 +DOXYGEN Version 1.3.6_20040427 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) (13 April 2004) +Dimitri van Heesch (dimitri@stack.nl) (27 April 2004) diff --git a/VERSION b/VERSION index 8e7c0ce..c0f8b09 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.6-20040413 +1.3.6-20040427 diff --git a/addon/doxywizard/inputbool.cpp b/addon/doxywizard/inputbool.cpp index be3d630..e73b605 100644 --- a/addon/doxywizard/inputbool.cpp +++ b/addon/doxywizard/inputbool.cpp @@ -14,7 +14,11 @@ #include "inputbool.h" #include "pagewidget.h" +#if QT_VERSION >= 300 +#include +#else #include +#endif #include InputBool::InputBool( const QString & text, PageWidget * parent, bool &flag ) @@ -25,9 +29,13 @@ InputBool::InputBool( const QString & text, PageWidget * parent, bool &flag ) layout->addWidget(cb); layout->addStretch(10); +#if QT_VERSION >= 300 + QStyle *winStyle = QStyleFactory::create("windows"); +#else QWindowsStyle *winStyle = new QWindowsStyle(); +#endif cb->setChecked( flag ); - cb->setStyle( winStyle ); + if (winStyle) cb->setStyle( winStyle ); cb->setMinimumSize( sizeHint() ); connect( cb, SIGNAL(toggled(bool)), SLOT(setState(bool)) ); diff --git a/configure b/configure index facf9b7..3f151d7 100755 --- a/configure +++ b/configure @@ -397,6 +397,10 @@ echo "using $f_perl"; test -f .makeconfig && rm .makeconfig test -f .tmakeconfig && rm .tmakeconfig +if test -z $PWD; then + PWD=`pwd` +fi + cat > .makeconfig <. Followed by a description of the parameter. - The existence of the parameter is not checked. - The text of the paragraph has no special internal structure. All visual - enhancement commands may be used inside the paragraph. + The existence of the parameter is checked and a warning is given if + the documentation of this (or any other) parameter is missing or not + present in the function declaration or definition. + + The \\param command has an optional attribute specifying the direction + of the attribute. Possible values are "in" and "out". Here is an example + for the function memcpy: + \code +/*! + * Copies bytes from a source memory area to a destination memory area, + * where both areas may not overlap. + * @param[out] dest The memory area to copy to. + * @param[in] src The memory area to copy from. + * @param[in] n The number of bytes to copy + */ +void memcpy(void *dest, const void *src, size_t n); + \endcode + If a parameter is both input and output, use [in,out] as an attribute. + + The parameter description is a paragraph with no special internal structure. + All visual enhancement commands may be used inside the paragraph. + Multiple adjacent \\param commands will be joined into a single paragraph. Each parameter description will start on a new line. The \\param description ends when a blank line or some other diff --git a/doc/index.doc b/doc/index.doc index 4956018..6aa4c19 100644 --- a/doc/index.doc +++ b/doc/index.doc @@ -26,8 +26,8 @@ Version: $(VERSION) \endif

Introduction

-Doxygen is a documentation system for C++, C, Java, IDL -(Corba and Microsoft flavors) and to some extent Objective-C, PHP, C# and D. +Doxygen is a documentation system for C++, C, Java, Objective-C, IDL +(Corba and Microsoft flavors) and to some extent PHP, C# and D. It can help you in three ways:
    diff --git a/doc/translator.py b/doc/translator.py index 4ec7d2f..8a8b99f 100644 --- a/doc/translator.py +++ b/doc/translator.py @@ -38,8 +38,8 @@ but is much less tricky and much more flexible. It also solves some problems that were not solved by the Perl version. The translator report content should be more useful for developers. - 2004/02/11 - - Some tuning-up to provide more useful information. + 2004/02/11 - Some tuning-up to provide more useful information. + 2004/04/16 - Added new tokens to the tokenizer (to remove some warnings). """ import os, re, sys, textwrap @@ -127,6 +127,8 @@ class Transl: '"': 'dquot', '.': 'dot', '%': 'perc', + '~': 'tilde', + '^': 'caret', } # Regular expression for recognizing identifiers. @@ -180,7 +182,7 @@ class Transl: else: msg = '\aWarning: unknown token "' + tokenStr + '"' msg += '\tfound on line %d' % tokenLineNo - msg += 'in "' + self.fname + '".\n' + msg += ' in "' + self.fname + '".\n' sys.stderr.write(msg) yield (tokenId, tokenStr, tokenLineNo) diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec index 0bf97b8..87799c0 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.3.6_20040413 +Version: 1.3.6_20040427 Release: 1 Epoch: 1 Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz diff --git a/qtools/qgdict.cpp b/qtools/qgdict.cpp index c3b2f74..e9306bb 100644 --- a/qtools/qgdict.cpp +++ b/qtools/qgdict.cpp @@ -41,7 +41,6 @@ #include "qdatastream.h" #include - // NOT REVISED /*! \class QGDict qgdict.h @@ -87,8 +86,8 @@ public: int QGDict::hashKeyString( const QString &key ) { #if defined(CHECK_NULL) - if ( key.isNull() ) - qWarning( "QGDict::hashStringKey: Invalid null key" ); + if ( key.isNull() ) + qWarning( "QGDict::hashStringKey: Invalid null key" ); #endif int i; register uint h=0; diff --git a/src/classdef.cpp b/src/classdef.cpp index 0ba7b6e..67fe145 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -129,8 +129,10 @@ ClassDef::~ClassDef() QCString ClassDef::displayName() const { + static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES"); + static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); QCString n; - if (Config_getBool("HIDE_SCOPE_NAMES")) + if (hideScopeNames) { n=m_className; } @@ -138,7 +140,7 @@ QCString ClassDef::displayName() const { n=qualifiedNameWithTemplateParameters(); } - if (Config_getBool("OPTIMIZE_OUTPUT_JAVA")) + if (optimizeOutputForJava) { n=substitute(n,"::","."); } @@ -1932,10 +1934,15 @@ bool ClassDef::hasDocumentation() const // returns TRUE iff class definition `bcd' represents an (in)direct base // class of class definition `cd'. -bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances) +bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances,int level) { bool found=FALSE; //printf("isBaseClass(cd=%s) looking for %s\n",cd->name().data(),bcd->name().data()); + if (level>256) + { + err("Possible recursive class relation while inside %s and looking for %s\n",name().data(),bcd->name().data()); + return FALSE; + } BaseClassListIterator bcli(*baseClasses()); for ( ; bcli.current() && !found ; ++bcli) { @@ -1945,7 +1952,7 @@ bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances) if (ccd==bcd) found=TRUE; else - found=ccd->isBaseClass(bcd,followInstances); + found=ccd->isBaseClass(bcd,followInstances,level+1); } return found; } @@ -2843,4 +2850,3 @@ MemberDef *ClassDef::getMemberByName(const QCString &name) return xmd; } - diff --git a/src/classdef.h b/src/classdef.h index d745f83..b82e603 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -149,7 +149,7 @@ class ClassDef : public Definition * class. This function will recusively traverse all branches of the * inheritance tree. */ - bool isBaseClass(ClassDef *bcd,bool followInstances); + bool isBaseClass(ClassDef *bcd,bool followInstances,int level=0); /*! Returns a sorted dictionary with all template instances found for * this template class. Returns 0 if not a template or no instances. diff --git a/src/code.l b/src/code.l index 5bf9935..366d007 100644 --- a/src/code.l +++ b/src/code.l @@ -1466,6 +1466,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) %x ObjCCall %x ObjCMName %x ObjCSkipStr +%x OldStyleArgs %% @@ -1783,7 +1784,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) if (getResolvedClass(g_currentDefinition,g_sourceFileDef,g_curClassName)==0) { ClassDef *ncd=new ClassDef("",1, - g_curClassName,ClassDef::Class,0,0,TRUE); + g_curClassName,ClassDef::Class,0,0,FALSE); g_codeClassSDict.append(g_curClassName,ncd); // insert base classes. char *s=g_curClassBases.first(); @@ -2280,7 +2281,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) g_code->codify(yytext); endFontClass(); } -{TYPEKW}/([^a-z_A-Z0-9]) { +{TYPEKW}/([^a-z_A-Z0-9]) { addParmType(); g_parmName=yytext; startFontClass("keywordtype"); @@ -2352,7 +2353,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) BEGIN( SkipInits ); } } -({BN}"const"|"volatile")*{BN}*"{" { +({BN}"const"|"volatile")*{BN}*"{" { if (g_insideBody) { g_theVarContext.pushScope(); @@ -2401,6 +2402,28 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) g_type.resize(0); g_name.resize(0); BEGIN( Body ); } +{ID} { + if (g_insideBody || !g_parmType.isEmpty()) + { + REJECT; + } + // could be K&R style definition + addParmType(); + g_parmName=yytext; + generateClassOrGlobalLink(*g_code,yytext,!g_insideBody); + BEGIN(OldStyleArgs); + } +{ID} { + addParmType(); + g_parmName=yytext; + generateClassOrGlobalLink(*g_code,yytext,!g_insideBody); + } +[,;] { + g_code->codify(yytext); + g_theVarContext.addVariable(g_parmType,g_parmName); + if (*yytext==';') g_parmType.resize(0); + g_parmName.resize(0); + } . { unput(*yytext); if (!g_insideBody) diff --git a/src/compound.xsd b/src/compound.xsd index ac77e4b..6edff66 100644 --- a/src/compound.xsd +++ b/src/compound.xsd @@ -36,7 +36,7 @@ - + @@ -52,35 +52,55 @@ - + - - - + + + + + + + - + + + + + - - + + + + + + - + + + + + - - - + + + + + + + @@ -112,7 +132,7 @@ - + @@ -140,7 +160,7 @@ - + @@ -179,20 +199,20 @@ - + - + - - + + @@ -206,9 +226,9 @@ - + - + @@ -220,14 +240,14 @@ - - + + - + @@ -240,7 +260,7 @@ - + @@ -250,7 +270,7 @@ - + @@ -260,7 +280,7 @@ - + @@ -269,7 +289,7 @@ - + @@ -382,11 +402,11 @@ - + - + @@ -437,9 +457,9 @@ - - - + + + @@ -488,7 +508,7 @@ - + @@ -506,11 +526,19 @@ - + + + + + + + + + @@ -523,7 +551,7 @@ - + @@ -532,7 +560,7 @@ - + @@ -722,5 +750,13 @@ + + + + + + + + diff --git a/src/compound_xsd.h b/src/compound_xsd.h index 6af2a92..adf1a25 100644 --- a/src/compound_xsd.h +++ b/src/compound_xsd.h @@ -36,7 +36,7 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" @@ -52,35 +52,55 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" " \n" "\n" " \n" -" \n" -" \n" -" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" "\n" " \n" -" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" "\n" " \n" -" \n" -" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" "\n" " \n" -" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" "\n" " \n" -" \n" -" \n" -" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" "\n" " \n" @@ -112,7 +132,7 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" @@ -140,7 +160,7 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" "\n" @@ -179,20 +199,20 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" "\n" " \n" " \n" " \n" " \n" -" \n" +" \n" " \n" " \n" "\n" " \n" -" \n" -" \n" +" \n" +" \n" " \n" "\n" " \n" @@ -206,9 +226,9 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" -" \n" +" \n" " \n" "\n" " \n" @@ -220,14 +240,14 @@ " \n" "\n" " \n" -" \n" -" \n" +" \n" +" \n" " \n" " \n" " \n" "\n" " \n" -" \n" +" \n" " \n" " \n" " \n" @@ -240,7 +260,7 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" "\n" " \n" @@ -250,7 +270,7 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" "\n" " \n" @@ -260,7 +280,7 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" "\n" " \n" @@ -269,7 +289,7 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" "\n" " \n" @@ -382,11 +402,11 @@ " \n" "\n" " \n" -" \n" +" \n" " \n" "\n" " \n" -" \n" +" \n" " \n" "\n" " \n" @@ -437,9 +457,9 @@ "\n" " \n" " \n" -" \n" -" \n" -" \n" +" \n" +" \n" +" \n" " \n" "\n" " \n" @@ -488,7 +508,7 @@ "\n" " \n" " \n" -" \n" +" \n" " \n" "\n" " \n" @@ -506,11 +526,19 @@ "\n" " \n" " \n" -" \n" +" \n" " \n" " \n" " \n" "\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" " \n" " \n" " \n" @@ -523,7 +551,7 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" "\n" " \n" @@ -532,7 +560,7 @@ " \n" " \n" " \n" -" \n" +" \n" " \n" "\n" " \n" @@ -722,5 +750,13 @@ " \n" " \n" "\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" "\n" "\n" diff --git a/src/definition.cpp b/src/definition.cpp index a99549b..aa20c7b 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -76,6 +76,7 @@ static void removeFromMap(Definition *d) Definition::Definition(const char *df,int dl, const char *name,const char *b, const char *d,bool isSymbol) + : m_reachableDefs(17) { //QCString ns; m_defFileName = df; @@ -111,6 +112,8 @@ Definition::Definition(const char *df,int dl, m_docFile=(QCString)"<"+name+">"; m_isSymbol = isSymbol; if (m_isSymbol) addToMap(name,this); + m_reachableDefs.setAutoDelete(TRUE); + m_reachabilityComputed=FALSE; } Definition::~Definition() @@ -578,9 +581,10 @@ void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) bool Definition::hasDocumentation() const { + static bool extractAll = Config_getBool("EXTRACT_ALL"); return !m_doc.isEmpty() || // has detailed docs !m_brief.isEmpty() || // has brief description - Config_getBool("EXTRACT_ALL"); // extract everything + extractAll; // extract everything } void Definition::addSourceReferencedBy(MemberDef *md) @@ -640,8 +644,10 @@ void Definition::addInnerCompound(Definition *) err("Error: Definition::addInnerCompound() called\n"); } -QCString Definition::qualifiedName() const +QCString Definition::qualifiedName() { + if (!m_qualifiedName.isEmpty()) return m_qualifiedName; + //printf("start Definition::qualifiedName() localName=%s\n",m_localName.data()); if (m_outerScope==0) { @@ -649,17 +655,16 @@ QCString Definition::qualifiedName() const else return m_localName; } - QCString qualifiedName; if (m_outerScope->name()=="") { - qualifiedName = m_localName.copy(); + m_qualifiedName = m_localName.copy(); } else { - qualifiedName = m_outerScope->qualifiedName()+"::"+m_localName; + m_qualifiedName = m_outerScope->qualifiedName()+"::"+m_localName; } //printf("end Definition::qualifiedName()=%s\n",qualifiedName.data()); - return qualifiedName; + return m_qualifiedName; }; QCString Definition::localName() const @@ -756,3 +761,32 @@ QCString Definition::convertNameToFile(const char *name,bool allowDots) const } } +void Definition::addReachableDef(Definition *def,int distance) +{ + if (m_reachableDefs.find(def->qualifiedName())) + { + m_reachableDefs.insert(def->qualifiedName(),new ReachableDefinition(def,distance)); + } +} + +void Definition::computeReachability() +{ + if (m_reachabilityComputed) return; + addReachableDef(this,0); + Definition *parent = getOuterScope(); + int i=1; + while (parent) + { + parent->computeReachability(); + QDictIterator dli(m_reachableDefs); + ReachableDefinition *rd; + for (dli.toFirst();(rd=dli.current());++dli) + { + addReachableDef(rd->def,i); + } + parent=parent->getOuterScope(); + i++; + } + m_reachabilityComputed=TRUE; +} + diff --git a/src/definition.h b/src/definition.h index 88d0479..a0a3cd9 100644 --- a/src/definition.h +++ b/src/definition.h @@ -20,6 +20,7 @@ #include "qtbc.h" #include +#include class FileDef; class OutputList; @@ -32,6 +33,14 @@ class GroupDef; class GroupList; struct ListItemInfo; struct SectionInfo; +class Definition; + +struct ReachableDefinition +{ + ReachableDefinition(Definition *d,int dist) : def(d), distance(dist) {} + Definition *def; + int distance; +}; /*! The common base class of all entity definitions found in the sources. */ class Definition @@ -58,7 +67,7 @@ class Definition /*! Returns the base name of the output file that contains this * definition. */ - virtual QCString qualifiedName() const; + virtual QCString qualifiedName(); QCString localName() const; virtual QCString getOutputFileBase() const = 0; /*! Returns the name of the source listing of this file. */ @@ -132,6 +141,7 @@ class Definition virtual Definition *getOuterScope() const { return m_outerScope; } virtual void addInnerCompound(Definition *d); virtual void setOuterScope(Definition *d) { m_outerScope = d; } + virtual void computeReachability(); MemberSDict *getReferencesMembers() const { return m_sourceRefsDict; } MemberSDict *getReferencedByMembers() const { return m_sourceRefByDict; } @@ -139,6 +149,7 @@ class Definition void makePartOfGroup(GroupDef *gd); GroupList *partOfGroups() const { return m_partOfGroups; } QCString convertNameToFile(const char *name,bool allowDots=FALSE) const; + void addReachableDef(Definition *d,int distance); protected: int m_startBodyLine; // line number of the start of the definition @@ -158,6 +169,9 @@ class Definition /*! List of groups this definition is part of */ GroupList *m_partOfGroups; + // reachability of other definitions from this one + QDict m_reachableDefs; + bool m_reachabilityComputed; private: int getXRefListId(const char *listName) const; @@ -181,6 +195,9 @@ class Definition QList *m_xrefListItems; QCString m_symbolName; bool m_isSymbol; + + + QCString m_qualifiedName; }; class DefinitionList : public QList diff --git a/src/docparser.cpp b/src/docparser.cpp index 33cccff..d6fcee9 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -3154,13 +3154,13 @@ endparamlist: //-------------------------------------------------------------------------- -int DocParamSect::parse(const QString &cmdName) +int DocParamSect::parse(const QString &cmdName,Direction d) { int retval=RetVal_OK; DBG(("DocParamSect::parse() start\n")); g_nodeStack.push(this); - DocParamList *pl = new DocParamList(this,m_type); + DocParamList *pl = new DocParamList(this,m_type,d); if (m_children.isEmpty()) { pl->markFirst(); @@ -3204,7 +3204,9 @@ int DocPara::handleSimpleSection(DocSimpleSect::Type t) return (rv!=TK_NEWPARA) ? rv : RetVal_OK; } -int DocPara::handleParamSection(const QString &cmdName,DocParamSect::Type t) +int DocPara::handleParamSection(const QString &cmdName, + DocParamSect::Type t, + int direction=DocParamSect::Unspecified) { DocParamSect *ps=0; if (!m_children.isEmpty() && // previous element @@ -3219,7 +3221,7 @@ int DocPara::handleParamSection(const QString &cmdName,DocParamSect::Type t) ps=new DocParamSect(this,t); m_children.append(ps); } - int rv=ps->parse(cmdName); + int rv=ps->parse(cmdName,(DocParamSect::Direction)direction); return (rv!=TK_NEWPARA) ? rv : RetVal_OK; } @@ -3738,7 +3740,7 @@ int DocPara::handleCommand(const QString &cmdName) warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: unexpected command %s",g_token->name.data()); break; case CMD_PARAM: - retval = handleParamSection(cmdName,DocParamSect::Param); + retval = handleParamSection(cmdName,DocParamSect::Param,g_token->paramDir); break; case CMD_RETVAL: retval = handleParamSection(cmdName,DocParamSect::RetVal); diff --git a/src/docparser.h b/src/docparser.h index 8df9c53..ff13c46 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -909,8 +909,13 @@ class DocParamSect : public CompAccept, public DocNode { Unknown, Param, RetVal, Exception }; - DocParamSect(DocNode *parent,Type t) : m_parent(parent), m_type(t) {} - int parse(const QString &cmdName); + enum Direction + { + In=1, Out=2, InOut=3, Unspecified=0 + }; + DocParamSect(DocNode *parent,Type t) + : m_parent(parent), m_type(t) {} + int parse(const QString &cmdName,Direction d); Kind kind() const { return Kind_ParamSect; } Type type() const { return m_type; } DocNode *parent() const { return m_parent; } @@ -919,6 +924,7 @@ class DocParamSect : public CompAccept, public DocNode private: DocNode * m_parent; Type m_type; + Direction m_dir; }; /*! Node representing a paragraph in the documentation tree */ @@ -943,7 +949,8 @@ class DocPara : public CompAccept, public DocNode int handleHtmlEndTag(const QString &tagName); int handleSimpleSection(DocSimpleSect::Type t); int handleXRefItem(); - int handleParamSection(const QString &cmdName,DocParamSect::Type t); + int handleParamSection(const QString &cmdName,DocParamSect::Type t, + int direction); void handleIncludeOperator(const QString &cmdName,DocIncOperator::Type t); void handleImage(const QString &cmdName); void handleDotFile(const QString &cmdName); @@ -965,14 +972,15 @@ class DocPara : public CompAccept, public DocNode class DocParamList : public DocNode { public: - DocParamList(DocNode *parent,DocParamSect::Type t) - : m_parent(parent) , m_type(t), m_isFirst(TRUE), m_isLast(TRUE) + DocParamList(DocNode *parent,DocParamSect::Type t,DocParamSect::Direction d) + : m_parent(parent) , m_type(t), m_dir(d), m_isFirst(TRUE), m_isLast(TRUE) { m_paragraph=new DocPara(this); } virtual ~DocParamList() { delete m_paragraph; } Kind kind() const { return Kind_ParamList; } DocNode *parent() const { return m_parent; } const QStrList ¶meters() { return m_params; } DocParamSect::Type type() const { return m_type; } + DocParamSect::Direction direction() const { return m_dir; } void markFirst(bool b=TRUE) { m_isFirst=b; } void markLast(bool b=TRUE) { m_isLast=b; } bool isFirst() const { return m_isFirst; } @@ -986,12 +994,13 @@ class DocParamList : public DocNode int parse(const QString &cmdName); private: - DocNode * m_parent; - DocPara * m_paragraph; - QStrList m_params; - DocParamSect::Type m_type; - bool m_isFirst; - bool m_isLast; + DocNode * m_parent; + DocPara * m_paragraph; + QStrList m_params; + DocParamSect::Type m_type; + DocParamSect::Direction m_dir; + bool m_isFirst; + bool m_isLast; }; /*! @brief Node representing an item of a auto list */ diff --git a/src/doctokenizer.h b/src/doctokenizer.h index 4bac78d..6b5fac8 100644 --- a/src/doctokenizer.h +++ b/src/doctokenizer.h @@ -98,6 +98,10 @@ struct TokenInfo // url bool isEMailAddr; + + // param attributes + enum ParamDir { In=1, Out=2, InOut=3, Unspecified=0 }; + ParamDir paramDir; }; // globals diff --git a/src/doctokenizer.l b/src/doctokenizer.l index 5c9b6ea..31a315d 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -288,6 +288,8 @@ LINKMASK [^ \t\n\r\\@<&${}]+("("[^\n)]*")")?({BLANK}*("const"|"volatile"))? SPCMD1 {CMD}[a-z_A-Z0-9]+ SPCMD2 {CMD}[\\@<>&$#%~] SPCMD3 {CMD}form#[0-9]+ +INOUT "in"|"out"|("in"{BLANK}*","{BLANK}*"out")|("out"{BLANK}*","{BLANK}*"in") +PARAMIO {CMD}param{BLANK}*"["{BLANK}*{INOUT}{BLANK}*"]" TEMPCHAR [a-z_A-Z0-9,: \t\*\&] FUNCCHAR [a-z_A-Z0-9,:\<\> \t\*\&] SCOPESEP "::"|"#"|"." @@ -391,8 +393,35 @@ LABELID [a-z_A-Z][a-z_A-Z0-9\-]* {SPCMD1} | {SPCMD2} { /* special command */ g_token->name = yytext+1; + g_token->paramDir=TokenInfo::Unspecified; return TK_COMMAND; } +{PARAMIO} { /* param [in,out] command */ + g_token->name = "param"; + QString s(yytext); + bool isIn = s.find("in")!=-1; + bool isOut = s.find("out")!=-1; + if (isIn) + { + if (isOut) + { + g_token->paramDir=TokenInfo::InOut; + } + else + { + g_token->paramDir=TokenInfo::In; + } + } + else if (isOut) + { + g_token->paramDir=TokenInfo::Out; + } + else + { + g_token->paramDir=TokenInfo::Unspecified; + } + return TK_COMMAND; + } ("http:"|"https:"|"ftp:"|"file:"|"news:"){URLMASK} { // URL g_token->name=yytext; g_token->isEMailAddr=FALSE; @@ -567,6 +596,7 @@ LABELID [a-z_A-Z][a-z_A-Z0-9\-]* {SPCMD1} | {SPCMD2} { /* special command */ g_token->name = yytext+1; + g_token->paramDir=TokenInfo::Unspecified; return TK_COMMAND; } {WORD1} | @@ -592,6 +622,7 @@ LABELID [a-z_A-Z][a-z_A-Z0-9\-]* {SPCMD1} | {SPCMD2} { /* special command */ g_token->name = yytext+1; + g_token->paramDir=TokenInfo::Unspecified; return TK_COMMAND; } {WORD1NQ} | @@ -663,6 +694,7 @@ LABELID [a-z_A-Z][a-z_A-Z0-9\-]* {SPCMD1} | {SPCMD2} { /* special command */ g_token->name = yytext+1; + g_token->paramDir=TokenInfo::Unspecified; return TK_COMMAND; } {WORD1NQ} | diff --git a/src/doxygen.cpp b/src/doxygen.cpp index d71e7c1..6ca2c29 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -1217,24 +1217,9 @@ static void findUsingDeclarations(Entry *root) // the possible scopes in which the using statement was found, starting // with the most inner scope and going to the most outer scope (i.e. // file scope). -// int scopeOffset = scName.length(); -// do -// { -// QCString scope=scopeOffset>0 ? -// scName.left(scopeOffset)+"::" : QCString(); -// //printf("Trying with scope=`%s'\n",scope.data()); -// usingCd = getClass(scope+root->name); -// if (scopeOffset==0) -// { -// scopeOffset=-1; -// } -// else if ((scopeOffset=scName.findRev("::",scopeOffset-1))==-1) -// { -// scopeOffset=0; -// } -// } while (scopeOffset>=0 && usingCd==0); - - usingCd = getResolvedClass(nd,fd,root->name); + + MemberDef *mtd=0; + usingCd = getResolvedClass(nd,fd,root->name,&mtd); //printf("%s -> %p\n",root->name.data(),usingCd); if (usingCd==0) // definition not in the input => add an artificial class @@ -1248,8 +1233,20 @@ static void findUsingDeclarations(Entry *root) usingCd->setClassIsArtificial(); } - // add the namespace the correct scope - if (usingCd) + if (mtd) // add the typedef to the correct scope + { + if (nd) + { + //printf("Inside namespace %s\n",nd->name().data()); + nd->addUsingDeclaration(mtd); + } + else if (fd) + { + //printf("Inside file %s\n",nd->name().data()); + fd->addUsingDeclaration(mtd); + } + } + else if (usingCd) // add the class to the correct scope { if (nd) { @@ -1623,20 +1620,23 @@ static MemberDef *addVariableToFile( return md; } - if (nd==0 && md->isExplicit()!=root->explicitExternal) - { - // merge ingroup specifiers - if (md->getGroupDef()==0 && root->groups->first()) - { - //GroupDef *gd=Doxygen::groupSDict[root->groups->first()->groupname.data()]; - //md->setGroupDef(gd, root->groups->first()->pri, root->fileName, root->startLine, !root->doc.isEmpty()); - addMemberToGroups(root,md); - } - else if (md->getGroupDef()!=0 && root->groups->count()==0) - { - root->groups->append(new Grouping(md->getGroupDef()->name(), md->getGroupPri())); - } - } + // TODO: rethink why we would need this! + //if (nd==0 && md->isExplicit()!=root->explicitExternal) + //{ + // // merge ingroup specifiers + // if (md->getGroupDef()==0 && root->groups->first()) + // { + // //GroupDef *gd=Doxygen::groupSDict[root->groups->first()->groupname.data()]; + // //md->setGroupDef(gd, root->groups->first()->pri, root->fileName, root->startLine, !root->doc.isEmpty()); + // addMemberToGroups(root,md); + // } + // else if (md->getGroupDef()!=0 && root->groups->count()==0) + // { + // // enabling has the result that an ungrouped, undocumented external variable is put + // // in a group if the definition is documented and grouped! + // //root->groups->append(new Grouping(md->getGroupDef()->name(), md->getGroupPri())); + // } + //} } } // new global variable, enum value or typedef @@ -1668,10 +1668,6 @@ static MemberDef *addVariableToFile( md->enableCallGraph(root->callGraph); md->setExplicitExternal(root->explicitExternal); addMemberToGroups(root,md); - //if (root->mGrpId!=-1) - //{ - // md->setMemberGroup(memberGroupDict[root->mGrpId]); - //} md->setRefItems(root->sli); if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') @@ -2286,8 +2282,8 @@ static void buildFunctionList(Entry *root) QCString nsName,rnsName; if (nd) nsName = nd->name().copy(); if (rnd) rnsName = rnd->name().copy(); - NamespaceSDict *unl = fd ? fd->getUsedNamespaces() : 0; - ClassSDict *ucl = fd ? fd->getUsedClasses() : 0; + NamespaceSDict *unl = fd ? fd->getUsedNamespaces() : 0; + SDict *ucl = fd ? fd->getUsedClasses() : 0; //printf("matching arguments for %s%s %s%s\n", // md->name().data(),md->argsString(),rname.data(),argListToString(root->argList).data()); if ( @@ -2968,32 +2964,34 @@ static ClassDef *findClassWithinClassContext(ClassDef *cd,const QCString &name) if (result && result!=cd) return result; } } - ClassSDict *cl = nd->getUsedClasses(); + SDict *cl = nd->getUsedClasses(); if (cl) { - ClassSDict::Iterator cli(*cl); - ClassDef *ucd; + SDict::Iterator cli(*cl); + Definition *ucd; for (cli.toFirst(); (ucd=cli.current()) ; ++cli) { - if (rightScopeMatch(ucd->name(),name)) + if (ucd->definitionType()==Definition::TypeClass && + rightScopeMatch(ucd->name(),name)) { - return ucd; + return (ClassDef *)ucd; } } } // TODO: check any inbetween namespaces as well! if (fd) // and in the global namespace { - ClassSDict *cl = fd->getUsedClasses(); + SDict *cl = fd->getUsedClasses(); if (cl) { - ClassSDict::Iterator cli(*cl); - ClassDef *ucd; + SDict::Iterator cli(*cl); + Definition *ucd; for (cli.toFirst(); (ucd=cli.current()); ++cli) { - if (rightScopeMatch(ucd->name(),name)) + if (ucd->definitionType()==Definition::TypeClass && + rightScopeMatch(ucd->name(),name)) { - return ucd; + return (ClassDef *)ucd; } } } @@ -3020,16 +3018,17 @@ static ClassDef *findClassWithinClassContext(ClassDef *cd,const QCString &name) } } } - ClassSDict *cl = fd->getUsedClasses(); + SDict *cl = fd->getUsedClasses(); if (cl) { - ClassSDict::Iterator cli(*cl); - ClassDef *ucd; + SDict::Iterator cli(*cl); + Definition *ucd; for (cli.toFirst(); (ucd=cli.current()) ; ++cli) { - if (rightScopeMatch(ucd->name(),name)) + if (ucd->definitionType()==Definition::TypeClass && + rightScopeMatch(ucd->name(),name)) { - return ucd; + return (ClassDef *)ucd; } } } @@ -4139,8 +4138,8 @@ static bool findGlobalMember(Entry *root, // namespaceName.data(),nd ? nd->name().data() : ""); FileDef *fd=findFileDef(Doxygen::inputNameDict,root->fileName,ambig); //printf("File %s\n",fd ? fd->name().data() : ""); - NamespaceSDict *nl = fd ? fd->getUsedNamespaces() : 0; - ClassSDict *cl = fd ? fd->getUsedClasses() : 0; + NamespaceSDict *nl = fd ? fd->getUsedNamespaces() : 0; + SDict *cl = fd ? fd->getUsedClasses() : 0; //printf("NamespaceList %p\n",nl); // search in the list of namespaces that are imported via a @@ -4676,14 +4675,14 @@ static void findMember(Entry *root, } } - ClassSDict *cl = new ClassSDict(17); + SDict *cl = new SDict(17); if (nd) { - ClassSDict *ncl = nd->getUsedClasses(); + SDict *ncl = nd->getUsedClasses(); if (ncl) { - ClassSDict::Iterator csdi(*ncl); - ClassDef *ncd; + SDict::Iterator csdi(*ncl); + Definition *ncd; for (csdi.toFirst();(ncd=csdi.current());++csdi) { cl->append(ncd->qualifiedName(),ncd); @@ -4692,11 +4691,11 @@ static void findMember(Entry *root, } if (fd) { - ClassSDict *fcl = fd->getUsedClasses(); + SDict *fcl = fd->getUsedClasses(); if (fcl) { - ClassSDict::Iterator csdi(*fcl); - ClassDef *fcd; + SDict::Iterator csdi(*fcl); + Definition *fcd; for (csdi.toFirst();(fcd=csdi.current());++csdi) { cl->append(fcd->qualifiedName(),fcd); diff --git a/src/filedef.cpp b/src/filedef.cpp index b04c5e3..0c00968 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -681,15 +681,15 @@ void FileDef::addUsingDirective(NamespaceDef *nd) } } -void FileDef::addUsingDeclaration(ClassDef *cd) +void FileDef::addUsingDeclaration(Definition *d) { if (usingDeclList==0) { - usingDeclList = new ClassSDict; + usingDeclList = new SDict(17); } - if (usingDeclList->find(cd->qualifiedName())==0) + if (usingDeclList->find(d->qualifiedName())==0) { - usingDeclList->append(cd->qualifiedName(),cd); + usingDeclList->append(d->qualifiedName(),d); } } @@ -1053,8 +1053,8 @@ void FileDef::combineUsingRelations() // add used classes of namespace nd to this namespace if (nd->getUsedClasses()) { - ClassSDict::Iterator cli(*nd->getUsedClasses()); - ClassDef *ucd; + SDict::Iterator cli(*nd->getUsedClasses()); + Definition *ucd; for (cli.toFirst();(ucd=cli.current());++cli) { //printf("Adding class %s to the using list of %s\n",cd->qualifiedName().data(),qualifiedName().data()); diff --git a/src/filedef.h b/src/filedef.h index d9d2f46..5d64763 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -134,8 +134,8 @@ class FileDef : public Definition void addUsingDirective(NamespaceDef *nd); NamespaceSDict *getUsedNamespaces() const { return usingDirList; } - void addUsingDeclaration(ClassDef *cd); - ClassSDict *getUsedClasses() const { return usingDeclList; } + void addUsingDeclaration(Definition *def); + SDict *getUsedClasses() const { return usingDeclList; } void combineUsingRelations(); bool generateSourceFile() const; @@ -188,7 +188,7 @@ class FileDef : public Definition QDict *includedByDict; QList *includedByList; NamespaceSDict *usingDirList; - ClassSDict *usingDeclList; + SDict *usingDeclList; //DefineList *defineList; QCString path; QCString filepath; diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index a2ca11f..62460df 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -189,12 +189,12 @@ void HtmlDocVisitor::visit(DocVerbatim *s) switch(s->type()) { case DocVerbatim::Code: // fall though - m_t << "
    "; + m_t << "
    "; parseCode(m_ci,s->context(),s->text().latin1(),s->isExample(),s->exampleFile()); m_t << "
    "; break; case DocVerbatim::Verbatim: - m_t << "
    "; + m_t << "
    "; filter(s->text()); m_t << "
    "; break; @@ -246,16 +246,16 @@ void HtmlDocVisitor::visit(DocInclude *inc) switch(inc->type()) { case DocInclude::Include: - m_t << "
    "; + m_t << "
    "; parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile()); m_t << "
    "; case DocInclude::IncWithLines: { - m_t << "
    ";
    +         m_t << "
    "; QFileInfo cfi( inc->file() ); FileDef fd( cfi.dirPath(), cfi.fileName() ); parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile(), &fd); - m_t << "
    "; + m_t << "
    "; } break; break; @@ -265,7 +265,7 @@ void HtmlDocVisitor::visit(DocInclude *inc) m_t << inc->text(); break; case DocInclude::VerbInclude: - m_t << "
    "; + m_t << "
    "; filter(inc->text()); m_t << "
    "; break; @@ -278,7 +278,7 @@ void HtmlDocVisitor::visit(DocIncOperator *op) // op->type(),op->isFirst(),op->isLast(),op->text().data()); if (op->isFirst()) { - if (!m_hide) m_t << "
    "; + if (!m_hide) m_t << "
    "; pushEnabled(); m_hide=TRUE; } @@ -868,7 +868,25 @@ void HtmlDocVisitor::visitPost(DocParamSect *) void HtmlDocVisitor::visitPre(DocParamList *pl) { if (m_hide) return; - m_t << " "; + m_t << " "; + if (pl->direction()!=DocParamSect::Unspecified) + { + m_t << "["; + if (pl->direction()==DocParamSect::In) + { + m_t << "in"; + } + else if (pl->direction()==DocParamSect::Out) + { + m_t << "out"; + } + else if (pl->direction()==DocParamSect::InOut) + { + m_t << "in,out"; + } + m_t << "] "; + } + m_t << ""; QStrListIterator li(pl->parameters()); const char *s; bool first=TRUE; diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 0da3849..0e3316a 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -888,7 +888,25 @@ void LatexDocVisitor::visitPost(DocParamSect *) void LatexDocVisitor::visitPre(DocParamList *pl) { if (m_hide) return; - m_t << "\\item[{\\em "; + m_t << "\\item["; + if (pl->direction()!=DocParamSect::Unspecified) + { + m_t << "\\mbox{"; + if (pl->direction()==DocParamSect::In) + { + m_t << "$\\leftarrow$"; + } + else if (pl->direction()==DocParamSect::Out) + { + m_t << "$\\rightarrow$"; + } + else if (pl->direction()==DocParamSect::InOut) + { + m_t << "$\\leftrightarrow$"; + } + m_t << "} "; + } + m_t << "{\\em "; QStrListIterator li(pl->parameters()); const char *s; bool first=TRUE; diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 4e44a98..9676557 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -2226,7 +2226,7 @@ bool MemberDef::isObjCMethod() const return FALSE; } -QCString MemberDef::qualifiedName() const +QCString MemberDef::qualifiedName() { if (isObjCMethod()) { diff --git a/src/memberdef.h b/src/memberdef.h index c19133e..564fdc0 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -99,7 +99,7 @@ class MemberDef : public Definition const char *getGroupFileName() const { return groupFileName; } int getGroupStartLine() const { return groupStartLine; } bool getGroupHasDocs() const { return groupHasDocs; } - QCString qualifiedName() const; + QCString qualifiedName(); // direct kind info Protection protection() const { return prot; } diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index 6d00bbc..5178b76 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -36,7 +36,7 @@ NamespaceDef::NamespaceDef(const char *df,int dl, fileName+=name; classSDict = new ClassSDict(17); namespaceSDict = new NamespaceSDict(17); - m_innerCompounds = new SDict(17); + m_innerCompounds = new SDict(257); usingDirList = 0; usingDeclList = 0; setReference(lref); @@ -399,15 +399,15 @@ void NamespaceDef::addUsingDirective(NamespaceDef *nd) } } -void NamespaceDef::addUsingDeclaration(ClassDef *cd) +void NamespaceDef::addUsingDeclaration(Definition *d) { if (usingDeclList==0) { - usingDeclList = new ClassSDict; + usingDeclList = new SDict(17); } - if (usingDeclList->find(cd->qualifiedName())==0) + if (usingDeclList->find(d->qualifiedName())==0) { - usingDeclList->append(cd->qualifiedName(),cd); + usingDeclList->append(d->qualifiedName(),d); } } @@ -480,8 +480,8 @@ void NamespaceDef::combineUsingRelations() // add used classes of namespace nd to this namespace if (nd->getUsedClasses()) { - ClassSDict::Iterator cli(*nd->getUsedClasses()); - ClassDef *ucd; + SDict::Iterator cli(*nd->getUsedClasses()); + Definition *ucd; for (cli.toFirst();(ucd=cli.current());++cli) { //printf("Adding class %s to the using list of %s\n",cd->qualifiedName().data(),qualifiedName().data()); diff --git a/src/namespacedef.h b/src/namespacedef.h index 7334f8e..51d30d2 100644 --- a/src/namespacedef.h +++ b/src/namespacedef.h @@ -55,8 +55,8 @@ class NamespaceDef : public Definition int countMembers(); void addUsingDirective(NamespaceDef *nd); NamespaceSDict *getUsedNamespaces() const { return usingDirList; } - void addUsingDeclaration(ClassDef *cd); - ClassSDict *getUsedClasses() const { return usingDeclList; } + void addUsingDeclaration(Definition *def); + SDict *getUsedClasses() const { return usingDeclList; } void combineUsingRelations(); QCString displayName() const; @@ -118,7 +118,7 @@ class NamespaceDef : public Definition NamespaceSDict *usingDirList; - ClassSDict *usingDeclList; + SDict *usingDeclList; SDict *m_innerCompounds; MemberList allMemberList; diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp index c5c9858..3a05f20 100644 --- a/src/perlmodgen.cpp +++ b/src/perlmodgen.cpp @@ -232,7 +232,7 @@ void PerlModOutput::iaddQuoted(const char *s) } } -inline void PerlModOutput::iaddField(const char *s) +void PerlModOutput::iaddField(const char *s) { continueBlock(); m_stream->add(s); diff --git a/src/scanner.l b/src/scanner.l index 457f5b0..f8c7033 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -491,7 +491,7 @@ static void prependScope() /*! Returns TRUE iff the current entry could be a K&R style C function */ static bool checkForKnRstyleC() { - if (((QCString)yyFileName).right(2)!=".c") return FALSE; // must be a C file + if (((QCString)yyFileName).right(2).lower()!=".c") return FALSE; // must be a C file if (!current->argList) return FALSE; ArgumentListIterator ali(*current->argList); Argument *a; @@ -3575,12 +3575,14 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] } "<" { current->name += *yytext; sharpCount=1; + roundCount=0; lastSkipSharpContext = YY_START; specName = ¤t->name; BEGIN ( Specialization ); } "<" { sharpCount=1; + roundCount=0; lastSkipSharpContext = YY_START; if (insideObjC) // start of protocol list { @@ -3594,17 +3596,19 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] } } "<" { *specName += *yytext; - sharpCount++; + if (roundCount==0) sharpCount++; } ">" { *specName += *yytext; - if (--sharpCount<=0) + if (roundCount==0 && --sharpCount<=0) BEGIN(lastSkipSharpContext); } {BN}+ { lineCount(); *specName +=' '; } "<<" { *specName += yytext; } ">>" { *specName += yytext; } "typename"{BN}+ { lineCount(); } +"(" { *specName += *yytext; roundCount++; } +")" { *specName += *yytext; roundCount--; } . { *specName += *yytext; } diff --git a/src/util.cpp b/src/util.cpp index c535634..f962c1f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -60,12 +60,13 @@ extern char **environ; //------------------------------------------------------------------------ -static QCache g_accessibilityCache(10000,10000); +static QCache g_lookupCache(20000,20000); +// object that automatically initializes the cache at startup class CacheInitializer { public: - CacheInitializer() { g_accessibilityCache.setAutoDelete(TRUE); } + CacheInitializer() { g_lookupCache.setAutoDelete(TRUE); } } g_cacheInitializer; @@ -578,7 +579,7 @@ ClassDef *getResolvedClassRec(Definition *scope, MemberDef **pTypeDef, QCString *pTemplSpec ); -int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item, +int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope,Definition *item, const QCString &explicitScopePart); /*! Returns the class representing the value of the typedef represented by \a md @@ -673,7 +674,7 @@ QCString substTypedef(Definition *scope,FileDef *fileScope,const QCString &name) if (md->isTypedef()) // d is a typedef { // test accessibility of typedef within scope. - int distance = isAccessibleFrom(scope,fileScope,d,""); + int distance = isAccessibleFromWithExpScope(scope,fileScope,d,""); if (distance!=-1 && distance *cl, FileDef *fileScope, Definition *item, const QCString &explicitScopePart="" @@ -719,26 +720,14 @@ bool accessibleViaUsingClass(const ClassSDict *cl, { if (cl) // see if the class was imported via a using statement { - ClassSDict::Iterator cli(*cl); - ClassDef *ucd; + SDict::Iterator cli(*cl); + Definition *ucd; + bool explicitScopePartEmpty = explicitScopePart.isEmpty(); for (cli.toFirst();(ucd=cli.current());++cli) { //printf("Trying via used class %s\n",ucd->name().data()); - Definition *sc = explicitScopePart.isEmpty() ? ucd : followPath(ucd,fileScope,explicitScopePart); - if (item->definitionType()==Definition::TypeMember) - { - MemberDef *md = (MemberDef *)item; - if (md->isTypedef()) // d is a typedef - { - QCString spec; - ClassDef *typedefClass = newResolveTypedef(fileScope,md,&spec); - if (sc && sc==typedefClass) return TRUE; - } - } - else // item is a class - { - if (sc && sc==item) return TRUE; - } + Definition *sc = explicitScopePartEmpty ? ucd : followPath(ucd,fileScope,explicitScopePart); + if (sc && sc==item) return TRUE; //printf("Try via used class done\n"); } } @@ -773,15 +762,10 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item) { //fprintf(stderr,"name().data(),item->name().data(),item->getOuterScope()->name().data()); - QCString key=scope->name()+"+"+item->qualifiedName(); - int *pval=g_accessibilityCache.find(key); + int result=0; // assume we found it int i; - if (pval) // value was cached - { - //fprintf(stderr,"> found cached value=%d\n",*pval); - return *pval; - } + if (item->getOuterScope()==scope) { //fprintf(stderr,"> found it\n"); @@ -790,7 +774,7 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item) { if (fileScope) { - ClassSDict *cl = fileScope->getUsedClasses(); + SDict *cl = fileScope->getUsedClasses(); if (accessibleViaUsingClass(cl,fileScope,item)) { //fprintf(stderr,"> found via used class\n"); @@ -812,7 +796,7 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item) if (scope->definitionType()==Definition::TypeNamespace) { NamespaceDef *nscope = (NamespaceDef*)scope; - ClassSDict *cl = nscope->getUsedClasses(); + SDict *cl = nscope->getUsedClasses(); if (accessibleViaUsingClass(cl,fileScope,item)) { //fprintf(stderr,"> found via used class\n"); @@ -831,7 +815,7 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item) result= (i==-1) ? -1 : i+1; } done: - g_accessibilityCache.insert(key,new int(result)); + //g_lookupCache.insert(key,new int(result)); return result; } @@ -840,7 +824,7 @@ done: * if item in not in this scope. The explicitScopePart limits the search * to scopes that match \a scope plus the explicit part. */ -int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item, +int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope,Definition *item, const QCString &explicitScopePart) { if (explicitScopePart.isEmpty()) @@ -848,17 +832,10 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item, // handle degenerate case where there is no explicit scope. return isAccessibleFrom(scope,fileScope,item); } - //printf("name().data():"", + //printf("name().data():"", // item?item->name().data():"", // explicitScopePart.data()); - QCString key=scope->name()+"+"+item->qualifiedName()+"+"+explicitScopePart; - int *pval=g_accessibilityCache.find(key); int result=0; // assume we found it - if (pval) // value was cached - { - //printf("> found cached value=%d\n",*pval); - return *pval; - } Definition *newScope = followPath(scope,fileScope,explicitScopePart); if (newScope) // explicitScope is inside scope => newScope is the result { @@ -878,14 +855,14 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item, // in A via a using directive. //printf("newScope is a namespace: %s!\n",newScope->name().data()); NamespaceDef *nscope = (NamespaceDef*)newScope; - ClassSDict *cl = nscope->getUsedClasses(); + SDict *cl = nscope->getUsedClasses(); if (cl) { - ClassSDict::Iterator cli(*cl); - ClassDef *cd; + SDict::Iterator cli(*cl); + Definition *cd; for (cli.toFirst();(cd=cli.current());++cli) { - i = isAccessibleFrom(scope,fileScope,item,cd->name()); + i = isAccessibleFromWithExpScope(scope,fileScope,item,cd->name()); if (i!=-1) { //printf("> found via explicit scope of used class\n"); @@ -902,7 +879,7 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item, { if (g_visitedNamespaces.find(nd->name())==0) { - i = isAccessibleFrom(scope,fileScope,item,nd->name()); + i = isAccessibleFromWithExpScope(scope,fileScope,item,nd->name()); if (i!=-1) { //printf("> found via explicit scope of used namespace\n"); @@ -915,7 +892,8 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item, // repeat for the parent scope if (scope!=Doxygen::globalScope) { - i = isAccessibleFrom(scope->getOuterScope(),fileScope,item,explicitScopePart); + i = isAccessibleFromWithExpScope(scope->getOuterScope(),fileScope, + item,explicitScopePart); } //printf("> result=%d\n",i); result = (i==-1) ? -1 : i+1; @@ -927,7 +905,7 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item, if (scope->definitionType()==Definition::TypeNamespace) { NamespaceDef *nscope = (NamespaceDef*)scope; - ClassSDict *cl = nscope->getUsedClasses(); + SDict *cl = nscope->getUsedClasses(); if (accessibleViaUsingClass(cl,fileScope,item,explicitScopePart)) { //printf("> found in used class\n"); @@ -944,7 +922,7 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item, { if (fileScope) { - ClassSDict *cl = fileScope->getUsedClasses(); + SDict *cl = fileScope->getUsedClasses(); if (accessibleViaUsingClass(cl,fileScope,item,explicitScopePart)) { //printf("> found in used class\n"); @@ -962,13 +940,14 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item, } else // continue by looking into the parent scope { - int i=isAccessibleFrom(scope->getOuterScope(),fileScope,item,explicitScopePart); + int i=isAccessibleFromWithExpScope(scope->getOuterScope(),fileScope, + item,explicitScopePart); //printf("> result=%d\n",i); result= (i==-1) ? -1 : i+1; } } done: - g_accessibilityCache.insert(key,new int(result)); + //g_lookupCache.insert(key,new int(result)); return result; } @@ -1006,6 +985,7 @@ ClassDef *getResolvedClassRec(Definition *scope, replaceNamespaceAliases(explicitScopePart,explicitScopePart.length()); name=name.mid(qualifierIndex+2); } + if (name.isEmpty()) { //printf("] empty name\n"); @@ -1016,22 +996,43 @@ ClassDef *getResolvedClassRec(Definition *scope, //printf("Looking for symbol %s result=%p\n",name.data(),dl); if (dl==0) { - //printf("] no such symbol\n"); - return 0; // symbol not found + // name is not a known symbol + return 0; } + // Since it is often the case that the same name is searched in the same + // scope over an over again (especially for the linked source code generation) + // we use a cache to collect previous results. This is possible since the + // result of a lookup is deterministic. As the key we use the concatenated + // scope, the name to search for and the explicit scope prefix. The speedup + // achieved by this simple cache can be enormous. + QCString key=scope->name()+"+"+name+"+"+explicitScopePart; + ClassDef **pval=g_lookupCache.find(key); + //printf("Searching for %s result=%p\n",key.data(),pval); + if (pval) + { + return *pval; + } + else // not found yet; we already add a 0 to avoid the possibility of + // endless recursion. + { + g_lookupCache.insert(key,new ClassDef*(0)); + } + + ClassDef *bestMatch=0; + //printf(" found %d symbol with name %s\n",dl->count(),name.data()); // now we look int the list of Definitions and determine which one is the "best" DefinitionListIterator dli(*dl); Definition *d; - ClassDef *bestMatch=0; MemberDef *bestTypedef=0; QCString bestTemplSpec; int minDistance=10000; // init at "infinite" - for (dli.toFirst();(d=dli.current());++dli) // foreach definition + int count=0; + for (dli.toFirst();(d=dli.current());++dli,++count) // foreach definition { - //printf(" found type %x name=%s\n", - // d->definitionType(),d->name().data()); + //fprintf(stderr," found type %x name=%s (%d/%d)\n", + // d->definitionType(),d->name().data(),count,dl->count()); // only look at classes and members if (d->definitionType()==Definition::TypeClass || @@ -1039,7 +1040,7 @@ ClassDef *getResolvedClassRec(Definition *scope, { g_visitedNamespaces.clear(); // test accessibility of definition within scope. - int distance = isAccessibleFrom(scope,fileScope,d,explicitScopePart); + int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart); if (distance!=-1) // definition is accessible { // see if we are dealing with a class or a typedef @@ -1060,8 +1061,6 @@ ClassDef *getResolvedClassRec(Definition *scope, if (md->isTypedef()) // d is a typedef { //printf(" found typedef!\n"); - QCString spec; - ClassDef *typedefClass = newResolveTypedef(fileScope,md,&spec); // we found a symbol at this distance, but if it didn't // resolve to a class, we still have to make sure that @@ -1069,8 +1068,9 @@ ClassDef *getResolvedClassRec(Definition *scope, // that symbol is hidden by this one. if (distancename().data():"",minDistance); return bestMatch; @@ -1119,7 +1129,6 @@ ClassDef *getResolvedClass(Definition *scope, { scope=Doxygen::globalScope; } - //printf("-------- start\n"); //printf("getResolvedClass(%s,%s)\n",scope?scope->name().data():"",n); ClassDef *result = getResolvedClassRec(scope,fileScope,n,pTypeDef,pTemplSpec); if (!mayBeUnlinkable && result && !result->isLinkable()) @@ -1129,7 +1138,6 @@ ClassDef *getResolvedClass(Definition *scope, //printf("getResolvedClass(%s,%s)=%s\n",scope?scope->name().data():"", // n,result?result->name().data():""); // - //printf("-------- end\n"); return result; } @@ -1308,54 +1316,28 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope,FileDef *fileSco NamespaceDef *nd=0; GroupDef *gd=0; - //QCString searchName=name; - //printf("word=`%s' scope=`%s'\n", - // word.data(),scope ? scope->name().data() : "" - // ); -// Definition *curScope = scope; - // check if `word' is a documented class name - //int scopeOffset=scopeName.length(); -// do // for each scope (starting with full scope and going to empty scope) -// { - //printf("Searching %s in %s...\n",word.data(),curScope?curScope->name().data():""); -// QCString fullName = word; -// QCString prefix; -// replaceNamespaceAliases(fullName,fullName.length()); -// //if (scopeOffset>0) -// if (curScope && curScope!=Doxygen::globalScope) -// { -// prefix = curScope->name(); -// replaceNamespaceAliases(prefix,prefix.length()); -// fullName.prepend(prefix+"::"); -// } - - MemberDef *typeDef=0; - if ((cd=getResolvedClass(scope,fileScope,word,&typeDef))) + MemberDef *typeDef=0; + if ((cd=getResolvedClass(scope,fileScope,word,&typeDef))) + { + // add link to the result + if (external ? cd->isLinkable() : cd->isLinkableInProject()) { - // add link to the result - if (external ? cd->isLinkable() : cd->isLinkableInProject()) - { - out.writeLink(cd->getReference(),cd->getOutputFileBase(),0,word); - found=TRUE; - } + out.writeLink(cd->getReference(),cd->getOutputFileBase(),0,word); + found=TRUE; } - else if (typeDef) + } + else if (typeDef) + { + if (external ? typeDef->isLinkable() : typeDef->isLinkableInProject()) { - if (external ? typeDef->isLinkable() : typeDef->isLinkableInProject()) - { - out.writeLink(typeDef->getReference(), - typeDef->getOutputFileBase(), - typeDef->anchor(), - word); - found=TRUE; - } + out.writeLink(typeDef->getReference(), + typeDef->getOutputFileBase(), + typeDef->anchor(), + word); + found=TRUE; } + } -// if (curScope) curScope = curScope->getOuterScope(); -// } //while (!found && scopeOffset>=0); -// while (!found && curScope); - -//endloop: if (scope && (scope->definitionType()==Definition::TypeClass || scope->definitionType()==Definition::TypeNamespace @@ -2072,7 +2054,7 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA, const QCString &className, const QCString &namespaceName, NamespaceSDict *usingNamespaces, - ClassSDict *usingClasses) + SDict *usingClasses) { //printf("match argument start %s:%s <-> %s:%s using nsp=%p class=%p\n", // srcA->type.data(),srcA->name.data(), @@ -2186,8 +2168,8 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA, } if (usingClasses && usingClasses->count()>0) { - ClassSDict::Iterator cli(*usingClasses); - ClassDef *cd; + SDict::Iterator cli(*usingClasses); + Definition *cd; for (;(cd=cli.current());++cli) { srcAType=trimScope(cd->name(),srcAType); @@ -2339,7 +2321,7 @@ static bool matchArgument(const Argument *srcA,const Argument *dstA, bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl, const char *cl,const char *ns,bool checkCV, NamespaceSDict *usingNamespaces, - ClassSDict *usingClasses) + SDict *usingClasses) { QCString className=cl; QCString namespaceName=ns; @@ -3536,6 +3518,7 @@ bool hasVisibleRoot(BaseClassList *bcl) QCString escapeCharsInString(const char *name,bool allowDots) { + static bool caseSenseNames = Config_getBool("CASE_SENSE_NAMES"); QCString result; char c; const char *p=name; @@ -3557,7 +3540,7 @@ QCString escapeCharsInString(const char *name,bool allowDots) case ',': result+="_00"; break; case ' ': result+="_01"; break; default: - if (Config_getBool("CASE_SENSE_NAMES") || !isupper(c)) + if (caseSenseNames || !isupper(c)) { result+=c; } @@ -3578,8 +3561,10 @@ QCString escapeCharsInString(const char *name,bool allowDots) */ QCString convertNameToFile(const char *name,bool allowDots) { + static bool shortNames = Config_getBool("SHORT_NAMES"); + static bool createSubdirs = Config_getBool("CREATE_SUBDIRS"); QCString result; - if (Config_getBool("SHORT_NAMES")) + if (shortNames) { static QDict usedNames(10007); static int count=1; @@ -3601,7 +3586,7 @@ QCString convertNameToFile(const char *name,bool allowDots) { result=escapeCharsInString(name,allowDots); } - if (Config_getBool("CREATE_SUBDIRS")) + if (createSubdirs) { if (Doxygen::htmlDirMap==0) { diff --git a/src/util.h b/src/util.h index 1ed34c5..248f640 100644 --- a/src/util.h +++ b/src/util.h @@ -26,6 +26,7 @@ #include #include #include +#include "sortdict.h" class ClassDef; class FileDef; @@ -43,13 +44,13 @@ class GroupDef; class NamespaceSDict; class ClassList; class MemberGroupSDict; -class Definition; struct TagInfo; class MemberNameInfoSDict; struct ListItemInfo; class PageDef; struct SectionInfo; class QDir; +class Definition; //-------------------------------------------------------------------- @@ -129,7 +130,7 @@ void writePageRef(OutputDocInterface &od,const char *cn,const char *mn); bool matchArguments(ArgumentList *,ArgumentList *, const char *cl=0,const char *ns=0,bool checkCV=TRUE, NamespaceSDict *usingNamespaces=0, - ClassSDict *usingClasses=0); + SDict *usingClasses=0); void mergeArguments(ArgumentList *,ArgumentList *,bool forceNameOverwrite=FALSE); QCString substituteClassNames(const QCString &s); QCString substitute(const char *s,const char *src,const char *dst); @@ -212,7 +213,7 @@ QCString linkToText(const char *link,bool isFileName); QCString stripExtension(const char *fName); void replaceNamespaceAliases(QCString &scope,int i); int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item); -int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item, +int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope,Definition *item, const QCString &explicitScopePart); int computeQualifiedIndex(const QString &name); void addDirPrefix(QCString &fileName); diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp index 423da30..a128a00 100644 --- a/src/xmldocvisitor.cpp +++ b/src/xmldocvisitor.cpp @@ -752,7 +752,25 @@ void XmlDocVisitor::visitPre(DocParamList *pl) const char *s; for (li.toFirst();(s=li.current());++li) { - m_t << ""; + m_t << "direction()!=DocParamSect::Unspecified) + { + m_t << " direction=\""; + if (pl->direction()==DocParamSect::In) + { + m_t << "in"; + } + else if (pl->direction()==DocParamSect::Out) + { + m_t << "out"; + } + else if (pl->direction()==DocParamSect::InOut) + { + m_t << "inout"; + } + m_t << "\""; + } + m_t << ">"; filter(s); m_t << "" << endl; } -- cgit v0.12