From c844985adde0459f1f01ed00d0a289591fbcd2af Mon Sep 17 00:00:00 2001 From: dimitri Date: Sun, 10 Sep 2006 20:49:41 +0000 Subject: Release-1.4.7-20060910 --- INSTALL | 4 +- README | 4 +- addon/doxyapp/doxyapp.cpp | 5 +- configure | 2 +- qtools/Doxyfile | 2 +- qtools/qcstring.cpp | 2413 ++++++++++++--------------------------------- qtools/qcstring.h | 118 ++- qtools/qfile.h | 3 +- qtools/qfile_unix.cpp | 13 + qtools/qfile_win32.cpp | 13 + qtools/qgstring.cpp | 200 ++++ qtools/qgstring.h | 137 +++ qtools/qtools.pro.in | 2 + src/classdef.cpp | 1024 +++++++++++-------- src/classdef.h | 93 +- src/code.l | 73 +- src/defgen.cpp | 24 +- src/definition.cpp | 453 ++++++--- src/definition.h | 67 +- src/diagram.cpp | 2 +- src/dirdef.cpp | 18 +- src/docparser.cpp | 33 +- src/dot.cpp | 17 +- src/doxygen.cpp | 864 +++++++++------- src/doxygen.h | 23 +- src/entry.cpp | 344 +------ src/entry.h | 15 +- src/filedef.cpp | 151 +-- src/filedef.h | 23 - src/groupdef.cpp | 27 +- src/htmlgen.cpp | 11 +- src/htmlgen.h | 3 +- src/index.cpp | 626 +++++++++--- src/index.h | 9 + src/latexgen.cpp | 41 +- src/latexgen.h | 3 +- src/libdoxygen.pro.in | 7 + src/lockingptr.h | 165 ++++ src/mangen.cpp | 7 +- src/mangen.h | 3 +- src/marshal.cpp | 639 ++++++++++++ src/marshal.h | 81 ++ src/memberdef.cpp | 1846 +++++++++++++++++++++++++++------- src/memberdef.h | 422 ++++---- src/membergroup.cpp | 37 + src/membergroup.h | 8 +- src/memberlist.cpp | 77 +- src/memberlist.h | 15 +- src/namespacedef.cpp | 117 +-- src/objcache.cpp | 315 ++++++ src/objcache.h | 113 +++ src/outputgen.h | 4 +- src/outputlist.h | 6 +- src/pagedef.cpp | 3 +- src/perlmodgen.cpp | 31 +- src/pre.l | 4 +- src/pyscanner.l | 2 +- src/rtfgen.cpp | 36 +- src/rtfgen.h | 9 +- src/scanner.l | 170 +++- src/sortdict.h | 69 ++ src/store.cpp | 392 ++++++++ src/store.h | 117 +++ src/tagreader.cpp | 2 +- src/translator_dk.h | 104 +- src/util.cpp | 121 ++- src/util.h | 4 +- src/xmlgen.cpp | 44 +- 68 files changed, 7454 insertions(+), 4376 deletions(-) create mode 100644 qtools/qgstring.cpp create mode 100644 qtools/qgstring.h create mode 100644 src/lockingptr.h create mode 100644 src/marshal.cpp create mode 100644 src/marshal.h create mode 100644 src/objcache.cpp create mode 100644 src/objcache.h create mode 100644 src/store.cpp create mode 100644 src/store.h diff --git a/INSTALL b/INSTALL index e05b46f..02be44e 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,7 @@ -DOXYGEN Version 1.4.7-20060810 +DOXYGEN Version 1.4.7-20060910 Please read the installation section of the manual (http://www.doxygen.org/install.html) for instructions. -------- -Dimitri van Heesch (10 August 2006) +Dimitri van Heesch (10 September 2006) diff --git a/README b/README index ad8c5ba..b394cec 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOXYGEN Version 1.4.7_20060810 +DOXYGEN Version 1.4.7_20060910 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) (10 August 2006) +Dimitri van Heesch (dimitri@stack.nl) (10 September 2006) diff --git a/addon/doxyapp/doxyapp.cpp b/addon/doxyapp/doxyapp.cpp index 75be1f1..0de169d 100644 --- a/addon/doxyapp/doxyapp.cpp +++ b/addon/doxyapp/doxyapp.cpp @@ -26,6 +26,7 @@ */ #include // ugly hack to get the right unistd.h (doxygen has one too) +#include #include "doxygen.h" #include "outputgen.h" #include "parserintf.h" @@ -274,7 +275,7 @@ int main(int argc,char **argv) parseInput(); // iterate over the input files - FileNameListIterator fnli(Doxygen::inputNameList); + FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; // foreach file with a certain name for (fnli.toFirst();(fn=fnli.current());++fnli) @@ -289,6 +290,8 @@ int main(int argc,char **argv) } } + // remove temporary files + unlink("/tmp/doxygen/doxygen_objdb.tmp"); // clean up after us rmdir("/tmp/doxygen"); diff --git a/configure b/configure index 4d7cda4..d6b6424 100755 --- a/configure +++ b/configure @@ -20,7 +20,7 @@ doxygen_version_minor=4 doxygen_version_revision=7 #NOTE: Setting version_mmn to "NO" will omit mmn info from the package. -doxygen_version_mmn=20060810 +doxygen_version_mmn=20060910 bin_dirs=`echo $PATH | sed -e "s/:/ /g"` diff --git a/qtools/Doxyfile b/qtools/Doxyfile index ff08b16..45f4765 100644 --- a/qtools/Doxyfile +++ b/qtools/Doxyfile @@ -829,7 +829,7 @@ MAN_LINKS = NO # generate an XML file that captures the structure of # the code including all documentation. -GENERATE_XML = YES +GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be diff --git a/qtools/qcstring.cpp b/qtools/qcstring.cpp index 44324c2..1bd7c7f 100644 --- a/qtools/qcstring.cpp +++ b/qtools/qcstring.cpp @@ -1,1760 +1,771 @@ -/**************************************************************************** -** -** -** Implementation of extended char array operations, and QByteArray and -** QCString classes -** -** Created : 920722 -** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the tools module of the Qt GUI Toolkit. -** -** This file may be distributed under the terms of the Q Public License -** as defined by Trolltech AS of Norway and appearing in the file -** LICENSE.QPL included in the packaging of this file. -** -** This file may be distributed and/or modified under the terms of the -** GNU General Public License version 2 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. -** -** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition -** licenses may use this file in accordance with the Qt Commercial License -** Agreement provided with the Software. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for -** information about Qt Commercial License Agreements. -** See http://www.trolltech.com/qpl/ for QPL licensing information. -** See http://www.trolltech.com/gpl/ for GPL licensing information. -** -** Contact info@trolltech.com if any conditions of this licensing are -** not clear to you. -** -**********************************************************************/ - -#include "qstring.h" -#include "qregexp.h" -#include "qdatastream.h" -#include -#include -#include -#include - -/***************************************************************************** - Safe and portable C string functions; extensions to standard string.h - *****************************************************************************/ - -/*! - \fn void *memmove( void *dst, const void *src, uint len ) - \relates QCString - - This function is normally part of the C library. Qt implements - memmove() for platforms that do not have it. - - memmove() copies \e len bytes from \e src into \e dst. The data is - copied correctly even if \e src and \e dst overlap. -*/ - -void *qmemmove( void *dst, const void *src, uint len ) -{ - register char *d; - register char *s; - if ( dst > src ) { - d = (char *)dst + len - 1; - s = (char *)src + len - 1; - while ( len-- ) - *d-- = *s--; - } else if ( dst < src ) { - d = (char *)dst; - s = (char *)src; - while ( len-- ) - *d++ = *s++; - } - return dst; -} - -/*! - \relates QCString - - Returns a duplicate string. - - Allocates space for a copy of \e str (using \c new), copies it, and returns - a pointer to the copy. - If \e src is null, it immediately returns 0. -*/ - -char *qstrdup( const char *str ) -{ - if ( !str ) - return 0; - char *dst = new char[strlen(str)+1]; - CHECK_PTR( dst ); - return strcpy( dst, str ); -} - -/*! - \relates QCString - - A safe strncpy() function. - - Copies all characters up to \e len bytes from \e str into \e dst and returns - a pointer to \e dst. Guarantees that \e dst is \0-terminated. - If \e src is null, it immediately returns 0. - - \sa qstrcpy() -*/ - -char *qstrncpy( char *dst, const char *src, uint len ) -{ - if ( !src ) - return 0; - strncpy( dst, src, len ); - if ( len > 0 ) - dst[len-1] = '\0'; - return dst; -} - -/*! - \fn int qstrcmp( const char *str1, const char *str2 ) - \relates QCString - - A safe strcmp() function. - - Compares \e str1 and \e str2. Returns a negative value if \e str1 - is less than \e str2, 0 if \e str1 is equal to \e str2 or a positive - value if \e str1 is greater than \e str2. - - Special case I: Returns 0 if \e str1 and \e str2 are both null. - - Special case II: Returns a random nonzero value if \e str1 is null - or \e str2 is null (but not both). - - \sa qstrncmp(), qstricmp(), qstrnicmp() -*/ - -/*! - \fn int qstrncmp( const char *str1, const char *str2, uint len ) - \relates QCString - - A safe strncmp() function. - - Compares \e str1 and \e str2 up to \e len bytes. - - Returns a negative value if \e str1 is less than \e str2, 0 if \e str1 - is equal to \e str2 or a positive value if \e str1 is greater than \e - str2. - - Special case I: Returns 0 if \e str1 and \e str2 are both null. - - Special case II: Returns a random nonzero value if \e str1 is null - or \e str2 is null (but not both). - - \sa qstrcmp(), qstricmp(), qstrnicmp() -*/ - -/*! - \fn int qstricmp( const char *str1, const char *str2 ) - \relates QCString - - A safe stricmp() function. - - Compares \e str1 and \e str2 ignoring the case. - - Returns a negative value if \e str1 is less than \e str2, 0 if \e str1 - is equal to \e str2 or a positive value if \e str1 is greater than \e - str2. - - Special case I: Returns 0 if \e str1 and \e str2 are both null. - - Special case II: Returns a random nonzero value if \e str1 is null - or \e str2 is null (but not both). - - \sa qstrcmp(), qstrncmp(), qstrnicmp() -*/ - -int qstricmp( const char *str1, const char *str2 ) -{ - register const uchar *s1 = (const uchar *)str1; - register const uchar *s2 = (const uchar *)str2; - int res; - uchar c; - if ( !s1 || !s2 ) - return s1 == s2 ? 0 : (int)((long)s2 - (long)s1); - for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ ) - if ( !c ) // strings are equal - break; - return res; -} - -/*! - \fn int strnicmp( const char *str1, const char *str2, uint len ) - \relates QCString - - A safe strnicmp() function. - - Compares \e str1 and \e str2 up to \e len bytes ignoring the case. - - Returns a negative value if \e str1 is less than \e str2, 0 if \e str1 - is equal to \e str2 or a positive value if \e str1 is greater than \e - str2. - - Special case I: Returns 0 if \e str1 and \e str2 are both null. - - Special case II: Returns a random nonzero value if \e str1 is null - or \e str2 is null (but not both). - - \sa qstrcmp(), qstrncmp() qstricmp() -*/ - -int qstrnicmp( const char *str1, const char *str2, uint len ) -{ - register const uchar *s1 = (const uchar *)str1; - register const uchar *s2 = (const uchar *)str2; - int res; - uchar c; - if ( !s1 || !s2 ) - return (int)((long)s2 - (long)s1); - for ( ; len--; s1++, s2++ ) { - if ( (res = (c=tolower(*s1)) - tolower(*s2)) ) - return res; - if ( !c ) // strings are equal - break; - } - return 0; -} - - -static Q_UINT16 crc_tbl[16]; -static bool crc_tbl_init = FALSE; - -static void createCRC16Table() // build CRC16 lookup table -{ - register uint i; - register uint j; - uint v0, v1, v2, v3; - for ( i=0; i<16; i++ ) { - v0 = i & 1; - v1 = (i >> 1) & 1; - v2 = (i >> 2) & 1; - v3 = (i >> 3) & 1; - j = 0; -#undef SET_BIT -#define SET_BIT(x,b,v) x |= v << b - SET_BIT(j, 0,v0); - SET_BIT(j, 7,v0); - SET_BIT(j,12,v0); - SET_BIT(j, 1,v1); - SET_BIT(j, 8,v1); - SET_BIT(j,13,v1); - SET_BIT(j, 2,v2); - SET_BIT(j, 9,v2); - SET_BIT(j,14,v2); - SET_BIT(j, 3,v3); - SET_BIT(j,10,v3); - SET_BIT(j,15,v3); - crc_tbl[i] = j; - } -} - -/*! - \relates QByteArray - Returns the CRC-16 checksum of \e len bytes starting at \e data. - - The checksum is independent of the byte order (endianness). -*/ - -Q_UINT16 qChecksum( const char *data, uint len ) -{ - if ( !crc_tbl_init ) { // create lookup table - createCRC16Table(); - crc_tbl_init = TRUE; - } - register Q_UINT16 crc = 0xffff; - uchar c; - uchar *p = (uchar *)data; - while ( len-- ) { - c = *p++; - crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)]; - c >>= 4; - crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)]; - } - return (~crc & 0xffff); -} - - -/***************************************************************************** - QByteArray member functions - *****************************************************************************/ - -// NOT REVISED -/*! \class QByteArray qcstring.h - - \brief The QByteArray class provides an array of bytes. - - \inherit QArray - \ingroup tools - \ingroup shared - - QByteArray is defined as QArray\. -*/ - - -/***************************************************************************** - QByteArray stream functions - *****************************************************************************/ - -/*! - \relates QByteArray - Writes a byte array to a stream and returns a reference to the stream. - - \sa \link datastreamformat.html Format of the QDataStream operators \endlink -*/ -#ifndef QT_NO_DATASTREAM - -QDataStream &operator<<( QDataStream &s, const QByteArray &a ) -{ - return s.writeBytes( a.data(), a.size() ); -} - -/*! - \relates QByteArray - Reads a byte array from a stream and returns a reference to the stream. - - \sa \link datastreamformat.html Format of the QDataStream operators \endlink -*/ - -QDataStream &operator>>( QDataStream &s, QByteArray &a ) -{ - Q_UINT32 len; - s >> len; // read size of array - if ( len == 0 || s.eof() ) { // end of file reached - a.resize( 0 ); - return s; - } - if ( !a.resize( (uint)len ) ) { // resize array -#if defined(CHECK_NULL) - qWarning( "QDataStream: Not enough memory to read QByteArray" ); -#endif - len = 0; - } - if ( len > 0 ) // not null array - s.readRawBytes( a.data(), (uint)len ); - return s; -} - -#endif //QT_NO_DATASTREAM - -/***************************************************************************** - QCString member functions - *****************************************************************************/ - -/*! - \class QCString qcstring.h - - \brief The QCString class provides an abstraction of the classic C - zero-terminated char array (char*). - - \ingroup tools - \ingroup shared - - QCString inherits QByteArray, which is defined as QArray\. - - Since QCString is a QArray, it uses \e explicit - \link shclass.html sharing\endlink with a reference count. - - You might use QCString for text that is never exposed to the user, - but for text the user sees, you should use QString (which provides - implicit sharing, Unicode and other internationalization support). - - Note that QCString is one of the weaker classes in Qt; its design is - flawed (it tries to behave like a more convenient const char *) and - as a result, algorithms that use QCString heavily all too often - perform badly. For example, append() is O(length()) since it scans - for a null terminator, which makes many algorithms that use QCString - scale even worse. - - Note that for the QCString methods that take a const char * - parameter the results are undefined if the QCString is not - zero-terminated. It is legal for the const char * parameter - to be 0. - - A QCString that has not been assigned to anything is \e null, i.e. both - the length and data pointer is 0. A QCString that references the empty - string ("", a single '\0' char) is \e empty. Both null and empty - QCStrings are legal parameters to the methods. Assigning const char - * 0 to QCString gives a null QCString. - - \sa \link shclass.html Shared classes\endlink -*/ - - -/* - Implementation note: The QCString methods for QRegExp searching are - implemented by converting the QCString to a QString and performing - the search on that. This implies a deep copy of the QCString - data. Therefore, if you are giong to perform many QRegExp searches - on one and the same, large QCString, you will get better performance - by converting the QCString to a QString yourself, and do the - searches on that. The results will be of course be identical. -*/ - - - -/*! - \fn QCString::QCString() - Constructs a null string. - \sa isNull() -*/ - -/*! - \fn QCString::QCString( const QCString &s ) - Constructs a shallow copy \e s. - \sa assign() -*/ - -/*! - Constructs a string with room for \e size characters, including the - '\0'-terminator. Makes a null string if \e size == 0. - - If \e size \> 0, then the first and last characters in the string are - initialized to '\0'. All other characters are uninitialized. - - \sa resize(), isNull() -*/ - -QCString::QCString( int size ) - : QByteArray( size ) -{ - if ( size > 0 ) { - *data() = '\0'; // set terminator - *(data()+(size-1)) = '\0'; - } -} - -/*! - Constructs a string that is a deep copy of \e str. - - If \a str is 0 a null string is created. - - \sa isNull() -*/ - -QCString::QCString( const char *str ) -{ - duplicate( str, qstrlen(str) + 1 ); -} - - -/*! - Constructs a string that is a deep copy of \e str, that is no more - than \a maxsize bytes long including the '\0'-terminator. - - Example: - \code - QCString str( "helloworld", 6 ); // Assigns "hello" to str. - \endcode - - If \a str contains a 0 byte within the first \a maxsize bytes, the - resulting QCString will be terminated by the 0. If \a str is 0 a - null string is created. - - \sa isNull() -*/ - -QCString::QCString( const char *str, uint maxsize ) -{ - if ( str == 0 ) - return; - uint len; // index of first '\0' - for ( len = 0; len < maxsize - 1; len++ ) { - if ( str[len] == '\0' ) - break; - } - QByteArray::resize( len + 1 ); - memcpy( data(), str, len ); - data()[len] = 0; -} - -/*! - \fn QCString &QCString::operator=( const QCString &s ) - Assigns a shallow copy of \e s to this string and returns a reference to - this string. -*/ - -/*! - \fn QCString &QCString::operator=( const char *str ) - Assigns a deep copy of \a str to this string and returns a reference to - this string. - - If \a str is 0 a null string is created. - - \sa isNull() -*/ - -/*! - \fn bool QCString::isNull() const - Returns TRUE if the string is null, i.e. if data() == 0. - A null string is also an empty string. - - Example: - \code - QCString a; // a.data() == 0, a.size() == 0, a.length() == 0 - QCString b == ""; // b.data() == "", b.size() == 1, b.length() == 0 - a.isNull(); // TRUE, because a.data() == 0 - a.isEmpty(); // TRUE, because a.length() == 0 - b.isNull(); // FALSE, because b.data() == "" - b.isEmpty(); // TRUE, because b.length() == 0 - \endcode - - \sa isEmpty(), length(), size() -*/ - -/*! - \fn bool QCString::isEmpty() const - - Returns TRUE if the string is empty, i.e. if length() == 0. - An empty string is not always a null string. - - See example in isNull(). - - \sa isNull(), length(), size() -*/ - -/*! - \fn uint QCString::length() const - Returns the length of the string, excluding the '\0'-terminator. - Equivalent to calling \c strlen(data()). - - Null strings and empty strings have zero length. - - \sa size(), isNull(), isEmpty() -*/ - -/*! - \fn bool QCString::truncate( uint pos ) - Truncates the string at position \e pos. - - Equivalent to calling \c resize(pos+1). - - Example: - \code - QCString s = "truncate this string"; - s.truncate( 5 ); // s == "trunc" - \endcode - - \sa resize() -*/ - -/*! - Extends or shrinks the string to \e len bytes, including the - '\0'-terminator. - - A \0-terminator is set at position len - 1 unless - len == 0. - - Example: - \code - QCString s = "resize this string"; - s.resize( 7 ); // s == "resize" - \endcode - - \sa truncate() -*/ - -bool QCString::resize( uint len ) -{ - detach(); - if ( !QByteArray::resize(len) ) - return FALSE; - if ( len ) - *(data()+len-1) = '\0'; - return TRUE; -} - - -/*! - Implemented as a call to the native vsprintf() (see your C-library - manual). - - If your string is shorter than 256 characters, this sprintf() calls - resize(256) to decrease the chance of memory corruption. The string is - resized back to its natural length before sprintf() returns. - - Example: - \code - QCString s; - s.sprintf( "%d - %s", 1, "first" ); // result < 256 chars - - QCString big( 25000 ); // very long string - big.sprintf( "%d - %s", 2, longString ); // result < 25000 chars - \endcode - - \warning All vsprintf() implementations will write past the end of - the target string (*this) if the format specification and arguments - happen to be longer than the target string, and some will also fail - if the target string is longer than some arbitrary implementation - limit. - - Giving user-supplied arguments to sprintf() is begging for trouble. - Sooner or later someone \e will paste a 3000-character line into - your application. -*/ - -QCString &QCString::sprintf( const char *format, ... ) -{ - detach(); - va_list ap; - va_start( ap, format ); - if ( size() < 256 ) - QByteArray::resize( 256 ); // make string big enough - vsprintf( data(), format, ap ); - resize( qstrlen(data()) + 1 ); // truncate - va_end( ap ); - return *this; -} - - -/*! - Fills the string with \e len bytes of value \e c, followed by a - '\0'-terminator. - - If \e len is negative, then the current string length is used. - - Returns FALSE is \e len is nonnegative and there is no memory to - resize the string, otherwise TRUE is returned. -*/ - -bool QCString::fill( char c, int len ) -{ - detach(); - if ( len < 0 ) - len = length(); - if ( !QByteArray::fill(c,len+1) ) - return FALSE; - *(data()+len) = '\0'; - return TRUE; -} - - -/*! - \fn QCString QCString::copy() const - Returns a deep copy of this string. - \sa detach() -*/ - - -/*! - Finds the first occurrence of the character \e c, starting at - position \e index. - - The search is case sensitive if \e cs is TRUE, or case insensitive if \e - cs is FALSE. - - Returns the position of \e c, or -1 if \e c could not be found. -*/ - -int QCString::find( char c, int index, bool cs ) const -{ - if ( (uint)index >= size() ) // index outside string - return -1; - register const char *d; - if ( cs ) { // case sensitive - d = strchr( data()+index, c ); - } else { - d = data()+index; - c = tolower( (uchar) c ); - while ( *d && tolower((uchar) *d) != c ) - d++; - if ( !*d && c ) // not found - d = 0; - } - return d ? (int)(d - data()) : -1; -} - -/*! - Finds the first occurrence of the string \e str, starting at position - \e index. - - The search is case sensitive if \e cs is TRUE, or case insensitive if \e - cs is FALSE. - - Returns the position of \e str, or -1 if \e str could not be found. -*/ - -int QCString::find( const char *str, int index, bool cs ) const -{ - if ( (uint)index >= size() ) // index outside string - return -1; - if ( !str ) // no search string - return -1; - if ( !*str ) // zero-length search string - return index; - register const char *d; - if ( cs ) { // case sensitive - d = strstr( data()+index, str ); - } else { // case insensitive - d = data()+index; - int len = qstrlen( str ); - while ( *d ) { - if ( qstrnicmp(d, str, len) == 0 ) - break; - d++; - } - if ( !*d ) // not found - d = 0; - } - return d ? (int)(d - data()) : -1; -} - -/*! - Finds the first occurrence of the character \e c, starting at - position \e index and searching backwards. - - The search is case sensitive if \e cs is TRUE, or case insensitive if \e - cs is FALSE. - - Returns the position of \e c, or -1 if \e c could not be found. -*/ - -int QCString::findRev( char c, int index, bool cs ) const -{ - const char *b = data(); - const char *d; - if ( index < 0 ) { // neg index ==> start from end - if ( size() == 0 ) - return -1; - if ( cs ) { - d = strrchr( b, c ); - return d ? (int)(d - b) : -1; - } - index = length(); - } else if ( (uint)index >= size() ) { // bad index - return -1; - } - d = b+index; - if ( cs ) { // case sensitive - while ( d >= b && *d != c ) - d--; - } else { // case insensitive - c = tolower( (uchar) c ); - while ( d >= b && tolower((uchar) *d) != c ) - d--; - } - return d >= b ? (int)(d - b) : -1; -} - -/*! - Finds the first occurrence of the string \e str, starting at - position \e index and searching backwards. - - The search is case sensitive if \e cs is TRUE, or case insensitive if \e - cs is FALSE. - - Returns the position of \e str, or -1 if \e str could not be found. -*/ - -int QCString::findRev( const char *str, int index, bool cs ) const -{ - int slen = qstrlen(str); - if ( index < 0 ) // neg index ==> start from end - index = length()-slen; - else if ( (uint)index >= size() ) // bad index - return -1; - else if ( (uint)(index + slen) > length() ) // str would be too long - index = length() - slen; - if ( index < 0 ) - return -1; - - register char *d = data() + index; - if ( cs ) { // case sensitive - for ( int i=index; i>=0; i-- ) - if ( qstrncmp(d--,str,slen)==0 ) - return i; - } else { // case insensitive - for ( int i=index; i>=0; i-- ) - if ( qstrnicmp(d--,str,slen)==0 ) - return i; - } - return -1; -} - - -/*! - Returns the number of times the character \e c occurs in the string. - - The match is case sensitive if \e cs is TRUE, or case insensitive if \e cs - if FALSE. -*/ - -int QCString::contains( char c, bool cs ) const -{ - int count = 0; - char *d = data(); - if ( !d ) - return 0; - if ( cs ) { // case sensitive - while ( *d ) - if ( *d++ == c ) - count++; - } else { // case insensitive - c = tolower( (uchar) c ); - while ( *d ) { - if ( tolower((uchar) *d) == c ) - count++; - d++; - } - } - return count; -} - -/*! - Returns the number of times \e str occurs in the string. - - The match is case sensitive if \e cs is TRUE, or case insensitive if \e - cs if FALSE. - - This function counts overlapping substrings, for example, "banana" - contains two occurrences of "ana". - - \sa findRev() -*/ - -int QCString::contains( const char *str, bool cs ) const -{ - int count = 0; - char *d = data(); - if ( !d ) - return 0; - int len = qstrlen( str ); - while ( *d ) { // counts overlapping strings - if ( cs ) { - if ( qstrncmp( d, str, len ) == 0 ) - count++; - } else { - if ( qstrnicmp(d, str, len) == 0 ) - count++; - } - d++; - } - return count; -} - -/*! - Returns a substring that contains the \e len leftmost characters - of the string. - - The whole string is returned if \e len exceeds the length of the string. - - Example: - \code - QCString s = "Pineapple"; - QCString t = s.left( 4 ); // t == "Pine" - \endcode - - \sa right(), mid() -*/ - -QCString QCString::left( uint len ) const -{ - if ( isEmpty() ) { - QCString empty; - return empty; - } else if ( len >= size() ) { - QCString same( data() ); - return same; - } else { - QCString s( len+1 ); - strncpy( s.data(), data(), len ); - *(s.data()+len) = '\0'; - return s; - } -} - -/*! - Returns a substring that contains the \e len rightmost characters - of the string. - - The whole string is returned if \e len exceeds the length of the string. - - Example: - \code - QCString s = "Pineapple"; - QCString t = s.right( 5 ); // t == "apple" - \endcode - - \sa left(), mid() -*/ - -QCString QCString::right( uint len ) const -{ - if ( isEmpty() ) { - QCString empty; - return empty; - } else { - uint l = length(); - if ( len > l ) - len = l; - char *p = data() + (l - len); - return QCString( p ); - } -} - -/*! - Returns a substring that contains the \e len characters of this - string, starting at position \e index. - - Returns a null string if the string is empty or \e index is out - of range. Returns the whole string from \e index if \e index+len exceeds - the length of the string. - - Example: - \code - QCString s = "Two pineapples"; - QCString t = s.mid( 4, 4 ); // t == "pine" - \endcode - - \sa left(), right() -*/ - -QCString QCString::mid( uint index, uint len ) const -{ - if ( len == 0xffffffff ) len = length()-index; - uint slen = qstrlen( data() ); - if ( isEmpty() || index >= slen ) { - QCString empty; - return empty; - } else { - register char *p = data()+index; - QCString s( len+1 ); - strncpy( s.data(), p, len ); - *(s.data()+len) = '\0'; - return s; - } -} - -/*! - Returns a string of length \e width (plus '\0') that contains this - string and padded by the \e fill character. - - If the length of the string exceeds \e width and \e truncate is FALSE, - then the returned string is a copy of the string. - If the length of the string exceeds \e width and \e truncate is TRUE, - then the returned string is a left(\e width). - - Example: - \code - QCString s("apple"); - QCString t = s.leftJustify(8, '.'); // t == "apple..." - \endcode - - \sa rightJustify() -*/ - -QCString QCString::leftJustify( uint width, char fill, bool truncate ) const -{ - QCString result; - int len = qstrlen(data()); - int padlen = width - len; - if ( padlen > 0 ) { - result.QByteArray::resize( len+padlen+1 ); - memcpy( result.data(), data(), len ); - memset( result.data()+len, fill, padlen ); - result[len+padlen] = '\0'; - } else { - if ( truncate ) - result = left( width ); - else - result = copy(); - } - return result; -} - -/*! - Returns a string of length \e width (plus '\0') that contains pad - characters followed by the string. - - If the length of the string exceeds \e width and \e truncate is FALSE, - then the returned string is a copy of the string. - If the length of the string exceeds \e width and \e truncate is TRUE, - then the returned string is a left(\e width). - - Example: - \code - QCString s("pie"); - QCString t = s.rightJustify(8, '.'); // t == ".....pie" - \endcode - - \sa leftJustify() -*/ - -QCString QCString::rightJustify( uint width, char fill, bool truncate ) const -{ - QCString result; - int len = qstrlen(data()); - int padlen = width - len; - if ( padlen > 0 ) { - result.QByteArray::resize( len+padlen+1 ); - memset( result.data(), fill, padlen ); - memcpy( result.data()+padlen, data(), len ); - result[len+padlen] = '\0'; - } else { - if ( truncate ) - result = left( width ); - else - result = copy(); - } - return result; -} - -/*! - Returns a new string that is the string converted to lower case. +/****************************************************************************** + * + * Copyright (C) 1997-2004 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. + * + */ - Presently it only handles 7-bit ASCII, or whatever tolower() - handles (if $LC_CTYPE is set, most UNIX systems do the Right Thing). +#include "qcstring.h" +#include "qgstring.h" - Example: - \code - QCString s("TeX"); - QCString t = s.lower(); // t == "tex" - \endcode +#include +#include +#include +#include +#include +#include +#include - \sa upper() -*/ -QCString QCString::lower() const +QCString::QCString(int size) { - QCString s( data() ); - register char *p = s.data(); - if ( p ) { - while ( *p ) { - *p = tolower((uchar) *p); - p++; - } + if (size>0) + { + m_data = (char *)malloc(size); + if (m_data) + { + if (size>1) memset(m_data,' ',size-1); + m_data[size-1]='\0'; } - return s; + } + else + { + m_data=0; + } } -/*! - Returns a new string that is the string converted to upper case. +QCString::QCString( const QCString &s ) +{ + duplicate(s); +} - Presently it only handles 7-bit ASCII, or whatever toupper() - handles (if $LC_CTYPE is set, most UNIX systems do the Right Thing). +QCString::QCString( const char *str ) +{ + duplicate(str); +} - Example: - \code - QCString s("TeX"); - QCString t = s.upper(); // t == "TEX" - \endcode +QCString::QCString( const char *str, uint maxlen ) +{ + uint l; + if (str && ( l = QMIN(qstrlen(str),maxlen) )) + { + m_data=(char *)malloc(l+1); + strncpy(m_data,str,maxlen); + m_data[l]='\0'; + } + else + { + m_data=0; + } +} - \sa lower() -*/ +QCString::~QCString() +{ + if (m_data) free(m_data); + m_data=0; +} -QCString QCString::upper() const +QCString &QCString::assign( const char *str ) { - QCString s( data() ); - register char *p = s.data(); - if ( p ) { - while ( *p ) { - *p = toupper((uchar)*p); - p++; - } - } - return s; + if (m_data) free(m_data); + duplicate(str); + return *this; } +bool QCString::resize( uint newlen ) +{ + if (newlen==0) + { + if (m_data) { free(m_data); m_data=0; } + return TRUE; + } + if (m_data==0) // newlen>0 + { + m_data = (char *)malloc(newlen); + } + else + { + m_data = (char *)realloc(m_data,newlen); + } + if (m_data==0) return FALSE; + m_data[newlen-1]='\0'; + return TRUE; +} -/*! - Returns a new string that has white space removed from the start and the end. +bool QCString::fill( char c, int len ) +{ + uint l=length(); + if (len<0) len=l; + if ((uint)len!=l) + { + if (m_data) free(m_data); + if (len>0) + { + m_data=(char *)malloc(len+1); + if (m_data==0) return FALSE; + m_data[len]='\0'; + } + else + { + m_data=0; + } + } + if (len>0) + { + uint i; + for (i=0;i<(uint)len;i++) m_data[i]=c; + } + return TRUE; +} - White space means any ASCII code 9, 10, 11, 12, 13 or 32. +QCString &QCString::sprintf( const char *format, ... ) +{ + va_list ap; + va_start( ap, format ); + uint l = length(); + const uint minlen=256; + if (llen ) // index outside string + return -1; + register const char *d; + if ( cs ) // case sensitive + { + d = strchr( m_data+index, c ); + } + else + { + d = m_data+index; + c = tolower( (uchar) c ); + while ( *d && tolower((uchar) *d) != c ) + d++; + if ( !*d && c ) // not found + d = 0; + } + return d ? (int)(d - m_data) : -1; +} -QCString QCString::stripWhiteSpace() const +int QCString::find( const char *str, int index, bool cs ) const { - if ( isEmpty() ) // nothing to do - return copy(); - - register char *s = data(); - QCString result = s; - int reslen = result.length(); - if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) ) - return result; // returns a copy - - s = result.data(); - int start = 0; - int end = reslen - 1; - while ( isspace((uchar) s[start]) ) // skip white space from start - start++; - if ( s[start] == '\0' ) { // only white space - result.resize( 1 ); - return result; + uint l = length(); + if ( m_data==0 || (uint)index > l ) // index outside string + return -1; + if ( !str ) // no search string + return -1; + if ( !*str ) // zero-length search string + return index; + register const char *d; + if ( cs ) // case sensitive + { + d = strstr( m_data+index, str ); + } + else // case insensitive + { + d = m_data+index; + int len = qstrlen( str ); + while ( *d ) + { + if ( qstrnicmp(d, str, len) == 0 ) + break; + d++; } - while ( end && isspace((uchar) s[end]) ) // skip white space from end - end--; - end -= start - 1; - memmove( result.data(), &s[start], end ); - result.resize( end + 1 ); - return result; + if ( !*d ) // not found + d = 0; + } + return d ? (int)(d - m_data) : -1; } +int QCString::find( const QRegExp &rx, int index ) const +{ + QString d = QString::fromLatin1( m_data ); + return d.find( rx, index ); +} -/*! - Returns a new string that has white space removed from the start and the end, - plus any sequence of internal white space replaced with a single space - (ASCII 32). - - White space means any ASCII code 9, 10, 11, 12, 13 or 32. +int QCString::findRev( char c, int index, bool cs) const +{ + const char *b = m_data; + const char *d; + uint len = length(); + if ( b == 0 ) return -1; // empty string + if ( index < 0 ) // neg index ==> start from end + { + if ( len == 0 ) return -1; + if ( cs ) + { + d = strrchr( b, c ); + return d ? (int)(d - b) : -1; + } + index = len; + } + else if ( (uint)index > len ) // bad index + { + return -1; + } + d = b+index; + if ( cs ) // case sensitive + { + while ( d >= b && *d != c ) + d--; + } + else // case insensitive + { + c = tolower( (uchar) c ); + while ( d >= b && tolower((uchar) *d) != c ) + d--; + } + return d >= b ? (int)(d - b) : -1; +} + +int QCString::findRev( const char *str, int index, bool cs) const +{ + int slen = qstrlen(str); + uint len = length(); + if ( index < 0 ) // neg index ==> start from end + index = len-slen; + else if ( (uint)index > len ) // bad index + return -1; + else if ( (uint)(index + slen) > len ) // str would be too long + index = len - slen; + if ( index < 0 ) + return -1; - \code - QCString s = " lots\t of\nwhite space "; - QCString t = s.simplifyWhiteSpace(); // t == "lots of white space" - \endcode + register char *d = m_data + index; + if ( cs ) // case sensitive + { + for ( int i=index; i>=0; i-- ) + if ( qstrncmp(d--,str,slen)==0 ) + return i; + } + else // case insensitive + { + for ( int i=index; i>=0; i-- ) + if ( qstrnicmp(d--,str,slen)==0 ) + return i; + } + return -1; - \sa stripWhiteSpace() -*/ +} -QCString QCString::simplifyWhiteSpace() const +int QCString::findRev( const QRegExp &rx, int index ) const { - if ( isEmpty() ) // nothing to do - return copy(); - QCString result( size() ); - char *from = data(); - char *to = result.data(); - char *first = to; - while ( TRUE ) { - while ( *from && isspace((uchar) *from) ) - from++; - while ( *from && !isspace((uchar)*from) ) - *to++ = *from++; - if ( *from ) - *to++ = 0x20; // ' ' - else - break; - } - if ( to > first && *(to-1) == 0x20 ) - to--; - *to = '\0'; - result.resize( (int)((long)to - (long)result.data()) + 1 ); - return result; + QString d = QString::fromLatin1( m_data ); + return d.findRev( rx, index ); } +int QCString::contains( char c, bool cs ) const +{ + int count = 0; + char *d = m_data; + if ( !d ) + return 0; + if ( cs ) // case sensitive + { + while ( *d ) + if ( *d++ == c ) + count++; + } + else // case insensitive + { + c = tolower( (uchar) c ); + while ( *d ) { + if ( tolower((uchar) *d) == c ) + count++; + d++; + } + } + return count; +} -/*! - Insert \e s into the string before position \e index. - - If \e index is beyond the end of the string, the string is extended with - spaces (ASCII 32) to length \e index and \e s is then appended. +int QCString::contains( const char *str, bool cs ) const +{ + int count = 0; + char *d = data(); + if ( !d ) + return 0; + int len = qstrlen( str ); + while ( *d ) // counts overlapping strings + { + if ( cs ) + { + if ( qstrncmp( d, str, len ) == 0 ) + count++; + } + else + { + if ( qstrnicmp(d, str, len) == 0 ) + count++; + } + d++; + } + return count; +} - \code - QCString s = "I like fish"; - s.insert( 2, "don't "); // s == "I don't like fish" - s = "x"; - s.insert( 3, "yz" ); // s == "x yz" - \endcode -*/ +int QCString::contains( const QRegExp &rx ) const +{ + QString d = QString::fromLatin1( m_data ); + return d.contains( rx ); +} -QCString &QCString::insert( uint index, const char *s ) +QCString QCString::left( uint len ) const { - int len = qstrlen(s); - if ( len == 0 ) - return *this; - uint olen = length(); - int nlen = olen + len; - if ( index >= olen ) { // insert after end of string - detach(); - if ( QByteArray::resize(nlen+index-olen+1) ) { - memset( data()+olen, ' ', index-olen ); - memcpy( data()+index, s, len+1 ); - } - } else if ( QByteArray::resize(nlen+1) ) { // normal insert - detach(); - memmove( data()+index+len, data()+index, olen-index+1 ); - memcpy( data()+index, s, len ); - } + if ( isEmpty() ) + { + return QCString(); + } + else if ( len >= length() ) + { return *this; + } + else + { + QCString s( len+1 ); + strncpy( s.data(), m_data, len ); + *(s.data()+len) = '\0'; + return s; + } } -/*! - Insert \e c into the string at (before) position \e index and returns - a reference to the string. - - If \e index is beyond the end of the string, the string is extended with - spaces (ASCII 32) to length \e index and \e c is then appended. - - Example: - \code - QCString s = "Yes"; - s.insert( 3, '!'); // s == "Yes!" - \endcode - - \sa remove(), replace() -*/ - -QCString &QCString::insert( uint index, char c ) // insert char +QCString QCString::right( uint len ) const { - char buf[2]; - buf[0] = c; - buf[1] = '\0'; - return insert( index, buf ); + if ( isEmpty() ) + { + return QCString(); + } + else + { + uint l = length(); + if ( len > l ) len = l; + char *p = m_data + (l - len); + return QCString( p ); + } +} + +QCString QCString::mid( uint index, uint len) const +{ + uint slen = length(); + if ( len == 0xffffffff ) len = slen-index; + if ( isEmpty() || index >= slen ) + { + return QCString(); + } + else + { + register char *p = data()+index; + QCString s( len+1 ); + strncpy( s.data(), p, len ); + *(s.data()+len) = '\0'; + return s; + } } -/*! - \fn QCString &QCString::prepend( const char *s ) - - Prepend \a s to the string. Equivalent to insert(0,s). - - \sa insert() -*/ - -/*! - Removes \e len characters starting at position \e index from the - string and returns a reference to the string. - - If \e index is too big, nothing happens. If \e index is valid, but - \e len is too large, the rest of the string is removed. - - \code - QCString s = "Montreal"; - s.remove( 1, 4 ); - // s == "Meal" - \endcode - - \sa insert(), replace() -*/ - -QCString &QCString::remove( uint index, uint len ) +QCString QCString::lower() const { - uint olen = length(); - if ( index + len >= olen ) { // range problems - if ( index < olen ) { // index ok - detach(); - resize( index+1 ); - } - } else if ( len != 0 ) { - detach(); - memmove( data()+index, data()+index+len, olen-index-len+1 ); - QByteArray::resize(olen-len+1); + QCString s( m_data ); + register char *p = s.data(); + if ( p ) + { + while ( *p ) + { + *p = tolower((uchar) *p); + p++; } - return *this; + } + return s; } -/*! - Replaces \e len characters starting at position \e index from the - string with \e s, and returns a reference to the string. - - If \e index is too big, nothing is deleted and \e s is inserted at the - end of the string. If \e index is valid, but \e len is too large, \e - str replaces the rest of the string. - - \code - QCString s = "Say yes!"; - s.replace( 4, 3, "NO" ); // s == "Say NO!" - \endcode - - \sa insert(), remove() -*/ +QCString QCString::upper() const +{ + QCString s( m_data ); + register char *p = s.data(); + if ( p ) { + while ( *p ) { + *p = toupper((uchar)*p); + p++; + } + } + return s; +} -QCString &QCString::replace( uint index, uint len, const char *s ) +QCString QCString::stripWhiteSpace() const { - remove( index, len ); - insert( index, s ); + if ( isEmpty() ) // nothing to do return *this; + + register char *s = m_data; + int reslen = length(); + if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) ) + return *this; // returns a copy + + QCString result(s); + s = result.data(); + int start = 0; + int end = reslen - 1; + while ( isspace((uchar) s[start]) ) // skip white space from start + start++; + if ( s[start] == '\0' ) + { // only white space + return QCString(); + } + while ( end && isspace((uchar) s[end]) ) // skip white space from end + end--; + end -= start - 1; + memmove( result.data(), &s[start], end ); + result.resize( end + 1 ); + return result; } +QCString QCString::simplifyWhiteSpace() const +{ + if ( isEmpty() ) // nothing to do + return *this; -/*! - Finds the first occurrence of the regular expression \e rx, starting at - position \e index. + QCString result( length()+1 ); + char *from = data(); + char *to = result.data(); + char *first = to; + while ( TRUE ) + { + while ( *from && isspace((uchar) *from) ) + from++; + while ( *from && !isspace((uchar)*from) ) + *to++ = *from++; + if ( *from ) + *to++ = 0x20; // ' ' + else + break; + } + if ( to > first && *(to-1) == 0x20 ) + to--; + *to = '\0'; + result.resize( (int)((long)to - (long)result.data()) + 1 ); + return result; +} - Returns the position of the next match, or -1 if \e rx was not found. -*/ +QCString &QCString::insert( uint index, const char *s ) +{ + int len = qstrlen(s); + if ( len == 0 ) + return *this; + uint olen = length(); + int nlen = olen + len; + if ( index >= olen ) // insert after end of string + { + m_data = (char *)realloc(m_data,nlen+index-olen+1); + if ( m_data ) + { + memset( m_data+olen, ' ', index-olen ); + memcpy( m_data+index, s, len+1 ); + } + } + else if ( (m_data = (char *)realloc(m_data,nlen+1)) ) // normal insert + { + memmove( m_data+index+len, m_data+index, olen-index+1 ); + memcpy( m_data+index, s, len ); + } + return *this; +} -int QCString::find( const QRegExp &rx, int index ) const +QCString &QCString::insert( uint index, char c ) // insert char { - QString d = QString::fromLatin1( data() ); - return d.find( rx, index ); + char buf[2]; + buf[0] = c; + buf[1] = '\0'; + return insert( index, buf ); } -/*! - Finds the first occurrence of the regular expression \e rx, starting at - position \e index and searching backwards. - - The search will start from the end of the string if \e index is negative. - - Returns the position of the next match (backwards), or -1 if \e rx was not - found. -*/ - -int QCString::findRev( const QRegExp &rx, int index ) const +QCString& QCString::operator+=( const char *str ) { - QString d = QString::fromLatin1( data() ); - return d.findRev( rx, index ); + if ( !str ) return *this; // nothing to append + uint len1 = length(); + uint len2 = qstrlen(str); + char *newData = (char *)realloc( m_data, len1 + len2 + 1 ); + if (newData) + { + m_data = newData; + memcpy( m_data + len1, str, len2 + 1 ); + } + return *this; } -/*! - Counts the number of overlapping occurrences of \e rx in the string. - - Example: - \code - QString s = "banana and panama"; - QRegExp r = QRegExp("a[nm]a", TRUE, FALSE); - s.contains( r ); // 4 matches - \endcode - - \sa find(), findRev() -*/ - -int QCString::contains( const QRegExp &rx ) const +QCString &QCString::operator+=( char c ) { - QString d = QString::fromLatin1( data() ); - return d.contains( rx ); + uint len = length(); + char *newData = (char *)realloc( m_data, length()+2 ); + if (newData) + { + m_data = newData; + m_data[len] = c; + m_data[len+1] = '\0'; + } + return *this; } +QCString &QCString::remove( uint index, uint len ) +{ + uint olen = length(); + if ( index + len >= olen ) // range problems + { + if ( index < olen ) // index ok + { + resize( index+1 ); + } + } + else if ( len != 0 ) + { + memmove( m_data+index, m_data+index+len, olen-index-len+1 ); + resize( olen-len+1 ); + } + return *this; +} -/*! - Replaces every occurrence of \e rx in the string with \e str. - Returns a reference to the string. - - Example: - \code - QString s = "banana"; - s.replace( QRegExp("a.*a"), "" ); // becomes "b" - - QString s = "banana"; - s.replace( QRegExp("^[bn]a"), " " ); // becomes " nana" - - QString s = "banana"; - s.replace( QRegExp("^[bn]a"), "" ); // NOTE! becomes "" - \endcode - -*/ +QCString &QCString::replace( uint index, uint len, const char *s ) +{ + remove( index, len ); + insert( index, s ); + return *this; +} QCString &QCString::replace( const QRegExp &rx, const char *str ) { - QString d = QString::fromLatin1( data() ); - QString r = QString::fromLatin1( str ); - d.replace( rx, r ); - setStr( d.ascii() ); - return *this; + QString d = QString::fromLatin1( m_data ); + QString r = QString::fromLatin1( str ); + d.replace( rx, r ); + operator=( d.ascii() ); + return *this; } -/*! - Returns the string converted to a long value. - - If \e ok is non-null, \e *ok is set to TRUE if there are no - conceivable errors, and FALSE if the string is not a number at all, or if - it has trailing garbage. -*/ - -long QCString::toLong( bool *ok ) const +long QCString::toLong( bool *ok ) const { - char *p = data(); - long val=0; - const long max_mult = 214748364; - bool is_ok = FALSE; - int neg = 0; - if ( !p ) - goto bye; - while ( isspace((uchar)*p) ) // skip leading space - p++; - if ( *p == '-' ) { - p++; - neg = 1; - } else if ( *p == '+' ) { - p++; - } - if ( !isdigit((uchar)*p) ) - goto bye; - while ( isdigit((uchar)*p) ) { - if ( val > max_mult || (val == max_mult && (*p-'0') > 7+neg) ) - goto bye; - val = 10*val + (*p++ - '0'); - } - if ( neg ) - val = -val; - while ( isspace((uchar)*p) ) // skip trailing space - p++; - if ( *p == '\0' ) - is_ok = TRUE; -bye: - if ( ok ) - *ok = is_ok; - return is_ok ? val : 0; + QString s(m_data); + return s.toLong(ok); } -/*! - Returns the string converted to an unsigned long - value. - - If \e ok is non-null, \e *ok is set to TRUE if there are no - conceivable errors, and FALSE if the string is not a number at all, - or if it has trailing garbage. -*/ - ulong QCString::toULong( bool *ok ) const { - char *p = data(); - ulong val=0; - const ulong max_mult = 429496729; - bool is_ok = FALSE; - if ( !p ) - goto bye; - while ( isspace((uchar)*p) ) // skip leading space - p++; - if ( *p == '+' ) - p++; - if ( !isdigit((uchar)*p) ) - goto bye; - while ( isdigit((uchar)*p) ) { - if ( val > max_mult || (val == max_mult && (*p-'0') > 5) ) - goto bye; - val = 10*val + (*p++ - '0'); - } - while ( isspace((uchar)*p) ) // skip trailing space - p++; - if ( *p == '\0' ) - is_ok = TRUE; -bye: - if ( ok ) - *ok = is_ok; - return is_ok ? val : 0; + QString s(m_data); + return s.toULong(ok); } -/*! - Returns the string converted to a short value. - - If \e ok is non-null, \e *ok is set to TRUE if there are no - conceivable errors, and FALSE if the string is not a number at all, or if - it has trailing garbage. -*/ - -short QCString::toShort( bool *ok ) const +short QCString::toShort( bool *ok ) const { - long v = toLong( ok ); - if ( ok && *ok && (v < -32768 || v > 32767) ) - *ok = FALSE; - return (short)v; + QString s(m_data); + return s.toShort(ok); } -/*! - Returns the string converted to an unsigned short value. - - If \e ok is non-null, \e *ok is set to TRUE if there are no - conceivable errors, and FALSE if the string is not a number at all, or if - it has trailing garbage. -*/ - ushort QCString::toUShort( bool *ok ) const { - ulong v = toULong( ok ); - if ( ok && *ok && (v > 65535) ) - *ok = FALSE; - return (ushort)v; + QString s(m_data); + return s.toUShort(ok); } - -/*! - Returns the string converted to a int value. - - If \e ok is non-null, \e *ok is set to TRUE if there are no - conceivable errors, and FALSE if the string is not a number at all, - or if it has trailing garbage. -*/ - int QCString::toInt( bool *ok ) const { - return (int)toLong( ok ); + QString s(m_data); + return s.toInt(ok); } -/*! - Returns the string converted to an unsigned int value. - - If \e ok is non-null, \e *ok is set to TRUE if there are no - conceivable errors, and FALSE if the string is not a number at all, - or if it has trailing garbage. -*/ - uint QCString::toUInt( bool *ok ) const { - return (uint)toULong( ok ); + QString s(m_data); + return s.toUInt(ok); } -/*! - Returns the string converted to a double value. - - If \e ok is non-null, \e *ok is set to TRUE if there are no conceivable - errors, and FALSE if the string is not a number at all, or if it has - trailing garbage. -*/ - -double QCString::toDouble( bool *ok ) const +QCString &QCString::setNum( long n ) { - char *end; - double val = strtod( data() ? data() : "", &end ); - if ( ok ) - *ok = ( data() && *data() && ( end == 0 || *end == '\0' ) ); - return val; + char buf[20]; + register char *p = &buf[19]; + bool neg; + if ( n < 0 ) + { + neg = TRUE; + n = -n; + } + else + { + neg = FALSE; + } + *p = '\0'; + do + { + *--p = ((int)(n%10)) + '0'; + n /= 10; + } while ( n ); + if ( neg ) *--p = '-'; + operator=( p ); + return *this; } -/*! - Returns the string converted to a float value. - - If \e ok is non-null, \e *ok is set to TRUE if there are no - conceivable errors, and FALSE if the string is not a number at all, - or if it has trailing garbage. -*/ - -float QCString::toFloat( bool *ok ) const +QCString &QCString::setNum( ulong n ) { - return (float)toDouble( ok ); + char buf[20]; + register char *p = &buf[19]; + *p = '\0'; + do + { + *--p = ((int)(n%10)) + '0'; + n /= 10; + } while ( n ); + operator=( p ); + return *this; } +void QCString::msg_index( uint index ) +{ +#if defined(CHECK_RANGE) + qWarning( "QCString::at: Absolute index %d out of range", index ); +#else + Q_UNUSED( index ) +#endif +} -/*! - Makes a deep copy of \e str. - Returns a reference to the string. -*/ - -QCString &QCString::setStr( const char *str ) +bool QCString::stripPrefix(const char *prefix) { - detach(); - if ( str ) // valid string - store( str, qstrlen(str)+1 ); - else // empty - resize( 0 ); - return *this; + if (prefix==0) return FALSE; + uint plen = qstrlen(prefix); + if (m_data && qstrncmp(prefix,m_data,plen)==0) // prefix matches + { + uint len = qstrlen(m_data); + uint newlen = len-plen+1; + qmemmove(m_data,m_data+plen,newlen); + resize(newlen); + return TRUE; + } + return FALSE; } -/*! - Sets the string to the printed value of \e n and returns a - reference to the string. -*/ +//--------------------------------------------------------------------------- -QCString &QCString::setNum( long n ) +void *qmemmove( void *dst, const void *src, uint len ) { - detach(); - char buf[20]; - register char *p = &buf[19]; - bool neg; - if ( n < 0 ) { - neg = TRUE; - n = -n; - } else { - neg = FALSE; + register char *d; + register char *s; + if ( dst > src ) { + d = (char *)dst + len - 1; + s = (char *)src + len - 1; + while ( len-- ) + *d-- = *s--; + } else if ( dst < src ) { + d = (char *)dst; + s = (char *)src; + while ( len-- ) + *d++ = *s++; } - *p = '\0'; - do { - *--p = ((int)(n%10)) + '0'; - n /= 10; - } while ( n ); - if ( neg ) - *--p = '-'; - store( p, qstrlen(p)+1 ); - return *this; + return dst; } -/*! - Sets the string to the printed unsigned value of \e n and - returns a reference to the string. -*/ - -QCString &QCString::setNum( ulong n ) +char *qstrdup( const char *str ) { - detach(); - char buf[20]; - register char *p = &buf[19]; - *p = '\0'; - do { - *--p = ((int)(n%10)) + '0'; - n /= 10; - } while ( n ); - store( p, qstrlen(p)+1 ); - return *this; + if ( !str ) + return 0; + char *dst = new char[strlen(str)+1]; + CHECK_PTR( dst ); + return strcpy( dst, str ); } -/*! - \fn QCString &QCString::setNum( int n ) - Sets the string to the printed value of \e n and returns a reference - to the string. -*/ - -/*! - \fn QCString &QCString::setNum( uint n ) - Sets the string to the printed unsigned value of \e n and returns a - reference to the string. -*/ - -/*! - \fn QCString &QCString::setNum( short n ) - Sets the string to the printed value of \e n and returns a reference - to the string. -*/ - -/*! - \fn QCString &QCString::setNum( ushort n ) - Sets the string to the printed unsigned value of \e n and returns a - reference to the string. -*/ - -/*! - Sets the string to the printed value of \e n. - - \arg \e f is the format specifier: 'f', 'F', 'e', 'E', 'g', 'G' (same - as sprintf()). - \arg \e prec is the precision. - - Returns a reference to the string. -*/ - -QCString &QCString::setNum( double n, char f, int prec ) +char *qstrncpy( char *dst, const char *src, uint len ) { -#if defined(CHECK_RANGE) - if ( !(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G') ) - qWarning( "QCString::setNum: Invalid format char '%c'", f ); -#endif - char format[20]; - register char *fs = format; // generate format string - *fs++ = '%'; // "%.l" - if ( prec > 99 ) - prec = 99; - *fs++ = '.'; - if ( prec >= 10 ) { - *fs++ = prec / 10 + '0'; - *fs++ = prec % 10 + '0'; - } else { - *fs++ = prec + '0'; - } - *fs++ = 'l'; - *fs++ = f; - *fs = '\0'; - return sprintf( format, n ); + if ( !src ) + return 0; + strncpy( dst, src, len ); + if ( len > 0 ) + dst[len-1] = '\0'; + return dst; } -/*! - \fn QCString &QCString::setNum( float n, char f, int prec ) - Sets the string to the printed value of \e n. - - \arg \e f is the format specifier: 'f', 'F', 'e', 'E', 'g', 'G' (same - as sprintf()). - \arg \e prec is the precision. - - Returns a reference to the string. -*/ - - -/*! - Sets the character at position \e index to \e c and expands the - string if necessary, filling with spaces. - - Returns FALSE if this \e index was out of range and the string could - not be expanded, otherwise TRUE. -*/ +int qstricmp( const char *str1, const char *str2 ) +{ + register const uchar *s1 = (const uchar *)str1; + register const uchar *s2 = (const uchar *)str2; + int res; + uchar c; + if ( !s1 || !s2 ) + return s1 == s2 ? 0 : (int)((long)s2 - (long)s1); + for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ ) + if ( !c ) // strings are equal + break; + return res; +} -bool QCString::setExpand( uint index, char c ) +int qstrnicmp( const char *str1, const char *str2, uint len ) { - detach(); - uint oldlen = length(); - if ( index >= oldlen ) { - if ( !QByteArray::resize( index+2 ) ) // no memory - return FALSE; - if ( index > oldlen ) - memset( data() + oldlen, ' ', index - oldlen ); - *(data() + index+1) = '\0'; // terminate padded string + register const uchar *s1 = (const uchar *)str1; + register const uchar *s2 = (const uchar *)str2; + int res; + uchar c; + if ( !s1 || !s2 ) + return (int)((long)s2 - (long)s1); + for ( ; len--; s1++, s2++ ) { + if ( (res = (c=tolower(*s1)) - tolower(*s2)) ) + return res; + if ( !c ) // strings are equal + break; } - *(data() + index) = c; - return TRUE; + return 0; } +#ifndef QT_NO_DATASTREAM -/*! - \fn QCString::operator const char *() const - Returns the string data. -*/ - - -/*! - \fn QCString& QCString::append( const char *str ) - Appends \e str to the string and returns a reference to the string. - Equivalent to operator+=(). - */ - -/*! - Appends \e str to the string and returns a reference to the string. -*/ - -QCString& QCString::operator+=( const char *str ) +QDataStream &operator<<( QDataStream &s, const QByteArray &a ) { - if ( !str ) - return *this; // nothing to append - detach(); - uint len1 = length(); - uint len2 = qstrlen(str); - if ( !QByteArray::resize( len1 + len2 + 1 ) ) - return *this; // no memory - memcpy( data() + len1, str, len2 + 1 ); - return *this; + return s.writeBytes( a.data(), a.size() ); } -/*! - Appends \e c to the string and returns a reference to the string. -*/ - -QCString &QCString::operator+=( char c ) +QDataStream &operator>>( QDataStream &s, QByteArray &a ) { - detach(); - uint len = length(); - if ( !QByteArray::resize( len + 2 ) ) - return *this; // no memory - *(data() + len) = c; - *(data() + len+1) = '\0'; - return *this; + Q_UINT32 len; + s >> len; // read size of array + if ( len == 0 || s.eof() ) { // end of file reached + a.resize( 0 ); + return s; + } + if ( !a.resize( (uint)len ) ) { // resize array +#if defined(CHECK_NULL) + qWarning( "QDataStream: Not enough memory to read QByteArray" ); +#endif + len = 0; + } + if ( len > 0 ) // not null array + s.readRawBytes( a.data(), (uint)len ); + return s; } - -/***************************************************************************** - QCString stream functions - *****************************************************************************/ -#ifndef QT_NO_DATASTREAM -/*! - \relates QCString - Writes a string to the stream. - - \sa \link datastreamformat.html Format of the QDataStream operators \endlink -*/ QDataStream &operator<<( QDataStream &s, const QCString &str ) { return s.writeBytes( str.data(), str.size() ); } -/*! - \relates QCString - Reads a string from the stream. - - \sa \link datastreamformat.html Format of the QDataStream operators \endlink -*/ - QDataStream &operator>>( QDataStream &s, QCString &str ) { - str.detach(); Q_UINT32 len; s >> len; // read size of string if ( len == 0 || s.eof() ) { // end of file reached str.resize( 0 ); return s; } - if ( !str.QByteArray::resize( (uint)len )) {// resize string + if ( !str.resize( (uint)len )) {// resize string #if defined(CHECK_NULL) qWarning( "QDataStream: Not enough memory to read QCString" ); #endif @@ -1764,154 +775,20 @@ QDataStream &operator>>( QDataStream &s, QCString &str ) s.readRawBytes( str.data(), (uint)len ); return s; } -#endif //QT_NO_DATASTREAM - -/***************************************************************************** - Documentation for related functions - *****************************************************************************/ -/*! - \fn bool operator==( const QCString &s1, const QCString &s2 ) - \relates QCString - Returns TRUE if the two strings are equal, or FALSE if they are different. - - Equivalent to qstrcmp(s1,s2) == 0. -*/ +#endif //QT_NO_DATASTREAM -/*! - \fn bool operator==( const QCString &s1, const char *s2 ) - \relates QCString - Returns TRUE if the two strings are equal, or FALSE if they are different. +inline QCString operator+( const QCString &s1, const QGString &s2 ) +{ + QCString tmp(s1); + tmp += s2.data(); + return tmp; +} - Equivalent to qstrcmp(s1,s2) == 0. -*/ +inline QCString operator+( const QGString &s1, const QCString &s2 ) +{ + QCString tmp(s1.data()); + tmp += s2; + return tmp; +} -/*! - \fn bool operator==( const char *s1, const QCString &s2 ) - \relates QCString - Returns TRUE if the two strings are equal, or FALSE if they are different. - - Equivalent to qstrcmp(s1,s2) == 0. -*/ - -/*! - \fn bool operator!=( const QCString &s1, const QCString &s2 ) - \relates QCString - Returns TRUE if the two strings are different, or FALSE if they are equal. - - Equivalent to qstrcmp(s1,s2) != 0. -*/ - -/*! - \fn bool operator!=( const QCString &s1, const char *s2 ) - \relates QCString - Returns TRUE if the two strings are different, or FALSE if they are equal. - - Equivalent to qstrcmp(s1,s2) != 0. -*/ - -/*! - \fn bool operator!=( const char *s1, const QCString &s2 ) - \relates QCString - Returns TRUE if the two strings are different, or FALSE if they are equal. - - Equivalent to qstrcmp(s1,s2) != 0. -*/ - -/*! - \fn bool operator<( const QCString &s1, const char *s2 ) - \relates QCString - Returns TRUE if \e s1 is alphabetically less than \e s2, otherwise FALSE. - - Equivalent to qstrcmp(s1,s2) \< 0. -*/ - -/*! - \fn bool operator<( const char *s1, const QCString &s2 ) - \relates QCString - Returns TRUE if \e s1 is alphabetically less than \e s2, otherwise FALSE. - - Equivalent to qstrcmp(s1,s2) \< 0. -*/ - -/*! - \fn bool operator<=( const QCString &s1, const char *s2 ) - \relates QCString - Returns TRUE if \e s1 is alphabetically less than or equal to \e s2, - otherwise FALSE. - - Equivalent to qstrcmp(s1,s2) \<= 0. -*/ - -/*! - \fn bool operator<=( const char *s1, const QCString &s2 ) - \relates QCString - Returns TRUE if \e s1 is alphabetically less than or equal to \e s2, - otherwise FALSE. - - Equivalent to qstrcmp(s1,s2) \<= 0. -*/ - -/*! - \fn bool operator>( const QCString &s1, const char *s2 ) - \relates QCString - Returns TRUE if \e s1 is alphabetically greater than \e s2, otherwise FALSE. - - Equivalent to qstrcmp(s1,s2) \> 0. -*/ - -/*! - \fn bool operator>( const char *s1, const QCString &s2 ) - \relates QCString - Returns TRUE if \e s1 is alphabetically greater than \e s2, otherwise FALSE. - - Equivalent to qstrcmp(s1,s2) \> 0. -*/ - -/*! - \fn bool operator>=( const QCString &s1, const char *s2 ) - \relates QCString - Returns TRUE if \e s1 is alphabetically greater than or equal to \e s2, - otherwise FALSE. - - Equivalent to qstrcmp(s1,s2) \>= 0. -*/ - -/*! - \fn bool operator>=( const char *s1, const QCString &s2 ) - \relates QCString - Returns TRUE if \e s1 is alphabetically greater than or equal to \e s2, - otherwise FALSE. - - Equivalent to qstrcmp(s1,s2) \>= 0. -*/ - -/*! - \fn QCString operator+( const QCString &s1, const QCString &s2 ) - \relates QCString - Returns the concatenated string of s1 and s2. -*/ - -/*! - \fn QCString operator+( const QCString &s1, const char *s2 ) - \relates QCString - Returns the concatenated string of s1 and s2. -*/ - -/*! - \fn QCString operator+( const char *s1, const QCString &s2 ) - \relates QCString - Returns the concatenated string of s1 and s2. -*/ - -/*! - \fn QCString operator+( const QCString &s, char c ) - \relates QCString - Returns the concatenated string of s and c. -*/ - -/*! - \fn QCString operator+( char c, const QCString &s ) - \relates QCString - Returns the concatenated string of c and s. -*/ diff --git a/qtools/qcstring.h b/qtools/qcstring.h index e735462..e56b1e4 100644 --- a/qtools/qcstring.h +++ b/qtools/qcstring.h @@ -43,14 +43,14 @@ #include "qarray.h" #endif // QT_H +#include #include #if defined(_OS_SUN_) && defined(_CC_GNU_) #include #endif -//#undef SMALLSTRING -#define SMALLSTRING +class QGString; /***************************************************************************** Fixes and workarounds for some platforms @@ -143,7 +143,6 @@ Q_EXPORT int qstrnicmp( const char *, const char *, uint len ); #endif - // qChecksum: Internet checksum Q_EXPORT Q_UINT16 qChecksum( const char *s, uint len ); @@ -166,34 +165,35 @@ Q_EXPORT QDataStream &operator<<( QDataStream &, const QByteArray & ); Q_EXPORT QDataStream &operator>>( QDataStream &, QByteArray & ); #endif - - -#ifdef SMALLSTRING -#define SCString QCString -#include "scstring.h" -#else - -/***************************************************************************** - QCString class - *****************************************************************************/ - class QRegExp; -class Q_EXPORT QCString : public QByteArray // C string class +/** This is an alternative implementation of QCString. It provides basically + * the same functions but uses less memory for administration. This class + * is just a wrapper around a plain C string requiring only 4 bytes "overhead". + * QCString features sharing of data and stores the string length, but + * requires 4 + 12 bytes for this (even for the empty string). As doxygen + * uses a LOT of string during a run it saves a lot of memory to use a + * more memory efficient implementation at the cost of relatively low + * runtime overhead. + */ +class QCString { public: - QCString() {} // make null string - QCString( int size ); // allocate size incl. \0 - QCString( const QCString &s ) : QByteArray( s ) {} - QCString( const char *str ); // deep copy - QCString( const char *str, uint maxlen ); // deep copy, max length - - QCString &operator=( const QCString &s );// shallow copy + QCString() : m_data(0) {} // make null string + QCString( const QCString &s ); + QCString( int size ); + QCString( const char *str ); + QCString( const char *str, uint maxlen ); + ~QCString(); + + QCString &operator=( const QCString &s );// deep copy QCString &operator=( const char *str ); // deep copy - bool isNull() const; + bool isNull() const; bool isEmpty() const; uint length() const; + uint size() const { return m_data ? length()+1 : 0; } + char * data() const { return m_data; } bool resize( uint newlen ); bool truncate( uint pos ); bool fill( char c, int len = -1 ); @@ -211,24 +211,23 @@ public: int contains( char c, bool cs=TRUE ) const; int contains( const char *str, bool cs=TRUE ) const; int contains( const QRegExp & ) const; + bool stripPrefix(const char *prefix); QCString left( uint len ) const; QCString right( uint len ) const; QCString mid( uint index, uint len=0xffffffff) const; - QCString leftJustify( uint width, char fill=' ', bool trunc=FALSE)const; - QCString rightJustify( uint width, char fill=' ',bool trunc=FALSE)const; - QCString lower() const; QCString upper() const; QCString stripWhiteSpace() const; QCString simplifyWhiteSpace() const; + QCString &assign( const char *str ); QCString &insert( uint index, const char * ); QCString &insert( uint index, char ); - QCString &append( const char * ); - QCString &prepend( const char * ); + QCString &append( const char *s ); + QCString &prepend( const char *s ); QCString &remove( uint index, uint len ); QCString &replace( uint index, uint len, const char * ); QCString &replace( const QRegExp &, const char * ); @@ -239,10 +238,7 @@ public: uint toUInt( bool *ok=0 ) const; long toLong( bool *ok=0 ) const; ulong toULong( bool *ok=0 ) const; - float toFloat( bool *ok=0 ) const; - double toDouble( bool *ok=0 ) const; - QCString &setStr( const char *s ); QCString &setNum( short ); QCString &setNum( ushort ); QCString &setNum( int ); @@ -252,14 +248,56 @@ public: QCString &setNum( float, char f='g', int prec=6 ); QCString &setNum( double, char f='g', int prec=6 ); - bool setExpand( uint index, char c ); - operator const char *() const; QCString &operator+=( const char *str ); QCString &operator+=( char c ); + char &at( uint index ) const; + char &operator[]( int i ) const { return at(i); } + + private: + static void msg_index( uint ); + void duplicate( const QCString &s ); + void duplicate( const char *str); + QCString &duplicate( const char *str, int); + + char * m_data; }; -#endif +inline char &QCString::at( uint index ) const +{ + return m_data[index]; +} + +inline void QCString::duplicate( const QCString &s ) +{ + if (!s.isEmpty()) + { + uint l = strlen(s.data()); + m_data = (char *)malloc(l+1); + if (m_data) memcpy(m_data,s.data(),l+1); + } + else + m_data=0; +} + +inline void QCString::duplicate( const char *str) +{ + if (str && str[0]!='\0') + { + uint l = strlen(str); + m_data = (char *)malloc(l+1); + if (m_data) memcpy(m_data,str,l+1); + } + else + m_data=0; +} + +inline QCString &QCString::duplicate( const char *str, int) +{ + if (m_data) free(m_data); + duplicate(str); + return *this; +} /***************************************************************************** QCString stream functions @@ -370,21 +408,26 @@ Q_EXPORT inline bool operator>=( const char *s1, const QCString &s2 ) Q_EXPORT inline QCString operator+( const QCString &s1, const QCString &s2 ) { - QCString tmp( s1.data() ); + QCString tmp(s1); tmp += s2; return tmp; } + +inline QCString operator+( const QCString &s1, const QGString &s2 ); +inline QCString operator+( const QGString &s1, const QCString &s2 ); + + Q_EXPORT inline QCString operator+( const QCString &s1, const char *s2 ) { - QCString tmp( s1.data() ); + QCString tmp(s1); tmp += s2; return tmp; } Q_EXPORT inline QCString operator+( const char *s1, const QCString &s2 ) { - QCString tmp( s1 ); + QCString tmp(s1); tmp += s2; return tmp; } @@ -404,4 +447,5 @@ Q_EXPORT inline QCString operator+( char c1, const QCString &s2 ) return tmp; } + #endif // QCSTRING_H diff --git a/qtools/qfile.h b/qtools/qfile.h index cfd357b..a447d2f 100644 --- a/qtools/qfile.h +++ b/qtools/qfile.h @@ -52,7 +52,7 @@ class Q_EXPORT QFile : public QIODevice // file I/O device class public: QFile(); QFile( const QString &name ); - ~QFile(); + virtual ~QFile(); QString name() const; void setName( const QString &name ); @@ -95,6 +95,7 @@ public: int handle() const; int64 pos() const; + int64 toEnd(); bool seek(int64 pos); protected: diff --git a/qtools/qfile_unix.cpp b/qtools/qfile_unix.cpp index fbf6acf..4d3a51b 100644 --- a/qtools/qfile_unix.cpp +++ b/qtools/qfile_unix.cpp @@ -643,6 +643,19 @@ int64 QFile::pos() const return -1; } +int64 QFile::toEnd() +{ + if (isOpen()) + { + // TODO: support 64 bit size + if (fseek( fh, 0, SEEK_END )!=-1) + { + return ftell( fh ); + } + } + return -1; +} + bool QFile::seek( int64 pos ) { if (isOpen()) diff --git a/qtools/qfile_win32.cpp b/qtools/qfile_win32.cpp index 83c8c8d..0cc91de 100644 --- a/qtools/qfile_win32.cpp +++ b/qtools/qfile_win32.cpp @@ -602,6 +602,19 @@ int64 QFile::pos() const return -1; } +int64 QFile::toEnd() +{ + if (isOpen()) + { + // TODO: support 64 bit size + if (fseek( fh, 0, SEEK_END )!=-1) + { + return ftell( fh ); + } + } + return -1; +} + bool QFile::seek( int64 pos ) { if (isOpen()) diff --git a/qtools/qgstring.cpp b/qtools/qgstring.cpp new file mode 100644 index 0000000..a19d747 --- /dev/null +++ b/qtools/qgstring.cpp @@ -0,0 +1,200 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2004 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. + * + */ + +#include "qgstring.h" + +#include + +#define BLOCK_SIZE 64 +#define ROUND_SIZE(x) ((x)+BLOCK_SIZE-1)&~(BLOCK_SIZE-1) + +QGString::QGString() // make null string + : m_data(0), m_len(0), m_memSize(0) +{ +} + +QGString::QGString(uint size) +{ + m_memSize = ROUND_SIZE(size); + if (m_memSize==0) + { + m_data=0; + m_len=0; + } + else + { + m_data = (char*)malloc(m_memSize); + m_data[0]='\0'; + m_len=0; + } +} + +QGString::QGString( const QGString &s ) +{ + if (s.m_memSize==0) + { + m_data = 0; + m_len = 0; + m_memSize = 0; + } + else + { + m_data = (char *)malloc(s.m_memSize); + m_len = s.m_len; + m_memSize = s.m_memSize; + qstrcpy(m_data,s.m_data); + } +} + +QGString::QGString( const char *str ) +{ + if (str==0) + { + m_data=0; + m_len=0; + m_memSize=0; + } + else + { + m_len = qstrlen(str); + m_memSize = ROUND_SIZE(m_len+1); + assert(m_memSize>=m_len+1); + m_data = (char *)malloc(m_memSize); + qstrcpy(m_data,str); + } +} + +QGString::~QGString() +{ + free(m_data); + m_data=0; +} + +bool QGString::resize( uint newlen ) +{ + m_len = 0; + if (newlen==0) + { + if (m_data) { free(m_data); m_data=0; } + m_memSize=0; + return TRUE; + } + m_memSize = ROUND_SIZE(newlen+1); + assert(m_memSize>=newlen+1); + if (m_data==0) + { + m_data = (char *)malloc(m_memSize); + } + else + { + m_data = (char *)realloc(m_data,m_memSize); + } + if (m_data==0) return FALSE; + m_data[newlen-1]='\0'; + m_len = qstrlen(m_data); + return TRUE; +} + +QGString &QGString::operator=( const QGString &s ) +{ + if (m_data) free(m_data); + if (s.m_memSize==0) // null string + { + m_data = 0; + m_len = 0; + m_memSize = 0; + } + else + { + m_len = s.m_len; + m_memSize = s.m_memSize; + m_data = (char*)malloc(m_memSize); + qstrcpy(m_data,s.m_data); + } + return *this; +} + +QGString &QGString::operator=( const char *str ) +{ + if (m_data) free(m_data); + if (str==0) // null string + { + m_data = 0; + m_len = 0; + m_memSize = 0; + } + else + { + m_len = qstrlen(str); + m_memSize = ROUND_SIZE(m_len+1); + assert(m_memSize>=m_len+1); + m_data = (char*)malloc(m_memSize); + qstrcpy(m_data,str); + } + return *this; +} + +QGString &QGString::operator+=( const QGString &s ) +{ + if (s.m_memSize==0) return *this; + uint len1 = length(); + uint len2 = s.length(); + uint memSize = ROUND_SIZE(len1 + len2 + 1); + assert(memSize>=len1+len2+1); + char *newData = memSize!=m_memSize ? (char*)realloc( m_data, memSize ) : m_data; + m_memSize = memSize; + if (m_data) + { + m_data = newData; + memcpy( m_data + len1, s, len2 + 1 ); + } + return *this; +} + +QGString &QGString::operator+=( const char *str ) +{ + if (!str) return *this; + uint len1 = length(); + uint len2 = qstrlen(str); + uint memSize = ROUND_SIZE(len1 + len2 + 1); + assert(memSize>=len1+len2+1); + char *newData = memSize!=m_memSize ? (char *)realloc( m_data, memSize ) : m_data; + m_memSize = memSize; + if (newData) + { + m_data = newData; + memcpy( m_data + len1, str, len2 + 1 ); + } + m_len+=len2; + return *this; +} + +QGString &QGString::operator+=( char c ) +{ + uint len = m_len; + uint memSize = ROUND_SIZE(len+2); + assert(memSize>=len+2); + char *newData = memSize!=m_memSize ? (char *)realloc( m_data, memSize ) : m_data; + m_memSize = memSize; + if (newData) + { + m_data = newData; + m_data[len] = c; + m_data[len+1] = '\0'; + } + m_len++; + return *this; +} + diff --git a/qtools/qgstring.h b/qtools/qgstring.h new file mode 100644 index 0000000..d3b997f --- /dev/null +++ b/qtools/qgstring.h @@ -0,0 +1,137 @@ +#ifndef QGSTRING_H +#define QGSTRING_H + +#include +#include + +#if defined(_OS_SUN_) && defined(_CC_GNU_) +#include +#endif + +#include "qcstring.h" + +/***************************************************************************** + Fixes and workarounds for some platforms + *****************************************************************************/ + +/** This is an alternative implementation of QCString. + */ +class QGString +{ + public: + QGString(); // make null string + QGString(uint size); + QGString( const QGString &s ); + QGString( const char *str ); + ~QGString() ; + + bool resize( uint newlen ); + + QGString &operator=( const QGString &s ); + QGString &operator=( const char *str ); + QGString &operator+=( const QGString &s ); + QGString &operator+=( const char *str ); + QGString &operator+=( char c ); + + bool isNull() const { return m_data==0; } + bool isEmpty() const { return m_len==0; } + uint length() const { return m_len; } + uint size() const { return m_memSize; } + char * data() const { return m_data; } + bool truncate( uint pos ) { return resize(pos+1); } + operator const char *() const { return (const char *)data(); } + char &at( uint index ) const { return m_data[index]; } + char &operator[]( int i ) const { return at(i); } + + private: + char * m_data; + uint m_len; + uint m_memSize; +}; + +/***************************************************************************** + QGString non-member operators + *****************************************************************************/ + +Q_EXPORT inline bool operator==( const QGString &s1, const QGString &s2 ) +{ return qstrcmp(s1.data(),s2.data()) == 0; } + +Q_EXPORT inline bool operator==( const QGString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) == 0; } + +Q_EXPORT inline bool operator==( const char *s1, const QGString &s2 ) +{ return qstrcmp(s1,s2.data()) == 0; } + +Q_EXPORT inline bool operator!=( const QGString &s1, const QGString &s2 ) +{ return qstrcmp(s1.data(),s2.data()) != 0; } + +Q_EXPORT inline bool operator!=( const QGString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) != 0; } + +Q_EXPORT inline bool operator!=( const char *s1, const QGString &s2 ) +{ return qstrcmp(s1,s2.data()) != 0; } + +Q_EXPORT inline bool operator<( const QGString &s1, const QGString& s2 ) +{ return qstrcmp(s1.data(),s2.data()) < 0; } + +Q_EXPORT inline bool operator<( const QGString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) < 0; } + +Q_EXPORT inline bool operator<( const char *s1, const QGString &s2 ) +{ return qstrcmp(s1,s2.data()) < 0; } + +Q_EXPORT inline bool operator<=( const QGString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) <= 0; } + +Q_EXPORT inline bool operator<=( const char *s1, const QGString &s2 ) +{ return qstrcmp(s1,s2.data()) <= 0; } + +Q_EXPORT inline bool operator>( const QGString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) > 0; } + +Q_EXPORT inline bool operator>( const char *s1, const QGString &s2 ) +{ return qstrcmp(s1,s2.data()) > 0; } + +Q_EXPORT inline bool operator>=( const QGString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) >= 0; } + +Q_EXPORT inline bool operator>=( const char *s1, const QGString &s2 ) +{ return qstrcmp(s1,s2.data()) >= 0; } + +Q_EXPORT inline QGString operator+( const QGString &s1, const QGString &s2 ) +{ + QGString tmp( s1.data() ); + tmp += s2; + return tmp; +} + +Q_EXPORT inline QGString operator+( const QGString &s1, const char *s2 ) +{ + QGString tmp( s1.data() ); + tmp += s2; + return tmp; +} + +Q_EXPORT inline QGString operator+( const char *s1, const QGString &s2 ) +{ + QGString tmp( s1 ); + tmp += s2; + return tmp; +} + +Q_EXPORT inline QGString operator+( const QGString &s1, char c2 ) +{ + QGString tmp( s1.data() ); + tmp += c2; + return tmp; +} + +Q_EXPORT inline QGString operator+( char c1, const QGString &s2 ) +{ + QGString tmp; + tmp += c1; + tmp += s2; + return tmp; +} + +#endif // QGSTRING_H diff --git a/qtools/qtools.pro.in b/qtools/qtools.pro.in index 718803e..d2550f6 100644 --- a/qtools/qtools.pro.in +++ b/qtools/qtools.pro.in @@ -22,6 +22,7 @@ HEADERS = qarray.h \ qgeneric.h \ qglist.h \ qglobal.h \ + qgstring.h \ qgvector.h \ qintdict.h \ qiodevice.h \ @@ -57,6 +58,7 @@ SOURCES = qbuffer.cpp \ qgdict.cpp \ qglist.cpp \ qglobal.cpp \ + qgstring.cpp \ qgvector.cpp \ qiodevice.cpp \ qregexp.cpp \ diff --git a/src/classdef.cpp b/src/classdef.cpp index a753940..1470ee3 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -43,6 +43,205 @@ // return result; //} +class ClassDefImpl +{ + public: + ClassDefImpl(); + ~ClassDefImpl(); + void init(const char *defFileName, const char *name, + const QCString &ctStr, const char *fName); + + /*! file name that forms the base for the output file containing the + * class documentation. For compatibility with Qt (e.g. links via tag + * files) this name cannot be derived from the class name directly. + */ + QCString fileName; + + /*! Include information about the header file should be included + * in the documentation. 0 by default, set by setIncludeFile(). + */ + IncludeInfo *incInfo; + + /*! List of base class (or super-classes) from which this class derives + * directly. + */ + BaseClassList *inherits; + + /*! List of sub-classes that directly derive from this class + */ + BaseClassList *inheritedBy; + + /*! Namespace this class is part of + * (this is the inner most namespace in case of nested namespaces) + */ + NamespaceDef *nspace; + + /*! File this class is defined in */ + FileDef *fileDef; + + /*! List of all members (including inherited members) */ + MemberNameInfoSDict *allMemberNameInfoSDict; + + /*! Template arguments of this class */ + ArgumentList *tempArgs; + + /*! Files that were used for generating the class documentation. */ + QStrList files; + + /*! Examples that use this class */ + ExampleSDict *exampleSDict; + + /*! Holds the kind of "class" this is. */ + ClassDef::CompoundType compType; + + /*! The protection level in which this class was found. + * Typically Public, but for nested classes this can also be Protected + * or Private. + */ + Protection prot; + + /*! The inner classes contained in this class. Will be 0 if there are + * no inner classes. + */ + ClassSDict *innerClasses; + + /* classes for the collaboration diagram */ + UsesClassDict *usesImplClassDict; + UsesClassDict *usedByImplClassDict; + UsesClassDict *usesIntfClassDict; + + /*! Template instances that exists of this class, the key in the + * dictionary is the template argument list. + */ + QDict *templateInstances; + + /*! Template instances that exists of this class, as defined by variables. + * We do NOT want to document these individually. The key in the + * dictionary is the template argument list. + */ + QDict *variableInstances; + + QDict *templBaseClassNames; + + /*! The class this class is an instance of. */ + ClassDef *templateMaster; + + /*! class name with outer class scope, but without namespace scope. */ + QCString className; + + /*! If this class is a Objective-C category, then this points to the + * class which is extended. + */ + ClassDef *categoryOf; + + QList memberLists; + + /* user defined member groups */ + MemberGroupSDict *memberGroupSDict; + + /*! Indicated whether this class exists because it is used by + * some other class only (TRUE) or if some class inherits from + * it (FALSE). This is need to remove used-only classes from + * the inheritance tree. + */ + bool artificial; + + /*! Is this an abstact class? */ + bool isAbstract; + + /*! Is the class part of an unnamed namespace? */ + bool isStatic; + + /*! Is the class part implemented in Objective C? */ + bool isObjC; + + /*! TRUE if classes members are merged with those of the base classes. */ + bool membersMerged; + + /*! TRUE if the class is defined in a source file rather than a header file. */ + bool isLocal; + + bool isTemplArg; + + /*! Does this class group its user-grouped members + * as a sub-section of the normal (public/protected/..) + * groups? + */ + bool subGrouping; +}; + +void ClassDefImpl::init(const char *defFileName, const char *name, + const QCString &ctStr, const char *fName) +{ + if (fName) + { + fileName=stripExtension(fName); + } + else + { + fileName=ctStr+name; + } + exampleSDict = 0; + inherits = 0; + inheritedBy = 0; + allMemberNameInfoSDict = 0; + incInfo=0; + tempArgs=0; + prot=Public; + nspace=0; + fileDef=0; + usesImplClassDict=0; + usedByImplClassDict=0; + usesIntfClassDict=0; + memberGroupSDict = 0; + innerClasses = 0; + subGrouping=Config_getBool("SUBGROUPING"); + templateInstances = 0; + variableInstances = 0; + templateMaster =0; + templBaseClassNames = 0; + artificial = FALSE; + isAbstract = FALSE; + isStatic = FALSE; + isTemplArg = FALSE; + membersMerged = FALSE; + categoryOf = 0; + QCString ns; + extractNamespaceName(name,className,ns); + //printf("m_name=%s m_className=%s ns=%s\n",m_name.data(),m_className.data(),ns.data()); + + if (((QCString)defFileName).right(5)!=".java" && + guessSection(defFileName)==Entry::SOURCE_SEC) + { + isLocal=TRUE; + } + else + { + isLocal=FALSE; + } +} + +ClassDefImpl::ClassDefImpl() +{ +} + +ClassDefImpl::~ClassDefImpl() +{ + delete inherits; + delete inheritedBy; + delete allMemberNameInfoSDict; + delete exampleSDict; + delete usesImplClassDict; + delete usedByImplClassDict; + delete usesIntfClassDict; + delete incInfo; + delete memberGroupSDict; + delete innerClasses; + delete templateInstances; + delete variableInstances; + delete templBaseClassNames; + delete tempArgs; +} // constructs a new class definition ClassDef::ClassDef( @@ -52,6 +251,14 @@ ClassDef::ClassDef( bool isSymbol) : Definition(defFileName,defLine,removeRedundantWhiteSpace(nm),0,0,isSymbol) { + visited=FALSE; + setReference(lref); + m_impl = new ClassDefImpl; + m_impl->compType = ct; + m_impl->isObjC = FALSE; + m_impl->init(defFileName,name(),compoundTypeString(),fName); + +#if 0 m_compType=ct; m_isObjC = FALSE; QCString compoundName=compoundTypeString(); @@ -67,8 +274,6 @@ ClassDef::ClassDef( m_inherits = 0; m_inheritedBy = 0; m_allMemberNameInfoSDict = 0; - visited=FALSE; - setReference(lref); m_incInfo=0; m_tempArgs=0; m_prot=Public; @@ -103,55 +308,13 @@ ClassDef::ClassDef( { m_isLocal=FALSE; } - - -#if 0 - pubMethods=0; - proMethods=0; - pacMethods=0; - priMethods=0; - pubStaticMethods=0; - proStaticMethods=0; - pacStaticMethods=0; - priStaticMethods=0; - pubSlots=0; - proSlots=0; - priSlots=0; - pubAttribs=0; - proAttribs=0; - pacAttribs=0; - priAttribs=0; - pubStaticAttribs=0; - proStaticAttribs=0; - pacStaticAttribs=0; - priStaticAttribs=0; - pubTypes=0; - proTypes=0; - pacTypes=0; - priTypes=0; - related=0; - signals=0; - friends=0; - dcopMethods=0; - properties=0; - events=0; - - constructors=0; - typedefMembers=0; - enumMembers=0; - enumValMembers=0; - functionMembers=0; - relatedMembers=0; - variableMembers=0; - propertyMembers=0; - eventMembers=0; #endif - } // destroy the class definition ClassDef::~ClassDef() { +#if 0 delete m_inherits; delete m_inheritedBy; delete m_allMemberNameInfoSDict; @@ -166,48 +329,8 @@ ClassDef::~ClassDef() delete m_variableInstances; delete m_templBaseClassNames; delete m_tempArgs; - -#if 0 - delete pubMethods; - delete proMethods; - delete pacMethods; - delete priMethods; - delete pubStaticMethods; - delete proStaticMethods; - delete pacStaticMethods; - delete priStaticMethods; - delete pubSlots; - delete proSlots; - delete priSlots; - delete pubAttribs; - delete proAttribs; - delete pacAttribs; - delete priAttribs; - delete pubStaticAttribs; - delete proStaticAttribs; - delete pacStaticAttribs; - delete priStaticAttribs; - delete pubTypes; - delete proTypes; - delete pacTypes; - delete priTypes; - delete related; - delete signals; - delete friends; - delete dcopMethods; - delete properties; - delete events; - - delete constructors; - delete typedefMembers; - delete enumMembers; - delete enumValMembers; - delete functionMembers; - delete relatedMembers; - delete variableMembers; - delete propertyMembers; - delete eventMembers; #endif + delete m_impl; } QCString ClassDef::getMemberListFileName() const @@ -222,7 +345,7 @@ QCString ClassDef::displayName() const QCString n; if (hideScopeNames) { - n=m_className; + n=m_impl->className; } else { @@ -232,7 +355,7 @@ QCString ClassDef::displayName() const { n=substitute(n,"::","."); } - if (m_compType==ClassDef::Protocol && n.right(2)=="-p") + if (m_impl->compType==ClassDef::Protocol && n.right(2)=="-p") { n="< "+n.left(n.length()-2)+" >"; } @@ -245,12 +368,12 @@ void ClassDef::insertBaseClass(ClassDef *cd,const char *n,Protection p, { //printf("*** insert base class %s into %s\n",cd->name().data(),name().data()); //inherits->inSort(new BaseClassDef(cd,p,s,t)); - if (m_inherits==0) + if (m_impl->inherits==0) { - m_inherits = new BaseClassList; - m_inherits->setAutoDelete(TRUE); + m_impl->inherits = new BaseClassList; + m_impl->inherits->setAutoDelete(TRUE); } - m_inherits->append(new BaseClassDef(cd,n,p,s,t)); + m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t)); } // inserts a sub class in the inherited list @@ -258,34 +381,34 @@ void ClassDef::insertSubClass(ClassDef *cd,Protection p, Specifier s,const char *t) { //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data()); - if (m_inheritedBy==0) + if (m_impl->inheritedBy==0) { - m_inheritedBy = new BaseClassList; - m_inheritedBy->setAutoDelete(TRUE); + m_impl->inheritedBy = new BaseClassList; + m_impl->inheritedBy->setAutoDelete(TRUE); } - m_inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t)); + m_impl->inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t)); } void ClassDef::addMembersToMemberGroup() { - QListIterator mli(m_memberLists); + QListIterator mli(m_impl->memberLists); MemberList *ml; for (mli.toFirst();(ml=mli.current());++mli) { if ((ml->listType()&MemberList::detailedLists)==0) { - ::addMembersToMemberGroup(ml,&memberGroupSDict,this); + ::addMembersToMemberGroup(ml,&m_impl->memberGroupSDict,this); } } // add members inside sections to their groups - if (memberGroupSDict) + if (m_impl->memberGroupSDict) { - MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { - if (mg->allMembersInSameSection() && m_subGrouping) + if (mg->allMembersInSameSection() && m_impl->subGrouping) { //printf("addToDeclarationSection(%s)\n",mg->header().data()); mg->addToDeclarationSection(); @@ -533,9 +656,10 @@ void ClassDef::internalInsertMember(MemberDef *md, if (md->virtualness()==Pure) { - m_isAbstract=TRUE; + m_impl->isAbstract=TRUE; } + ::addClassMemberNameToIndex(md); if (addToAllList && !(Config_getBool("HIDE_FRIEND_COMPOUNDS") && md->isFriend() && @@ -547,12 +671,12 @@ void ClassDef::internalInsertMember(MemberDef *md, MemberInfo *mi = new MemberInfo((MemberDef *)md, prot,md->virtualness(),FALSE); MemberNameInfo *mni=0; - if (m_allMemberNameInfoSDict==0) + if (m_impl->allMemberNameInfoSDict==0) { - m_allMemberNameInfoSDict = new MemberNameInfoSDict(17); - m_allMemberNameInfoSDict->setAutoDelete(TRUE); + m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17); + m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE); } - if ((mni=m_allMemberNameInfoSDict->find(md->name()))) + if ((mni=m_impl->allMemberNameInfoSDict->find(md->name()))) { mni->append(mi); } @@ -560,7 +684,7 @@ void ClassDef::internalInsertMember(MemberDef *md, { mni = new MemberNameInfo(md->name()); mni->append(mi); - m_allMemberNameInfoSDict->append(mni->memberName(),mni); + m_impl->allMemberNameInfoSDict->append(mni->memberName(),mni); } } } @@ -575,7 +699,7 @@ void ClassDef::computeAnchors() { ClassDef *context = Config_getBool("INLINE_INHERITED_MEMB") ? this : 0; const char *letters = "abcdefghijklmnopqrstuvwxyz0123456789"; - QListIterator mli(m_memberLists); + QListIterator mli(m_impl->memberLists); MemberList *ml; int index = 0; for (mli.toFirst();(ml=mli.current());++mli) @@ -586,9 +710,9 @@ void ClassDef::computeAnchors() } } - if (memberGroupSDict) + if (m_impl->memberGroupSDict) { - MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { @@ -599,9 +723,9 @@ void ClassDef::computeAnchors() void ClassDef::distributeMemberGroupDocumentation() { - if (memberGroupSDict) + if (m_impl->memberGroupSDict) { - MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { @@ -613,16 +737,16 @@ void ClassDef::distributeMemberGroupDocumentation() void ClassDef::findSectionsInDocumentation() { docFindSections(documentation(),this,0,docFile()); - if (memberGroupSDict) + if (m_impl->memberGroupSDict) { - MemberGroupSDict::Iterator mgli(*memberGroupSDict); + MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { mg->findSectionsInDocumentation(); } } - QListIterator mli(m_memberLists); + QListIterator mli(m_impl->memberLists); MemberList *ml; for (mli.toFirst();(ml=mli.current());++mli) { @@ -637,10 +761,10 @@ void ClassDef::findSectionsInDocumentation() // add a file name to the used files set void ClassDef::insertUsedFile(const char *f) { - if (m_files.find(f)==-1) m_files.append(f); - if (m_templateInstances) + if (m_impl->files.find(f)==-1) m_impl->files.append(f); + if (m_impl->templateInstances) { - QDictIterator qdi(*m_templateInstances); + QDictIterator qdi(*m_impl->templateInstances); ClassDef *cd; for (qdi.toFirst();(cd=qdi.current());++qdi) { @@ -675,17 +799,17 @@ void ClassDef::setIncludeFile(FileDef *fd, const char *includeName,bool local, bool force) { //printf("ClassDef::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force); - if (!m_incInfo) m_incInfo=new IncludeInfo; - if ((includeName && m_incInfo->includeName.isEmpty()) || - (fd!=0 && m_incInfo->fileDef==0) + if (!m_impl->incInfo) m_impl->incInfo=new IncludeInfo; + if ((includeName && m_impl->incInfo->includeName.isEmpty()) || + (fd!=0 && m_impl->incInfo->fileDef==0) ) { //printf("Setting file info\n"); - m_incInfo->fileDef = fd; - m_incInfo->includeName = includeName; - m_incInfo->local = local; + m_impl->incInfo->fileDef = fd; + m_impl->incInfo->includeName = includeName; + m_impl->incInfo->local = local; } - if (force && includeName) m_incInfo->includeName = includeName; + if (force && includeName) m_impl->incInfo->includeName = includeName; } // TODO: fix this: a nested template class can have multiple outer templates @@ -694,7 +818,7 @@ void ClassDef::setIncludeFile(FileDef *fd, // int ti; // ClassDef *pcd=0; // int pi=0; -// if (m_tempArgs) return m_tempArgs; +// if (m_impl->tempArgs) return m_impl->tempArgs; // // find the outer most class scope // while ((ti=name().find("::",pi))!=-1 && // (pcd=getClass(name().left(ti)))==0 @@ -825,12 +949,12 @@ void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &pageType ol.parseDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE); } // write examples - if (exampleFlag && m_exampleSDict) + if (exampleFlag && m_impl->exampleSDict) { ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": "); ol.writeDescItem(); ol.newParagraph(); - writeExample(ol,m_exampleSDict); + writeExample(ol,m_impl->exampleSDict); ol.endSimpleSect(); } ol.newParagraph(); @@ -849,11 +973,11 @@ void ClassDef::showUsedFiles(OutputList &ol) { ol.writeRuler(); ol.parseText(theTranslator->trGeneratedFromFiles( - m_isObjC && m_compType==Interface ? Class : m_compType, - m_files.count()==1)); + m_impl->isObjC && m_impl->compType==Interface ? Class : m_impl->compType, + m_impl->files.count()==1)); bool first=TRUE; - const char *file = m_files.first(); + const char *file = m_impl->files.first(); while (file) { bool ambig; @@ -914,7 +1038,7 @@ void ClassDef::showUsedFiles(OutputList &ol) } - file=m_files.next(); + file=m_impl->files.next(); } if (!first) ol.endItemList(); } @@ -928,8 +1052,8 @@ void ClassDef::writeDocumentation(OutputList &ol) pageType += compoundTypeString(); toupper(pageType.at(1)); QCString pageTitle = theTranslator->trCompoundReference(displayName(), - m_compType == Interface && m_isObjC ? Class : m_compType, - m_tempArgs != 0); + m_impl->compType == Interface && m_impl->isObjC ? Class : m_impl->compType, + m_impl->tempArgs != 0); startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_ClassVisible); if (getOuterScope()!=Doxygen::globalScope) @@ -947,9 +1071,9 @@ void ClassDef::writeDocumentation(OutputList &ol) ol.writeString(""); - if (m_inherits && m_inherits->count()>0) + if (m_impl->inherits && m_impl->inherits->count()>0) { - BaseClassListIterator bli(*m_inherits); + BaseClassListIterator bli(*m_impl->inherits); ol.writeString(" addRelatedPage() %s gd=%p\n",root->name.data(),gd); QCString doc; @@ -464,7 +479,7 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional) { GroupDef *gd; - if ((gd=Doxygen::groupSDict[root->name])) + if ((gd=Doxygen::groupSDict->find(root->name))) { if ( root->groupDocType==Entry::GROUPDOC_NORMAL ) { @@ -506,7 +521,7 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional) gd->setBriefDescription(root->brief,root->briefFile,root->briefLine); gd->setDocumentation(root->doc,root->docFile,root->docLine); gd->addSectionsToDefinition(root->anchors); - Doxygen::groupSDict.append(root->name,gd); + Doxygen::groupSDict->append(root->name,gd); gd->setRefItems(root->sli); } } @@ -538,7 +553,7 @@ static void findGroupScope(EntryNav *rootNav) rootNav->parent() && !rootNav->parent()->name().isEmpty()) { GroupDef *gd; - if ((gd=Doxygen::groupSDict[rootNav->name()])) + if ((gd=Doxygen::groupSDict->find(rootNav->name()))) { QCString scope = rootNav->parent()->name(); if (rootNav->parent()->section()==Entry::PACKAGEDOC_SEC) @@ -568,7 +583,7 @@ static void organizeSubGroupsFiltered(EntryNav *rootNav,bool additional) (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional)) { GroupDef *gd; - if ((gd=Doxygen::groupSDict[root->name])) + if ((gd=Doxygen::groupSDict->find(root->name))) { //printf("adding %s to group %s\n",root->name.data(),gd->name().data()); addGroupToGroups(root,gd); @@ -640,7 +655,7 @@ static void buildFileList(EntryNav *rootNav) for (;(g=gli.current());++gli) { GroupDef *gd=0; - if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict[g->groupname])) + if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) { gd->addFile(fd); //printf("File %s: in group %s\n",fd->name().data(),s->data()); @@ -828,7 +843,7 @@ static Definition *buildScopeFromQualifiedName(const QCString name,int level) QCString nsName = name.mid(idx,l); if (!fullScope.isEmpty()) fullScope+="::"; fullScope+=nsName; - NamespaceDef *nd=Doxygen::namespaceSDict.find(fullScope); + NamespaceDef *nd=Doxygen::namespaceSDict->find(fullScope); Definition *innerScope = nd; ClassDef *cd=0; if (nd==0) cd = getClass(fullScope); @@ -844,7 +859,7 @@ static Definition *buildScopeFromQualifiedName(const QCString name,int level) "[generated]",1,fullScope); // add namespace to the list - Doxygen::namespaceSDict.inSort(fullScope,nd); + Doxygen::namespaceSDict->inSort(fullScope,nd); innerScope = nd; } else // scope is a namespace @@ -949,7 +964,7 @@ ArgumentList *getTemplateArgumentsFromName( int i,p=0; while ((i=name.find("::",p))!=-1) { - NamespaceDef *nd = Doxygen::namespaceSDict[name.left(i)]; + NamespaceDef *nd = Doxygen::namespaceSDict->find(name.left(i)); if (nd==0) { ClassDef *cd = getClass(name.left(i)); @@ -1024,7 +1039,7 @@ static void addClassToContext(EntryNav *rootNav) QCString qualifiedName = scName.isEmpty() ? fullName : scName+"::"+fullName; ClassDef *cd = getClass(qualifiedName); - + Debug::print(Debug::Classes,0, " Found class with name %s (qualifiedName=%s -> cd=%p)\n", cd ? cd->name().data() : root->name.data(), qualifiedName.data(),cd); @@ -1137,7 +1152,7 @@ static void addClassToContext(EntryNav *rootNav) // add class to the list //printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data()); - Doxygen::classSDict.append(fullName,cd); + Doxygen::classSDict->append(fullName,cd); } @@ -1191,7 +1206,7 @@ static void buildClassDocList(EntryNav *rootNav) static void resolveClassNestingRelations() { - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE; int nestingLevel=0; @@ -1200,13 +1215,60 @@ static void resolveClassNestingRelations() { // iterate over all classes searching for a class with right nesting // level (starting with 0 and going up until no more classes are found) + // + // we start with all classes that are inside a namespace and then + // do the ones outside the namespace to avoid an "internal inconsistency" for the + // following: + // File A: + // using namespace N; + // class C::P {} + // File B: + // namespace N { class C { class P {}; }; } + // + // If file A is parsed before file B then without it C::P would not be related to N. done=TRUE; - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd=0; + // first handle any class inside a namespace + for (cli.toFirst();(cd=cli.current());++cli) + { + QCString c,n; + extractNamespaceName(cd->name(),c,n,TRUE); + if (cd->name().contains("::")==nestingLevel && !n.isEmpty()) + { + cd->visited=TRUE; + //printf("Level=%d processing=%s\n",nestingLevel,cd->name().data()); + // also add class to the correct structural context + Definition *d = findScopeFromQualifiedName(Doxygen::globalScope, + cd->name(),cd->getFileDef()); + if (d==0) // we didn't find anything, create the scope artificially + // anyway, so we can at least relate scopes properly. + { + Definition *d = buildScopeFromQualifiedName(cd->name(),cd->name().contains("::")); + if (d!=cd) // avoid recursion in case of redundant scopes, i.e: namespace N { class N::C {}; } + // for this case doxygen assumes the exitance of a namespace N::N in which C is to be found! + { + d->addInnerCompound(cd); + cd->setOuterScope(d); + warn(cd->getDefFileName(),cd->getDefLine(), + "Warning: Internal inconsistency: scope for class %s not " + "found!\n",cd->name().data() + ); + } + } + else + { + //printf("****** adding %s to scope %s\n",cd->name().data(),d->name().data()); + d->addInnerCompound(cd); + cd->setOuterScope(d); + } + } + if (!cd->visited) done=FALSE; + } + // and now the same for classes outside any namespace for (cli.toFirst();(cd=cli.current());++cli) { - //printf("nested relation for class %s\n",cd->name().data()); - if (cd->name().contains("::")==nestingLevel) + if (cd->name().contains("::")==nestingLevel && !cd->visited) { cd->visited=TRUE; //printf("Level=%d processing=%s\n",nestingLevel,cd->name().data()); @@ -1271,7 +1333,7 @@ static void buildNamespaceList(EntryNav *rootNav) //printf("Found namespace %s in %s at line %d\n",root->name.data(), // root->fileName.data(), root->startLine); NamespaceDef *nd; - if ((nd=Doxygen::namespaceSDict[fullName])) // existing namespace + if ((nd=Doxygen::namespaceSDict->find(fullName))) // existing namespace { if (!root->doc.isEmpty() || !root->brief.isEmpty()) // block contains docs { @@ -1341,7 +1403,7 @@ static void buildNamespaceList(EntryNav *rootNav) nd->setBodySegment(root->bodyLine,root->endBodyLine); nd->setBodyDef(fd); // add class to the list - Doxygen::namespaceSDict.inSort(fullName,nd); + Doxygen::namespaceSDict->inSort(fullName,nd); // also add namespace to the correct structural context Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName); @@ -1409,7 +1471,7 @@ static void findUsingDirectives(EntryNav *rootNav) // see if the using statement was found inside a namespace or inside // the global file scope. if (rootNav->parent() && rootNav->parent()->section()==Entry::NAMESPACE_SEC && - (fd==0 || fd->name().right(5)!=".java") // not a .java file + (fd==0 || !fd->isJava()) // not a .java file ) { nsName=stripAnonymousNamespaceScope(rootNav->parent()->name()); @@ -1497,7 +1559,7 @@ static void findUsingDirectives(EntryNav *rootNav) for (;(g=gli.current());++gli) { GroupDef *gd=0; - if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict[g->groupname])) + if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) gd->addNamespace(nd); } @@ -1512,7 +1574,7 @@ static void findUsingDirectives(EntryNav *rootNav) nd->setBriefDescription(root->brief,root->briefFile,root->briefLine); nd->insertUsedFile(root->fileName); // add class to the list - Doxygen::namespaceSDict.inSort(name,nd); + Doxygen::namespaceSDict->inSort(name,nd); nd->setRefItems(root->sli); } } @@ -1591,7 +1653,7 @@ static void findUsingDeclarations(EntryNav *rootNav) usingCd = getClass(name); if (usingCd==0) { - usingCd = Doxygen::hiddenClasses.find(name); + usingCd = Doxygen::hiddenClasses->find(name); } //printf("%s -> %p\n",root->name.data(),usingCd); @@ -1602,7 +1664,7 @@ static void findUsingDeclarations(EntryNav *rootNav) usingCd = new ClassDef( "",1, name,ClassDef::Class); - Doxygen::hiddenClasses.append(root->name,usingCd); + Doxygen::hiddenClasses->append(root->name,usingCd); usingCd->setClassIsArtificial(); } else @@ -1692,15 +1754,20 @@ static void findUsingDeclImports(EntryNav *rootNav) Entry *root = rootNav->entry(); //printf("found member %s\n",mni->memberName()); - MemberDef *newMd = new MemberDef( + MemberDef *newMd = 0; + { + LockingPtr templAl = md->templateArguments(); + LockingPtr al = md->templateArguments(); + newMd = new MemberDef( root->fileName,root->startLine, md->typeString(),memName,md->argsString(), md->excpString(),root->protection,root->virt, md->isStatic(),FALSE,md->memberType(), - md->templateArguments(),md->argumentList() + templAl.pointer(),al.pointer() ); - cd->insertMember(newMd); + } newMd->setMemberClass(cd); + cd->insertMember(newMd); if (!root->doc.isEmpty() || !root->brief.isEmpty()) { newMd->setDocumentation(root->doc,root->docFile,root->docLine); @@ -1743,7 +1810,7 @@ static void findUsingDeclImports(EntryNav *rootNav) static void findIncludedUsingDirectives() { // first mark all files as not visited - FileNameListIterator fnli(Doxygen::inputNameList); + FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (fnli.toFirst();(fn=fnli.current());++fnli) { @@ -1832,7 +1899,7 @@ static MemberDef *addVariableToClass( // see if the member is already found in the same scope // (this may be the case for a static member that is initialized // outside the class) - MemberName *mn=Doxygen::memberNameSDict[name]; + MemberName *mn=Doxygen::memberNameSDict->find(name); if (mn) { MemberNameIterator mni(*mn); @@ -1897,7 +1964,7 @@ static MemberDef *addVariableToClass( //printf("Adding memberName=%s\n",mn->memberName()); //Doxygen::memberNameDict.insert(name,mn); //Doxygen::memberNameList.append(mn); - Doxygen::memberNameSDict.append(name,mn); + Doxygen::memberNameSDict->append(name,mn); // add the member to the class } cd->insertMember(md); @@ -1982,7 +2049,7 @@ static MemberDef *addVariableToFile( } def.stripPrefix("static "); - MemberName *mn=Doxygen::functionNameSDict[name]; + MemberName *mn=Doxygen::functionNameSDict->find(name); if (mn) { //QCString nscope=removeAnonymousScopes(scope); @@ -2055,16 +2122,16 @@ static MemberDef *addVariableToFile( md->setRefItems(root->sli); if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') { - nd->insertMember(md); md->setNamespace(nd); + nd->insertMember(md); } // add member to the file (we do this even if we have already inserted // it into the namespace. if (fd) { - fd->insertMember(md); md->setFileDef(fd); + fd->insertMember(md); } // add member definition to the list of globals @@ -2076,7 +2143,7 @@ static MemberDef *addVariableToFile( { mn = new MemberName(name); mn->append(md); - Doxygen::functionNameSDict.append(name,mn); + Doxygen::functionNameSDict->append(name,mn); } rootNav->changeSection(Entry::EMPTY_SEC); return md; @@ -2143,7 +2210,7 @@ static bool isVarWithConstructor(EntryNav *rootNav) } if (!rootNav->parent()->name().isEmpty()) { - ctx=Doxygen::namespaceSDict.find(rootNav->parent()->name()); + ctx=Doxygen::namespaceSDict->find(rootNav->parent()->name()); } type = root->type; // remove qualifiers @@ -2601,7 +2668,7 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, // add member to the global list of all members //printf("Adding member=%s class=%s\n",md->name().data(),cd->name().data()); MemberName *mn; - if ((mn=Doxygen::memberNameSDict[name])) + if ((mn=Doxygen::memberNameSDict->find(name))) { mn->append(md); } @@ -2609,7 +2676,7 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, { mn = new MemberName(name); mn->append(md); - Doxygen::memberNameSDict.append(name,mn); + Doxygen::memberNameSDict->append(name,mn); } // add member to the class cd @@ -2684,7 +2751,7 @@ static void buildFunctionList(EntryNav *rootNav) int te=rname.find('>'); if (memIndex>0 && (ts==-1 || te==-1)) { - nd = Doxygen::namespaceSDict.find(rname.left(memIndex)); + nd = Doxygen::namespaceSDict->find(rname.left(memIndex)); isMember = nd==0; if (nd) { @@ -2729,7 +2796,7 @@ static void buildFunctionList(EntryNav *rootNav) bool found=FALSE; MemberName *mn; MemberDef *md=0; - if ((mn=Doxygen::functionNameSDict[rname])) + if ((mn=Doxygen::functionNameSDict->find(rname))) { Debug::print(Debug::Functions,0," --> function %s already found!\n",rname.data()); MemberNameIterator mni(*mn); @@ -2747,8 +2814,9 @@ static void buildFunctionList(EntryNav *rootNav) if (rnd) rnsName = rnd->name().copy(); //printf("matching arguments for %s%s %s%s\n", // md->name().data(),md->argsString(),rname.data(),argListToString(root->argList).data()); + LockingPtr mdAl = md->argumentList(); if ( - matchArguments2(md->getOuterScope(),mfd,md->argumentList(), + matchArguments2(md->getOuterScope(),mfd,mdAl.pointer(), rnd ? rnd : Doxygen::globalScope,rfd,root->argList, FALSE) ) @@ -2756,7 +2824,7 @@ static void buildFunctionList(EntryNav *rootNav) GroupDef *gd=0; if (root->groups->first()!=0) { - gd = Doxygen::groupSDict[root->groups->first()->groupname.data()]; + gd = Doxygen::groupSDict->find(root->groups->first()->groupname.data()); } //printf("match!\n"); // see if we need to create a new member @@ -2778,7 +2846,7 @@ static void buildFunctionList(EntryNav *rootNav) if (found) { // merge argument lists - mergeArguments(md->argumentList(),root->argList,!root->doc.isEmpty()); + mergeArguments(mdAl.pointer(),root->argList,!root->doc.isEmpty()); // merge documentation if (md->documentation().isEmpty() && !root->doc.isEmpty()) { @@ -2936,21 +3004,21 @@ static void buildFunctionList(EntryNav *rootNav) if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') { // add member to namespace - nd->insertMember(md); md->setNamespace(nd); + nd->insertMember(md); } if (fd) { // add member to the file (we do this even if we have already // inserted it into the namespace) - fd->insertMember(md); md->setFileDef(fd); + fd->insertMember(md); } // add member to the list of file members //printf("Adding member=%s\n",md->name().data()); MemberName *mn; - if ((mn=Doxygen::functionNameSDict[name])) + if ((mn=Doxygen::functionNameSDict->find(name))) { mn->append(md); } @@ -2958,7 +3026,7 @@ static void buildFunctionList(EntryNav *rootNav) { mn = new MemberName(name); mn->append(md); - Doxygen::functionNameSDict.append(name,mn); + Doxygen::functionNameSDict->append(name,mn); } addMemberToGroups(root,md); if (!root->relatesDup) // if this is a relatesalso command, allow find @@ -3001,13 +3069,13 @@ static void buildFunctionList(EntryNav *rootNav) static void findFriends() { //printf("findFriends()\n"); - MemberNameSDict::Iterator fnli(Doxygen::functionNameSDict); + MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); MemberName *fn; for (;(fn=fnli.current());++fnli) // for each global function name { //printf("Function name=`%s'\n",fn->memberName()); MemberName *mn; - if ((mn=Doxygen::memberNameSDict[fn->memberName()])) + if ((mn=Doxygen::memberNameSDict->find(fn->memberName()))) { // there are members with the same name //printf("Function name is also a member name\n"); MemberNameIterator fni(*fn); @@ -3021,16 +3089,18 @@ static void findFriends() //printf("Checking for matching arguments // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n", // mmd->isRelated(),mmd->isFriend(),mmd->isFunction()); + LockingPtr mmdAl = mmd->argumentList(); + LockingPtr fmdAl = fmd->argumentList(); if ((mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) && - matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), mmd->argumentList(), - fmd->getOuterScope(), fmd->getFileDef(), fmd->argumentList(), + matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), mmdAl.pointer(), + fmd->getOuterScope(), fmd->getFileDef(), fmdAl.pointer(), TRUE ) ) // if the member is related and the arguments match then the // function is actually a friend. { - mergeArguments(mmd->argumentList(),fmd->argumentList()); + mergeArguments(mmdAl.pointer(),fmdAl.pointer()); if (!fmd->documentation().isEmpty()) { mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine()); @@ -3115,7 +3185,7 @@ static void transferFunctionDocumentation() //printf("transferFunctionDocumentation()\n"); // find matching function declaration and definitions. - MemberNameSDict::Iterator mnli(Doxygen::functionNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); MemberName *mn; for (;(mn=mnli.current());++mnli) { @@ -3140,9 +3210,11 @@ static void transferFunctionDocumentation() //printf("mdef=(%p,%s) mdec=(%p,%s)\n", // mdef, mdef ? mdef->name().data() : "", // mdec, mdec ? mdec->name().data() : ""); - if (mdef && mdec && - matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdef->argumentList(), - mdec->getOuterScope(),mdec->getFileDef(),mdec->argumentList(), + + LockingPtr mdefAl = mdef->argumentList(); + LockingPtr mdecAl = mdec->argumentList(); + if (matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdefAl.pointer(), + mdec->getOuterScope(),mdec->getFileDef(),mdecAl.pointer(), TRUE ) ) /* match found */ @@ -3154,7 +3226,7 @@ static void transferFunctionDocumentation() // ); // first merge argument documentation - transferArgumentDocumentation(mdec->argumentList(),mdef->argumentList()); + transferArgumentDocumentation(mdecAl.pointer(),mdefAl.pointer()); /* copy documentation between function definition and declaration */ if (!mdec->briefDescription().isEmpty()) @@ -3170,12 +3242,12 @@ static void transferFunctionDocumentation() //printf("transfering docs mdef->mdec (%s->%s)\n",mdef->argsString(),mdec->argsString()); mdec->setDocumentation(mdef->documentation(),mdef->docFile(),mdef->docLine()); mdec->setDocsForDefinition(mdef->isDocsForDefinition()); - if (mdef->argumentList()) + if (mdefAl!=0) { - ArgumentList *mdefAl = new ArgumentList; - stringToArgumentList(mdef->argsString(),mdefAl); - transferArgumentDocumentation(mdef->argumentList(),mdefAl); - mdec->setArgumentList(mdefAl); + ArgumentList *mdefAlComb = new ArgumentList; + stringToArgumentList(mdef->argsString(),mdefAlComb); + transferArgumentDocumentation(mdefAl.pointer(),mdefAlComb); + mdec->setArgumentList(mdefAlComb); } } else if (!mdec->documentation().isEmpty()) @@ -3183,12 +3255,12 @@ static void transferFunctionDocumentation() //printf("transfering docs mdec->mdef (%s->%s)\n",mdec->argsString(),mdef->argsString()); mdef->setDocumentation(mdec->documentation(),mdec->docFile(),mdec->docLine()); mdef->setDocsForDefinition(mdec->isDocsForDefinition()); - if (mdec->argumentList()) + if (mdecAl!=0) { - ArgumentList *mdecAl = new ArgumentList; - stringToArgumentList(mdec->argsString(),mdecAl); - transferArgumentDocumentation(mdec->argumentList(),mdecAl); - mdef->setDeclArgumentList(mdecAl); + ArgumentList *mdecAlComb = new ArgumentList; + stringToArgumentList(mdec->argsString(),mdecAlComb); + transferArgumentDocumentation(mdecAl.pointer(),mdecAlComb); + mdef->setDeclArgumentList(mdecAlComb); } } if (!mdef->inbodyDocumentation().isEmpty()) @@ -3261,7 +3333,7 @@ static void transferFunctionDocumentation() static void transferFunctionReferences() { - MemberNameSDict::Iterator mnli(Doxygen::functionNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); MemberName *mn; for (;(mn=mnli.current());++mnli) { @@ -3280,63 +3352,68 @@ static void transferFunctionReferences() else if (md->isVariable() && !md->isExternal() && !md->isStatic()) mdef=md; } - if (mdef && mdec && - matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdef->argumentList(), - mdec->getOuterScope(),mdec->getFileDef(),mdec->argumentList(), - TRUE - ) - ) /* match found */ + if (mdef && mdec) { - MemberSDict *defDict = mdef->getReferencesMembers(); - MemberSDict *decDict = mdec->getReferencesMembers(); - if (defDict) - { - MemberSDict::Iterator msdi(*defDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) + LockingPtr mdefAl = mdef->argumentList(); + LockingPtr mdecAl = mdec->argumentList(); + if ( + matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdefAl.pointer(), + mdec->getOuterScope(),mdec->getFileDef(),mdecAl.pointer(), + TRUE + ) + ) /* match found */ + { + LockingPtr defDict = mdef->getReferencesMembers(); + LockingPtr decDict = mdec->getReferencesMembers(); + if (defDict!=0) { - if (decDict==0 || decDict->find(rmd->name())==0) + MemberSDict::Iterator msdi(*defDict); + MemberDef *rmd; + for (msdi.toFirst();(rmd=msdi.current());++msdi) { - mdec->addSourceReferences(rmd); + if (decDict==0 || decDict->find(rmd->name())==0) + { + mdec->addSourceReferences(rmd); + } } } - } - if (decDict) - { - MemberSDict::Iterator msdi(*decDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) + if (decDict!=0) { - if (defDict==0 || defDict->find(rmd->name())==0) + MemberSDict::Iterator msdi(*decDict); + MemberDef *rmd; + for (msdi.toFirst();(rmd=msdi.current());++msdi) { - mdef->addSourceReferences(rmd); + if (defDict==0 || defDict->find(rmd->name())==0) + { + mdef->addSourceReferences(rmd); + } } } - } - defDict = mdef->getReferencedByMembers(); - decDict = mdec->getReferencedByMembers(); - if (defDict) - { - MemberSDict::Iterator msdi(*defDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) + defDict = mdef->getReferencedByMembers(); + decDict = mdec->getReferencedByMembers(); + if (defDict!=0) { - if (decDict==0 || decDict->find(rmd->name())==0) + MemberSDict::Iterator msdi(*defDict); + MemberDef *rmd; + for (msdi.toFirst();(rmd=msdi.current());++msdi) { - mdec->addSourceReferencedBy(rmd); + if (decDict==0 || decDict->find(rmd->name())==0) + { + mdec->addSourceReferencedBy(rmd); + } } } - } - if (decDict) - { - MemberSDict::Iterator msdi(*decDict); - MemberDef *rmd; - for (msdi.toFirst();(rmd=msdi.current());++msdi) + if (decDict!=0) { - if (defDict==0 || defDict->find(rmd->name())==0) + MemberSDict::Iterator msdi(*decDict); + MemberDef *rmd; + for (msdi.toFirst();(rmd=msdi.current());++msdi) { - mdef->addSourceReferencedBy(rmd); + if (defDict==0 || defDict->find(rmd->name())==0) + { + mdef->addSourceReferencedBy(rmd); + } } } } @@ -3350,7 +3427,7 @@ static void transferRelatedFunctionDocumentation() { // find match between function declaration and definition for // related functions - MemberNameSDict::Iterator mnli(Doxygen::functionNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); MemberName *mn; for (mnli.toFirst();(mn=mnli.current());++mnli) { @@ -3361,17 +3438,19 @@ static void transferRelatedFunctionDocumentation() { //printf(" Function `%s'\n",md->name().data()); MemberName *rmn; - if ((rmn=Doxygen::memberNameSDict[md->name()])) // check if there is a member with the same name + if ((rmn=Doxygen::memberNameSDict->find(md->name()))) // check if there is a member with the same name { //printf(" Member name found\n"); MemberDef *rmd; MemberNameIterator rmni(*rmn); for (rmni.toFirst();(rmd=rmni.current());++rmni) // for each member with the same name { + LockingPtr mdAl = md->argumentList(); + LockingPtr rmdAl = rmd->argumentList(); //printf(" Member found: related=`%d'\n",rmd->isRelated()); if (rmd->isRelated() && // related function - matchArguments2( md->getOuterScope(), md->getFileDef(), md->argumentList(), - rmd->getOuterScope(),rmd->getFileDef(),rmd->argumentList(), + matchArguments2( md->getOuterScope(), md->getFileDef(), mdAl.pointer(), + rmd->getOuterScope(),rmd->getFileDef(),rmdAl.pointer(), TRUE ) ) @@ -3555,7 +3634,7 @@ static void findUsedClassesForClass(EntryNav *rootNav, found=TRUE; Debug::print(Debug::Classes,0," New used class `%s'\n", usedName.data()); - ClassDef *usedCd = Doxygen::hiddenClasses.find(usedName); + ClassDef *usedCd = Doxygen::hiddenClasses->find(usedName); if (usedCd==0) { usedCd = new ClassDef( @@ -3563,7 +3642,7 @@ static void findUsedClassesForClass(EntryNav *rootNav, usedName,ClassDef::Class); //printf("making %s a template argument!!!\n",usedCd->name().data()); usedCd->makeTemplateArgument(); - Doxygen::hiddenClasses.append(usedName,usedCd); + Doxygen::hiddenClasses->append(usedName,usedCd); } if (usedCd) { @@ -3598,7 +3677,7 @@ static void findUsedClassesForClass(EntryNav *rootNav, } if (!found && !type.isEmpty()) // used class is not documented in any scope { - ClassDef *usedCd = Doxygen::hiddenClasses.find(type); + ClassDef *usedCd = Doxygen::hiddenClasses->find(type); if (usedCd==0 && !Config_getBool("HIDE_UNDOC_RELATIONS")) { if (type.right(2)=="(*") // type is a function pointer @@ -3609,7 +3688,7 @@ static void findUsedClassesForClass(EntryNav *rootNav, usedCd = new ClassDef( masterCd->getDefFileName(),masterCd->getDefLine(), type,ClassDef::Class); - Doxygen::hiddenClasses.append(type,usedCd); + Doxygen::hiddenClasses->append(type,usedCd); } if (usedCd) { @@ -3719,7 +3798,7 @@ static bool findTemplateInstanceRelation(Entry *root, if (freshInstance) { Debug::print(Debug::Classes,0," found fresh instance '%s'!\n",instanceClass->name().data()); - Doxygen::classSDict.append(instanceClass->name(),instanceClass); + Doxygen::classSDict->append(instanceClass->name(),instanceClass); instanceClass->setTemplateBaseClassNames(templateNames); // search for new template instances caused by base classes of @@ -4037,23 +4116,23 @@ static bool findClassRelation( baseClass=0; if (isATemplateArgument) { - baseClass=Doxygen::hiddenClasses.find(baseClassName); + baseClass=Doxygen::hiddenClasses->find(baseClassName); if (baseClass==0) { baseClass=new ClassDef(root->fileName,root->startLine, baseClassName,ClassDef::Class); - Doxygen::hiddenClasses.append(baseClassName,baseClass); + Doxygen::hiddenClasses->append(baseClassName,baseClass); if (isArtificial) baseClass->setClassIsArtificial(); } } else { - baseClass=Doxygen::classSDict.find(baseClassName); + baseClass=Doxygen::classSDict->find(baseClassName); if (baseClass==0) { baseClass=new ClassDef(root->fileName,root->startLine, baseClassName,ClassDef::Class); - Doxygen::classSDict.append(baseClassName,baseClass); + Doxygen::classSDict->append(baseClassName,baseClass); if (isArtificial) baseClass->setClassIsArtificial(); } } @@ -4153,7 +4232,7 @@ static void findClassEntries(EntryNav *rootNav) */ static void findInheritedTemplateInstances() { - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE; QDictIterator edi(classEntries); EntryNav *rootNav; @@ -4176,7 +4255,7 @@ static void findInheritedTemplateInstances() static void findUsedTemplateInstances() { - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE; QDictIterator edi(classEntries); EntryNav *rootNav; @@ -4198,7 +4277,7 @@ static void findUsedTemplateInstances() static void computeClassRelations() { - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE; QDictIterator edi(classEntries); EntryNav *rootNav; @@ -4321,13 +4400,13 @@ static void computeTemplateClassRelations() static void computeMemberReferences() { - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { cd->computeAnchors(); } - FileName *fn=Doxygen::inputNameList.first(); + FileName *fn=Doxygen::inputNameList->first(); while (fn) { FileDef *fd=fn->first(); @@ -4336,15 +4415,15 @@ static void computeMemberReferences() fd->computeAnchors(); fd=fn->next(); } - fn=Doxygen::inputNameList.next(); + fn=Doxygen::inputNameList->next(); } - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd=0; for (nli.toFirst();(nd=nli.current());++nli) { nd->computeAnchors(); } - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { @@ -4356,7 +4435,7 @@ static void computeMemberReferences() static void addListReferences() { - MemberNameSDict::Iterator mnli(Doxygen::memberNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); MemberName *mn=0; for (mnli.toFirst();(mn=mnli.current());++mnli) { @@ -4367,7 +4446,7 @@ static void addListReferences() md->visited=FALSE; } } - MemberNameSDict::Iterator fnli(Doxygen::functionNameSDict); + MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); for (fnli.toFirst();(mn=fnli.current());++fnli) { MemberNameIterator mni(*mn); @@ -4378,13 +4457,13 @@ static void addListReferences() } } - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { cd->addListReferences(); } - FileName *fn=Doxygen::inputNameList.first(); + FileName *fn=Doxygen::inputNameList->first(); while (fn) { FileDef *fd=fn->first(); @@ -4393,15 +4472,15 @@ static void addListReferences() fd->addListReferences(); fd=fn->next(); } - fn=Doxygen::inputNameList.next(); + fn=Doxygen::inputNameList->next(); } - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd=0; for (nli.toFirst();(nd=nli.current());++nli) { nd->addListReferences(); } - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { @@ -4416,9 +4495,12 @@ static void addListReferences() { name = pd->getGroupDef()->getOutputFileBase().copy(); } - addRefItem(pd->xrefListItems(), - theTranslator->trPage(TRUE,TRUE), - name,pd->title()); + { + LockingPtr< QList > xrefItems = pd->xrefListItems(); + addRefItem(xrefItems.pointer(), + theTranslator->trPage(TRUE,TRUE), + name,pd->title()); + } } } @@ -4458,22 +4540,23 @@ static void addMemberDocs(EntryNav *rootNav, // TODO determine scope based on root not md Definition *rscope = md->getOuterScope(); + LockingPtr mdAl = md->argumentList(); if (al) { //printf("merging arguments (1) docs=%d\n",root->doc.isEmpty()); - mergeArguments(md->argumentList(),al,!root->doc.isEmpty()); + mergeArguments(mdAl.pointer(),al,!root->doc.isEmpty()); } else { if ( - matchArguments2( md->getOuterScope(), md->getFileDef(), md->argumentList(), + matchArguments2( md->getOuterScope(), md->getFileDef(), mdAl.pointer(), rscope,rfd,root->argList, TRUE ) ) { //printf("merging arguments (2)\n"); - mergeArguments(md->argumentList(),root->argList,!root->doc.isEmpty()); + mergeArguments(mdAl.pointer(),root->argList,!root->doc.isEmpty()); } } if (over_load) // the \overload keyword was used @@ -4614,10 +4697,10 @@ static bool findGlobalMember(EntryNav *rootNav, QCString n=name; if (n.isEmpty()) return FALSE; if (n.find("::")!=-1) return FALSE; // skip undefined class members - MemberName *mn=Doxygen::functionNameSDict[n+tempArg]; // look in function dictionary + MemberName *mn=Doxygen::functionNameSDict->find(n+tempArg); // look in function dictionary if (mn==0) { - mn=Doxygen::functionNameSDict[n]; // try without template arguments + mn=Doxygen::functionNameSDict->find(n); // try without template arguments } if (mn) // function name defined { @@ -4653,12 +4736,13 @@ static bool findGlobalMember(EntryNav *rootNav, QCString nsName = nd ? nd->name().data() : ""; NamespaceDef *rnd = 0; - if (!namespaceName.isEmpty()) rnd = Doxygen::namespaceSDict[namespaceName]; + if (!namespaceName.isEmpty()) rnd = Doxygen::namespaceSDict->find(namespaceName); + LockingPtr mdAl = md->argumentList(); bool matching= - (md->argumentList()==0 && root->argList->count()==0) || + (mdAl==0 && root->argList->count()==0) || md->isVariable() || md->isTypedef() || /* in case of function pointers */ - matchArguments2(md->getOuterScope(),md->getFileDef(),md->argumentList(), + matchArguments2(md->getOuterScope(),md->getFileDef(),mdAl.pointer(), rnd ? rnd : Doxygen::globalScope,fd,root->argList, FALSE); @@ -4967,7 +5051,7 @@ static void findMember(EntryNav *rootNav, { QCString joinedName = rootNav->parent()->name()+"::"+scopeName; if (!scopeName.isEmpty() && - (getClass(joinedName) || Doxygen::namespaceSDict[joinedName])) + (getClass(joinedName) || Doxygen::namespaceSDict->find(joinedName))) { scopeName = joinedName; } @@ -4990,7 +5074,7 @@ static void findMember(EntryNav *rootNav, for (nsdi.toFirst();(fnd=nsdi.current());++nsdi) { joinedName = fnd->name()+"::"+scopeName; - if (Doxygen::namespaceSDict[joinedName]) + if (Doxygen::namespaceSDict->find(joinedName)) { scopeName=joinedName; break; @@ -5151,11 +5235,11 @@ static void findMember(EntryNav *rootNav, } if (!funcTempList.isEmpty()) // try with member specialization { - mn=Doxygen::memberNameSDict[funcName+funcTempList]; + mn=Doxygen::memberNameSDict->find(funcName+funcTempList); } if (mn==0) // try without specialization { - mn=Doxygen::memberNameSDict[funcName]; + mn=Doxygen::memberNameSDict->find(funcName); } if (!isRelated && mn) // function name already found { @@ -5200,9 +5284,10 @@ static void findMember(EntryNav *rootNav, // get the template parameter lists found at the member declaration QList declTemplArgs; cd->getTemplateParameterLists(declTemplArgs); - if (md->templateArguments()) + LockingPtr templAl = md->templateArguments(); + if (templAl!=0) { - declTemplArgs.append(md->templateArguments()); + declTemplArgs.append(templAl.pointer()); } // get the template parameter lists found at the member definition @@ -5216,9 +5301,10 @@ static void findMember(EntryNav *rootNav, /* substitute the occurrences of class template names in the * argument list before matching */ + LockingPtr mdAl = md->argumentList(); if (declTemplArgs.count()>0 && defTemplArgs && declTemplArgs.count()==defTemplArgs->count() && - md->argumentList() + mdAl.pointer() ) { /* the function definition has template arguments @@ -5228,13 +5314,13 @@ static void findMember(EntryNav *rootNav, */ argList = new ArgumentList; substituteTemplatesInArgList(declTemplArgs,*defTemplArgs, - md->argumentList(),argList); + mdAl.pointer(),argList); substDone=TRUE; } else /* no template arguments, compare argument lists directly */ { - argList = md->argumentList(); + argList = mdAl.pointer(); } Debug::print(Debug::FindMembers,0, @@ -5245,7 +5331,7 @@ static void findMember(EntryNav *rootNav, bool matching= md->isVariable() || md->isTypedef() || // needed for function pointers - (md->argumentList()==0 && root->argList->count()==0) || + (mdAl.pointer()==0 && root->argList->count()==0) || matchArguments2( md->getClassDef(),md->getFileDef(),argList, cd,fd,root->argList, @@ -5303,8 +5389,9 @@ static void findMember(EntryNav *rootNav, //printf("cd->name()==%s className=%s\n",cd->name().data(),className.data()); if (cd!=0 && rightScopeMatch(cd->name(),className)) { - if (root->tArgLists && md->templateArguments() && - root->tArgLists->getLast()->count()<=md->templateArguments()->count()) + LockingPtr templAl = md->templateArguments(); + if (root->tArgLists && templAl!=0 && + root->tArgLists->getLast()->count()<=templAl->count()) { addMethodToClass(rootNav,cd,md->name(),isFriend); return; @@ -5340,9 +5427,10 @@ static void findMember(EntryNav *rootNav, ClassDef *cd=md->getClassDef(); if (cd!=0 && rightScopeMatch(cd->name(),className)) { - if (md->templateArguments()) + LockingPtr templAl = md->templateArguments(); + if (templAl!=0) { - warn_cont(" template %s\n",tempArgListToString(md->templateArguments()).data()); + warn_cont(" template %s\n",tempArgListToString(templAl.pointer()).data()); } warn_cont(" "); if (md->typeString()) @@ -5481,7 +5569,7 @@ static void findMember(EntryNav *rootNav, bool newMemberName=FALSE; bool isDefine=FALSE; { - MemberName *mn = Doxygen::functionNameSDict[funcName]; + MemberName *mn = Doxygen::functionNameSDict->find(funcName); if (mn) { MemberDef *md = mn->first(); @@ -5495,7 +5583,7 @@ static void findMember(EntryNav *rootNav, FileDef *fd=rootNav->fileDef(); - if ((mn=Doxygen::memberNameSDict[funcName])==0) + if ((mn=Doxygen::memberNameSDict->find(funcName))==0) { mn=new MemberName(funcName); newMemberName=TRUE; // we create a new member name @@ -5505,9 +5593,10 @@ static void findMember(EntryNav *rootNav, MemberDef *rmd=mn->first(); while (rmd && newMember) // see if we got another member with matching arguments { + LockingPtr rmdAl = rmd->argumentList(); newMember=newMember && - !matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmd->argumentList(), + !matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmdAl.pointer(), cd,fd,root->argList, TRUE); if (newMember) rmd=mn->next(); @@ -5554,15 +5643,16 @@ static void findMember(EntryNav *rootNav, bool found=FALSE; if (root->bodyLine==-1) { - MemberName *rmn=Doxygen::functionNameSDict[funcName]; + MemberName *rmn=Doxygen::functionNameSDict->find(funcName); if (rmn) { MemberDef *rmd=rmn->first(); while (rmd && !found) // see if we got another member with matching arguments { + LockingPtr rmdAl = rmd->argumentList(); // check for matching argument lists if ( - matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmd->argumentList(), + matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmdAl.pointer(), cd,fd,root->argList, TRUE) ) @@ -5614,7 +5704,7 @@ static void findMember(EntryNav *rootNav, { //Doxygen::memberNameList.append(mn); //Doxygen::memberNameDict.insert(funcName,mn); - Doxygen::memberNameSDict.append(funcName,mn); + Doxygen::memberNameSDict->append(funcName,mn); } } if (root->relatesDup) @@ -5672,7 +5762,7 @@ localObjCMethod: cd->insertMember(md); cd->insertUsedFile(root->fileName); md->setRefItems(root->sli); - if ((mn=Doxygen::memberNameSDict[root->name])) + if ((mn=Doxygen::memberNameSDict->find(root->name))) { mn->append(md); } @@ -5680,7 +5770,7 @@ localObjCMethod: { mn = new MemberName(root->name); mn->append(md); - Doxygen::memberNameSDict.append(root->name,mn); + Doxygen::memberNameSDict->append(root->name,mn); } } else @@ -5953,18 +6043,18 @@ static void findEnums(EntryNav *rootNav) { //printf("Enum `%s'::`%s'\n",cd->name(),name.data()); fd=0; - mnsd=&Doxygen::memberNameSDict; + mnsd=Doxygen::memberNameSDict; isGlobal=FALSE; } else if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') // found enum inside namespace { - mnsd=&Doxygen::functionNameSDict; + mnsd=Doxygen::functionNameSDict; isGlobal=TRUE; } else // found a global enum { fd=rootNav->fileDef(); - mnsd=&Doxygen::functionNameSDict; + mnsd=Doxygen::functionNameSDict; isGlobal=TRUE; } @@ -6001,8 +6091,8 @@ static void findEnums(EntryNav *rootNav) } //printf("definition=%s\n",md->definition()); defSet=TRUE; - nd->insertMember(md); md->setNamespace(nd); + nd->insertMember(md); } // even if we have already added the enum to a namespace, we still @@ -6017,8 +6107,8 @@ static void findEnums(EntryNav *rootNav) } if (fd) { - fd->insertMember(md); md->setFileDef(fd); + fd->insertMember(md); } } else if (cd) @@ -6064,7 +6154,7 @@ static void findEnums(EntryNav *rootNav) { //printf("e->name=%s isRelated=%d\n",e->name.data(),isRelated); MemberName *fmn=0; - MemberNameSDict *emnsd = isRelated ? &Doxygen::functionNameSDict : mnsd; + MemberNameSDict *emnsd = isRelated ? Doxygen::functionNameSDict : mnsd; if (!e->name().isEmpty() && (fmn=(*emnsd)[e->name()])) // get list of members with the same name as the field { @@ -6173,7 +6263,7 @@ static void findEnumDocumentation(EntryNav *rootNav) { //printf("Enum: scope=`%s' name=`%s'\n",cd->name(),name.data()); QCString className=cd->name().copy(); - MemberName *mn=Doxygen::memberNameSDict[name]; + MemberName *mn=Doxygen::memberNameSDict->find(name); if (mn) { MemberNameIterator mni(*mn); @@ -6227,7 +6317,7 @@ static void findEnumDocumentation(EntryNav *rootNav) else // enum outside class { //printf("Enum outside class: %s grpId=%d\n",name.data(),root->mGrpId); - MemberName *mn=Doxygen::functionNameSDict[name]; + MemberName *mn=Doxygen::functionNameSDict->find(name); if (mn) { MemberNameIterator mni(*mn); @@ -6284,9 +6374,9 @@ static void findDEV(const MemberNameSDict &mnsd) { if (md->isEnumerate()) // member is an enum { - MemberList *fmdl = md->enumFieldList(); + LockingPtr fmdl = md->enumFieldList(); int documentedEnumValues=0; - if (fmdl) // enum has values + if (fmdl!=0) // enum has values { MemberListIterator fmni(*fmdl); MemberDef *fmd; @@ -6307,8 +6397,8 @@ static void findDEV(const MemberNameSDict &mnsd) // values. static void findDocumentedEnumValues() { - findDEV(Doxygen::memberNameSDict); - findDEV(Doxygen::functionNameSDict); + findDEV(*Doxygen::memberNameSDict); + findDEV(*Doxygen::functionNameSDict); } @@ -6319,7 +6409,7 @@ static void findDocumentedEnumValues() static void computeMemberRelations() { - MemberNameSDict::Iterator mnli(Doxygen::memberNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); MemberName *mn; for ( ; (mn=mnli.current()) ; ++mnli ) // for each member name { @@ -6343,9 +6433,11 @@ static void computeMemberRelations() // argListToString(bmd->argumentList()).data(), // argListToString(md->argumentList()).data() // ); + LockingPtr bmdAl = bmd->argumentList(); + LockingPtr mdAl = md->argumentList(); if ( - matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),bmd->argumentList(), - md->getOuterScope(), md->getFileDef(), md->argumentList(), + matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),bmdAl.pointer(), + md->getOuterScope(), md->getFileDef(), mdAl.pointer(), TRUE ) ) @@ -6380,7 +6472,7 @@ static void computeMemberRelations() //static void computeClassImplUsageRelations() //{ // ClassDef *cd; -// ClassSDict::Iterator cli(Doxygen::classSDict); +// ClassSDict::Iterator cli(*Doxygen::classSDict); // for (;(cd=cli.current());++cli) // { // cd->determineImplUsageRelation(); @@ -6391,7 +6483,7 @@ static void computeMemberRelations() static void createTemplateInstanceMembers() { - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; // for each class for (cli.toFirst();(cd=cli.current());++cli) @@ -6419,14 +6511,14 @@ static void buildCompleteMemberLists() { ClassDef *cd; // merge members of categories into the class they extend - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); for (cli.toFirst();(cd=cli.current());++cli) { int i=cd->name().find('('); if (i!=-1) // it is an Objective-C category { QCString baseName=cd->name().left(i); - ClassDef *baseClass=Doxygen::classSDict.find(baseName); + ClassDef *baseClass=Doxygen::classSDict->find(baseName); if (baseClass) { //printf("*** merging members of category %s into %s\n", @@ -6458,9 +6550,9 @@ static void buildCompleteMemberLists() static void generateFileSources() { if (documentedHtmlFiles==0) return; - if (Doxygen::inputNameList.count()>0) + if (Doxygen::inputNameList->count()>0) { - FileNameListIterator fnli(Doxygen::inputNameList); + FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (;(fn=fnli.current());++fnli) { @@ -6490,9 +6582,9 @@ static void generateFileDocs() { if (documentedHtmlFiles==0) return; - if (Doxygen::inputNameList.count()>0) + if (Doxygen::inputNameList->count()>0) { - FileNameListIterator fnli(Doxygen::inputNameList); + FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (fnli.toFirst();(fn=fnli.current());++fnli) { @@ -6516,7 +6608,7 @@ static void generateFileDocs() static void addSourceReferences() { // add source references for class definitions - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { @@ -6527,7 +6619,7 @@ static void addSourceReferences() } } // add source references for namespace definitions - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd=0; for (nli.toFirst();(nd=nli.current());++nli) { @@ -6539,7 +6631,7 @@ static void addSourceReferences() } // add source references for member names - MemberNameSDict::Iterator mnli(Doxygen::memberNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); MemberName *mn=0; for (mnli.toFirst();(mn=mnli.current());++mnli) { @@ -6560,7 +6652,7 @@ static void addSourceReferences() } } } - MemberNameSDict::Iterator fnli(Doxygen::functionNameSDict); + MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); for (fnli.toFirst();(mn=fnli.current());++fnli) { MemberNameIterator mni(*mn); @@ -6647,15 +6739,15 @@ static void generateClassDocs() msg("Generating example index...\n"); } - generateClassList(Doxygen::classSDict); - generateClassList(Doxygen::hiddenClasses); + generateClassList(*Doxygen::classSDict); + generateClassList(*Doxygen::hiddenClasses); } //---------------------------------------------------------------------------- static void inheritDocumentation() { - MemberNameSDict::Iterator mnli(Doxygen::memberNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); MemberName *mn; //int count=0; for (;(mn=mnli.current());++mnli) @@ -6693,7 +6785,7 @@ static void inheritDocumentation() static void combineUsingRelations() { // for each file - FileNameListIterator fnli(Doxygen::inputNameList); + FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (fnli.toFirst();(fn=fnli.current());++fnli) { @@ -6715,7 +6807,7 @@ static void combineUsingRelations() } // for each namespace - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; for (nli.toFirst() ; (nd=nli.current()) ; ++nli ) { @@ -6732,14 +6824,14 @@ static void combineUsingRelations() static void addMembersToMemberGroup() { // for each class - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; for ( ; (cd=cli.current()) ; ++cli ) { cd->addMembersToMemberGroup(); } // for each file - FileName *fn=Doxygen::inputNameList.first(); + FileName *fn=Doxygen::inputNameList->first(); while (fn) { FileDef *fd=fn->first(); @@ -6748,17 +6840,17 @@ static void addMembersToMemberGroup() fd->addMembersToMemberGroup(); fd=fn->next(); } - fn=Doxygen::inputNameList.next(); + fn=Doxygen::inputNameList->next(); } // for each namespace - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; for ( ; (nd=nli.current()) ; ++nli ) { nd->addMembersToMemberGroup(); } // for each group - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { @@ -6771,14 +6863,14 @@ static void addMembersToMemberGroup() static void distributeMemberGroupDocumentation() { // for each class - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; for ( ; (cd=cli.current()) ; ++cli ) { cd->distributeMemberGroupDocumentation(); } // for each file - FileName *fn=Doxygen::inputNameList.first(); + FileName *fn=Doxygen::inputNameList->first(); while (fn) { FileDef *fd=fn->first(); @@ -6787,17 +6879,17 @@ static void distributeMemberGroupDocumentation() fd->distributeMemberGroupDocumentation(); fd=fn->next(); } - fn=Doxygen::inputNameList.next(); + fn=Doxygen::inputNameList->next(); } // for each namespace - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; for ( ; (nd=nli.current()) ; ++nli ) { nd->distributeMemberGroupDocumentation(); } // for each group - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { @@ -6810,14 +6902,14 @@ static void distributeMemberGroupDocumentation() static void findSectionsInDocumentation() { // for each class - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; for ( ; (cd=cli.current()) ; ++cli ) { cd->findSectionsInDocumentation(); } // for each file - FileName *fn=Doxygen::inputNameList.first(); + FileName *fn=Doxygen::inputNameList->first(); while (fn) { FileDef *fd=fn->first(); @@ -6826,17 +6918,17 @@ static void findSectionsInDocumentation() fd->findSectionsInDocumentation(); fd=fn->next(); } - fn=Doxygen::inputNameList.next(); + fn=Doxygen::inputNameList->next(); } // for each namespace - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; for ( ; (nd=nli.current()) ; ++nli ) { nd->findSectionsInDocumentation(); } // for each group - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { @@ -6869,7 +6961,7 @@ static void flushCachedTemplateRelations() } // remove all cached typedef resolutions whose target is a // template class as this may now be a template instance - MemberNameSDict::Iterator fnli(Doxygen::functionNameSDict); + MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); MemberName *fn; for (;(fn=fnli.current());++fnli) // for each global function name { @@ -6884,7 +6976,7 @@ static void flushCachedTemplateRelations() } } } - MemberNameSDict::Iterator mnli(Doxygen::memberNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); for (;(fn=mnli.current());++mnli) // for each class method name { MemberNameIterator mni(*fn); @@ -6925,7 +7017,7 @@ static void findDefineDocumentation(EntryNav *rootNav) md->setFileDef(rootNav->parent()->fileDef()); //printf("Adding member=%s\n",md->name().data()); MemberName *mn; - if ((mn=Doxygen::functionNameSDict[root->name])) + if ((mn=Doxygen::functionNameSDict->find(root->name))) { mn->append(md); } @@ -6933,12 +7025,10 @@ static void findDefineDocumentation(EntryNav *rootNav) { mn = new MemberName(root->name); mn->append(md); - //Doxygen::functionNameDict.insert(root->name,mn); - //Doxygen::functionNameList.append(mn); - Doxygen::functionNameSDict.append(root->name,mn); + Doxygen::functionNameSDict->append(root->name,mn); } } - MemberName *mn=Doxygen::functionNameSDict[root->name]; + MemberName *mn=Doxygen::functionNameSDict->find(root->name); if (mn) { int count=0; @@ -7067,7 +7157,7 @@ static void findDirDocumentation(EntryNav *rootNav) normalizedName+='/'; } DirDef *dir,*matchingDir=0; - SDict::Iterator sdi(Doxygen::directories); + SDict::Iterator sdi(*Doxygen::directories); for (sdi.toFirst();(dir=sdi.current());++sdi) { //printf("Dir: %s<->%s\n",dir->name().data(),normalizedName.data()); @@ -7373,6 +7463,7 @@ static void generateExampleDocs() for (pdi.toFirst();(pd=pdi.current());++pdi) { msg("Generating docs for example %s...\n",pd->name().data()); + resetCCodeParserState(); QCString n=pd->getOutputFileBase(); startFile(*outputList,n,n,pd->name()); startTitle(*outputList,n); @@ -7397,7 +7488,7 @@ static void generateExampleDocs() static void generateGroupDocs() { - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { @@ -7432,7 +7523,7 @@ static void generateNamespaceDocs() { writeNamespaceIndex(*outputList); - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; // for each namespace... for (;(nd=nli.current());++nli) @@ -8284,10 +8375,9 @@ void initDoxygen() setlocale(LC_ALL,""); setlocale(LC_NUMERIC,"C"); #endif - Doxygen::symbolMap = new QDict(1000); - //Doxygen::symbolMap->setAutoDelete(TRUE); - Doxygen::globalScope = new NamespaceDef("",1,""); + //Doxygen::symbolMap->setAutoDelete(TRUE); + Doxygen::runningTime.start(); initPreprocessor(); @@ -8297,20 +8387,10 @@ void initDoxygen() // register any additional parsers here... - Doxygen::sectionDict.setAutoDelete(TRUE); - Doxygen::inputNameList.setAutoDelete(TRUE); - Doxygen::memberNameSDict.setAutoDelete(TRUE); - Doxygen::functionNameSDict.setAutoDelete(TRUE); - Doxygen::hiddenClasses.setAutoDelete(TRUE); - Doxygen::classSDict.setAutoDelete(TRUE); - Doxygen::pageSDict->setAutoDelete(TRUE); - Doxygen::exampleSDict->setAutoDelete(TRUE); - excludeNameDict.setAutoDelete(TRUE); - Doxygen::memGrpInfoDict.setAutoDelete(TRUE); - Doxygen::tagDestinationDict.setAutoDelete(TRUE); - Doxygen::lookupCache.setAutoDelete(TRUE); - Doxygen::directories.setAutoDelete(TRUE); - Doxygen::dirRelations.setAutoDelete(TRUE); + + initClassMemberIndices(); + initNamespaceMemberIndices(); + initFileMemberIndices(); } void cleanUpDoxygen() @@ -8327,30 +8407,39 @@ void cleanUpDoxygen() delete Doxygen::xrefLists; delete Doxygen::parserManager; cleanUpPreprocessor(); - Config::deleteInstance(); - QTextCodec::deleteAllCodecs(); delete theTranslator; delete outputList; Mappers::freeMappers(); codeFreeScanner(); - // iterate through Doxygen::symbolMap and delete all - // DefinitionList objects, since they have no owner - QDictIterator dli(*Doxygen::symbolMap); - DefinitionIntf *di; - for (dli.toFirst();(di=dli.current());) + if (Doxygen::symbolMap) { - if (di->definitionType()==DefinitionIntf::TypeSymbolList) + // iterate through Doxygen::symbolMap and delete all + // DefinitionList objects, since they have no owner + QDictIterator dli(*Doxygen::symbolMap); + DefinitionIntf *di; + for (dli.toFirst();(di=dli.current());) { - DefinitionIntf *tmp = Doxygen::symbolMap->take(dli.currentKey()); - delete (DefinitionList *)tmp; - } - else - { - ++dli; - } - } + if (di->definitionType()==DefinitionIntf::TypeSymbolList) + { + DefinitionIntf *tmp = Doxygen::symbolMap->take(dli.currentKey()); + delete (DefinitionList *)tmp; + } + else + { + ++dli; + } + } + } + delete Doxygen::inputNameList; + delete Doxygen::memberNameSDict; + delete Doxygen::functionNameSDict; + delete Doxygen::groupSDict; + delete Doxygen::classSDict; + delete Doxygen::hiddenClasses; + delete Doxygen::namespaceSDict; + delete Doxygen::directories; //delete Doxygen::symbolMap; <- we cannot do this unless all static lists // (such as Doxygen::namespaceSDict) @@ -8676,12 +8765,85 @@ void checkConfiguration() void parseInput() { - Doxygen::inputNameDict = new FileNameDict(10007); - Doxygen::includeNameDict = new FileNameDict(10007); - Doxygen::exampleNameDict = new FileNameDict(1009); + /************************************************************************** + * Make sure the output directory exists + **************************************************************************/ + QCString &outputDirectory = Config_getString("OUTPUT_DIRECTORY"); + if (outputDirectory.isEmpty()) + { + outputDirectory=QDir::currentDirPath(); + } + else + { + QDir dir(outputDirectory); + if (!dir.exists()) + { + dir.setPath(QDir::currentDirPath()); + if (!dir.mkdir(outputDirectory)) + { + err("Error: tag OUTPUT_DIRECTORY: Output directory `%s' does not " + "exist and cannot be created\n",outputDirectory.data()); + cleanUpDoxygen(); + exit(1); + } + else if (!Config_getBool("QUIET")) + { + err("Notice: Output directory `%s' does not exist. " + "I have created it for you.\n", outputDirectory.data()); + } + dir.cd(outputDirectory); + } + outputDirectory=dir.absPath(); + } + + /************************************************************************** + * Initialize global lists and dictionaries + **************************************************************************/ + + Doxygen::symbolMap = new QDict(1000); + Doxygen::symbolCache = new ObjCache(15); // 15 -> room for 32768 elements, + // ~1.0 MByte "overhead" + Doxygen::symbolStorage = new Store; + + if (Doxygen::symbolStorage->open(outputDirectory+"/doxygen_objdb.tmp")==-1) + { + err("Failed to open temporary file %s\n",(outputDirectory+"/doxygen_objdb.tmp").data()); + exit(1); + } + + Doxygen::inputNameList = new FileNameList; + Doxygen::inputNameList->setAutoDelete(TRUE); + Doxygen::memberNameSDict = new MemberNameSDict(10000); + Doxygen::memberNameSDict->setAutoDelete(TRUE); + Doxygen::functionNameSDict = new MemberNameSDict(10000); + Doxygen::functionNameSDict->setAutoDelete(TRUE); + Doxygen::groupSDict = new GroupSDict(17); + Doxygen::groupSDict->setAutoDelete(TRUE); + Doxygen::globalScope = new NamespaceDef("",1,""); + Doxygen::namespaceSDict = new NamespaceSDict(20); + Doxygen::namespaceSDict->setAutoDelete(TRUE); + Doxygen::classSDict = new ClassSDict(1009); + Doxygen::classSDict->setAutoDelete(TRUE); + Doxygen::hiddenClasses = new ClassSDict(257); + Doxygen::hiddenClasses->setAutoDelete(TRUE); + Doxygen::directories = new DirSDict(17); + Doxygen::directories->setAutoDelete(TRUE); + Doxygen::pageSDict = new PageSDict(1009); // all doc pages + Doxygen::pageSDict->setAutoDelete(TRUE); + Doxygen::exampleSDict = new PageSDict(1009); // all examples + Doxygen::exampleSDict->setAutoDelete(TRUE); + Doxygen::inputNameDict = new FileNameDict(10007); + Doxygen::includeNameDict = new FileNameDict(10007); + Doxygen::exampleNameDict = new FileNameDict(1009); Doxygen::exampleNameDict->setAutoDelete(TRUE); - Doxygen::imageNameDict = new FileNameDict(257); - Doxygen::dotFileNameDict = new FileNameDict(257); + Doxygen::imageNameDict = new FileNameDict(257); + Doxygen::dotFileNameDict = new FileNameDict(257); + Doxygen::sectionDict.setAutoDelete(TRUE); + Doxygen::memGrpInfoDict.setAutoDelete(TRUE); + Doxygen::tagDestinationDict.setAutoDelete(TRUE); + Doxygen::lookupCache.setAutoDelete(TRUE); + Doxygen::dirRelations.setAutoDelete(TRUE); + excludeNameDict.setAutoDelete(TRUE); /************************************************************************** * Initialize some global constants @@ -8788,7 +8950,7 @@ void parseInput() inputSize+=readFileOrDirectory( path, - &Doxygen::inputNameList, + Doxygen::inputNameList, Doxygen::inputNameDict, &excludeNameDict, &Config_getList("FILE_PATTERNS"), @@ -8820,34 +8982,6 @@ void parseInput() * Check/create output directorties * **************************************************************************/ - QCString &outputDirectory = Config_getString("OUTPUT_DIRECTORY"); - if (outputDirectory.isEmpty()) - { - outputDirectory=QDir::currentDirPath(); - } - else - { - QDir dir(outputDirectory); - if (!dir.exists()) - { - dir.setPath(QDir::currentDirPath()); - if (!dir.mkdir(outputDirectory)) - { - err("Error: tag OUTPUT_DIRECTORY: Output directory `%s' does not " - "exist and cannot be created\n",outputDirectory.data()); - cleanUpDoxygen(); - exit(1); - } - else if (!Config_getBool("QUIET")) - { - err("Notice: Output directory `%s' does not exist. " - "I have created it for you.\n", outputDirectory.data()); - } - dir.cd(outputDirectory); - } - outputDirectory=dir.absPath(); - } - QCString &htmlOutput = Config_getString("HTML_OUTPUT"); bool &generateHtml = Config_getBool("GENERATE_HTML"); if (htmlOutput.isEmpty() && generateHtml) @@ -8949,10 +9083,11 @@ void parseInput() * Handle Tag Files * **************************************************************************/ - g_storage.setName(outputDirectory+"/doxygen_entrydb.tmp"); - if (!g_storage.open(IO_WriteOnly)) + g_storage = new FileStorage; + g_storage->setName(outputDirectory+"/doxygen_entrydb.tmp"); + if (!g_storage->open(IO_WriteOnly)) { - err("Failed to create temporary storage file %s/doxygen_entrydb.tmp", + err("Failed to create temporary storage file %s/doxygen_entrydb.tmp\n", outputDirectory.data()); exit(1); } @@ -8975,8 +9110,8 @@ void parseInput() **************************************************************************/ parseFiles(root,rootNav); - g_storage.close(); - if (!g_storage.open(IO_ReadOnly)) + g_storage->close(); + if (!g_storage->open(IO_ReadOnly)) { err("Failed to open temporary storage file %s/doxygen_entrydb.tmp for reading", outputDirectory.data()); @@ -9014,7 +9149,6 @@ void parseInput() buildNamespaceList(rootNav); findUsingDirectives(rootNav); - msg("Building file list...\n"); buildFileList(rootNav); //generateFileTree(); @@ -9101,14 +9235,16 @@ void parseInput() findGroupScope(rootNav); msg("Sorting lists...\n"); - Doxygen::memberNameSDict.sort(); - Doxygen::functionNameSDict.sort(); - Doxygen::hiddenClasses.sort(); - Doxygen::classSDict.sort(); + Doxygen::memberNameSDict->sort(); + Doxygen::functionNameSDict->sort(); + Doxygen::hiddenClasses->sort(); + Doxygen::classSDict->sort(); msg("Freeing entry tree\n"); delete rootNav; - g_storage.close(); + g_storage->close(); + delete g_storage; + g_storage=0; QDir thisDir; thisDir.remove(outputDirectory+"/doxygen_entrydb.tmp"); @@ -9143,7 +9279,7 @@ void parseInput() // compute the shortest possible names of all files // without loosing the uniqueness of the file names. msg("Generating disk names...\n"); - Doxygen::inputNameList.generateDiskNames(); + Doxygen::inputNameList->generateDiskNames(); msg("Adding source references...\n"); addSourceReferences(); @@ -9445,7 +9581,23 @@ void generateOutput() Doxygen::sysElapsedTime ); } + + /************************************************************************** + * Start cleaning up * + **************************************************************************/ + + //Doxygen::symbolCache->printStats(); + //Doxygen::symbolStorage->printStats(); cleanUpDoxygen(); + finializeDocParser(); + Doxygen::symbolStorage->close(); + QDir thisDir; + thisDir.remove(Config_getString("OUTPUT_DIRECTORY")+"/doxygen_objdb.tmp"); + Config::deleteInstance(); + QTextCodec::deleteAllCodecs(); + delete Doxygen::symbolCache; + delete Doxygen::symbolMap; + delete Doxygen::symbolStorage; } diff --git a/src/doxygen.h b/src/doxygen.h index 88df1e5..43ee18b 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -43,6 +43,8 @@ class PageDef; class SearchIndex; class DirDef; class ParserManager; +class ObjCache; +class Store; typedef QList StringList; typedef QDict FileDict; @@ -73,8 +75,8 @@ extern QCString spaces; class Doxygen { public: - static ClassSDict classSDict; - static ClassSDict hiddenClasses; + static ClassSDict *classSDict; + static ClassSDict *hiddenClasses; static PageSDict *exampleSDict; static PageSDict *pageSDict; static PageDef *mainPage; @@ -82,20 +84,17 @@ class Doxygen static FileNameDict *includeNameDict; static FileNameDict *exampleNameDict; static FileNameDict *inputNameDict; - static FileNameList inputNameList; + static FileNameList *inputNameList; static FileNameDict *imageNameDict; static FileNameDict *dotFileNameDict; static QStrList tagfileList; - static MemberNameSDict memberNameSDict; - static MemberNameSDict functionNameSDict; - static FileList fileList; - static FileDict fileDict; - static ClassDef unrelatedClass; + static MemberNameSDict *memberNameSDict; + static MemberNameSDict *functionNameSDict; static QTextStream tagFile; static SectionDict sectionDict; static StringDict namespaceAliasDict; - static GroupSDict groupSDict; - static NamespaceSDict namespaceSDict; + static GroupSDict *groupSDict; + static NamespaceSDict *namespaceSDict; static FormulaList formulaList; static FormulaDict formulaDict; static FormulaDict formulaNameDict; @@ -114,10 +113,12 @@ class Doxygen static bool outputToWizard; static QDict *htmlDirMap; static QCache lookupCache; - static DirSDict directories; + static DirSDict *directories; static SDict dirRelations; static ParserManager *parserManager; static bool suppressDocWarnings; + static ObjCache *symbolCache; + static Store *symbolStorage; }; void initDoxygen(); diff --git a/src/entry.cpp b/src/entry.cpp index 32e8027..34d7241 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -15,8 +15,10 @@ * */ +#include #include #include "entry.h" +#include "marshal.h" #include "util.h" #include "section.h" @@ -61,10 +63,10 @@ Entry::Entry(const Entry &e) m_parent = e.m_parent; type = e.type.copy(); name = e.name.copy(); - args = e.args.copy(); + args = e.args; bitfields = e.bitfields.copy(); exception = e.exception.copy(); - program = e.program.copy(); + program = e.program; includeFile = e.includeFile.copy(); includeName = e.includeFile.copy(); doc = e.doc.copy(); @@ -261,7 +263,7 @@ int Entry::getSize() return sizeof(Entry); } -void Entry::createSubtreeIndex(EntryNav *nav,QFile &storage,FileDef *fd) +void Entry::createSubtreeIndex(EntryNav *nav,FileStorage *storage,FileDef *fd) { EntryNav *childNav = new EntryNav(nav,this); nav->addChild(childNav); @@ -281,7 +283,7 @@ void Entry::createSubtreeIndex(EntryNav *nav,QFile &storage,FileDef *fd) } } -void Entry::createNavigationIndex(EntryNav *rootNav,QFile &storage,FileDef *fd) +void Entry::createNavigationIndex(EntryNav *rootNav,FileStorage *storage,FileDef *fd) { //printf("createNavigationIndex(%p) sublist=%p\n",this,m_sublist); if (m_sublist) @@ -333,323 +335,9 @@ void Entry::addSpecialListItem(const char *listName,int itemId) //------------------------------------------------------------------ -#define NULL_LIST 0xffffffff - -void marshalInt(QFile &f,int v) -{ - uchar b[4]; - b[0]=((uint)v)>>24; - b[1]=(((uint)v)>>16)&0xff; - b[2]=(((uint)v)>>8)&0xff; - b[3]=v&0xff; - f.writeBlock((const char *)b,4); -} - -void marshalUInt(QFile &f,uint v) -{ - uchar b[4]; - b[0]=v>>24; - b[1]=(v>>16)&0xff; - b[2]=(v>>8)&0xff; - b[3]=v&0xff; - f.writeBlock((const char *)b,4); -} - -void marshalBool(QFile &f,bool b) -{ - char c = b; - f.writeBlock(&c,sizeof(char)); -} - -void marshalQCString(QFile &f,const QCString &s) -{ - uint l=s.length(); - marshalUInt(f,l); - if (l>0) f.writeBlock(s.data(),l); -} - -void marshalArgumentList(QFile &f,ArgumentList *argList) -{ - if (argList==0) - { - marshalUInt(f,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(f,argList->count()); - ArgumentListIterator ali(*argList); - Argument *a; - for (ali.toFirst();(a=ali.current());++ali) - { - marshalQCString(f,a->attrib); - marshalQCString(f,a->type); - marshalQCString(f,a->canType); - marshalQCString(f,a->name); - marshalQCString(f,a->array); - marshalQCString(f,a->defval); - marshalQCString(f,a->docs); - } - marshalBool(f,argList->constSpecifier); - marshalBool(f,argList->volatileSpecifier); - marshalBool(f,argList->pureSpecifier); - } -} - -void marshalArgumentLists(QFile &f,QList *argLists) -{ - if (argLists==0) - { - marshalUInt(f,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(f,argLists->count()); - QListIterator ali(*argLists); - ArgumentList *al; - for (ali.toFirst();(al=ali.current());++ali) - { - marshalArgumentList(f,al); - } - } -} - -void marshalBaseInfoList(QFile &f, QList *baseList) -{ - if (baseList==0) - { - marshalUInt(f,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(f,baseList->count()); - QListIterator bli(*baseList); - BaseInfo *bi; - for (bli.toFirst();(bi=bli.current());++bli) - { - marshalQCString(f,bi->name); - marshalInt(f,(int)bi->prot); - marshalInt(f,(int)bi->virt); - } - } -} - -void marshalGroupingList(QFile &f, QList *groups) -{ - if (groups==0) - { - marshalUInt(f,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(f,groups->count()); - QListIterator gli(*groups); - Grouping *g; - for (gli.toFirst();(g=gli.current());++gli) - { - marshalQCString(f,g->groupname); - marshalInt(f,(int)g->pri); - } - } -} - -void marshalSectionInfoList(QFile &f, QList *anchors) -{ - if (anchors==0) - { - marshalUInt(f,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(f,anchors->count()); - QListIterator sli(*anchors); - SectionInfo *si; - for (sli.toFirst();(si=sli.current());++sli) - { - marshalQCString(f,si->label); - marshalQCString(f,si->title); - marshalQCString(f,si->ref); - marshalInt(f,(int)si->type); - marshalQCString(f,si->fileName); - } - } -} - -void marshalItemInfoList(QFile &f, QList *sli) -{ - if (sli==0) - { - marshalUInt(f,NULL_LIST); // null pointer representation - } - else - { - marshalUInt(f,sli->count()); - QListIterator liii(*sli); - ListItemInfo *lii; - for (liii.toFirst();(lii=liii.current());++liii) - { - marshalQCString(f,lii->type); - marshalInt(f,lii->itemId); - } - } -} - -//------------------------------------------------------------------ - -int unmarshalInt(QFile &f) -{ - uchar b[4]; - f.readBlock((char *)b,4); - int result=(int)((((uint)b[0])<<24)+((uint)b[1]<<16)+((uint)b[2]<<8)+(uint)b[3]); - //printf("unmarshalInt: %x %x %x %x: %x offset=%llx\n",b[0],b[1],b[2],b[3],result,f.pos()); - return result; -} - -uint unmarshalUInt(QFile &f) -{ - uchar b[4]; - f.readBlock((char *)b,4); - uint result=(((uint)b[0])<<24)+((uint)b[1]<<16)+((uint)b[2]<<8)+(uint)b[3]; - //printf("unmarshalUInt: %x %x %x %x: %x offset=%llx\n",b[0],b[1],b[2],b[3],result,f.pos()); - return result; -} - -bool unmarshalBool(QFile &f) -{ - char result; - f.readBlock(&result,sizeof(result)); - //printf("unmarshalBool: %x offset=%llx\n",result,f.pos()); - return result; -} - -QCString unmarshalQCString(QFile &f) -{ - uint len = unmarshalUInt(f); - //printf("unmarshalQCString: len=%d offset=%llx\n",len,f.pos()); - QCString result(len+1); - result.at(len)='\0'; - if (len>0) - { - f.readBlock(result.data(),len); - } - //printf("unmarshalQCString: result=%s\n",result.data()); - return result; -} - -ArgumentList *unmarshalArgumentList(QFile &f) -{ - uint i; - uint count = unmarshalUInt(f); - if (count==NULL_LIST) return 0; // null list - ArgumentList *result = new ArgumentList; - result->setAutoDelete(TRUE); - //printf("unmarshalArgumentList: %d\n",count); - for (i=0;iattrib = unmarshalQCString(f); - a->type = unmarshalQCString(f); - a->canType = unmarshalQCString(f); - a->name = unmarshalQCString(f); - a->array = unmarshalQCString(f); - a->defval = unmarshalQCString(f); - a->docs = unmarshalQCString(f); - result->append(a); - } - result->constSpecifier = unmarshalBool(f); - result->volatileSpecifier = unmarshalBool(f); - result->pureSpecifier = unmarshalBool(f); - return result; -} - -QList *unmarshalArgumentLists(QFile &f) -{ - uint i; - uint count = unmarshalUInt(f); - if (count==NULL_LIST) return 0; // null list - QList *result = new QList; - result->setAutoDelete(TRUE); - //printf("unmarshalArgumentLists: %d\n",count); - for (i=0;iappend(unmarshalArgumentList(f)); - } - return result; -} - -QList *unmarshalBaseInfoList(QFile &f) -{ - uint i; - uint count = unmarshalUInt(f); - if (count==NULL_LIST) return 0; // null list - QList *result = new QList; - result->setAutoDelete(TRUE); - for (i=0;iappend(new BaseInfo(name,prot,virt)); - } - return result; -} - -QList *unmarshalGroupingList(QFile &f) -{ - uint i; - uint count = unmarshalUInt(f); - if (count==NULL_LIST) return 0; // null list - QList *result = new QList; - result->setAutoDelete(TRUE); - for (i=0;iappend(new Grouping(name,prio)); - } - return result; -} - -QList *unmarshalSectionInfoList(QFile &f) -{ - uint i; - uint count = unmarshalUInt(f); - if (count==NULL_LIST) return 0; // null list - QList *result = new QList; - result->setAutoDelete(TRUE); - for (i=0;iappend(new SectionInfo(fileName,label,title,type,ref)); - } - return result; -} - -QList *unmarshalItemInfoList(QFile &f) -{ - uint i; - uint count = unmarshalUInt(f); - if (count==NULL_LIST) return 0; // null list - QList *result = new QList; - result->setAutoDelete(TRUE); - for (i=0;itype = unmarshalQCString(f); - lii->itemId = unmarshalInt(f); - result->append(lii); - } - return result; -} - -//------------------------------------------------------------------ - #define HEADER ('D'<<24)+('O'<<16)+('X'<<8)+'!' -bool saveEntry(Entry *e,QFile &f) +static bool saveEntry(Entry *e,FileStorage *f) { marshalUInt(f,HEADER); marshalInt(f,(int)e->protection); @@ -667,8 +355,8 @@ bool saveEntry(Entry *e,QFile &f) marshalQCString(f,e->bitfields); marshalArgumentList(f,e->argList); marshalArgumentLists(f,e->tArgLists); - marshalQCString(f,e->program); - marshalQCString(f,e->initializer); + marshalQGString(f,e->program); + marshalQGString(f,e->initializer); marshalQCString(f,e->includeFile); marshalQCString(f,e->includeName); marshalQCString(f,e->doc); @@ -701,7 +389,7 @@ bool saveEntry(Entry *e,QFile &f) return TRUE; } -bool loadEntry(Entry *e,QFile &f) +static bool loadEntry(Entry *e,FileStorage *f) { uint header=unmarshalUInt(f); if (header!=HEADER) @@ -725,8 +413,8 @@ bool loadEntry(Entry *e,QFile &f) delete e->argList; e->argList = unmarshalArgumentList(f); e->tArgLists = unmarshalArgumentLists(f); - e->program = unmarshalQCString(f); - e->initializer = unmarshalQCString(f); + e->program = unmarshalQGString(f); + e->initializer = unmarshalQGString(f); e->includeFile = unmarshalQCString(f); e->includeName = unmarshalQCString(f); e->doc = unmarshalQCString(f); @@ -805,7 +493,7 @@ void EntryNav::addChild(EntryNav *e) m_subList->append(e); } -bool EntryNav::loadEntry(QFile &storage) +bool EntryNav::loadEntry(FileStorage *storage) { if (m_noLoad) { @@ -829,7 +517,7 @@ bool EntryNav::loadEntry(QFile &storage) //} //m_info->parent = 0; //printf("load entry: seek to %llx\n",m_offset); - if (!storage.seek(m_offset)) + if (!storage->seek(m_offset)) { //printf("seek failed!\n"); return FALSE; @@ -837,9 +525,9 @@ bool EntryNav::loadEntry(QFile &storage) return ::loadEntry(m_info,storage); } -bool EntryNav::saveEntry(Entry *e,QFile &storage) +bool EntryNav::saveEntry(Entry *e,FileStorage *storage) { - m_offset = storage.pos(); + m_offset = storage->pos(); //printf("EntryNav::saveEntry offset=%llx\n",m_offset); return ::saveEntry(e,storage); } diff --git a/src/entry.h b/src/entry.h index 7cf6615..50100ae 100644 --- a/src/entry.h +++ b/src/entry.h @@ -21,10 +21,13 @@ #include "qtbc.h" #include +#include + struct SectionInfo; class QFile; class EntryNav; class FileDef; +class FileStorage; enum Protection { Public, Protected, Private, Package } ; enum Specifier { Normal, Virtual, Pure } ; @@ -262,7 +265,7 @@ class Entry ~Entry(); int getSize(); void addSpecialListItem(const char *listName,int index); - void createNavigationIndex(EntryNav *rootNav,QFile &storage,FileDef *fd); + void createNavigationIndex(EntryNav *rootNav,FileStorage *storage,FileDef *fd); // while parsing a file these function can be used to navigate/build the tree void setParent(Entry *parent) { m_parent = parent; } @@ -300,8 +303,8 @@ class Entry QCString bitfields; //!< member's bit fields ArgumentList *argList; //!< member arguments as a list QList *tArgLists; //!< template argument declarations - QCString program; //!< the program text - QCString initializer; //!< initial value (for variables) + QGString program; //!< the program text + QGString initializer; //!< initial value (for variables) QCString includeFile; //!< include file (2 arg of \\class, must be unique) QCString includeName; //!< include name (3 arg of \\class) QCString doc; //!< documentation block (partly parsed) @@ -361,7 +364,7 @@ class Entry } private: - void createSubtreeIndex(EntryNav *nav,QFile &storage,FileDef *fd); + void createSubtreeIndex(EntryNav *nav,FileStorage *storage,FileDef *fd); Entry *m_parent; //!< parent node in the tree QList *m_sublist; //!< entries that are children of this one Entry &operator=(const Entry &); @@ -373,8 +376,8 @@ class EntryNav EntryNav(EntryNav *parent,Entry *e); ~EntryNav(); void addChild(EntryNav *); - bool loadEntry(QFile &storage); - bool saveEntry(Entry *e,QFile &storage); + bool loadEntry(FileStorage *storage); + bool saveEntry(Entry *e,FileStorage *storage); void setEntry(Entry *e); void releaseEntry(); void changeSection(int section) { m_section = section; } diff --git a/src/filedef.cpp b/src/filedef.cpp index dfa5cc4..c43cd72 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -58,8 +58,6 @@ class DevNullCodeDocInterface : public CodeOutputInterface virtual void linkableSymbol(int, const char *,Definition *,Definition *) {} }; - - /*! create a new file definition, where \a p is the file path, \a nm the file name, and \a ref is an HTML anchor name if the file was read from a tag file or 0 otherwise @@ -84,23 +82,6 @@ FileDef::FileDef(const char *p,const char *nm, srcMemberDict = 0; usingDirList = 0; usingDeclList = 0; - -#if 0 - allMemberList = 0; - decDefineMembers = 0; - decProtoMembers = 0; - decTypedefMembers = 0; - decEnumMembers = 0; - decFuncMembers = 0; - decVarMembers = 0; - docDefineMembers = 0; - docProtoMembers = 0; - docTypedefMembers = 0; - docEnumMembers = 0; - docFuncMembers = 0; - docVarMembers = 0; -#endif - package = 0; isSource = FALSE; docname = nm; @@ -128,22 +109,6 @@ FileDef::~FileDef() delete usingDirList; delete usingDeclList; delete memberGroupSDict; - -#if 0 - delete allMemberList; - delete decDefineMembers; - delete decProtoMembers; - delete decTypedefMembers; - delete decEnumMembers; - delete decFuncMembers; - delete decVarMembers; - delete docDefineMembers; - delete docProtoMembers; - delete docTypedefMembers; - delete docEnumMembers; - delete docFuncMembers; - delete docVarMembers; -#endif } /*! Compute the HTML anchor names for all members in the class */ @@ -535,17 +500,11 @@ void FileDef::writeDocumentation(OutputList &ol) //allMemberList.writeDeclarations(ol,0,0,this,0,0,0); writeMemberDeclarations(ol,MemberList::decDefineMembers,theTranslator->trDefines()); - //if (decDefineMembers) decDefineMembers->writeDeclarations(ol,0,0,this,0,theTranslator->trDefines(),0); writeMemberDeclarations(ol,MemberList::decProtoMembers,theTranslator->trFuncProtos()); - //if (decProtoMembers) decProtoMembers->writeDeclarations(ol,0,0,this,0,theTranslator->trFuncProtos(),0); writeMemberDeclarations(ol,MemberList::decTypedefMembers,theTranslator->trTypedefs()); - //if (decTypedefMembers) decTypedefMembers->writeDeclarations(ol,0,0,this,0,theTranslator->trTypedefs(),0); writeMemberDeclarations(ol,MemberList::decEnumMembers,theTranslator->trEnumerations()); - //if (decEnumMembers) decEnumMembers->writeDeclarations(ol,0,0,this,0,theTranslator->trEnumerations(),0); writeMemberDeclarations(ol,MemberList::decFuncMembers,theTranslator->trFunctions()); - //if (decFuncMembers) decFuncMembers->writeDeclarations(ol,0,0,this,0,theTranslator->trFunctions(),0); writeMemberDeclarations(ol,MemberList::decVarMembers,theTranslator->trVariables()); - //if (decVarMembers) decVarMembers->writeDeclarations(ol,0,0,this,0,theTranslator->trVariables(),0); ol.endMemberSections(); if (!Config_getBool("DETAILS_AT_TOP")) @@ -587,46 +546,11 @@ void FileDef::writeMemberDocumentation(OutputList &ol) } writeMemberDocumentation(ol,MemberList::docDefineMembers,theTranslator->trDefineDocumentation()); - //if (docDefineMembers) - //{ - // docDefineMembers->writeDocumentation(ol,name(),this, - // theTranslator->trDefineDocumentation()); - //} - writeMemberDocumentation(ol,MemberList::docProtoMembers,theTranslator->trFunctionPrototypeDocumentation()); - //if (docProtoMembers) - //{ - // docProtoMembers->writeDocumentation(ol,name(),this, - // theTranslator->trFunctionPrototypeDocumentation()); - //} - writeMemberDocumentation(ol,MemberList::docTypedefMembers,theTranslator->trTypedefDocumentation()); - //if (docTypedefMembers) - //{ - // docTypedefMembers->writeDocumentation(ol,name(),this, - // theTranslator->trTypedefDocumentation()); - //} - writeMemberDocumentation(ol,MemberList::docEnumMembers,theTranslator->trEnumerationTypeDocumentation()); - //if (docEnumMembers) - //{ - // docEnumMembers->writeDocumentation(ol,name(),this, - // theTranslator->trEnumerationTypeDocumentation()); - //} - writeMemberDocumentation(ol,MemberList::docFuncMembers,theTranslator->trFunctionDocumentation()); - //if (docFuncMembers) - //{ - // docFuncMembers->writeDocumentation(ol,name(),this, - // theTranslator->trFunctionDocumentation()); - //} - writeMemberDocumentation(ol,MemberList::docVarMembers,theTranslator->trVariableDocumentation()); - //if (docVarMembers) - //{ - // docVarMembers->writeDocumentation(ol,name(),this, - // theTranslator->trVariableDocumentation()); - //} if (Config_getBool("SEPARATE_MEMBER_PAGES")) { @@ -648,14 +572,6 @@ void FileDef::writeMemberPages(OutputList &ol) ml->writeDocumentationPage(ol,name(),this); } } -#if 0 - if (docDefineMembers) docDefineMembers->writeDocumentationPage(ol,name(),this); - if (docProtoMembers) docProtoMembers->writeDocumentationPage(ol,name(),this); - if (docTypedefMembers) docTypedefMembers->writeDocumentationPage(ol,name(),this); - if (docEnumMembers) docEnumMembers->writeDocumentationPage(ol,name(),this); - if (docFuncMembers) docFuncMembers->writeDocumentationPage(ol,name(),this); - if (docVarMembers) docVarMembers->writeDocumentationPage(ol,name(),this); -#endif ol.popGeneratorState(); } @@ -773,14 +689,6 @@ void FileDef::addMembersToMemberGroup() ::addMembersToMemberGroup(ml,&memberGroupSDict,this); } } -#if 0 - ::addMembersToMemberGroup(decDefineMembers, &memberGroupSDict,this); - ::addMembersToMemberGroup(decProtoMembers, &memberGroupSDict,this); - ::addMembersToMemberGroup(decTypedefMembers, &memberGroupSDict,this); - ::addMembersToMemberGroup(decEnumMembers, &memberGroupSDict,this); - ::addMembersToMemberGroup(decFuncMembers, &memberGroupSDict,this); - ::addMembersToMemberGroup(decVarMembers, &memberGroupSDict,this); -#endif } /*! Adds member definition \a md to the list of all members of this file */ @@ -789,75 +697,46 @@ void FileDef::insertMember(MemberDef *md) //printf("%s:FileDef::insertMember(%s (=%p) list has %d elements)\n", // name().data(),md->name().data(),md,allMemberList.count()); MemberList *allMemberList = getMemberList(MemberList::allMembersList); - if (allMemberList && allMemberList->findRef(md)!=-1) + if (allMemberList && allMemberList->findRef(md)!=-1) // TODO optimize the findRef! { return; } if (allMemberList==0) { - allMemberList = new MemberList(MemberList::allMembersList); + allMemberList = new MemberList(MemberList::allMembersList);; m_memberLists.append(allMemberList); } allMemberList->append(md); + ::addFileMemberNameToIndex(md); switch (md->memberType()) { case MemberDef::Variable: case MemberDef::Property: addMemberToList(MemberList::decVarMembers,md); - //if (decVarMembers==0) decVarMembers = new MemberList; - //if (sortBriefDocs) decVarMembers->inSort(md); else decVarMembers->append(md); addMemberToList(MemberList::docVarMembers,md); - //if (docVarMembers==0) docVarMembers = new MemberList; - //if (sortMemberDocs) docVarMembers->inSort(md); else docVarMembers->append(md); - //docVarMembers->setInFile(TRUE); break; case MemberDef::Function: addMemberToList(MemberList::decFuncMembers,md); - //if (decFuncMembers==0) decFuncMembers = new MemberList; - //if (sortBriefDocs) decFuncMembers->inSort(md); else decFuncMembers->append(md); addMemberToList(MemberList::docFuncMembers,md); - //if (docFuncMembers==0) docFuncMembers = new MemberList; - //if (sortMemberDocs) docFuncMembers->inSort(md); else docFuncMembers->append(md); - //docFuncMembers->setInFile(TRUE); break; case MemberDef::Typedef: addMemberToList(MemberList::decTypedefMembers,md); - //if (decTypedefMembers==0) decTypedefMembers = new MemberList; - //if (sortBriefDocs) decTypedefMembers->inSort(md); else decTypedefMembers->append(md); addMemberToList(MemberList::docTypedefMembers,md); - //if (docTypedefMembers==0) docTypedefMembers = new MemberList; - //if (sortMemberDocs) docTypedefMembers->inSort(md); else docTypedefMembers->append(md); - //docTypedefMembers->setInFile(TRUE); break; case MemberDef::Enumeration: addMemberToList(MemberList::decEnumMembers,md); - //if (decEnumMembers==0) decEnumMembers = new MemberList; - //if (sortBriefDocs) decEnumMembers->inSort(md); else decEnumMembers->append(md); addMemberToList(MemberList::docEnumMembers,md); - //if (docEnumMembers==0) docEnumMembers = new MemberList; - //if (sortMemberDocs) docEnumMembers->inSort(md); else docEnumMembers->append(md); - //docEnumMembers->setInFile(TRUE); break; case MemberDef::EnumValue: // enum values are shown inside their enums break; case MemberDef::Prototype: addMemberToList(MemberList::decProtoMembers,md); - //if (decProtoMembers==0) decProtoMembers = new MemberList; - //if (sortBriefDocs) decProtoMembers->inSort(md); else decProtoMembers->append(md); addMemberToList(MemberList::docProtoMembers,md); - //if (docProtoMembers==0) docProtoMembers = new MemberList; - //if (sortMemberDocs) docProtoMembers->inSort(md); else docProtoMembers->append(md); - //docProtoMembers->setInFile(TRUE); break; case MemberDef::Define: addMemberToList(MemberList::decDefineMembers,md); - //if (decDefineMembers==0) decDefineMembers = new MemberList; - //if (sortBriefDocs) decDefineMembers->inSort(md); else decDefineMembers->append(md); addMemberToList(MemberList::docDefineMembers,md); - //if (docDefineMembers==0) docDefineMembers = new MemberList; - //if (sortMemberDocs) docDefineMembers->inSort(md); else docDefineMembers->append(md); - //docDefineMembers->setInFile(TRUE); break; default: err("FileDef::insertMembers(): " @@ -1074,10 +953,13 @@ bool FileDef::generateSourceFile() const void FileDef::addListReferences() { - addRefItem(xrefListItems(), - theTranslator->trFile(TRUE,TRUE), - getOutputFileBase(),name() - ); + { + LockingPtr< QList > xrefItems = xrefListItems(); + addRefItem(xrefItems.pointer(), + theTranslator->trFile(TRUE,TRUE), + getOutputFileBase(),name() + ); + } if (memberGroupSDict) { MemberGroupSDict::Iterator mgli(*memberGroupSDict); @@ -1096,15 +978,6 @@ void FileDef::addListReferences() ml->addListReferences(this); } } - -#if 0 - if (docDefineMembers) docDefineMembers->addListReferences(this); - if (docProtoMembers) docProtoMembers->addListReferences(this); - if (docTypedefMembers) docTypedefMembers->addListReferences(this); - if (docEnumMembers) docEnumMembers->addListReferences(this); - if (docFuncMembers) docFuncMembers->addListReferences(this); - if (docVarMembers) docVarMembers->addListReferences(this); -#endif } //------------------------------------------------------------------- @@ -1316,7 +1189,7 @@ static void addDirsAsGroups(Directory *root,GroupDef *parent,int level) } else { - Doxygen::groupSDict.append(root->path(),gd); + Doxygen::groupSDict->append(root->path(),gd); } } QListIterator dli(root->children()); @@ -1336,7 +1209,7 @@ void generateFileTree() Directory *root=new Directory(0,"root"); root->setLast(TRUE); - FileNameListIterator fnli(Doxygen::inputNameList); + FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (fnli.toFirst();(fn=fnli.current());++fnli) { diff --git a/src/filedef.h b/src/filedef.h index 1b194f8..c794b70 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -170,31 +170,8 @@ class FileDef : public Definition void addListReferences(); bool isDocumentationFile() const; - - //void generateXML(QTextStream &t); - //void generateXMLSection(QTextStream &t,MemberList *ml,const char *type); - MemberList *getMemberList(MemberList::ListType lt) const; const QList &getMemberLists() const { return m_memberLists; } -#if 0 - MemberList *allMemberList; - - // members in the declaration part of the documentation - MemberList *decDefineMembers; - MemberList *decProtoMembers; - MemberList *decTypedefMembers; - MemberList *decEnumMembers; - MemberList *decFuncMembers; - MemberList *decVarMembers; - - // members in the detailed part of the documentation - MemberList *docDefineMembers; - MemberList *docProtoMembers; - MemberList *docTypedefMembers; - MemberList *docEnumMembers; - MemberList *docFuncMembers; - MemberList *docVarMembers; -#endif /* user defined member groups */ MemberGroupSDict *getMemberGroupSDict() const { return memberGroupSDict; } diff --git a/src/groupdef.cpp b/src/groupdef.cpp index 993b213..13a5681 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -244,10 +244,13 @@ bool GroupDef::insertMember(MemberDef *md,bool docOnly) // both inside a file => definition and declaration do not have to be in the same file (srcMd->getOuterScope()->definitionType()==Definition::TypeFile && md->getOuterScope()->definitionType()==Definition::TypeFile); + + LockingPtr srcMdAl = srcMd->argumentList(); + LockingPtr mdAl = md->argumentList(); if (srcMd->isFunction() && md->isFunction() && - matchArguments2(srcMd->getOuterScope(),srcMd->getFileDef(),srcMd->argumentList(), - md->getOuterScope(),md->getFileDef(),md->argumentList(), + matchArguments2(srcMd->getOuterScope(),srcMd->getFileDef(),srcMdAl.pointer(), + md->getOuterScope(),md->getFileDef(),mdAl.pointer(), TRUE ) && sameScope @@ -467,7 +470,8 @@ void GroupDef::addGroup(const GroupDef *def) bool GroupDef::isASubGroup() const { - return partOfGroups() && partOfGroups()->count()!=0; + LockingPtr groups = partOfGroups(); + return groups!=0 && groups->count()!=0; } int GroupDef::countMembers() const @@ -890,7 +894,7 @@ void addClassToGroups(Entry *root,ClassDef *cd) for (;(g=gli.current());++gli) { GroupDef *gd=0; - if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict[g->groupname])) + if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) { gd->addClass(cd); cd->makePartOfGroup(gd); @@ -908,7 +912,7 @@ void addNamespaceToGroups(Entry *root,NamespaceDef *nd) { GroupDef *gd=0; //printf("group `%s'\n",s->data()); - if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict[g->groupname])) + if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) { gd->addNamespace(nd); nd->makePartOfGroup(gd); @@ -926,7 +930,7 @@ void addDirToGroups(Entry *root,DirDef *dd) { GroupDef *gd=0; //printf("group `%s'\n",g->groupname.data()); - if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict[g->groupname])) + if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) { gd->addDir(dd); dd->makePartOfGroup(gd); @@ -944,7 +948,7 @@ void addGroupToGroups(Entry *root,GroupDef *subGroup) for (;(g=gli.current());++gli) { GroupDef *gd=0; - if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict[g->groupname]) && + if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)) && !gd->containsGroup(subGroup) ) { gd->addGroup(subGroup); @@ -973,7 +977,7 @@ void addMemberToGroups(Entry *root,MemberDef *md) { GroupDef *gd=0; if (!g->groupname.isEmpty() && - (gd=Doxygen::groupSDict[g->groupname]) && + (gd=Doxygen::groupSDict->find(g->groupname)) && g->pri >= pri) { if (fgd && gd!=fgd && g->pri==pri) @@ -1067,7 +1071,7 @@ void addExampleToGroups(Entry *root,PageDef *eg) for (;(g=gli.current());++gli) { GroupDef *gd=0; - if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict[g->groupname])) + if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname))) { gd->addExample(eg); eg->makePartOfGroup(gd); @@ -1090,10 +1094,13 @@ QCString GroupDef::getOutputFileBase() const void GroupDef::addListReferences() { - addRefItem(xrefListItems(), + { + LockingPtr< QList > xrefItems = xrefListItems(); + addRefItem(xrefItems.pointer(), theTranslator->trGroup(TRUE,TRUE), getOutputFileBase(),name() ); + } MemberGroupSDict::Iterator mgli(*memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 7907c94..e96d1a8 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -755,10 +755,9 @@ void HtmlGenerator::writeString(const char *text) t << text; } -void HtmlGenerator::writeIndexItem(const char *ref,const char *f, - const char *name) +void HtmlGenerator::startIndexItem(const char *ref,const char *f) { - //printf("HtmlGenerator::writeIndexItem(%s,%s,%s)\n",ref,f,name); + //printf("HtmlGenerator::startIndexItem(%s,%s,%s)\n",ref,f,name); QCString *dest; t << "
  • "; if (ref || f) @@ -785,7 +784,11 @@ void HtmlGenerator::writeIndexItem(const char *ref,const char *f, { t << ""; } - docify(name); +} + +void HtmlGenerator::endIndexItem(const char *ref,const char *f) +{ + //printf("HtmlGenerator::endIndexItem(%s,%s,%s)\n",ref,f,name); if (ref || f) { t << "" << endl; diff --git a/src/htmlgen.h b/src/htmlgen.h index c9e3a62..88a8841 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -72,7 +72,8 @@ class HtmlGenerator : public OutputGenerator void endIndexValue(const char *,bool); void startItemList() { t << "
      " << endl; } void endItemList() { t << "
    " << endl; } - void writeIndexItem(const char *ref,const char *file,const char *name); + void startIndexItem(const char *ref,const char *file); + void endIndexItem(const char *ref,const char *file); void docify(const char *text); void codify(const char *text); void writeObjectLink(const char *ref,const char *file, diff --git a/src/index.cpp b/src/index.cpp index 8e878cd..49a8609 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -74,19 +74,6 @@ void countDataStructures() documentedGroups = countGroups(); documentedNamespaces = countNamespaces(); documentedDirs = countDirs(); - int i; - for (i=0;i<(int)CMHL_Total;i++) - { - documentedClassMembers[i] = countClassMembers(i); - } - for (i=0;i<(int)FMHL_Total;i++) - { - documentedFileMembers[i] = countFileMembers(i); - } - for (i=0;i<(int)NMHL_Total;i++) - { - documentedNamespaceMembers[i] = countNamespaceMembers(i); - } } static void startIndexHierarchy(OutputList &ol,int level) @@ -117,9 +104,25 @@ static void endIndexHierarchy(OutputList &ol,int level) //---------------------------------------------------------------------------- -static bool g_memberIndexLetterUsed[CMHL_Total][256]; -static bool g_fileIndexLetterUsed[FMHL_Total][256]; -static bool g_namespaceIndexLetterUsed[NMHL_Total][256]; +class MemberIndexList : public QList +{ + public: + MemberIndexList() : QList() {} + ~MemberIndexList() {} + int compareItems(GCI item1, GCI item2) + { + MemberDef *md1=(MemberDef *)item1; + MemberDef *md2=(MemberDef *)item2; + return stricmp(md1->name(),md2->name()); + } +}; + +#define MEMBER_INDEX_ENTRIES 128 + +static MemberIndexList g_memberIndexLetterUsed[CMHL_Total][MEMBER_INDEX_ENTRIES]; +static MemberIndexList g_fileIndexLetterUsed[FMHL_Total][MEMBER_INDEX_ENTRIES]; +static MemberIndexList g_namespaceIndexLetterUsed[NMHL_Total][MEMBER_INDEX_ENTRIES]; + static bool g_classIndexLetterUsed[CHL_Total][256]; const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX; @@ -329,7 +332,9 @@ void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper,int level) if (cd->isLinkable()) { //printf("Writing class %s\n",cd->displayName().data()); - ol.writeIndexItem(cd->getReference(),cd->getOutputFileBase(),cd->displayName()); + ol.startIndexItem(cd->getReference(),cd->getOutputFileBase()); + ol.parseText(cd->displayName()); + ol.endIndexItem(cd->getReference(),cd->getOutputFileBase()); if (cd->isReference()) { ol.startTypewriter(); @@ -347,7 +352,9 @@ void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper,int level) } else { - ol.writeIndexItem(0,0,cd->name()); + ol.startIndexItem(0,0); + ol.parseText(cd->name()); + ol.endIndexItem(0,0); if (hasHtmlHelp) { htmlHelp->addContentsItem(hasChildren,cd->displayName(),0); @@ -548,7 +555,9 @@ static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started) { //printf("Writing class %s isLinkable()=%d isLinkableInProject()=%d cd->templateMaster()=%p\n", // cd->displayName().data(),cd->isLinkable(),cd->isLinkableInProject(),cd->templateMaster()); - ol.writeIndexItem(cd->getReference(),cd->getOutputFileBase(),cd->displayName()); + ol.startIndexItem(cd->getReference(),cd->getOutputFileBase()); + ol.parseText(cd->displayName()); + ol.endIndexItem(cd->getReference(),cd->getOutputFileBase()); if (cd->isReference()) { ol.startTypewriter(); @@ -566,7 +575,9 @@ static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started) } else { - ol.writeIndexItem(0,0,cd->displayName()); + ol.startIndexItem(0,0); + ol.parseText(cd->displayName()); + ol.endIndexItem(0,0); if (hasHtmlHelp) { htmlHelp->addContentsItem(hasChildren,cd->displayName(),0); @@ -602,12 +613,12 @@ void writeClassHierarchy(OutputList &ol) ftvHelp = FTVHelp::getInstance(); } - initClassHierarchy(&Doxygen::classSDict); - initClassHierarchy(&Doxygen::hiddenClasses); + initClassHierarchy(Doxygen::classSDict); + initClassHierarchy(Doxygen::hiddenClasses); bool started=FALSE; - writeClassTreeForList(ol,&Doxygen::classSDict,started); - writeClassTreeForList(ol,&Doxygen::hiddenClasses,started); + writeClassTreeForList(ol,Doxygen::classSDict,started); + writeClassTreeForList(ol,Doxygen::hiddenClasses,started); if (started) { endIndexHierarchy(ol,0); @@ -642,10 +653,10 @@ static int countClassesInTreeList(const ClassSDict &cl) int countClassHierarchy() { int count=0; - initClassHierarchy(&Doxygen::classSDict); - initClassHierarchy(&Doxygen::hiddenClasses); - count+=countClassesInTreeList(Doxygen::classSDict); - count+=countClassesInTreeList(Doxygen::hiddenClasses); + initClassHierarchy(Doxygen::classSDict); + initClassHierarchy(Doxygen::hiddenClasses); + count+=countClassesInTreeList(*Doxygen::classSDict); + count+=countClassesInTreeList(*Doxygen::hiddenClasses); return count; } @@ -751,7 +762,7 @@ void countFiles(int &htmlFiles,int &files) { htmlFiles=0; files=0; - FileNameListIterator fnli(Doxygen::inputNameList); + FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (;(fn=fnli.current());++fnli) { @@ -821,7 +832,7 @@ void writeFileIndex(OutputList &ol) if (Config_getBool("FULL_PATH_NAMES")) { // re-sort input files in (dir,file) output order instead of (file,dir) input order - FileName *fn=Doxygen::inputNameList.first(); + FileName *fn=Doxygen::inputNameList->first(); while (fn) { FileDef *fd=fn->first(); @@ -845,7 +856,7 @@ void writeFileIndex(OutputList &ol) } fd=fn->next(); } - fn=Doxygen::inputNameList.next(); + fn=Doxygen::inputNameList->next(); } } @@ -857,7 +868,7 @@ void writeFileIndex(OutputList &ol) } else { - fl = Doxygen::inputNameList.first(); + fl = Doxygen::inputNameList->first(); } while (fl) { @@ -953,7 +964,7 @@ void writeFileIndex(OutputList &ol) } else { - fl=Doxygen::inputNameList.next(); + fl=Doxygen::inputNameList->next(); } } ol.endIndexList(); @@ -973,7 +984,7 @@ void writeFileIndex(OutputList &ol) int countNamespaces() { int count=0; - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; for (;(nd=nli.current());++nli) { @@ -1038,7 +1049,7 @@ void writeNamespaceIndex(OutputList &ol) bool first=TRUE; - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { @@ -1101,7 +1112,7 @@ int countAnnotatedClasses() { int count=0; //ClassDef *cd=Doxygen::classList.first(); - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; for (;(cd=cli.current());++cli) { @@ -1122,7 +1133,7 @@ void writeAnnotatedClassList(OutputList &ol) bool hasHtmlHelp = generateHtml && Config_getBool("GENERATE_HTMLHELP"); bool hasFtvHelp = generateHtml && Config_getBool("GENERATE_TREEVIEW"); ol.startIndexList(); - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; // clear index @@ -1236,7 +1247,7 @@ void writeAlphabeticalClassList(OutputList &ol) memset (indexLetterUsed, 0, sizeof (indexLetterUsed)); // first count the number of headers - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; uint startLetter=0; int headerItems=0; @@ -1506,15 +1517,130 @@ void writeAnnotatedIndex(OutputList &ol) } //---------------------------------------------------------------------------- +static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *separator, + QCString &prevClassName) +{ + ClassDef *cd=md->getClassDef(); + if ( cd && prevClassName!=cd->displayName()) + { + ol.docify(separator); + ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(), + cd->displayName()); + ol.writeString("\n"); + prevClassName = cd->displayName(); + } +} -void writeMemberList(OutputList &ol,bool useSections, - ClassMemberHighlight filter,char sectionFilter) +static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *separator, + QCString &prevFileName) { + FileDef *fd=md->getFileDef(); + if (fd && prevFileName!=fd->name()) + { + ol.docify(separator); + ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(), + fd->name()); + ol.writeString("\n"); + prevFileName = fd->name(); + } +} + +static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char *separator, + QCString &prevNamespaceName) +{ + NamespaceDef *nd=md->getNamespaceDef(); + if (nd && prevNamespaceName!=nd->name()) + { + ol.docify(separator); + ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(), + nd->name()); + ol.writeString("\n"); + prevNamespaceName = nd->name(); + } +} + +typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator, + QCString &prevNamespaceName); + +static void writeMemberList(OutputList &ol,bool useSections,int page, + MemberIndexList memberLists[MEMBER_INDEX_ENTRIES], + DefinitionIntf::DefType type) +{ + int pi; + int startIndex = page==-1 ? 0 : page; + int endIndex = page==-1 ? MEMBER_INDEX_ENTRIES-1 : page; + ASSERT((int)type<3); + static writeLinkForMember_t writeLinkForMemberMap[3] = + { + &writeClassLinkForMember, + &writeFileLinkForMember, + &writeNamespaceLinkForMember + }; + QCString prevName; + QCString prevDefName; + bool first=TRUE; + bool firstSection=TRUE; + for (pi=startIndex; pi<=endIndex; pi++) // page==-1 => pi=[0..127], page!=-1 => pi=page + { + MemberIndexList *ml = &memberLists[pi]; + if (ml->count()==0) continue; + ml->sort(); + QListIterator mli(*ml); + MemberDef *md; + for (mli.toFirst();(md=mli.current());++mli) + { + char *sep; + bool isFunc=!md->isObjCMethod() && + (md->isFunction() || md->isSlot() || md->isSignal()); + QCString name=md->name(); + if (name!=prevName) // same entry + { + if ((prevName.isEmpty() || tolower(name.at(0))!=tolower(prevName.at(0))) && useSections) // new section + { + if (!firstSection) ol.endItemList(); + char cs[2]; + cs[0]=tolower(name.at(0));cs[1]='\0'; + QCString anchor=(QCString)"index_"+cs; + QCString title=(QCString)"- "+cs+" -"; + ol.startSection(anchor,title,SectionInfo::Subsection); + ol.docify(title); + ol.endSection(anchor,SectionInfo::Subsection); + ol.startItemList(); + firstSection=FALSE; + } + else if (!useSections && first) + { + ol.startItemList(); + first=FALSE; + } + + // member name + ol.writeListItem(); + ol.docify(name); + if (isFunc) ol.docify("()"); + ol.writeString("\n"); + + // link to class + prevDefName=""; + sep = ": "; + prevName = name; + } + else // same entry + { + sep = ", "; + // link to class for other members with the same name + } + writeLinkForMemberMap[(int)type](ol,md,sep,prevDefName); + } + } + ol.endItemList(); + +#if 0 bool first = TRUE; char lastChar = 0; static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS"); - MemberNameSDict::Iterator mnli(Doxygen::memberNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); MemberName *mn=0; for (mnli.toFirst();(mn=mnli.current());++mnli) { @@ -1608,16 +1734,98 @@ void writeMemberList(OutputList &ol,bool useSections, } } ol.endItemList(); +#endif } //---------------------------------------------------------------------------- +void initClassMemberIndices() +{ + int i=0; + int j=0; + for (j=0;jisLinkableInProject() && + (cd=md->getClassDef()) && + cd->isLinkableInProject() && + cd->templateMaster()==0) + { + QCString n = md->name(); + int letter = tolower(n.at(0)) & 0x7f; + if (!n.isEmpty()) + { + bool isFriendToHide = hideFriendCompounds && + (QCString(md->typeString())=="friend class" || + QCString(md->typeString())=="friend struct" || + QCString(md->typeString())=="friend union"); + if (!(md->isFriend() && isFriendToHide)) + { + g_memberIndexLetterUsed[CMHL_All][letter].append(md); + documentedClassMembers[CMHL_All]++; + } + if (md->isFunction() || md->isSlot() || md->isSignal()) + { + g_memberIndexLetterUsed[CMHL_Functions][letter].append(md); + documentedClassMembers[CMHL_Functions]++; + } + else if (md->isVariable()) + { + g_memberIndexLetterUsed[CMHL_Variables][letter].append(md); + documentedClassMembers[CMHL_Variables]++; + } + else if (md->isTypedef()) + { + g_memberIndexLetterUsed[CMHL_Typedefs][letter].append(md); + documentedClassMembers[CMHL_Typedefs]++; + } + else if (md->isEnumerate()) + { + g_memberIndexLetterUsed[CMHL_Enums][letter].append(md); + documentedClassMembers[CMHL_Enums]++; + } + else if (md->isEnumValue()) + { + g_memberIndexLetterUsed[CMHL_EnumValues][letter].append(md); + documentedClassMembers[CMHL_EnumValues]++; + } + else if (md->isProperty()) + { + g_memberIndexLetterUsed[CMHL_Properties][letter].append(md); + documentedClassMembers[CMHL_Properties]++; + } + else if (md->isEvent()) + { + g_memberIndexLetterUsed[CMHL_Events][letter].append(md); + documentedClassMembers[CMHL_Events]++; + } + else if (md->isRelated() || (md->isFriend() && !isFriendToHide)) + { + g_memberIndexLetterUsed[CMHL_Related][letter].append(md); + documentedClassMembers[CMHL_Related]++; + } + } + } +} + +#if 0 int countClassMembers(int filter) { static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS"); int i=0;for (i=0;i<256;i++) g_memberIndexLetterUsed[filter][i]=FALSE; int count=0; - MemberNameSDict::Iterator mnli(Doxygen::memberNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); MemberName *mn=0; for (mnli.toFirst();(mn=mnli.current());++mnli) { @@ -1659,10 +1867,211 @@ int countClassMembers(int filter) } return count; } +#endif + +//---------------------------------------------------------------------------- + +void initNamespaceMemberIndices() +{ + int i=0; + int j=0; + for (j=0;jgetNamespaceDef(); + if (nd && nd->isLinkableInProject() && md->isLinkableInProject()) + { + QCString n = md->name(); + int letter = tolower(n.at(0)); + if (!n.isEmpty()) + { + g_namespaceIndexLetterUsed[NMHL_All][letter].append(md); + documentedNamespaceMembers[NMHL_All]++; + + if (md->isFunction()) + { + g_namespaceIndexLetterUsed[NMHL_Functions][letter].append(md); + documentedNamespaceMembers[NMHL_Functions]++; + } + else if (md->isVariable()) + { + g_namespaceIndexLetterUsed[NMHL_Variables][letter].append(md); + documentedNamespaceMembers[NMHL_Variables]++; + } + else if (md->isTypedef()) + { + g_namespaceIndexLetterUsed[NMHL_Typedefs][letter].append(md); + documentedNamespaceMembers[NMHL_Typedefs]++; + } + else if (md->isEnumerate()) + { + g_namespaceIndexLetterUsed[NMHL_Enums][letter].append(md); + documentedNamespaceMembers[NMHL_Enums]++; + } + else if (md->isEnumValue()) + { + g_namespaceIndexLetterUsed[NMHL_EnumValues][letter].append(md); + documentedNamespaceMembers[NMHL_EnumValues]++; + } + } + } +} + +#if 0 +int countNamespaceMembers(int filter) +{ + int i=0;for (i=0;i<256;i++) g_namespaceIndexLetterUsed[filter][i]=FALSE; + int count=0; + MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); + MemberName *mn=0; + for (mnli.toFirst();(mn=mnli.current());++mnli) + { + MemberDef *md=mn->first(); + bool found=FALSE; + while (md && !found) + { + NamespaceDef *nd=md->getNamespaceDef(); + if (nd && nd->isLinkableInProject() && md->isLinkableInProject() && + ( filter==NMHL_All || + (filter==NMHL_Functions && md->isFunction()) || + (filter==NMHL_Variables && md->isVariable()) || + (filter==NMHL_Typedefs && md->isTypedef()) || + (filter==NMHL_Enums && md->isEnumerate()) || + (filter==NMHL_EnumValues && md->isEnumValue()) + ) + ) + { + QCString n = mn->memberName(); + if (!n.isEmpty()) g_namespaceIndexLetterUsed[filter][tolower(n.at(0))]=TRUE; + found=TRUE; + } + else + md=mn->next(); + } + if (found) count++; + } + return count; +} +#endif //---------------------------------------------------------------------------- -void writeQuickMemberIndex(OutputList &ol,bool *charUsed,int page, +void initFileMemberIndices() +{ + int i=0; + int j=0; + for (j=0;jgetFileDef(); + if (fd && fd->isLinkableInProject() && md->isLinkableInProject()) + { + QCString n = md->name(); + int letter = tolower(n.at(0)); + if (!n.isEmpty()) + { + g_fileIndexLetterUsed[FMHL_All][letter].append(md); + documentedFileMembers[FMHL_All]++; + + if (md->isFunction()) + { + g_fileIndexLetterUsed[FMHL_Functions][letter].append(md); + documentedFileMembers[FMHL_Functions]++; + } + else if (md->isVariable()) + { + g_fileIndexLetterUsed[FMHL_Variables][letter].append(md); + documentedFileMembers[FMHL_Variables]++; + } + else if (md->isTypedef()) + { + g_fileIndexLetterUsed[FMHL_Typedefs][letter].append(md); + documentedFileMembers[FMHL_Typedefs]++; + } + else if (md->isEnumerate()) + { + g_fileIndexLetterUsed[FMHL_Enums][letter].append(md); + documentedFileMembers[FMHL_Enums]++; + } + else if (md->isEnumValue()) + { + g_fileIndexLetterUsed[FMHL_EnumValues][letter].append(md); + documentedFileMembers[FMHL_EnumValues]++; + } + else if (md->isDefine()) + { + g_fileIndexLetterUsed[FMHL_Defines][letter].append(md); + documentedFileMembers[FMHL_Defines]++; + } + } + } +} + +#if 0 +int countFileMembers(int filter) +{ + int i=0;for (i=0;i<256;i++) g_fileIndexLetterUsed[filter][i]=FALSE; + int count=0; + MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); + MemberName *mn=0; + for (mnli.toFirst();(mn=mnli.current());++mnli) + { + MemberDef *md=mn->first(); + FileDef *fd; + bool found=FALSE; + while (md && !found) + { + if (md->isLinkableInProject() && + (fd=md->getFileDef()) && + fd->isLinkableInProject() && + ( filter==FMHL_All || + (filter==FMHL_Functions && md->isFunction()) || + (filter==FMHL_Variables && md->isVariable()) || + (filter==FMHL_Typedefs && md->isTypedef()) || + (filter==FMHL_Enums && md->isEnumerate()) || + (filter==FMHL_EnumValues && md->isEnumValue()) || + (filter==FMHL_Defines && md->isDefine()) + ) + ) + { + QCString n = mn->memberName(); + if (!n.isEmpty()) + { + g_fileIndexLetterUsed[filter][tolower(n.at(0))]=TRUE; + } + found=TRUE; + } + else + md=mn->next(); + } + if (found) count++; + } + return count; +} +#endif + +//---------------------------------------------------------------------------- + +void writeQuickMemberIndex(OutputList &ol, + MemberIndexList charUsed[MEMBER_INDEX_ENTRIES],int page, QCString fullName,bool multiPage) { bool first=TRUE; @@ -1671,7 +2080,7 @@ void writeQuickMemberIndex(OutputList &ol,bool *charUsed,int page, for (i=33;i<127;i++) { char is[2];is[0]=(char)i;is[1]='\0'; - if (charUsed[i]) + if (charUsed[i].count()>0) { QCString anchor; QCString extension=Doxygen::htmlFileExtension; @@ -1734,7 +2143,7 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h bool first=TRUE; for (page=0;page0) { QCString fileName = cmhlInfo[hl].fname; if (multiPageIndex && !first) @@ -1786,7 +2195,10 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h ol.writeString(" "); } ol.newParagraph(); - writeMemberList(ol,quickIndex,hl,page); + writeMemberList(ol,quickIndex, + multiPageIndex?page:-1, + g_memberIndexLetterUsed[hl], + Definition::TypeClass); endFile(ol); first=FALSE; } @@ -1828,6 +2240,7 @@ void writeClassMemberIndex(OutputList &ol) //---------------------------------------------------------------------------- +#if 0 static void writeFileMemberList(OutputList &ol, bool useSections, FileMemberHighlight filter, @@ -1835,7 +2248,7 @@ static void writeFileMemberList(OutputList &ol, { char lastChar=0; bool first=TRUE; - MemberNameSDict::Iterator mnli(Doxygen::functionNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); MemberName *mn=0; for (mnli.toFirst();(mn=mnli.current());++mnli) { @@ -1933,7 +2346,7 @@ void writeNamespaceMemberList(OutputList &ol,bool useSections, { char lastChar=0; bool first=TRUE; - MemberNameSDict::Iterator mnli(Doxygen::functionNameSDict); + MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); MemberName *mn=0; for (mnli.toFirst();(mn=mnli.current());++mnli) { @@ -2016,88 +2429,10 @@ void writeNamespaceMemberList(OutputList &ol,bool useSections, } if (!first) ol.endItemList(); } +#endif //---------------------------------------------------------------------------- -int countNamespaceMembers(int filter) -{ - int i=0;for (i=0;i<256;i++) g_namespaceIndexLetterUsed[filter][i]=FALSE; - int count=0; - MemberNameSDict::Iterator mnli(Doxygen::functionNameSDict); - MemberName *mn=0; - for (mnli.toFirst();(mn=mnli.current());++mnli) - { - MemberDef *md=mn->first(); - bool found=FALSE; - while (md && !found) - { - NamespaceDef *nd=md->getNamespaceDef(); - if (nd && nd->isLinkableInProject() && md->isLinkableInProject() && - ( filter==NMHL_All || - (filter==NMHL_Functions && md->isFunction()) || - (filter==NMHL_Variables && md->isVariable()) || - (filter==NMHL_Typedefs && md->isTypedef()) || - (filter==NMHL_Enums && md->isEnumerate()) || - (filter==NMHL_EnumValues && md->isEnumValue()) - ) - ) - { - QCString n = mn->memberName(); - if (!n.isEmpty()) g_namespaceIndexLetterUsed[filter][tolower(n.at(0))]=TRUE; - found=TRUE; - } - else - md=mn->next(); - } - if (found) count++; - } - return count; -} - -//---------------------------------------------------------------------------- - -int countFileMembers(int filter) -{ - int i=0;for (i=0;i<256;i++) g_fileIndexLetterUsed[filter][i]=FALSE; - int count=0; - MemberNameSDict::Iterator mnli(Doxygen::functionNameSDict); - MemberName *mn=0; - for (mnli.toFirst();(mn=mnli.current());++mnli) - { - MemberDef *md=mn->first(); - FileDef *fd; - bool found=FALSE; - while (md && !found) - { - if (md->isLinkableInProject() && - (fd=md->getFileDef()) && - fd->isLinkableInProject() && - ( filter==FMHL_All || - (filter==FMHL_Functions && md->isFunction()) || - (filter==FMHL_Variables && md->isVariable()) || - (filter==FMHL_Typedefs && md->isTypedef()) || - (filter==FMHL_Enums && md->isEnumerate()) || - (filter==FMHL_EnumValues && md->isEnumValue()) || - (filter==FMHL_Defines && md->isDefine()) - ) - ) - { - QCString n = mn->memberName(); - if (!n.isEmpty()) - { - g_fileIndexLetterUsed[filter][tolower(n.at(0))]=TRUE; - } - found=TRUE; - } - else - md=mn->next(); - } - if (found) count++; - } - return count; -} - -//---------------------------------------------------------------------------- static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl) { @@ -2137,7 +2472,7 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl) bool first=TRUE; for (page=0;page0) { QCString fileName = fmhlInfo[hl].fname; if (multiPageIndex && !first) @@ -2188,7 +2523,11 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl) ol.writeString(" "); } ol.newParagraph(); - writeFileMemberList(ol,quickIndex,hl,page); + //writeFileMemberList(ol,quickIndex,hl,page); + writeMemberList(ol,quickIndex, + multiPageIndex?page:-1, + g_fileIndexLetterUsed[hl], + Definition::TypeFile); endFile(ol); first=FALSE; } @@ -2266,7 +2605,7 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol, bool first=TRUE; for (page=0;page0) { QCString fileName = nmhlInfo[hl].fname; if (multiPageIndex && !first) @@ -2315,7 +2654,11 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol, } ol.newParagraph(); - writeNamespaceMemberList(ol,quickIndex,hl,page); + //writeNamespaceMemberList(ol,quickIndex,hl,page); + writeMemberList(ol,quickIndex, + multiPageIndex?page:-1, + g_namespaceIndexLetterUsed[hl], + Definition::TypeNamespace); endFile(ol); } } @@ -2547,7 +2890,9 @@ void writePageIndex(OutputList &ol) bool hasSubPages = pd->hasSubPages(); - ol.writeIndexItem(pd->getReference(),pd->getOutputFileBase(),pageTitle); + ol.startIndexItem(pd->getReference(),pd->getOutputFileBase()); + ol.parseText(pageTitle); + ol.endIndexItem(pd->getReference(),pd->getOutputFileBase()); if (pd->isReference()) { ol.startTypewriter(); @@ -2584,7 +2929,7 @@ void writePageIndex(OutputList &ol) int countGroups() { int count=0; - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { @@ -2602,7 +2947,7 @@ int countGroups() int countDirs() { int count=0; - SDict::Iterator dli(Doxygen::directories); + SDict::Iterator dli(*Doxygen::directories); DirDef *dd; for (dli.toFirst();(dd=dli.current());++dli) { @@ -2757,7 +3102,9 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,int level) //parseText(ol,gd->groupTitle()); //ol.endTextLink(); - ol.writeIndexItem(gd->getReference(),gd->getOutputFileBase(),gd->groupTitle()); + ol.startIndexItem(gd->getReference(),gd->getOutputFileBase()); + ol.parseText(gd->groupTitle()); + ol.endIndexItem(gd->getReference(),gd->getOutputFileBase()); if (gd->isReference()) { ol.startTypewriter(); @@ -3033,7 +3380,7 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,int level) void writeGroupHierarchy(OutputList &ol) { startIndexHierarchy(ol,0); - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { @@ -3085,8 +3432,9 @@ void writeDirTreeNode(OutputList &ol, DirDef *dd,int level) ftvHelp->incContentsDepth(); } - ol.writeIndexItem(dd->getReference(),dd->getOutputFileBase(), - dd->shortName()); + ol.startIndexItem(dd->getReference(),dd->getOutputFileBase()); + ol.parseText(dd->shortName()); + ol.endIndexItem(dd->getReference(),dd->getOutputFileBase()); if (dd->isReference()) { ol.startTypewriter(); @@ -3132,7 +3480,7 @@ void writeDirTreeNode(OutputList &ol, DirDef *dd,int level) void writeDirHierarchy(OutputList &ol) { startIndexHierarchy(ol,0); - SDict::Iterator dli(Doxygen::directories); + SDict::Iterator dli(*Doxygen::directories); DirDef *dd; for (dli.toFirst();(dd=dli.current());++dli) { diff --git a/src/index.h b/src/index.h index 7e30e0a..90dc11f 100644 --- a/src/index.h +++ b/src/index.h @@ -21,6 +21,8 @@ #include "qtbc.h" #include +class MemberDef; + enum IndexSections { isTitlePageStart, @@ -166,4 +168,11 @@ void startFile(OutputList &ol,const char *name,const char *manName, const char *title,HighlightedItem hli=HLI_None); void endFile(OutputList &ol,bool external=FALSE); +void initClassMemberIndices(); +void initFileMemberIndices(); +void initNamespaceMemberIndices(); +void addClassMemberNameToIndex(MemberDef *md); +void addFileMemberNameToIndex(MemberDef *md); +void addNamespaceMemberNameToIndex(MemberDef *md); + #endif diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 0e61bd0..df39700 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -520,7 +520,7 @@ void LatexGenerator::startIndexSection(IndexSections is) break; case isModuleDocumentation: { - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; bool found=FALSE; for (gli.toFirst();(gd=gli.current()) && !found;++gli) @@ -536,7 +536,7 @@ void LatexGenerator::startIndexSection(IndexSections is) break; case isDirDocumentation: { - SDict::Iterator dli(Doxygen::directories); + SDict::Iterator dli(*Doxygen::directories); DirDef *dd; bool found=FALSE; for (dli.toFirst();(dd=dli.current()) && !found;++dli) @@ -552,7 +552,7 @@ void LatexGenerator::startIndexSection(IndexSections is) break; case isNamespaceDocumentation: { - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; bool found=FALSE; for (nli.toFirst();(nd=nli.current()) && !found;++nli) @@ -568,7 +568,7 @@ void LatexGenerator::startIndexSection(IndexSections is) break; case isClassDocumentation: { - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd=0; bool found=FALSE; for (cli.toFirst();(cd=cli.current()) && !found;++cli) @@ -585,7 +585,7 @@ void LatexGenerator::startIndexSection(IndexSections is) case isFileDocumentation: { bool isFirst=TRUE; - FileName *fn=Doxygen::inputNameList.first(); + FileName *fn=Doxygen::inputNameList->first(); while (fn) { FileDef *fd=fn->first(); @@ -603,7 +603,7 @@ void LatexGenerator::startIndexSection(IndexSections is) } fd=fn->next(); } - fn=Doxygen::inputNameList.next(); + fn=Doxygen::inputNameList->next(); } } break; @@ -670,7 +670,7 @@ void LatexGenerator::endIndexSection(IndexSections is) break; case isModuleDocumentation: { - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; bool found=FALSE; for (gli.toFirst();(gd=gli.current()) && !found;++gli) @@ -693,7 +693,7 @@ void LatexGenerator::endIndexSection(IndexSections is) break; case isDirDocumentation: { - SDict::Iterator dli(Doxygen::directories); + SDict::Iterator dli(*Doxygen::directories); DirDef *dd; bool found=FALSE; for (dli.toFirst();(dd=dli.current()) && !found;++dli) @@ -716,7 +716,7 @@ void LatexGenerator::endIndexSection(IndexSections is) break; case isNamespaceDocumentation: { - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; bool found=FALSE; for (nli.toFirst();(nd=nli.current()) && !found;++nli) @@ -740,7 +740,7 @@ void LatexGenerator::endIndexSection(IndexSections is) break; case isClassDocumentation: { - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd=0; bool found=FALSE; for (cli.toFirst();(cd=cli.current()) && !found;++cli) @@ -764,7 +764,7 @@ void LatexGenerator::endIndexSection(IndexSections is) case isFileDocumentation: { bool isFirst=TRUE; - FileName *fn=Doxygen::inputNameList.first(); + FileName *fn=Doxygen::inputNameList->first(); while (fn) { FileDef *fd=fn->first(); @@ -785,7 +785,7 @@ void LatexGenerator::endIndexSection(IndexSections is) } fd=fn->next(); } - fn=Doxygen::inputNameList.next(); + fn=Doxygen::inputNameList->next(); } } break; @@ -870,18 +870,21 @@ void LatexGenerator::writeString(const char *text) t << text; } -void LatexGenerator::writeIndexItem(const char *ref,const char *fn, - const char *name) +void LatexGenerator::startIndexItem(const char *ref,const char *fn) { t << "\\item "; if (!ref && fn) { t << "\\contentsline{section}{"; - docify(name); + } +} + +void LatexGenerator::endIndexItem(const char *ref,const char *fn) +{ + if (!ref && fn) + { t << "}{\\pageref{" << fn << "}}{}" << endl; } - else - docify(name); } //void LatexGenerator::writeIndexFileItem(const char *,const char *text) @@ -999,7 +1002,7 @@ void LatexGenerator::writeObjectLink(const char *ref, const char *f, } else { - t << "\\bf{"; + t << "{\\bf"; docify(text); t << "}"; } @@ -1007,7 +1010,7 @@ void LatexGenerator::writeObjectLink(const char *ref, const char *f, void LatexGenerator::startPageRef() { - t << " \\doxyref{"; + t << " \\doxyref{}{"; } void LatexGenerator::endPageRef(const char *clname, const char *anchor) diff --git a/src/latexgen.h b/src/latexgen.h index 23f87ce..2a502e4 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -70,7 +70,8 @@ class LatexGenerator : public OutputGenerator void endIndexValue(const char *,bool); void startItemList() { t << "\\begin{CompactItemize}" << endl; } void endItemList() { t << "\\end{CompactItemize}" << endl; } - void writeIndexItem(const char *ref,const char *file,const char *name); + void startIndexItem(const char *ref,const char *file); + void endIndexItem(const char *ref,const char *file); void docify(const char *text); void codify(const char *text); void writeObjectLink(const char *ref,const char *file, diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in index 62b8d33..957e056 100644 --- a/src/libdoxygen.pro.in +++ b/src/libdoxygen.pro.in @@ -60,15 +60,18 @@ HEADERS = bufstr.h \ language.h \ latexdocvisitor.h \ latexgen.h \ + lockingptr.h \ logos.h \ mandocvisitor.h \ mangen.h \ + marshal.h \ memberdef.h \ membergroup.h \ memberlist.h \ membername.h \ message.h \ namespacedef.h \ + objcache.h \ outputgen.h \ outputlist.h \ pagedef.h \ @@ -88,6 +91,7 @@ HEADERS = bufstr.h \ search_php.h \ section.h \ sortdict.h \ + store.h \ tagreader.h \ translator.h \ translator_adapter.h \ @@ -167,12 +171,14 @@ SOURCES = ce_lex.cpp \ logos.cpp \ mandocvisitor.cpp \ mangen.cpp \ + marshal.cpp \ memberdef.cpp \ membergroup.cpp \ memberlist.cpp \ membername.cpp \ message.cpp \ namespacedef.cpp \ + objcache.cpp \ outputgen.cpp \ outputlist.cpp \ pagedef.cpp \ @@ -187,6 +193,7 @@ SOURCES = ce_lex.cpp \ rtfstyle.cpp \ scanner.cpp \ searchindex.cpp \ + store.cpp \ tagreader.cpp \ translator.cpp \ util.cpp \ diff --git a/src/lockingptr.h b/src/lockingptr.h new file mode 100644 index 0000000..e981056 --- /dev/null +++ b/src/lockingptr.h @@ -0,0 +1,165 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2006 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 LOCKINGPTR_H +#define LOCKINGPTR_H + +/*! @brief Abstract interface for lockable objects. + * + * By implementing this interface, a smart pointer can be created which + * will lock this object. This is used to prevent that an internal pointer + * owned by a lockable object would become invalid when the object is removed from + * memory, leaving the client with an invalid pointer. By letting the client use + * a smart pointer instead of the real object the object will be locked into + * memory until the pointer is no longer used, at which point the owner object will be + * unlock and can be removed from memory. + */ +class LockableObj +{ + public: + LockableObj() : m_lockCount(0) {} + virtual ~LockableObj() {} + + /*! Returns TRUE if the object is currently locked. */ + bool isLocked() const { return m_lockCount>0; } + +#ifndef _WIN32 + protected: +#endif + /*! Called when the object is locked. */ + virtual void lock() const = 0; + + /*! Called when the object is unlocked. */ + virtual void unlock() const = 0; + +#ifndef _WIN32 // HACK: VC++ 6.0 does not understand friend template classes. + private: + template friend class LockingPtr; +#endif + + int m_lockCount; +}; + +/*! @brief Smart pointer which keeps a lock on the owner of the pointer. + * + * With the pointer an owner object derived from LockableObj is associated. + * As long as the smart object exists it will keep a lock on the obj by calling + * LockableObj::lock(). Smart pointers can be copied and passed by value. As + * soon as there or no more smart pointer references to the object, + * LockableObj::unlock() will be called automatically. + */ +template class LockingPtr +{ + LockableObj *m_owner; + const T *m_ptr; + + public: + /*! Creates a smart pointer for pointer \a p owned by object \a o. + */ + LockingPtr(const LockableObj *o,const T* p) + { + if (o->m_lockCount==0) o->lock(); + m_owner = (LockableObj *)o; + m_owner->m_lockCount++; + m_ptr = p; + } + + /*! Copies the smart pointer \a lp + */ + LockingPtr(const LockingPtr &lp) + { + m_ptr = lp.m_ptr; + m_owner = lp.m_owner; + m_owner->m_lockCount++; + } + + /*! Assigns the smart pointer \a lp + */ + LockingPtr &operator=(const LockingPtr &lp) + { + m_owner->m_lockCount--; + if (m_owner->m_lockCount==0) // no more references + { + m_owner->unlock(); + } + m_ptr = lp.m_ptr; + m_owner = lp.m_owner; + m_owner->m_lockCount++; + return *this; + } + + /*! Destroys the smart pointer, will unlock the owner. + */ + ~LockingPtr() + { + m_owner->m_lockCount--; + if (m_owner->m_lockCount==0) // no more references + { + m_owner->unlock(); + } + } + + bool isNull() const + { + return m_ptr==0; + } + + bool operator!() const + { + return !m_ptr; + } + + bool operator==(T *p) const + { + return m_ptr==p; + } + + bool operator==(const LockingPtr &lp) const + { + return m_ptr==lp.m_ptr; + } + + bool operator!=(T *p) const + { + return m_ptr!=p; + } + + bool operator!=(const LockingPtr &lp) const + { + return m_ptr!=lp.m_ptr; + } + + /*! Dereference operator */ + const T& operator* () const + { + return *m_ptr; + } + + T* pointer() const + { + return (T*)m_ptr; + } + + /*! Pointer operator */ + T* operator-> () const + { + return (T*)m_ptr; + } +}; + +#endif // LOCKINGPTR_H + diff --git a/src/mangen.cpp b/src/mangen.cpp index 278c267..6eeb184 100644 --- a/src/mangen.cpp +++ b/src/mangen.cpp @@ -184,8 +184,11 @@ void ManGenerator::writeString(const char *text) docify(text); } -void ManGenerator::writeIndexItem(const char *,const char *, - const char *) +void ManGenerator::startIndexItem(const char *,const char *) +{ +} + +void ManGenerator::endIndexItem(const char *,const char *) { } diff --git a/src/mangen.h b/src/mangen.h index 738fd65..9908977 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -74,7 +74,8 @@ class ManGenerator : public OutputGenerator //void startAlphabeticalIndexList() {} //void endAlphabeticalIndexList() {} //void writeIndexHeading(const char *) {} - void writeIndexItem(const char *ref,const char *file,const char *name); + void startIndexItem(const char *ref,const char *file); + void endIndexItem(const char *ref,const char *file); void docify(const char *text); void codify(const char *text); void writeObjectLink(const char *ref,const char *file, diff --git a/src/marshal.cpp b/src/marshal.cpp new file mode 100644 index 0000000..a625369 --- /dev/null +++ b/src/marshal.cpp @@ -0,0 +1,639 @@ +#include +#include + +#include "sortdict.h" +#include "marshal.h" +#include "entry.h" +#include "section.h" +#include "memberlist.h" +#include "definition.h" +#include "groupdef.h" +#include "example.h" + + +void marshalInt(StorageIntf *s,int v) +{ + uchar b[4]; + b[0]=((uint)v)>>24; + b[1]=(((uint)v)>>16)&0xff; + b[2]=(((uint)v)>>8)&0xff; + b[3]=v&0xff; + s->write((const char *)b,4); +} + +void marshalUInt(StorageIntf *s,uint v) +{ + uchar b[4]; + b[0]=v>>24; + b[1]=(v>>16)&0xff; + b[2]=(v>>8)&0xff; + b[3]=v&0xff; + s->write((const char *)b,4); +} + +void marshalBool(StorageIntf *s,bool b) +{ + char c = b; + s->write(&c,sizeof(char)); +} + +void marshalQCString(StorageIntf *s,const QCString &str) +{ + uint l=str.length(); + marshalUInt(s,l); + if (l>0) s->write(str.data(),l); +} + +void marshalQGString(StorageIntf *s,const QGString &str) +{ + uint l=str.length(); + marshalUInt(s,l); + if (l>0) s->write(str.data(),l); +} + +void marshalArgumentList(StorageIntf *s,ArgumentList *argList) +{ + if (argList==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,argList->count()); + if (argList->count()>0) + { + ArgumentListIterator ali(*argList); + Argument *a; + for (ali.toFirst();(a=ali.current());++ali) + { + marshalQCString(s,a->attrib); + marshalQCString(s,a->type); + marshalQCString(s,a->canType); + marshalQCString(s,a->name); + marshalQCString(s,a->array); + marshalQCString(s,a->defval); + marshalQCString(s,a->docs); + } + } + marshalBool(s,argList->constSpecifier); + marshalBool(s,argList->volatileSpecifier); + marshalBool(s,argList->pureSpecifier); + } +} + +void marshalArgumentLists(StorageIntf *s,QList *argLists) +{ + if (argLists==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,argLists->count()); + QListIterator ali(*argLists); + ArgumentList *al; + for (ali.toFirst();(al=ali.current());++ali) + { + marshalArgumentList(s,al); + } + } +} + +void marshalBaseInfoList(StorageIntf *s, QList *baseList) +{ + if (baseList==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,baseList->count()); + QListIterator bli(*baseList); + BaseInfo *bi; + for (bli.toFirst();(bi=bli.current());++bli) + { + marshalQCString(s,bi->name); + marshalInt(s,(int)bi->prot); + marshalInt(s,(int)bi->virt); + } + } +} + +void marshalGroupingList(StorageIntf *s, QList *groups) +{ + if (groups==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,groups->count()); + QListIterator gli(*groups); + Grouping *g; + for (gli.toFirst();(g=gli.current());++gli) + { + marshalQCString(s,g->groupname); + marshalInt(s,(int)g->pri); + } + } +} + +void marshalSectionInfoList(StorageIntf *s, QList *anchors) +{ + if (anchors==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,anchors->count()); + QListIterator sli(*anchors); + SectionInfo *si; + for (sli.toFirst();(si=sli.current());++sli) + { + marshalQCString(s,si->label); + marshalQCString(s,si->title); + marshalQCString(s,si->ref); + marshalInt(s,(int)si->type); + marshalQCString(s,si->fileName); + } + } +} + +void marshalItemInfoList(StorageIntf *s, QList *sli) +{ + if (sli==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,sli->count()); + QListIterator liii(*sli); + ListItemInfo *lii; + for (liii.toFirst();(lii=liii.current());++liii) + { + marshalQCString(s,lii->type); + marshalInt(s,lii->itemId); + } + } +} + +void marshalObjPointer(StorageIntf *s,void *obj) +{ + char *b = (char *)&obj; + s->write(b,sizeof(void *)); +} + +void marshalSectionDict(StorageIntf *s,SectionDict *sections) +{ + if (sections==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,sections->count()); + QDictIterator sli(*sections); + SectionInfo *si; + for (sli.toFirst();(si=sli.current());++sli) + { + marshalQCString(s,sli.currentKey()); + marshalObjPointer(s,si); + } + } +} + +void marshalMemberSDict(StorageIntf *s,MemberSDict *memberSDict) +{ + if (memberSDict==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,memberSDict->count()); + //printf(" marshalMemberSDict: items=%d\n",memberSDict->count()); + SDict::IteratorDict mdi(*memberSDict); + MemberDef *md; + int count=0; + for (mdi.toFirst();(md=mdi.current());++mdi) + { + //printf(" marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md); + marshalQCString(s,mdi.currentKey()); + marshalObjPointer(s,md); + count++; + } + assert(count==memberSDict->count()); + } +} + +void marshalDocInfo(StorageIntf *s,DocInfo *docInfo) +{ + if (docInfo==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,1); + marshalQCString(s,docInfo->doc); + marshalInt(s,docInfo->line); + marshalQCString(s,docInfo->file); + } +} + +void marshalBodyInfo(StorageIntf *s,BodyInfo *bodyInfo) +{ + if (bodyInfo==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,1); + marshalInt(s,bodyInfo->startLine); + marshalInt(s,bodyInfo->endLine); + marshalObjPointer(s,bodyInfo->fileDef); + } +} + +void marshalGroupList(StorageIntf *s,GroupList *groupList) +{ + if (groupList==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,groupList->count()); + QListIterator gli(*groupList); + GroupDef *gd=0; + for (gli.toFirst();(gd=gli.current());++gli) + { + marshalObjPointer(s,gd); + } + } +} + +void marshalMemberList(StorageIntf *s,MemberList *ml) +{ + if (ml==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,1); // not a null pointer + ml->marshal(s); + } +} + +void marshalExampleSDict(StorageIntf *s,ExampleSDict *ed) +{ + if (ed==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,ed->count()); + //printf(" marshalMemberSDict: items=%d\n",memberSDict->count()); + SDict::IteratorDict edi(*ed); + Example *e; + for (edi.toFirst();(e=edi.current());++edi) + { + //printf(" marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md); + marshalQCString(s,edi.currentKey()); + marshalQCString(s,e->anchor); + marshalQCString(s,e->name); + marshalQCString(s,e->file); + } + } +} + +void marshalMemberLists(StorageIntf *s,SDict *mls) +{ + if (mls==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,mls->count()); + //printf(" marshalMemberSDict: items=%d\n",memberSDict->count()); + SDict::IteratorDict mli(*mls); + MemberList *ml; + for (mli.toFirst();(ml=mli.current());++mli) + { + //printf(" marshalMemberSDict: %d: key=%s value=%p\n",count,mdi.currentKey().data(),md); + marshalQCString(s,mli.currentKey()); + marshalObjPointer(s,ml); // assume we are not owner of the list + } + } +} + +//------------------------------------------------------------------ + +int unmarshalInt(StorageIntf *s) +{ + uchar b[4]; + s->read((char *)b,4); + int result=(int)((((uint)b[0])<<24)+((uint)b[1]<<16)+((uint)b[2]<<8)+(uint)b[3]); + //printf("unmarshalInt: %x %x %x %x: %x offset=%llx\n",b[0],b[1],b[2],b[3],result,f.pos()); + return result; +} + +uint unmarshalUInt(StorageIntf *s) +{ + uchar b[4]; + s->read((char *)b,4); + uint result=(((uint)b[0])<<24)+((uint)b[1]<<16)+((uint)b[2]<<8)+(uint)b[3]; + //printf("unmarshalUInt: %x %x %x %x: %x offset=%llx\n",b[0],b[1],b[2],b[3],result,f.pos()); + return result; +} + +bool unmarshalBool(StorageIntf *s) +{ + char result; + s->read(&result,sizeof(result)); + //printf("unmarshalBool: %x offset=%llx\n",result,f.pos()); + return result; +} + +QCString unmarshalQCString(StorageIntf *s) +{ + uint len = unmarshalUInt(s); + //printf("unmarshalQCString: len=%d offset=%llx\n",len,f.pos()); + QCString result(len+1); + result.at(len)='\0'; + if (len>0) + { + s->read(result.data(),len); + } + //printf("unmarshalQCString: result=%s\n",result.data()); + return result; +} + +QGString unmarshalQGString(StorageIntf *s) +{ + uint len = unmarshalUInt(s); + //printf("unmarshalQCString: len=%d offset=%llx\n",len,f.pos()); + QGString result(len+1); + result.at(len)='\0'; + if (len>0) + { + s->read(result.data(),len); + } + //printf("unmarshalQCString: result=%s\n",result.data()); + return result; +} + +ArgumentList *unmarshalArgumentList(StorageIntf *s) +{ + uint i; + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; // null list + ArgumentList *result = new ArgumentList; + assert(count<1000000); + //printf("unmarshalArgumentList: %d\n",count); + for (i=0;iattrib = unmarshalQCString(s); + a->type = unmarshalQCString(s); + a->canType = unmarshalQCString(s); + a->name = unmarshalQCString(s); + a->array = unmarshalQCString(s); + a->defval = unmarshalQCString(s); + a->docs = unmarshalQCString(s); + result->append(a); + } + result->constSpecifier = unmarshalBool(s); + result->volatileSpecifier = unmarshalBool(s); + result->pureSpecifier = unmarshalBool(s); + return result; +} + +QList *unmarshalArgumentLists(StorageIntf *s) +{ + uint i; + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; // null list + QList *result = new QList; + result->setAutoDelete(TRUE); + assert(count<1000000); + //printf("unmarshalArgumentLists: %d\n",count); + for (i=0;iappend(unmarshalArgumentList(s)); + } + return result; +} + +QList *unmarshalBaseInfoList(StorageIntf *s) +{ + uint i; + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; // null list + QList *result = new QList; + result->setAutoDelete(TRUE); + assert(count<1000000); + for (i=0;iappend(new BaseInfo(name,prot,virt)); + } + return result; +} + +QList *unmarshalGroupingList(StorageIntf *s) +{ + uint i; + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; // null list + QList *result = new QList; + result->setAutoDelete(TRUE); + assert(count<1000000); + for (i=0;iappend(new Grouping(name,prio)); + } + return result; +} + +QList *unmarshalSectionInfoList(StorageIntf *s) +{ + uint i; + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; // null list + QList *result = new QList; + result->setAutoDelete(TRUE); + assert(count<1000000); + for (i=0;iappend(new SectionInfo(fileName,label,title,type,ref)); + } + return result; +} + +QList *unmarshalItemInfoList(StorageIntf *s) +{ + uint i; + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; // null list + QList *result = new QList; + result->setAutoDelete(TRUE); + assert(count<1000000); + for (i=0;itype = unmarshalQCString(s); + lii->itemId = unmarshalInt(s); + result->append(lii); + } + return result; +} + +void *unmarshalObjPointer(StorageIntf *s) +{ + void *result; + s->read((char *)&result,sizeof(void*)); + return result; +} + +SectionDict *unmarshalSectionDict(StorageIntf *s) +{ + uint i; + uint count = unmarshalUInt(s); + //printf("unmarshalSectionDict count=%d\n",count); + if (count==NULL_LIST) return 0; // null list + SectionDict *result = new SectionDict(17); + assert(count<1000000); + for (i=0;ilabel.data()); + result->insert(key,si); + } + return result; +} + +MemberSDict *unmarshalMemberSDict(StorageIntf *s) +{ + uint i; + uint count = unmarshalUInt(s); + //printf("--- unmarshalMemberSDict count=%d\n",count); + if (count==NULL_LIST) + { + //printf("--- end unmarshalMemberSDict\n"); + return 0; // null list + } + MemberSDict *result = new MemberSDict; + assert(count<1000000); + //printf("Reading %d key-value pairs\n",count); + for (i=0;iinSort(key,md); // note: this can lead to unmarshalling another object! + } + //printf("--- end unmarshalMemberSDict\n"); + return result; +} + +DocInfo *unmarshalDocInfo(StorageIntf *s) +{ + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; + DocInfo *result = new DocInfo; + result->doc = unmarshalQCString(s); + result->line = unmarshalInt(s); + result->file = unmarshalQCString(s); + return result; +} + +BodyInfo *unmarshalBodyInfo(StorageIntf *s) +{ + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; + BodyInfo *result = new BodyInfo; + result->startLine = unmarshalInt(s); + result->endLine = unmarshalInt(s); + result->fileDef = (FileDef*)unmarshalObjPointer(s); + return result; +} + +GroupList *unmarshalGroupList(StorageIntf *s) +{ + uint i; + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; // null list + assert(count<1000000); + GroupList *result = new GroupList; + for (i=0;iappend(gd); + } + return result; +} + +MemberList *unmarshalMemberList(StorageIntf *s) +{ + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; + MemberList *ml = new MemberList; + ml->unmarshal(s); + return ml; +} + +ExampleSDict *unmarshalExampleSDict(StorageIntf *s) +{ + uint i; + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; + ExampleSDict *result = new ExampleSDict; + assert(count<1000000); + for (i=0;ianchor); + marshalQCString(s,e->name); + marshalQCString(s,e->file); + result->inSort(key,e); + } + return result; +} + +SDict *unmarshalMemberLists(StorageIntf *s) +{ + uint i; + uint count = unmarshalUInt(s); + if (count==NULL_LIST) return 0; + SDict *result = new SDict(7); + assert(count<1000000); + for (i=0;iappend(key,ml); + } + return result; +} + + diff --git a/src/marshal.h b/src/marshal.h new file mode 100644 index 0000000..dd751fa --- /dev/null +++ b/src/marshal.h @@ -0,0 +1,81 @@ +#ifndef MARSHAL_H +#define MARSHAL_H + +#include +#include +#include "sortdict.h" +#include "store.h" + +class ArgumentList; +class BaseInfo; +class Grouping; +class SectionInfo; +class ListItemInfo; +class QCString; +class QGString; +class SectionDict; +class MemberSDict; +class GroupList; +class BodyInfo; +class DocInfo; +class MemberList; +class ExampleSDict; + +#define NULL_LIST 0xffffffff + +class FileStorage : public QFile, public StorageIntf +{ + public: + FileStorage() : QFile() {} + FileStorage( const QString &name) : QFile(name) {} + int read(char *buf,uint size) { return QFile::readBlock(buf,size); } + int write(const char *buf,uint size) { return QFile::writeBlock(buf,size); } +}; + +//----- marshaling function: datatype -> byte stream -------------------- + +void marshalInt(StorageIntf *s,int v); +void marshalUInt(StorageIntf *s,uint v); +void marshalBool(StorageIntf *s,bool b); +void marshalQCString(StorageIntf *s,const QCString &str); +void marshalQGString(StorageIntf *s,const QGString &str); +void marshalArgumentList(StorageIntf *s,ArgumentList *argList); +void marshalArgumentLists(StorageIntf *s,QList *argLists); +void marshalBaseInfoList(StorageIntf *s, QList *baseList); +void marshalGroupingList(StorageIntf *s, QList *groups); +void marshalSectionInfoList(StorageIntf *s, QList *anchors); +void marshalItemInfoList(StorageIntf *s, QList *sli); +void marshalObjPointer(StorageIntf *s,void *obj); +void marshalSectionDict(StorageIntf *s,SectionDict *sections); +void marshalMemberSDict(StorageIntf *s,MemberSDict *memberSDict); +void marshalDocInfo(StorageIntf *s,DocInfo *docInfo); +void marshalBodyInfo(StorageIntf *s,BodyInfo *bodyInfo); +void marshalGroupList(StorageIntf *s,GroupList *groupList); +void marshalMemberList(StorageIntf *s,MemberList *ml); +void marshalExampleSDict(StorageIntf *s,ExampleSDict *ed); +void marshalMemberLists(StorageIntf *s,SDict *mls); + +//----- unmarshaling function: byte stream -> datatype ------------------ + +int unmarshalInt(StorageIntf *s); +uint unmarshalUInt(StorageIntf *s); +bool unmarshalBool(StorageIntf *s); +QCString unmarshalQCString(StorageIntf *s); +QGString unmarshalQGString(StorageIntf *s); +ArgumentList * unmarshalArgumentList(StorageIntf *s); +QList *unmarshalArgumentLists(StorageIntf *s); +QList * unmarshalBaseInfoList(StorageIntf *s); +QList * unmarshalGroupingList(StorageIntf *s); +QList * unmarshalSectionInfoList(StorageIntf *s); +QList *unmarshalItemInfoList(StorageIntf *s); +void * unmarshalObjPointer(StorageIntf *s); +SectionDict * unmarshalSectionDict(StorageIntf *s); +MemberSDict * unmarshalMemberSDict(StorageIntf *s); +DocInfo * unmarshalDocInfo(StorageIntf *s); +BodyInfo * unmarshalBodyInfo(StorageIntf *s); +GroupList * unmarshalGroupList(StorageIntf *s); +MemberList * unmarshalMemberList(StorageIntf *s); +ExampleSDict * unmarshalExampleSDict(StorageIntf *s); +SDict * unmarshalMemberLists(StorageIntf *s); + +#endif diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 3759a65..9ae8123 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "memberdef.h" #include "membername.h" @@ -35,6 +36,10 @@ #include "dot.h" #include "searchindex.h" #include "parserintf.h" +#include "marshal.h" + +#define START_MARKER 0x4D454D5B // MEM[ +#define END_MARKER 0x4D454D5D // MEM] //----------------------------------------------------------------------------- @@ -79,7 +84,7 @@ static QCString addTemplateNames(const QCString &s,const QCString &n,const QCStr static bool writeDefArgumentList(OutputList &ol,ClassDef *cd, const QCString & /*scopeName*/,MemberDef *md) { - ArgumentList *defArgList=(md->isDocsForDefinition() && !md->isProperty()) ? + LockingPtr defArgList=(md->isDocsForDefinition() && !md->isProperty()) ? md->argumentList() : md->declArgumentList(); //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition()); if (defArgList==0) @@ -285,6 +290,262 @@ static void writeTemplatePrefix(OutputList &ol,ArgumentList *al) } //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +class MemberDefImpl +{ + public: + MemberDefImpl(); + ~MemberDefImpl(); + void init(Definition *def,const char *t,const char *a,const char *e, + Protection p,Specifier v,bool s,bool r,MemberDef::MemberType mt, + const ArgumentList *tal,const ArgumentList *al + ); + + ClassDef *classDef; // member of or related to + FileDef *fileDef; // member of file definition + NamespaceDef *nspace; // the namespace this member is in. + + MemberDef *enumScope; // the enclosing scope, if this is an enum field + MemberDef *annEnumType; // the annonymous enum that is the type of this member + MemberList *enumFields; // enumeration fields + + MemberDef *redefines; // the members that this member redefines + MemberList *redefinedBy; // the list of members that redefine this one + + MemberDef *memDef; // member definition for this declaration + MemberDef *memDec; // member declaration for this definition + ClassDef *relatedAlso; // points to class marked by relatedAlso + + ExampleSDict *exampleSDict; // a dictionary of all examples for quick access + + QCString type; // return type + QCString args; // function arguments/variable array specifiers + QCString def; // member definition in code (fully qualified name) + QCString anc; // HTML anchor name + Specifier virt; // normal/virtual/pure virtual + Protection prot; // protection type [Public/Protected/Private] + QCString decl; // member declaration in class + + QCString bitfields; // struct member bitfields + QCString read; // property read accessor + QCString write; // property write accessor + QCString exception; // exceptions that can be thrown + QCString initializer; // initializer + int initLines; // number of lines in the initializer + + int memSpec; // The specifiers present for this member + MemberDef::MemberType mtype; // returns the kind of member + int maxInitLines; // when the initializer will be displayed + int userInitLines; // result of explicit \hideinitializer or \showinitializer + MemberDef *annMemb; + + ArgumentList *defArgList; // argument list of this member definition + ArgumentList *declArgList; // argument list of this member declaration + + ArgumentList *tArgList; // template argument list of function template + MemberDef *templateMaster; + QList *defTmpArgLists; // lists of template argument lists + // (for template functions in nested template classes) + + ClassDef *cachedAnonymousType; // if the member has an anonymous compound + // as its type then this is computed by + // getClassDefOfAnonymousType() and + // cached here. + SDict *classSectionSDict; // not accessible + + MemberDef *groupAlias; // Member containing the definition + int grpId; // group id + MemberGroup *memberGroup; // group's member definition + GroupDef *group; // group in which this member is in + Grouping::GroupPri_t grouppri; // priority of this definition + QCString groupFileName; // file where this grouping was defined + int groupStartLine; // line " " " " " + MemberDef *groupMember; + + bool isTypedefValCached; + ClassDef *cachedTypedefValue; + QCString cachedTypedefTemplSpec; + + // inbody documentation + int inbodyLine; + QCString inbodyFile; + QCString inbodyDocs; + + // documentation inheritance + MemberDef *docProvider; + + // to store the output file base from tag files + QCString explicitOutputFileBase; + + // objective-c + bool implOnly; // function found in implementation but not + // in the interface + bool hasDocumentedParams; + bool hasDocumentedReturnType; + bool isDMember; + bool related; // is this a member that is only related to a class + bool stat; // is it a static function? + bool proto; // is it a prototype; + bool docEnumValues; // is an enum with documented enum values. + bool annScope; // member is part of an annoymous scope + bool annUsed; + bool hasCallGraph; + bool hasCallerGraph; + bool explExt; // member was explicitly declared external + bool tspec; // member is a template specialization + bool groupHasDocs; // true if the entry that caused the grouping was documented + bool docsForDefinition; // TRUE => documentation block is put before + // definition. + // FALSE => block is put before declaration. +}; + +MemberDefImpl::MemberDefImpl() : + enumFields(0), + redefinedBy(0), + exampleSDict(0), + defArgList(0), + declArgList(0), + tArgList(0), + defTmpArgLists(0), + classSectionSDict(0) +{ +} + +MemberDefImpl::~MemberDefImpl() +{ + delete redefinedBy; + delete exampleSDict; + delete enumFields; + delete defArgList; + delete tArgList; + delete defTmpArgLists; + delete classSectionSDict; + delete declArgList; +} + +void MemberDefImpl::init(Definition *def, + const char *t,const char *a,const char *e, + Protection p,Specifier v,bool s,bool r,MemberDef::MemberType mt, + const ArgumentList *tal,const ArgumentList *al + ) +{ + classDef=0; + fileDef=0; + redefines=0; + relatedAlso=0; + redefinedBy=0; + nspace=0; + memDef=0; + memDec=0; + group=0; + grpId=-1; + exampleSDict=0; + enumFields=0; + enumScope=0; + defTmpArgLists=0; + hasCallGraph = FALSE; + hasCallerGraph = FALSE; + initLines=0; + type=t; + if (mt==MemberDef::Typedef) type.stripPrefix("typedef "); + type.stripPrefix("struct "); + type.stripPrefix("class " ); + type.stripPrefix("union " ); + type=removeRedundantWhiteSpace(type); + args=a; + args=removeRedundantWhiteSpace(args); + if (type.isEmpty()) decl=def->name()+args; else decl=type+" "+def->name()+args; + + memberGroup=0; + virt=v; + prot=p; + related=r; + stat=s; + mtype=mt; + exception=e; + proto=FALSE; + annScope=FALSE; + memSpec=0; + annMemb=0; + annUsed=FALSE; + annEnumType=0; + groupAlias=0; + explExt=FALSE; + tspec=FALSE; + cachedAnonymousType=0; + maxInitLines=Config_getInt("MAX_INITIALIZER_LINES"); + userInitLines=-1; + docEnumValues=FALSE; + // copy function template arguments (if any) + if (tal) + { + tArgList = new ArgumentList; + tArgList->setAutoDelete(TRUE); + ArgumentListIterator ali(*tal); + Argument *a; + for (;(a=ali.current());++ali) + { + tArgList->append(new Argument(*a)); + } + } + else + { + tArgList=0; + } + //printf("new member al=%p\n",al); + // copy function definition arguments (if any) + if (al) + { + defArgList = new ArgumentList; + defArgList->setAutoDelete(TRUE); + ArgumentListIterator ali(*al); + Argument *a; + for (;(a=ali.current());++ali) + { + //printf("copy argument %s (doc=%s)\n",a->name.data(),a->docs.data()); + defArgList->append(new Argument(*a)); + } + defArgList->constSpecifier = al->constSpecifier; + defArgList->volatileSpecifier = al->volatileSpecifier; + defArgList->pureSpecifier = al->pureSpecifier; + //printf("defArgList(%p)->constSpecifier=%d\n",defArgList,defArgList->constSpecifier); + } + else + { + defArgList=0; + } + // convert function declaration arguments (if any) + if (!args.isEmpty()) + { + declArgList = new ArgumentList; + stringToArgumentList(args,declArgList); + //printf("setDeclArgList %s to %p const=%d\n",args.data(), + // declArgList,declArgList->constSpecifier); + } + else + { + declArgList = 0; + } + templateMaster = 0; + classSectionSDict = 0; + docsForDefinition = TRUE; + isTypedefValCached = FALSE; + cachedTypedefValue = 0; + inbodyLine = -1; + implOnly=FALSE; + groupMember = 0; + hasDocumentedParams = FALSE; + hasDocumentedReturnType = FALSE; + docProvider = 0; + isDMember = def->getDefFileName().right(2).lower()==".d"; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- /*! Creates a new member definition. * @@ -311,8 +572,12 @@ MemberDef::MemberDef(const char *df,int dl, const char *t,const char *na,const char *a,const char *e, Protection p,Specifier v,bool s,bool r,MemberType mt, const ArgumentList *tal,const ArgumentList *al - ) : Definition(df,dl,na) + ) : Definition(df,dl,removeRedundantWhiteSpace(na)) { + m_impl = new MemberDefImpl; + m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al); + +#if 0 //printf("++++++ MemberDef(%s file=%s,line=%d static=%d) ++++++ \n", // na,df,dl,s); classDef=0; @@ -328,9 +593,6 @@ MemberDef::MemberDef(const char *df,int dl, exampleSDict=0; enumFields=0; enumScope=0; - enumDeclList=0; - //scopeTAL=0; - //membTAL=0; m_defTmpArgLists=0; m_hasCallGraph = FALSE; m_hasCallerGraph = FALSE; @@ -346,7 +608,6 @@ MemberDef::MemberDef(const char *df,int dl, args=removeRedundantWhiteSpace(args); if (type.isEmpty()) decl=name()+args; else decl=type+" "+name()+args; - //declLine=0; memberGroup=0; virt=v; prot=p; @@ -359,10 +620,7 @@ MemberDef::MemberDef(const char *df,int dl, memSpec=0; annMemb=0; annUsed=FALSE; - annShown=FALSE; annEnumType=0; - //indDepth=0; - section=0; groupAlias=0; explExt=FALSE; tspec=FALSE; @@ -432,71 +690,71 @@ MemberDef::MemberDef(const char *df,int dl, m_hasDocumentedReturnType = FALSE; m_docProvider = 0; m_isDMember = getDefFileName().right(2).lower()==".d"; +#endif } /*! Destroys the member definition. */ MemberDef::~MemberDef() { - delete redefinedBy; - delete exampleSDict; - delete enumFields; - delete defArgList; - delete tArgList; - delete m_defTmpArgLists; - delete classSectionSDict; - delete declArgList; + delete m_impl; } void MemberDef::setReimplements(MemberDef *md) { + makeResident(); //if (redefines==0) redefines = new MemberList; //if (redefines->find(md)==-1) redefines->inSort(md); - redefines = md; + m_impl->redefines = md; } void MemberDef::insertReimplementedBy(MemberDef *md) { - if (m_templateMaster) + makeResident(); + if (m_impl->templateMaster) { - m_templateMaster->insertReimplementedBy(md); + m_impl->templateMaster->insertReimplementedBy(md); } - if (redefinedBy==0) redefinedBy = new MemberList(MemberList::redefinedBy); - if (redefinedBy->findRef(md)==-1) + if (m_impl->redefinedBy==0) m_impl->redefinedBy = new MemberList(MemberList::redefinedBy); + if (m_impl->redefinedBy->findRef(md)==-1) { - redefinedBy->inSort(md); + m_impl->redefinedBy->inSort(md); } } MemberDef *MemberDef::reimplements() const { - return redefines; + makeResident(); + return m_impl->redefines; } -MemberList *MemberDef::reimplementedBy() const +LockingPtr MemberDef::reimplementedBy() const { - return redefinedBy; + makeResident(); + return LockingPtr(this,m_impl->redefinedBy); } void MemberDef::insertEnumField(MemberDef *md) { - if (enumFields==0) enumFields=new MemberList(MemberList::enumFields); - enumFields->append(md); + makeResident(); + if (m_impl->enumFields==0) m_impl->enumFields=new MemberList(MemberList::enumFields); + m_impl->enumFields->append(md); } bool MemberDef::addExample(const char *anchor,const char *nameStr, const char *file) { + makeResident(); //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file); - if (exampleSDict==0) exampleSDict = new ExampleSDict; - if (exampleSDict->find(nameStr)==0) + if (m_impl->exampleSDict==0) m_impl->exampleSDict = new ExampleSDict; + if (m_impl->exampleSDict->find(nameStr)==0) { //printf("Add reference to example %s to member %s\n",nameStr,name.data()); Example *e=new Example; e->anchor=anchor; e->name=nameStr; e->file=file; - exampleSDict->inSort(nameStr,e); + m_impl->exampleSDict->inSort(nameStr,e); return TRUE; } return FALSE; @@ -504,39 +762,41 @@ bool MemberDef::addExample(const char *anchor,const char *nameStr, bool MemberDef::hasExamples() { - if (exampleSDict==0) + makeResident(); + if (m_impl->exampleSDict==0) return FALSE; else - return exampleSDict->count()>0; + return m_impl->exampleSDict->count()>0; } QCString MemberDef::getOutputFileBase() const { + makeResident(); static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES"); QCString baseName; - if (explicitOutputFileBase) + if (m_impl->explicitOutputFileBase) { - return explicitOutputFileBase; + return m_impl->explicitOutputFileBase; } - else if (m_templateMaster) + else if (m_impl->templateMaster) { - return m_templateMaster->getOutputFileBase(); + return m_impl->templateMaster->getOutputFileBase(); } - else if (group) + else if (m_impl->group) { - baseName=group->getOutputFileBase(); + baseName=m_impl->group->getOutputFileBase(); } - else if (classDef) + else if (m_impl->classDef) { - baseName=classDef->getOutputFileBase(); + baseName=m_impl->classDef->getOutputFileBase(); } - else if (nspace) + else if (m_impl->nspace) { - baseName=nspace->getOutputFileBase(); + baseName=m_impl->nspace->getOutputFileBase(); } - else if (fileDef) + else if (m_impl->fileDef) { - baseName=fileDef->getOutputFileBase(); + baseName=m_impl->fileDef->getOutputFileBase(); } if (baseName.isEmpty()) @@ -563,40 +823,42 @@ QCString MemberDef::getOutputFileBase() const QCString MemberDef::getReference() const { - if (m_templateMaster) + makeResident(); + if (m_impl->templateMaster) { - return m_templateMaster->getReference(); + return m_impl->templateMaster->getReference(); } - else if (group) + else if (m_impl->group) { - return group->getReference(); + return m_impl->group->getReference(); } - else if (classDef) + else if (m_impl->classDef) { - return classDef->getReference(); + return m_impl->classDef->getReference(); } - else if (nspace) + else if (m_impl->nspace) { - return nspace->getReference(); + return m_impl->nspace->getReference(); } - else if (fileDef) + else if (m_impl->fileDef) { - return fileDef->getReference(); + return m_impl->fileDef->getReference(); } return ""; } QCString MemberDef::anchor() const { - QCString result=anc; - if (groupAlias) return groupAlias->anchor(); - if (m_templateMaster) return m_templateMaster->anchor(); - if (enumScope) result.prepend(enumScope->anchor()); - if (group) + makeResident(); + QCString result=m_impl->anc; + if (m_impl->groupAlias) return m_impl->groupAlias->anchor(); + if (m_impl->templateMaster) return m_impl->templateMaster->anchor(); + if (m_impl->enumScope) result.prepend(m_impl->enumScope->anchor()); + if (m_impl->group) { - if (groupMember) + if (m_impl->groupMember) { - result=groupMember->anchor(); + result=m_impl->groupMember->anchor(); } else { @@ -610,10 +872,11 @@ bool MemberDef::isLinkableInProject() const { static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE"); static bool extractStatic = Config_getBool("EXTRACT_STATIC"); + makeResident(); //printf("MemberDef::isLinkableInProject(name=%s)\n",name().data()); - if (m_templateMaster) + if (m_impl->templateMaster) { - return m_templateMaster->isLinkableInProject(); + return m_impl->templateMaster->isLinkableInProject(); } if (name().isEmpty() || name().at(0)=='@') { @@ -625,32 +888,32 @@ bool MemberDef::isLinkableInProject() const //printf("no docs or reference\n"); return FALSE; // no documentation } - if (group && !group->isLinkableInProject()) + if (m_impl->group && !m_impl->group->isLinkableInProject()) { //printf("group but group not linkable!\n"); return FALSE; // group but group not linkable } - if (!group && classDef && !classDef->isLinkableInProject()) + if (!m_impl->group && m_impl->classDef && !m_impl->classDef->isLinkableInProject()) { //printf("in a class but class not linkable!\n"); return FALSE; // in class but class not linkable } - if (!group && nspace && !related && !nspace->isLinkableInProject()) + if (!m_impl->group && m_impl->nspace && !m_impl->related && !m_impl->nspace->isLinkableInProject()) { //printf("in a namespace but namespace not linkable!\n"); return FALSE; // in namespace but namespace not linkable } - if (!group && !nspace && !related && !classDef && fileDef && !fileDef->isLinkableInProject()) + if (!m_impl->group && !m_impl->nspace && !m_impl->related && !m_impl->classDef && m_impl->fileDef && !m_impl->fileDef->isLinkableInProject()) { //printf("in a file but file not linkable!\n"); return FALSE; // in file (and not in namespace) but file not linkable } - if (prot==Private && !extractPrivate && mtype!=Friend) + if (m_impl->prot==Private && !extractPrivate && m_impl->mtype!=Friend) { //printf("private and invisible!\n"); return FALSE; // hidden due to protection } - if (isStatic() && classDef==0 && !extractStatic) + if (isStatic() && m_impl->classDef==0 && !extractStatic) { //printf("static and invisible!\n"); return FALSE; // hidden due to staticness @@ -661,9 +924,10 @@ bool MemberDef::isLinkableInProject() const bool MemberDef::isLinkable() const { - if (m_templateMaster) + makeResident(); + if (m_impl->templateMaster) { - return m_templateMaster->isLinkable(); + return m_impl->templateMaster->isLinkable(); } else { @@ -676,25 +940,28 @@ void MemberDef::setDefinitionTemplateParameterLists(QList *lists) { if (lists) { - if (m_defTmpArgLists) delete m_defTmpArgLists; - m_defTmpArgLists = copyArgumentLists(lists); + makeResident(); + if (m_impl->defTmpArgLists) delete m_impl->defTmpArgLists; + m_impl->defTmpArgLists = copyArgumentLists(lists); } } void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *, FileDef *fd,GroupDef *gd,bool onlyText) { + makeResident(); + LockingPtr lock(this,this); QCString sep = Config_getBool("OPTIMIZE_OUTPUT_JAVA") ? "." : "::"; QCString n = name(); - if (classDef && gd) n.prepend(classDef->name()+sep); - else if (nspace && (gd || fd)) n.prepend(nspace->name()+sep); + if (m_impl->classDef && gd) n.prepend(m_impl->classDef->name()+sep); + else if (m_impl->nspace && (gd || fd)) n.prepend(m_impl->nspace->name()+sep); if (isObjCMethod()) { if (isStatic()) ol.docify("+ "); else ol.docify("- "); } if (!onlyText) // write link { - if (mtype==EnumValue && getGroupDef()==0 && // enum value is not grouped + if (m_impl->mtype==EnumValue && getGroupDef()==0 && // enum value is not grouped getEnumScope() && getEnumScope()->getGroupDef()) // but its container is { GroupDef *enumValGroup = getEnumScope()->getGroupDef(); @@ -720,7 +987,9 @@ void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *, */ ClassDef *MemberDef::getClassDefOfAnonymousType() { - if (cachedAnonymousType) return cachedAnonymousType; + makeResident(); + if (m_impl->cachedAnonymousType) return m_impl->cachedAnonymousType; + LockingPtr lock(this,this); QCString cname; if (getClassDef()!=0) @@ -731,7 +1000,7 @@ ClassDef *MemberDef::getClassDefOfAnonymousType() { cname=getNamespaceDef()->name().copy(); } - QCString ltype(type); + QCString ltype(m_impl->type); // strip `static' keyword from ltype //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7); // strip `friend' keyword from ltype @@ -766,7 +1035,7 @@ ClassDef *MemberDef::getClassDefOfAnonymousType() annoClassDef=getClass(ts); } } - cachedAnonymousType = annoClassDef; + m_impl->cachedAnonymousType = annoClassDef; return annoClassDef; } @@ -775,95 +1044,97 @@ ClassDef *MemberDef::getClassDefOfAnonymousType() */ bool MemberDef::isBriefSectionVisible() const { - static bool extractStatic = Config_getBool("EXTRACT_STATIC"); - static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS"); - static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC"); - static bool repeatBrief = Config_getBool("REPEAT_BRIEF"); - static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS"); - static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE"); - - //printf("Member %s grpId=%d docs=%s file=%s args=%s\n", - // name().data(), - // 0,"", //grpId,grpId==-1?"":Doxygen::memberDocDict[grpId]->data(), - // "", //getFileDef()->name().data(), - // argsString()); - - MemberGroupInfo *info = Doxygen::memGrpInfoDict[grpId]; - //QCString *pMemGrp = Doxygen::memberDocDict[grpId]; - bool hasDocs = hasDocumentation() || - // part of a documented member group - (grpId!=-1 && info && !info->doc.isEmpty()); - - // only include static members with file/namespace scope if - // explicitly enabled in the config file - bool visibleIfStatic = !(getClassDef()==0 && - isStatic() && - !extractStatic - ); - - // only include members is the are documented or - // HIDE_UNDOC_MEMBERS is NO in the config file - bool visibleIfDocumented = (!hideUndocMembers || - hasDocs || - isDocumentedFriendClass() - ); + static bool extractStatic = Config_getBool("EXTRACT_STATIC"); + static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS"); + static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC"); + static bool repeatBrief = Config_getBool("REPEAT_BRIEF"); + static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS"); + static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE"); + + //printf("Member %s grpId=%d docs=%s file=%s args=%s\n", + // name().data(), + // 0,"", //grpId,grpId==-1?"":Doxygen::memberDocDict[grpId]->data(), + // "", //getFileDef()->name().data(), + // argsString()); + + makeResident(); + LockingPtr lock(this,this); + MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId]; + //QCString *pMemGrp = Doxygen::memberDocDict[grpId]; + bool hasDocs = hasDocumentation() || + // part of a documented member group + (m_impl->grpId!=-1 && info && !info->doc.isEmpty()); + + // only include static members with file/namespace scope if + // explicitly enabled in the config file + bool visibleIfStatic = !(getClassDef()==0 && + isStatic() && + !extractStatic + ); - // hide members with no detailed description and brief descriptions - // explicitly disabled. - bool visibleIfEnabled = !(hideUndocMembers && - documentation().isEmpty() && - !briefMemberDesc && - !repeatBrief + // only include members is the are documented or + // HIDE_UNDOC_MEMBERS is NO in the config file + bool visibleIfDocumented = (!hideUndocMembers || + hasDocs || + isDocumentedFriendClass() ); - // Hide friend (class|struct|union) declarations if HIDE_FRIEND_COMPOUNDS is true - bool visibleIfFriendCompound = !(hideFriendCompounds && - isFriend() && - (type=="friend class" || - type=="friend struct" || - type=="friend union" - ) - ); - - // only include members that are non-private unless EXTRACT_PRIVATE is - // set to YES or the member is part of a group - bool visibleIfPrivate = (protection()!=Private || - extractPrivate || - mtype==Friend - ); - - // hide member if it overrides a member in a superclass and has no - // documentation of its own - //bool visibleIfDocVirtual = !reimplements() || - // !Config_getBool("INHERIT_DOCS") || - // hasDocs; - - // true if this member is a constructor or destructor - bool cOrDTor = isConstructor() || isDestructor(); - - // hide default constructors or destructors (no args) without - // documentation - bool visibleIfNotDefaultCDTor = !(cOrDTor && - defArgList && - (defArgList->isEmpty() || - defArgList->first()->type == "void" - ) && - !hasDocs - ); - - //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d" - // "visibleIfPrivate=%d visibleIfDocVirtual=%d visibltIfNotDefaultCDTor=%d " - // "visibleIfFriendCompound=%d\n",visibleIfStatic,visibleIfDocumented, - // visibleIfEnabled,visibleIfPrivate,visibleIfDocVirtual,visibleIfNotDefaultCDTor, - // visibleIfFriendCompound); - - bool visible = visibleIfStatic && visibleIfDocumented && - visibleIfEnabled && visibleIfPrivate && - /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor && - visibleIfFriendCompound && - !annScope; - //printf("MemberDef::isBriefSectionVisible() %d\n",visible); - return visible; + // hide members with no detailed description and brief descriptions + // explicitly disabled. + bool visibleIfEnabled = !(hideUndocMembers && + documentation().isEmpty() && + !briefMemberDesc && + !repeatBrief + ); + + // Hide friend (class|struct|union) declarations if HIDE_FRIEND_COMPOUNDS is true + bool visibleIfFriendCompound = !(hideFriendCompounds && + isFriend() && + (m_impl->type=="friend class" || + m_impl->type=="friend struct" || + m_impl->type=="friend union" + ) + ); + + // only include members that are non-private unless EXTRACT_PRIVATE is + // set to YES or the member is part of a group + bool visibleIfPrivate = (protection()!=Private || + extractPrivate || + m_impl->mtype==Friend + ); + + // hide member if it overrides a member in a superclass and has no + // documentation of its own + //bool visibleIfDocVirtual = !reimplements() || + // !Config_getBool("INHERIT_DOCS") || + // hasDocs; + + // true if this member is a constructor or destructor + bool cOrDTor = isConstructor() || isDestructor(); + + // hide default constructors or destructors (no args) without + // documentation + bool visibleIfNotDefaultCDTor = !(cOrDTor && + m_impl->defArgList && + (m_impl->defArgList->isEmpty() || + m_impl->defArgList->first()->type == "void" + ) && + !hasDocs + ); + + //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d" + // "visibleIfPrivate=%d visibleIfDocVirtual=%d visibltIfNotDefaultCDTor=%d " + // "visibleIfFriendCompound=%d\n",visibleIfStatic,visibleIfDocumented, + // visibleIfEnabled,visibleIfPrivate,visibleIfDocVirtual,visibleIfNotDefaultCDTor, + // visibleIfFriendCompound); + + bool visible = visibleIfStatic && visibleIfDocumented && + visibleIfEnabled && visibleIfPrivate && + /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor && + visibleIfFriendCompound && + !m_impl->annScope; + //printf("MemberDef::isBriefSectionVisible() %d\n",visible); + return visible; } @@ -876,7 +1147,9 @@ void MemberDef::writeDeclaration(OutputList &ol, // hide enum value, since they appear already as part of the enum, unless they // are explicitly grouped. - if (!inGroup && mtype==EnumValue) return; + makeResident(); + if (!inGroup && m_impl->mtype==EnumValue) return; + LockingPtr lock(this,this); // hide members whose brief section should not be visible //if (!isBriefSectionVisible()) return; @@ -889,7 +1162,7 @@ void MemberDef::writeDeclaration(OutputList &ol, if (!Config_getString("GENERATE_TAGFILE").isEmpty()) { Doxygen::tagFile << " mtype) { case Define: Doxygen::tagFile << "define"; break; case EnumValue: Doxygen::tagFile << "enumvalue"; break; @@ -905,18 +1178,18 @@ void MemberDef::writeDeclaration(OutputList &ol, case DCOP: Doxygen::tagFile << "dcop"; break; case Slot: Doxygen::tagFile << "slot"; break; } - if (prot!=Public) + if (m_impl->prot!=Public) { Doxygen::tagFile << "\" protection=\""; - if (prot==Protected) Doxygen::tagFile << "protected"; - else if (prot==Package) Doxygen::tagFile << "package"; - else /* Private */ Doxygen::tagFile << "private"; + if (m_impl->prot==Protected) Doxygen::tagFile << "protected"; + else if (m_impl->prot==Package) Doxygen::tagFile << "package"; + else /* Private */ Doxygen::tagFile << "private"; } - if (virt!=Normal) + if (m_impl->virt!=Normal) { Doxygen::tagFile << "\" virtualness=\""; - if (virt==Virtual) Doxygen::tagFile << "virtual"; - else /* Pure */ Doxygen::tagFile << "pure"; + if (m_impl->virt==Virtual) Doxygen::tagFile << "virtual"; + else /* Pure */ Doxygen::tagFile << "pure"; } if (isStatic()) { @@ -955,13 +1228,13 @@ void MemberDef::writeDeclaration(OutputList &ol, ClassDef *annoClassDef=getClassDefOfAnonymousType(); // start a new member declaration - bool isAnonymous = annoClassDef || annMemb || annEnumType; + bool isAnonymous = annoClassDef || m_impl->annMemb || m_impl->annEnumType; ///printf("startMemberItem for %s\n",name().data()); - ol.startMemberItem( isAnonymous ? 1 : tArgList ? 3 : 0); + ol.startMemberItem( isAnonymous ? 1 : m_impl->tArgList ? 3 : 0); // If there is no detailed description we need to write the anchor here. bool detailsVisible = isDetailedSectionLinkable(); - if (!detailsVisible && !annMemb) + if (!detailsVisible && !m_impl->annMemb) { QCString doxyName=name().copy(); if (!cname.isEmpty()) doxyName.prepend(cname+"::"); @@ -975,7 +1248,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ol.popGeneratorState(); } - if (annoClassDef || annMemb) + if (annoClassDef || m_impl->annMemb) { int j; for (j=0;jtArgList) { if (!isAnonymous) ol.startMemberTemplateParams(); - writeTemplatePrefix(ol,tArgList); + writeTemplatePrefix(ol,m_impl->tArgList); if (!isAnonymous) ol.endMemberTemplateParams(); } // *** write type - QCString ltype(type); - if (mtype==Typedef) ltype.prepend("typedef "); + QCString ltype(m_impl->type); + if (m_impl->mtype==Typedef) ltype.prepend("typedef "); // strip `friend' keyword from ltype ltype.stripPrefix("friend "); static QRegExp r("@[0-9]+"); @@ -1011,7 +1284,7 @@ void MemberDef::writeDeclaration(OutputList &ol, int ir=i+l; //printf("<<<<<<<<<<<<<<\n"); ol.startAnonTypeScope(s_indentLevel++); - annoClassDef->writeDeclaration(ol,annMemb,inGroup); + annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup); //printf(">>>>>>>>>>>>>> startMemberItem(2)\n"); ol.startMemberItem(2); int j; @@ -1035,7 +1308,7 @@ void MemberDef::writeDeclaration(OutputList &ol, linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype.left(i),TRUE); getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd); //ol+=*getAnonymousEnumType()->enumDecl(); - linkifyText(TextGeneratorOLImpl(ol),d,fileDef,name(),ltype.right(ltype.length()-i-l),TRUE); + linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,name(),ltype.right(ltype.length()-i-l),TRUE); } else { @@ -1068,7 +1341,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ol.enable(OutputGenerator::Html); } - if (annMemb) + if (m_impl->annMemb) { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); @@ -1077,7 +1350,7 @@ void MemberDef::writeDeclaration(OutputList &ol, } else { - ol.insertMemberAlign(tArgList!=0); + ol.insertMemberAlign(m_impl->tArgList!=0); } // *** write name @@ -1086,26 +1359,27 @@ void MemberDef::writeDeclaration(OutputList &ol, //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable()); if (!(name().isEmpty() || name().at(0)=='@') && // name valid (hasDocumentation() || isReference()) && // has docs - !(prot==Private && !Config_getBool("EXTRACT_PRIVATE") && mtype!=Friend) && // hidden due to protection - !(isStatic() && classDef==0 && !Config_getBool("EXTRACT_STATIC")) // hidden due to static-ness + !(m_impl->prot==Private && !Config_getBool("EXTRACT_PRIVATE") && m_impl->mtype!=Friend) && // hidden due to protection + !(isStatic() && m_impl->classDef==0 && !Config_getBool("EXTRACT_STATIC")) // hidden due to static-ness ) { - if (annMemb) + if (m_impl->annMemb) { //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor()); - annMemb->writeLink(ol, - annMemb->getClassDef(), - annMemb->getNamespaceDef(), - annMemb->getFileDef(), - annMemb->getGroupDef() + m_impl->annMemb->writeLink(ol, + m_impl->annMemb->getClassDef(), + m_impl->annMemb->getNamespaceDef(), + m_impl->annMemb->getFileDef(), + m_impl->annMemb->getGroupDef() ); - annMemb->annUsed=annUsed=TRUE; + m_impl->annMemb->setAnonymousUsed(); + setAnonymousUsed(); } else { //printf("writeLink %s->%d\n",name.data(),hasDocumentation()); ClassDef *rcd = cd; - if (isReference() && classDef) rcd = classDef; + if (isReference() && m_impl->classDef) rcd = m_impl->classDef; writeLink(ol,rcd,nd,fd,gd); } } @@ -1119,9 +1393,13 @@ void MemberDef::writeDeclaration(OutputList &ol, // there is a brief member description and brief member // descriptions are enabled or there is no detailed description. { - if (annMemb) annMemb->annUsed=annUsed=TRUE; + if (m_impl->annMemb) + { + m_impl->annMemb->setAnonymousUsed(); + setAnonymousUsed(); + } ClassDef *rcd = cd; - if (isReference() && classDef) rcd = classDef; + if (isReference() && m_impl->classDef) rcd = m_impl->classDef; writeLink(ol,rcd,nd,fd,gd,TRUE); } } @@ -1142,9 +1420,9 @@ void MemberDef::writeDeclaration(OutputList &ol, } // *** write bitfields - if (!bitfields.isEmpty()) // add bitfields + if (!m_impl->bitfields.isEmpty()) // add bitfields { - linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),bitfields.simplifyWhiteSpace()); + linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->bitfields.simplifyWhiteSpace()); } else if (hasOneLineInitializer() //!init.isEmpty() && initLines==0 && // one line initializer @@ -1154,12 +1432,12 @@ void MemberDef::writeDeclaration(OutputList &ol, if (!isDefine()) { ol.writeString(" = "); - linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),init.simplifyWhiteSpace()); + linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->initializer.simplifyWhiteSpace()); } else { ol.writeNonBreakableSpace(3); - linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),init); + linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->initializer); } } @@ -1189,7 +1467,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ol.endTypewriter(); } - if (!detailsVisible && !annMemb) + if (!detailsVisible && !m_impl->annMemb) { ol.endDoxyAnchor(cfname,anchor()); } @@ -1213,7 +1491,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ol.disableAllBut(OutputGenerator::Html); //ol.endEmphasis(); ol.docify(" "); - if (group!=0 && gd==0) // forward link to the group + if (m_impl->group!=0 && gd==0) // forward link to the group { ol.startTextLink(getOutputFileBase(),anchor()); } @@ -1241,6 +1519,7 @@ bool MemberDef::isDetailedSectionLinkable() const static bool extractStatic = Config_getBool("EXTRACT_STATIC"); static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE"); + makeResident(); // the member has details documentation for any of the following reasons bool docFilter = // treat everything as documented @@ -1250,9 +1529,9 @@ bool MemberDef::isDetailedSectionLinkable() const // has inbody docs !inbodyDocumentation().isEmpty() || // is an enum with values that are documented - (mtype==Enumeration && docEnumValues) || + (m_impl->mtype==Enumeration && m_impl->docEnumValues) || // is documented enum value - (mtype==EnumValue && !briefDescription().isEmpty()) || + (m_impl->mtype==EnumValue && !briefDescription().isEmpty()) || // has brief description that is part of the detailed description (!briefDescription().isEmpty() && // has brief docs (alwaysDetailedSec && // they or visible in @@ -1264,7 +1543,7 @@ bool MemberDef::isDetailedSectionLinkable() const //(initLines>0 && initLineshasDocumentation()); + (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()); // this is not a global static or global statics should be extracted bool staticFilter = getClassDef()!=0 || !isStatic() || extractStatic; @@ -1272,7 +1551,7 @@ bool MemberDef::isDetailedSectionLinkable() const // only include members that are non-private unless EXTRACT_PRIVATE is // set to YES or the member is part of a group bool privateFilter = (protection()!=Private || extractPrivate || - mtype==Friend + m_impl->mtype==Friend ); // member is part of an anonymous scope that is the type of @@ -1284,9 +1563,9 @@ bool MemberDef::isDetailedSectionLinkable() const // is true bool friendCompoundFilter = !(Config_getBool("HIDE_FRIEND_COMPOUNDS") && isFriend() && - (type=="friend class" || - type=="friend struct" || - type=="friend union" + (m_impl->type=="friend class" || + m_impl->type=="friend struct" || + m_impl->type=="friend union" ) ); @@ -1323,6 +1602,9 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, if ( !hasDocs ) return; if (isEnumValue() && !showEnumValues) return; + makeResident(); + LockingPtr lock(this,this); + QCString scopeName = scName; QCString memAnchor = anchor(); QCString ciname = container->name(); @@ -1439,10 +1721,10 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, if (!Config_getBool("HIDE_SCOPE_NAMES")) { bool first=TRUE; - if (m_defTmpArgLists) + if (m_impl->defTmpArgLists) // definition has explicit template parameter declarations { - QListIterator ali(*m_defTmpArgLists); + QListIterator ali(*m_impl->defTmpArgLists); ArgumentList *tal; for (ali.toFirst();(tal=ali.current());++ali) { @@ -1476,10 +1758,10 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, } } } - if (tArgList) // function template prefix + if (m_impl->tArgList) // function template prefix { ol.startMemberDocPrefixItem(); - writeTemplatePrefix(ol,tArgList); + writeTemplatePrefix(ol,m_impl->tArgList); ol.endMemberDocPrefixItem(); } } @@ -1527,12 +1809,12 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, if (!isDefine()) { ol.docify(" = "); - linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),init.simplifyWhiteSpace()); + linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),m_impl->initializer.simplifyWhiteSpace()); } else { ol.writeNonBreakableSpace(3); - linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),init); + linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),m_impl->initializer); } } if (excpString()) // add exception list @@ -1543,13 +1825,13 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, } Specifier lvirt=virtualness(); - + if (!isObjCMethod() && (protection()!=Public || lvirt!=Normal || isFriend() || isRelated() || isExplicit() || isMutable() || (isInline() && Config_getBool("INLINE_INFO")) || isSignal() || isSlot() || - isStatic() || (classDef && classDef!=container) || + isStatic() || (m_impl->classDef && m_impl->classDef!=container) || isSettable() || isGettable() || isReadable() || isWritable() || isFinal() || isAbstract() ) @@ -1583,7 +1865,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, if (isSignal()) sl.append("signal"); if (isSlot()) sl.append("slot"); } - if (classDef && classDef!=container) sl.append("inherited"); + if (m_impl->classDef && m_impl->classDef!=container) sl.append("inherited"); const char *s=sl.first(); while (s) { @@ -1628,7 +1910,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, { //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data()); ol.startBold(); - if (mtype==Define) + if (m_impl->mtype==Define) ol.parseText(theTranslator->trDefineValue()); else ol.parseText(theTranslator->trInitialValue()); @@ -1636,16 +1918,19 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension()); pIntf->resetCodeParserState(); ol.startCodeFragment(); - pIntf->parseCode(ol,scopeName,init,FALSE,0); + pIntf->parseCode(ol,scopeName,m_impl->initializer,FALSE,0); ol.endCodeFragment(); } - QCString brief = m_templateMaster ? - m_templateMaster->briefDescription() : briefDescription(); - QCString detailed = m_templateMaster ? - m_templateMaster->documentation() : documentation(); - ArgumentList *docArgList = m_templateMaster ? - m_templateMaster->defArgList : defArgList; + QCString brief = briefDescription(); + QCString detailed = documentation(); + LockingPtr docArgList = LockingPtr(this,m_impl->defArgList); + if (m_impl->templateMaster) + { + brief = m_impl->templateMaster->briefDescription(); + detailed = m_impl->templateMaster->documentation(); + docArgList = m_impl->templateMaster->argumentList(); + } /* write brief description */ if (!brief.isEmpty() && @@ -1662,19 +1947,19 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, if (!detailed.isEmpty()) { ol.parseDoc(docFile(),docLine(),getOuterScope()?getOuterScope():container,this,detailed+"\n",TRUE,FALSE); - if (!m_inbodyDocs.isEmpty()) + if (!m_impl->inbodyDocs.isEmpty()) { ol.newParagraph(); - ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,m_inbodyDocs+"\n",TRUE,FALSE); + ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,m_impl->inbodyDocs+"\n",TRUE,FALSE); } } else if (!brief.isEmpty() && (Config_getBool("REPEAT_BRIEF") || !Config_getBool("BRIEF_MEMBER_DESC"))) { - if (!m_inbodyDocs.isEmpty()) + if (!m_impl->inbodyDocs.isEmpty()) { ol.newParagraph(); - ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,m_inbodyDocs+"\n",TRUE,FALSE); + ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,m_impl->inbodyDocs+"\n",TRUE,FALSE); } } @@ -1682,7 +1967,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n", // defArgList, // defArgList?defArgList->hasDocumentation():-1); - if (docArgList && docArgList->hasDocumentation()) + if (docArgList!=0 && docArgList->hasDocumentation()) { //printf("***** argumentList is documented\n"); ol.startParamList(BaseOutputDocInterface::Param,theTranslator->trParameters()+": "); @@ -1716,8 +2001,8 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, if (isEnumerate()) { bool first=TRUE; - MemberList *fmdl=enumFieldList(); - if (fmdl) + LockingPtr fmdl=enumFieldList(); + if (fmdl!=0) { MemberDef *fmd=fmdl->first(); while (fmd) @@ -1842,8 +2127,8 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, //ol.writeString("."); } - MemberList *bml=reimplementedBy(); - if (bml) + LockingPtr bml=reimplementedBy(); + if (bml!=0) { MemberListIterator mli(*bml); MemberDef *bmd=0; @@ -1867,7 +2152,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ol.enable(OutputGenerator::RTF); QCString reimplInLine; - if (virt==Pure || (classDef && classDef->compoundType()==ClassDef::Interface)) + if (m_impl->virt==Pure || (m_impl->classDef && m_impl->classDef->compoundType()==ClassDef::Interface)) { reimplInLine = theTranslator->trImplementedInList(count); } @@ -1920,7 +2205,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, { ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": "); ol.writeDescItem(); - writeExample(ol,getExamples()); + writeExample(ol,m_impl->exampleSDict); //ol.endDescItem(); ol.endSimpleSect(); } @@ -1932,11 +2217,11 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, writeInlineCode(ol,cname); // write call graph - if ((m_hasCallGraph || Config_getBool("CALL_GRAPH")) + if ((m_impl->hasCallGraph || Config_getBool("CALL_GRAPH")) && isFunction() && Config_getBool("HAVE_DOT") ) { - DotCallGraph callGraph(this,Config_getInt("MAX_DOT_GRAPH_DEPTH"), false); + DotCallGraph callGraph(this,Config_getInt("MAX_DOT_GRAPH_DEPTH"), FALSE); if (!callGraph.isTrivial()) { msg("Generating call graph for function %s\n",qualifiedName().data()); @@ -1948,7 +2233,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ol.enableAll(); } } - if ((m_hasCallerGraph || Config_getBool("CALLER_GRAPH")) + if ((m_impl->hasCallerGraph || Config_getBool("CALLER_GRAPH")) && isFunction() && Config_getBool("HAVE_DOT") ) { @@ -1996,7 +2281,8 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, QCString MemberDef::memberTypeName() const { - switch (mtype) + makeResident(); + switch (m_impl->mtype) { case Define: return "define"; case Function: return "function"; @@ -2017,7 +2303,8 @@ QCString MemberDef::memberTypeName() const void MemberDef::warnIfUndocumented() { - if (memberGroup) return; + makeResident(); + if (m_impl->memberGroup) return; ClassDef *cd = getClassDef(); NamespaceDef *nd = getNamespaceDef(); FileDef *fd = getFileDef(); @@ -2041,7 +2328,7 @@ void MemberDef::warnIfUndocumented() if ((!hasUserDocumentation() && !extractAll) && !isFriendClass() && name().find('@')==-1 && d->name().find('@')==-1 && - (prot!=Private || Config_getBool("EXTRACT_PRIVATE")) + (m_impl->prot!=Private || Config_getBool("EXTRACT_PRIVATE")) ) { warn_undoc(getDefFileName(),getDefLine(),"Warning: Member %s%s (%s) of %s %s is not documented.", @@ -2050,21 +2337,18 @@ void MemberDef::warnIfUndocumented() } -//void MemberDef::setEnumDecl(OutputList &ed) -//{ -// enumDeclList=new OutputList(&ed); -// *enumDeclList+=ed; -//} bool MemberDef::isFriendClass() const { + makeResident(); return (isFriend() && - (type=="friend class" || type=="friend struct" || - type=="friend union")); + (m_impl->type=="friend class" || m_impl->type=="friend struct" || + m_impl->type=="friend union")); } bool MemberDef::isDocumentedFriendClass() const { + makeResident(); ClassDef *fcd=0; QCString baseName=name(); int i=baseName.find('<'); @@ -2075,25 +2359,29 @@ bool MemberDef::isDocumentedFriendClass() const bool MemberDef::hasDocumentation() const { + makeResident(); return Definition::hasDocumentation() || - !m_inbodyDocs.isEmpty() || - (mtype==Enumeration && docEnumValues) || // has enum values - (defArgList!=0 && defArgList->hasDocumentation()); // has doc arguments + !m_impl->inbodyDocs.isEmpty() || + (m_impl->mtype==Enumeration && m_impl->docEnumValues) || // has enum values + (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()); // has doc arguments } void MemberDef::setMemberGroup(MemberGroup *grp) { - memberGroup = grp; + makeResident(); + m_impl->memberGroup = grp; } bool MemberDef::visibleMemberGroup(bool hideNoHeader) { - return memberGroup!=0 && - (!hideNoHeader || memberGroup->header()!="[NOHEADER]"); + makeResident(); + return m_impl->memberGroup!=0 && + (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]"); } QCString MemberDef::getScopeString() const { + makeResident(); QCString result; if (getClassDef()) result=getClassDef()->displayName(); else if (getNamespaceDef()) result=getNamespaceDef()->displayName(); @@ -2127,10 +2415,11 @@ static QCString escapeAnchor(const QCString &anchor) void MemberDef::setAnchor(const char *a) { + makeResident(); //anc=a; a=a; QCString memAnchor = name(); - if (!args.isEmpty()) memAnchor+=args; + if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args; // include definition as well, to distinguish between two template // specializations that only differ in the template parameters. @@ -2141,7 +2430,7 @@ void MemberDef::setAnchor(const char *a) QCString sigStr(33); MD5Buffer((const unsigned char *)memAnchor.data(),memAnchor.length(),md5_sig); MD5SigToString(md5_sig,sigStr.data(),33); - anc = sigStr; + m_impl->anc = sigStr; } void MemberDef::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, @@ -2149,48 +2438,54 @@ void MemberDef::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, bool hasDocs,MemberDef *member) { //printf("%s MemberDef::setGroupDef(%s)\n",name().data(),gd->name().data()); - group=gd; - grouppri=pri; - groupFileName=fileName; - groupStartLine=startLine; - groupHasDocs=hasDocs; - groupMember=member; + makeResident(); + m_impl->group=gd; + m_impl->grouppri=pri; + m_impl->groupFileName=fileName; + m_impl->groupStartLine=startLine; + m_impl->groupHasDocs=hasDocs; + m_impl->groupMember=member; } void MemberDef::setEnumScope(MemberDef *md) { - enumScope=md; - if (md->group) + makeResident(); + m_impl->enumScope=md; + if (md->getGroupDef()) { - group=md->group; - grouppri=md->grouppri; - groupFileName=md->groupFileName; - groupStartLine=md->groupStartLine; - groupHasDocs=md->groupHasDocs; + m_impl->group=md->getGroupDef(); + m_impl->grouppri=md->getGroupPri(); + m_impl->groupFileName=md->getGroupFileName(); + m_impl->groupStartLine=md->getGroupStartLine(); + m_impl->groupHasDocs=md->getGroupHasDocs(); } } void MemberDef::setMemberClass(ClassDef *cd) { - classDef=cd; + makeResident(); + m_impl->classDef=cd; setOuterScope(cd); } void MemberDef::setNamespace(NamespaceDef *nd) { - nspace=nd; + makeResident(); + m_impl->nspace=nd; setOuterScope(nd); } MemberDef *MemberDef::createTemplateInstanceMember( ArgumentList *formalArgs,ArgumentList *actualArgs) { + makeResident(); + LockingPtr lock(this,this); //printf(" Member %s %s %s\n",typeString(),name().data(),argsString()); ArgumentList *actualArgList = 0; - if (defArgList) + if (m_impl->defArgList) { actualArgList = new ArgumentList; - ArgumentListIterator ali(*defArgList); + ArgumentListIterator ali(*m_impl->defArgList); Argument *arg; for (;(arg=ali.current());++ali) { @@ -2198,9 +2493,9 @@ MemberDef *MemberDef::createTemplateInstanceMember( actArg->type = substituteTemplateArgumentsInString(actArg->type,formalArgs,actualArgs); actualArgList->append(actArg); } - actualArgList->constSpecifier = defArgList->constSpecifier; - actualArgList->volatileSpecifier = defArgList->volatileSpecifier; - actualArgList->pureSpecifier = defArgList->pureSpecifier; + actualArgList->constSpecifier = m_impl->defArgList->constSpecifier; + actualArgList->volatileSpecifier = m_impl->defArgList->volatileSpecifier; + actualArgList->pureSpecifier = m_impl->defArgList->pureSpecifier; } QCString methodName=name(); @@ -2211,14 +2506,14 @@ MemberDef *MemberDef::createTemplateInstanceMember( MemberDef *imd = new MemberDef( getDefFileName(),getDefLine(), - substituteTemplateArgumentsInString(type,formalArgs,actualArgs), + substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs), methodName, - substituteTemplateArgumentsInString(args,formalArgs,actualArgs), - exception, prot, - virt, stat, related, mtype, 0, 0 + substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs), + m_impl->exception, m_impl->prot, + m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0 ); - imd->defArgList = actualArgList; - imd->def = substituteTemplateArgumentsInString(def,formalArgs,actualArgs); + imd->setArgumentList(actualArgList); + imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs)); imd->setBodyDef(getBodyDef()); imd->setBodySegment(getStartBodyLine(),getEndBodyLine()); //imd->setBodyMember(this); @@ -2230,34 +2525,38 @@ MemberDef *MemberDef::createTemplateInstanceMember( bool MemberDef::hasOneLineInitializer() const { + makeResident(); //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n", // name().data(),init.data(),initLines,maxInitLines,userInitLines); - return !init.isEmpty() && initLines==0 && // one line initializer - ((maxInitLines>0 && userInitLines==-1) || userInitLines>0); // enabled by default or explicitly + return !m_impl->initializer.isEmpty() && m_impl->initLines==0 && // one line initializer + ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly } bool MemberDef::hasMultiLineInitializer() const { + makeResident(); //printf("initLines=%d userInitLines=%d maxInitLines=%d\n", // initLines,userInitLines,maxInitLines); - return initLines>0 && - ((initLinesinitLines>0 && + ((m_impl->initLinesmaxInitLines && m_impl->userInitLines==-1) // implicitly enabled + || m_impl->initLinesuserInitLines // explicitly enabled ); } void MemberDef::setInitializer(const char *initializer) { + makeResident(); //printf("setInitializer(%s)\n",initializer); - init=initializer; - int p=init.length()-1; - while (p>=0 && isspace((uchar)init.at(p))) p--; - init=init.left(p+1); - initLines=init.contains('\n'); + m_impl->initializer=initializer; + int p=m_impl->initializer.length()-1; + while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--; + m_impl->initializer=m_impl->initializer.left(p+1); + m_impl->initLines=m_impl->initializer.contains('\n'); } void MemberDef::addListReference(Definition *) { + makeResident(); static bool optimizeOutputForC = Config_getBool("OPTIMIZE_OUTPUT_FOR_C"); static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES"); static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); @@ -2300,30 +2599,38 @@ void MemberDef::addListReference(Definition *) memArgs = argsString(); } } - if (xrefListItems()) + LockingPtr< QList > xrefItems = xrefListItems(); + if (xrefItems!=0) { - addRefItem(xrefListItems(),memLabel, + addRefItem(xrefItems.pointer(),memLabel, getOutputFileBase()+"#"+anchor(),memName,memArgs); } - else - { - } } MemberList *MemberDef::getSectionList(Definition *d) const { - return (d!=0 && classSectionSDict) ? classSectionSDict->find((char *)d) : 0; + makeResident(); + char key[20]; + sprintf(key,"%p",d); + return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0; } void MemberDef::setSectionList(Definition *d, MemberList *sl) { - if (classSectionSDict==0) classSectionSDict = new SDict(7); - classSectionSDict->append((char *)d,sl); + makeResident(); + char key[20]; + sprintf(key,"%p",d); + if (m_impl->classSectionSDict==0) + { + m_impl->classSectionSDict = new SDict(7); + } + m_impl->classSectionSDict->append(key,sl); } Specifier MemberDef::virtualness() const { - Specifier v = virt; + makeResident(); + Specifier v = m_impl->virt; MemberDef *rmd = reimplements(); while (rmd && v==Normal) { @@ -2335,19 +2642,21 @@ Specifier MemberDef::virtualness() const bool MemberDef::isConstructor() const { - if (classDef) + makeResident(); + if (m_impl->classDef) { - if (m_isDMember) // for D + if (m_impl->isDMember) // for D { return name()=="this"; } - else if (fileDef && getLanguageFromFileName(fileDef->name())==SrcLangExt_PHP) + else if (m_impl->fileDef && + getLanguageFromFileName(m_impl->fileDef->name())==SrcLangExt_PHP) { // for PHP return name()=="__construct"; } else // for other languages { - QCString locName = classDef->localName(); + QCString locName = m_impl->classDef->localName(); int i=locName.find('<'); if (i==-1) // not a template class { @@ -2365,11 +2674,13 @@ bool MemberDef::isConstructor() const bool MemberDef::isDestructor() const { - if (m_isDMember) // for D + makeResident(); + if (m_impl->isDMember) // for D { return name()=="~this"; } - else if (fileDef && getLanguageFromFileName(fileDef->name())==SrcLangExt_PHP) + else if (m_impl->fileDef && + getLanguageFromFileName(m_impl->fileDef->name())==SrcLangExt_PHP) { // for PHP return name()=="__destruct"; } @@ -2382,9 +2693,11 @@ bool MemberDef::isDestructor() const void MemberDef::writeEnumDeclaration(OutputList &typeDecl, ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd) { + makeResident(); + LockingPtr lock(this,this); int enumMemCount=0; - QList *fmdl=enumFieldList(); + QList *fmdl=m_impl->enumFields; uint numVisibleEnumValues=0; if (fmdl) { @@ -2395,7 +2708,10 @@ void MemberDef::writeEnumDeclaration(OutputList &typeDecl, fmd=fmdl->next(); } } - if (numVisibleEnumValues==0 && !isBriefSectionVisible()) return; + if (numVisibleEnumValues==0 && !isBriefSectionVisible()) + { + return; + } QCString n = name(); int i=n.findRev("::"); @@ -2503,64 +2819,73 @@ void MemberDef::writeEnumDeclaration(OutputList &typeDecl, void MemberDef::setArgumentList(ArgumentList *al) { - if (defArgList) delete defArgList; - defArgList = al; + makeResident(); + if (m_impl->defArgList) delete m_impl->defArgList; + m_impl->defArgList = al; } void MemberDef::setDeclArgumentList(ArgumentList *al) { - if (declArgList) delete declArgList; - declArgList = al; + makeResident(); + if (m_impl->declArgList) delete m_impl->declArgList; + m_impl->declArgList = al; } void MemberDef::findSectionsInDocumentation() { + makeResident(); docFindSections(documentation(),this,0,docFile()); } void MemberDef::enableCallGraph(bool e) { - m_hasCallGraph=e; + makeResident(); + m_impl->hasCallGraph=e; if (e) Doxygen::parseSourcesNeeded = TRUE; } void MemberDef::enableCallerGraph(bool e) { - m_hasCallerGraph=e; + makeResident(); + m_impl->hasCallerGraph=e; if (e) Doxygen::parseSourcesNeeded = TRUE; } bool MemberDef::protectionVisible() const { - return prot==Public || - (prot==Private && Config_getBool("EXTRACT_PRIVATE")) || - (prot==Protected && Config_getBool("EXTRACT_PROTECTED")) || - (prot==Package && Config_getBool("EXTRACT_PACKAGE")); + makeResident(); + return m_impl->prot==Public || + (m_impl->prot==Private && Config_getBool("EXTRACT_PRIVATE")) || + (m_impl->prot==Protected && Config_getBool("EXTRACT_PROTECTED")) || + (m_impl->prot==Package && Config_getBool("EXTRACT_PACKAGE")); } void MemberDef::setInbodyDocumentation(const char *docs, const char *docFile,int docLine) { - m_inbodyDocs = docs; - m_inbodyDocs = m_inbodyDocs.stripWhiteSpace(); - m_inbodyLine = docLine; - m_inbodyFile = docFile; + makeResident(); + m_impl->inbodyDocs = docs; + m_impl->inbodyDocs = m_impl->inbodyDocs.stripWhiteSpace(); + m_impl->inbodyLine = docLine; + m_impl->inbodyFile = docFile; } bool MemberDef::isObjCMethod() const { - if (classDef && classDef->isObjectiveC() && isFunction()) return TRUE; + makeResident(); + if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isFunction()) return TRUE; return FALSE; } QCString MemberDef::qualifiedName() { + makeResident(); if (isObjCMethod()) { QCString qm; if (isStatic()) qm="+"; else qm="-"; qm+="["; - qm+=classDef->name()+" "; + qm+=m_impl->classDef->name()+" "; qm+=name(); qm+="]"; return qm; @@ -2575,14 +2900,16 @@ void MemberDef::setTagInfo(TagInfo *ti) { if (ti) { - anc=ti->anchor; + makeResident(); + m_impl->anc=ti->anchor; setReference(ti->tagName); - explicitOutputFileBase = stripExtension(ti->fileName); + m_impl->explicitOutputFileBase = stripExtension(ti->fileName); } } QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const { + makeResident(); QCString qm; if (showStatic) { @@ -2592,9 +2919,862 @@ QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const if (!localLink) // link to method of same class { qm+=" ("; - qm+=classDef->name(); + qm+=m_impl->classDef->name(); qm+=")"; } return qm; } +const char *MemberDef::declaration() const +{ + makeResident(); + return m_impl->decl; +} + +const char *MemberDef::definition() const +{ + makeResident(); + return m_impl->def; +} + +const char *MemberDef::typeString() const +{ + makeResident(); + return m_impl->type; +} + +const char *MemberDef::argsString() const +{ + makeResident(); + return m_impl->args; +} + +const char *MemberDef::excpString() const +{ + makeResident(); + return m_impl->exception; +} + +const char *MemberDef::bitfieldString() const +{ + makeResident(); + return m_impl->bitfields; +} + +const QCString &MemberDef::initializer() const +{ + makeResident(); + return m_impl->initializer; +} + +int MemberDef::initializerLines() const +{ + makeResident(); + return m_impl->initLines; +} + +int MemberDef::getMemberSpecifiers() const +{ + makeResident(); + return m_impl->memSpec; +} + +ClassDef *MemberDef::getClassDef() const +{ + makeResident(); + return m_impl->classDef; +} + +FileDef *MemberDef::getFileDef() const +{ + makeResident(); + return m_impl->fileDef; +} + +NamespaceDef* MemberDef::getNamespaceDef() const +{ + makeResident(); + return m_impl->nspace; +} + +const char *MemberDef::getReadAccessor() const +{ + makeResident(); + return m_impl->read; +} + +const char *MemberDef::getWriteAccessor() const +{ + makeResident(); + return m_impl->write; +} + +GroupDef *MemberDef::getGroupDef() const +{ + makeResident(); + return m_impl->group; +} + +Grouping::GroupPri_t MemberDef::getGroupPri() const +{ + makeResident(); + return m_impl->grouppri; +} + +const char *MemberDef::getGroupFileName() const +{ + makeResident(); + return m_impl->groupFileName; +} + +int MemberDef::getGroupStartLine() const +{ + makeResident(); + return m_impl->groupStartLine; +} + +bool MemberDef::getGroupHasDocs() const +{ + makeResident(); + return m_impl->groupHasDocs; +} + +Protection MemberDef::protection() const +{ + makeResident(); + return m_impl->prot; +} + +MemberDef::MemberType MemberDef::memberType() const +{ + makeResident(); + return m_impl->mtype; +} + +bool MemberDef::isSignal() const +{ + makeResident(); + return m_impl->mtype==Signal; +} + +bool MemberDef::isSlot() const +{ + makeResident(); + return m_impl->mtype==Slot; +} + +bool MemberDef::isVariable() const +{ + makeResident(); + return m_impl->mtype==Variable; +} + +bool MemberDef::isEnumerate() const +{ + makeResident(); + return m_impl->mtype==Enumeration; +} + +bool MemberDef::isEnumValue() const +{ + makeResident(); + return m_impl->mtype==EnumValue; +} + +bool MemberDef::isTypedef() const +{ + makeResident(); + return m_impl->mtype==Typedef; +} + +bool MemberDef::isFunction() const +{ + makeResident(); + return m_impl->mtype==Function; +} + +bool MemberDef::isDefine() const +{ + makeResident(); + return m_impl->mtype==Define; +} + +bool MemberDef::isFriend() const +{ + makeResident(); + return m_impl->mtype==Friend; +} + +bool MemberDef::isDCOP() const +{ + makeResident(); + return m_impl->mtype==DCOP; +} + +bool MemberDef::isProperty() const +{ + makeResident(); + return m_impl->mtype==Property; +} + +bool MemberDef::isEvent() const +{ + makeResident(); + return m_impl->mtype==Event; +} + +bool MemberDef::isRelated() const +{ + makeResident(); + return m_impl->related; +} + +bool MemberDef::isStatic() const +{ + makeResident(); + return m_impl->stat; +} + +bool MemberDef::isInline() const +{ + makeResident(); + return (m_impl->memSpec&Entry::Inline)!=0; +} + +bool MemberDef::isExplicit() const +{ + makeResident(); + return (m_impl->memSpec&Entry::Explicit)!=0; +} + +bool MemberDef::isMutable() const +{ + makeResident(); + return (m_impl->memSpec&Entry::Mutable)!=0; +} + +bool MemberDef::isGettable() const +{ + makeResident(); + return (m_impl->memSpec&Entry::Gettable)!=0; +} + +bool MemberDef::isSettable() const +{ + makeResident(); + return (m_impl->memSpec&Entry::Settable)!=0; +} + +bool MemberDef::isReadable() const +{ + makeResident(); + return (m_impl->memSpec&Entry::Readable)!=0; +} + +bool MemberDef::isWritable() const +{ + makeResident(); + return (m_impl->memSpec&Entry::Writable)!=0; +} + +bool MemberDef::isFinal() const +{ + makeResident(); + return (m_impl->memSpec&Entry::Final)!=0; +} + +bool MemberDef::isAbstract() const +{ + makeResident(); + return (m_impl->memSpec&Entry::Abstract)!=0; +} + +bool MemberDef::isImplementation() const +{ + makeResident(); + return m_impl->implOnly; +} + +bool MemberDef::isExternal() const +{ + makeResident(); + return m_impl->explExt; +} + +bool MemberDef::isTemplateSpecialization() const +{ + makeResident(); + return m_impl->tspec; +} + +bool MemberDef::hasDocumentedParams() const +{ + makeResident(); + return m_impl->hasDocumentedParams; +} + +bool MemberDef::hasDocumentedReturnType() const +{ + makeResident(); + return m_impl->hasDocumentedReturnType; +} + +int MemberDef::inbodyLine() const +{ + makeResident(); + return m_impl->inbodyLine; +} + +QCString MemberDef::inbodyFile() const +{ + makeResident(); + return m_impl->inbodyFile; +} + +const QCString &MemberDef::inbodyDocumentation() const +{ + makeResident(); + return m_impl->inbodyDocs; +} + +ClassDef *MemberDef::relatedAlso() const +{ + makeResident(); + return m_impl->relatedAlso; +} + +bool MemberDef::hasDocumentedEnumValues() const +{ + makeResident(); + return m_impl->docEnumValues; +} + +MemberDef *MemberDef::getAnonymousEnumType() const +{ + makeResident(); + return m_impl->annEnumType; +} + +bool MemberDef::isDocsForDefinition() const +{ + makeResident(); + return m_impl->docsForDefinition; +} + +MemberDef *MemberDef::getEnumScope() const +{ + makeResident(); + return m_impl->enumScope; +} + +LockingPtr MemberDef::enumFieldList() const +{ + makeResident(); + return LockingPtr(this,m_impl->enumFields); +} + +LockingPtr MemberDef::getExamples() const +{ + makeResident(); + return LockingPtr(this,m_impl->exampleSDict); +} + +bool MemberDef::isPrototype() const +{ + makeResident(); + return m_impl->proto; +} + +LockingPtr MemberDef::argumentList() const +{ + makeResident(); + return LockingPtr(this,m_impl->defArgList); +} + +LockingPtr MemberDef::declArgumentList() const +{ + makeResident(); + return LockingPtr(this,m_impl->declArgList); +} + +LockingPtr MemberDef::templateArguments() const +{ + makeResident(); + return LockingPtr(this,m_impl->tArgList); +} + +LockingPtr< QList > MemberDef::definitionTemplateParameterLists() const +{ + makeResident(); + return LockingPtr< QList >(this,m_impl->defTmpArgLists); +} + +int MemberDef::getMemberGroupId() const +{ + makeResident(); + return m_impl->grpId; +} + +MemberGroup *MemberDef::getMemberGroup() const +{ + makeResident(); + return m_impl->memberGroup; +} + +bool MemberDef::fromAnonymousScope() const +{ + makeResident(); + return m_impl->annScope; +} + +bool MemberDef::anonymousDeclShown() const +{ + makeResident(); + return m_impl->annUsed; +} + +void MemberDef::setAnonymousUsed() +{ + makeResident(); + m_impl->annUsed = TRUE; +} + +bool MemberDef::hasCallGraph() const +{ + makeResident(); + return m_impl->hasCallGraph; +} + +bool MemberDef::hasCallerGraph() const +{ + makeResident(); + return m_impl->hasCallerGraph; +} + +MemberDef *MemberDef::templateMaster() const +{ + makeResident(); + return m_impl->templateMaster; +} + +bool MemberDef::isTypedefValCached() const +{ + makeResident(); + return m_impl->isTypedefValCached; +} + +ClassDef *MemberDef::getCachedTypedefVal() const +{ + makeResident(); + return m_impl->cachedTypedefValue; +} + +QCString MemberDef::getCachedTypedefTemplSpec() const +{ + makeResident(); + return m_impl->cachedTypedefTemplSpec; +} + +MemberDef *MemberDef::memberDefinition() const +{ + makeResident(); + return m_impl->memDef; +} + +MemberDef *MemberDef::memberDeclaration() const +{ + makeResident(); + return m_impl->memDec; +} + +MemberDef *MemberDef::inheritsDocsFrom() const +{ + makeResident(); + return m_impl->docProvider; +} + +MemberDef *MemberDef::getGroupAlias() const +{ + makeResident(); + return m_impl->groupAlias; +} + +void MemberDef::setMemberType(MemberType t) +{ + makeResident(); + m_impl->mtype=t; +} + +void MemberDef::setDefinition(const char *d) +{ + makeResident(); + m_impl->def=d; +} + +void MemberDef::setFileDef(FileDef *fd) +{ + makeResident(); + m_impl->fileDef=fd; +} + +void MemberDef::setProtection(Protection p) +{ + makeResident(); + m_impl->prot=p; +} + +void MemberDef::setMemberSpecifiers(int s) +{ + makeResident(); + m_impl->memSpec=s; +} + +void MemberDef::mergeMemberSpecifiers(int s) +{ + makeResident(); + m_impl->memSpec|=s; +} + +void MemberDef::setBitfields(const char *s) +{ + makeResident(); + m_impl->bitfields = s; +} + +void MemberDef::setMaxInitLines(int lines) +{ + makeResident(); + m_impl->userInitLines=lines; +} + +void MemberDef::setExplicitExternal(bool b) +{ + makeResident(); + m_impl->explExt=b; +} + +void MemberDef::setReadAccessor(const char *r) +{ + makeResident(); + m_impl->read=r; +} + +void MemberDef::setWriteAccessor(const char *w) +{ + makeResident(); + m_impl->write=w; +} + +void MemberDef::setTemplateSpecialization(bool b) +{ + makeResident(); + m_impl->tspec=b; +} + +void MemberDef::makeRelated() +{ + makeResident(); + m_impl->related=TRUE; +} + +void MemberDef::setHasDocumentedParams(bool b) +{ + makeResident(); + m_impl->hasDocumentedParams = b; +} + +void MemberDef::setHasDocumentedReturnType(bool b) +{ + makeResident(); + m_impl->hasDocumentedReturnType = b; +} + +void MemberDef::setInheritsDocsFrom(MemberDef *md) +{ + makeResident(); + m_impl->docProvider = md; +} + +void MemberDef::setArgsString(const char *as) +{ + makeResident(); + m_impl->args = as; +} + +void MemberDef::setRelatedAlso(ClassDef *cd) +{ + makeResident(); + m_impl->relatedAlso=cd; +} + +void MemberDef::setEnumClassScope(ClassDef *cd) +{ + makeResident(); + m_impl->classDef = cd; +} + +void MemberDef::setDocumentedEnumValues(bool value) +{ + makeResident(); + m_impl->docEnumValues=value; +} + +void MemberDef::setAnonymousEnumType(MemberDef *md) +{ + makeResident(); + m_impl->annEnumType = md; +} + +void MemberDef::setPrototype(bool p) +{ + makeResident(); + m_impl->proto=p; +} + +void MemberDef::setMemberGroupId(int id) +{ + makeResident(); + m_impl->grpId=id; +} + +void MemberDef::makeImplementationDetail() +{ + makeResident(); + m_impl->implOnly=TRUE; +} + +void MemberDef::setFromAnonymousScope(bool b) +{ + makeResident(); + m_impl->annScope=b; +} + +void MemberDef::setFromAnonymousMember(MemberDef *m) +{ + makeResident(); + m_impl->annMemb=m; +} + +void MemberDef::setTemplateMaster(MemberDef *mt) +{ + makeResident(); + m_impl->templateMaster=mt; +} + +void MemberDef::setDocsForDefinition(bool b) +{ + makeResident(); + m_impl->docsForDefinition = b; +} + +void MemberDef::setGroupAlias(MemberDef *md) +{ + makeResident(); + m_impl->groupAlias = md; +} + +void MemberDef::invalidateTypedefValCache() +{ + makeResident(); + m_impl->isTypedefValCached=FALSE; +} + +void MemberDef::setMemberDefinition(MemberDef *md) +{ + makeResident(); + m_impl->memDef=md; +} + +void MemberDef::setMemberDeclaration(MemberDef *md) +{ + makeResident(); + m_impl->memDec=md; +} + +void MemberDef::cacheTypedefVal(ClassDef*val, QCString const& templSpec) +{ + makeResident(); + m_impl->isTypedefValCached=TRUE; + m_impl->cachedTypedefValue=val; + m_impl->cachedTypedefTemplSpec=templSpec; +} + +void MemberDef::flushToDisk() const +{ + //printf("%p: MemberDef::flushToDisk()\n",this); + // write the definition base class member variables to disk + Definition::flushToDisk(); + + if (isLocked()) return; + //printf("%p: flushing specific part\n",this); + + // write the memberdef member variables to disk + marshalUInt(Doxygen::symbolStorage,START_MARKER); + marshalObjPointer (Doxygen::symbolStorage,m_impl->classDef); + marshalObjPointer (Doxygen::symbolStorage,m_impl->fileDef); + marshalObjPointer (Doxygen::symbolStorage,m_impl->nspace); + marshalObjPointer (Doxygen::symbolStorage,m_impl->enumScope); + marshalObjPointer (Doxygen::symbolStorage,m_impl->annEnumType); + marshalMemberList (Doxygen::symbolStorage,m_impl->enumFields); + marshalObjPointer (Doxygen::symbolStorage,m_impl->redefines); + marshalMemberList (Doxygen::symbolStorage,m_impl->redefinedBy); + marshalObjPointer (Doxygen::symbolStorage,m_impl->memDef); + marshalObjPointer (Doxygen::symbolStorage,m_impl->memDec); + marshalObjPointer (Doxygen::symbolStorage,m_impl->relatedAlso); + marshalExampleSDict (Doxygen::symbolStorage,m_impl->exampleSDict); + marshalQCString (Doxygen::symbolStorage,m_impl->type); + marshalQCString (Doxygen::symbolStorage,m_impl->args); + marshalQCString (Doxygen::symbolStorage,m_impl->def); + marshalQCString (Doxygen::symbolStorage,m_impl->anc); + marshalInt (Doxygen::symbolStorage,(int)m_impl->virt); + marshalInt (Doxygen::symbolStorage,(int)m_impl->prot); + marshalQCString (Doxygen::symbolStorage,m_impl->decl); + marshalQCString (Doxygen::symbolStorage,m_impl->bitfields); + marshalQCString (Doxygen::symbolStorage,m_impl->read); + marshalQCString (Doxygen::symbolStorage,m_impl->write); + marshalQCString (Doxygen::symbolStorage,m_impl->exception); + marshalQCString (Doxygen::symbolStorage,m_impl->initializer); + marshalInt (Doxygen::symbolStorage,m_impl->initLines); + marshalInt (Doxygen::symbolStorage,m_impl->memSpec); + marshalInt (Doxygen::symbolStorage,(int)m_impl->mtype); + marshalInt (Doxygen::symbolStorage,m_impl->maxInitLines); + marshalInt (Doxygen::symbolStorage,m_impl->userInitLines); + marshalObjPointer (Doxygen::symbolStorage,m_impl->annMemb); + marshalArgumentList (Doxygen::symbolStorage,m_impl->defArgList); + marshalArgumentList (Doxygen::symbolStorage,m_impl->declArgList); + marshalArgumentList (Doxygen::symbolStorage,m_impl->tArgList); + marshalObjPointer (Doxygen::symbolStorage,m_impl->templateMaster); + marshalArgumentLists(Doxygen::symbolStorage,m_impl->defTmpArgLists); + marshalObjPointer (Doxygen::symbolStorage,m_impl->cachedAnonymousType); + marshalMemberLists (Doxygen::symbolStorage,m_impl->classSectionSDict); + marshalObjPointer (Doxygen::symbolStorage,m_impl->groupAlias); + marshalInt (Doxygen::symbolStorage,m_impl->grpId); + marshalObjPointer (Doxygen::symbolStorage,m_impl->memberGroup); + marshalObjPointer (Doxygen::symbolStorage,m_impl->group); + marshalInt (Doxygen::symbolStorage,(int)m_impl->grouppri); + marshalQCString (Doxygen::symbolStorage,m_impl->groupFileName); + marshalInt (Doxygen::symbolStorage,m_impl->groupStartLine); + marshalObjPointer (Doxygen::symbolStorage,m_impl->groupMember); + marshalBool (Doxygen::symbolStorage,m_impl->isTypedefValCached); + marshalObjPointer (Doxygen::symbolStorage,m_impl->cachedTypedefValue); + marshalQCString (Doxygen::symbolStorage,m_impl->cachedTypedefTemplSpec); + marshalInt (Doxygen::symbolStorage,m_impl->inbodyLine); + marshalQCString (Doxygen::symbolStorage,m_impl->inbodyFile); + marshalQCString (Doxygen::symbolStorage,m_impl->inbodyDocs); + marshalObjPointer (Doxygen::symbolStorage,m_impl->docProvider); + marshalQCString (Doxygen::symbolStorage,m_impl->explicitOutputFileBase); + marshalBool (Doxygen::symbolStorage,m_impl->implOnly); + marshalBool (Doxygen::symbolStorage,m_impl->hasDocumentedParams); + marshalBool (Doxygen::symbolStorage,m_impl->hasDocumentedReturnType); + marshalBool (Doxygen::symbolStorage,m_impl->isDMember); + marshalBool (Doxygen::symbolStorage,m_impl->related); + marshalBool (Doxygen::symbolStorage,m_impl->stat); + marshalBool (Doxygen::symbolStorage,m_impl->proto); + marshalBool (Doxygen::symbolStorage,m_impl->docEnumValues); + marshalBool (Doxygen::symbolStorage,m_impl->annScope); + marshalBool (Doxygen::symbolStorage,m_impl->annUsed); + marshalBool (Doxygen::symbolStorage,m_impl->hasCallGraph); + marshalBool (Doxygen::symbolStorage,m_impl->hasCallerGraph); + marshalBool (Doxygen::symbolStorage,m_impl->explExt); + marshalBool (Doxygen::symbolStorage,m_impl->tspec); + marshalBool (Doxygen::symbolStorage,m_impl->groupHasDocs); + marshalBool (Doxygen::symbolStorage,m_impl->docsForDefinition); + marshalUInt(Doxygen::symbolStorage,END_MARKER); + + // function doesn't modify the object conceptually but compiler doesn't know this. + MemberDef *that = (MemberDef *)this; + delete that->m_impl; + that->m_impl=0; +} + +void MemberDef::loadFromDisk() const +{ + //printf("%p: MemberDef::loadFromDisk()\n",this); + Definition::loadFromDisk(); + + if (isLocked()) + { + assert(m_impl!=0); + return; + } + assert(m_impl==0); + //printf("%p: loading specific part\n",this); + + MemberDef *that = (MemberDef *)this; + that->m_impl = new MemberDefImpl; + + uint marker = unmarshalUInt(Doxygen::symbolStorage); + assert(marker==START_MARKER); + m_impl->classDef = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->fileDef = (FileDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->nspace = (NamespaceDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->enumScope = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->annEnumType = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->enumFields = unmarshalMemberList (Doxygen::symbolStorage); + m_impl->redefines = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->redefinedBy = unmarshalMemberList (Doxygen::symbolStorage); + m_impl->memDef = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->memDec = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->relatedAlso = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->exampleSDict = unmarshalExampleSDict (Doxygen::symbolStorage); + m_impl->type = unmarshalQCString (Doxygen::symbolStorage); + m_impl->args = unmarshalQCString (Doxygen::symbolStorage); + m_impl->def = unmarshalQCString (Doxygen::symbolStorage); + m_impl->anc = unmarshalQCString (Doxygen::symbolStorage); + m_impl->virt = (Specifier)unmarshalInt (Doxygen::symbolStorage); + m_impl->prot = (Protection)unmarshalInt(Doxygen::symbolStorage); + m_impl->decl = unmarshalQCString (Doxygen::symbolStorage); + m_impl->bitfields = unmarshalQCString (Doxygen::symbolStorage); + m_impl->read = unmarshalQCString (Doxygen::symbolStorage); + m_impl->write = unmarshalQCString (Doxygen::symbolStorage); + m_impl->exception = unmarshalQCString (Doxygen::symbolStorage); + m_impl->initializer = unmarshalQCString (Doxygen::symbolStorage); + m_impl->initLines = unmarshalInt (Doxygen::symbolStorage); + m_impl->memSpec = unmarshalInt (Doxygen::symbolStorage); + m_impl->mtype = (MemberDef::MemberType)unmarshalInt (Doxygen::symbolStorage); + m_impl->maxInitLines = unmarshalInt (Doxygen::symbolStorage); + m_impl->userInitLines = unmarshalInt (Doxygen::symbolStorage); + m_impl->annMemb = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->defArgList = unmarshalArgumentList (Doxygen::symbolStorage); + m_impl->declArgList = unmarshalArgumentList (Doxygen::symbolStorage); + m_impl->tArgList = unmarshalArgumentList (Doxygen::symbolStorage); + m_impl->templateMaster = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->defTmpArgLists = unmarshalArgumentLists(Doxygen::symbolStorage); + m_impl->cachedAnonymousType = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->classSectionSDict = unmarshalMemberLists (Doxygen::symbolStorage); + m_impl->groupAlias = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->grpId = unmarshalInt (Doxygen::symbolStorage); + m_impl->memberGroup = (MemberGroup*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->group = (GroupDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->grouppri = (Grouping::GroupPri_t)unmarshalInt (Doxygen::symbolStorage); + m_impl->groupFileName = unmarshalQCString (Doxygen::symbolStorage); + m_impl->groupStartLine = unmarshalInt (Doxygen::symbolStorage); + m_impl->groupMember = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->isTypedefValCached = unmarshalBool (Doxygen::symbolStorage); + m_impl->cachedTypedefValue = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->cachedTypedefTemplSpec = unmarshalQCString (Doxygen::symbolStorage); + m_impl->inbodyLine = unmarshalInt (Doxygen::symbolStorage); + m_impl->inbodyFile = unmarshalQCString (Doxygen::symbolStorage); + m_impl->inbodyDocs = unmarshalQCString (Doxygen::symbolStorage); + m_impl->docProvider = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage); + m_impl->explicitOutputFileBase = unmarshalQCString (Doxygen::symbolStorage); + m_impl->implOnly = unmarshalBool (Doxygen::symbolStorage); + m_impl->hasDocumentedParams = unmarshalBool (Doxygen::symbolStorage); + m_impl->hasDocumentedReturnType = unmarshalBool (Doxygen::symbolStorage); + m_impl->isDMember = unmarshalBool (Doxygen::symbolStorage); + m_impl->related = unmarshalBool (Doxygen::symbolStorage); + m_impl->stat = unmarshalBool (Doxygen::symbolStorage); + m_impl->proto = unmarshalBool (Doxygen::symbolStorage); + m_impl->docEnumValues = unmarshalBool (Doxygen::symbolStorage); + m_impl->annScope = unmarshalBool (Doxygen::symbolStorage); + m_impl->annUsed = unmarshalBool (Doxygen::symbolStorage); + m_impl->hasCallGraph = unmarshalBool (Doxygen::symbolStorage); + m_impl->hasCallerGraph = unmarshalBool (Doxygen::symbolStorage); + m_impl->explExt = unmarshalBool (Doxygen::symbolStorage); + m_impl->tspec = unmarshalBool (Doxygen::symbolStorage); + m_impl->groupHasDocs = unmarshalBool (Doxygen::symbolStorage); + m_impl->docsForDefinition = unmarshalBool (Doxygen::symbolStorage); + marker = unmarshalUInt(Doxygen::symbolStorage); + assert(marker==END_MARKER); +} + diff --git a/src/memberdef.h b/src/memberdef.h index 1d2d9d3..52ee455 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -38,6 +38,7 @@ class OutputList; class GroupDef; class QTextStream; class ArgumentList; +class MemberDefImpl; struct SourceReference { @@ -73,76 +74,79 @@ class MemberDef : public Definition ~MemberDef(); DefType definitionType() const { return TypeMember; } + //----------------------------------------------------------------------------------- + // ---- getters ----- + //----------------------------------------------------------------------------------- + // link id QCString getOutputFileBase() const; QCString getReference() const; QCString anchor() const; - const char *declaration() const { return decl; } - const char *definition() const { return def; } - const char *typeString() const { return type; } - const char *argsString() const { return args; } - const char *excpString() const { return exception; } - const char *bitfieldString() const { return bitfields; } - const QCString &initializer() const { return init; } - int initializerLines() const { return initLines; } - int getMemberSpecifiers() const { return memSpec; } + const char *declaration() const; + const char *definition() const; + const char *typeString() const; + const char *argsString() const; + const char *excpString() const; + const char *bitfieldString() const; + const QCString &initializer() const; + int initializerLines() const; + int getMemberSpecifiers() const; MemberList *getSectionList(Definition *d) const; // scope query members - ClassDef *getClassDef() const { return classDef; } - FileDef *getFileDef() const { return fileDef; } - NamespaceDef* getNamespaceDef() const { return nspace; } - //Definition *getCompoundDef() const; + ClassDef *getClassDef() const; + FileDef *getFileDef() const; + NamespaceDef* getNamespaceDef() const; // grabbing the property read/write accessor names - const char *getReadAccessor() const { return read; } - const char *getWriteAccessor() const { return write; } + const char *getReadAccessor() const; + const char *getWriteAccessor() const; // querying the grouping definition - GroupDef *getGroupDef() const { return group; } - Grouping::GroupPri_t getGroupPri() const { return grouppri; } - const char *getGroupFileName() const { return groupFileName; } - int getGroupStartLine() const { return groupStartLine; } - bool getGroupHasDocs() const { return groupHasDocs; } + GroupDef *getGroupDef() const; + Grouping::GroupPri_t getGroupPri() const; + const char *getGroupFileName() const; + int getGroupStartLine() const; + bool getGroupHasDocs() const; QCString qualifiedName(); QCString objCMethodName(bool localLink,bool showStatic) const; // direct kind info - Protection protection() const { return prot; } + Protection protection() const; Specifier virtualness() const; - MemberType memberType() const { return mtype; } + MemberType memberType() const; QCString memberTypeName() const; // getter methods - bool isSignal() const { return mtype==Signal; } - bool isSlot() const { return mtype==Slot; } - bool isVariable() const { return mtype==Variable; } - bool isEnumerate() const { return mtype==Enumeration; } - bool isEnumValue() const { return mtype==EnumValue; } - bool isTypedef() const { return mtype==Typedef; } - bool isFunction() const { return mtype==Function; } - bool isDefine() const { return mtype==Define; } - bool isFriend() const { return mtype==Friend; } - bool isDCOP() const { return mtype==DCOP; } - bool isProperty() const { return mtype==Property; } - bool isEvent() const { return mtype==Event; } - bool isRelated() const { return related; } - bool isStatic() const { return stat; } - bool isInline() const { return (memSpec&Entry::Inline)!=0; } - bool isExplicit() const { return (memSpec&Entry::Explicit)!=0; } - bool isMutable() const { return (memSpec&Entry::Mutable)!=0; } - bool isGettable() const { return (memSpec&Entry::Gettable)!=0; } - bool isSettable() const { return (memSpec&Entry::Settable)!=0; } - bool isReadable() const { return (memSpec&Entry::Readable)!=0; } - bool isWritable() const { return (memSpec&Entry::Writable)!=0; } - bool isFinal() const { return (memSpec&Entry::Final)!=0; } - bool isAbstract() const { return (memSpec&Entry::Abstract)!=0; } - bool isImplementation() const { return m_implOnly; } - bool isExternal() const { return explExt; } - bool isTemplateSpecialization() const { return tspec; } - bool hasDocumentedParams() const { return m_hasDocumentedParams; } - bool hasDocumentedReturnType() const { return m_hasDocumentedReturnType; } + bool isSignal() const; + bool isSlot() const; + bool isVariable() const; + bool isEnumerate() const; + bool isEnumValue() const; + bool isTypedef() const; + bool isFunction() const; + bool isDefine() const; + bool isFriend() const; + bool isDCOP() const; + bool isProperty() const; + bool isEvent() const; + bool isRelated() const; + bool isStatic() const; + bool isInline() const; + bool isExplicit() const; + bool isMutable() const; + bool isGettable() const; + bool isSettable() const; + bool isReadable() const; + bool isWritable() const; + bool isFinal() const; + bool isAbstract() const; + bool isImplementation() const; + bool isExternal() const; + bool isTemplateSpecialization() const; + bool hasDocumentedParams() const; + bool hasDocumentedReturnType() const; bool isObjCMethod() const; bool isConstructor() const; bool isDestructor() const; @@ -160,153 +164,173 @@ class MemberDef : public Definition bool isFriendClass() const; bool isDocumentedFriendClass() const; + MemberDef *reimplements() const; + LockingPtr reimplementedBy() const; + + int inbodyLine() const; + QCString inbodyFile() const; + const QCString &inbodyDocumentation() const; + + ClassDef *relatedAlso() const; + + bool hasDocumentedEnumValues() const; + MemberDef *getAnonymousEnumType() const; + bool isDocsForDefinition() const; + MemberDef *getEnumScope() const; + LockingPtr enumFieldList() const; + + bool hasExamples(); + LockingPtr getExamples() const; + bool isPrototype() const; + + // argument related members + LockingPtr argumentList() const; + LockingPtr declArgumentList() const; + LockingPtr templateArguments() const; + LockingPtr< QList > definitionTemplateParameterLists() const; + + // member group related members + int getMemberGroupId() const; + MemberGroup *getMemberGroup() const; + + bool fromAnonymousScope() const; + bool anonymousDeclShown() const; + + // callgraph related members + bool hasCallGraph() const; + bool hasCallerGraph() const; + bool visibleMemberGroup(bool hideNoHeader); + + MemberDef *templateMaster() const; + QCString getScopeString() const; + ClassDef *getClassDefOfAnonymousType(); + + // cached typedef functions + bool isTypedefValCached() const; + ClassDef *getCachedTypedefVal() const; + QCString getCachedTypedefTemplSpec() const; + + MemberDef *memberDefinition() const; + MemberDef *memberDeclaration() const; + MemberDef *inheritsDocsFrom() const; + MemberDef *getGroupAlias() const; + + //----------------------------------------------------------------------------------- + // ---- setters ----- + //----------------------------------------------------------------------------------- + // set functions - void setMemberType(MemberType t) { mtype=t; } - void setDefinition(const char *d) { def=d; } - void setFileDef(FileDef *fd) { fileDef=fd; } + void setMemberType(MemberType t); + void setDefinition(const char *d); + void setFileDef(FileDef *fd); void setAnchor(const char *a); - void setProtection(Protection p) { prot=p; } - void setMemberSpecifiers(int s) { memSpec=s; } - void mergeMemberSpecifiers(int s) { memSpec|=s; } + void setProtection(Protection p); + void setMemberSpecifiers(int s); + void mergeMemberSpecifiers(int s); void setInitializer(const char *i); - void setBitfields(const char *s) { bitfields = s; } - void setMaxInitLines(int lines) { userInitLines=lines; } + void setBitfields(const char *s); + void setMaxInitLines(int lines); void setMemberClass(ClassDef *cd); void setSectionList(Definition *d,MemberList *sl); void setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, const QCString &fileName,int startLine,bool hasDocs, MemberDef *member=0); - void setExplicitExternal(bool b) { explExt=b; } - void setReadAccessor(const char *r) { read=r; } - void setWriteAccessor(const char *w) { write=w; } - void setTemplateSpecialization(bool b) { tspec=b; } + void setExplicitExternal(bool b); + void setReadAccessor(const char *r); + void setWriteAccessor(const char *w); + void setTemplateSpecialization(bool b); - void makeRelated() { related=TRUE; } - void setHasDocumentedParams(bool b) { m_hasDocumentedParams = b; } - void setHasDocumentedReturnType(bool b) { m_hasDocumentedReturnType = b; } - void setInheritsDocsFrom(MemberDef *md) { m_docProvider = md; } + void makeRelated(); + void setHasDocumentedParams(bool b); + void setHasDocumentedReturnType(bool b); + void setInheritsDocsFrom(MemberDef *md); void setTagInfo(TagInfo *i); - void setArgsString(const char *as) { args = as; } + void setArgsString(const char *as); - // output generation - void writeDeclaration(OutputList &ol, - ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, - bool inGroup); - void writeDocumentation(MemberList *ml,OutputList &ol, - const char *scopeName,Definition *container, - bool inGroup,bool showEnumValues=FALSE); - void warnIfUndocumented(); - // relation to other members void setReimplements(MemberDef *md); void insertReimplementedBy(MemberDef *md); - MemberDef *reimplements() const; - MemberList *reimplementedBy() const; - + // in-body documentation void setInbodyDocumentation(const char *docs,const char *file,int line); - int inbodyLine() const { return m_inbodyLine; } - QCString inbodyFile() const { return m_inbodyFile; } - const QCString &inbodyDocumentation() const { return m_inbodyDocs; } - - // For function documentation that can also be found in a class's related func section. - void setRelatedAlso(ClassDef *cd) { m_relatedAlso=cd; } - ClassDef *relatedAlso() const { return m_relatedAlso; } - + + void setRelatedAlso(ClassDef *cd); + // enumeration specific members void insertEnumField(MemberDef *md); void setEnumScope(MemberDef *md); - void setEnumClassScope(ClassDef *cd) { classDef = cd; } - MemberDef *getEnumScope() const { return enumScope; } - MemberList *enumFieldList() const { return enumFields; } - void setDocumentedEnumValues(bool value) { docEnumValues=value; } - bool hasDocumentedEnumValues() const { return docEnumValues; } - void setAnonymousEnumType(MemberDef *md) { annEnumType = md; } - MemberDef *getAnonymousEnumType() const { return annEnumType; } - bool isDocsForDefinition() const { return docsForDefinition; } - + void setEnumClassScope(ClassDef *cd); + void setDocumentedEnumValues(bool value); + void setAnonymousEnumType(MemberDef *md); + // example related members bool addExample(const char *anchor,const char *name,const char *file); - bool hasExamples(); - ExampleSDict *getExamples() const { return exampleSDict; } // prototype related members - void setPrototype(bool p) { proto=p; } - bool isPrototype() const { return proto; } - + void setPrototype(bool p); + // argument related members - ArgumentList *argumentList() const { return defArgList; } - ArgumentList *declArgumentList() const { return declArgList; } void setArgumentList(ArgumentList *al); void setDeclArgumentList(ArgumentList *al); - ArgumentList *templateArguments() const { return tArgList; } void setDefinitionTemplateParameterLists(QList *lists); - QList *definitionTemplateParameterLists() const - { return m_defTmpArgLists; } - + // namespace related members void setNamespace(NamespaceDef *nd); // member group related members void setMemberGroup(MemberGroup *grp); - MemberGroup *getMemberGroup() const { return memberGroup; } - void setMemberGroupId(int id) { grpId=id; } - int getMemberGroupId() const { return grpId; } - void makeImplementationDetail() { m_implOnly=TRUE; } - + void setMemberGroupId(int id); + void makeImplementationDetail(); + // anonymous scope members - void setFromAnonymousScope(bool b) { annScope=b; } - void setFromAnonymousMember(MemberDef *m) { annMemb=m; } - bool fromAnonymousScope() const { return annScope; } - bool anonymousDeclShown() const { return annUsed; } + void setFromAnonymousScope(bool b); + void setFromAnonymousMember(MemberDef *m); - // callgraph related members - bool hasCallGraph() const { return m_hasCallGraph; } void enableCallGraph(bool e); - - // callergraph related members - bool hasCallerGraph() const { return m_hasCallerGraph; } void enableCallerGraph(bool e); - - bool visibleMemberGroup(bool hideNoHeader); - MemberDef *templateMaster() const { return m_templateMaster; } - QCString getScopeString() const; - - ClassDef *getClassDefOfAnonymousType(); - MemberDef *createTemplateInstanceMember(ArgumentList *formalArgs, - ArgumentList *actualArgs); - void setTemplateMaster(MemberDef *mt) { m_templateMaster=mt; } + void setTemplateMaster(MemberDef *mt); void addListReference(Definition *d); + void setDocsForDefinition(bool b); + void setGroupAlias(MemberDef *md); - MemberDef *inheritsDocsFrom() const { return m_docProvider; } - - void setDocsForDefinition(bool b) { docsForDefinition = b; } - void setGroupAlias(MemberDef *md) { groupAlias = md; } - MemberDef *getGroupAlias() const { return groupAlias; } - - // cached typedef functions - bool isTypedefValCached() const { return m_isTypedefValCached; } - ClassDef *getCachedTypedefVal() const { return m_cachedTypedefValue; } - QCString getCachedTypedefTemplSpec() const { return m_cachedTypedefTemplSpec; } - void cacheTypedefVal(ClassDef *val,const QCString &templSpec) - { m_isTypedefValCached=TRUE; m_cachedTypedefValue=val; m_cachedTypedefTemplSpec=templSpec; } - void invalidateTypedefValCache() { m_isTypedefValCached=FALSE; } + void cacheTypedefVal(ClassDef *val,const QCString &templSpec); + void invalidateTypedefValCache(); // declaration <-> definition relation - void setMemberDefinition(MemberDef *md) { memDef=md; } - void setMemberDeclaration(MemberDef *md) { memDec=md; } - MemberDef *memberDefinition() const { return memDef; } - MemberDef *memberDeclaration() const { return memDec; } + void setMemberDefinition(MemberDef *md); + void setMemberDeclaration(MemberDef *md); + void setAnonymousUsed(); + + //----------------------------------------------------------------------------------- + // --- actions ---- + //----------------------------------------------------------------------------------- + + // output generation + void writeDeclaration(OutputList &ol, + ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, + bool inGroup); + void writeDocumentation(MemberList *ml,OutputList &ol, + const char *scopeName,Definition *container, + bool inGroup,bool showEnumValues=FALSE); + void warnIfUndocumented(); + + MemberDef *createTemplateInstanceMember(ArgumentList *formalArgs, + ArgumentList *actualArgs); + void writeEnumDeclaration(OutputList &typeDecl, ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd); void findSectionsInDocumentation(); bool visited; - + + protected: + void flushToDisk() const; + void loadFromDisk() const; private: + static int s_indentLevel; // disable copying of member defs MemberDef(const MemberDef &); MemberDef &operator=(const MemberDef &); @@ -315,107 +339,7 @@ class MemberDef : public Definition ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, bool onlyText=FALSE); - ClassDef *classDef; // member of or related to - FileDef *fileDef; // member of file definition - NamespaceDef *nspace; // the namespace this member is in. - - MemberDef *enumScope; // the enclosing scope, if this is an enum field - MemberDef *annEnumType; // the annonymous enum that is the type of this member - MemberList *enumFields; // enumeration fields - OutputList *enumDeclList; // stored piece of documentation for enumeration. - - MemberDef *redefines; // the members that this member redefines - MemberList *redefinedBy; // the list of members that redefine this one - - MemberDef *memDef; // member definition for this declaration - MemberDef *memDec; // member declaration for this definition - ClassDef *m_relatedAlso; // points to class marked by relatedAlso - - ExampleSDict *exampleSDict; // a dictionary of all examples for quick access - - QCString type; // return type - QCString args; // function arguments/variable array specifiers - QCString def; // member definition in code (fully qualified name) - QCString anc; // HTML anchor name - Specifier virt; // normal/virtual/pure virtual - Protection prot; // protection type [Public/Protected/Private] - QCString decl; // member declaration in class: TODO: can be generated - - QCString bitfields; // struct member bitfields - QCString read; // property read accessor - QCString write; // property write accessor - QCString exception; // exceptions that can be thrown - QCString init; // initializer - int initLines; // number of lines in the initializer - - int memSpec; // The specifiers present for this member - MemberType mtype; // returns the kind of member - int maxInitLines; // when the initializer will be displayed - int userInitLines; // result of explicit \hideinitializer or \showinitializer - MemberList *section; // declation list containing this member - MemberDef *annMemb; - - ArgumentList *defArgList; // argument list of this member definition - ArgumentList *declArgList; // argument list of this member declaration - - ArgumentList *tArgList; // template argument list of function template - MemberDef *m_templateMaster; - QList *m_defTmpArgLists; - - ClassDef *cachedAnonymousType; // if the member has an anonymous compound - // as its type then this is computed by - // getClassDefOfAnonymousType() and - // cached here. - SDict *classSectionSDict; - - MemberDef *groupAlias; // Member containing the definition - int grpId; // group id - MemberGroup *memberGroup; // group's member definition - GroupDef *group; // group in which this member is in - Grouping::GroupPri_t grouppri; // priority of this definition - QCString groupFileName; // file where this grouping was defined - int groupStartLine; // line " " " " " - MemberDef *groupMember; - - bool m_isTypedefValCached; - ClassDef *m_cachedTypedefValue; - QCString m_cachedTypedefTemplSpec; - - // inbody documentation - int m_inbodyLine; - QCString m_inbodyFile; - QCString m_inbodyDocs; - - // documentation inheritance - MemberDef *m_docProvider; - - // to store the output file base from tag files - QCString explicitOutputFileBase; - - // objective-c - bool m_implOnly; // function found in implementation but not - // in the interface - bool m_hasDocumentedParams; - bool m_hasDocumentedReturnType; - bool m_isDMember; - bool related; // is this a member that is only related to a class - bool stat; // is it a static function? - bool proto; // is it a prototype; - bool docEnumValues; // is an enum with documented enum values. - bool annScope; // member is part of an annoymous scope - bool annUsed; - bool annShown; - bool m_hasCallGraph; - bool m_hasCallerGraph; - bool explExt; // member was explicitly declared external - bool tspec; // member is a template specialization - bool groupHasDocs; // true if the entry that caused the grouping was documented - bool docsForDefinition; // TRUE => documentation block is put before - // definition. - // FALSE => block is put before declaration. - - static int s_indentLevel; - + MemberDefImpl *m_impl; }; #endif diff --git a/src/membergroup.cpp b/src/membergroup.cpp index e3c4b24..786b38f 100644 --- a/src/membergroup.cpp +++ b/src/membergroup.cpp @@ -27,6 +27,7 @@ #include "groupdef.h" #include "doxygen.h" #include "docparser.h" +#include "marshal.h" //static QCString idToName(int id) //{ @@ -35,6 +36,10 @@ // return result; //} +MemberGroup::MemberGroup() +{ +} + MemberGroup::MemberGroup(Definition *parent, int id,const char *hdr,const char *d,const char *docFile) { @@ -244,3 +249,35 @@ void MemberGroup::findSectionsInDocumentation() memberList->findSectionsInDocumentation(); } +void MemberGroup::marshal(StorageIntf *s) +{ + marshalMemberList(s,memberList); + marshalObjPointer(s,inDeclSection); // reference only + marshalInt(s,grpId); + marshalQCString(s,grpHeader); + marshalQCString(s,fileName); + marshalObjPointer(s,scope); + marshalQCString(s,doc); + marshalBool(s,inSameSection); + marshalInt(s,m_numDecMembers); + marshalInt(s,m_numDocMembers); + marshalObjPointer(s,m_parent); + marshalQCString(s,m_docFile); +} + +void MemberGroup::unmarshal(StorageIntf *s) +{ + memberList = unmarshalMemberList(s); + inDeclSection = (MemberList *)unmarshalObjPointer(s); + grpId = unmarshalInt(s); + grpHeader = unmarshalQCString(s); + fileName = unmarshalQCString(s); + scope = (Definition *)unmarshalObjPointer(s); + doc = unmarshalQCString(s); + inSameSection = unmarshalBool(s); + m_numDecMembers = unmarshalInt(s); + m_numDocMembers = unmarshalInt(s); + m_parent = (Definition *)unmarshalObjPointer(s); + m_docFile = unmarshalQCString(s); +} + diff --git a/src/membergroup.h b/src/membergroup.h index 9c72fd6..885341a 100644 --- a/src/membergroup.h +++ b/src/membergroup.h @@ -20,6 +20,7 @@ #include "qtbc.h" #include +#include #include "sortdict.h" #define DOX_NOGROUP -1 @@ -32,10 +33,12 @@ class MemberList; class GroupDef; class OutputList; class Definition; +class StorageIntf; class MemberGroup { public: + MemberGroup(); MemberGroup(Definition *parent,int id,const char *header, const char *docs,const char *docFile); ~MemberGroup(); @@ -74,14 +77,17 @@ class MemberGroup MemberList *members() const { return memberList; } Definition *parent() const { return m_parent; } + void marshal(StorageIntf *s); + void unmarshal(StorageIntf *s); + private: MemberList *memberList; // list of all members in the group + MemberList *inDeclSection; int grpId; QCString grpHeader; QCString fileName; // base name of the generated file Definition *scope; QCString doc; - MemberList *inDeclSection; bool inSameSection; int m_numDecMembers; int m_numDocMembers; diff --git a/src/memberlist.cpp b/src/memberlist.cpp index b4fbdb3..78509bb 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -25,12 +25,17 @@ #include "doxygen.h" #include "outputlist.h" #include "groupdef.h" +#include "marshal.h" + +MemberList::MemberList() +{ +} MemberList::MemberList(ListType lt) : m_listType(lt) { memberGroupList=0; - m_numDecMembers=-1; // special value indicating that computation is needed - m_numDocMembers=-1; // special value indicating that computation is needed + m_numDecMembers=-1; // special value indicating that value needs to be computed + m_numDocMembers=-1; // special value indicating that value needs to be computed m_inGroup=FALSE; m_inFile=FALSE; } @@ -456,9 +461,10 @@ void MemberList::addListReferences(Definition *def) if (md->getGroupDef()==0 || def->definitionType()==Definition::TypeGroup) { md->addListReference(def); - if (md->memberType()==MemberDef::Enumeration && md->enumFieldList()) + LockingPtr enumFields = md->enumFieldList(); + if (md->memberType()==MemberDef::Enumeration && enumFields!=0) { - MemberListIterator vmli(*md->enumFieldList()); + MemberListIterator vmli(*enumFields); MemberDef *vmd; for ( ; (vmd=vmli.current()) ; ++vmli) { @@ -497,6 +503,69 @@ void MemberList::findSectionsInDocumentation() } } +void MemberList::marshal(StorageIntf *s) +{ + marshalInt(s,(int)m_listType); + marshalInt(s,m_varCnt); + marshalInt(s,m_funcCnt); + marshalInt(s,m_enumCnt); + marshalInt(s,m_enumValCnt); + marshalInt(s,m_typeCnt); + marshalInt(s,m_protoCnt); + marshalInt(s,m_defCnt); + marshalInt(s,m_friendCnt); + marshalInt(s,m_numDecMembers); + marshalInt(s,m_numDocMembers); + marshalBool(s,m_inGroup); + marshalBool(s,m_inFile); + if (memberGroupList==0) + { + marshalUInt(s,NULL_LIST); // null pointer representation + } + else + { + marshalUInt(s,memberGroupList->count()); + QListIterator mgi(*memberGroupList); + MemberGroup *mg=0; + for (mgi.toFirst();(mg=mgi.current());++mgi) + { + mg->marshal(s); + } + } +} + +void MemberList::unmarshal(StorageIntf *s) +{ + m_listType = (MemberList::ListType)unmarshalInt(s); + m_varCnt = unmarshalInt(s); + m_funcCnt = unmarshalInt(s); + m_enumCnt = unmarshalInt(s); + m_enumValCnt = unmarshalInt(s); + m_typeCnt = unmarshalInt(s); + m_protoCnt = unmarshalInt(s); + m_defCnt = unmarshalInt(s); + m_friendCnt = unmarshalInt(s); + m_numDecMembers = unmarshalInt(s); + m_numDocMembers = unmarshalInt(s); + m_inGroup = unmarshalBool(s); + m_inFile = unmarshalBool(s); + uint i,count = unmarshalUInt(s); + if (count==NULL_LIST) // empty list + { + memberGroupList = 0; + } + else // add member groups + { + memberGroupList = new MemberGroupList; + for (i=0;iunmarshal(s); + memberGroupList->append(mg); + } + } +} + //-------------------------------------------------------------------------- int MemberSDict::compareItems(GCI item1, GCI item2) diff --git a/src/memberlist.h b/src/memberlist.h index 27c1c52..1467835 100644 --- a/src/memberlist.h +++ b/src/memberlist.h @@ -25,6 +25,7 @@ class GroupDef; class MemberGroup; class MemberGroupList; +class StorageIntf; class MemberList : public QList { @@ -99,6 +100,7 @@ class MemberList : public QList memberGroup = 55 }; + MemberList(); MemberList(ListType lt); ~MemberList(); ListType listType() const { return m_listType; } @@ -134,9 +136,18 @@ class MemberList : public QList void findSectionsInDocumentation(); MemberGroupList *getMemberGroupList() const { return memberGroupList; } + void marshal(StorageIntf *s); + void unmarshal(StorageIntf *s); + private: - int m_varCnt,m_funcCnt,m_enumCnt,m_enumValCnt,m_typeCnt; - int m_protoCnt,m_defCnt,m_friendCnt; + int m_varCnt; + int m_funcCnt; + int m_enumCnt; + int m_enumValCnt; + int m_typeCnt; + int m_protoCnt; + int m_defCnt; + int m_friendCnt; 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; diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index 5918966..e216081 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -91,14 +91,6 @@ void NamespaceDef::findSectionsInDocumentation() ml->findSectionsInDocumentation(); } } -#if 0 - decDefineMembers.findSectionsInDocumentation(); - decProtoMembers.findSectionsInDocumentation(); - decTypedefMembers.findSectionsInDocumentation(); - decEnumMembers.findSectionsInDocumentation(); - decFuncMembers.findSectionsInDocumentation(); - decVarMembers.findSectionsInDocumentation(); -#endif } void NamespaceDef::insertUsedFile(const char *f) @@ -159,14 +151,6 @@ void NamespaceDef::addMembersToMemberGroup() ::addMembersToMemberGroup(ml,&memberGroupSDict,this); } } -#if 0 - ::addMembersToMemberGroup(&decDefineMembers,&memberGroupSDict,this); - ::addMembersToMemberGroup(&decProtoMembers,&memberGroupSDict,this); - ::addMembersToMemberGroup(&decTypedefMembers,&memberGroupSDict,this); - ::addMembersToMemberGroup(&decEnumMembers,&memberGroupSDict,this); - ::addMembersToMemberGroup(&decFuncMembers,&memberGroupSDict,this); - ::addMembersToMemberGroup(&decVarMembers,&memberGroupSDict,this); -#endif } void NamespaceDef::insertMember(MemberDef *md) @@ -178,82 +162,35 @@ void NamespaceDef::insertMember(MemberDef *md) m_memberLists.append(allMemberList); } allMemberList->append(md); + ::addNamespaceMemberNameToIndex(md); //static bool sortBriefDocs=Config_getBool("SORT_BRIEF_DOCS"); switch(md->memberType()) { case MemberDef::Variable: addMemberToList(MemberList::decVarMembers,md); - //if (sortBriefDocs) - // decVarMembers.inSort(md); - //else - // decVarMembers.append(md); addMemberToList(MemberList::docVarMembers,md); - //if (sortBriefDocs) - // docVarMembers.inSort(md); - //else - // docVarMembers.append(md); break; case MemberDef::Function: addMemberToList(MemberList::decFuncMembers,md); - //if (sortBriefDocs) - // decFuncMembers.inSort(md); - //else - // decFuncMembers.append(md); addMemberToList(MemberList::docFuncMembers,md); - //if (sortBriefDocs) - // docFuncMembers.inSort(md); - //else - // docFuncMembers.append(md); break; case MemberDef::Typedef: addMemberToList(MemberList::decTypedefMembers,md); - //if (sortBriefDocs) - // decTypedefMembers.inSort(md); - //else - // decTypedefMembers.append(md); addMemberToList(MemberList::docTypedefMembers,md); - //if (sortBriefDocs) - // docTypedefMembers.inSort(md); - //else - // docTypedefMembers.append(md); break; case MemberDef::Enumeration: addMemberToList(MemberList::decEnumMembers,md); - //if (sortBriefDocs) - // decEnumMembers.inSort(md); - //else - // decEnumMembers.append(md); addMemberToList(MemberList::docEnumMembers,md); - //if (sortBriefDocs) - // docEnumMembers.inSort(md); - //else - // docEnumMembers.append(md); break; case MemberDef::EnumValue: break; case MemberDef::Prototype: addMemberToList(MemberList::decProtoMembers,md); - //if (sortBriefDocs) - // decProtoMembers.inSort(md); - //else - // decProtoMembers.append(md); addMemberToList(MemberList::docProtoMembers,md); - //if (sortBriefDocs) - // docProtoMembers.inSort(md); - //else - // docProtoMembers.append(md); break; case MemberDef::Define: addMemberToList(MemberList::decDefineMembers,md); - //if (sortBriefDocs) - // decDefineMembers.inSort(md); - //else - // decDefineMembers.append(md); addMemberToList(MemberList::docDefineMembers,md); - //if (sortBriefDocs) - // docDefineMembers.inSort(md); - //else - // docDefineMembers.append(md); break; default: err("NamespaceDef::insertMembers(): " @@ -262,7 +199,6 @@ void NamespaceDef::insertMember(MemberDef *md) md->getClassDef() ? md->getClassDef()->name().data() : "", name().data()); } - //addMemberToGroup(md,groupId); } void NamespaceDef::computeAnchors() @@ -388,17 +324,11 @@ void NamespaceDef::writeDocumentation(OutputList &ol) } writeMemberDeclarations(ol,MemberList::decDefineMembers,theTranslator->trDefines()); - //decDefineMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trDefines(),0); writeMemberDeclarations(ol,MemberList::decProtoMembers,theTranslator->trFuncProtos()); - //decProtoMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trFuncProtos(),0); writeMemberDeclarations(ol,MemberList::decTypedefMembers,theTranslator->trTypedefs()); - //decTypedefMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trTypedefs(),0); writeMemberDeclarations(ol,MemberList::decEnumMembers,theTranslator->trEnumerations()); - //decEnumMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trEnumerations(),0); writeMemberDeclarations(ol,MemberList::decFuncMembers,theTranslator->trFunctions()); - //decFuncMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trFunctions(),0); writeMemberDeclarations(ol,MemberList::decVarMembers,theTranslator->trVariables()); - //decVarMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trVariables(),0); ol.endMemberSections(); if (!Config_getBool("DETAILS_AT_TOP")) @@ -441,28 +371,11 @@ void NamespaceDef::writeMemberDocumentation(OutputList &ol) } writeMemberDocumentation(ol,MemberList::docDefineMembers,theTranslator->trDefineDocumentation()); - //docDefineMembers.writeDocumentation(ol,name(),this, - // theTranslator->trDefineDocumentation()); - writeMemberDocumentation(ol,MemberList::docProtoMembers,theTranslator->trFunctionPrototypeDocumentation()); - //docProtoMembers.writeDocumentation(ol,name(),this, - // theTranslator->trFunctionPrototypeDocumentation()); - writeMemberDocumentation(ol,MemberList::docTypedefMembers,theTranslator->trTypedefDocumentation()); - //docTypedefMembers.writeDocumentation(ol,name(),this, - // theTranslator->trTypedefDocumentation()); - writeMemberDocumentation(ol,MemberList::docEnumMembers,theTranslator->trEnumerationTypeDocumentation()); - //docEnumMembers.writeDocumentation(ol,name(),this, - // theTranslator->trEnumerationTypeDocumentation()); - writeMemberDocumentation(ol,MemberList::docFuncMembers,theTranslator->trFunctionDocumentation()); - //docFuncMembers.writeDocumentation(ol,name(),this, - // theTranslator->trFunctionDocumentation()); - writeMemberDocumentation(ol,MemberList::docVarMembers,theTranslator->trVariableDocumentation()); - //docVarMembers.writeDocumentation(ol,name(),this, - // theTranslator->trVariableDocumentation()); if (Config_getBool("SEPARATE_MEMBER_PAGES")) { @@ -484,15 +397,6 @@ void NamespaceDef::writeMemberPages(OutputList &ol) ml->writeDocumentationPage(ol,name(),this); } } -#if 0 - docDefineMembers.writeDocumentationPage(ol,name(),this); - docProtoMembers.writeDocumentationPage(ol,name(),this); - docTypedefMembers.writeDocumentationPage(ol,name(),this); - docEnumMembers.writeDocumentationPage(ol,name(),this); - docFuncMembers.writeDocumentationPage(ol,name(),this); - docVarMembers.writeDocumentationPage(ol,name(),this); -#endif - ol.popGeneratorState(); } @@ -602,10 +506,13 @@ Definition *NamespaceDef::findInnerCompound(const char *n) void NamespaceDef::addListReferences() { - addRefItem(xrefListItems(), - theTranslator->trNamespace(TRUE,TRUE), - getOutputFileBase(),displayName() - ); + { + LockingPtr< QList > xrefItems = xrefListItems(); + addRefItem(xrefItems.pointer(), + theTranslator->trNamespace(TRUE,TRUE), + getOutputFileBase(),displayName() + ); + } MemberGroupSDict::Iterator mgli(*memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) @@ -621,14 +528,6 @@ void NamespaceDef::addListReferences() ml->addListReferences(this); } } -#if 0 - docDefineMembers.addListReferences(this); - docProtoMembers.addListReferences(this); - docTypedefMembers.addListReferences(this); - docEnumMembers.addListReferences(this); - docFuncMembers.addListReferences(this); - docVarMembers.addListReferences(this); -#endif } QCString NamespaceDef::displayName() const diff --git a/src/objcache.cpp b/src/objcache.cpp new file mode 100644 index 0000000..c192504 --- /dev/null +++ b/src/objcache.cpp @@ -0,0 +1,315 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2006 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. + * + */ + +#include +#include +#include "objcache.h" + +//---------------------------------------------------------------------- + +#ifdef CACHE_STATS +int ObjCache::misses = 0; +int ObjCache::hits = 0; +#endif + +//---------------------------------------------------------------------- + +ObjCache::ObjCache(unsigned int logSize) + : m_head(-1), m_tail(-1), //m_numEntries(0), + m_size(1<index); + moveToFront(hnode->index); +#ifdef CACHE_STATS + hits++; +#endif + } + else // object not in the cache. + { + void *lruObj=0; + if (m_freeCacheNodes!=-1) // cache not full -> add element to the cache + { + // remove element from free list + int index = m_freeCacheNodes; + m_freeCacheNodes = m_cache[index].next; + + // add to head of the list + if (m_tail==-1) + { + m_tail = index; + } + m_cache[index].prev = -1; + m_cache[index].next = m_head; + if (m_head!=-1) + { + m_cache[m_head].prev = index; + } + m_head = index; + } + else // cache full -> replace element in the cache + { + //printf("Cache full!\n"); + lruObj = m_cache[m_tail].obj; + hashRemove(lruObj); + moveToFront(m_tail); // m_tail indexes the emptied element, which becomes m_head + } + //printf("numEntries=%d size=%d\n",m_numEntries,m_size); + m_cache[m_head].obj = obj; + hnode = hashInsert(obj); + hnode->index = m_head; + *victim = lruObj; +#ifdef CACHE_STATS + misses++; +#endif + } + return m_head; +} + +void ObjCache::del(int index) +{ + assert(index!=-1); + assert(m_cache[index].obj!=0); + hashRemove(m_cache[index].obj); + moveToFront(index); + m_head = m_cache[index].next; + if (m_head==-1) + m_tail=-1; + else + m_cache[m_head].prev=-1; + m_cache[index].obj=0; + m_cache[index].prev=-1; + m_cache[index].next = m_freeCacheNodes; + m_freeCacheNodes = index; +} + +#ifdef CACHE_DEBUG +#define cache_debug_printf printf +void ObjCache::printLRU() +{ + cache_debug_printf("MRU->LRU: "); + int index = m_head; + while (index!=-1) + { + cache_debug_printf("%d=%p ",index,m_cache[index].obj); + index = m_cache[index].next; + } + cache_debug_printf("\n"); + + cache_debug_printf("LRU->MRU: "); + index = m_tail; + while (index!=-1) + { + cache_debug_printf("%d=%p ",index,m_cache[index].obj); + index = m_cache[index].prev; + } + cache_debug_printf("\n"); +} +#endif + +#ifdef CACHE_STATS +#define cache_stats_printf printf +void ObjCache::printStats() +{ + cache_stats_printf("ObjCache: hits=%d misses=%d hit ratio=%f\n",hits,misses,hits*100.0/(hits+misses)); +} +#endif + +void ObjCache::moveToFront(int index) +{ + int prev,next; + if (m_head!=index) + { + next = m_cache[index].next; + prev = m_cache[index].prev; + + // de-chain node at index + m_cache[prev].next = next; + if (next!=-1) m_cache[next].prev = prev; else m_tail = prev; + + // add to head + m_cache[index].prev = -1; + m_cache[index].next = m_head; + m_cache[m_head].prev = index; + m_head = index; + } +} + +unsigned int ObjCache::hash(void *addr) +{ + // Thomas Wang's 32 bit Mix Function + + // TODO: what if sizeof(void*)!=4 ? + unsigned int key = (unsigned int)addr; + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key & (m_size-1); +} + +ObjCache::HashNode *ObjCache::hashFind(void *obj) +{ + HashNode *node = 0; + int index = m_hash[hash(obj)].head; + //printf("hashFind: obj=%p index=%d\n",obj,index); + while (index!=-1 && + m_hash[index].obj!=obj + ) // search for right object in the list + { + index = m_hash[index].nextHash; + } + // found the obj at index, so it is in the cache! + if (index!=-1) + { + node = &m_hash[index]; + } + return node; +} + +ObjCache::HashNode *ObjCache::hashInsert(void *obj) +{ + int index = hash(obj); + //printf("Inserting %p index=%d\n",obj,index); + + // remove element from empty list + int newElement = m_freeHashNodes; + assert(newElement!=-1); + m_freeHashNodes = m_hash[m_freeHashNodes].nextHash; + + if (m_hash[index].head!=-1) // hash collision -> goto end of the list + { + index = m_hash[index].head; + while (m_hash[index].nextHash!=-1) + { + index = m_hash[index].nextHash; + } + // add to end of the list + m_hash[index].nextHash = newElement; + } + else // first element in the hash list + { + m_hash[index].head = newElement; + } + // add to the end of the list + m_hash[newElement].nextHash = -1; + m_hash[newElement].obj = obj; + return &m_hash[newElement]; +} + +void ObjCache::hashRemove(void *obj) +{ + int index = hash(obj); + + // find element + int curIndex = m_hash[index].head; + int prevIndex=-1; + while (m_hash[curIndex].obj!=obj) + { + prevIndex = curIndex; + curIndex = m_hash[curIndex].nextHash; + } + + if (prevIndex==-1) // remove from start + { + m_hash[index].head = m_hash[curIndex].nextHash; + } + else // remove in the middle + { + m_hash[prevIndex].nextHash = m_hash[curIndex].nextHash; + } + + // add curIndex element to empty list + m_hash[curIndex].nextHash = m_freeHashNodes; + m_hash[curIndex].index = -1; + m_hash[curIndex].obj = 0; + m_freeHashNodes = curIndex; +} + +#ifdef CACHE_TEST +int main() +{ + int i; + struct obj + { + obj() : handle(-1) {} + int handle; + }; + obj *objs = new obj[100]; + ObjCache c(3); + for (i=0;i<32;i++) + { + int objId=(i%3)+(i>>2)*4; + printf("------- use(%d=%p)--------\n",objId,&objs[objId]); +#ifdef CACHE_DEBUG + c.printLRU(); +#endif + obj *victim=0; + if (objs[objId].handle==-1) + { + objs[objId].handle = c.add(&objs[objId],(void**)&victim); + if (victim) victim->handle=-1; + } + else + { + c.use(objs[objId].handle); + } + printf("i=%d objId=%d using %p victim=%p\n",i,objId,&objs[objId],victim); + } + for (i=0;i<100;i++) + { + if (objs[i].handle!=-1) + { + printf("------ del objId=%d handle=%d ------\n",i,objs[i].handle); + c.del(objs[i].handle); + objs[i].handle=-1; +#ifdef CACHE_DEBUG + c.printLRU(); +#endif + } + } + c.printStats(); + return 0; +} +#endif diff --git a/src/objcache.h b/src/objcache.h new file mode 100644 index 0000000..3516534 --- /dev/null +++ b/src/objcache.h @@ -0,0 +1,113 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2006 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 OBJCACHE_H +#define OBJCACHE_H + +//#define CACHE_TEST +//#define CACHE_DEBUG +#define CACHE_STATS + +/** @brief Cache for objects. + * + * This cache is used to decide which objects should remain in + * memory. It uses a least recently used policy (LRU) to decide + * which object should make room for a new object when the cache + * is full. An object should be added using add(), and then use() + * should be called when the object is used. + */ +class ObjCache +{ + private: + struct CacheNode + { + CacheNode() : next(-1), prev(-1), obj(0) {} + int next; + int prev; + void *obj; + }; + struct HashNode + { + HashNode() : head(-1), nextHash(-1), index(-1), obj(0) {} + int head; + int nextHash; + int index; + void *obj; + }; + + public: + /*! Creates the cache. The number of elements in the cache is 2 to + * the power of \a logSize. + */ + ObjCache(unsigned int logSize); + + /*! Deletes the cache and free all internal data-structures used. */ + ~ObjCache(); + + /*! Adds \a obj to the cache. When victim is not null, this object is + * removed from the cache to make room for \a obj. + * Returns a handle to the object, which can be used by the use() + * function, each time the object is used. + */ + int add(void *obj,void **victim); + + /*! Indicates that this object is used. This will move the object + * to the front of the internal LRU list to make sure it is removed last. + * The parameter \a handle is returned when called add(). + */ + void use(int handle) + { + hits++; + if (handle==m_lastHandle) return; + m_lastHandle = handle; + moveToFront(handle); + } + + /*! Removes the item identified by \a handle from the cache. + * @see add() + */ + void del(int handle); + + /*! Debug function. Prints the LRU list */ + void printLRU(); + /*! Print miss/hits statistics */ + void printStats(); + + private: + void moveToFront(int index); + unsigned int hash(void *addr); + HashNode *hashFind(void *obj); + HashNode *hashInsert(void *obj); + void hashRemove(void *obj); + + CacheNode *m_cache; + HashNode *m_hash; + int m_head; + int m_tail; + int m_size; + int m_freeHashNodes; + int m_freeCacheNodes; + int m_lastHandle; + +#ifdef CACHE_STATS + static int misses; + static int hits; +#endif +}; + +#endif // OBJCACHE_H + diff --git a/src/outputgen.h b/src/outputgen.h index 81cda2d..dbe6807 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -299,8 +299,8 @@ class OutputGenerator : public BaseOutputDocInterface virtual void endIndexKey() = 0; virtual void startIndexValue(bool) = 0; virtual void endIndexValue(const char *,bool) = 0; - virtual void writeIndexItem(const char *ref,const char *file, - const char *text) = 0; + virtual void startIndexItem(const char *ref,const char *file) = 0; + virtual void endIndexItem(const char *ref,const char *file) = 0; virtual void startGroupHeader() = 0; virtual void endGroupHeader() = 0; virtual void startMemberSections() = 0; diff --git a/src/outputlist.h b/src/outputlist.h index 8c6def4..bdc0f01 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -115,8 +115,10 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::startItemList); } void endItemList() { forall(&OutputGenerator::endItemList); } - void writeIndexItem(const char *ref,const char *file,const char *text) - { forall(&OutputGenerator::writeIndexItem,ref,file,text); } + void startIndexItem(const char *ref,const char *file) + { forall(&OutputGenerator::startIndexItem,ref,file); } + void endIndexItem(const char *ref,const char *file) + { forall(&OutputGenerator::endIndexItem,ref,file); } void docify(const char *s) { forall(&OutputGenerator::docify,s); } void codify(const char *s) diff --git a/src/pagedef.cpp b/src/pagedef.cpp index a965946..7ed229f 100644 --- a/src/pagedef.cpp +++ b/src/pagedef.cpp @@ -29,7 +29,8 @@ void PageDef::findSectionsInDocumentation() GroupDef *PageDef::getGroupDef() const { - return partOfGroups() ? partOfGroups()->getFirst() : 0; + LockingPtr groups = partOfGroups(); + return groups!=0 ? groups->getFirst() : 0; } QCString PageDef::getOutputFileBase() const diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp index cf8be57..c1298d5 100644 --- a/src/perlmodgen.cpp +++ b/src/perlmodgen.cpp @@ -1440,16 +1440,16 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) md->memberType()!=MemberDef::Enumeration) m_output.addFieldQuotedString("type", md->typeString()); + LockingPtr al = md->argumentList(); if (isFunc) //function { - ArgumentList *al = md->argumentList(); - m_output.addFieldBoolean("const", al && al->constSpecifier) - .addFieldBoolean("volatile", al && al->volatileSpecifier); + m_output.addFieldBoolean("const", al!=0 && al->constSpecifier) + .addFieldBoolean("volatile", al!=0 && al->volatileSpecifier); m_output.openList("parameters"); - ArgumentList *declAl = md->declArgumentList(); - ArgumentList *defAl = md->argumentList(); - if (declAl && declAl->count()>0) + LockingPtr declAl = md->declArgumentList(); + LockingPtr defAl = md->argumentList(); + if (declAl!=0 && declAl->count()>0) { ArgumentListIterator declAli(*declAl); ArgumentListIterator defAli(*defAl); @@ -1487,7 +1487,7 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) md->argsString()!=0) // define { m_output.openList("parameters"); - ArgumentListIterator ali(*md->argumentList()); + ArgumentListIterator ali(*al); Argument *a; for (ali.toFirst();(a=ali.current());++ali) { @@ -1505,10 +1505,11 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) if (md->memberType()==MemberDef::Enumeration) // enum { - if (md->enumFieldList()) + LockingPtr enumFields = md->enumFieldList(); + if (enumFields!=0) { m_output.openList("values"); - MemberListIterator emli(*md->enumFieldList()); + MemberListIterator emli(*enumFields); MemberDef *emd; for (emli.toFirst();(emd=emli.current());++emli) { @@ -1534,8 +1535,8 @@ void PerlModGenerator::generatePerlModForMember(MemberDef *md,Definition *) .addFieldQuotedString("name", rmd->name()) .closeHash(); - MemberList *rbml = md->reimplementedBy(); - if (rbml) + LockingPtr rbml = md->reimplementedBy(); + if (rbml!=0) { MemberListIterator mli(*rbml); m_output.openList("reimplemented_by"); @@ -2014,21 +2015,21 @@ bool PerlModGenerator::generatePerlModOutput() m_output.add("$doxydocs=").openHash(); m_output.openList("classes"); - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) generatePerlModForClass(cd); m_output.closeList(); m_output.openList("namespaces"); - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) generatePerlModForNamespace(nd); m_output.closeList(); m_output.openList("files"); - FileNameListIterator fnli(Doxygen::inputNameList); + FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (;(fn=fnli.current());++fnli) { @@ -2040,7 +2041,7 @@ bool PerlModGenerator::generatePerlModOutput() m_output.closeList(); m_output.openList("groups"); - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (;(gd=gli.current());++gli) { diff --git a/src/pre.l b/src/pre.l index e5300bc..ba206ec 100644 --- a/src/pre.l +++ b/src/pre.l @@ -1048,13 +1048,13 @@ void addDefine() md->setFileDef(g_yyFileDef); md->setDefinition("#define "+g_defName); - MemberName *mn=Doxygen::functionNameSDict[g_defName]; + MemberName *mn=Doxygen::functionNameSDict->find(g_defName); if (mn==0) { mn = new MemberName(g_defName); //Doxygen::functionNameList.append(mn); //Doxygen::functionNameDict.insert(g_defName,mn); - Doxygen::functionNameSDict.append(g_defName,mn); + Doxygen::functionNameSDict->append(g_defName,mn); } mn->append(md); if (g_yyFileDef) g_yyFileDef->insertMember(md); diff --git a/src/pyscanner.l b/src/pyscanner.l index ea4776b..5f7abb0 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -88,7 +88,7 @@ static bool g_doubleQuote; static bool g_specialBlock; //static bool g_expectModuleDocs; static int g_stringContext; -static QCString * g_copyString; +static QGString * g_copyString; static int g_indent = 0; static int g_curIndent = 0; diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp index 3494dd8..0194de9 100644 --- a/src/rtfgen.cpp +++ b/src/rtfgen.cpp @@ -417,7 +417,7 @@ void RTFGenerator::startIndexSection(IndexSections is) case isModuleDocumentation: { //Module Documentation - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; bool found=FALSE; for (gli.toFirst();(gd=gli.current()) && !found;++gli) @@ -433,7 +433,7 @@ void RTFGenerator::startIndexSection(IndexSections is) case isDirDocumentation: { //Directory Documentation - SDict::Iterator dli(Doxygen::directories); + SDict::Iterator dli(*Doxygen::directories); DirDef *dd; bool found=FALSE; for (dli.toFirst();(dd=dli.current()) && !found;++dli) @@ -449,7 +449,7 @@ void RTFGenerator::startIndexSection(IndexSections is) case isNamespaceDocumentation: { // Namespace Documentation - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; bool found=FALSE; for (nli.toFirst();(nd=nli.current()) && !found;++nli) @@ -465,7 +465,7 @@ void RTFGenerator::startIndexSection(IndexSections is) case isClassDocumentation: { //Compound Documentation - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd=0; bool found=FALSE; for (cli.toFirst();(cd=cli.current()) && !found;++cli) @@ -482,7 +482,7 @@ void RTFGenerator::startIndexSection(IndexSections is) { //File Documentation bool isFirst=TRUE; - FileName *fn=Doxygen::inputNameList.first(); + FileName *fn=Doxygen::inputNameList->first(); while (fn) { FileDef *fd=fn->first(); @@ -499,7 +499,7 @@ void RTFGenerator::startIndexSection(IndexSections is) } fd=fn->next(); } - fn=Doxygen::inputNameList.next(); + fn=Doxygen::inputNameList->next(); } } break; @@ -647,7 +647,7 @@ void RTFGenerator::endIndexSection(IndexSections is) break; case isModuleDocumentation: { - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; t << "{\\tc \\v " << theTranslator->trModuleDocumentation() << "}"<< endl; for (gli.toFirst();(gd=gli.current());++gli) @@ -664,7 +664,7 @@ void RTFGenerator::endIndexSection(IndexSections is) break; case isDirDocumentation: { - SDict::Iterator dli(Doxygen::directories); + SDict::Iterator dli(*Doxygen::directories); DirDef *dd; t << "{\\tc \\v " << theTranslator->trDirDocumentation() << "}"<< endl; for (dli.toFirst();(dd=dli.current());++dli) @@ -681,7 +681,7 @@ void RTFGenerator::endIndexSection(IndexSections is) break; case isNamespaceDocumentation: { - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; bool found=FALSE; for (nli.toFirst();(nd=nli.current()) && !found;++nli) @@ -711,7 +711,7 @@ void RTFGenerator::endIndexSection(IndexSections is) break; case isClassDocumentation: { - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd=0; bool found=FALSE; @@ -743,7 +743,7 @@ void RTFGenerator::endIndexSection(IndexSections is) case isFileDocumentation: { bool isFirst=TRUE; - FileName *fn=Doxygen::inputNameList.first(); + FileName *fn=Doxygen::inputNameList->first(); t << "{\\tc \\v " << theTranslator->trFileDocumentation() << "}"<< endl; while (fn) @@ -772,7 +772,7 @@ void RTFGenerator::endIndexSection(IndexSections is) } fd=fn->next(); } - fn=Doxygen::inputNameList.next(); + fn=Doxygen::inputNameList->next(); } } break; @@ -935,12 +935,14 @@ void RTFGenerator::writeListItem() m_omitParagraph = TRUE; } -void RTFGenerator::writeIndexItem(const char *ref,const char *fn, - const char *name) +void RTFGenerator::startIndexItem(const char *,const char *) { - DBG_RTF(t << "{\\comment (writeIndexItem)}" << endl) - //t << rtf_LCList_DepthStyle() << endl; - docify(name); + DBG_RTF(t << "{\\comment (startIndexItem)}" << endl) +} + +void RTFGenerator::endIndexItem(const char *ref,const char *fn) +{ + DBG_RTF(t << "{\\comment (endIndexItem)}" << endl) if (!ref && fn) { t << "\\tab "; diff --git a/src/rtfgen.h b/src/rtfgen.h index 91ca8b6..b0edb10 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -72,12 +72,8 @@ class RTFGenerator : public OutputGenerator void endIndexValue(const char *,bool); void startItemList(); void endItemList(); - //void startEnumList(); - //void endEnumList(); - //void startAlphabeticalIndexList() {} - //void endAlphabeticalIndexList() {} - //void writeIndexHeading(const char *) {} - void writeIndexItem(const char *ref,const char *file,const char *name); + void startIndexItem(const char *ref,const char *file); + void endIndexItem(const char *ref,const char *file); void docify(const char *text); void codify(const char *text); void writeObjectLink(const char *ref,const char *file, @@ -88,7 +84,6 @@ class RTFGenerator : public OutputGenerator void endTextLink(); void startHtmlLink(const char *url); void endHtmlLink(); - //void writeMailLink(const char *url); void startTypewriter() { t << "{\\f2 "; } void endTypewriter() { t << "}"; } void startGroupHeader(); diff --git a/src/scanner.l b/src/scanner.l index a1b76e2..3e8da49 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -123,10 +123,15 @@ static QCString fullArgString; static ArgumentList *currentArgumentList; static char lastCopyArgChar; + +static QCString *pCopyQuotedString; static QCString *pCopyRoundString; static QCString *pCopyCurlyString; -static QCString *pCopyQuotedString; -static QCString *pSkipVerbString; + +static QGString *pCopyCurlyGString; +static QGString *pCopyRoundGString; +static QGString *pCopyQuotedGString; +static QGString *pSkipVerbString; static QStack autoGroupStack; static bool insideFormula; @@ -640,8 +645,12 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) %x NSAliasArg %x CopyString %x CopyPHPString +%x CopyGString +%x CopyPHPGString %x CopyRound %x CopyCurly +%x GCopyRound +%x GCopyCurly %x SkipUnionSwitch %x Specialization %x FuncPtrInit @@ -772,7 +781,8 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) lineCount() ; } -{B}*"signals"{BN}*":"{BN}* { current->mtype = mtype = Signal; +{B}*("signals"|"Q_SIGNALS"){BN}*":"{BN}* { current->mtype = mtype = Signal; + current->protection = protection = Public ; current->type.resize(0); current->name.resize(0); @@ -781,7 +791,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) lineCount() ; } -{B}*"public"{BN}*"slots"{BN}*":"{BN}* { +{B}*"public"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* { current->protection = protection = Public ; current->mtype = mtype = Slot; current->type.resize(0); @@ -791,7 +801,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) lineCount(); } -{B}*"protected"{BN}*"slots"{BN}*":"{BN}* { +{B}*"protected"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* { current->protection = protection = Protected ; current->mtype = mtype = Slot; current->type.resize(0); @@ -801,7 +811,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) lineCount(); } -{B}*"private"{BN}*"slots"{BN}*":"{BN}* { +{B}*"private"{BN}*("slots"|"Q_SLOTS"){BN}*":"{BN}* { current->protection = protection = Private ; current->mtype = mtype = Slot; current->type.resize(0); @@ -1886,17 +1896,17 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) /* Read initializer rules */ "(" { lastRoundContext=YY_START; - pCopyRoundString=¤t->initializer; + pCopyRoundGString=¤t->initializer; roundCount=0; current->initializer+=*yytext; - BEGIN(CopyRound); + BEGIN(GCopyRound); } "{" { lastCurlyContext=YY_START; - pCopyCurlyString=¤t->initializer; + pCopyCurlyGString=¤t->initializer; curlyCount=0; current->initializer+=*yytext; - BEGIN(CopyCurly); + BEGIN(GCopyCurly); } [;,] { //printf(">> initializer `%s' <<\n",current->initializer.data()); @@ -1924,8 +1934,8 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) { lastStringContext=YY_START; current->initializer+=*yytext; - pCopyQuotedString=¤t->initializer; - BEGIN(CopyString); + pCopyQuotedGString=¤t->initializer; + BEGIN(CopyGString); } } "->" { @@ -1949,9 +1959,9 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) if (insidePHP) { current->initializer+=yytext; - pCopyQuotedString = ¤t->initializer; + pCopyQuotedGString = ¤t->initializer; lastStringContext=YY_START; - BEGIN(CopyPHPString); + BEGIN(CopyPHPGString); } else { @@ -2037,6 +2047,29 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) *pCopyQuotedString+=*yytext; } + /* generic quoted growable string copy rules */ +\\. { + *pCopyQuotedGString+=yytext; + } +\" { + *pCopyQuotedGString+=*yytext; + BEGIN( lastStringContext ); + } +\' { + *pCopyQuotedGString+=*yytext; + BEGIN( lastStringContext ); + } +"/*"|"*/"|"//" { + *pCopyQuotedGString+=yytext; + } +\n { + *pCopyQuotedGString+=*yytext; + yyLineNr++; + } +. { + *pCopyQuotedGString+=*yytext; + } + /* generic round bracket list copy rules */ \" { *pCopyRoundString+=*yytext; @@ -2087,6 +2120,56 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) *pCopyRoundString+=*yytext; } + /* generic round bracket list copy rules for growable strings */ +\" { + *pCopyRoundGString+=*yytext; + pCopyQuotedGString=pCopyRoundGString; + lastStringContext=YY_START; + BEGIN(CopyGString); + } +"(" { + *pCopyRoundGString+=*yytext; + roundCount++; + } +")" { + *pCopyRoundGString+=*yytext; + if (--roundCount<0) + BEGIN(lastRoundContext); + } +\n { + yyLineNr++; + *pCopyRoundGString+=*yytext; + } +\' { + if (insidePHP) + { + current->initializer+=yytext; + pCopyQuotedGString = pCopyRoundGString; + lastStringContext=YY_START; + BEGIN(CopyPHPGString); + } + else + { + *pCopyRoundGString+=yytext; + } + } +{CHARLIT} { + if (insidePHP) + { + REJECT; + } + else + { + *pCopyRoundGString+=yytext; + } + } +[^"'()\n]+ { + *pCopyRoundGString+=yytext; + } +. { + *pCopyRoundGString+=*yytext; + } + /* generic curly bracket list copy rules */ \" { *pCopyCurlyString+=*yytext; @@ -2132,6 +2215,56 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) . { *pCopyCurlyString+=*yytext; } + + /* generic curly bracket list copy rules for growable strings */ +\" { + *pCopyCurlyGString+=*yytext; + pCopyQuotedGString=pCopyCurlyGString; + lastStringContext=YY_START; + BEGIN(CopyGString); + } +\' { + *pCopyCurlyGString+=*yytext; + if (insidePHP) + { + pCopyQuotedGString=pCopyCurlyGString; + lastStringContext=YY_START; + BEGIN(CopyPHPGString); + } + } +"{" { + *pCopyCurlyGString+=*yytext; + curlyCount++; + } +"}" { + *pCopyCurlyGString+=*yytext; + if (--curlyCount<0) + BEGIN(lastCurlyContext); + } +{CHARLIT} { if (insidePHP) + { + REJECT; + } + else + { + *pCopyCurlyGString+=yytext; + } + } +[^"'{}\/\n]+ { + *pCopyCurlyGString+=yytext; + } +"/" { *pCopyCurlyGString+=yytext; } +\n { + yyLineNr++; + *pCopyCurlyGString+=*yytext; + } +. { + *pCopyCurlyGString+=*yytext; + } + + /* ---------------------- */ + + ":" { if (current->type.isEmpty()) // anonymous padding field, e.g. "int :7;" { @@ -2377,9 +2510,9 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) BEGIN( SkipVerbString ); } \" { current->program += yytext ; - pCopyQuotedString = ¤t->program; + pCopyQuotedGString = ¤t->program; lastStringContext=YY_START; - BEGIN( CopyString ); + BEGIN( CopyGString ); } "/*"{B}* { current->program += yytext ; lastContext = YY_START ; @@ -2398,9 +2531,9 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) else { // begin of single quoted string current->program += yytext; - pCopyQuotedString = ¤t->program; + pCopyQuotedGString = ¤t->program; lastStringContext=YY_START; - BEGIN(CopyPHPString); + BEGIN(CopyPHPGString); } } {CHARLIT} { @@ -4213,6 +4346,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) } else { + mtype = Method; unput(';'); BEGIN(FindMembers); } diff --git a/src/sortdict.h b/src/sortdict.h index e54da38..07c450a 100644 --- a/src/sortdict.h +++ b/src/sortdict.h @@ -319,6 +319,75 @@ class SDict QListIterator *m_li; }; + class IteratorDict; // first forward declare + friend class IteratorDict; // then make it a friend + /*! Simple iterator for SDict. It iterates in over the dictionary elements + * in an unsorted way, but does provide information about the element's key. + */ + class IteratorDict + { + public: + /*! Create an iterator given the dictionary. */ + IteratorDict(const SDict &dict) + { + m_di = new QDictIterator(*dict.m_dict); + } + + /*! Destroys the dictionary */ + virtual ~IteratorDict() + { + delete m_di; + } + + /*! Set the iterator to the first element in the list. + * \return The first compound, or zero if the list was empty. + */ + T *toFirst() const + { + return m_di->toFirst(); + } + + /*! Set the iterator to the last element in the list. + * \return The first compound, or zero if the list was empty. + */ + T *toLast() const + { + return m_di->toLast(); + } + + /*! Returns the current compound */ + T *current() const + { + return m_di->current(); + } + + /*! Returns the current key */ + QCString currentKey() const + { + return m_di->currentKey(); + } + + /*! Moves the iterator to the next element. + * \return the new "current" element, or zero if the iterator was + * already pointing at the last element. + */ + T *operator++() + { + return m_di->operator++(); + } + + /*! Moves the iterator to the previous element. + * \return the new "current" element, or zero if the iterator was + * already pointing at the first element. + */ + T *operator--() + { + return m_di->operator--(); + } + + private: + QDictIterator *m_di; + }; }; /*! internal wrapper class that redirects compareItems() to the diff --git a/src/store.cpp b/src/store.cpp new file mode 100644 index 0000000..f1f24cd --- /dev/null +++ b/src/store.cpp @@ -0,0 +1,392 @@ +#include "store.h" + + +#include +#include +#include +#include +#include + +#define BLOCK_SIZE 512 // should be >8 and a multiple of 8 +#define BLOCK_POINTER_SIZE sizeof(off_t) + + +#define ASSERTS_ENABLED + +#ifdef ASSERTS_ENABLED +#define STORE_ASSERT(x) assert(x) +#else +#define STORE_ASSERT(x) +#endif + +#ifdef _WIN32 // TODO: add 64bit support using _fseeki64 and _ftelli64 (studio 2003+ req) +#define fseeko fseek +#define ftello ftell +#endif + + +//------------------------------------------------------------------------------------ + +Store::Store() +{ + m_file = 0; + m_front = 0; + m_head = 0; + m_state = Init; + m_reads = 0; + m_writes = 0; +} + +Store::~Store() +{ + if (m_file) fclose(m_file); + + // clean up free list + while (m_head) + { + Node *node = m_head; + m_head = node->next; + delete node; + } +} + +int Store::open(const char *name) +{ + int i; + STORE_ASSERT(m_state==Init); + if (m_file) return 0; // already open + m_file = fopen(name,"w+b"); + if (m_file==0) return -1; + + // first block serves as header, so offset=0 can be used as the end of the list. + for (i=0;ipos; + // point head to next free item + m_head = node->next; + delete node; + // move to start of the block + if (fseeko(m_file,pos,SEEK_SET)==-1) + { + fprintf(stderr,"Store::alloc: Error seeking to position %d: %s\n", + (int)pos,strerror(errno)); + exit(1); + } + STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 ); + } + //printf("%x: Store::alloc\n",(int)pos); + return pos; +} + +int Store::write(const char *buf,uint size) +{ + STORE_ASSERT(m_state==Writing); + //printf("%x: Store::write\n",(int)ftello(m_file)); + do + { + off_t curPos = ftello(m_file); + int bytesInBlock = BLOCK_SIZE - BLOCK_POINTER_SIZE - (curPos & (BLOCK_SIZE-1)); + int bytesLeft = bytesInBlock<(int)size ? (int)size-bytesInBlock : 0; + int numBytes = size - bytesLeft; + STORE_ASSERT(bytesInBlock>=0); + STORE_ASSERT(numBytes<=(int)(BLOCK_SIZE-BLOCK_POINTER_SIZE)); + if (numBytes>0) + { + if ((int)fwrite(buf,1,numBytes,m_file)!=numBytes) + { + fprintf(stderr,"Error writing: %s\n",strerror(errno)); + exit(1); + } + m_writes++; + } + if (bytesLeft>0) // still more bytes to write + { + STORE_ASSERT(((ftello(m_file)+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0); + // allocate new block + if (m_head==0) // no free blocks to reuse + { + //printf("%x: Store::write: new: pos=%x\n",(int)m_front,(int)ftello(m_file)); + // write pointer to next block + if (fwrite(&m_front,BLOCK_POINTER_SIZE,1,m_file)!=1) + { + fprintf(stderr,"Error writing to store: %s\n",strerror(errno)); + exit(1); + } + STORE_ASSERT(ftello(m_file)==(curPos&~(BLOCK_SIZE-1))+BLOCK_SIZE); + + // move to next block + if (fseeko(m_file,0,SEEK_END)==-1) // go to end of the file + { + fprintf(stderr,"Store::alloc: Error seeking to end of file: %s\n",strerror(errno)); + exit(1); + } + STORE_ASSERT(ftello(m_file)==m_front); + // move front to the next of the block + m_front+=BLOCK_SIZE; + } + else // reuse block from the free list + { + // write pointer to next block + if (fwrite(&m_head->pos,BLOCK_POINTER_SIZE,1,m_file)!=1) + { + fprintf(stderr,"Error writing to store: %s\n",strerror(errno)); + exit(1); + } + Node *node = m_head; + off_t pos = node->pos; + // point head to next free item + m_head = node->next; + delete node; + // move to start of the block + if (fseeko(m_file,pos,SEEK_SET)==-1) + { + fprintf(stderr,"Store::write: Error seeking to position %d: %s\n", + (int)pos,strerror(errno)); + exit(1); + } + //printf("%x: Store::write: reuse\n",(int)pos); + } + } + size-=numBytes; + buf+=numBytes; + } + while (size>0); + return size; +} + +void Store::end() +{ + STORE_ASSERT(m_state==Writing); + off_t curPos = ftello(m_file); + int bytesInBlock = BLOCK_SIZE - (curPos & (BLOCK_SIZE-1)); + //printf("%x: Store::end erasing %x bytes\n",(int)curPos&~(BLOCK_SIZE-1),bytesInBlock); + //printf("end: bytesInBlock=%x\n",bytesInBlock); + // zero out rest of the block + int i; + for (i=0;i0 && (pos & (BLOCK_SIZE-1))==0); + // goto end of the block + off_t cur = pos, next; + while (1) + { + // add new node to the free list + Node *node = new Node; + node->next = m_head; + node->pos = cur; + + m_head = node; + // goto the end of cur block + if (fseeko(m_file,cur+BLOCK_SIZE-BLOCK_POINTER_SIZE,SEEK_SET)==-1) + { + fprintf(stderr,"Store::release: Error seeking to position %d: %s\n", + (int)(cur+BLOCK_SIZE-BLOCK_POINTER_SIZE),strerror(errno)); + exit(1); + } + // read pointer to next block + if (fread(&next,BLOCK_POINTER_SIZE,1,m_file)!=1) + { + fprintf(stderr,"Store::release: Error reading from store: %s\n",strerror(errno)); + exit(1); + } + if (next==0) break; // found end of list -> cur is last element + STORE_ASSERT((next & (BLOCK_SIZE-1))==0); + cur = next; + //printf("%x: Store::release\n",(int)cur); + } +} + +void Store::seek(off_t pos) +{ + STORE_ASSERT(m_state==Reading); + //printf("%x: Store::seek\n",(int)pos); + if (fseeko(m_file,pos,SEEK_SET)==-1) + { + fprintf(stderr,"Store::seek: Error seeking to position %d: %s\n", + (int)pos,strerror(errno)); + exit(1); + } + STORE_ASSERT((pos&(BLOCK_SIZE-1))==0); +} + +int Store::read(char *buf,uint size) +{ + STORE_ASSERT(m_state==Reading); + //printf("%x: Store::read total=%d\n",(int)ftello(m_file),size); + do + { + off_t curPos = ftello(m_file); + int bytesInBlock = BLOCK_SIZE - BLOCK_POINTER_SIZE - (curPos & (BLOCK_SIZE-1)); + int bytesLeft = bytesInBlock<(int)size ? (int)size-bytesInBlock : 0; + int numBytes = size - bytesLeft; + //printf(" Store::read: pos=%x num=%d left=%d\n",(int)curPos,numBytes,bytesLeft); + + if (numBytes>0) + { + //printf("%x: Store::read: %d out of %d bytes\n",(int)ftello(m_file),numBytes,size); + if ((int)fread(buf,1,numBytes,m_file)!=numBytes) + { + fprintf(stderr,"Error reading from store: %s\n",strerror(errno)); + exit(1); + } + m_reads++; + } + if (bytesLeft>0) + { + off_t newPos; + // read offset of the next block + STORE_ASSERT(((ftello(m_file)+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0); + if (fread((char *)&newPos,BLOCK_POINTER_SIZE,1,m_file)!=1) + { + fprintf(stderr,"Error reading from store: %s\n",strerror(errno)); + exit(1); + } + //printf("%x: Store::read: continue in next block, %d bytes to go\n",(int)newPos,bytesLeft); + //printf(" Store::read: next block=%x\n",(int)newPos); + STORE_ASSERT(newPos!=0); + STORE_ASSERT((newPos&(BLOCK_SIZE-1))==0); + curPos = newPos; + // move to next block + if (fseeko(m_file,curPos,SEEK_SET)==-1) + { + fprintf(stderr,"Store::read: Error seeking to position %d: %s\n", + (int)curPos,strerror(errno)); + exit(1); + } + } + + size-=numBytes; + buf+=numBytes; + } + while (size>0); + return size; +} + +void Store::printFreeList() +{ + printf("FreeList: "); + off_t pos = m_head->pos; + while (pos) + { + printf("%x ",(int)pos); + m_head = m_head->next; + } + printf("\n"); +} + +void Store::printStats() +{ + printf("ObjStore: block size %d bytes, total size %ld blocks, wrote %d blocks, read %d blocks\n", + BLOCK_SIZE,(long)(m_front/BLOCK_SIZE),m_reads,m_writes); +} + +#ifdef STORE_TEST + +int main() +{ + printf("sizeof(off_t)=%d\n",(int)sizeof(off_t)); + Store s; + if (s.open("test.db")==0) + { + const char *str1 = "This is a test message... "; + const char *str2 = "Another message. "; + + int i,j; + for (j=0;j<5;j++) + { + char buf[100]; + + off_t handle = s.alloc(); + for (i=0;i<1000000000;i++) + { + s.write(str1,strlen(str1)+1); + } + s.end(); + off_t handle2 = s.alloc(); + for (i=0;i<10;i++) + { + s.write(str2,strlen(str2)+1); + } + s.end(); + + s.seek(handle); + for (i=0;i<3;i++) + { + s.read(buf,strlen(str1)+1); + printf("i=%d Read: %s\n",i,buf); + } + + s.release(handle); + + s.seek(handle2); + for (i=0;i<3;i++) + { + s.read(buf,strlen(str2)+1); + printf("i=%d Read: %s\n",i,buf); + } + + s.release(handle2); + } + + s.close(); + } + else + { + printf("Open failed! %s\n",strerror(errno)); + } +} + +#endif + diff --git a/src/store.h b/src/store.h new file mode 100644 index 0000000..3fc3ac0 --- /dev/null +++ b/src/store.h @@ -0,0 +1,117 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2006 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 STORE_H +#define STORE_H + +#include +#include +#include + +/*! @brief Abstract interface for file based memory storage operations */ +class StorageIntf +{ + public: + /*! Required by gcc */ + virtual ~StorageIntf() {} + /*! Read \a size bytes from the store into \a buf. */ + virtual int read(char *buf,uint size) = 0; + /*! Write \a size bytes from \a buf into the store. */ + virtual int write(const char *buf,uint size) = 0; +}; + +/*! @brief The Store is a file based memory manager. + * + * You can open the store using open(). Then obtain a handle via alloc() + * followed by a sequence of write() commands to store information, + * and finalize it using end(). + * + * Later on you locate the information + * with seek() using the handle obtained with alloc(), and then use a + * sequence of read() calls to read the information back. + * + * If no longer needed the storage space can be freed using release(). + * + * The store will dynamically grow the file on disk if needed. + */ +class Store : public StorageIntf +{ + public: + /*! Creates a store. */ + Store(); + + /*! Releases the store object. Will close the underlying file if opened. */ + ~Store(); + + /*! Opens the file underlying the store using \a name as the file name. + * Returns 0 upon success, or -1 otherwise. + */ + int open(const char *name); + + /*! Allocates a handle to write to and read from. */ + off_t alloc(); + + /*! Writes \a size bytes in array \a buf to the store. + * First alloc() has to be called. + * \note The information can only be read after end() has been called. + */ + int write(const char *buf,uint size); + + /*! Ends the sequence of writes. + * \note After this call, first alloc() has to be called + * before new writes can be done. + */ + void end(); + + /*! Releases the memory corresponding to the handle returned with alloc() */ + void release(off_t handle); + + /*! Closes the store */ + void close(); + + /*! Goes to the start of information corresponding to handle \a pos */ + void seek(off_t handle); + + /*! Reads \a size bytes from the store into the array pointed to be \a buf. + * \note Before reading seek() has to be called to set the right start of the store. + */ + int read(char *buf,uint size); + + void printStats(); + + private: + enum State + { + Init, + Reading, + Writing + }; + struct Node + { + off_t pos; + struct Node *next; + }; + void printFreeList(); + FILE *m_file; + off_t m_front; + Node *m_head; + State m_state; + int m_reads; + int m_writes; +}; + +#endif diff --git a/src/tagreader.cpp b/src/tagreader.cpp index 253d7d5..a8a74bb 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -1247,7 +1247,7 @@ void TagFileParser::buildLists(Entry *root) { mn = new FileName(fullName,tfi->name); mn->append(fd); - Doxygen::inputNameList.inSort(mn); + Doxygen::inputNameList->inSort(mn); Doxygen::inputNameDict->insert(tfi->name,mn); } buildMemberList(fe,tfi->members); diff --git a/src/translator_dk.h b/src/translator_dk.h index 1d498e5..98fdea1 100644 --- a/src/translator_dk.h +++ b/src/translator_dk.h @@ -23,6 +23,7 @@ * First version (not complete) for Doxygen 1.2.7 * Extended and revised for Doxygen 1.3 * Extended and revised for Doxygen 1.3.4 + * Extended and revised for Doxygen 1.3.8 */ /* Translator's notes: @@ -34,25 +35,30 @@ '..?' angiver ord, der endnu ikke er fundet en oversættelse til '(do.)' angiver ord, der med vilje ikke er oversat, idet jeg selv overvejende bruger det engelske udtryk - '(-> _) angiver ord, der er fundet en oversættelse til, men som jeg - vægrer mig ved at oversætte. + '(-> _)' angiver ord, der er fundet en oversættelse til, men som jeg + vægrer mig ved at oversætte. + 'KLID:_' angiver ord, hvor jeg med overlæg har rettet mig efter + KLID.dk's oversættelsesguide (enig eller ej). ) bug -> 'kendt fejl' class -> klasse compound -> 'sammensat type' constructor -> konstruktør ? destructor -> destruktør ? + directory -> KLID:katalog (kunne også være 'bibliotek','mappe','folder') event -> begivenhed ? - exception (-> undtagelse ?) + exception (-> undtagelse ?) friend ..? - interface -> grænseflade ? + interface -> grænseflade ? member -> medlem (TODO) namespace -> (do.) + overloaded -> KLID:overdefineret private -> privat property -> egenskab? protected -> beskyttet ?? public -> offentlig - slot ..? + reference(vb) -> "indeholde referencer til" (?) + slot ..? source code -> kildekode struct -> datastruktur template (-> skabelon ?) @@ -62,6 +68,7 @@ Specielle forbindelser: 'Inheritance diagram' -> Stamtræ (selvom Nedarvningsdiagram også gik an) + ----- @@ -258,7 +265,7 @@ class TranslatorDanish : public TranslatorAdapter_1_3_9 /*! This is an introduction to the class hierarchy. */ virtual QCString trClassHierarchyDescription() { return "Denne nedarvningsliste er sorteret næsten - " - "men ikke helt - alfabetisk:"; + "men ikke nødvendigvis helt - alfabetisk:"; } /*! This is an introduction to the list with all files. */ @@ -323,7 +330,7 @@ class TranslatorDanish : public TranslatorAdapter_1_3_9 } else { result+="fil-medlemmer"; } - result+=" med links til "; + result+=", med links til "; if (extractAll) result+="de filer, de tilhører:"; else @@ -871,7 +878,7 @@ class TranslatorDanish : public TranslatorAdapter_1_3_9 /*! this text is put before an include dependency graph */ virtual QCString trInclDepGraph(const char *fName) { - return (QCString)"Include-afhængighedsgraf for "+fName+":"; + return (QCString)"Inklusions-afhængighedsgraf for "+fName+":"; } /*! header that is put before the list of constructor/destructors. */ virtual QCString trConstructorDocumentation() @@ -1297,7 +1304,7 @@ class TranslatorDanish : public TranslatorAdapter_1_3_9 */ virtual QCString trReferences() { - return "Referencer"; + return "Indeholder referencer til"; } ////////////////////////////////////////////////////////////////////////// @@ -1458,6 +1465,85 @@ class TranslatorDanish : public TranslatorAdapter_1_3_9 } +////////////////////////////////////////////////////////////////////////// +// new since 1.3.9 +////////////////////////////////////////////////////////////////////////// + + /*! This is used as the name of the chapter containing the directory + * hierarchy. + */ + virtual QCString trDirIndex() + { return "Katalogstruktur"; } + + /*! This is used as the name of the chapter containing the documentation + * of the directories. + */ + virtual QCString trDirDocumentation() + { return "Katalog-dokumentation"; } + + /*! This is used as the title of the directory index and also in the + * Quick links of an HTML page, to link to the directory hierarchy. + */ + virtual QCString trDirectories() + { return "Kataloger"; } + + /*! This returns a sentences that introduces the directory hierarchy. + * and the fact that it is sorted alphabetically per level + */ + virtual QCString trDirDescription() + { return "Denne katalogstruktur er sorteret næsten - " + "men ikke nødvendigvis helt - alfabetisk:"; + } + + /*! This returns the title of a directory page. The name of the + * directory is passed via \a dirName. + */ + virtual QCString trDirReference(const char *dirName) + { QCString result="Indhold af kataloget "; result+=dirName; return result;} + + /*! This returns the word directory with or without starting capital + * (\a first_capital) and in sigular or plural form (\a singular). + */ + virtual QCString trDir(bool first_capital, bool singular) + { + return createNoun(first_capital, singular, "katalog", "er"); + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.4.1 +////////////////////////////////////////////////////////////////////////// + + /*! This text is added to the documentation when the \\overload command + * is used for a overloaded function. + */ + virtual QCString trOverloadText() + { + return "Dette er en overdefineret medlemsfunktion, " + "defineret af bekvemmelighedshensyn. " + "Den adskiller sig kun fra den ovenstående funktion i, " + "hvilke argumenter den tager."; + } + +////////////////////////////////////////////////////////////////////////// +// new since 1.4.6 +////////////////////////////////////////////////////////////////////////// + + /*! This is used to introduce a caller (or called-by) graph */ + virtual QCString trCallerGraph() + { + return "Her er kalder-grafen for denne funktion:"; + } + + /*! This is used in the documentation of a file/namespace before the list + * of documentation blocks for enumeration values + */ + /* + virtual QCString trEnumerationValueDocumentation() + { return "Enumerator-dokumentation"; } //TODO? +*/ + + + /*---------- For internal use: ----------------------------------------*/ protected: /*! For easy flexible-noun implementation. diff --git a/src/util.cpp b/src/util.cpp index 8db8b80..c9993a1 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -217,9 +217,9 @@ int iSystem(const char *command,const char *args,bool commandHasConsole) } else { - // gswin32 is a GUI api which will pop up a window and run - // asynchronously. To prevent both, we use ShellExecuteEx and - // WaitForSingleObject (thanks to Robert Golias for the code) + // gswin32 is a GUI api which will pop up a window and run + // asynchronously. To prevent both, we use ShellExecuteEx and + // WaitForSingleObject (thanks to Robert Golias for the code) SHELLEXECUTEINFO sInfo = { sizeof(SHELLEXECUTEINFO), /* structure size */ @@ -335,7 +335,7 @@ QCString stripAnonymousNamespaceScope(const QCString &s) while ((i=getScopeFragment(s,p,&l))!=-1) { //printf("Scope fragment %s\n",s.mid(i,l).data()); - if (Doxygen::namespaceSDict[s.left(i+l)]!=0) + if (Doxygen::namespaceSDict->find(s.left(i+l))!=0) { if (s.at(i)!='@') { @@ -501,11 +501,11 @@ QCString resolveTypeDef(Definition *context,const QCString &qualifiedName, MemberNameSDict *mnd=0; if (resScope->definitionType()==Definition::TypeClass) { - mnd=&Doxygen::memberNameSDict; + mnd=Doxygen::memberNameSDict; } else { - mnd=&Doxygen::functionNameSDict; + mnd=Doxygen::functionNameSDict; } MemberName *mn=mnd->find(resName); if (mn) @@ -558,7 +558,7 @@ QCString resolveTypeDef(Definition *context,const QCString &qualifiedName, ClassDef *getClass(const char *name) { if (name==0 || name[0]=='\0') return 0; - return Doxygen::classSDict.find(name); + return Doxygen::classSDict->find(name); } NamespaceDef *getResolvedNamespace(const char *name) @@ -578,11 +578,11 @@ NamespaceDef *getResolvedNamespace(const char *name) { warn_cont("Warning: possible recursive namespace alias detected for %s!\n",name); } - return Doxygen::namespaceSDict[subst->data()]; + return Doxygen::namespaceSDict->find(subst->data()); } else { - return Doxygen::namespaceSDict[name]; + return Doxygen::namespaceSDict->find(name); } } @@ -606,7 +606,7 @@ int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope,Definition * * Example: typedef int T; will return 0, since "int" is not a class. */ -static ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md, +ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md, MemberDef **pMemType,QCString *pTemplSpec) { //printf("newResolveTypedef(md=%p,cachedVal=%p)\n",md,md->getCachedTypedefVal()); @@ -668,7 +668,7 @@ static ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md, } else // Something like A::B => lookup A::B, spec= { - *pTemplSpec = type.mid(i); + if (pTemplSpec) *pTemplSpec = type.mid(i); } result = getResolvedClassRec(md->getOuterScope(),fileScope, stripTemplateSpecifiersFromScope(type.left(i),FALSE),0,0); @@ -700,7 +700,8 @@ static ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md, /*! Substitutes a simple unqualified \a name within \a scope. Returns the * value of the typedef or \a name if no typedef was found. */ -QCString substTypedef(Definition *scope,FileDef *fileScope,const QCString &name) +static QCString substTypedef(Definition *scope,FileDef *fileScope,const QCString &name, + MemberDef **pTypeDef=0) { QCString result=name; if (name.isEmpty()) return result; @@ -752,7 +753,12 @@ QCString substTypedef(Definition *scope,FileDef *fileScope,const QCString &name) } } } - if (bestMatch) result = bestMatch->typeString(); + if (bestMatch) + { + result = bestMatch->typeString(); + if (pTypeDef) *pTypeDef=bestMatch; + } + //printf("substTypedef(%s,%s)=%s\n",scope?scope->name().data():"", // name.data(),result.data()); return result; @@ -782,14 +788,24 @@ static Definition *endOfPathIsUsedClass(SDict *cl,const QCString &lo */ static Definition *followPath(Definition *start,FileDef *fileScope,const QCString &path) { - int is,ps=0; + int is,ps; int l; Definition *current=start; + ps=0; // for each part of the explicit scope while ((is=getScopeFragment(path,ps,&l))!=-1) { // try to resolve the part if it is a typedef - QCString qualScopePart = substTypedef(current,fileScope,path.mid(is,l)); + MemberDef *typeDef=0; + QCString qualScopePart = substTypedef(current,fileScope,path.mid(is,l),&typeDef); + if (typeDef) + { + ClassDef *type = newResolveTypedef(fileScope,typeDef); + if (type) + { + return type; + } + } Definition *next = current->findInnerCompound(qualScopePart); if (next==0) // failed to follow the path { @@ -1090,6 +1106,7 @@ int isAccessibleFromWithExpScope(Definition *scope,FileDef *fileScope, #endif } done: + //printf("> result=%d\n",result); visitedDict.remove(key); //Doxygen::lookupCache.insert(key,new int(result)); return result; @@ -1111,8 +1128,8 @@ void getResolvedSymbol(Definition *scope, QCString &bestTemplSpec ) { - //printf(" found type %x name=%s (%d/%d) d=%p\n", - // d->definitionType(),d->name().data(),count,dl->count(),d); + //printf(" found type %x name=%s d=%p\n", + // d->definitionType(),d->name().data(),d); // only look at classes and members if (d->definitionType()==Definition::TypeClass || @@ -1275,7 +1292,7 @@ ClassDef *getResolvedClassRec(Definition *scope, } DefinitionIntf *di = Doxygen::symbolMap->find(name); - //printf("Looking for symbol %s result=%p\n",name.data(),dl); + //printf("Looking for symbol %s result=%p\n",name.data(),di); if (di==0) { return 0; @@ -2083,12 +2100,11 @@ QCString yearToString() return result; } - //---------------------------------------------------------------------- // recursive function that returns the number of branches in the // inheritance tree that the base class `bcd' is below the class `cd' -int minClassDistance(ClassDef *cd,ClassDef *bcd,int level) +int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level) { if (bcd->categoryOf()) // use class that is being extended in case of // an Objective-C category @@ -3381,7 +3397,7 @@ bool getDefs(const QCString &scName,const QCString &memberName, //printf("mScope=`%s' mName=`%s'\n",mScope.data(),mName.data()); - MemberName *mn = Doxygen::memberNameSDict[mName]; + MemberName *mn = Doxygen::memberNameSDict->find(mName); //printf("mName=%s mn=%p\n",mName.data(),mn); if (!forceEmptyScope && mn && !(scopeName.isEmpty() && mScope.isEmpty())) { @@ -3420,8 +3436,9 @@ bool getDefs(const QCString &scName,const QCString &memberName, { //if (mmd->isLinkable()) //{ + LockingPtr mmdAl = mmd->argumentList(); bool match=args==0 || - matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),mmd->argumentList(), + matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),mmdAl.pointer(), fcd,fcd->getFileDef(),argList, checkCV ); @@ -3429,12 +3446,15 @@ bool getDefs(const QCString &scName,const QCString &memberName, if (match) { ClassDef *mcd=mmd->getClassDef(); - int m=minClassDistance(fcd,mcd); - if (misLinkable()) + if (mcd) { - mdist=m; - cd=mcd; - md=mmd; + int m=minClassDistance(fcd,mcd); + if (misLinkable()) + { + mdist=m; + cd=mcd; + md=mmd; + } } } //} @@ -3453,13 +3473,16 @@ bool getDefs(const QCString &scName,const QCString &memberName, //{ ClassDef *mcd=mmd->getClassDef(); //printf(" >Class %s found\n",mcd->name().data()); - int m=minClassDistance(fcd,mcd); - if (misLinkable()*/ ) + if (mcd) { - //printf("Class distance %d\n",m); - mdist=m; - cd=mcd; - md=mmd; + int m=minClassDistance(fcd,mcd); + if (misLinkable()*/ ) + { + //printf("Class distance %d\n",m); + mdist=m; + cd=mcd; + md=mmd; + } } //} } @@ -3514,7 +3537,8 @@ bool getDefs(const QCString &scName,const QCString &memberName, QCString className = mmd->getClassDef()->name(); - if (matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),mmd->argumentList(), + LockingPtr mmdAl = mmd->argumentList(); + if (matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),mmdAl.pointer(), Doxygen::globalScope,mmd->getFileDef(),argList, checkCV ) @@ -3540,7 +3564,7 @@ bool getDefs(const QCString &scName,const QCString &memberName, // maybe an namespace, file or group member ? //printf("Testing for global function scopeName=`%s' mScope=`%s' :: mName=`%s'\n", // scopeName.data(),mScope.data(),mName.data()); - if ((mn=Doxygen::functionNameSDict[mName])) // name is known + if ((mn=Doxygen::functionNameSDict->find(mName))) // name is known { //printf(" >function name found\n"); NamespaceDef *fnd=0; @@ -3558,7 +3582,7 @@ bool getDefs(const QCString &scName,const QCString &memberName, } //printf("Trying namespace %s\n",namespaceName.data()); if (!namespaceName.isEmpty() && - (fnd=Doxygen::namespaceSDict[namespaceName]) && + (fnd=Doxygen::namespaceSDict->find(namespaceName)) && fnd->isLinkable() ) { @@ -3577,9 +3601,10 @@ bool getDefs(const QCString &scName,const QCString &memberName, if (args && strcmp(args,"()")!=0) { argList=new ArgumentList; + LockingPtr mmdAl = mmd->argumentList(); stringToArgumentList(args,argList); match=matchArguments2( - mmd->getOuterScope(),mmd->getFileDef(),mmd->argumentList(), + mmd->getOuterScope(),mmd->getFileDef(),mmdAl.pointer(), fnd,mmd->getFileDef(),argList, checkCV); } @@ -3659,9 +3684,10 @@ bool getDefs(const QCString &scName,const QCString &memberName, if (args && !md->isDefine() && strcmp(args,"()")!=0) { argList=new ArgumentList; + LockingPtr mdAl = md->argumentList(); stringToArgumentList(args,argList); match=matchArguments2( - md->getOuterScope(),fd,md->argumentList(), + md->getOuterScope(),fd,mdAl.pointer(), Doxygen::globalScope,fd,argList, checkCV); delete argList; argList=0; @@ -3780,7 +3806,7 @@ bool getScopeDefs(const char *docScope,const char *scope, { return TRUE; // class link written => quit } - else if ((nd=Doxygen::namespaceSDict[fullName]) && nd->isLinkable()) + else if ((nd=Doxygen::namespaceSDict->find(fullName)) && nd->isLinkable()) { return TRUE; // namespace link written => quit } @@ -3915,7 +3941,7 @@ bool resolveRef(/* in */ const char *scName, // md->name().data(),md,md->anchor().data(),md->isLinkable(),(*resContext)->name().data()); return TRUE; } - else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupSDict[nameStr])) + else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupSDict->find(nameStr))) { // group link *resContext=gd; return TRUE; @@ -4068,7 +4094,7 @@ bool resolveLink(/* in */ const char *scName, *resContext=pd; return TRUE; } - else if ((gd=Doxygen::groupSDict[linkRef])) // link to a group + else if ((gd=Doxygen::groupSDict->find(linkRef))) // link to a group { *resContext=gd; return TRUE; @@ -4089,12 +4115,12 @@ bool resolveLink(/* in */ const char *scName, *resContext=cd; return TRUE; } - else if ((nd=Doxygen::namespaceSDict.find(linkRef))) + else if ((nd=Doxygen::namespaceSDict->find(linkRef))) { *resContext=nd; return TRUE; } - else if ((dir=Doxygen::directories.find(QFileInfo(linkRef).absFilePath()+"/")) + else if ((dir=Doxygen::directories->find(QFileInfo(linkRef).absFilePath()+"/")) && dir->isLinkable()) // TODO: make this location independent like filedefs { *resContext=dir; @@ -4782,8 +4808,8 @@ void addMembersToMemberGroup(MemberList *ml, { if (md->isEnumerate()) // insert enum value of this enum into groups { - QList *fmdl=md->enumFieldList(); - if (fmdl) + LockingPtr fmdl=md->enumFieldList(); + if (fmdl!=0) { MemberDef *fmd=fmdl->first(); while (fmd) @@ -5310,14 +5336,15 @@ void addRefItem(const QList *sli, void addGroupListToTitle(OutputList &ol,Definition *d) { - if (d->partOfGroups()) // write list of group to which this definition belongs + LockingPtr groups = d->partOfGroups(); + if (groups!=0) // write list of group to which this definition belongs { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); ol.lineBreak(); ol.startSmall(); ol.docify("["); - GroupListIterator gli(*d->partOfGroups()); + GroupListIterator gli(*groups); GroupDef *gd; bool first=TRUE; for (gli.toFirst();(gd=gli.current());++gli) diff --git a/src/util.h b/src/util.h index d0ee110..881ad78 100644 --- a/src/util.h +++ b/src/util.h @@ -220,7 +220,7 @@ void initClassHierarchy(ClassSDict *cl); bool hasVisibleRoot(BaseClassList *bcl); -int minClassDistance(ClassDef *cd,ClassDef *bcd,int level=0); +int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level=0); QCString convertNameToFile(const char *name,bool allowDots=FALSE); @@ -325,6 +325,8 @@ SrcLangExt getLanguageFromFileName(const QCString fileName); bool checkIfTypedef(Definition *scope,FileDef *fileScope,const char *n); +ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md, + MemberDef **pMemType=0,QCString *pTemplSpec=0); #endif diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index 2f751a9..3b416d0 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -456,9 +456,10 @@ static void writeTemplateArgumentList(ArgumentList *al, static void writeMemberTemplateLists(MemberDef *md,QTextStream &t) { - if (md->templateArguments()) // function template prefix + LockingPtr templMd = md->templateArguments(); + if (templMd!=0) // function template prefix { - writeTemplateArgumentList(md->templateArguments(),t,md->getClassDef(),md->getFileDef(),8); + writeTemplateArgumentList(templMd.pointer(),t,md->getClassDef(),md->getFileDef(),8); } } @@ -622,9 +623,9 @@ static void generateXMLForMember(MemberDef *md,QTextStream &ti,QTextStream &t,De if (isFunc) { - ArgumentList *al = md->argumentList(); + LockingPtr al = md->argumentList(); t << " const=\""; - if (al && al->constSpecifier) t << "yes"; else t << "no"; + if (al!=0 && al->constSpecifier) t << "yes"; else t << "no"; t << "\""; t << " explicit=\""; @@ -711,8 +712,8 @@ static void generateXMLForMember(MemberDef *md,QTextStream &ti,QTextStream &t,De << rmd->getOutputFileBase() << "_1" << rmd->anchor() << "\">" << convertToXML(rmd->name()) << "" << endl; } - MemberList *rbml = md->reimplementedBy(); - if (rbml) + LockingPtr rbml = md->reimplementedBy(); + if (rbml!=0) { MemberListIterator mli(*rbml); for (mli.toFirst();(rmd=mli.current());++mli) @@ -725,9 +726,9 @@ static void generateXMLForMember(MemberDef *md,QTextStream &ti,QTextStream &t,De if (isFunc) //function { - ArgumentList *declAl = md->declArgumentList(); - ArgumentList *defAl = md->argumentList(); - if (declAl && declAl->count()>0) + LockingPtr declAl = md->declArgumentList(); + LockingPtr defAl = md->argumentList(); + if (declAl!=0 && declAl->count()>0) { ArgumentListIterator declAli(*declAl); ArgumentListIterator defAli(*defAl); @@ -820,9 +821,10 @@ static void generateXMLForMember(MemberDef *md,QTextStream &ti,QTextStream &t,De if (md->memberType()==MemberDef::Enumeration) // enum { - if (md->enumFieldList()) + LockingPtr enumFields = md->enumFieldList(); + if (enumFields!=0) { - MemberListIterator emli(*md->enumFieldList()); + MemberListIterator emli(*enumFields); MemberDef *emd; for (emli.toFirst();(emd=emli.current());++emli) { @@ -887,18 +889,20 @@ static void generateXMLForMember(MemberDef *md,QTextStream &ti,QTextStream &t,De } //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers()); - if (md->getReferencesMembers()) + LockingPtr mdict = md->getReferencesMembers(); + if (mdict!=0) { - MemberSDict::Iterator mdi(*md->getReferencesMembers()); + MemberSDict::Iterator mdi(*mdict); MemberDef *rmd; for (mdi.toFirst();(rmd=mdi.current());++mdi) { writeMemberReference(t,def,rmd,"references"); } } - if (md->getReferencedByMembers()) + mdict = md->getReferencedByMembers(); + if (mdict!=0) { - MemberSDict::Iterator mdi(*md->getReferencedByMembers()); + MemberSDict::Iterator mdi(*mdict); MemberDef *rmd; for (mdi.toFirst();(rmd=mdi.current());++mdi) { @@ -1837,7 +1841,7 @@ void generateXML() t << "version=\"" << versionString << "\">" << endl; { - ClassSDict::Iterator cli(Doxygen::classSDict); + ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) { @@ -1854,14 +1858,14 @@ void generateXML() // generateXMLForClass(cd,t); // } //} - NamespaceSDict::Iterator nli(Doxygen::namespaceSDict); + NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { msg("Generating XML output for namespace %s\n",nd->name().data()); generateXMLForNamespace(nd,t); } - FileNameListIterator fnli(Doxygen::inputNameList); + FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (;(fn=fnli.current());++fnli) { @@ -1873,7 +1877,7 @@ void generateXML() generateXMLForFile(fd,t); } } - GroupSDict::Iterator gli(Doxygen::groupSDict); + GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (;(gd=gli.current());++gli) { @@ -1891,7 +1895,7 @@ void generateXML() } { DirDef *dir; - DirSDict::Iterator sdi(Doxygen::directories); + DirSDict::Iterator sdi(*Doxygen::directories); for (sdi.toFirst();(dir=sdi.current());++sdi) { msg("Generate XML output for dir %s\n",dir->name().data()); -- cgit v0.12