From bb783fb795f9c0d077fa201ed673be93825486ce Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Sun, 20 Sep 2020 15:28:23 +0200 Subject: Refactoring: replaced QCache by STL based LRU cache implementation. Also prepared some code for multi-threaded use, and Removed tabs and trailing spaces for code.l --- qtools/CMakeLists.txt | 1 - qtools/qcache.h | 105 -- qtools/qgcache.cpp | 878 ----------- qtools/qgcache.h | 130 -- src/cache.h | 162 ++ src/code.l | 4012 ++++++++++++++++++++++++------------------------- src/doxygen.cpp | 40 +- src/doxygen.h | 10 +- src/util.cpp | 82 +- 9 files changed, 2234 insertions(+), 3186 deletions(-) delete mode 100644 qtools/qcache.h delete mode 100644 qtools/qgcache.cpp delete mode 100644 qtools/qgcache.h create mode 100644 src/cache.h diff --git a/qtools/CMakeLists.txt b/qtools/CMakeLists.txt index a7082c7..0a77289 100644 --- a/qtools/CMakeLists.txt +++ b/qtools/CMakeLists.txt @@ -10,7 +10,6 @@ qdir.cpp qfile.cpp qfileinfo.cpp qgarray.cpp -qgcache.cpp qgdict.cpp qglist.cpp qglobal.cpp diff --git a/qtools/qcache.h b/qtools/qcache.h deleted file mode 100644 index 87f9866..0000000 --- a/qtools/qcache.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** -** Definition of QCache template class -** -** Created : 950209 -** -** 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. -** -**********************************************************************/ - -#ifndef QCACHE_H -#define QCACHE_H - -#ifndef QT_H -#include "qgcache.h" -#endif // QT_H - -template class Q_EXPORT QCache : public QGCache -{ -public: - QCache( const QCache &c ) : QGCache(c) {} - QCache( int maxCost=100, uint size=17, bool caseSensitive=TRUE ) - : QGCache( maxCost, size, AsciiKey, caseSensitive, TRUE ) {} - ~QCache() { clear(); } - QCache &operator=( const QCache &c ) - { return (QCache&)QGCache::operator=(c); } - int maxCost() const { return QGCache::maxCost(); } - int totalCost() const { return QGCache::totalCost(); } - void setMaxCost( int m ) { QGCache::setMaxCost(m); } - uint count() const { return QGCache::count(); } - uint size() const { return QGCache::size(); } - bool isEmpty() const { return QGCache::count() == 0; } - void clear() { QGCache::clear(); } - bool insert( const char *k, const type *d, int c=1, int p=0 ) - { return QGCache::insert_other(k,(Item)d,c,p);} - bool remove( const char *k ) - { return QGCache::remove_other(k); } - type *take( const char *k ) - { return (type *)QGCache::take_other(k); } - type *find( const char *k, bool ref=TRUE ) const - { return (type *)QGCache::find_other(k,ref);} - type *operator[]( const char *k ) const - { return (type *)QGCache::find_other(k);} - void statistics() const { QGCache::statistics(); } - int hits() const { return QGCache::hits(); } - int misses() const { return QGCache::misses(); } -private: - void deleteItem( Item d ) { if ( del_item ) delete (type *)d; } -}; - - - -template class Q_EXPORT QCacheIterator : public QGCacheIterator -{ -public: - QCacheIterator( const QCache &c ):QGCacheIterator((QGCache &)c) {} - QCacheIterator( const QCacheIterator &ci) - : QGCacheIterator( (QGCacheIterator &)ci ) {} - QCacheIterator &operator=(const QCacheIterator&ci) - { return ( QCacheIterator&)QGCacheIterator::operator=( ci ); } - uint count() const { return QGCacheIterator::count(); } - bool isEmpty() const { return QGCacheIterator::count() == 0; } - bool atFirst() const { return QGCacheIterator::atFirst(); } - bool atLast() const { return QGCacheIterator::atLast(); } - type *toFirst() { return (type *)QGCacheIterator::toFirst(); } - type *toLast() { return (type *)QGCacheIterator::toLast(); } - operator type *() const { return (type *)QGCacheIterator::get(); } - type *current() const { return (type *)QGCacheIterator::get(); } - const char *currentKey() const{ return QGCacheIterator::getKeyAscii(); } - type *operator()() { return (type *)QGCacheIterator::operator()();} - type *operator++() { return (type *)QGCacheIterator::operator++(); } - type *operator+=(uint j) { return (type *)QGCacheIterator::operator+=(j);} - type *operator--() { return (type *)QGCacheIterator::operator--(); } - type *operator-=(uint j) { return (type *)QGCacheIterator::operator-=(j);} -}; - - -#endif // QCACHE_H diff --git a/qtools/qgcache.cpp b/qtools/qgcache.cpp deleted file mode 100644 index 230823c..0000000 --- a/qtools/qgcache.cpp +++ /dev/null @@ -1,878 +0,0 @@ -/**************************************************************************** -** -** -** Implementation of QGCache and QGCacheIterator classes -** -** Created : 950208 -** -** 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 "qgcache.h" -#include "qinternallist.h" -#include "qdict.h" -#include "qstring.h" - - -// NOT REVISED -/*! - \class QGCache qgcache.h - - \brief The QGCache class is an internal class for implementing QCache template classes. - - QGCache is a strictly internal class that acts as a base class for the - \link collection.html collection classes\endlink QCache and QIntCache. -*/ - - -/***************************************************************************** - QGCacheItem class (internal cache item) - *****************************************************************************/ - -struct QCacheItem -{ - QCacheItem( void *k, QCollection::Item d, int c, short p ) - : priority(p), skipPriority(p), cost(c), key(k), data(d), node(0) {} - short priority; - short skipPriority; - int cost; - void *key; - QCollection::Item data; - QLNode *node; -}; - - -/***************************************************************************** - QCList class (internal list of cache items) - *****************************************************************************/ - -class QCList : private QInternalList -{ -friend class QGCacheIterator; -friend class QCListIt; -public: - QCList() {} - ~QCList(); - - void insert( QCacheItem * ); // insert according to priority - void insert( int, QCacheItem * ); - void take( QCacheItem * ); - void reference( QCacheItem * ); - - void setAutoDelete( bool del ) { QCollection::setAutoDelete(del); } - - bool removeFirst() { return QInternalList::removeFirst(); } - bool removeLast() { return QInternalList::removeLast(); } - - QCacheItem *first() { return QInternalList::first(); } - QCacheItem *last() { return QInternalList::last(); } - QCacheItem *prev() { return QInternalList::prev(); } - QCacheItem *next() { return QInternalList::next(); } - -#if defined(DEBUG) - int inserts; // variables for statistics - int insertCosts; - int insertMisses; - int finds; - int hits; - int hitCosts; - int dumps; - int dumpCosts; -#endif -}; - - -QCList::~QCList() -{ -#if defined(DEBUG) - ASSERT( count() == 0 ); -#endif -} - - -void QCList::insert( QCacheItem *ci ) -{ - QCacheItem *item = first(); - while( item && item->skipPriority > ci->priority ) { - item->skipPriority--; - item = next(); - } - if ( item ) - QInternalList::insert( at(), ci ); - else - append( ci ); -#if defined(DEBUG) - ASSERT( ci->node == 0 ); -#endif - ci->node = currentNode(); -} - -inline void QCList::insert( int i, QCacheItem *ci ) -{ - QInternalList::insert( i, ci ); -#if defined(DEBUG) - ASSERT( ci->node == 0 ); -#endif - ci->node = currentNode(); -} - - -void QCList::take( QCacheItem *ci ) -{ - if ( ci ) { -#if defined(DEBUG) - ASSERT( ci->node != 0 ); -#endif - takeNode( ci->node ); - ci->node = 0; - } -} - - -inline void QCList::reference( QCacheItem *ci ) -{ -#if defined(DEBUG) - ASSERT( ci != 0 && ci->node != 0 ); -#endif - ci->skipPriority = ci->priority; - relinkNode( ci->node ); // relink as first item -} - - -class QCListIt: public QInternalListIterator -{ -public: - QCListIt( const QCList *p ): QInternalListIterator( *p ) {} - QCListIt( const QCListIt *p ): QInternalListIterator( *p ) {} -}; - - -/***************************************************************************** - QCDict class (internal dictionary of cache items) - *****************************************************************************/ - -// -// Since we need to decide if the dictionary should use an int or const -// char * key (the "bool trivial" argument in the constructor below) -// we cannot use the macro/template dict, but inherit directly from QGDict. -// - -class QCDict : public QGDict -{ -public: - QCDict( uint size, uint kt, bool caseSensitive, bool copyKeys ) - : QGDict( size, (KeyType)kt, caseSensitive, copyKeys ) {} - - QCacheItem *find_string(const QCString &key) const - { return (QCacheItem*)((QCDict*)this)->look_string(key, 0, 0); } - QCacheItem *find_ascii(const char *key) const - { return (QCacheItem*)((QCDict*)this)->look_ascii(key, 0, 0); } - QCacheItem *find_int(long key) const - { return (QCacheItem*)((QCDict*)this)->look_int(key, 0, 0); } - - QCacheItem *take_string(const QCString &key) - { return (QCacheItem*)QGDict::take_string(key); } - QCacheItem *take_ascii(const char *key) - { return (QCacheItem*)QGDict::take_ascii(key); } - QCacheItem *take_int(long key) - { return (QCacheItem*)QGDict::take_int(key); } - - bool insert_string( const QCString &key, const QCacheItem *ci ) - { return QGDict::look_string(key,(Item)ci,1)!=0;} - bool insert_ascii( const char *key, const QCacheItem *ci ) - { return QGDict::look_ascii(key,(Item)ci,1)!=0;} - bool insert_int( long key, const QCacheItem *ci ) - { return QGDict::look_int(key,(Item)ci,1)!=0;} - - bool remove_string( QCacheItem *item ) - { return QGDict::remove_string(*((QCString*)(item->key)),item); } - bool remove_ascii( QCacheItem *item ) - { return QGDict::remove_ascii((const char *)item->key,item); } - bool remove_int( QCacheItem *item ) - { return QGDict::remove_int((intptr_t)item->key,item);} - - void statistics() { QGDict::statistics(); } -}; - - -/***************************************************************************** - QGDict member functions - *****************************************************************************/ - -/*! - \internal - Constructs a cache. -*/ - -QGCache::QGCache( int maxCost, uint size, KeyType kt, bool caseSensitive, - bool copyKeys ) -{ - keytype = kt; - lruList = new QCList; - CHECK_PTR( lruList ); - lruList->setAutoDelete( TRUE ); - copyk = ((keytype == AsciiKey) && copyKeys); - dict = new QCDict( size, kt, caseSensitive, FALSE ); - CHECK_PTR( dict ); - mCost = maxCost; - tCost = 0; -#if defined(DEBUG) - lruList->inserts = 0; - lruList->insertCosts = 0; - lruList->insertMisses = 0; - lruList->finds = 0; - lruList->hits = 0; - lruList->hitCosts = 0; - lruList->dumps = 0; - lruList->dumpCosts = 0; -#endif -} - -/*! - \internal - Cannot copy a cache. -*/ - -QGCache::QGCache( const QGCache & ) - : QCollection() -{ -#if defined(CHECK_NULL) - qFatal( "QGCache::QGCache(QGCache &): Cannot copy a cache" ); -#endif -} - -/*! - \internal - Removes all items from the cache and destroys it. -*/ - -QGCache::~QGCache() -{ - clear(); // delete everything first - delete dict; - delete lruList; -} - -/*! - \internal - Cannot assign a cache. -*/ - -QGCache &QGCache::operator=( const QGCache & ) -{ -#if defined(CHECK_NULL) - qFatal( "QGCache::operator=: Cannot copy a cache" ); -#endif - return *this; // satisfy the compiler -} - - -/*! - \fn uint QGCache::count() const - \internal - Returns the number of items in the cache. -*/ - -/*! - \fn uint QGCache::size() const - \internal - Returns the size of the hash array. -*/ - -/*! - \fn int QGCache::maxCost() const - \internal - Returns the maximum cache cost. -*/ - -/*! - \fn int QGCache::totalCost() const - \internal - Returns the total cache cost. -*/ - -/*! - \internal - Sets the maximum cache cost. -*/ - -void QGCache::setMaxCost( int maxCost ) -{ - if ( maxCost < tCost ) { - if ( !makeRoomFor(tCost - maxCost) ) // remove excess cost - return; - } - mCost = maxCost; -} - - -/*! - \internal - Inserts an item into the cache. - - \warning If this function returns FALSE, you must delete \a data - yourself. Additionally, be very careful about using \a data after - calling this function, as any other insertions into the cache, from - anywhere in the application, or within Qt itself, could cause the - data to be discarded from the cache, and the pointer to become - invalid. -*/ - -bool QGCache::insert_string( const QCString &key, QCollection::Item data, - int cost, int priority) -{ - if ( tCost + cost > mCost ) { - if ( !makeRoomFor(tCost + cost - mCost, priority) ) { -#if defined(DEBUG) - lruList->insertMisses++; -#endif - return FALSE; - } - } -#if defined(DEBUG) - ASSERT( keytype == StringKey ); - lruList->inserts++; - lruList->insertCosts += cost; -#endif - if ( priority < -32768 ) - priority = -32768; - else if ( priority > 32767 ) - priority = 32677; - QCacheItem *ci = new QCacheItem( new QCString(key), newItem(data), - cost, (short)priority ); - CHECK_PTR( ci ); - lruList->insert( 0, ci ); - dict->insert_string( key, ci ); - tCost += cost; - return TRUE; -} - - -/*! \internal */ - -bool QGCache::insert_other( const char *key, QCollection::Item data, - int cost, int priority) -{ - if ( tCost + cost > mCost ) { - if ( !makeRoomFor(tCost + cost - mCost, priority) ) { -#if defined(DEBUG) - lruList->insertMisses++; -#endif - return FALSE; - } - } -#if defined(DEBUG) - ASSERT( keytype != StringKey ); - lruList->inserts++; - lruList->insertCosts += cost; -#endif - if ( keytype == AsciiKey && copyk ) - key = qstrdup( key ); - if ( priority < -32768 ) - priority = -32768; - else if ( priority > 32767 ) - priority = 32677; - QCacheItem *ci = new QCacheItem( (void*)key, newItem(data), cost, - (short)priority ); - CHECK_PTR( ci ); - lruList->insert( 0, ci ); - if ( keytype == AsciiKey ) - dict->insert_ascii( key, ci ); - else - dict->insert_int( (intptr_t)key, ci ); - tCost += cost; - return TRUE; -} - - -/*! - \internal - Removes an item from the cache. -*/ - -bool QGCache::remove_string( const QCString &key ) -{ - Item d = take_string( key ); - if ( d ) - deleteItem( d ); - return d != 0; -} - - -/*! \internal */ - -bool QGCache::remove_other( const char *key ) -{ - Item d = take_other( key ); - if ( d ) - deleteItem( d ); - return d != 0; -} - - -/*! - \internal - Takes an item out of the cache (no delete). -*/ - -QCollection::Item QGCache::take_string( const QCString &key ) -{ - QCacheItem *ci = dict->take_string( key ); // take from dict - Item d; - if ( ci ) { - d = ci->data; - tCost -= ci->cost; - lruList->take( ci ); // take from list - delete (QCString*)ci->key; - delete ci; - } else { - d = 0; - } - return d; -} - -/*! - \internal - Takes an item out of the cache (no delete). -*/ - -QCollection::Item QGCache::take_other( const char *key ) -{ - QCacheItem *ci; - if ( keytype == AsciiKey ) - ci = dict->take_ascii( key ); - else - ci = dict->take_int( (intptr_t)key ); - Item d; - if ( ci ) { - d = ci->data; - tCost -= ci->cost; - lruList->take( ci ); // take from list - if ( copyk ) - delete [] (char *)ci->key; - delete ci; - } else { - d = 0; - } - return d; -} - - -/*! - \internal - Clears the cache. -*/ - -void QGCache::clear() -{ - QCacheItem *ci; - while ( (ci = lruList->first()) ) { - switch ( keytype ) { - case StringKey: - dict->remove_string( ci ); - delete (QCString*)ci->key; - break; - case AsciiKey: - dict->remove_ascii( ci ); - if ( copyk ) - delete [] (char*)ci->key; - break; - case IntKey: - dict->remove_int( ci ); - break; - case PtrKey: // unused - break; - } - deleteItem( ci->data ); // delete data - lruList->removeFirst(); // remove from list - } - tCost = 0; -} - - -/*! - \internal - Finds an item in the cache. -*/ - -QCollection::Item QGCache::find_string( const QCString &key, bool ref ) const -{ - QCacheItem *ci = dict->find_string( key ); -#if defined(DEBUG) - lruList->finds++; -#endif - if ( ci ) { -#if defined(DEBUG) - lruList->hits++; - lruList->hitCosts += ci->cost; -#endif - if ( ref ) - lruList->reference( ci ); - return ci->data; - } - return 0; -} - - -/*! - \internal - Finds an item in the cache. -*/ - -QCollection::Item QGCache::find_other( const char *key, bool ref ) const -{ - QCacheItem *ci = keytype == AsciiKey ? dict->find_ascii(key) - : dict->find_int((intptr_t)key); -#if defined(DEBUG) - lruList->finds++; -#endif - if ( ci ) { -#if defined(DEBUG) - lruList->hits++; - lruList->hitCosts += ci->cost; -#endif - if ( ref ) - lruList->reference( ci ); - return ci->data; - } - return 0; -} - - -/*! - \internal - Allocates cache space for one or more items. -*/ - -bool QGCache::makeRoomFor( int cost, int priority ) -{ - if ( cost > mCost ) // cannot make room for more - return FALSE; // than maximum cost - if ( priority == -1 ) - priority = 32767; - QCacheItem *ci = lruList->last(); - int cntCost = 0; - int dumps = 0; // number of items to dump - while ( cntCost < cost && ci && ci->skipPriority <= priority ) { - cntCost += ci->cost; - ci = lruList->prev(); - dumps++; - } - if ( cntCost < cost ) // can enough cost be dumped? - return FALSE; // no -#if defined(DEBUG) - ASSERT( dumps > 0 ); -#endif - while ( dumps-- ) { - ci = lruList->last(); -#if defined(DEBUG) - lruList->dumps++; - lruList->dumpCosts += ci->cost; -#endif - switch ( keytype ) { - case StringKey: - dict->remove_string( ci ); - delete (QCString*)ci->key; - break; - case AsciiKey: - dict->remove_ascii( ci ); - if ( copyk ) - delete [] (char *)ci->key; - break; - case IntKey: - dict->remove_int( ci ); - break; - case PtrKey: // unused - break; - } - deleteItem( ci->data ); // delete data - lruList->removeLast(); // remove from list - } - tCost -= cntCost; - return TRUE; -} - - -/*! - \internal - Outputs debug statistics. -*/ - -void QGCache::statistics() const -{ -#if defined(DEBUG) - QCString line; - line.fill( '*', 80 ); - qDebug( "%s",line.data() ); - qDebug( "CACHE STATISTICS:" ); - qDebug( "cache contains %d item%s, with a total cost of %d", - count(), count() != 1 ? "s" : "", tCost ); - qDebug( "maximum cost is %d, cache is %d%% full.", - mCost, (200*tCost + mCost) / (mCost*2) ); - qDebug( "find() has been called %d time%s", - lruList->finds, lruList->finds != 1 ? "s" : "" ); - qDebug( "%d of these were hits, items found had a total cost of %d.", - lruList->hits,lruList->hitCosts ); - qDebug( "%d item%s %s been inserted with a total cost of %d.", - lruList->inserts,lruList->inserts != 1 ? "s" : "", - lruList->inserts != 1 ? "have" : "has", lruList->insertCosts ); - qDebug( "%d item%s %s too large or had too low priority to be inserted.", - lruList->insertMisses, lruList->insertMisses != 1 ? "s" : "", - lruList->insertMisses != 1 ? "were" : "was" ); - qDebug( "%d item%s %s been thrown away with a total cost of %d.", - lruList->dumps, lruList->dumps != 1 ? "s" : "", - lruList->dumps != 1 ? "have" : "has", lruList->dumpCosts ); - qDebug( "Statistics from internal dictionary class:" ); - dict->statistics(); - qDebug( "%s",line.data() ); -#endif -} - -int QGCache::hits() const -{ - return lruList->hits; -} - -int QGCache::misses() const -{ - return lruList->finds - lruList->hits; -} - - -/***************************************************************************** - QGCacheIterator member functions - *****************************************************************************/ - -/*! - \class QGCacheIterator qgcache.h - - \brief An internal class for implementing QCacheIterator and QIntCacheIterator. - - QGCacheIterator is a strictly internal class that does the heavy work for - QCacheIterator and QIntCacheIterator. -*/ - -/*! - \internal - Constructs an iterator that operates on the cache \e c. -*/ - -QGCacheIterator::QGCacheIterator( const QGCache &c ) -{ - it = new QCListIt( c.lruList ); -#if defined(DEBUG) - ASSERT( it != 0 ); -#endif -} - -/*! - \internal - Constructs an iterator that operates on the same cache as \e ci. -*/ - -QGCacheIterator::QGCacheIterator( const QGCacheIterator &ci ) -{ - it = new QCListIt( ci.it ); -#if defined(DEBUG) - ASSERT( it != 0 ); -#endif -} - -/*! - \internal - Destroys the iterator. -*/ - -QGCacheIterator::~QGCacheIterator() -{ - delete it; -} - -/*! - \internal - Assigns the iterator \e ci to this cache iterator. -*/ - -QGCacheIterator &QGCacheIterator::operator=( const QGCacheIterator &ci ) -{ - *it = *ci.it; - return *this; -} - -/*! - \internal - Returns the number of items in the cache. -*/ - -uint QGCacheIterator::count() const -{ - return it->count(); -} - -/*! - \internal - Returns TRUE if the iterator points to the first item. -*/ - -bool QGCacheIterator::atFirst() const -{ - return it->atFirst(); -} - -/*! - \internal - Returns TRUE if the iterator points to the last item. -*/ - -bool QGCacheIterator::atLast() const -{ - return it->atLast(); -} - -/*! - \internal - Sets the list iterator to point to the first item in the cache. -*/ - -QCollection::Item QGCacheIterator::toFirst() -{ - QCacheItem *item = it->toFirst(); - return item ? item->data : 0; -} - -/*! - \internal - Sets the list iterator to point to the last item in the cache. -*/ - -QCollection::Item QGCacheIterator::toLast() -{ - QCacheItem *item = it->toLast(); - return item ? item->data : 0; -} - -/*! - \internal - Returns the current item. -*/ - -QCollection::Item QGCacheIterator::get() const -{ - QCacheItem *item = it->current(); - return item ? item->data : 0; -} - -/*! - \internal - Returns the key of the current item. -*/ - -QCString QGCacheIterator::getKeyString() const -{ - QCacheItem *item = it->current(); - return item ? *((QCString*)item->key) : QCString(); -} - -/*! - \internal - Returns the key of the current item, as a \0-terminated C string. -*/ - -const char *QGCacheIterator::getKeyAscii() const -{ - QCacheItem *item = it->current(); - return item ? (const char *)item->key : 0; -} - -/*! - \internal - Returns the key of the current item, as a long. -*/ - -intptr_t QGCacheIterator::getKeyInt() const -{ - QCacheItem *item = it->current(); - return item ? (intptr_t)item->key : 0; -} - -/*! - \internal - Moves to the next item (postfix). -*/ - -QCollection::Item QGCacheIterator::operator()() -{ - QCacheItem *item = it->operator()(); - return item ? item->data : 0; -} - -/*! - \internal - Moves to the next item (prefix). -*/ - -QCollection::Item QGCacheIterator::operator++() -{ - QCacheItem *item = it->operator++(); - return item ? item->data : 0; -} - -/*! - \internal - Moves \e jumps positions forward. -*/ - -QCollection::Item QGCacheIterator::operator+=( uint jump ) -{ - QCacheItem *item = it->operator+=(jump); - return item ? item->data : 0; -} - -/*! - \internal - Moves to the previous item (prefix). -*/ - -QCollection::Item QGCacheIterator::operator--() -{ - QCacheItem *item = it->operator--(); - return item ? item->data : 0; -} - -/*! - \internal - Moves \e jumps positions backward. -*/ - -QCollection::Item QGCacheIterator::operator-=( uint jump ) -{ - QCacheItem *item = it->operator-=(jump); - return item ? item->data : 0; -} diff --git a/qtools/qgcache.h b/qtools/qgcache.h deleted file mode 100644 index 5d8a243..0000000 --- a/qtools/qgcache.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** -** Definition of QGCache and QGCacheIterator classes -** -** Created : 950208 -** -** 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. -** -**********************************************************************/ - -#ifndef QGCACHE_H -#define QGCACHE_H - -#ifndef QT_H -#include "qcollection.h" -#include "qglist.h" -#include "qgdict.h" -#endif // QT_H - - -class QCList; // internal classes -class QCListIt; -class QCDict; - - -class Q_EXPORT QGCache : public QCollection // generic LRU cache -{ -friend class QGCacheIterator; -protected: - enum KeyType { StringKey, AsciiKey, IntKey, PtrKey }; - // identical to QGDict's, but PtrKey is not used at the moment - - QGCache( int maxCost, uint size, KeyType kt, bool caseSensitive, - bool copyKeys ); - QGCache( const QGCache & ); // not allowed, calls fatal() - ~QGCache(); - QGCache &operator=( const QGCache & ); // not allowed, calls fatal() - - uint count() const { return ((QGDict*)dict)->count(); } - uint size() const { return ((QGDict*)dict)->size(); } - int maxCost() const { return mCost; } - int totalCost() const { return tCost; } - void setMaxCost( int maxCost ); - void clear(); - - bool insert_string( const QCString &key, QCollection::Item, - int cost, int priority ); - bool insert_other( const char *key, QCollection::Item, - int cost, int priority ); - bool remove_string( const QCString &key ); - bool remove_other( const char *key ); - QCollection::Item take_string( const QCString &key ); - QCollection::Item take_other( const char *key ); - - QCollection::Item find_string( const QCString &key, bool ref=TRUE ) const; - QCollection::Item find_other( const char *key, bool ref=TRUE ) const; - - void statistics() const; - int hits() const; - int misses() const; - -private: - bool makeRoomFor( int cost, int priority = -1 ); - KeyType keytype; - QCList *lruList; - QCDict *dict; - int mCost; - int tCost; - bool copyk; -}; - - -class Q_EXPORT QGCacheIterator // generic cache iterator -{ -protected: - QGCacheIterator( const QGCache & ); - QGCacheIterator( const QGCacheIterator & ); - ~QGCacheIterator(); - QGCacheIterator &operator=( const QGCacheIterator & ); - - uint count() const; - bool atFirst() const; - bool atLast() const; - QCollection::Item toFirst(); - QCollection::Item toLast(); - - QCollection::Item get() const; - QCString getKeyString() const; - const char *getKeyAscii() const; - intptr_t getKeyInt() const; - - QCollection::Item operator()(); - QCollection::Item operator++(); - QCollection::Item operator+=( uint ); - QCollection::Item operator--(); - QCollection::Item operator-=( uint ); - -protected: - QCListIt *it; // iterator on cache list -}; - - -#endif // QGCACHE_H diff --git a/src/cache.h b/src/cache.h new file mode 100644 index 0000000..5f7c834 --- /dev/null +++ b/src/cache.h @@ -0,0 +1,162 @@ +/***************************************************************************** + * + * Copyright (C) 1997-2020 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 CACHE_H +#define CACHE_H + +#include +#include +#include +#include + +/*! Fixed size cache for value type V using keys of type K. + * + * When the maximum capacity has reached, the least recently used value is removed from the cache + * (LRU strategy). + */ +template +class Cache +{ + public: + using kv_pair = std::pair; + using iterator = typename std::list::iterator; + using const_iterator = typename std::list::const_iterator; + + //! creates a cache that can hold \a capacity elements + Cache(size_t capacity) : m_capacity(capacity) + { + } + + //! Inserts \a value under \a key in the cache + V *insert(const K &key,V &&value) + { + // remove item if it already exists + remove(key); + // store new item + m_cacheItemList.push_front(kv_pair(key,std::move(value))); + V *result = &m_cacheItemList.front().second; + m_cacheItemMap[key] = m_cacheItemList.begin(); + // remove least recently used item if cache is full + resize(); + return result; + } + + //! Inserts \a value under \a key in the cache + V *insert(const K &key,const V &value) + { + // remove item if it already exists + remove(key); + // store new item + m_cacheItemList.push_front(kv_pair(key,value)); + V *result = &m_cacheItemList.front().second; + m_cacheItemMap[key] = m_cacheItemList.begin(); + // remove least recently used item if cache is full + resize(); + return result; + } + + //! Removes entry \a key from the cache. + //! \note this invalidates any iterators + void remove(const K &key) + { + // remove item if it already exists + auto it = m_cacheItemMap.find(key); + if (it != m_cacheItemMap.end()) + { + m_cacheItemList.erase(it->second); + m_cacheItemMap.erase(it); + } + } + + //! Finds a value in the cache given the corresponding \a key. + //! @returns a pointer to the value or nullptr if the key is not found in the cache + //! @note The hit and miss counters are updated, see hits() and misses(). + V *find(const K &key) + { + auto it = m_cacheItemMap.find(key); + if (it != m_cacheItemMap.end()) + { + // move the item to the front of the list + m_cacheItemList.splice(m_cacheItemList.begin(), + m_cacheItemList, + it->second); + m_hits++; + // return the value + return &it->second->second; + } + else + { + m_misses++; + } + return nullptr; + } + + //! Returns the number of values stored in the cache. + size_t size() const + { + return m_cacheItemMap.size(); + } + + //! Returns the maximum number of values that can be stored in the cache. + size_t capacity() const + { + return m_capacity; + } + + //! Returns how many of the find() calls did find a value in the cache. + uint64_t hits() const + { + return m_hits; + } + + //! Returns how many of the find() calls did not found a value in the cache. + uint64_t misses() const + { + return m_misses; + } + + //! Clears all values in the cache. + void clear() + { + m_cacheItemMap.clear(); + m_cacheItemList.clear(); + } + + iterator begin() { return m_cacheItemList.begin(); } + iterator end() { return m_cacheItemList.end(); } + const_iterator begin() const { return m_cacheItemList.cbegin(); } + const_iterator end() const { return m_cacheItemList.cend(); } + + private: + void resize() + { + if (m_cacheItemMap.size() > m_capacity) + { + auto last_it = m_cacheItemList.end(); + --last_it; + m_cacheItemMap.erase(last_it->first); + m_cacheItemList.pop_back(); + } + } + size_t m_capacity; + // list of items in the cache, sorted by most to least recently used. + std::list m_cacheItemList; + // mapping for each key to a place in the list where item is found + std::unordered_map m_cacheItemMap; + uint64_t m_hits=0; + uint64_t m_misses=0; +}; + +#endif diff --git a/src/code.l b/src/code.l index 43011f0..9374b40 100644 --- a/src/code.l +++ b/src/code.l @@ -3,8 +3,8 @@ * Copyright (C) 1997-2020 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 + * 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. * @@ -23,7 +23,7 @@ %{ /* - * includes + * includes */ #include @@ -69,9 +69,9 @@ #define USE_STATE2STRING 0 /* ----------------------------------------------------------------- - * statics + * statics */ - + // context for an Objective-C method call struct ObjCCallCtx { @@ -102,15 +102,15 @@ class VariableContext void pushScope() { m_scopes.push_back(Scope()); - DBG_CTX((stderr,"** Push var context %d\n",m_scopes.count())); + DBG_CTX((stderr,"** Push var context %zu\n",m_scopes.size())); } void popScope() { if (!m_scopes.empty()) { - DBG_CTX((stderr,"** Pop var context %d\n",m_scopes.count())); - m_scopes.pop_back(); + DBG_CTX((stderr,"** Pop var context %zu\n",m_scopes.size())); + m_scopes.pop_back(); } else { @@ -166,10 +166,10 @@ class CallContext if (m_defList.size()>1) { DBG_CTX((stderr,"** Pop call context %zu\n",m_defList.size())); - const Ctx &ctx = m_defList.back(); - name_ = ctx.name; - type_ = ctx.type; - m_defList.pop_back(); + const Ctx &ctx = m_defList.back(); + name_ = ctx.name; + type_ = ctx.type; + m_defList.pop_back(); } else { @@ -204,10 +204,10 @@ struct codeYY_state QCString parmName; const char * inputString = 0; //!< the code fragment as text - yy_size_t inputPosition = 0; //!< read offset during parsing + yy_size_t inputPosition = 0; //!< read offset during parsing int inputLines = 0; //!< number of line in the code fragment - int yyLineNr = 0; //!< current line number - int yyColNr = 0; //!< current column number + int yyLineNr = 0; //!< current line number + int yyColNr = 0; //!< current column number bool needsTermination = FALSE; bool exampleBlock = FALSE; @@ -220,12 +220,12 @@ struct codeYY_state QCString args; QCString classScope; QCString realScope; - std::stack scopeStack; //!< 1 if bracket starts a scope, - // 2 for internal blocks + std::stack scopeStack; //!< 1 if bracket starts a scope, + // 2 for internal blocks int anchorCount = 0; FileDef * sourceFileDef = 0; bool lineNumbers = FALSE; - Definition * currentDefinition = 0; + const Definition * currentDefinition = 0; MemberDef * currentMemberDef = 0; bool includeCodeFragment = FALSE; const char * currentFontClass = 0; @@ -236,20 +236,20 @@ struct codeYY_state QCString saveType; QCString delimiter; - int bracketCount = 0; - int curlyCount = 0; - int sharpCount = 0; + int bracketCount = 0; + int curlyCount = 0; + int sharpCount = 0; bool inFunctionTryBlock = FALSE; bool inForEachExpression = FALSE; int lastTemplCastContext = 0; - int lastSpecialCContext = 0; + int lastSpecialCContext = 0; int lastStringContext = 0; int lastSkipCppContext = 0; int lastVerbStringContext = 0; int lastObjCCallContext = 0; int memCallContext = 0; - int lastCContext = 0; + int lastCContext = 0; int skipInlineInitContext = 0; SrcLangExt lang = SrcLangExt_Unknown; @@ -311,21 +311,21 @@ static void addType(yyscan_t yyscanner); static void addParmType(yyscan_t yyscanner); static void addUsingDirective(yyscan_t yyscanner,const char *name); static void setParameterList(yyscan_t yyscanner,const MemberDef *md); -static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,Definition *d); +static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,const Definition *d); static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name); static void updateCallContextForSmartPointer(yyscan_t yyscanner); static bool getLinkInScope(yyscan_t yyscanner,const QCString &c, // scope const QCString &m, // member - const char *memberText, // exact text - CodeOutputInterface &ol, - const char *text, - bool varOnly=FALSE - ); + const char *memberText, // exact text + CodeOutputInterface &ol, + const char *text, + bool varOnly=FALSE + ); static bool getLink(yyscan_t yyscanner,const char *className, const char *memberName, - CodeOutputInterface &ol, - const char *text=0, - bool varOnly=FALSE); + CodeOutputInterface &ol, + const char *text=0, + bool varOnly=FALSE); static void generateClassOrGlobalLink(yyscan_t yyscanner,CodeOutputInterface &ol,const char *clName, bool typeOnly=FALSE,bool varOnly=FALSE); static bool generateClassMemberLink(yyscan_t yyscanner,CodeOutputInterface &ol,MemberDef *xmd,const char *memName); @@ -346,15 +346,15 @@ static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size); /* ----------------------------------------------------------------- */ -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size); +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size); %} B [ \t] BN [ \t\n\r] -ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* +ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* SEP ("::"|"\\") SCOPENAME ({SEP}{BN}*)?({ID}{BN}*{SEP}{BN}*)*("~"{BN}*)?{ID} TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">" @@ -409,12 +409,12 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} %x SkipString %x SkipStringS %x SkipVerbString -%x SkipCPP -%x SkipComment -%x SkipCxxComment -%x RemoveSpecialCComment -%x StripSpecialCComment -%x Body +%x SkipCPP +%x SkipComment +%x SkipCxxComment +%x RemoveSpecialCComment +%x StripSpecialCComment +%x Body %x FuncCall %x MemberCall %x MemberCall2 @@ -424,22 +424,22 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} %x AlignAsEnd %x PackageName %x ClassVar -%x CppCliTypeModifierFollowup +%x CppCliTypeModifierFollowup %x Bases %x SkipSharp %x ReadInclude %x TemplDecl %x TemplCast -%x CallEnd +%x CallEnd %x ObjCMethod -%x ObjCParams -%x ObjCParamType +%x ObjCParams +%x ObjCParamType %x ObjCCall %x ObjCMName %x ObjCSkipStr %x ObjCCallComment %x OldStyleArgs -%x UsingName +%x UsingName %x RawString %x InlineInit @@ -447,258 +447,258 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} <*>\x0d ^([ \t]*"#"[ \t]*("include"|"import")[ \t]*)("<"|"\"") { - startFontClass(yyscanner,"preprocessor"); - yyextra->code->codify(yytext); - BEGIN( ReadInclude ); - } -("@interface"|"@implementation"|"@protocol")[ \t\n]+ { + startFontClass(yyscanner,"preprocessor"); + yyextra->code->codify(yytext); + BEGIN( ReadInclude ); + } +("@interface"|"@implementation"|"@protocol")[ \t\n]+ { yyextra->insideObjC=TRUE; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - if (!yyextra->insideTemplate) - BEGIN( ClassName ); - } + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + if (!yyextra->insideTemplate) + BEGIN( ClassName ); + } (("public"|"private"){B}+)?("ref"|"value"|"interface"|"enum"){B}+("class"|"struct") { - if (yyextra->insideTemplate) REJECT; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - BEGIN( ClassName ); - } -"property"|"event"/{BN}* { - if (yyextra->insideTemplate) REJECT; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } -(KEYWORD_CPPCLI_DATATYPE|("partial"{B}+)?"class"|"struct"|"union"|"namespace"|"interface"){B}+ { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - if (!yyextra->insideTemplate) - BEGIN( ClassName ); - } -("package")[ \t\n]+ { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - BEGIN( PackageName ); - } -\n { - if (!yyextra->insideObjC) REJECT; - codifyLines(yyscanner,yytext); - BEGIN(Body); - } -"-"|"+" { - if (!yyextra->insideObjC || yyextra->insideBody) - { - yyextra->code->codify(yytext); - } - else // Start of Objective-C method - { - //printf("Method!\n"); - yyextra->code->codify(yytext); - BEGIN(ObjCMethod); - } - } -":" { - yyextra->code->codify(yytext); - BEGIN(ObjCParams); - } -"(" { - yyextra->code->codify(yytext); - BEGIN(ObjCParamType); - } -";"|"{" { - yyextra->code->codify(yytext); - if (*yytext=='{') - { - if (yyextra->searchingForBody) - { - yyextra->searchingForBody=FALSE; - yyextra->insideBody=TRUE; - } - if (yyextra->insideBody) yyextra->bodyCurlyCount++; - if (!yyextra->curClassName.isEmpty()) // valid class name - { - pushScope(yyscanner,yyextra->curClassName); + if (yyextra->insideTemplate) REJECT; + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + BEGIN( ClassName ); + } +"property"|"event"/{BN}* { + if (yyextra->insideTemplate) REJECT; + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } +(KEYWORD_CPPCLI_DATATYPE|("partial"{B}+)?"class"|"struct"|"union"|"namespace"|"interface"){B}+ { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + if (!yyextra->insideTemplate) + BEGIN( ClassName ); + } +("package")[ \t\n]+ { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + BEGIN( PackageName ); + } +\n { + if (!yyextra->insideObjC) REJECT; + codifyLines(yyscanner,yytext); + BEGIN(Body); + } +"-"|"+" { + if (!yyextra->insideObjC || yyextra->insideBody) + { + yyextra->code->codify(yytext); + } + else // Start of Objective-C method + { + //printf("Method!\n"); + yyextra->code->codify(yytext); + BEGIN(ObjCMethod); + } + } +":" { + yyextra->code->codify(yytext); + BEGIN(ObjCParams); + } +"(" { + yyextra->code->codify(yytext); + BEGIN(ObjCParamType); + } +";"|"{" { + yyextra->code->codify(yytext); + if (*yytext=='{') + { + if (yyextra->searchingForBody) + { + yyextra->searchingForBody=FALSE; + yyextra->insideBody=TRUE; + } + if (yyextra->insideBody) yyextra->bodyCurlyCount++; + if (!yyextra->curClassName.isEmpty()) // valid class name + { + pushScope(yyscanner,yyextra->curClassName); DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); - yyextra->scopeStack.push(SCOPEBLOCK); - } - } + yyextra->scopeStack.push(SCOPEBLOCK); + } + } yyextra->type.resize(0); yyextra->name.resize(0); - BEGIN(Body); - } -{ID}{B}*":" { - yyextra->code->codify(yytext); - } -{TYPEKW} { - startFontClass(yyscanner,"keywordtype"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - yyextra->parmType=yytext; - } -{ID} { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - yyextra->parmType=yytext; - } -")" { - yyextra->code->codify(yytext); - BEGIN(ObjCParams); - } -{ID} { - yyextra->code->codify(yytext); - yyextra->parmName=yytext; - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - } + BEGIN(Body); + } +{ID}{B}*":" { + yyextra->code->codify(yytext); + } +{TYPEKW} { + startFontClass(yyscanner,"keywordtype"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + yyextra->parmType=yytext; + } +{ID} { + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + yyextra->parmType=yytext; + } +")" { + yyextra->code->codify(yytext); + BEGIN(ObjCParams); + } +{ID} { + yyextra->code->codify(yytext); + yyextra->parmName=yytext; + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + } {ID} { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } -. { - yyextra->code->codify(yytext); - } -\n { - codifyLines(yyscanner,yytext); - } -[^\n\"\>]+/(">"|"\"") { - //FileInfo *f; - bool ambig; - bool found=FALSE; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } +. { + yyextra->code->codify(yytext); + } +\n { + codifyLines(yyscanner,yytext); + } +[^\n\"\>]+/(">"|"\"") { + //FileInfo *f; + bool ambig; + bool found=FALSE; const FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,yytext,ambig); - //printf("looking for include %s -> %s fd=%p\n",yytext,absPath.data(),fd); - if (fd && fd->isLinkable()) - { - if (ambig) // multiple input files match the name - { - //printf("===== yes %s is ambiguous\n",yytext); - QCString name = QDir::cleanDirPath(yytext).utf8(); - if (!name.isEmpty() && yyextra->sourceFileDef) - { - FileName *fn = Doxygen::inputNameLinkedMap->find(name); - if (fn) - { - // see if this source file actually includes the file + //printf("looking for include %s -> %s fd=%p\n",yytext,absPath.data(),fd); + if (fd && fd->isLinkable()) + { + if (ambig) // multiple input files match the name + { + //printf("===== yes %s is ambiguous\n",yytext); + QCString name = QDir::cleanDirPath(yytext).utf8(); + if (!name.isEmpty() && yyextra->sourceFileDef) + { + const FileName *fn = Doxygen::inputNameLinkedMap->find(name); + if (fn) + { + // see if this source file actually includes the file auto it = std::find_if(fn->begin(), fn->end(), [&sfd=yyextra->sourceFileDef] (const auto &lfd) { return sfd->isIncluded(lfd->absFilePath()); }); found = it!=fn->end(); - } - } - } - else // not ambiguous - { - found = TRUE; - } - } - //printf(" include file %s found=%d\n",fd ? fd->absFilePath().data() : "",found); - if (found) - { - writeMultiLineCodeLink(yyscanner,*yyextra->code,fd,yytext); - } - else - { - yyextra->code->codify(yytext); - } - char c=(char)yyinput(yyscanner); - QCString text; - text+=c; - yyextra->code->codify(text); - endFontClass(yyscanner); - BEGIN( Body ); - } -^[ \t]*"#" { - startFontClass(yyscanner,"preprocessor"); - yyextra->lastSkipCppContext = YY_START; - yyextra->code->codify(yytext); - BEGIN( SkipCPP ) ; - } -\" { - yyextra->code->codify(yytext); - yyextra->lastStringContext=YY_START; - BEGIN( SkipString ) ; - } -. { - yyextra->code->codify(yytext); - } -[^\n\/\\\"]+ { - yyextra->code->codify(yytext); - } -\\[\r]?\n { - codifyLines(yyscanner,yytext); - } -"//"/[^/!] { - REJECT; - yyextra->code->codify(yytext); - } -"{" { + } + } + } + else // not ambiguous + { + found = TRUE; + } + } + //printf(" include file %s found=%d\n",fd ? fd->absFilePath().data() : "",found); + if (found) + { + writeMultiLineCodeLink(yyscanner,*yyextra->code,fd,yytext); + } + else + { + yyextra->code->codify(yytext); + } + char c=(char)yyinput(yyscanner); + QCString text; + text+=c; + yyextra->code->codify(text); + endFontClass(yyscanner); + BEGIN( Body ); + } +^[ \t]*"#" { + startFontClass(yyscanner,"preprocessor"); + yyextra->lastSkipCppContext = YY_START; + yyextra->code->codify(yytext); + BEGIN( SkipCPP ) ; + } +\" { + yyextra->code->codify(yytext); + yyextra->lastStringContext=YY_START; + BEGIN( SkipString ) ; + } +. { + yyextra->code->codify(yytext); + } +[^\n\/\\\"]+ { + yyextra->code->codify(yytext); + } +\\[\r]?\n { + codifyLines(yyscanner,yytext); + } +"//"/[^/!] { + REJECT; + yyextra->code->codify(yytext); + } +"{" { yyextra->theVarContext.pushScope(); DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); - yyextra->scopeStack.push(INNERBLOCK); - - if (yyextra->searchingForBody) - { - yyextra->searchingForBody=FALSE; - yyextra->insideBody=TRUE; - } - yyextra->code->codify(yytext); - if (yyextra->insideBody) - { - yyextra->bodyCurlyCount++; - } - yyextra->type.resize(0); - yyextra->name.resize(0); - BEGIN( Body ); - } -"}" { + yyextra->scopeStack.push(INNERBLOCK); + + if (yyextra->searchingForBody) + { + yyextra->searchingForBody=FALSE; + yyextra->insideBody=TRUE; + } + yyextra->code->codify(yytext); + if (yyextra->insideBody) + { + yyextra->bodyCurlyCount++; + } + yyextra->type.resize(0); + yyextra->name.resize(0); + BEGIN( Body ); + } +"}" { yyextra->theVarContext.popScope(); - yyextra->type.resize(0); - yyextra->name.resize(0); + yyextra->type.resize(0); + yyextra->name.resize(0); if (!yyextra->scopeStack.empty()) { - int scope = yyextra->scopeStack.top(); + int scope = yyextra->scopeStack.top(); yyextra->scopeStack.pop(); DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK)); - if (scope==SCOPEBLOCK || scope==CLASSBLOCK) - { - popScope(yyscanner); - } - } - - yyextra->code->codify(yytext); - - DBG_CTX((stderr,"yyextra->bodyCurlyCount=%d\n",yyextra->bodyCurlyCount)); - if (--yyextra->bodyCurlyCount<=0) - { - yyextra->insideBody=FALSE; - yyextra->currentMemberDef=0; - if (yyextra->currentDefinition) - yyextra->currentDefinition=yyextra->currentDefinition->getOuterScope(); - } - BEGIN(Body); - } -"@end" { - //printf("End of objc scope fd=%s\n",yyextra->sourceFileDef->name().data()); + if (scope==SCOPEBLOCK || scope==CLASSBLOCK) + { + popScope(yyscanner); + } + } + + yyextra->code->codify(yytext); + + DBG_CTX((stderr,"yyextra->bodyCurlyCount=%d\n",yyextra->bodyCurlyCount)); + if (--yyextra->bodyCurlyCount<=0) + { + yyextra->insideBody=FALSE; + yyextra->currentMemberDef=0; + if (yyextra->currentDefinition) + yyextra->currentDefinition=yyextra->currentDefinition->getOuterScope(); + } + BEGIN(Body); + } +"@end" { + //printf("End of objc scope fd=%s\n",yyextra->sourceFileDef->name().data()); if (yyextra->sourceFileDef) - { - FileDef *fd=yyextra->sourceFileDef; - yyextra->insideObjC = fd->name().lower().right(2)==".m" || - fd->name().lower().right(3)==".mm"; - //printf("insideObjC=%d\n",yyextra->insideObjC); - } - else - { - yyextra->insideObjC = FALSE; - } - if (yyextra->insideBody) - { + { + const FileDef *fd=yyextra->sourceFileDef; + yyextra->insideObjC = fd->name().lower().right(2)==".m" || + fd->name().lower().right(3)==".mm"; + //printf("insideObjC=%d\n",yyextra->insideObjC); + } + else + { + yyextra->insideObjC = FALSE; + } + if (yyextra->insideBody) + { yyextra->theVarContext.popScope(); if (!yyextra->scopeStack.empty()) @@ -706,235 +706,235 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} int scope = yyextra->scopeStack.top(); yyextra->scopeStack.pop(); DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK)); - if (scope==SCOPEBLOCK || scope==CLASSBLOCK) + if (scope==SCOPEBLOCK || scope==CLASSBLOCK) { popScope(yyscanner); } } yyextra->insideBody=FALSE; - } - - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - - yyextra->currentMemberDef=0; - if (yyextra->currentDefinition) - yyextra->currentDefinition=yyextra->currentDefinition->getOuterScope(); - BEGIN(Body); - } -";" { - yyextra->code->codify(yytext); - yyextra->searchingForBody=FALSE; - BEGIN( Body ); - } -[*&^%]+ { - yyextra->type=yyextra->curClassName.copy(); - yyextra->name.resize(0); - yyextra->code->codify(yytext); - BEGIN( Body ); // variable of type struct * - } -"__declspec"{B}*"("{B}*{ID}{B}*")" { - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } -{ID}("."{ID})* | -{ID}("::"{ID})* { + } + + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + + yyextra->currentMemberDef=0; + if (yyextra->currentDefinition) + yyextra->currentDefinition=yyextra->currentDefinition->getOuterScope(); + BEGIN(Body); + } +";" { + yyextra->code->codify(yytext); + yyextra->searchingForBody=FALSE; + BEGIN( Body ); + } +[*&^%]+ { + yyextra->type=yyextra->curClassName.copy(); + yyextra->name.resize(0); + yyextra->code->codify(yytext); + BEGIN( Body ); // variable of type struct * + } +"__declspec"{B}*"("{B}*{ID}{B}*")" { + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } +{ID}("."{ID})* | +{ID}("::"{ID})* { if (yyextra->lang==SrcLangExt_CSharp) yyextra->curClassName=substitute(yytext,".","::"); else yyextra->curClassName=yytext; - addType(yyscanner); + addType(yyscanner); if (yyextra->curClassName=="alignas") { - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); endFontClass(yyscanner); BEGIN( AlignAs ); } else { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - BEGIN( ClassVar ); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + BEGIN( ClassVar ); } - } -"(" { + } +"(" { yyextra->bracketCount=1; - yyextra->code->codify(yytext); + yyextra->code->codify(yytext); BEGIN( AlignAsEnd ); } -\n { yyextra->yyLineNr++; +\n { yyextra->yyLineNr++; codifyLines(yyscanner,yytext); } . { yyextra->code->codify(yytext); } "(" { yyextra->code->codify(yytext); - yyextra->bracketCount++; + yyextra->bracketCount++; } -")" { +")" { yyextra->code->codify(yytext); if (--yyextra->bracketCount<=0) { BEGIN(ClassName); } } -\n { yyextra->yyLineNr++; - codifyLines(yyscanner,yytext); +\n { yyextra->yyLineNr++; + codifyLines(yyscanner,yytext); } . { yyextra->code->codify(yytext); } -{ID}("\\"{ID})* { // PHP namespace +{ID}("\\"{ID})* { // PHP namespace yyextra->curClassName=substitute(yytext,"\\","::"); - yyextra->scopeStack.push(CLASSBLOCK); - pushScope(yyscanner,yyextra->curClassName); - addType(yyscanner); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - BEGIN( ClassVar ); - } + yyextra->scopeStack.push(CLASSBLOCK); + pushScope(yyscanner,yyextra->curClassName); + addType(yyscanner); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + BEGIN( ClassVar ); + } {ID}{B}*"("{ID}")" { // Obj-C category yyextra->curClassName=removeRedundantWhiteSpace(yytext); - yyextra->scopeStack.push(CLASSBLOCK); - pushScope(yyscanner,yyextra->curClassName); - addType(yyscanner); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - BEGIN( ClassVar ); - } -{ID}("."{ID})* { - yyextra->curClassName=substitute(yytext,".","::"); - //printf("found package: %s\n",yyextra->curClassName.data()); - addType(yyscanner); - codifyLines(yyscanner,yytext); - } -"=" { - unput(*yytext); - BEGIN( Body ); - } -("extends"|"implements") { // Java, Slice - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - yyextra->curClassBases.clear(); - BEGIN( Bases ); - } + yyextra->scopeStack.push(CLASSBLOCK); + pushScope(yyscanner,yyextra->curClassName); + addType(yyscanner); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + BEGIN( ClassVar ); + } +{ID}("."{ID})* { + yyextra->curClassName=substitute(yytext,".","::"); + //printf("found package: %s\n",yyextra->curClassName.data()); + addType(yyscanner); + codifyLines(yyscanner,yytext); + } +"=" { + unput(*yytext); + BEGIN( Body ); + } +("extends"|"implements") { // Java, Slice + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + yyextra->curClassBases.clear(); + BEGIN( Bases ); + } ("sealed"|"abstract")/{BN}*(":"|"{") { - DBG_CTX((stderr,"***** C++/CLI modifier %s on yyextra->curClassName=%s\n",yytext,yyextra->curClassName.data())); - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - BEGIN( CppCliTypeModifierFollowup ); - } -{ID} { - yyextra->type = yyextra->curClassName.copy(); - yyextra->name = yytext; - if (yyextra->insideBody) - { - yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); - } - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } -{B}*":"{B}* { - codifyLines(yyscanner,yytext); - yyextra->curClassBases.clear(); - BEGIN( Bases ); - } -[ \t]*";" | + DBG_CTX((stderr,"***** C++/CLI modifier %s on yyextra->curClassName=%s\n",yytext,yyextra->curClassName.data())); + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + BEGIN( CppCliTypeModifierFollowup ); + } +{ID} { + yyextra->type = yyextra->curClassName.copy(); + yyextra->name = yytext; + if (yyextra->insideBody) + { + yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); + } + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } +{B}*":"{B}* { + codifyLines(yyscanner,yytext); + yyextra->curClassBases.clear(); + BEGIN( Bases ); + } +[ \t]*";" | ^{B}*/"@"{ID} | // Objective-C interface {B}*"{"{B}* { yyextra->theVarContext.pushScope(); - yyextra->code->codify(yytext); - if (YY_START==ClassVar && yyextra->curClassName.isEmpty()) - { - yyextra->curClassName = yyextra->name.copy(); - } - if (yyextra->searchingForBody) - { - yyextra->searchingForBody=FALSE; - yyextra->insideBody=TRUE; - } - if (yyextra->insideBody) yyextra->bodyCurlyCount++; - if (!yyextra->curClassName.isEmpty()) // valid class name - { + yyextra->code->codify(yytext); + if (YY_START==ClassVar && yyextra->curClassName.isEmpty()) + { + yyextra->curClassName = yyextra->name.copy(); + } + if (yyextra->searchingForBody) + { + yyextra->searchingForBody=FALSE; + yyextra->insideBody=TRUE; + } + if (yyextra->insideBody) yyextra->bodyCurlyCount++; + if (!yyextra->curClassName.isEmpty()) // valid class name + { DBG_CTX((stderr,"** scope stack push CLASSBLOCK\n")); - yyextra->scopeStack.push(CLASSBLOCK); - pushScope(yyscanner,yyextra->curClassName); - DBG_CTX((stderr,"***** yyextra->curClassName=%s\n",yyextra->curClassName.data())); - if (getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,yyextra->curClassName)==0) - { - DBG_CTX((stderr,"Adding new class %s\n",yyextra->curClassName.data())); + yyextra->scopeStack.push(CLASSBLOCK); + pushScope(yyscanner,yyextra->curClassName); + DBG_CTX((stderr,"***** yyextra->curClassName=%s\n",yyextra->curClassName.data())); + if (getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,yyextra->curClassName)==0) + { + DBG_CTX((stderr,"Adding new class %s\n",yyextra->curClassName.data())); std::unique_ptr ncd { createClassDef("",1,1, - yyextra->curClassName,ClassDef::Class,0,0,FALSE) }; - // insert base classes. - char *s=yyextra->curClassBases.first(); - while (s) - { - const ClassDef *bcd=0; + yyextra->curClassName,ClassDef::Class,0,0,FALSE) }; + // insert base classes. + char *s=yyextra->curClassBases.first(); + while (s) + { + const ClassDef *bcd=0; auto it = yyextra->codeClassMap.find(s); if (it!=yyextra->codeClassMap.end()) { bcd=it->second.get(); } - if (bcd==0) bcd=getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,s); - if (bcd && bcd!=ncd.get()) - { - ncd->insertBaseClass(const_cast(bcd),s,Public,Normal); - } - s=yyextra->curClassBases.next(); - } - yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(ncd))); - } - //printf("yyextra->codeClassList.count()=%d\n",yyextra->codeClassList.count()); - } - else // not a class name -> assume inner block - { + if (bcd==0) bcd=getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,s); + if (bcd && bcd!=ncd.get()) + { + ncd->insertBaseClass(const_cast(bcd),s,Public,Normal); + } + s=yyextra->curClassBases.next(); + } + yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(ncd))); + } + //printf("yyextra->codeClassList.count()=%d\n",yyextra->codeClassList.count()); + } + else // not a class name -> assume inner block + { DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); - yyextra->scopeStack.push(INNERBLOCK); - } - yyextra->curClassName.resize(0); - yyextra->curClassBases.clear(); - BEGIN( Body ); - } -"virtual"|"public"|"protected"|"private"|"@public"|"@private"|"@protected" { - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } -{SEP}?({ID}{SEP})*{ID} { - DBG_CTX((stderr,"%s:addBase(%s)\n",yyextra->curClassName.data(),yytext)); - yyextra->curClassBases.inSort(yytext); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } -"<" { - yyextra->code->codify(yytext); - if (!yyextra->insideObjC) - { - yyextra->sharpCount=1; - BEGIN ( SkipSharp ); - } - else - { - yyextra->insideProtocolList=TRUE; - } - } -">" { - yyextra->code->codify(yytext); - yyextra->insideProtocolList=FALSE; - } + yyextra->scopeStack.push(INNERBLOCK); + } + yyextra->curClassName.resize(0); + yyextra->curClassBases.clear(); + BEGIN( Body ); + } +"virtual"|"public"|"protected"|"private"|"@public"|"@private"|"@protected" { + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } +{SEP}?({ID}{SEP})*{ID} { + DBG_CTX((stderr,"%s:addBase(%s)\n",yyextra->curClassName.data(),yytext)); + yyextra->curClassBases.inSort(yytext); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } +"<" { + yyextra->code->codify(yytext); + if (!yyextra->insideObjC) + { + yyextra->sharpCount=1; + BEGIN ( SkipSharp ); + } + else + { + yyextra->insideProtocolList=TRUE; + } + } +">" { + yyextra->code->codify(yytext); + yyextra->insideProtocolList=FALSE; + } "<" { - yyextra->code->codify(yytext); - ++yyextra->sharpCount; - } -">" { - yyextra->code->codify(yytext); - if (--yyextra->sharpCount<=0) - BEGIN ( Bases ); - } + yyextra->code->codify(yytext); + ++yyextra->sharpCount; + } +">" { + yyextra->code->codify(yytext); + if (--yyextra->sharpCount<=0) + BEGIN ( Bases ); + } "\"" { - yyextra->code->codify(yytext); - yyextra->lastStringContext=YY_START; + yyextra->code->codify(yytext); + yyextra->lastStringContext=YY_START; BEGIN(SkipString); } "\'" { - yyextra->code->codify(yytext); - yyextra->lastStringContext=YY_START; + yyextra->code->codify(yytext); + yyextra->lastStringContext=YY_START; BEGIN(SkipStringS); } "(" { @@ -951,106 +951,106 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} if (--yyextra->sharpCount<=0) BEGIN ( Bases ); } - - -"," { - yyextra->code->codify(yytext); - } - + + +"," { + yyextra->code->codify(yytext); + } + {SCOPEPREFIX}?"operator"{B}*"()"{B}*/"(" { - addType(yyscanner); - generateFunctionLink(yyscanner,*yyextra->code,yytext); - yyextra->bracketCount=0; - yyextra->args.resize(0); - yyextra->name+=yytext; - BEGIN( FuncCall ); - } + addType(yyscanner); + generateFunctionLink(yyscanner,*yyextra->code,yytext); + yyextra->bracketCount=0; + yyextra->args.resize(0); + yyextra->name+=yytext; + BEGIN( FuncCall ); + } {SCOPEPREFIX}?"operator"/"(" { - addType(yyscanner); - generateFunctionLink(yyscanner,*yyextra->code,yytext); - yyextra->bracketCount=0; - yyextra->args.resize(0); - yyextra->name+=yytext; - BEGIN( FuncCall ); + addType(yyscanner); + generateFunctionLink(yyscanner,*yyextra->code,yytext); + yyextra->bracketCount=0; + yyextra->args.resize(0); + yyextra->name+=yytext; + BEGIN( FuncCall ); } {SCOPEPREFIX}?"operator"[^a-z_A-Z0-9\(\n]+/"(" { - addType(yyscanner); - generateFunctionLink(yyscanner,*yyextra->code,yytext); - yyextra->bracketCount=0; - yyextra->args.resize(0); - yyextra->name+=yytext; - BEGIN( FuncCall ); - } -("template"|"generic")/([^a-zA-Z0-9]) { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - yyextra->insideTemplate=TRUE; - yyextra->sharpCount=0; - } -"using"{BN}+"namespace"{BN}+ { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - BEGIN(UsingName); - } -{ID}("::"{ID})* { addUsingDirective(yyscanner,yytext); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + addType(yyscanner); + generateFunctionLink(yyscanner,*yyextra->code,yytext); + yyextra->bracketCount=0; + yyextra->args.resize(0); + yyextra->name+=yytext; + BEGIN( FuncCall ); + } +("template"|"generic")/([^a-zA-Z0-9]) { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + yyextra->insideTemplate=TRUE; + yyextra->sharpCount=0; + } +"using"{BN}+"namespace"{BN}+ { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + BEGIN(UsingName); + } +{ID}("::"{ID})* { addUsingDirective(yyscanner,yytext); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); DBG_CTX((stderr,"** scope stack push CLASSBLOCK\n")); - yyextra->scopeStack.push(CLASSBLOCK); - pushScope(yyscanner,yytext); - BEGIN(Body); + yyextra->scopeStack.push(CLASSBLOCK); + pushScope(yyscanner,yytext); + BEGIN(Body); } -\n { codifyLines(yyscanner,yytext); BEGIN(Body); } -. { codifyLines(yyscanner,yytext); BEGIN(Body); } -"$"?"this"("->"|".") { yyextra->code->codify(yytext); // this-> for C++, this. for C# - yyextra->prefixed_with_this_keyword = TRUE; +\n { codifyLines(yyscanner,yytext); BEGIN(Body); } +. { codifyLines(yyscanner,yytext); BEGIN(Body); } +"$"?"this"("->"|".") { yyextra->code->codify(yytext); // this-> for C++, this. for C# + yyextra->prefixed_with_this_keyword = TRUE; } -{KEYWORD}/([^a-z_A-Z0-9]) { +{KEYWORD}/([^a-z_A-Z0-9]) { if (yyextra->lang==SrcLangExt_Java && qstrcmp("internal",yytext) ==0) REJECT; if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - if (QCString(yytext)=="typedef") - { - addType(yyscanner); - yyextra->name+=yytext; - } - endFontClass(yyscanner); - } -{KEYWORD}/{B}* { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + if (QCString(yytext)=="typedef") + { + addType(yyscanner); + yyextra->name+=yytext; + } + endFontClass(yyscanner); + } +{KEYWORD}/{B}* { if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } -{KEYWORD}/{BN}*"(" { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } +{KEYWORD}/{BN}*"(" { if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT; - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - yyextra->name.resize(0);yyextra->type.resize(0); - } -"in"/{BN}* { - if (!yyextra->inForEachExpression) REJECT; - startFontClass(yyscanner,"keywordflow"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - // insert the variable in the parent scope, see bug 546158 - yyextra->theVarContext.popScope(); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - yyextra->theVarContext.pushScope(); - yyextra->name.resize(0);yyextra->type.resize(0); - } -{FLOWKW}/{BN}*"(" { - startFontClass(yyscanner,"keywordflow"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - yyextra->name.resize(0);yyextra->type.resize(0); - yyextra->inForEachExpression = (qstrcmp(yytext,"for each")==0 || qstrcmp(yytext, "foreach")==0); - BEGIN(FuncCall); - } + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + yyextra->name.resize(0);yyextra->type.resize(0); + } +"in"/{BN}* { + if (!yyextra->inForEachExpression) REJECT; + startFontClass(yyscanner,"keywordflow"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + // insert the variable in the parent scope, see bug 546158 + yyextra->theVarContext.popScope(); + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + yyextra->theVarContext.pushScope(); + yyextra->name.resize(0);yyextra->type.resize(0); + } +{FLOWKW}/{BN}*"(" { + startFontClass(yyscanner,"keywordflow"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + yyextra->name.resize(0);yyextra->type.resize(0); + yyextra->inForEachExpression = (qstrcmp(yytext,"for each")==0 || qstrcmp(yytext, "foreach")==0); + BEGIN(FuncCall); + } {FLOWCONDITION}/{BN}*"(" { if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) { @@ -1063,16 +1063,16 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} yyextra->inForEachExpression = (strcmp(yytext,"for each")==0 || strcmp(yytext, "foreach")==0); BEGIN(FuncCall); } -{FLOWKW}/([^a-z_A-Z0-9]) { - startFontClass(yyscanner,"keywordflow"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - if (yyextra->inFunctionTryBlock && (qstrcmp(yytext,"catch")==0 || qstrcmp(yytext,"finally")==0)) - { - yyextra->inFunctionTryBlock=FALSE; - } - } -{FLOWCONDITION}/([^a-z_A-Z0-9]) { +{FLOWKW}/([^a-z_A-Z0-9]) { + startFontClass(yyscanner,"keywordflow"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + if (yyextra->inFunctionTryBlock && (qstrcmp(yytext,"catch")==0 || qstrcmp(yytext,"finally")==0)) + { + yyextra->inFunctionTryBlock=FALSE; + } + } +{FLOWCONDITION}/([^a-z_A-Z0-9]) { if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) { yyextra->currentMemberDef->incrementFlowKeyWordCount(); @@ -1085,11 +1085,11 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} yyextra->inFunctionTryBlock=FALSE; } } -{FLOWKW}/{B}* { - startFontClass(yyscanner,"keywordflow"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } +{FLOWKW}/{B}* { + startFontClass(yyscanner,"keywordflow"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } {FLOWCONDITION}/{B}* { if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) { @@ -1100,32 +1100,32 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} endFontClass(yyscanner); } "*"{B}*")" { // end of cast? - yyextra->code->codify(yytext); - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->bracketCount--; + yyextra->code->codify(yytext); + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->bracketCount--; yyextra->parmType = yyextra->name; - BEGIN(FuncCall); + BEGIN(FuncCall); } "\\)"|"\\(" { yyextra->code->codify(yytext); } -[\\|\)\+\-\/\%\~\!] { - yyextra->code->codify(yytext); - yyextra->name.resize(0);yyextra->type.resize(0); - if (*yytext==')') - { - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->bracketCount--; - BEGIN(FuncCall); - } - } +[\\|\)\+\-\/\%\~\!] { + yyextra->code->codify(yytext); + yyextra->name.resize(0);yyextra->type.resize(0); + if (*yytext==')') + { + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->bracketCount--; + BEGIN(FuncCall); + } + } {TYPEKW}/{B}* { - startFontClass(yyscanner,"keywordtype"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - addType(yyscanner); - yyextra->name+=yytext; - } + startFontClass(yyscanner,"keywordtype"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + addType(yyscanner); + yyextra->name+=yytext; + } {TYPEKWSL}/{B}* { if (yyextra->lang!=SrcLangExt_Slice) { @@ -1133,395 +1133,395 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} } else { - startFontClass(yyscanner,"keywordtype"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - addType(yyscanner); - yyextra->name+=yytext; + startFontClass(yyscanner,"keywordtype"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + addType(yyscanner); + yyextra->name+=yytext; } - } + } "generic"/{B}*"<"[^\n\/\-\.\{\"\>]*">"{B}* { - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - yyextra->sharpCount=0; - BEGIN(TemplDecl); - } -"template"/{B}*"<"[^\n\/\-\.\{\"\>]*">"{B}* { // template<...> - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - yyextra->sharpCount=0; - BEGIN(TemplDecl); - } -"class"|"typename" { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } -"<" { - yyextra->code->codify(yytext); - yyextra->sharpCount++; - } -">" { + startFontClass(yyscanner,"keyword"); yyextra->code->codify(yytext); - yyextra->sharpCount--; - if (yyextra->sharpCount<=0) - { - BEGIN(Body); - } - } -">" { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - BEGIN( yyextra->lastTemplCastContext ); - } -{ID}("::"{ID})* { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } -("const"|"volatile"){B}* { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } -[*^]* { - codifyLines(yyscanner,yytext); - } -{CASTKW}{B}*"<" { // static_cast( - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - yyextra->lastTemplCastContext = YY_START; - BEGIN(TemplCast); - } -"$this->"{SCOPENAME}/{BN}*[;,)\]] { // PHP member variable - addType(yyscanner); - generatePHPVariableLink(yyscanner,*yyextra->code,yytext); - yyextra->name+=yytext+7; + endFontClass(yyscanner); + yyextra->sharpCount=0; + BEGIN(TemplDecl); + } +"template"/{B}*"<"[^\n\/\-\.\{\"\>]*">"{B}* { // template<...> + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + yyextra->sharpCount=0; + BEGIN(TemplDecl); + } +"class"|"typename" { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } +"<" { + yyextra->code->codify(yytext); + yyextra->sharpCount++; + } +">" { + yyextra->code->codify(yytext); + yyextra->sharpCount--; + if (yyextra->sharpCount<=0) + { + BEGIN(Body); + } + } +">" { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + BEGIN( yyextra->lastTemplCastContext ); + } +{ID}("::"{ID})* { + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } +("const"|"volatile"){B}* { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } +[*^]* { + codifyLines(yyscanner,yytext); + } +{CASTKW}{B}*"<" { // static_cast( + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + yyextra->lastTemplCastContext = YY_START; + BEGIN(TemplCast); + } +"$this->"{SCOPENAME}/{BN}*[;,)\]] { // PHP member variable + addType(yyscanner); + generatePHPVariableLink(yyscanner,*yyextra->code,yytext); + yyextra->name+=yytext+7; } {SCOPENAME}{B}*"<"[^\n\/\-\.\{\"\>\(]*">"("::"{ID})*/{B}* { // A *pt; - if (isCastKeyword(yytext) && YY_START==Body) - { - REJECT; - } - addType(yyscanner); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - yyextra->name+=yytext; - } -{SCOPENAME}/{BN}*[:;,)\]] { // "int var;" or "var, var2" or "debug(f) macro" , or int var : 5; - addType(yyscanner); - // changed this to generateFunctionLink, see bug 624514 - //generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,FALSE,TRUE); - generateFunctionLink(yyscanner,*yyextra->code,yytext); - yyextra->name+=yytext; - } -{SCOPENAME}/{B}* { // p->func() - addType(yyscanner); - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - yyextra->name+=yytext; - } -"("{B}*("*"{B}*)+{SCOPENAME}+{B}*")"/{B}* { // (*p)->func() but not "if (p) ..." - yyextra->code->codify(yytext); - uint s=0;while (s<(uint)yyleng && !isId(yytext[s])) s++; + if (isCastKeyword(yytext) && YY_START==Body) + { + REJECT; + } + addType(yyscanner); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + yyextra->name+=yytext; + } +{SCOPENAME}/{BN}*[:;,)\]] { // "int var;" or "var, var2" or "debug(f) macro" , or int var : 5; + addType(yyscanner); + // changed this to generateFunctionLink, see bug 624514 + //generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,FALSE,TRUE); + generateFunctionLink(yyscanner,*yyextra->code,yytext); + yyextra->name+=yytext; + } +{SCOPENAME}/{B}* { // p->func() + addType(yyscanner); + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + yyextra->name+=yytext; + } +"("{B}*("*"{B}*)+{SCOPENAME}+{B}*")"/{B}* { // (*p)->func() but not "if (p) ..." + yyextra->code->codify(yytext); + uint s=0;while (s<(uint)yyleng && !isId(yytext[s])) s++; uint e=(uint)yyleng-1;while (e>1 && !isId(yytext[e])) e--; - QCString varname = ((QCString)yytext).mid(s,e-s+1); - addType(yyscanner); - yyextra->name=varname; - } + QCString varname = ((QCString)yytext).mid(s,e-s+1); + addType(yyscanner); + yyextra->name=varname; + } {SCOPETNAME}{B}*"<"[^\n\/\-\.\{\"\>]*">"/{BN}*"(" | -{SCOPETNAME}/{BN}*"(" { // a() or c::a() or t::a() or A\B\foo() - if (isCastKeyword(yytext)) - { - REJECT; - } - addType(yyscanner); - generateFunctionLink(yyscanner,*yyextra->code,yytext); - yyextra->bracketCount=0; - yyextra->args.resize(0); - yyextra->name+=yytext; - BEGIN( FuncCall ); - } -{RAWBEGIN} { +{SCOPETNAME}/{BN}*"(" { // a() or c::a() or t::a() or A\B\foo() + if (isCastKeyword(yytext)) + { + REJECT; + } + addType(yyscanner); + generateFunctionLink(yyscanner,*yyextra->code,yytext); + yyextra->bracketCount=0; + yyextra->args.resize(0); + yyextra->name+=yytext; + BEGIN( FuncCall ); + } +{RAWBEGIN} { QCString text=yytext; uint i=(uint)text.find('R'); yyextra->code->codify(text.left(i+1)); - startFontClass(yyscanner,"stringliteral"); - yyextra->code->codify(yytext+i+1); - yyextra->lastStringContext=YY_START; - yyextra->inForEachExpression = FALSE; + startFontClass(yyscanner,"stringliteral"); + yyextra->code->codify(yytext+i+1); + yyextra->lastStringContext=YY_START; + yyextra->inForEachExpression = FALSE; yyextra->delimiter = yytext+i+2; yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1); - BEGIN( RawString ); - } -\" { - startFontClass(yyscanner,"stringliteral"); - yyextra->code->codify(yytext); - yyextra->lastStringContext=YY_START; - yyextra->inForEachExpression = FALSE; - BEGIN( SkipString ); - } + BEGIN( RawString ); + } +\" { + startFontClass(yyscanner,"stringliteral"); + yyextra->code->codify(yytext); + yyextra->lastStringContext=YY_START; + yyextra->inForEachExpression = FALSE; + BEGIN( SkipString ); + } {NUMBER} { //Note similar code in commentcnv.l if (yyextra->lang!=SrcLangExt_Cpp) REJECT; - yyextra->code->codify(yytext); - } -\' { - startFontClass(yyscanner,"stringliteral"); - yyextra->code->codify(yytext); - yyextra->lastStringContext=YY_START; - yyextra->inForEachExpression = FALSE; - BEGIN( SkipStringS ); - } -[^\"\\\r\n]* { - yyextra->code->codify(yytext); - } -[^\'\\\r\n]* { - yyextra->code->codify(yytext); - } -"//"|"/*" { - yyextra->code->codify(yytext); - } -@?\" { - yyextra->code->codify(yytext); - endFontClass(yyscanner); - BEGIN( yyextra->lastStringContext ); - } -\' { - yyextra->code->codify(yytext); - endFontClass(yyscanner); - BEGIN( yyextra->lastStringContext ); - } -\\. { - yyextra->code->codify(yytext); - } -{RAWEND} { + yyextra->code->codify(yytext); + } +\' { + startFontClass(yyscanner,"stringliteral"); + yyextra->code->codify(yytext); + yyextra->lastStringContext=YY_START; + yyextra->inForEachExpression = FALSE; + BEGIN( SkipStringS ); + } +[^\"\\\r\n]* { + yyextra->code->codify(yytext); + } +[^\'\\\r\n]* { + yyextra->code->codify(yytext); + } +"//"|"/*" { + yyextra->code->codify(yytext); + } +@?\" { + yyextra->code->codify(yytext); + endFontClass(yyscanner); + BEGIN( yyextra->lastStringContext ); + } +\' { + yyextra->code->codify(yytext); + endFontClass(yyscanner); + BEGIN( yyextra->lastStringContext ); + } +\\. { + yyextra->code->codify(yytext); + } +{RAWEND} { yyextra->code->codify(yytext); QCString delimiter = yytext+1; delimiter=delimiter.left(delimiter.length()-1); if (delimiter==yyextra->delimiter) { - BEGIN( yyextra->lastStringContext ); + BEGIN( yyextra->lastStringContext ); } } [^)\n]+ { yyextra->code->codify(yytext); } . { yyextra->code->codify(yytext); } \n { codifyLines(yyscanner,yytext); } -[^"\n]+ { - yyextra->code->codify(yytext); - } -\"\" { // escaped quote - yyextra->code->codify(yytext); - } -\" { // end of string - yyextra->code->codify(yytext); - endFontClass(yyscanner); - BEGIN( yyextra->lastVerbStringContext ); - } -. { - yyextra->code->codify(yytext); - } -\n { - codifyLines(yyscanner,yytext); - } -":" { - yyextra->code->codify(yytext); - yyextra->name.resize(0);yyextra->type.resize(0); - } -"<" { - if (yyextra->insideTemplate) - { - yyextra->sharpCount++; - } - yyextra->code->codify(yytext); - } -">" { - if (yyextra->insideTemplate) - { - if (--yyextra->sharpCount<=0) - { - yyextra->insideTemplate=FALSE; - } - } - yyextra->code->codify(yytext); - } -"'"((\\0[Xx0-9]+)|(\\.)|(.))"'" { - startFontClass(yyscanner,"charliteral"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } -"."|"->" { - if (yytext[0]=='-') // -> could be overloaded - { - updateCallContextForSmartPointer(yyscanner); - } - yyextra->code->codify(yytext); - yyextra->memCallContext = YY_START; - BEGIN( MemberCall ); - } -{SCOPETNAME}/{BN}*"(" { - if (yyextra->theCallContext.getScope()) - { - if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext)) - { - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yytext); - } - yyextra->name.resize(0); - } - else - { - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yytext); - yyextra->name.resize(0); - } - yyextra->type.resize(0); - if (yyextra->memCallContext==Body) - { - BEGIN(FuncCall); - } - else - { - BEGIN(yyextra->memCallContext); - } - } -{SCOPENAME}/{B}* { - if (yyextra->theCallContext.getScope()) - { - DBG_CTX((stderr,"yyextra->theCallContext.getClass()=%p\n",yyextra->theCallContext.getScope())); - if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext)) - { - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yytext); - } - yyextra->name.resize(0); - } - else - { - DBG_CTX((stderr,"no class context!\n")); - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yytext); - yyextra->name.resize(0); - } - yyextra->type.resize(0); - BEGIN(yyextra->memCallContext); - } -[,=;\[] { - if (yyextra->insideObjC && *yytext=='[') - { - //printf("Found start of ObjC call!\n"); - // start of a method call - yyextra->contextMap.clear(); - yyextra->nameMap.clear(); - yyextra->objectMap.clear(); - yyextra->wordMap.clear(); +[^"\n]+ { + yyextra->code->codify(yytext); + } +\"\" { // escaped quote + yyextra->code->codify(yytext); + } +\" { // end of string + yyextra->code->codify(yytext); + endFontClass(yyscanner); + BEGIN( yyextra->lastVerbStringContext ); + } +. { + yyextra->code->codify(yytext); + } +\n { + codifyLines(yyscanner,yytext); + } +":" { + yyextra->code->codify(yytext); + yyextra->name.resize(0);yyextra->type.resize(0); + } +"<" { + if (yyextra->insideTemplate) + { + yyextra->sharpCount++; + } + yyextra->code->codify(yytext); + } +">" { + if (yyextra->insideTemplate) + { + if (--yyextra->sharpCount<=0) + { + yyextra->insideTemplate=FALSE; + } + } + yyextra->code->codify(yytext); + } +"'"((\\0[Xx0-9]+)|(\\.)|(.))"'" { + startFontClass(yyscanner,"charliteral"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } +"."|"->" { + if (yytext[0]=='-') // -> could be overloaded + { + updateCallContextForSmartPointer(yyscanner); + } + yyextra->code->codify(yytext); + yyextra->memCallContext = YY_START; + BEGIN( MemberCall ); + } +{SCOPETNAME}/{BN}*"(" { + if (yyextra->theCallContext.getScope()) + { + if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext)) + { + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yytext); + } + yyextra->name.resize(0); + } + else + { + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yytext); + yyextra->name.resize(0); + } + yyextra->type.resize(0); + if (yyextra->memCallContext==Body) + { + BEGIN(FuncCall); + } + else + { + BEGIN(yyextra->memCallContext); + } + } +{SCOPENAME}/{B}* { + if (yyextra->theCallContext.getScope()) + { + DBG_CTX((stderr,"yyextra->theCallContext.getClass()=%p\n",yyextra->theCallContext.getScope())); + if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext)) + { + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yytext); + } + yyextra->name.resize(0); + } + else + { + DBG_CTX((stderr,"no class context!\n")); + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yytext); + yyextra->name.resize(0); + } + yyextra->type.resize(0); + BEGIN(yyextra->memCallContext); + } +[,=;\[] { + if (yyextra->insideObjC && *yytext=='[') + { + //printf("Found start of ObjC call!\n"); + // start of a method call + yyextra->contextMap.clear(); + yyextra->nameMap.clear(); + yyextra->objectMap.clear(); + yyextra->wordMap.clear(); yyextra->commentMap.clear(); - yyextra->currentCtxId = 0; - yyextra->currentNameId = 0; - yyextra->currentObjId = 0; - yyextra->currentCtx = 0; - yyextra->braceCount = 0; - unput('['); - BEGIN(ObjCCall); - } - else - { - yyextra->code->codify(yytext); - yyextra->saveName = yyextra->name.copy(); - yyextra->saveType = yyextra->type.copy(); - if (*yytext!='[' && !yyextra->type.isEmpty()) - { - //printf("yyextra->scopeStack.bottom()=%p\n",yyextra->scopeStack.bottom()); - //if (yyextra->scopeStack.top()!=CLASSBLOCK) // commented out for bug731363 - { - //printf("AddVariable: '%s' '%s' context=%d\n", - // yyextra->type.data(),yyextra->name.data(),yyextra->theVarContext.count()); - yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); - } - yyextra->name.resize(0); - } - if (*yytext==';' || *yytext=='=') - { - yyextra->type.resize(0); - yyextra->name.resize(0); - } - else if (*yytext=='[') - { - yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); - } - yyextra->args.resize(0); + yyextra->currentCtxId = 0; + yyextra->currentNameId = 0; + yyextra->currentObjId = 0; + yyextra->currentCtx = 0; + yyextra->braceCount = 0; + unput('['); + BEGIN(ObjCCall); + } + else + { + yyextra->code->codify(yytext); + yyextra->saveName = yyextra->name.copy(); + yyextra->saveType = yyextra->type.copy(); + if (*yytext!='[' && !yyextra->type.isEmpty()) + { + //printf("yyextra->scopeStack.bottom()=%p\n",yyextra->scopeStack.bottom()); + //if (yyextra->scopeStack.top()!=CLASSBLOCK) // commented out for bug731363 + { + //printf("AddVariable: '%s' '%s' context=%d\n", + // yyextra->type.data(),yyextra->name.data(),yyextra->theVarContext.count()); + yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); + } + yyextra->name.resize(0); + } + if (*yytext==';' || *yytext=='=') + { + yyextra->type.resize(0); + yyextra->name.resize(0); + } + else if (*yytext=='[') + { + yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); + } + yyextra->args.resize(0); yyextra->parmType.resize(0); yyextra->parmName.resize(0); - } - } + } + } /* -{ID} { - if (qstrcmp(yytext,"self")==0 || qstrcmp(yytext,"super")==0) - { - // TODO: get proper base class for "super" - yyextra->theCallContext.setClass(getClass(yyextra->curClassName)); - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } - else - { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } - yyextra->name.resize(0); - BEGIN(ObjCMemberCall2); - } -"[" { - yyextra->code->codify(yytext); - yyextra->theCallContext.pushScope(yyscanner,yyextra->name, yyextra->type); - } -{ID}":"? { - yyextra->name+=yytext; - if (yyextra->theCallContext.getClass()) - { - //printf("Calling method %s\n",yyextra->name.data()); - if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getClass(),yyextra->name)) - { - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yyextra->name); - } - } - else - { - yyextra->code->codify(yytext); - addToSearchIndex(yyscanner,yyextra->name); - } - yyextra->name.resize(0); - BEGIN(ObjCMemberCall3); - } -"]" { - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->code->codify(yytext); - BEGIN(Body); - } +{ID} { + if (qstrcmp(yytext,"self")==0 || qstrcmp(yytext,"super")==0) + { + // TODO: get proper base class for "super" + yyextra->theCallContext.setClass(getClass(yyextra->curClassName)); + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } + else + { + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } + yyextra->name.resize(0); + BEGIN(ObjCMemberCall2); + } +"[" { + yyextra->code->codify(yytext); + yyextra->theCallContext.pushScope(yyscanner,yyextra->name, yyextra->type); + } +{ID}":"? { + yyextra->name+=yytext; + if (yyextra->theCallContext.getClass()) + { + //printf("Calling method %s\n",yyextra->name.data()); + if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getClass(),yyextra->name)) + { + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yyextra->name); + } + } + else + { + yyextra->code->codify(yytext); + addToSearchIndex(yyscanner,yyextra->name); + } + yyextra->name.resize(0); + BEGIN(ObjCMemberCall3); + } +"]" { + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->code->codify(yytext); + BEGIN(Body); + } */ "["|"{" { saveObjCContext(yyscanner); - yyextra->currentCtx->format+=*yytext; - BEGIN(ObjCCall); - //printf("open\n"); + yyextra->currentCtx->format+=*yytext; + BEGIN(ObjCCall); + //printf("open\n"); } "]"|"}" { - yyextra->currentCtx->format+=*yytext; + yyextra->currentCtx->format+=*yytext; restoreObjCContext(yyscanner); - BEGIN(ObjCMName); - if (yyextra->currentCtx==0) - { - // end of call + BEGIN(ObjCMName); + if (yyextra->currentCtx==0) + { + // end of call ObjCCallCtx *ctx = 0; auto it = yyextra->contextMap.find(0); if (it!=yyextra->contextMap.end()) { ctx = it->second.get(); } - writeObjCMethodCall(yyscanner,ctx); - BEGIN(Body); - } - //printf("close\n"); + writeObjCMethodCall(yyscanner,ctx); + BEGIN(Body); + } + //printf("close\n"); } "//".* { yyextra->currentCtx->format+=escapeComment(yyscanner,yytext); @@ -1531,758 +1531,758 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} yyextra->currentCtx->comment=yytext; BEGIN(ObjCCallComment); } -"*/" { +"*/" { yyextra->currentCtx->comment+=yytext; yyextra->currentCtx->format+=escapeComment(yyscanner,yyextra->currentCtx->comment); - BEGIN(yyextra->lastObjCCallContext); - } + BEGIN(yyextra->lastObjCCallContext); + } [^*\n]+ { yyextra->currentCtx->comment+=yytext; } "//"|"/*" { yyextra->currentCtx->comment+=yytext; } \n { yyextra->currentCtx->comment+=*yytext; } . { yyextra->currentCtx->comment+=*yytext; } -{ID} { +{ID} { yyextra->currentCtx->format+=escapeObject(yyscanner,yytext); - if (yyextra->braceCount==0) - { - yyextra->currentCtx->objectTypeOrName=yytext; + if (yyextra->braceCount==0) + { + yyextra->currentCtx->objectTypeOrName=yytext; //printf("new type=%s\n",yyextra->currentCtx->objectTypeOrName.data()); - BEGIN(ObjCMName); - } - } -{ID}/{BN}*"]" { - if (yyextra->braceCount==0 && - yyextra->currentCtx->methodName.isEmpty()) + BEGIN(ObjCMName); + } + } +{ID}/{BN}*"]" { + if (yyextra->braceCount==0 && + yyextra->currentCtx->methodName.isEmpty()) { - yyextra->currentCtx->methodName=yytext; + yyextra->currentCtx->methodName=yytext; yyextra->currentCtx->format+=escapeName(yyscanner,yytext); - } - else - { + } + else + { yyextra->currentCtx->format+=escapeWord(yyscanner,yytext); - } + } } -{ID}/{BN}*":" { +{ID}/{BN}*":" { if (yyextra->braceCount==0) { - yyextra->currentCtx->methodName+=yytext; + yyextra->currentCtx->methodName+=yytext; yyextra->currentCtx->methodName+=":"; - } + } yyextra->currentCtx->format+=escapeName(yyscanner,yytext); } [^\n\"$\\]* { yyextra->currentCtx->format+=yytext; } -\\. { yyextra->currentCtx->format+=yytext; } -"\"" { yyextra->currentCtx->format+=yytext; - BEGIN(yyextra->lastStringContext); +\\. { yyextra->currentCtx->format+=yytext; } +"\"" { yyextra->currentCtx->format+=yytext; + BEGIN(yyextra->lastStringContext); } {CHARLIT} { yyextra->currentCtx->format+=yytext; } -"@"?"\"" { yyextra->currentCtx->format+=yytext; +"@"?"\"" { yyextra->currentCtx->format+=yytext; yyextra->lastStringContext=YY_START; - BEGIN(ObjCSkipStr); + BEGIN(ObjCSkipStr); } "$" { yyextra->currentCtx->format+="$$"; } "(" { yyextra->currentCtx->format+=*yytext; yyextra->braceCount++; } ")" { yyextra->currentCtx->format+=*yytext; yyextra->braceCount--; } -"@"/"\"" { // needed to prevent matching the global rule (for C#) +"@"/"\"" { // needed to prevent matching the global rule (for C#) yyextra->currentCtx->format+=yytext; } {ID} { yyextra->currentCtx->format+=escapeWord(yyscanner,yytext); } . { yyextra->currentCtx->format+=*yytext; } \n { yyextra->currentCtx->format+=*yytext; } -"]" { - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->code->codify(yytext); - // TODO: nested arrays like: a[b[0]->func()]->func() - yyextra->name = yyextra->saveName.copy(); - yyextra->type = yyextra->saveType.copy(); - } -[0-9]+ { - yyextra->code->codify(yytext); - } -[0-9]+[xX][0-9A-Fa-f]+ { - yyextra->code->codify(yytext); - } +"]" { + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->code->codify(yytext); + // TODO: nested arrays like: a[b[0]->func()]->func() + yyextra->name = yyextra->saveName.copy(); + yyextra->type = yyextra->saveType.copy(); + } +[0-9]+ { + yyextra->code->codify(yytext); + } +[0-9]+[xX][0-9A-Fa-f]+ { + yyextra->code->codify(yytext); + } {KEYWORD}/([^a-z_A-Z0-9]) { - //addParmType(yyscanner); - //yyextra->parmName=yytext; + //addParmType(yyscanner); + //yyextra->parmName=yytext; if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT; - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } {TYPEKW}/([^a-z_A-Z0-9]) { - addParmType(yyscanner); - yyextra->parmName=yytext; - startFontClass(yyscanner,"keywordtype"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } + addParmType(yyscanner); + yyextra->parmName=yytext; + startFontClass(yyscanner,"keywordtype"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } {TYPEKWSL}/([^a-z_A-Z0-9]) { if (yyextra->lang!=SrcLangExt_Slice) { - REJECT; + REJECT; + } + else + { + addParmType(yyscanner); + yyextra->parmName=yytext; + startFontClass(yyscanner,"keywordtype"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } + } +{FLOWKW}/([^a-z_A-Z0-9]) { + addParmType(yyscanner); + yyextra->parmName=yytext; + startFontClass(yyscanner,"keywordflow"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } +{FLOWCONDITION}/([^a-z_A-Z0-9]) { + if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) + { + yyextra->currentMemberDef->incrementFlowKeyWordCount(); + } + addParmType(yyscanner); + yyextra->parmName=yytext; + startFontClass(yyscanner,"keywordflow"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } +{ID}(({B}*"<"[^\n\[\](){}<>]*">")?({B}*"::"{B}*{ID})?)* { + if (isCastKeyword(yytext)) + { + REJECT; + } + addParmType(yyscanner); + yyextra->parmName=yytext; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); + } +";" { // probably a cast, not a function call + yyextra->code->codify(yytext); + yyextra->inForEachExpression = FALSE; + BEGIN( Body ); + } +, { + yyextra->code->codify(yytext); + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + } +"{" { + if (yyextra->bracketCount>0) + { + yyextra->code->codify(yytext); + yyextra->skipInlineInitContext=YY_START; + yyextra->curlyCount=0; + BEGIN(InlineInit); + } + else + { + REJECT; + } + } +"{" { yyextra->curlyCount++; + yyextra->code->codify(yytext); + } +"}" { + yyextra->code->codify(yytext); + if (--yyextra->curlyCount<=0) + { + BEGIN(yyextra->skipInlineInitContext); + } + } +\n { + codifyLines(yyscanner,yytext); + } +. { + yyextra->code->codify(yytext); + } +"(" { + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + yyextra->code->codify(yytext); + yyextra->bracketCount++; + yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); + if (YY_START==FuncCall && !yyextra->insideBody) + { + yyextra->theVarContext.pushScope(); + } + } +{OPERATOR} { // operator + if (qstrcmp(yytext,"*") && + qstrcmp(yytext,"&") && + qstrcmp(yytext,"^") && + qstrcmp(yytext,"%")) // typically a pointer or reference + { + // not a * or &, or C++/CLI's ^ or % + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + } + yyextra->code->codify(yytext); + } +("*"{B}*)?")" { + if (yytext[0]==')') // no a pointer cast + { + //printf("addVariable(%s,%s)\n",yyextra->parmType.data(),yyextra->parmName.data()); + if (yyextra->parmType.isEmpty()) + { + yyextra->parmType=yyextra->parmName; + yyextra->parmName.resize(0); + } + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + } + else + { + yyextra->parmType = yyextra->parmName; + yyextra->parmName.resize(0); + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + } + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->inForEachExpression = FALSE; + //yyextra->theCallContext.setClass(0); // commented out, otherwise a()->b() does not work for b(). + yyextra->code->codify(yytext); + if (--yyextra->bracketCount<=0) + { + if (yyextra->name.isEmpty()) + { + BEGIN( Body ); + } + else + { + BEGIN( CallEnd ); + } + } + } +[ \t\n]* { codifyLines(yyscanner,yytext); } + /* +")"[ \t\n]*[;:] { + */ +[;:] { + codifyLines(yyscanner,yytext); + yyextra->bracketCount=0; + if (*yytext==';') yyextra->searchingForBody=FALSE; + if (!yyextra->type.isEmpty()) + { + DBG_CTX((stderr,"add variable yyextra->type=%s yyextra->name=%s)\n",yyextra->type.data(),yyextra->name.data())); + yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); + } + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + yyextra->theCallContext.setScope(0); + if (*yytext==';' || yyextra->insideBody) + { + if (!yyextra->insideBody) + { + yyextra->theVarContext.popScope(); + } + yyextra->name.resize(0);yyextra->type.resize(0); + BEGIN( Body ); + } + else + { + yyextra->bracketCount=0; + BEGIN( SkipInits ); + } + } +("const"|"volatile"|"sealed"|"override")({BN}+("const"|"volatile"|"sealed"|"override"))*/{BN}*(";"|"="|"throw"{BN}*"(") { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } +("const"|"volatile"|"sealed"|"override")*({BN}+("const"|"volatile"|"sealed"|"override"))*{BN}*"{" { + if (yyextra->insideBody) + { + yyextra->theVarContext.pushScope(); + } + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + //yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + int index = yyextra->name.findRev("::"); + DBG_CTX((stderr,"yyextra->name=%s\n",yyextra->name.data())); + if (index!=-1) + { + QCString scope = yyextra->name.left((uint)index); + if (!yyextra->classScope.isEmpty()) scope.prepend(yyextra->classScope+"::"); + const ClassDef *cd=getResolvedClass(Doxygen::globalScope,yyextra->sourceFileDef,scope); + if (cd) + { + setClassScope(yyscanner,cd->name()); + yyextra->scopeStack.push(SCOPEBLOCK); + DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); + } + else + { + //setClassScope(yyscanner,yyextra->realScope); + yyextra->scopeStack.push(INNERBLOCK); + DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); + } + } + else + { + DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); + yyextra->scopeStack.push(INNERBLOCK); + } + yytext[yyleng-1]='\0'; + QCString cv(yytext); + if (!cv.stripWhiteSpace().isEmpty()) + { + startFontClass(yyscanner,"keyword"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } + else // just whitespace + { + codifyLines(yyscanner,yytext); + } + yyextra->code->codify("{"); + if (yyextra->searchingForBody) + { + yyextra->searchingForBody=FALSE; + yyextra->insideBody=TRUE; + } + if (yyextra->insideBody) yyextra->bodyCurlyCount++; + yyextra->type.resize(0); yyextra->name.resize(0); + BEGIN( Body ); + } +"try" { // function-try-block + startFontClass(yyscanner,"keyword"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + yyextra->inFunctionTryBlock=TRUE; + } +{ID} { + if (yyextra->insideBody || !yyextra->parmType.isEmpty()) + { + REJECT; + } + // could be K&R style definition + addParmType(yyscanner); + yyextra->parmName=yytext; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); + BEGIN(OldStyleArgs); + } +{ID} { + addParmType(yyscanner); + yyextra->parmName=yytext; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); + } +[,;] { + yyextra->code->codify(yytext); + yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + if (*yytext==';') yyextra->parmType.resize(0); + yyextra->parmName.resize(0); + } +"#" { + startFontClass(yyscanner,"preprocessor"); + yyextra->lastSkipCppContext = Body; + yyextra->code->codify(yytext); + BEGIN( SkipCPP ); + } +. { + unput(*yytext); + if (!yyextra->insideBody) + { + yyextra->theVarContext.popScope(); + } + yyextra->name.resize(0);yyextra->args.resize(0); + yyextra->parmType.resize(0);yyextra->parmName.resize(0); + BEGIN( Body ); + } +";" { + yyextra->code->codify(yytext); + yyextra->type.resize(0); yyextra->name.resize(0); + BEGIN( Body ); + } +"{" { + yyextra->code->codify(yytext); + if (yyextra->searchingForBody) + { + yyextra->searchingForBody=FALSE; + yyextra->insideBody=TRUE; + } + if (yyextra->insideBody) yyextra->bodyCurlyCount++; + if (yyextra->name.find("::")!=-1) + { + DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); + yyextra->scopeStack.push(SCOPEBLOCK); + setClassScope(yyscanner,yyextra->realScope); + } + else + { + DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); + yyextra->scopeStack.push(INNERBLOCK); + } + yyextra->type.resize(0); yyextra->name.resize(0); + BEGIN( Body ); + } +{ID} { + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + } +{ID}/"(" { + generateFunctionLink(yyscanner,*yyextra->code,yytext); + } +{ID}/("."|"->") { + yyextra->name=yytext; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + BEGIN( MemberCall2 ); + } +("("{B}*("*"{B}*)+{ID}+{B}*")"{B}*)/("."|"->") { + yyextra->code->codify(yytext); + uint s=0;while (!isId(yytext[s])) s++; + uint e=(uint)yyleng-1;while (e>1 && !isId(yytext[e])) e--; + yyextra->name=((QCString)yytext).mid(s,e-s+1); + BEGIN( MemberCall2 ); + } +{ID}/([ \t\n]*"(") { + if (!yyextra->args.isEmpty()) + generateMemberLink(yyscanner,*yyextra->code,yyextra->args,yytext); + else + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + yyextra->args.resize(0); + BEGIN( FuncCall ); + } +{ID}/([ \t\n]*("."|"->")) { + //yyextra->code->codify(yytext); + yyextra->name=yytext; + generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); + BEGIN( MemberCall2 ); + } +"->"|"." { + if (yytext[0]=='-') // -> could be overloaded + { + updateCallContextForSmartPointer(yyscanner); + } + yyextra->code->codify(yytext); + yyextra->memCallContext = YY_START; + BEGIN( MemberCall ); + } +"/*"("!"?)"*/" { + yyextra->code->codify(yytext); + endFontClass(yyscanner); + BEGIN( yyextra->lastCContext ) ; + } +"//"|"/*" { + yyextra->code->codify(yytext); + } +[^*/\n]+ { + yyextra->code->codify(yytext); + } +[ \t]*"*/" { + yyextra->code->codify(yytext); + endFontClass(yyscanner); + if (yyextra->lastCContext==SkipCPP) + { + startFontClass(yyscanner,"preprocessor"); + } + BEGIN( yyextra->lastCContext ) ; + } +[^\r\n]*"\\"[\r]?\n { // line continuation + codifyLines(yyscanner,yytext); + } +[^\r\n]+ { + yyextra->code->codify(yytext); + } +\r +\n { + unput('\n'); + endFontClass(yyscanner); + BEGIN( yyextra->lastCContext ) ; + } +. { + yyextra->code->codify(yytext); + } +"*/"{B}*\n({B}*\n)*({B}*(("//@"[{}])|("/*@"[{}]"*/")){B}*\n)?{B}*"/*"[*!]/[^/*] { + yyextra->yyLineNr+=QCString(yytext).contains('\n'); + } +"*/"{B}*\n({B}*\n)*({B}*(("//@"[{}])|("/*@"[{}]"*/")){B}*\n)? { + if (yyextra->lastSpecialCContext==SkipCxxComment) + { // force end of C++ comment here + yyextra->yyLineNr+=QCString(yytext).contains('\n'); + nextCodeLine(yyscanner); + endFontClass(yyscanner); + BEGIN( yyextra->lastCContext ) ; + } + else + { + yyextra->yyLineNr+=QCString(yytext).contains('\n'); + if (yytext[yyleng-1]=='\n') + { + yyextra->yyLineNr--; + unput('\n'); + } + else + { + nextCodeLine(yyscanner); + } + BEGIN(yyextra->lastSpecialCContext); + } + } +"*/" { + BEGIN(yyextra->lastSpecialCContext); + } +[^*\n]+ +"//"|"/*" +\n { yyextra->yyLineNr++; } +. +[^a-z_A-Z0-9(\n] { + yyextra->code->codify(yytext); + yyextra->type.resize(0); + yyextra->name.resize(0); + BEGIN(yyextra->memCallContext); + } +<*>\n({B}*"//"[!/][^\n]*\n)+ { // remove special one-line comment + if (YY_START==SkipCPP) REJECT; + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + yyextra->yyLineNr+=QCString(yytext).contains('\n'); + nextCodeLine(yyscanner); } else { - addParmType(yyscanner); - yyextra->parmName=yytext; - startFontClass(yyscanner,"keywordtype"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); } - } -{FLOWKW}/([^a-z_A-Z0-9]) { - addParmType(yyscanner); - yyextra->parmName=yytext; - startFontClass(yyscanner,"keywordflow"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } -{FLOWCONDITION}/([^a-z_A-Z0-9]) { - if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) + if (YY_START==SkipCxxComment) { - yyextra->currentMemberDef->incrementFlowKeyWordCount(); + endFontClass(yyscanner); + BEGIN( yyextra->lastCContext ) ; } - addParmType(yyscanner); - yyextra->parmName=yytext; - startFontClass(yyscanner,"keywordflow"); - yyextra->code->codify(yytext); + } +\n/.*\n { endFontClass(yyscanner); + BEGIN( yyextra->lastSkipCppContext ) ; + unput('\n'); } -{ID}(({B}*"<"[^\n\[\](){}<>]*">")?({B}*"::"{B}*{ID})?)* { - if (isCastKeyword(yytext)) - { - REJECT; - } - addParmType(yyscanner); - yyextra->parmName=yytext; - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); - } -";" { // probably a cast, not a function call - yyextra->code->codify(yytext); - yyextra->inForEachExpression = FALSE; - BEGIN( Body ); - } -, { - yyextra->code->codify(yytext); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - } -"{" { - if (yyextra->bracketCount>0) +<*>\n{B}*"//@"[{}].*\n { // remove one-line group marker + if (Config_getBool(STRIP_CODE_COMMENTS)) { - yyextra->code->codify(yytext); - yyextra->skipInlineInitContext=YY_START; - yyextra->curlyCount=0; - BEGIN(InlineInit); + yyextra->yyLineNr+=2; + nextCodeLine(yyscanner); } else { - REJECT; + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } + if (YY_START==SkipCxxComment) + { + endFontClass(yyscanner); + BEGIN( yyextra->lastCContext ) ; } } -"{" { yyextra->curlyCount++; - yyextra->code->codify(yytext); +<*>\n{B}*"/*@"[{}] { // remove one-line group marker + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + yyextra->yyLineNr++; + BEGIN(RemoveSpecialCComment); + } + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + yyextra->lastCContext = YY_START ; + } + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + BEGIN(SkipComment); + } } -"}" { - yyextra->code->codify(yytext); - if (--yyextra->curlyCount<=0) +<*>^{B}*"//@"[{}].*\n { // remove one-line group marker + if (Config_getBool(STRIP_CODE_COMMENTS)) { - BEGIN(yyextra->skipInlineInitContext); + yyextra->yyLineNr++; + nextCodeLine(yyscanner); + } + else + { + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); } } -\n { - codifyLines(yyscanner,yytext); +<*>^{B}*"/*@"[{}] { // remove multi-line group marker + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + BEGIN(RemoveSpecialCComment); + } + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + yyextra->lastCContext = YY_START ; + } + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + BEGIN(SkipComment); + } } -. { - yyextra->code->codify(yytext); +<*>^{B}*"//"[!/][^\n]*\n { // remove special one-line comment + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + yyextra->yyLineNr++; + //nextCodeLine(yyscanner); + } + else + { + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } } -"(" { - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - yyextra->code->codify(yytext); - yyextra->bracketCount++; - yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); - if (YY_START==FuncCall && !yyextra->insideBody) - { - yyextra->theVarContext.pushScope(); - } - } -{OPERATOR} { // operator - if (qstrcmp(yytext,"*") && - qstrcmp(yytext,"&") && - qstrcmp(yytext,"^") && - qstrcmp(yytext,"%")) // typically a pointer or reference - { - // not a * or &, or C++/CLI's ^ or % - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - } - yyextra->code->codify(yytext); - } -("*"{B}*)?")" { - if (yytext[0]==')') // no a pointer cast +<*>"//"[!/][^\n]*/\n { // strip special one-line comment + if (YY_START==SkipComment || YY_START==SkipString) REJECT; + if (!Config_getBool(STRIP_CODE_COMMENTS)) { - //printf("addVariable(%s,%s)\n",yyextra->parmType.data(),yyextra->parmName.data()); - if (yyextra->parmType.isEmpty()) + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + endFontClass(yyscanner); + } + } +<*>"/*[tag:"[^\]\n]*"]*/"{B}* { // special pattern /*[tag:filename]*/ to force linking to a tag file + yyextra->forceTagReference=yytext; + uint s=(uint)yyextra->forceTagReference.find(':'); + uint e=(uint)yyextra->forceTagReference.findRev(']'); + yyextra->forceTagReference = yyextra->forceTagReference.mid(s+1,e-s-1); + } +<*>\n{B}*"/*"[!*]/[^/*] { + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + yyextra->yyLineNr++; + BEGIN(RemoveSpecialCComment); + } + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) { - yyextra->parmType=yyextra->parmName; - yyextra->parmName.resize(0); + yyextra->lastCContext = YY_START ; } - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); + startFontClass(yyscanner,"comment"); + codifyLines(yyscanner,yytext); + BEGIN(SkipComment); + } + } +<*>^{B}*"/**"[*]+/[^/] { // special C "banner" comment block at a new line + if (Config_getBool(JAVADOC_BANNER) && Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + BEGIN(RemoveSpecialCComment); } else { - yyextra->parmType = yyextra->parmName; - yyextra->parmName.resize(0); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - } - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->inForEachExpression = FALSE; - //yyextra->theCallContext.setClass(0); // commented out, otherwise a()->b() does not work for b(). - yyextra->code->codify(yytext); - if (--yyextra->bracketCount<=0) - { - if (yyextra->name.isEmpty()) - { - BEGIN( Body ); - } - else - { - BEGIN( CallEnd ); - } - } - } -[ \t\n]* { codifyLines(yyscanner,yytext); } - /* -")"[ \t\n]*[;:] { - */ -[;:] { - codifyLines(yyscanner,yytext); - yyextra->bracketCount=0; - if (*yytext==';') yyextra->searchingForBody=FALSE; - if (!yyextra->type.isEmpty()) - { - DBG_CTX((stderr,"add variable yyextra->type=%s yyextra->name=%s)\n",yyextra->type.data(),yyextra->name.data())); - yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name); - } - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - yyextra->theCallContext.setScope(0); - if (*yytext==';' || yyextra->insideBody) - { - if (!yyextra->insideBody) - { - yyextra->theVarContext.popScope(); - } - yyextra->name.resize(0);yyextra->type.resize(0); - BEGIN( Body ); - } - else - { - yyextra->bracketCount=0; - BEGIN( SkipInits ); - } - } -("const"|"volatile"|"sealed"|"override")({BN}+("const"|"volatile"|"sealed"|"override"))*/{BN}*(";"|"="|"throw"{BN}*"(") { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } -("const"|"volatile"|"sealed"|"override")*({BN}+("const"|"volatile"|"sealed"|"override"))*{BN}*"{" { - if (yyextra->insideBody) - { - yyextra->theVarContext.pushScope(); - } - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - //yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - int index = yyextra->name.findRev("::"); - DBG_CTX((stderr,"yyextra->name=%s\n",yyextra->name.data())); - if (index!=-1) - { - QCString scope = yyextra->name.left((uint)index); - if (!yyextra->classScope.isEmpty()) scope.prepend(yyextra->classScope+"::"); - const ClassDef *cd=getResolvedClass(Doxygen::globalScope,yyextra->sourceFileDef,scope); - if (cd) - { - setClassScope(yyscanner,cd->name()); - yyextra->scopeStack.push(SCOPEBLOCK); - DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); - } - else - { - //setClassScope(yyscanner,yyextra->realScope); - yyextra->scopeStack.push(INNERBLOCK); - DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); - } - } - else - { - DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); - yyextra->scopeStack.push(INNERBLOCK); - } - yytext[yyleng-1]='\0'; - QCString cv(yytext); - if (!cv.stripWhiteSpace().isEmpty()) - { - startFontClass(yyscanner,"keyword"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - else // just whitespace - { - codifyLines(yyscanner,yytext); - } - yyextra->code->codify("{"); - if (yyextra->searchingForBody) - { - yyextra->searchingForBody=FALSE; - yyextra->insideBody=TRUE; - } - if (yyextra->insideBody) yyextra->bodyCurlyCount++; - yyextra->type.resize(0); yyextra->name.resize(0); - BEGIN( Body ); - } -"try" { // function-try-block - startFontClass(yyscanner,"keyword"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - yyextra->inFunctionTryBlock=TRUE; - } -{ID} { - if (yyextra->insideBody || !yyextra->parmType.isEmpty()) - { - REJECT; - } - // could be K&R style definition - addParmType(yyscanner); - yyextra->parmName=yytext; - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); - BEGIN(OldStyleArgs); - } -{ID} { - addParmType(yyscanner); - yyextra->parmName=yytext; - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody); - } -[,;] { - yyextra->code->codify(yytext); - yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName); - if (*yytext==';') yyextra->parmType.resize(0); - yyextra->parmName.resize(0); - } -"#" { - startFontClass(yyscanner,"preprocessor"); - yyextra->lastSkipCppContext = Body; - yyextra->code->codify(yytext); - BEGIN( SkipCPP ); - } -. { - unput(*yytext); - if (!yyextra->insideBody) - { - yyextra->theVarContext.popScope(); - } - yyextra->name.resize(0);yyextra->args.resize(0); - yyextra->parmType.resize(0);yyextra->parmName.resize(0); - BEGIN( Body ); - } -";" { - yyextra->code->codify(yytext); - yyextra->type.resize(0); yyextra->name.resize(0); - BEGIN( Body ); - } -"{" { - yyextra->code->codify(yytext); - if (yyextra->searchingForBody) - { - yyextra->searchingForBody=FALSE; - yyextra->insideBody=TRUE; - } - if (yyextra->insideBody) yyextra->bodyCurlyCount++; - if (yyextra->name.find("::")!=-1) - { - DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n")); - yyextra->scopeStack.push(SCOPEBLOCK); - setClassScope(yyscanner,yyextra->realScope); - } - else - { - DBG_CTX((stderr,"** scope stack push INNERBLOCK\n")); - yyextra->scopeStack.push(INNERBLOCK); - } - yyextra->type.resize(0); yyextra->name.resize(0); - BEGIN( Body ); - } -{ID} { - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - } -{ID}/"(" { - generateFunctionLink(yyscanner,*yyextra->code,yytext); - } -{ID}/("."|"->") { - yyextra->name=yytext; - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - BEGIN( MemberCall2 ); - } -("("{B}*("*"{B}*)+{ID}+{B}*")"{B}*)/("."|"->") { - yyextra->code->codify(yytext); - uint s=0;while (!isId(yytext[s])) s++; - uint e=(uint)yyleng-1;while (e>1 && !isId(yytext[e])) e--; - yyextra->name=((QCString)yytext).mid(s,e-s+1); - BEGIN( MemberCall2 ); - } -{ID}/([ \t\n]*"(") { - if (!yyextra->args.isEmpty()) - generateMemberLink(yyscanner,*yyextra->code,yyextra->args,yytext); - else - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - yyextra->args.resize(0); - BEGIN( FuncCall ); - } -{ID}/([ \t\n]*("."|"->")) { - //yyextra->code->codify(yytext); - yyextra->name=yytext; - generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext); - BEGIN( MemberCall2 ); - } -"->"|"." { - if (yytext[0]=='-') // -> could be overloaded - { - updateCallContextForSmartPointer(yyscanner); - } - yyextra->code->codify(yytext); - yyextra->memCallContext = YY_START; - BEGIN( MemberCall ); - } -"/*"("!"?)"*/" { - yyextra->code->codify(yytext); - endFontClass(yyscanner); - BEGIN( yyextra->lastCContext ) ; - } -"//"|"/*" { - yyextra->code->codify(yytext); - } -[^*/\n]+ { - yyextra->code->codify(yytext); - } -[ \t]*"*/" { - yyextra->code->codify(yytext); - endFontClass(yyscanner); - if (yyextra->lastCContext==SkipCPP) + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + yyextra->lastCContext = YY_START ; + } + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + BEGIN(SkipComment); + } + } +<*>^{B}*"/*"[!*]/[^/*] { // special C comment block at a new line + if (Config_getBool(STRIP_CODE_COMMENTS)) { - startFontClass(yyscanner,"preprocessor"); + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + BEGIN(RemoveSpecialCComment); } - BEGIN( yyextra->lastCContext ) ; - } -[^\r\n]*"\\"[\r]?\n { // line continuation - codifyLines(yyscanner,yytext); - } -[^\r\n]+ { - yyextra->code->codify(yytext); - } -\r -\n { - unput('\n'); - endFontClass(yyscanner); - BEGIN( yyextra->lastCContext ) ; - } -. { - yyextra->code->codify(yytext); - } -"*/"{B}*\n({B}*\n)*({B}*(("//@"[{}])|("/*@"[{}]"*/")){B}*\n)?{B}*"/*"[*!]/[^/*] { - yyextra->yyLineNr+=QCString(yytext).contains('\n'); - } -"*/"{B}*\n({B}*\n)*({B}*(("//@"[{}])|("/*@"[{}]"*/")){B}*\n)? { - if (yyextra->lastSpecialCContext==SkipCxxComment) - { // force end of C++ comment here - yyextra->yyLineNr+=QCString(yytext).contains('\n'); - nextCodeLine(yyscanner); - endFontClass(yyscanner); - BEGIN( yyextra->lastCContext ) ; - } - else - { - yyextra->yyLineNr+=QCString(yytext).contains('\n'); - if (yytext[yyleng-1]=='\n') + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) { - yyextra->yyLineNr--; - unput('\n'); + yyextra->lastCContext = YY_START ; } - else + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + BEGIN(SkipComment); + } + } +<*>"/*"[!*]/[^/*] { // special C comment block half way a line + if (YY_START==SkipString) REJECT; + if (Config_getBool(STRIP_CODE_COMMENTS)) + { + if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; + BEGIN(RemoveSpecialCComment); + } + else + { + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) { - nextCodeLine(yyscanner); + yyextra->lastCContext = YY_START ; } - BEGIN(yyextra->lastSpecialCContext); - } - } -"*/" { - BEGIN(yyextra->lastSpecialCContext); - } -[^*\n]+ -"//"|"/*" -\n { yyextra->yyLineNr++; } -. -[^a-z_A-Z0-9(\n] { - yyextra->code->codify(yytext); - yyextra->type.resize(0); - yyextra->name.resize(0); - BEGIN(yyextra->memCallContext); - } -<*>\n({B}*"//"[!/][^\n]*\n)+ { // remove special one-line comment - if (YY_START==SkipCPP) REJECT; - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - yyextra->yyLineNr+=QCString(yytext).contains('\n'); - nextCodeLine(yyscanner); - } - else - { - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - if (YY_START==SkipCxxComment) - { - endFontClass(yyscanner); - BEGIN( yyextra->lastCContext ) ; - } - } -\n/.*\n { - endFontClass(yyscanner); - BEGIN( yyextra->lastSkipCppContext ) ; - unput('\n'); - } -<*>\n{B}*"//@"[{}].*\n { // remove one-line group marker - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - yyextra->yyLineNr+=2; - nextCodeLine(yyscanner); - } - else - { - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - if (YY_START==SkipCxxComment) - { - endFontClass(yyscanner); - BEGIN( yyextra->lastCContext ) ; - } - } -<*>\n{B}*"/*@"[{}] { // remove one-line group marker - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - yyextra->yyLineNr++; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - BEGIN(SkipComment); - } - } -<*>^{B}*"//@"[{}].*\n { // remove one-line group marker - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - yyextra->yyLineNr++; - nextCodeLine(yyscanner); - } - else - { - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - } -<*>^{B}*"/*@"[{}] { // remove multi-line group marker - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - BEGIN(SkipComment); - } - } -<*>^{B}*"//"[!/][^\n]*\n { // remove special one-line comment - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - yyextra->yyLineNr++; - //nextCodeLine(yyscanner); - } - else - { - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - } -<*>"//"[!/][^\n]*/\n { // strip special one-line comment - if (YY_START==SkipComment || YY_START==SkipString) REJECT; - if (!Config_getBool(STRIP_CODE_COMMENTS)) - { - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - endFontClass(yyscanner); - } - } -<*>"/*[tag:"[^\]\n]*"]*/"{B}* { // special pattern /*[tag:filename]*/ to force linking to a tag file - yyextra->forceTagReference=yytext; - uint s=(uint)yyextra->forceTagReference.find(':'); - uint e=(uint)yyextra->forceTagReference.findRev(']'); - yyextra->forceTagReference = yyextra->forceTagReference.mid(s+1,e-s-1); - } -<*>\n{B}*"/*"[!*]/[^/*] { - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - yyextra->yyLineNr++; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,yytext); - BEGIN(SkipComment); - } - } -<*>^{B}*"/**"[*]+/[^/] { // special C "banner" comment block at a new line - if (Config_getBool(JAVADOC_BANNER) && Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - BEGIN(SkipComment); - } - } -<*>^{B}*"/*"[!*]/[^/*] { // special C comment block at a new line - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - BEGIN(SkipComment); - } - } -<*>"/*"[!*]/[^/*] { // special C comment block half way a line - if (YY_START==SkipString) REJECT; - if (Config_getBool(STRIP_CODE_COMMENTS)) - { - if (YY_START != RemoveSpecialCComment) yyextra->lastSpecialCContext = YY_START; - BEGIN(RemoveSpecialCComment); - } - else - { - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - BEGIN(SkipComment); - } - } -<*>"/*"("!"?)"*/" { + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + BEGIN(SkipComment); + } + } +<*>"/*"("!"?)"*/" { if (YY_START==SkipString) REJECT; if (!Config_getBool(STRIP_CODE_COMMENTS)) - { - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - endFontClass(yyscanner); - } - } + { + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + endFontClass(yyscanner); + } + } [^\*\n]+ { yyextra->code->codify(yytext); } -<*>"/*" { - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - // check is to prevent getting stuck in skipping C++ comments - if (YY_START != SkipComment && YY_START != SkipCxxComment) - { - yyextra->lastCContext = YY_START ; - } - BEGIN( SkipComment ) ; - } -<*>@\" { // C# verbatim string - startFontClass(yyscanner,"stringliteral"); - yyextra->code->codify(yytext); - yyextra->lastVerbStringContext=YY_START; - BEGIN(SkipVerbString); - } -<*>"//" { - startFontClass(yyscanner,"comment"); - yyextra->code->codify(yytext); - yyextra->lastCContext = YY_START ; - BEGIN( SkipCxxComment ) ; - } -<*>"("|"[" { - yyextra->code->codify(yytext); - yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); - } -<*>")"|"]" { - yyextra->code->codify(yytext); - yyextra->theCallContext.popScope(yyextra->name, yyextra->type); - } -<*>\n { - yyextra->yyColNr++; - codifyLines(yyscanner,yytext); - } +<*>"/*" { + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + // check is to prevent getting stuck in skipping C++ comments + if (YY_START != SkipComment && YY_START != SkipCxxComment) + { + yyextra->lastCContext = YY_START ; + } + BEGIN( SkipComment ) ; + } +<*>@\" { // C# verbatim string + startFontClass(yyscanner,"stringliteral"); + yyextra->code->codify(yytext); + yyextra->lastVerbStringContext=YY_START; + BEGIN(SkipVerbString); + } +<*>"//" { + startFontClass(yyscanner,"comment"); + yyextra->code->codify(yytext); + yyextra->lastCContext = YY_START ; + BEGIN( SkipCxxComment ) ; + } +<*>"("|"[" { + yyextra->code->codify(yytext); + yyextra->theCallContext.pushScope(yyextra->name, yyextra->type); + } +<*>")"|"]" { + yyextra->code->codify(yytext); + yyextra->theCallContext.popScope(yyextra->name, yyextra->type); + } +<*>\n { + yyextra->yyColNr++; + codifyLines(yyscanner,yytext); + } <*>[\x80-\xFF]* { // keep utf8 characters together... - yyextra->yyColNr+=yyleng; - yyextra->code->codify(yytext); + yyextra->yyColNr+=yyleng; + yyextra->code->codify(yytext); + } +<*>. { + yyextra->yyColNr++; + yyextra->code->codify(yytext); } -<*>. { - yyextra->yyColNr++; - yyextra->code->codify(yytext); - } /* -<*>([ \t\n]*"\n"){2,} { // combine multiple blank lines - //QCString sepLine=yytext; - //yyextra->code->codify("\n\n"); - //yyextra->yyLineNr+=sepLine.contains('\n'); - //char sepLine[3]="\n\n"; - codifyLines(yyscanner,yytext); - } +<*>([ \t\n]*"\n"){2,} { // combine multiple blank lines + //QCString sepLine=yytext; + //yyextra->code->codify("\n\n"); + //yyextra->yyLineNr+=sepLine.contains('\n'); + //char sepLine[3]="\n\n"; + codifyLines(yyscanner,yytext); + } */ %% @@ -2296,7 +2296,7 @@ void VariableContext::addVariable(yyscan_t yyscanner,const QCString &type,const //printf("VariableContext::addVariable(%s,%s)\n",type.data(),name.data()); QCString ltype = type.simplifyWhiteSpace(); QCString lname = name.simplifyWhiteSpace(); - if (ltype.left(7)=="struct ") + if (ltype.left(7)=="struct ") { ltype = ltype.right(ltype.length()-7); } @@ -2305,8 +2305,8 @@ void VariableContext::addVariable(yyscan_t yyscanner,const QCString &type,const ltype = ltype.right(ltype.length()-6); } if (ltype.isEmpty() || lname.isEmpty()) return; - DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' g_currentDefinition=%s\n", - ltype.data(),lname.data(),g_currentDefinition?g_currentDefinition->name().data():"")); + DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' currentDefinition=%s\n", + ltype.data(),lname.data(),yyextra->currentDefinition?yyextra->currentDefinition->name().data():"")); Scope *scope = m_scopes.empty() ? &m_globalScope : &m_scopes.back(); const ClassDef *varType = 0; auto it = yyextra->codeClassMap.find(ltype.str()); @@ -2357,9 +2357,9 @@ void VariableContext::addVariable(yyscan_t yyscanner,const QCString &type,const addVariable(yyscanner,typeName,name); } } - else + else { - if (!m_scopes.empty()) // for local variables add a dummy entry so the name + if (!m_scopes.empty()) // for local variables add a dummy entry so the name // is hidden to avoid false links to global variables with the same name // TODO: make this work for namespaces as well! { @@ -2507,7 +2507,7 @@ static void startCodeLine(yyscan_t yyscanner) //QCString lineNumber,lineAnchor; //lineNumber.sprintf("%05d",yyextra->yyLineNr); //lineAnchor.sprintf("l%05d",yyextra->yyLineNr); - + Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr); //printf("%s:startCodeLine(%d)=%p\n",yyextra->sourceFileDef->name().data(),yyextra->yyLineNr,d); if (!yyextra->includeCodeFragment && d) @@ -2530,15 +2530,15 @@ static void startCodeLine(yyscan_t yyscanner) if (yyextra->currentMemberDef) { yyextra->code->writeLineNumber(yyextra->currentMemberDef->getReference(), - yyextra->currentMemberDef->getOutputFileBase(), - yyextra->currentMemberDef->anchor(),yyextra->yyLineNr); + yyextra->currentMemberDef->getOutputFileBase(), + yyextra->currentMemberDef->anchor(),yyextra->yyLineNr); setCurrentDoc(yyscanner,lineAnchor); } else if (d->isLinkableInProject()) { yyextra->code->writeLineNumber(d->getReference(), - d->getOutputFileBase(), - 0,yyextra->yyLineNr); + d->getOutputFileBase(), + 0,yyextra->yyLineNr); setCurrentDoc(yyscanner,lineAnchor); } } @@ -2548,7 +2548,7 @@ static void startCodeLine(yyscan_t yyscanner) } } DBG_CTX((stderr,"startCodeLine(%d)\n",yyextra->yyLineNr)); - yyextra->code->startCodeLine(yyextra->sourceFileDef && yyextra->lineNumbers); + yyextra->code->startCodeLine(yyextra->sourceFileDef && yyextra->lineNumbers); if (yyextra->currentFontClass) { yyextra->code->startFontClass(yyextra->currentFontClass); @@ -2570,7 +2570,7 @@ static void nextCodeLine(yyscan_t yyscanner) struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; const char * fc = yyextra->currentFontClass; endCodeLine(yyscanner); - if (yyextra->yyLineNrinputLines) + if (yyextra->yyLineNrinputLines) { yyextra->currentFontClass = fc; startCodeLine(yyscanner); @@ -2612,7 +2612,7 @@ static void codifyLines(yyscan_t yyscanner,const char *text) } /*! writes a link to a fragment \a text that may span multiple lines, inserting - * line numbers for each line. If \a text contains newlines, the link will be + * line numbers for each line. If \a text contains newlines, the link will be * split into multiple links with the same destination, one for each line. */ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, @@ -2625,7 +2625,7 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); - QCString tooltip; + QCString tooltip; if (!sourceTooltips) // fall back to simple "title" tooltips { tooltip = d->briefDescriptionAsTooltip(); @@ -2680,7 +2680,7 @@ static void addUsingDirective(yyscan_t yyscanner,const char *name) struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; if (yyextra->sourceFileDef && name) { - NamespaceDef *nd = Doxygen::namespaceSDict->find(name); + const NamespaceDef *nd = Doxygen::namespaceSDict->find(name); if (nd) { yyextra->sourceFileDef->addUsingDirective(nd); @@ -2706,7 +2706,7 @@ static void setParameterList(yyscan_t yyscanner,const MemberDef *md) } } -static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,Definition *d) +static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,const Definition *d) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; int pos=0; @@ -2747,7 +2747,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) QCString scope = name.left(scopeEnd); QCString locName = name.right(name.length()-scopeEnd-2); //printf("explicit scope: name=%s scope=%s\n",locName.data(),scope.data()); - ClassDef *mcd = getClass(scope); + const ClassDef *mcd = getClass(scope); if (mcd && !locName.isEmpty()) { MemberDef *md=mcd->getMemberByName(locName); @@ -2763,18 +2763,18 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) const NamespaceDef *mnd = getResolvedNamespace(scope); if (mnd && !locName.isEmpty()) { - MemberDef *md=mnd->getMemberByName(locName); - if (md) - { - //printf("name=%s scope=%s\n",locName.data(),scope.data()); - yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); - return md; - } + MemberDef *md=mnd->getMemberByName(locName); + if (md) + { + //printf("name=%s scope=%s\n",locName.data(),scope.data()); + yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); + return md; + } } } } - - MemberName *mn; + + const MemberName *mn; const ClassDef *mcd = yyextra->theVarContext.findVariable(name); if (mcd) // local variable { @@ -2788,21 +2788,21 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) else { DBG_CTX((stderr,"class member? scope=%s\n",yyextra->classScope.data())); - // look for a class member + // look for a class member mcd = getClass(yyextra->classScope); if (mcd) { DBG_CTX((stderr,"Inside class %s\n",mcd->name().data())); MemberDef *md=mcd->getMemberByName(name); - if (md) + if (md) { DBG_CTX((stderr,"Found member %s\n",md->name().data())); - if (yyextra->scopeStack.empty() || yyextra->scopeStack.top()!=CLASSBLOCK) - { + if (yyextra->scopeStack.empty() || yyextra->scopeStack.top()!=CLASSBLOCK) + { DBG_CTX((stderr,"class member '%s' mcd=%s\n",name.data(),mcd->name().data())); - yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); - } - return md; + yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); + } + return md; } } } @@ -2825,19 +2825,19 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) { for (const auto &md : *mn) { - //printf("mn=%p md=%p md->getBodyDef()=%p yyextra->sourceFileDef=%p\n", - // mn,md, - // md->getBodyDef(),yyextra->sourceFileDef); + //printf("mn=%p md=%p md->getBodyDef()=%p yyextra->sourceFileDef=%p\n", + // mn,md, + // md->getBodyDef(),yyextra->sourceFileDef); - // in case there are multiple members we could link to, we - // only link to members if defined in the same file or - // defined as external. + // in case there are multiple members we could link to, we + // only link to members if defined in the same file or + // defined as external. if ((!md->isStatic() || md->getBodyDef()==yyextra->sourceFileDef) && - (yyextra->forceTagReference.isEmpty() || yyextra->forceTagReference==md->getReference()) - ) + (yyextra->forceTagReference.isEmpty() || yyextra->forceTagReference==md->getReference()) + ) { yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); - //printf("returning member %s in source file %s\n",md->name().data(),yyextra->sourceFileDef->name().data()); + //printf("returning member %s in source file %s\n",md->name().data(),yyextra->sourceFileDef->name().data()); return md.get(); } } @@ -2852,7 +2852,7 @@ static void updateCallContextForSmartPointer(yyscan_t yyscanner) struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; const Definition *d = yyextra->theCallContext.getScope(); //printf("updateCallContextForSmartPointer() cd=%s\n",cd ? d->name().data() : ""); - MemberDef *md; + const MemberDef *md; if (d && d->definitionType()==Definition::TypeClass && (md=(dynamic_cast(d))->isSmartPointer())) { const ClassDef *ncd = stripClassName(yyscanner,md->typeString(),md->getOuterScope()); @@ -2867,11 +2867,11 @@ static void updateCallContextForSmartPointer(yyscan_t yyscanner) static bool getLinkInScope(yyscan_t yyscanner, const QCString &c, // scope const QCString &m, // member - const char *memberText, // exact text - CodeOutputInterface &ol, - const char *text, - bool varOnly - ) + const char *memberText, // exact text + CodeOutputInterface &ol, + const char *text, + bool varOnly + ) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; const MemberDef *md = 0; @@ -2880,7 +2880,7 @@ static bool getLinkInScope(yyscan_t yyscanner, const NamespaceDef *nd = 0; const GroupDef *gd = 0; DBG_CTX((stderr,"getLinkInScope: trying '%s'::'%s' varOnly=%d\n",c.data(),m.data(),varOnly)); - if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,yyextra->sourceFileDef,FALSE,yyextra->forceTagReference) && + if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,yyextra->sourceFileDef,FALSE,yyextra->forceTagReference) && (!varOnly || md->isVariable())) { if (md->isLinkable()) @@ -2933,9 +2933,9 @@ static bool getLinkInScope(yyscan_t yyscanner, static bool getLink(yyscan_t yyscanner, const char *className, const char *memberName, - CodeOutputInterface &ol, - const char *text, - bool varOnly) + CodeOutputInterface &ol, + const char *text, + bool varOnly) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //printf("getLink(%s,%s) yyextra->curClassName=%s\n",className,memberName,yyextra->curClassName.data()); @@ -2988,11 +2988,11 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, //printf("generateClassOrGlobalLink(className=%s)\n",className.data()); if (!yyextra->prefixed_with_this_keyword || (lcd=yyextra->theVarContext.findVariable(className))==0) // not a local variable { - Definition *d = yyextra->currentDefinition; + const Definition *d = yyextra->currentDefinition; //printf("d=%s yyextra->sourceFileDef=%s\n",d?d->name().data():"",yyextra->sourceFileDef?yyextra->sourceFileDef->name().data():""); cd = getResolvedClass(d,yyextra->sourceFileDef,className,&md); - DBG_CTX((stderr,"non-local variable name=%s context=%d cd=%s md=%s!\n", - className.data(),yyextra->theVarContext.count(),cd?cd->name().data():"", + DBG_CTX((stderr,"non-local variable name=%s cd=%s md=%s!\n", + className.data(),cd?cd->name().data():"", md?md->name().data():"")); if (cd==0 && md==0 && (i=className.find('<'))!=-1) { @@ -3000,7 +3000,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, DBG_CTX((stderr,"bareName=%s\n",bareName.data())); if (bareName!=className) { - cd=getResolvedClass(d,yyextra->sourceFileDef,bareName,&md); // try unspecialized version + cd=getResolvedClass(d,yyextra->sourceFileDef,bareName,&md); // try unspecialized version } } const NamespaceDef *nd = getResolvedNamespace(className); @@ -3019,24 +3019,24 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, { if (getLink(yyscanner,yyextra->classScope,clName,ol,clName,varOnly)) { - return; + return; } } } else { //printf("local variable!\n"); - if (lcd!=VariableContext::dummyContext) + if (lcd!=VariableContext::dummyContext) { //printf("non-dummy context lcd=%s!\n",lcd->name().data()); yyextra->theCallContext.setScope(lcd); // to following is needed for links to a global variable, but is // no good for a link to a local variable that is also a global symbol. - + //if (getLink(yyscanner,yyextra->classScope,clName,ol,clName)) //{ - //return; + //return; //} } isLocal=TRUE; @@ -3055,8 +3055,8 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, // yyextra->exampleFile.data()); if (const_cast(cd)->addExample(anchor,yyextra->exampleName,yyextra->exampleFile)) { - ol.writeCodeAnchor(anchor); - yyextra->anchorCount++; + ol.writeCodeAnchor(anchor); + yyextra->anchorCount++; } } writeMultiLineCodeLink(yyscanner,ol,cd,clName); @@ -3067,7 +3067,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, const Definition *d = md->getOuterScope()==Doxygen::globalScope ? md->getFileDef() : md->getOuterScope(); if (md->getGroupDef()) d = md->getGroupDef(); - if (d && d->isLinkable() && md->isLinkable() && + if (d && d->isLinkable() && md->isLinkable() && yyextra->currentMemberDef && yyextra->collectXRefs) { addDocCrossReference(yyextra->currentMemberDef,const_cast(md)); @@ -3081,55 +3081,55 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, { if (md==0) // not found as a typedef { - md = setCallContextForVar(yyscanner,clName); - //printf("setCallContextForVar(%s) md=%p yyextra->currentDefinition=%p\n",clName,md,yyextra->currentDefinition); - if (md && yyextra->currentDefinition) - { - DBG_CTX((stderr,"%s accessible from %s? %d md->getOuterScope=%s\n", - md->name().data(),yyextra->currentDefinition->name().data(), - isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md), - md->getOuterScope()->name().data())); - } - - if (md && yyextra->currentDefinition && - isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md)==-1) - { - md=0; // variable not accessible - } + md = setCallContextForVar(yyscanner,clName); + //printf("setCallContextForVar(%s) md=%p yyextra->currentDefinition=%p\n",clName,md,yyextra->currentDefinition); + if (md && yyextra->currentDefinition) + { + DBG_CTX((stderr,"%s accessible from %s? %d md->getOuterScope=%s\n", + md->name().data(),yyextra->currentDefinition->name().data(), + isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md), + md->getOuterScope()->name().data())); + } + + if (md && yyextra->currentDefinition && + isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md)==-1) + { + md=0; // variable not accessible + } } if (md && (!varOnly || md->isVariable())) { DBG_CTX((stderr,"is a global md=%p yyextra->currentDefinition=%s linkable=%d\n",md,yyextra->currentDefinition?yyextra->currentDefinition->name().data():"",md->isLinkable())); - if (md->isLinkable()) - { - QCString text; - if (!yyextra->forceTagReference.isEmpty()) // explicit reference to symbol in tag file - { - text=yyextra->forceTagReference; - if (text.right(4)==".tag") // strip .tag if present - { - text=text.left(text.length()-4); - } - text+=getLanguageSpecificSeparator(md->getLanguage()); - text+=clName; - const_cast(md)->setName(text); + if (md->isLinkable()) + { + QCString text; + if (!yyextra->forceTagReference.isEmpty()) // explicit reference to symbol in tag file + { + text=yyextra->forceTagReference; + if (text.right(4)==".tag") // strip .tag if present + { + text=text.left(text.length()-4); + } + text+=getLanguageSpecificSeparator(md->getLanguage()); + text+=clName; + const_cast(md)->setName(text); const_cast(md)->setLocalName(text); - } - else // normal reference - { - text=clName; - } - writeMultiLineCodeLink(yyscanner,ol,md,text); + } + else // normal reference + { + text=clName; + } + writeMultiLineCodeLink(yyscanner,ol,md,text); addToSearchIndex(yyscanner,clName); - if (yyextra->currentMemberDef && yyextra->collectXRefs) - { - addDocCrossReference(yyextra->currentMemberDef,const_cast(md)); - } - return; - } + if (yyextra->currentMemberDef && yyextra->collectXRefs) + { + addDocCrossReference(yyextra->currentMemberDef,const_cast(md)); + } + return; + } } } - + // nothing found, just write out the word DBG_CTX((stderr,"not found!\n")); codifyLines(yyscanner,clName); @@ -3181,9 +3181,9 @@ static bool generateClassMemberLink(yyscan_t yyscanner, { // add usage reference if (yyextra->currentDefinition && yyextra->currentMemberDef && - /*xmd!=yyextra->currentMemberDef &&*/ yyextra->insideBody && yyextra->collectXRefs) + /*xmd!=yyextra->currentMemberDef &&*/ yyextra->insideBody && yyextra->collectXRefs) { - addDocCrossReference(yyextra->currentMemberDef,xmd); + addDocCrossReference(yyextra->currentMemberDef,xmd); } // write the actual link @@ -3213,7 +3213,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner, } else { - Definition *innerDef = cd->findInnerCompound(memName); + const Definition *innerDef = cd->findInnerCompound(memName); if (innerDef) { yyextra->theCallContext.setScope(innerDef); @@ -3227,7 +3227,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner, { const NamespaceDef *nd = dynamic_cast(def); //printf("Looking for %s inside namespace %s\n",memName,nd->name().data()); - Definition *innerDef = nd->findInnerCompound(memName); + const Definition *innerDef = nd->findInnerCompound(memName); if (innerDef) { yyextra->theCallContext.setScope(innerDef); @@ -3252,27 +3252,27 @@ static void generateMemberLink(yyscan_t yyscanner, // look for the variable in the current context const ClassDef *vcd = yyextra->theVarContext.findVariable(varName); - if (vcd) + if (vcd) { if (vcd!=VariableContext::dummyContext) { //printf("Class found!\n"); - if (getLink(yyscanner,vcd->name(),memName,ol)) + if (getLink(yyscanner,vcd->name(),memName,ol)) { - //printf("Found result!\n"); - return; + //printf("Found result!\n"); + return; } if (vcd->baseClasses()) { - BaseClassListIterator bcli(*vcd->baseClasses()); - for ( ; bcli.current() ; ++bcli) - { - if (getLink(yyscanner,bcli.current()->classDef->name(),memName,ol)) - { - //printf("Found result!\n"); - return; - } - } + BaseClassListIterator bcli(*vcd->baseClasses()); + for ( ; bcli.current() ; ++bcli) + { + if (getLink(yyscanner,bcli.current()->classDef->name(),memName,ol)) + { + //printf("Found result!\n"); + return; + } + } } } } @@ -3285,46 +3285,46 @@ static void generateMemberLink(yyscan_t yyscanner, MemberName *vmn=Doxygen::memberNameLinkedMap->find(varName); if (vmn==0) { - int vi; - QCString vn=varName; - if ((vi=vn.findRev("::"))!=-1 || (vi=vn.findRev('.'))!=-1) // explicit scope A::b(), probably static member - { - ClassDef *jcd = getClass(vn.left(vi)); - vn=vn.right(vn.length()-vi-2); - vmn=Doxygen::memberNameLinkedMap->find(vn); - //printf("Trying name '%s' scope=%s\n",vn.data(),scope.data()); - if (vmn) - { + int vi; + QCString vn=varName; + if ((vi=vn.findRev("::"))!=-1 || (vi=vn.findRev('.'))!=-1) // explicit scope A::b(), probably static member + { + const ClassDef *jcd = getClass(vn.left(vi)); + vn=vn.right(vn.length()-vi-2); + vmn=Doxygen::memberNameLinkedMap->find(vn); + //printf("Trying name '%s' scope=%s\n",vn.data(),scope.data()); + if (vmn) + { for (const auto &vmd : *vmn) - { - if (vmd->getClassDef()==jcd) - { - //printf("Found variable type=%s\n",vmd->typeString()); - const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); - if (mcd && mcd->isLinkable()) - { - if (generateClassMemberLink(yyscanner,ol,mcd,memName)) return; - } - } - } - } - } + { + if (vmd->getClassDef()==jcd) + { + //printf("Found variable type=%s\n",vmd->typeString()); + const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); + if (mcd && mcd->isLinkable()) + { + if (generateClassMemberLink(yyscanner,ol,mcd,memName)) return; + } + } + } + } + } } if (vmn) { - //printf("There is a variable with name '%s'\n",varName); + //printf("There is a variable with name '%s'\n",varName); for (const auto &vmd : *vmn) - { - if (vmd->getClassDef()==vcd) - { - //printf("Found variable type=%s\n",vmd->typeString()); - const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); - if (mcd && mcd->isLinkable()) - { - if (generateClassMemberLink(yyscanner,ol,mcd,memName)) return; - } - } - } + { + if (vmd->getClassDef()==vcd) + { + //printf("Found variable type=%s\n",vmd->typeString()); + const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); + if (mcd && mcd->isLinkable()) + { + if (generateClassMemberLink(yyscanner,ol,mcd,memName)) return; + } + } + } } } } @@ -3362,13 +3362,13 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons int len=2; int i=locFunc.findRev("::"); if (yyextra->currentMemberDef && yyextra->currentMemberDef->resolveAlias()->getClassDef() && - funcName==yyextra->currentMemberDef->localName() && + funcName==yyextra->currentMemberDef->localName() && yyextra->currentMemberDef->getDefLine()==yyextra->yyLineNr && generateClassMemberLink(yyscanner,ol,yyextra->currentMemberDef,funcName) ) { // special case where funcName is the name of a method that is also - // defined on this line. In this case we can directly link to + // defined on this line. In this case we can directly link to // yyextra->currentMemberDef, which is not only faster, but // in case of overloaded methods, this will make sure that we link to // the correct method, and thereby get the correct reimplemented relations. @@ -3446,7 +3446,7 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons BaseClassListIterator bcli(*ccd->baseClasses()); for ( ; bcli.current() ; ++bcli) { - if (getLink(yyscanner,bcli.current()->classDef->name(),funcWithScope,ol,funcName)) + if (getLink(yyscanner,bcli.current()->classDef->name(),funcWithScope,ol,funcName)) { goto exit; } @@ -3458,7 +3458,7 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons { generateClassOrGlobalLink(yyscanner,ol,funcName); } -exit: +exit: yyextra->forceTagReference.resize(0); return; } @@ -3470,17 +3470,17 @@ static int countLines(yyscan_t yyscanner) const char *p=yyextra->inputString; char c; int count=1; - while ((c=*p)) - { - p++ ; - if (c=='\n') count++; + while ((c=*p)) + { + p++ ; + if (c=='\n') count++; } - if (p>yyextra->inputString && *(p-1)!='\n') + if (p>yyextra->inputString && *(p-1)!='\n') { // last line does not end with a \n, so we add an extra // line and explicitly terminate the line after parsing. - count++, - yyextra->needsTermination=TRUE; - } + count++, + yyextra->needsTermination=TRUE; + } return count; } @@ -3518,62 +3518,62 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) if (!ctx->objectTypeOrName.isEmpty() && ctx->objectTypeOrName.at(0)!='$') { //printf("Looking for object=%s method=%s\n",ctx->objectTypeOrName.data(), - // ctx->methodName.data()); + // ctx->methodName.data()); const ClassDef *cd = yyextra->theVarContext.findVariable(ctx->objectTypeOrName); if (cd==0) // not a local variable { - if (ctx->objectTypeOrName=="self") - { - if (yyextra->currentDefinition && - yyextra->currentDefinition->definitionType()==Definition::TypeClass) - { - ctx->objectType = dynamic_cast(yyextra->currentDefinition); - } - } - else - { - ctx->objectType = getResolvedClass( - yyextra->currentDefinition, - yyextra->sourceFileDef, - ctx->objectTypeOrName, - &ctx->method); - } - //printf(" object is class? %p\n",ctx->objectType); - if (ctx->objectType) // found class - { - ctx->method = ctx->objectType->getMemberByName(ctx->methodName); - //printf(" yes->method=%s\n",ctx->method?ctx->method->name().data():""); - } - else if (ctx->method==0) // search for class variable with the same name - { - //printf(" no\n"); - //printf("yyextra->currentDefinition=%p\n",yyextra->currentDefinition); - if (yyextra->currentDefinition && - yyextra->currentDefinition->definitionType()==Definition::TypeClass) - { - ctx->objectVar = (dynamic_cast(yyextra->currentDefinition))->getMemberByName(ctx->objectTypeOrName); - //printf(" ctx->objectVar=%p\n",ctx->objectVar); - if (ctx->objectVar) - { - ctx->objectType = stripClassName(yyscanner,ctx->objectVar->typeString(),yyextra->currentDefinition); - //printf(" ctx->objectType=%p\n",ctx->objectType); - if (ctx->objectType && !ctx->methodName.isEmpty()) - { - ctx->method = ctx->objectType->getMemberByName(ctx->methodName); - //printf(" ctx->method=%p\n",ctx->method); - } - } - } - } + if (ctx->objectTypeOrName=="self") + { + if (yyextra->currentDefinition && + yyextra->currentDefinition->definitionType()==Definition::TypeClass) + { + ctx->objectType = dynamic_cast(yyextra->currentDefinition); + } + } + else + { + ctx->objectType = getResolvedClass( + yyextra->currentDefinition, + yyextra->sourceFileDef, + ctx->objectTypeOrName, + &ctx->method); + } + //printf(" object is class? %p\n",ctx->objectType); + if (ctx->objectType) // found class + { + ctx->method = ctx->objectType->getMemberByName(ctx->methodName); + //printf(" yes->method=%s\n",ctx->method?ctx->method->name().data():""); + } + else if (ctx->method==0) // search for class variable with the same name + { + //printf(" no\n"); + //printf("yyextra->currentDefinition=%p\n",yyextra->currentDefinition); + if (yyextra->currentDefinition && + yyextra->currentDefinition->definitionType()==Definition::TypeClass) + { + ctx->objectVar = (dynamic_cast(yyextra->currentDefinition))->getMemberByName(ctx->objectTypeOrName); + //printf(" ctx->objectVar=%p\n",ctx->objectVar); + if (ctx->objectVar) + { + ctx->objectType = stripClassName(yyscanner,ctx->objectVar->typeString(),yyextra->currentDefinition); + //printf(" ctx->objectType=%p\n",ctx->objectType); + if (ctx->objectType && !ctx->methodName.isEmpty()) + { + ctx->method = ctx->objectType->getMemberByName(ctx->methodName); + //printf(" ctx->method=%p\n",ctx->method); + } + } + } + } } else // local variable { - //printf(" object is local variable\n"); - if (cd!=VariableContext::dummyContext && !ctx->methodName.isEmpty()) - { - ctx->method = cd->getMemberByName(ctx->methodName); - //printf(" class=%p method=%p\n",cd,ctx->method); - } + //printf(" object is local variable\n"); + if (cd!=VariableContext::dummyContext && !ctx->methodName.isEmpty()) + { + ctx->method = cd->getMemberByName(ctx->methodName); + //printf(" class=%p method=%p\n",cd,ctx->method); + } } } } @@ -3586,215 +3586,215 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) char nc=*p++; if (nc=='$') // escaped $ { - yyextra->code->codify("$"); + yyextra->code->codify("$"); } - else // name fragment or reference to a nested call + else // name fragment or reference to a nested call { - if (nc=='n') // name fragment - { + if (nc=='n') // name fragment + { nc=*p++; - QCString refIdStr; - while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } - p--; - int refId=refIdStr.toInt(); - auto it = yyextra->nameMap.find(refId); - if (it!=yyextra->nameMap.end()) - { - QCString name = it->second; - if (ctx->method && ctx->method->isLinkable()) - { + QCString refIdStr; + while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } + p--; + int refId=refIdStr.toInt(); + auto it = yyextra->nameMap.find(refId); + if (it!=yyextra->nameMap.end()) + { + QCString name = it->second; + if (ctx->method && ctx->method->isLinkable()) + { writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->method,name); - if (yyextra->currentMemberDef && yyextra->collectXRefs) - { - addDocCrossReference(yyextra->currentMemberDef,const_cast(ctx->method)); - } - } - else - { - codifyLines(yyscanner,name); - } - } - else - { - //printf("Invalid name: id=%d\n",refId); - } - } - else if (nc=='o') // reference to potential object name - { + if (yyextra->currentMemberDef && yyextra->collectXRefs) + { + addDocCrossReference(yyextra->currentMemberDef,const_cast(ctx->method)); + } + } + else + { + codifyLines(yyscanner,name); + } + } + else + { + //printf("Invalid name: id=%d\n",refId); + } + } + else if (nc=='o') // reference to potential object name + { nc=*p++; - QCString refIdStr; - while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } - p--; - int refId=refIdStr.toInt(); + QCString refIdStr; + while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } + p--; + int refId=refIdStr.toInt(); auto it = yyextra->objectMap.find(refId); - if (it!=yyextra->objectMap.end()) - { - QCString object = it->second; - if (object=="self") - { - if (yyextra->currentDefinition && - yyextra->currentDefinition->definitionType()==Definition::TypeClass) - { - ctx->objectType = dynamic_cast(yyextra->currentDefinition); - if (ctx->objectType->categoryOf()) - { - ctx->objectType = ctx->objectType->categoryOf(); - } - if (ctx->objectType && !ctx->methodName.isEmpty()) - { - ctx->method = ctx->objectType->getMemberByName(ctx->methodName); - } - } - startFontClass(yyscanner,"keyword"); + if (it!=yyextra->objectMap.end()) + { + QCString object = it->second; + if (object=="self") + { + if (yyextra->currentDefinition && + yyextra->currentDefinition->definitionType()==Definition::TypeClass) + { + ctx->objectType = dynamic_cast(yyextra->currentDefinition); + if (ctx->objectType->categoryOf()) + { + ctx->objectType = ctx->objectType->categoryOf(); + } + if (ctx->objectType && !ctx->methodName.isEmpty()) + { + ctx->method = ctx->objectType->getMemberByName(ctx->methodName); + } + } + startFontClass(yyscanner,"keyword"); codifyLines(yyscanner,object); - endFontClass(yyscanner); - } - else if (object=="super") - { - if (yyextra->currentDefinition && - yyextra->currentDefinition->definitionType()==Definition::TypeClass) - { - ClassDef *cd = dynamic_cast(yyextra->currentDefinition); - if (cd->categoryOf()) - { - cd = cd->categoryOf(); - } - BaseClassList *bcd = cd->baseClasses(); - if (bcd) // get direct base class (there should be only one) - { - BaseClassListIterator bli(*bcd); - BaseClassDef *bclass; - for (bli.toFirst();(bclass=bli.current());++bli) - { - if (bclass->classDef->compoundType()!=ClassDef::Protocol) - { - ctx->objectType = bclass->classDef; - if (ctx->objectType && !ctx->methodName.isEmpty()) - { - ctx->method = ctx->objectType->getMemberByName(ctx->methodName); - } - } - } - } - } - startFontClass(yyscanner,"keyword"); + endFontClass(yyscanner); + } + else if (object=="super") + { + if (yyextra->currentDefinition && + yyextra->currentDefinition->definitionType()==Definition::TypeClass) + { + const ClassDef *cd = dynamic_cast(yyextra->currentDefinition); + if (cd->categoryOf()) + { + cd = cd->categoryOf(); + } + const BaseClassList *bcd = cd->baseClasses(); + if (bcd) // get direct base class (there should be only one) + { + BaseClassListIterator bli(*bcd); + BaseClassDef *bclass; + for (bli.toFirst();(bclass=bli.current());++bli) + { + if (bclass->classDef->compoundType()!=ClassDef::Protocol) + { + ctx->objectType = bclass->classDef; + if (ctx->objectType && !ctx->methodName.isEmpty()) + { + ctx->method = ctx->objectType->getMemberByName(ctx->methodName); + } + } + } + } + } + startFontClass(yyscanner,"keyword"); codifyLines(yyscanner,object); - endFontClass(yyscanner); - } - else if (ctx->objectVar && ctx->objectVar->isLinkable()) // object is class variable - { - writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->objectVar,object); - if (yyextra->currentMemberDef && yyextra->collectXRefs) - { - addDocCrossReference(yyextra->currentMemberDef,const_cast(ctx->objectVar)); - } - } - else if (ctx->objectType && - ctx->objectType!=VariableContext::dummyContext && - ctx->objectType->isLinkable() - ) // object is class name - { - const ClassDef *cd = ctx->objectType; - writeMultiLineCodeLink(yyscanner,*yyextra->code,cd,object); - } - else // object still needs to be resolved - { - const ClassDef *cd = getResolvedClass(yyextra->currentDefinition, - yyextra->sourceFileDef, object); - if (cd && cd->isLinkable()) - { - if (ctx->objectType==0) ctx->objectType=cd; - writeMultiLineCodeLink(yyscanner,*yyextra->code,cd,object); - } - else - { - codifyLines(yyscanner,object); - } - } - } - else - { - //printf("Invalid object: id=%d\n",refId); - } - } - else if (nc=='c') // reference to nested call - { + endFontClass(yyscanner); + } + else if (ctx->objectVar && ctx->objectVar->isLinkable()) // object is class variable + { + writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->objectVar,object); + if (yyextra->currentMemberDef && yyextra->collectXRefs) + { + addDocCrossReference(yyextra->currentMemberDef,const_cast(ctx->objectVar)); + } + } + else if (ctx->objectType && + ctx->objectType!=VariableContext::dummyContext && + ctx->objectType->isLinkable() + ) // object is class name + { + const ClassDef *cd = ctx->objectType; + writeMultiLineCodeLink(yyscanner,*yyextra->code,cd,object); + } + else // object still needs to be resolved + { + const ClassDef *cd = getResolvedClass(yyextra->currentDefinition, + yyextra->sourceFileDef, object); + if (cd && cd->isLinkable()) + { + if (ctx->objectType==0) ctx->objectType=cd; + writeMultiLineCodeLink(yyscanner,*yyextra->code,cd,object); + } + else + { + codifyLines(yyscanner,object); + } + } + } + else + { + //printf("Invalid object: id=%d\n",refId); + } + } + else if (nc=='c') // reference to nested call + { nc=*p++; - QCString refIdStr; - while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } - p--; - int refId=refIdStr.toInt(); + QCString refIdStr; + while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } + p--; + int refId=refIdStr.toInt(); auto it = yyextra->contextMap.find(refId); - if (it!=yyextra->contextMap.end()) // recurse into nested call - { + if (it!=yyextra->contextMap.end()) // recurse into nested call + { ObjCCallCtx *ictx = it->second.get(); - writeObjCMethodCall(yyscanner,ictx); - if (ictx->method) // link to nested call successfully - { - // get the ClassDef representing the method's return type - if (QCString(ictx->method->typeString())=="id") - { - // see if the method name is unique, if so we link to it - MemberName *mn=Doxygen::memberNameLinkedMap->find(ctx->methodName); - //printf("mn->count=%d ictx->method=%s ctx->methodName=%s\n", - // mn==0?-1:(int)mn->count(), - // ictx->method->name().data(), - // ctx->methodName.data()); - if (mn && mn->size()==1) // member name unique - { - ctx->method = mn->front().get(); - } - } - else - { - ctx->objectType = stripClassName(yyscanner,ictx->method->typeString(),yyextra->currentDefinition); - if (ctx->objectType && !ctx->methodName.isEmpty()) - { - ctx->method = ctx->objectType->getMemberByName(ctx->methodName); - } - } - //printf(" ***** method=%s -> object=%p\n",ictx->method->name().data(),ctx->objectType); - } - } - else - { - //printf("Invalid context: id=%d\n",refId); - } - } - else if (nc=='w') // some word - { + writeObjCMethodCall(yyscanner,ictx); + if (ictx->method) // link to nested call successfully + { + // get the ClassDef representing the method's return type + if (QCString(ictx->method->typeString())=="id") + { + // see if the method name is unique, if so we link to it + MemberName *mn=Doxygen::memberNameLinkedMap->find(ctx->methodName); + //printf("mn->count=%d ictx->method=%s ctx->methodName=%s\n", + // mn==0?-1:(int)mn->count(), + // ictx->method->name().data(), + // ctx->methodName.data()); + if (mn && mn->size()==1) // member name unique + { + ctx->method = mn->front().get(); + } + } + else + { + ctx->objectType = stripClassName(yyscanner,ictx->method->typeString(),yyextra->currentDefinition); + if (ctx->objectType && !ctx->methodName.isEmpty()) + { + ctx->method = ctx->objectType->getMemberByName(ctx->methodName); + } + } + //printf(" ***** method=%s -> object=%p\n",ictx->method->name().data(),ctx->objectType); + } + } + else + { + //printf("Invalid context: id=%d\n",refId); + } + } + else if (nc=='w') // some word + { nc=*p++; - QCString refIdStr; - while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } - p--; - int refId=refIdStr.toInt(); + QCString refIdStr; + while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } + p--; + int refId=refIdStr.toInt(); auto it = yyextra->wordMap.find(refId); - if (it!=yyextra->wordMap.end()) - { + if (it!=yyextra->wordMap.end()) + { QCString word = it->second; codifyLines(yyscanner,word); - } - } + } + } else if (nc=='d') // comment block { nc=*p++; - QCString refIdStr; - while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } - p--; - int refId=refIdStr.toInt(); + QCString refIdStr; + while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; } + p--; + int refId=refIdStr.toInt(); auto it = yyextra->commentMap.find(refId); if (it!=yyextra->commentMap.end()) { - QCString comment = it->second; + QCString comment = it->second; startFontClass(yyscanner,"comment"); - codifyLines(yyscanner,comment); - endFontClass(yyscanner); + codifyLines(yyscanner,comment); + endFontClass(yyscanner); } } - else // illegal marker - { - ASSERT("invalid escape sequence"==0); - } + else // illegal marker + { + ASSERT("invalid escape sequence"==0); + } } } else // normal non-marker character @@ -3811,7 +3811,7 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) } // Replaces an Objective-C method name fragment s by a marker of the form -// $n12, the number (12) can later be used as a key for obtaining the name +// $n12, the number (12) can later be used as a key for obtaining the name // fragment, from yyextra->nameMap static QCString escapeName(yyscan_t yyscanner,const char *s) { @@ -3964,10 +3964,10 @@ void CCodeParser::resetCodeParserState() yyextra->anchorCount = 0; } -void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const QCString &s, +void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const QCString &s, SrcLangExt lang,bool exBlock, const char *exName,FileDef *fd, - int startLine,int endLine,bool inlineFragment, - const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, + int startLine,int endLine,bool inlineFragment, + const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, bool collectXRefs) { yyscan_t yyscanner = p->yyscanner; @@ -4008,7 +4008,7 @@ void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const while (!yyextra->scopeStack.empty()) yyextra->scopeStack.pop(); yyextra->classScope = className; //printf("parseCCode %s\n",className); - yyextra->exampleBlock = exBlock; + yyextra->exampleBlock = exBlock; yyextra->exampleName = exName; yyextra->sourceFileDef = fd; yyextra->lineNumbers = fd!=0 && showLineNumbers; @@ -4021,7 +4021,7 @@ void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const } yyextra->lang = lang; yyextra->insideObjC = lang==SrcLangExt_ObjC; - if (yyextra->sourceFileDef) + if (yyextra->sourceFileDef) { setCurrentDoc(yyscanner,"l00001"); } diff --git a/src/doxygen.cpp b/src/doxygen.cpp index a8cda22..c8ce386 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -145,7 +145,7 @@ QDict *Doxygen::symbolMap = 0; QDict *Doxygen::clangUsrMap = 0; bool Doxygen::outputToWizard=FALSE; QDict * Doxygen::htmlDirMap = 0; -QCache *Doxygen::lookupCache; +Cache *Doxygen::lookupCache; DirSDict *Doxygen::directories; SDict Doxygen::dirRelations(257); ParserManager *Doxygen::parserManager = 0; @@ -8047,15 +8047,20 @@ static void flushCachedTemplateRelations() // as there can be new template instances in the inheritance path // to this class. Optimization: only remove those classes that // have inheritance instances as direct or indirect sub classes. - QCacheIterator ci(*Doxygen::lookupCache); - LookupInfo *li=0; - for (ci.toFirst();(li=ci.current());++ci) + StringVector elementsToRemove; + for (const auto &ci : *Doxygen::lookupCache) { - if (li->classDef) + const LookupInfo &li = ci.second; + if (li.classDef) { - Doxygen::lookupCache->remove(ci.currentKey()); + elementsToRemove.push_back(ci.first); } } + for (const auto &k : elementsToRemove) + { + Doxygen::lookupCache->remove(k); + } + // remove all cached typedef resolutions whose target is a // template class as this may now be a template instance // for each global function name @@ -8099,16 +8104,20 @@ static void flushUnresolvedRelations() // class A { class I {} }; // class B : public A {}; // class C : public B::I {}; - // - QCacheIterator ci(*Doxygen::lookupCache); - LookupInfo *li=0; - for (ci.toFirst();(li=ci.current());++ci) + + StringVector elementsToRemove; + for (const auto &ci : *Doxygen::lookupCache) { - if (li->classDef==0 && li->typeDef==0) + const LookupInfo &li = ci.second; + if (li.classDef==0 && li.typeDef==0) { - Doxygen::lookupCache->remove(ci.currentKey()); + elementsToRemove.push_back(ci.first); } } + for (const auto &k : elementsToRemove) + { + Doxygen::lookupCache->remove(k); + } // for each global function name for (const auto &fn : *Doxygen::functionNameLinkedMap) @@ -10861,8 +10870,7 @@ void parseInput() if (cacheSize<0) cacheSize=0; if (cacheSize>9) cacheSize=9; uint lookupSize = 65536 << cacheSize; - Doxygen::lookupCache = new QCache(lookupSize,lookupSize); - Doxygen::lookupCache->setAutoDelete(TRUE); + Doxygen::lookupCache = new Cache(lookupSize); #ifdef HAS_SIGNALS signal(SIGINT, stopDoxygen); @@ -11691,9 +11699,9 @@ void generateOutput() } int cacheParam; - msg("lookup cache used %d/%d hits=%d misses=%d\n", - Doxygen::lookupCache->count(), + msg("lookup cache used %ld/%ld hits=%lld misses=%lld\n", Doxygen::lookupCache->size(), + Doxygen::lookupCache->capacity(), Doxygen::lookupCache->hits(), Doxygen::lookupCache->misses()); cacheParam = computeIdealCacheParam(Doxygen::lookupCache->misses()*2/3); // part of the cache is flushed, hence the 2/3 correction factor diff --git a/src/doxygen.h b/src/doxygen.h index dc05750..f2b7dda 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -17,7 +17,6 @@ #define DOXYGEN_H #include -#include #include #include #include @@ -29,6 +28,7 @@ #include "dirdef.h" #include "memberlist.h" #include "define.h" +#include "cache.h" #define THREAD_LOCAL thread_local #define AtomicInt std::atomic_int @@ -78,11 +78,11 @@ class StringDict : public QDict struct LookupInfo { - LookupInfo() : classDef(0), typeDef(0) {} + LookupInfo() = default; LookupInfo(const ClassDef *cd,const MemberDef *td,QCString ts,QCString rt) : classDef(cd), typeDef(td), templSpec(ts),resolvedType(rt) {} - const ClassDef *classDef; - const MemberDef *typeDef; + const ClassDef *classDef = 0; + const MemberDef *typeDef = 0; QCString templSpec; QCString resolvedType; }; @@ -127,7 +127,7 @@ class Doxygen static QDict *clangUsrMap; static bool outputToWizard; static QDict *htmlDirMap; - static QCache *lookupCache; + static Cache *lookupCache; static DirSDict *directories; static SDict dirRelations; static ParserManager *parserManager; diff --git a/src/util.cpp b/src/util.cpp index d78c80e..6b30584 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include "util.h" #include "message.h" @@ -1028,7 +1027,6 @@ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Defi } done: accessStack.pop(); - //Doxygen::lookupCache.insert(key,new int(result)); return result; } @@ -1196,7 +1194,6 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop done: //printf(" > result=%d\n",result); accessStack.pop(); - //Doxygen::lookupCache.insert(key,new int(result)); return result; } @@ -1208,7 +1205,7 @@ int computeQualifiedIndex(const QCString &name) static void getResolvedSymbol(const Definition *scope, const FileDef *fileScope, - Definition *d, + const Definition *d, const QCString &explicitScopePart, const std::unique_ptr &actTemplParams, int &minDistance, @@ -1224,7 +1221,7 @@ static void getResolvedSymbol(const Definition *scope, // only look at classes and members that are enums or typedefs if (d->definitionType()==Definition::TypeClass || (d->definitionType()==Definition::TypeMember && - ((dynamic_cast(d))->isTypedef() || (dynamic_cast(d))->isEnumerate()) + ((dynamic_cast(d))->isTypedef() || (dynamic_cast(d))->isEnumerate()) ) ) { @@ -1237,7 +1234,7 @@ static void getResolvedSymbol(const Definition *scope, // see if we are dealing with a class or a typedef if (d->definitionType()==Definition::TypeClass) // d is a class { - ClassDef *cd = dynamic_cast(d); + const ClassDef *cd = dynamic_cast(d); //printf("cd=%s\n",cd->name().data()); if (!cd->isTemplateArgument()) // skip classes that // are only there to @@ -1282,7 +1279,7 @@ static void getResolvedSymbol(const Definition *scope, } else if (d->definitionType()==Definition::TypeMember) { - MemberDef *md = dynamic_cast(d); + const MemberDef *md = dynamic_cast(d); //printf(" member isTypedef()=%d\n",md->isTypedef()); if (md->isTypedef()) // d is a typedef { @@ -1365,6 +1362,8 @@ static void getResolvedSymbol(const Definition *scope, //printf(" bestMatch=%p bestResolvedType=%s\n",bestMatch,bestResolvedType.data()); } +static std::mutex g_cacheMutex; + /* Find the fully qualified class name referred to by the input class * or typedef name against the input scope. * Loops through scope and each of its parent scopes looking for a @@ -1411,7 +1410,7 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, } //printf("Looking for symbol %s\n",name.data()); - DefinitionIntf *di = Doxygen::symbolMap->find(name); + const DefinitionIntf *di = Doxygen::symbolMap->find(name); // the -g (for C# generics) and -p (for ObjC protocols) are now already // stripped from the key used in the symbolMap, so that is not needed here. if (di==0) @@ -1468,26 +1467,30 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, } *p='\0'; - LookupInfo *pval=Doxygen::lookupCache->find(key); - //printf("Searching for %s result=%p\n",key.data(),pval); - if (pval) + LookupInfo *pval = 0; { - //printf("LookupInfo %p %p '%s' %p\n", - // pval->classDef, pval->typeDef, pval->templSpec.data(), - // pval->resolvedType.data()); - if (pTemplSpec) *pTemplSpec=pval->templSpec; - if (pTypeDef) *pTypeDef=pval->typeDef; - if (pResolvedType) *pResolvedType=pval->resolvedType; - //printf("] cachedMatch=%s\n", - // pval->classDef?pval->classDef->name().data():""); - //if (pTemplSpec) - // printf("templSpec=%s\n",pTemplSpec->data()); - return pval->classDef; - } - else // not found yet; we already add a 0 to avoid the possibility of - // endless recursion. - { - Doxygen::lookupCache->insert(key,new LookupInfo); + std::lock_guard lock(g_cacheMutex); + pval=Doxygen::lookupCache->find(key.str()); + //printf("Searching for %s result=%p\n",key.data(),pval); + if (pval) + { + //printf("LookupInfo %p %p '%s' %p\n", + // pval->classDef, pval->typeDef, pval->templSpec.data(), + // pval->resolvedType.data()); + if (pTemplSpec) *pTemplSpec=pval->templSpec; + if (pTypeDef) *pTypeDef=pval->typeDef; + if (pResolvedType) *pResolvedType=pval->resolvedType; + //printf("] cachedMatch=%s\n", + // pval->classDef?pval->classDef->name().data():""); + //if (pTemplSpec) + // printf("templSpec=%s\n",pTemplSpec->data()); + return pval->classDef; + } + else // not found yet; we already add a 0 to avoid the possibility of + // endless recursion. + { + pval = Doxygen::lookupCache->insert(key.str(),LookupInfo()); + } } const ClassDef *bestMatch=0; @@ -1533,18 +1536,14 @@ static const ClassDef *getResolvedClassRec(const Definition *scope, //printf("getResolvedClassRec: bestMatch=%p pval->resolvedType=%s\n", // bestMatch,bestResolvedType.data()); - pval=Doxygen::lookupCache->find(key); if (pval) { + std::lock_guard lock(g_cacheMutex); pval->classDef = bestMatch; pval->typeDef = bestTypedef; pval->templSpec = bestTemplSpec; pval->resolvedType = bestResolvedType; } - else - { - Doxygen::lookupCache->insert(key,new LookupInfo(bestMatch,bestTypedef,bestTemplSpec,bestResolvedType)); - } //printf("] bestMatch=%s distance=%d\n", // bestMatch?bestMatch->name().data():"",minDistance); //if (pTemplSpec) @@ -4487,7 +4486,7 @@ struct FindFileCacheElem bool isAmbig; }; -static QCache g_findFileDefCache(5000); +static Cache g_findFileDefCache(5000); static std::mutex g_findFileDefMutex; @@ -4504,8 +4503,7 @@ FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n,bool &ambig) QCString key = addr; key+=n; - g_findFileDefCache.setAutoDelete(TRUE); - FindFileCacheElem *cachedResult = g_findFileDefCache.find(key); + FindFileCacheElem *cachedResult = g_findFileDefCache.find(key.str()); //printf("key=%s cachedResult=%p\n",key.data(),cachedResult); if (cachedResult) { @@ -4515,7 +4513,7 @@ FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n,bool &ambig) } else { - cachedResult = new FindFileCacheElem(0,FALSE); + cachedResult = g_findFileDefCache.insert(key.str(),FindFileCacheElem(0,FALSE)); } QCString name=QDir::cleanDirPath(n).utf8(); @@ -4543,8 +4541,6 @@ FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n,bool &ambig) if (path.isEmpty() || isSamePath) { cachedResult->fileDef = fd.get(); - g_findFileDefCache.insert(key,cachedResult); - //printf("=1 ===> add to cache %p\n",fd); return fd.get(); } } @@ -4563,12 +4559,10 @@ FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n,bool &ambig) lastMatch=fd; } } - //printf(">1 ===> add to cache %p\n",fd); ambig=(count>1); cachedResult->isAmbig = ambig; cachedResult->fileDef = lastMatch; - g_findFileDefCache.insert(key,cachedResult); return lastMatch; } } @@ -4577,8 +4571,6 @@ FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n,bool &ambig) //printf("not found!\n"); } exit: - //printf("0 ===> add to cache %p: %s\n",cachedResult,n); - g_findFileDefCache.insert(key,cachedResult); //delete cachedResult; return 0; } @@ -4732,9 +4724,9 @@ bool hasVisibleRoot(const BaseClassList *bcl) // note that this function is not reentrant due to the use of static growBuf! QCString escapeCharsInString(const char *name,bool allowDots,bool allowUnderscore) { - static bool caseSenseNames = Config_getBool(CASE_SENSE_NAMES); - static bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES); - static GrowBuf growBuf; + bool caseSenseNames = Config_getBool(CASE_SENSE_NAMES); + bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES); + static THREAD_LOCAL GrowBuf growBuf; growBuf.clear(); if (name==0) return ""; signed char c; -- cgit v0.12