summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2014-10-23 18:33:19 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2014-10-23 18:33:19 (GMT)
commit43edc14cd357dcb070402bccc5030507570c22a4 (patch)
tree05c76a0026b6d1fabe1c3967b041e38b9550f9f7
parent151876a8321204bd2ec08ec6c4de38ba9fb2d034 (diff)
downloadDoxygen-43edc14cd357dcb070402bccc5030507570c22a4.zip
Doxygen-43edc14cd357dcb070402bccc5030507570c22a4.tar.gz
Doxygen-43edc14cd357dcb070402bccc5030507570c22a4.tar.bz2
Introduce new optimized string implementation (attempt 2)
-rw-r--r--qtools/qcstring.cpp618
-rw-r--r--qtools/qcstring.h802
-rw-r--r--qtools/qtools.pro.in3
-rw-r--r--qtools/scstring.cpp798
-rw-r--r--qtools/scstring.h155
-rw-r--r--src/definition.cpp12
-rw-r--r--src/dirdef.h2
-rw-r--r--src/filedef.h2
-rw-r--r--src/htmlgen.cpp43
-rw-r--r--src/membergroup.h2
-rw-r--r--src/util.cpp46
-rw-r--r--src/util.h2
-rw-r--r--src/vhdldocgen.cpp5
-rw-r--r--src/vhdljjparser.cpp6
-rw-r--r--tmake/lib/linux-g++/tmake.conf2
-rw-r--r--tmake/lib/macosx-c++/tmake.conf2
-rw-r--r--vhdlparser/VhdlParserIF.cpp1
17 files changed, 861 insertions, 1640 deletions
diff --git a/qtools/qcstring.cpp b/qtools/qcstring.cpp
index 4038d55..16c168b 100644
--- a/qtools/qcstring.cpp
+++ b/qtools/qcstring.cpp
@@ -3,8 +3,8 @@
* Copyright (C) 1997-2004 by Dimitri van Heesch.
*
* Permission to use, copy, modify, and distribute this software and its
- * documentation under the terms of the GNU General Public License is hereby
- * granted. No representations are made about the suitability of this software
+ * 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.
*
@@ -24,281 +24,146 @@
#include <qregexp.h>
#include <qdatastream.h>
-
-QCString::QCString(int size)
-{
- if (size>0)
- {
- m_data = (char *)malloc(size);
- if (m_data)
- {
- if (size>1) memset(m_data,' ',size-1);
- m_data[size-1]='\0';
- }
- }
- else
- {
- m_data=0;
- }
-}
-
-QCString::QCString( const QCString &s )
-{
- duplicate(s);
-}
-
-QCString::QCString( const char *str )
-{
- duplicate(str);
-}
-
-QCString::QCString( const char *str, uint maxlen )
-{
- uint l;
- if (str && ( l = QMIN(qstrlen(str),maxlen) ))
- {
- m_data=(char *)malloc(l+1);
- strncpy(m_data,str,l+1);
- m_data[l]='\0';
- }
- else
- {
- m_data=0;
- }
-}
-
-QCString::~QCString()
-{
- if (m_data) free(m_data);
- m_data=0;
-}
-
-QCString &QCString::assign( const char *str )
+QCString &QCString::sprintf( const char *format, ... )
{
- if (m_data) free(m_data);
- duplicate(str);
+ va_list ap;
+ va_start( ap, format );
+ const int minlen=256;
+ if (length()<minlen) resize(minlen);
+ vsnprintf( data(), minlen, format, ap);
+ resize(strlen(data())+1);
+ va_end( ap );
return *this;
}
-bool QCString::resize( uint newlen )
+int QCString::find( char c, int index, bool cs ) const
{
- if (newlen==0)
- {
- if (m_data) { free(m_data); m_data=0; }
- return TRUE;
- }
- if (m_data==0) // newlen>0
+ if (index<0 || index>=(int)length()) return -1; // index outside string
+ register const char *pos;
+ if (cs)
{
- m_data = (char *)malloc(newlen);
+ pos = strchr(data()+index,c);
}
else
{
- m_data = (char *)realloc(m_data,newlen);
+ pos = data()+index;
+ c = tolower((unsigned char)c);
+ while (*pos && tolower((unsigned char)*pos)!=c) pos++;
+ if (!*pos && c) pos=0; // not found
}
- if (m_data==0) return FALSE;
- m_data[newlen-1]='\0';
- return TRUE;
+ return pos ? (int)(pos - data()) : -1;
}
-bool QCString::fill( char c, int len )
+int QCString::find( const char *str, int index, bool cs ) const
{
- uint l=length();
- if (len<0) len=l;
- if ((uint)len!=l)
+ int l = length();
+ if (index<0 || index>=l) return -1; // index outside string
+ if (!str) return -1; // no string to search for
+ if (!*str) return index; // empty string matching at index
+ register char *pos;
+ if (cs) // case sensitive
{
- if (m_data) free(m_data);
- if (len>0)
- {
- m_data=(char *)malloc(len+1);
- if (m_data==0) return FALSE;
- m_data[len]='\0';
- }
- else
- {
- m_data=0;
- }
+ pos = strstr(data()+index,str);
}
- if (len>0)
+ else // case insensitive
{
- uint i;
- for (i=0;i<(uint)len;i++) m_data[i]=c;
- }
- return TRUE;
-}
-
-QCString &QCString::sprintf( const char *format, ... )
-{
- va_list ap;
- va_start( ap, format );
- uint l = length();
- const uint minlen=256;
- if (l<minlen)
- {
- if (m_data)
- m_data = (char *)realloc(m_data,minlen);
- else
- m_data = (char *)malloc(minlen);
- }
- vsprintf( m_data, format, ap );
- resize( qstrlen(m_data) + 1 ); // truncate
- va_end( ap );
- return *this;
-}
-
-
-int QCString::find( char c, int index, bool cs ) const
-{
- uint len = length();
- if ( m_data==0 || (uint)index>len ) // index outside string
- return -1;
- register const char *d;
- if ( cs ) // case sensitive
- {
- d = strchr( m_data+index, c );
- }
- else
- {
- d = m_data+index;
- c = tolower( (uchar) c );
- while ( *d && tolower((uchar) *d) != c )
- d++;
- if ( !*d && c ) // not found
- d = 0;
- }
- return d ? (int)(d - m_data) : -1;
-}
-
-int QCString::find( const char *str, int index, bool cs ) const
-{
- uint l = length();
- if ( m_data==0 || (uint)index > l ) // index outside string
- return -1;
- if ( !str ) // no search string
- return -1;
- if ( !*str ) // zero-length search string
- return index;
- register const char *d;
- if ( cs ) // case sensitive
- {
- d = strstr( m_data+index, str );
- }
- else // case insensitive
- {
- d = m_data+index;
- int len = qstrlen( str );
- while ( *d )
+ pos = data();
+ int len = strlen(str);
+ while (*pos)
{
- if ( qstrnicmp(d, str, len) == 0 )
- break;
- d++;
+ if (strncasecmp(pos,str,len)==0) break;
+ pos++;
}
- if ( !*d ) // not found
- d = 0;
+ if (!*pos) pos = 0; // not found
}
- return d ? (int)(d - m_data) : -1;
+ return pos ? (int)(pos - data()) : -1;
}
-int QCString::find( const QCString &str,int index,bool cs) const
+int QCString::find( const QCString &str, int index, bool cs ) const
{
return find(str.data(),index,cs);
}
int QCString::find( const QRegExp &rx, int index ) const
{
- QString d = QString::fromLatin1( m_data );
+ QString d = QString::fromLatin1( data() );
return d.find( rx, index );
}
int QCString::findRev( char c, int index, bool cs) const
{
- const char *b = m_data;
- const char *d;
- uint len = length();
- if ( b == 0 ) return -1; // empty string
- if ( index < 0 ) // neg index ==> start from end
+ const char *b = data();
+ const char *pos;
+ int len = length();
+ if (len==0) return -1; // empty string
+ if (index<0) // start from end
{
- if ( len == 0 ) return -1;
- if ( cs )
+ if (cs)
{
- d = strrchr( b, c );
- return d ? (int)(d - b) : -1;
+ pos = strrchr(b,c);
+ return pos ? (int)(pos - b) : -1;
}
- index = len;
- }
- else if ( (uint)index > len ) // bad index
- {
+ index=len;
+ }
+ else if (index>len) // bad index
+ {
return -1;
}
- d = b+index;
- if ( cs ) // case sensitive
+ pos = b+index;
+ if (cs)
{
- while ( d >= b && *d != c )
- d--;
- }
- else // case insensitive
+ while ( pos>=b && *pos!=c) pos--;
+ }
+ else
{
- c = tolower( (uchar) c );
- while ( d >= b && tolower((uchar) *d) != c )
- d--;
+ c = tolower((unsigned char)c);
+ while ( pos>=b && tolower((unsigned char)*pos)!=c) pos--;
}
- return d >= b ? (int)(d - b) : -1;
+ return pos>=b ? (int)(pos - b) : -1;
}
int QCString::findRev( const char *str, int index, bool cs) const
{
- int slen = qstrlen(str);
- uint len = length();
- if ( index < 0 ) // neg index ==> start from end
- index = len-slen;
- else if ( (uint)index > len ) // bad index
- return -1;
- else if ( (uint)(index + slen) > len ) // str would be too long
- index = len - slen;
- if ( index < 0 )
- return -1;
-
- register char *d = m_data + index;
- if ( cs ) // case sensitive
- {
- for ( int i=index; i>=0; i-- )
- if ( qstrncmp(d--,str,slen)==0 )
- return i;
- }
- else // case insensitive
- {
- for ( int i=index; i>=0; i-- )
- if ( qstrnicmp(d--,str,slen)==0 )
- return i;
+ int slen = strlen(str);
+ int len = length();
+ if (index<0) index = len-slen; // start from end
+ else if (index>len) return -1; // bad index
+ else if (index+slen>len) index=len-slen; // str would be too long
+ if (index<0) return -1; // no match possible
+ register char *pos = data()+index;
+ if (cs) // case sensitive
+ {
+ for (int i=index; i>=0; i--) if (strncmp(pos--,str,slen)==0) return i;
+ }
+ else // case insensitive
+ {
+ for (int i=index; i>=0; i--) if (strncasecmp(pos,str,slen)==0) return i;
}
return -1;
-
}
int QCString::findRev( const QRegExp &rx, int index ) const
{
- QString d = QString::fromLatin1( m_data );
+ QString d = QString::fromLatin1( data() );
return d.findRev( rx, index );
}
int QCString::contains( char c, bool cs ) const
{
- int count = 0;
- char *d = m_data;
- if ( !d )
- return 0;
- if ( cs ) // case sensitive
- {
- while ( *d )
- if ( *d++ == c )
- count++;
- }
- else // case insensitive
- {
- c = tolower( (uchar) c );
- while ( *d ) {
- if ( tolower((uchar) *d) == c )
- count++;
- d++;
+ if (length()==0) return 0;
+ int count=0;
+ const char *pos = data();
+ if (cs)
+ {
+ while (*pos) if (*pos++ == c) count++;
+ }
+ else
+ {
+ c = tolower((unsigned char)c);
+ while (*pos)
+ {
+ if (tolower((unsigned char)*pos)==c) count++;
+ pos++;
}
}
return count;
@@ -306,96 +171,106 @@ int QCString::contains( char c, bool cs ) const
int QCString::contains( const char *str, bool cs ) const
{
- int count = 0;
- char *d = data();
- if ( !d )
- return 0;
- int len = qstrlen( str );
- while ( *d ) // counts overlapping strings
+ if (str==0 || length()==0) return 0;
+ int count=0;
+ const char *pos = data();
+ int len = strlen(str);
+ while (*pos)
{
- if ( cs )
+ if (cs)
{
- if ( qstrncmp( d, str, len ) == 0 )
- count++;
- }
- else
+ if (strncmp(pos,str,len)==0) count++;
+ }
+ else
{
- if ( qstrnicmp(d, str, len) == 0 )
- count++;
+ if (strncasecmp(pos,str,len)==0) count++;
}
- d++;
+ pos++;
}
return count;
}
int QCString::contains( const QRegExp &rx ) const
-{
- QString d = QString::fromLatin1( m_data );
+{
+ QString d = QString::fromLatin1( data() );
return d.contains( rx );
}
+bool QCString::stripPrefix(const char *prefix)
+{
+ if (prefix==0 || length()==0) return FALSE;
+ int len = strlen(prefix);
+ if (strncmp(prefix,data(),len)==0)
+ {
+ int newlen = length()-len+1;
+ qmemmove(data(),data()+len,newlen);
+ resize(newlen);
+ return TRUE;
+ }
+ return FALSE;
+}
+
QCString QCString::left( uint len ) const
{
- if ( isEmpty() )
+ if (isEmpty())
{
return QCString();
- }
- else if ( len >= length() )
+ }
+ else if (len>=length())
{
- return *this;
- }
- else
+ return QCString(data());
+ }
+ else
{
QCString s( len+1 );
- strncpy( s.data(), m_data, len );
- *(s.data()+len) = '\0';
+ memcpy( s.data(), data(), len);
return s;
}
}
QCString QCString::right( uint len ) const
{
- if ( isEmpty() )
+ if (isEmpty())
{
return QCString();
- }
- else
+ }
+ else
{
- uint l = length();
- if ( len > l ) len = l;
- char *p = m_data + (l - len);
- return QCString( p );
- }
+ int l = length();
+ if ((int)len>l) len=l;
+ const char *pos = data() + (l-len);
+ return QCString(pos);
+ }
}
QCString QCString::mid( uint index, uint len) const
{
- uint slen = length();
- if ( len == 0xffffffff ) len = slen-index;
- if ( isEmpty() || index >= slen )
+ int slen = length();
+ if (len==0xffffffff) len = slen-index;
+ if (isEmpty() || (int)index>=slen)
{
return QCString();
- }
- else
+ }
+ else
{
register char *p = data()+index;
- QCString s( len+1 );
- strncpy( s.data(), p, len );
- *(s.data()+len) = '\0';
+ QCString s(len+1);
+ memcpy(s.data(),p,len);
return s;
}
}
QCString QCString::lower() const
{
- QCString s( m_data );
- register char *p = s.data();
- if ( p )
+ if (length()==0) return QCString();
+ QCString s(data());
+ register char *pos = s.data();
+ if (pos)
{
- while ( *p )
+ while (*pos)
{
- *p = tolower((uchar) *p);
- p++;
+ *pos = tolower((unsigned char)*pos);
+ pos++;
}
}
return s;
@@ -403,41 +278,44 @@ QCString QCString::lower() const
QCString QCString::upper() const
{
- QCString s( m_data );
- register char *p = s.data();
- if ( p ) {
- while ( *p ) {
- *p = toupper((uchar)*p);
- p++;
+ if (length()==0) return QCString();
+ QCString s(data());
+ register char *pos = s.data();
+ if (pos)
+ {
+ while (*pos)
+ {
+ *pos = toupper((unsigned char)*pos);
+ pos++;
}
}
return s;
}
-QCString QCString::stripWhiteSpace() const
+QCString QCString::stripWhiteSpace() const
{
if ( isEmpty() ) // nothing to do
return *this;
- register char *s = m_data;
+ register char *s = data();
int reslen = length();
- if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
- return *this; // returns a copy
+ if ( !isspace((uchar)s[0]) && !isspace((uchar)s[reslen-1]) )
+ return *this; // returns a copy
QCString result(s);
- s = result.data();
+ s = result.data();
int start = 0;
int end = reslen - 1;
while ( isspace((uchar) s[start]) ) // skip white space from start
- start++;
- if ( s[start] == '\0' )
+ start++;
+ if ( s[start] == '\0' )
{ // only white space
return QCString();
}
while ( end && isspace((uchar) s[end]) ) // skip white space from end
end--;
end -= start - 1;
- memmove( result.data(), &s[start], end );
+ qmemmove( result.data(), &s[start], end );
result.resize( end + 1 );
return result;
}
@@ -451,7 +329,7 @@ QCString QCString::simplifyWhiteSpace() const
char *from = data();
char *to = result.data();
char *first = to;
- while ( TRUE )
+ while ( TRUE )
{
while ( *from && isspace((uchar) *from) )
from++;
@@ -469,84 +347,66 @@ QCString QCString::simplifyWhiteSpace() const
return result;
}
+QCString &QCString::assign( const char *str )
+{
+ return operator=(str);
+}
+
QCString &QCString::insert( uint index, const char *s )
-{
+{
int len = s ? qstrlen(s) : 0;
- if ( len == 0 )
- return *this;
- uint olen = length();
- int nlen = olen + len;
- if ( index >= olen ) // insert after end of string
- {
- m_data = (char *)realloc(m_data,nlen+index-olen+1);
- if ( m_data )
- {
- memset( m_data+olen, ' ', index-olen );
- memcpy( m_data+index, s, len+1 );
- }
- }
- else if ( (m_data = (char *)realloc(m_data,nlen+1)) ) // normal insert
- {
- memmove( m_data+index+len, m_data+index, olen-index+1 );
- memcpy( m_data+index, s, len );
+ if ( len == 0 ) return *this;
+ int olen = length();
+ int nlen = olen + len;
+ if ((int)index>=olen)
+ {
+ resize(nlen+index-olen+1);
+ memset(data()+olen, ' ', index-olen);
+ memcpy(data()+index,s, len+1);
+ }
+ else
+ {
+ resize(nlen+1);
+ qmemmove(data()+index+len,data()+index,olen-index+1);
+ memcpy(data()+index,s,len);
}
return *this;
}
-QCString &QCString::insert( uint index, char c ) // insert char
+QCString &QCString::insert( uint index, char c)
{
char buf[2];
buf[0] = c;
buf[1] = '\0';
return insert( index, buf );
}
-
-QCString& QCString::operator+=( const char *str )
+QCString &QCString::append( const char *s )
{
- if ( !str ) return *this; // nothing to append
- uint len1 = length();
- uint len2 = qstrlen(str);
- char *newData = (char *)realloc( m_data, len1 + len2 + 1 );
- if (newData)
- {
- m_data = newData;
- memcpy( m_data + len1, str, len2 + 1 );
- }
- return *this;
+ return operator+=(s);
}
-
-QCString &QCString::operator+=( char c )
+QCString &QCString::prepend( const char *s )
{
- uint len = length();
- char *newData = (char *)realloc( m_data, length()+2 );
- if (newData)
- {
- m_data = newData;
- m_data[len] = c;
- m_data[len+1] = '\0';
- }
- return *this;
+ return insert(0,s);
}
-
QCString &QCString::remove( uint index, uint len )
{
uint olen = length();
if ( index + len >= olen ) // range problems
- {
+ {
if ( index < olen ) // index ok
- {
+ {
resize( index+1 );
}
- }
- else if ( len != 0 )
+ }
+ else if ( len != 0 )
{
- memmove( m_data+index, m_data+index+len, olen-index-len+1 );
+ qmemmove( data()+index, data()+index+len, olen-index-len+1 );
resize( olen-len+1 );
}
return *this;
}
-QCString &QCString::replace( uint index, uint len, const char *s )
+QCString &QCString::replace( uint index, uint len, const char *s)
{
remove( index, len );
insert( index, s );
@@ -555,65 +415,85 @@ QCString &QCString::replace( uint index, uint len, const char *s )
QCString &QCString::replace( const QRegExp &rx, const char *str )
{
- QString d = QString::fromLatin1( m_data );
+ QString d = QString::fromLatin1( data() );
QString r = QString::fromLatin1( str );
d.replace( rx, r );
operator=( d.ascii() );
return *this;
}
-long QCString::toLong( bool *ok ) const
+short QCString::toShort(bool *ok) const
+{
+ QString s(data());
+ return s.toShort(ok);
+}
+
+ushort QCString::toUShort(bool *ok) const
+{
+ QString s(data());
+ return s.toUShort(ok);
+}
+
+int QCString::toInt(bool *ok) const
+{
+ QString s(data());
+ return s.toInt(ok);
+}
+
+uint QCString::toUInt(bool *ok) const
+{
+ QString s(data());
+ return s.toUInt(ok);
+}
+
+long QCString::toLong(bool *ok) const
{
- QString s(m_data);
+ QString s(data());
return s.toLong(ok);
}
-ulong QCString::toULong( bool *ok ) const
+ulong QCString::toULong(bool *ok) const
{
- QString s(m_data);
+ QString s(data());
return s.toULong(ok);
}
-short QCString::toShort( bool *ok ) const
+QCString &QCString::setNum(short n)
{
- QString s(m_data);
- return s.toShort(ok);
+ return setNum((long)n);
}
-ushort QCString::toUShort( bool *ok ) const
+QCString &QCString::setNum(ushort n)
{
- QString s(m_data);
- return s.toUShort(ok);
+ return setNum((ulong)n);
}
-int QCString::toInt( bool *ok ) const
+QCString &QCString::setNum(int n)
{
- QString s(m_data);
- return s.toInt(ok);
+ return setNum((long)n);
}
-uint QCString::toUInt( bool *ok ) const
+QCString &QCString::setNum(uint n)
{
- QString s(m_data);
- return s.toUInt(ok);
+ return setNum((ulong)n);
}
-QCString &QCString::setNum( long n )
+QCString &QCString::setNum(long n)
{
char buf[20];
register char *p = &buf[19];
bool neg;
- if ( n < 0 )
+ if ( n < 0 )
{
neg = TRUE;
n = -n;
- }
- else
+ }
+ else
{
neg = FALSE;
}
*p = '\0';
- do
+ do
{
*--p = ((int)(n%10)) + '0';
n /= 10;
@@ -623,12 +503,12 @@ QCString &QCString::setNum( long n )
return *this;
}
-QCString &QCString::setNum( ulong n )
+QCString &QCString::setNum( ulong n)
{
char buf[20];
register char *p = &buf[19];
*p = '\0';
- do
+ do
{
*--p = ((int)(n%10)) + '0';
n /= 10;
@@ -637,31 +517,7 @@ QCString &QCString::setNum( ulong n )
return *this;
}
-void QCString::msg_index( uint index )
-{
-#if defined(CHECK_RANGE)
- qWarning( "QCString::at: Absolute index %d out of range", index );
-#else
- Q_UNUSED( index )
-#endif
-}
-
-bool QCString::stripPrefix(const char *prefix)
-{
- if (prefix==0) return FALSE;
- uint plen = qstrlen(prefix);
- if (m_data && qstrncmp(prefix,m_data,plen)==0) // prefix matches
- {
- uint len = qstrlen(m_data);
- uint newlen = len-plen+1;
- qmemmove(m_data,m_data+plen,newlen);
- resize(newlen);
- return TRUE;
- }
- return FALSE;
-}
-
-//---------------------------------------------------------------------------
+//-------------------------------------------------
void *qmemmove( void *dst, const void *src, uint len )
{
diff --git a/qtools/qcstring.h b/qtools/qcstring.h
index f7d2c95..6930718 100644
--- a/qtools/qcstring.h
+++ b/qtools/qcstring.h
@@ -1,38 +1,16 @@
/****************************************************************************
-**
**
-** Definition of the extended char array operations,
-** and QByteArray and QCString classes
+** Copyright (C) 1997-2004 by Dimitri van Heesch.
**
-** Created : 920609
+** 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.
**
-** 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.
+** Note: this is a reimplementation of the qcstring.h that came with
+** an Qt version 2.2.3. For short strings it stores the string data inside
+** the object. For long strings it uses a separate array with reference counting.
**
**********************************************************************/
@@ -43,6 +21,7 @@
#include "qarray.h"
#endif // QT_H
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -54,6 +33,7 @@
#include <strings.h>
#endif
+#include <assert.h>
class QGString;
@@ -77,7 +57,6 @@ inline char *hack_strrchr( const char *s, int c )
#define strrchr(s,c) hack_strrchr((s),(c))
#endif
-
/*****************************************************************************
Safe and portable C string functions; extensions to standard string.h
*****************************************************************************/
@@ -127,39 +106,6 @@ Q_EXPORT int qstricmp( const char *str1, const char *str2 );
Q_EXPORT int qstrnicmp( const char *str1, const char *str2, uint len );
-#if 0
-// ### TODO for 3.0: these and the cstr* functions should be used if
-// !defined(QT_CLEAN_NAMESPACE)
-// We want to keep source compatibility for 2.x
-// ### TODO for 4.0: completely remove these and the cstr* functions
-
-#if !defined(QT_GENUINE_STR)
-
-#undef strlen
-#define strlen qstrlen
-
-#undef strcpy
-#define strcpy qstrcpy
-
-#undef strcmp
-#define strcmp qstrcmp
-
-#undef strncmp
-#define strncmp qstrncmp
-
-#undef stricmp
-#define stricmp qstricmp
-
-#undef strnicmp
-#define strnicmp qstrnicmp
-
-#endif
-#endif
-
-// qChecksum: Internet checksum
-
-Q_EXPORT Q_UINT16 qChecksum( const char *s, uint len );
-
/*****************************************************************************
QByteArray class
*****************************************************************************/
@@ -169,7 +115,6 @@ template class Q_EXPORT QArray<char>;
#endif
typedef QArray<char> QByteArray;
-
/*****************************************************************************
QByteArray stream functions
*****************************************************************************/
@@ -181,142 +126,556 @@ Q_EXPORT QDataStream &operator>>( QDataStream &, QByteArray & );
class QRegExp;
/** This is an alternative implementation of QCString. It provides basically
- * the same functions but uses less memory for administration. This class
- * is just a wrapper around a plain C string requiring only 4 bytes "overhead".
- * QCString features sharing of data and stores the string length, but
- * requires 4 + 12 bytes for this (even for the empty string). As doxygen
- * uses a LOT of string during a run it saves a lot of memory to use a
- * more memory efficient implementation at the cost of relatively low
- * runtime overhead.
+ * the same functions but uses reference counting and copy on write.
*/
-class QCString
+class QCString
{
public:
- QCString() : m_data(0) {} // make null string
- QCString( const QCString &s );
- QCString( int size );
- QCString( const char *str );
- QCString( const char *str, uint maxlen );
- ~QCString();
-
- QCString &operator=( const QCString &s );// deep copy
- QCString &operator=( const char *str ); // deep copy
-
- bool isNull() const;
- bool isEmpty() const;
- uint length() const;
- uint size() const { return m_data ? length()+1 : 0; }
- char * data() const { return m_data; }
- bool resize( uint newlen );
- bool truncate( uint pos );
- bool fill( char c, int len = -1 );
-
- QCString copy() const;
-
- QCString &sprintf( const char *format, ... );
-
- int find( char c, int index=0, bool cs=TRUE ) const;
- int find( const char *str, int index=0, bool cs=TRUE ) const;
- int find( const QCString &str, int index=0, bool cs=TRUE ) const;
- int find( const QRegExp &, int index=0 ) const;
- int findRev( char c, int index=-1, bool cs=TRUE) const;
- int findRev( const char *str, int index=-1, bool cs=TRUE) const;
- int findRev( const QRegExp &, int index=-1 ) const;
- int contains( char c, bool cs=TRUE ) const;
- int contains( const char *str, bool cs=TRUE ) const;
- int contains( const QRegExp & ) const;
- bool stripPrefix(const char *prefix);
-
- QCString left( uint len ) const;
- QCString right( uint len ) const;
- QCString mid( uint index, uint len=0xffffffff) const;
-
- QCString lower() const;
- QCString upper() const;
-
- QCString stripWhiteSpace() const;
- QCString simplifyWhiteSpace() const;
-
- QCString &assign( const char *str );
- QCString &insert( uint index, const char * );
- QCString &insert( uint index, char );
- QCString &append( const char *s );
- QCString &prepend( const char *s );
- QCString &remove( uint index, uint len );
- QCString &replace( uint index, uint len, const char * );
- QCString &replace( const QRegExp &, const char * );
-
- short toShort( bool *ok=0 ) const;
- ushort toUShort( bool *ok=0 ) const;
- int toInt( bool *ok=0 ) const;
- uint toUInt( bool *ok=0 ) const;
- long toLong( bool *ok=0 ) const;
- ulong toULong( bool *ok=0 ) const;
-
- QCString &setNum( short );
- QCString &setNum( ushort );
- QCString &setNum( int );
- QCString &setNum( uint );
- QCString &setNum( long );
- QCString &setNum( ulong );
- QCString &setNum( float, char f='g', int prec=6 );
- QCString &setNum( double, char f='g', int prec=6 );
-
- operator const char *() const;
- QCString &operator+=( const char *str );
- QCString &operator+=( char c );
- char &at( uint index ) const;
- char &operator[]( int i ) const { return at(i); }
-
- private:
- static void msg_index( uint );
- void duplicate( const QCString &s );
- void duplicate( const char *str);
- QCString &duplicate( const char *str, int);
-
- char * m_data;
-};
-
-inline char &QCString::at( uint index ) const
-{
- return m_data[index];
-}
+ /** creates an empty string */
+ QCString() : m_rep()
+ {
+ }
+
+ /** destroys the string */
+ ~QCString()
+ {
+ }
+
+ /** makes a copy of a string. */
+ QCString( const QCString &s ) : m_rep(s.m_rep)
+ {
+ }
+
+ /** creates a string with room for size characters
+ * @param[in] size the number of character to allocate (including the 0-terminator)
+ */
+ QCString( int size ) : m_rep(size)
+ {
+ }
+
+ /** creates a string from a plain C string.
+ * @param[in] str A zero terminated C string. When 0 an empty string is created.
+ */
+ QCString( const char *str ) : m_rep(str)
+ {
+ }
+
+ /** creates a string from \a str and copies over the first \a maxlen characters. */
+ QCString( const char *str, uint maxlen ) : m_rep(str,maxlen)
+ {
+ }
+
+ /** replaces the contents by that of string \a s. */
+ QCString &operator=( const QCString &s )
+ {
+ m_rep = s.m_rep;
+ return *this;
+ }
+
+ /** replaces the contents by that of C string \a str. */
+ QCString &operator=( const char *str)
+ {
+ m_rep = str;
+ return *this;
+ }
+
+ /** Returns TRUE iff the string is empty. Equivalent to isEmpty(). */
+ bool isNull() const
+ {
+ return m_rep.isEmpty();
+ }
+
+ /** Returns TRUE iff the string is empty */
+ bool isEmpty() const
+ {
+ return m_rep.isEmpty();
+ }
+
+ /** Returns the length of the string, excluding the 0-terminator. Equivalent to size(). */
+ uint length() const
+ {
+ return m_rep.length();
+ }
+
+ /** Returns the length of the string, excluding the 0-terminator. */
+ uint size() const
+ {
+ return m_rep.length();
+ }
+
+ /** Returns a pointer to the contents of the string in the form of a 0-terminated C string */
+ char *data() const
+ {
+ return m_rep.data();
+ }
+
+ /** Resizes the string to hold \a newlen characters
+ * (this value should include the 0-terminator). If the string is enlarged the contents will
+ * be left unmodified.
+ */
+ bool resize( uint newlen )
+ {
+ m_rep.resize(newlen);
+ return TRUE;
+ }
+
+ /** Truncates the string at position \a pos. */
+ bool truncate( uint pos )
+ {
+ return resize(pos+1);
+ }
+
+ /** Fills a string with a predefined character
+ * @param[in] c the character used to fill the string with.
+ * @param[in] len the number of character to fill. Use -1 to fill the whole string.
+ * @note the string will be resized to contain \a len characters. The contents of the
+ * string will be lost.
+ */
+ bool fill( char c, int len = -1 )
+ {
+ m_rep.fill(c,len);
+ return TRUE;
+ }
+
+ /** Returns a deep copy of the string. */
+ QCString copy() const
+ {
+ if (length()==0) return QCString();
+ QCString cs(length()+1);
+ memcpy(cs.data(),data(),length());
+ return cs;
+ }
+
+ QCString &sprintf( const char *format, ... );
+ int find( char c, int index=0, bool cs=TRUE ) const;
+ int find( const char *str, int index=0, bool cs=TRUE ) const;
+ int find( const QCString &str, int index=0, bool cs=TRUE ) const;
+ int find( const QRegExp &rx, int index=0 ) const;
+ int findRev( char c, int index=-1, bool cs=TRUE) const;
+ int findRev( const char *str, int index=-1, bool cs=TRUE) const;
+ int findRev( const QRegExp &rx, int index=-1 ) const;
+ int contains( char c, bool cs=TRUE ) const;
+ int contains( const char *str, bool cs=TRUE ) const;
+ int contains( const QRegExp &rx ) const;
+ bool stripPrefix(const char *prefix);
+ QCString left( uint len ) const;
+ QCString right( uint len ) const;
+ QCString mid( uint index, uint len=0xffffffff) const;
+ QCString lower() const;
+ QCString upper() const;
+ QCString stripWhiteSpace() const;
+ QCString simplifyWhiteSpace() const;
+ QCString &assign( const char *str );
+ QCString &insert( uint index, const char *s );
+ QCString &insert( uint index, char c);
+ QCString &append( const char *s );
+ QCString &prepend( const char *s );
+ QCString &remove( uint index, uint len );
+ QCString &replace( uint index, uint len, const char *s);
+ QCString &replace( const QRegExp &rx, const char *str );
+ short toShort( bool *ok=0 ) const;
+ ushort toUShort( bool *ok=0 ) const;
+ int toInt( bool *ok=0 ) const;
+ uint toUInt( bool *ok=0 ) const;
+ long toLong( bool *ok=0 ) const;
+ ulong toULong( bool *ok=0 ) const;
+ QCString &setNum(short n);
+ QCString &setNum(ushort n);
+ QCString &setNum(int n);
+ QCString &setNum(uint n);
+ QCString &setNum(long n);
+ QCString &setNum(ulong n);
+
+ /** Converts the string to a plain C string */
+ operator const char *() const
+ {
+ return (const char *)data();
+ }
+
+ /** Appends string \a str to this string and returns a reference to the result. */
+ QCString &operator+=( const char *str )
+ {
+ if (!str) return *this;
+ int len1 = length();
+ int len2 = strlen(str);
+ resize(len1+len2+1);
+ memcpy(data()+len1,str,len2);
+ return *this;
+ }
+
+ /** Appends character \a c to this string and returns a reference to the result. */
+ QCString &operator+=( char c )
+ {
+ int len = length();
+ resize(len+2);
+ data()[len]=c;
+ return *this;
+ }
+
+ /** Returns a reference to the character at index \a i. */
+ char &at( uint i) const
+ {
+ return m_rep.at(i);
+ }
+
+ /** Indexing operator. Equavalent to at(). */
+ char &operator[]( int i ) const
+ {
+ return m_rep.at((uint)i);
+ }
-inline void QCString::duplicate( const QCString &s )
-{
- if (!s.isEmpty())
- {
- uint l = (uint)strlen(s.data());
- m_data = (char *)malloc(l+1);
- if (m_data) memcpy(m_data,s.data(),l+1);
- }
- else
- {
- m_data=0;
- }
-}
+ private:
-inline void QCString::duplicate( const char *str)
-{
- if (str && str[0]!='\0')
- {
- uint l = (uint)strlen(str);
- m_data = (char *)malloc(l+1);
- if (m_data) memcpy(m_data,str,l+1);
- }
- else
- {
- m_data=0;
- }
-}
+ struct LSData;
+
+ // long string representation
+ struct LongStringRep
+ {
+ uchar isShort; // : 1; // should be shared with ShortStringRep
+ //uchar : 7;
+ LSData *d;
+ };
+
+#define SHORT_STR_CAPACITY ((int)sizeof(LongStringRep)-2)
+#define SHORT_STR_MAX_LEN (SHORT_STR_CAPACITY-1)
+
+ // short string representation
+ struct ShortStringRep
+ {
+ uchar isShort; // : 1; // should be shared with LongStringRep
+ uchar len; // : 7;
+ char str[SHORT_STR_CAPACITY]; // size including 0-terminator
+ };
+
+ // ref counting string header
+ struct LSHeader
+ {
+ int len; // length of string without 0 terminator
+ int refCount; // -1=leaked, 0=one ref & non-cost, n>0, n+1 refs, const
+ };
+ // ref counting string data and methods
+ struct LSData : public LSHeader
+ {
+ char *toStr()
+ {
+ return (char*)(this+1); // string data starts after the header
+ }
+
+ // creates a LSData item with room for size bytes (which includes the 0 terminator!)
+ // if size is zero, an empty string will be created.
+ static LSData *create(int size)
+ {
+ LSData *data;
+ data = (LSData*)malloc(sizeof(LSHeader)+size);
+ data->len = size-1;
+ data->refCount = 0;
+ data->toStr()[size-1] = 0;
+ return data;
+ }
+ // remove out reference to the data. Frees memory if no more users
+ void dispose()
+ {
+ if (--refCount<0) free(this);
+ }
+
+ // resizes LSData so it can hold size bytes (which includes the 0 terminator!)
+ // Since this is for long strings only, size should be > SHORT_STR_CAPACITY
+ static LSData *resize(LSData *d,int size)
+ {
+ if (d->len>0 && d->refCount==0) // non-const, non-empty
+ {
+ d = (LSData*)realloc(d,sizeof(LSHeader)+size);
+ d->len = size-1;
+ d->toStr()[size-1] = 0;
+ return d;
+ }
+ else // need to make a copy
+ {
+ LSData *newData = LSData::create(size);
+ int len = d->len;
+ if (len>=size) len=size-1;
+ memcpy(newData->toStr(),d->toStr(),len);
+ newData->toStr()[len]=0;
+ d->dispose();
+ return newData;
+ }
+ }
+ };
+
+ class StringRep
+ {
+ public:
+ StringRep()
+ {
+ initEmpty();
+ }
+ void initEmpty()
+ {
+ u.s.isShort=TRUE;
+ u.s.len=0;
+ //memset(u.s.str,0,SHORT_STR_CAPACITY);
+ }
+ ~StringRep()
+ {
+ if (!u.s.isShort)
+ {
+ u.l.d->dispose();
+ }
+ }
+ StringRep(const StringRep &s)
+ {
+ if (&s!=this)
+ {
+ u.s.isShort = s.u.s.isShort;
+ if (s.u.s.isShort)
+ {
+ u.s.len = s.u.s.len;
+ memcpy(u.s.str,s.u.s.str,s.u.s.len+1);
+ }
+ else
+ {
+ u.l.d = s.u.l.d;
+ u.l.d->refCount++;
+ }
+ }
+ else // self-assignment
+ {
+ u = s.u; // avoid uninitialized warning from gcc
+ }
+ }
+ StringRep(int size)
+ {
+ u.s.isShort = size<=SHORT_STR_CAPACITY;
+ if (size<=SHORT_STR_CAPACITY) // init short string
+ {
+ if (size>0)
+ {
+ u.s.len = size-1;
+ u.s.str[size-1]='\0';
+ }
+ else
+ {
+ u.s.len = 0;
+ }
+ }
+ else // int long string
+ {
+ u.l.d = LSData::create(size);
+ }
+ }
+ StringRep(const char *str)
+ {
+ if (str)
+ {
+ int len = strlen(str);
+ u.s.isShort = len<SHORT_STR_CAPACITY;
+ if (len<SHORT_STR_CAPACITY)
+ {
+ u.s.len = len;
+ qstrncpy(u.s.str,str,SHORT_STR_CAPACITY);
+ }
+ else
+ {
+ u.l.d = LSData::create(len+1);
+ memcpy(u.l.d->toStr(),str,u.l.d->len);
+ }
+ }
+ else // create empty string
+ {
+ initEmpty();
+ }
+ }
+ StringRep( const char *str, uint maxlen )
+ {
+ if (str && maxlen>0)
+ {
+ uint len=strlen(str);
+ if (len>maxlen) len=maxlen;
+ u.s.isShort = len<=SHORT_STR_MAX_LEN;
+ if (u.s.isShort)
+ {
+ u.s.len = len;
+ memcpy(u.s.str,str,len);
+ u.s.str[len]='\0';
+ }
+ else
+ {
+ u.l.d = LSData::create(len+1);
+ memcpy(u.l.d->toStr(),str,len);
+ }
+ }
+ else // create empty string
+ {
+ initEmpty();
+ }
+ }
+ StringRep &operator=(const StringRep &s)
+ {
+ if (&s!=this)
+ {
+ if (!u.s.isShort)
+ {
+ u.l.d->dispose();
+ }
+ u.s.isShort = s.u.s.isShort;
+ if (u.s.isShort) // copy by value
+ {
+ u.s.len = s.u.s.len;
+ memcpy(u.s.str,s.u.s.str,s.u.s.len+1);
+ }
+ else // copy by reference
+ {
+ u.l.d = s.u.l.d;
+ u.l.d->refCount++;
+ }
+ }
+ else // self-assignment
+ {
+ u = s.u; // avoid uninitialized warning from gcc
+ }
+ return *this;
+ }
+ StringRep &operator=(const char *str)
+ {
+ if (!u.s.isShort)
+ {
+ u.l.d->dispose();
+ }
+ if (str)
+ {
+ int len = strlen(str);
+ u.s.isShort = len<SHORT_STR_CAPACITY;
+ if (len<SHORT_STR_CAPACITY)
+ {
+ u.s.len = len;
+ qstrncpy(u.s.str,str,SHORT_STR_CAPACITY);
+ }
+ else
+ {
+ u.l.d = LSData::create(len+1);
+ memcpy(u.l.d->toStr(),str,len);
+ }
+ }
+ else
+ {
+ initEmpty();
+ }
+ return *this;
+ }
+ bool isEmpty() const
+ {
+ return u.s.isShort && u.s.len==0;
+ }
+ uint length() const
+ {
+ return u.s.isShort ? u.s.len : u.l.d->len;
+ }
+ char *data() const
+ {
+ if (u.s.isShort)
+ {
+ return u.s.len==0 ? 0 : (char*)u.s.str;
+ }
+ else
+ {
+ return u.l.d->len==0 ? 0 : u.l.d->toStr();
+ }
+ }
+ char &at(int i) const
+ {
+ if (u.s.isShort)
+ {
+ return (char&)u.s.str[i];
+ }
+ else
+ {
+ return u.l.d->toStr()[i];
+ }
+ }
+ bool resize( uint newlen )
+ {
+ if (u.s.isShort && newlen<=SHORT_STR_CAPACITY) // resize short string
+ {
+ if (newlen>0)
+ {
+ u.s.len = newlen-1;
+ u.s.str[newlen-1]='\0';
+ }
+ else // string becomes empty
+ {
+ initEmpty();
+ }
+ }
+ else if (u.s.isShort) // turn short string into long string
+ {
+ StringRep tmp = *this;
+ u.s.isShort=FALSE;
+ u.l.d = LSData::create(newlen);
+ if (tmp.u.s.len>0)
+ {
+ memcpy(u.l.d->toStr(),tmp.u.s.str,tmp.u.s.len+1);
+ }
+ else
+ {
+ u.l.d->toStr()[0]='\0';
+ }
+ }
+ else if (!u.s.isShort && newlen<=SHORT_STR_CAPACITY) // turn long string into short string
+ {
+ if (newlen>0)
+ {
+ StringRep tmp(newlen); // copy short part into tmp buffer
+ memcpy(tmp.u.s.str,u.l.d->toStr(),newlen-1);
+ tmp.u.s.str[newlen-1]='\0';
+ u.l.d->dispose();
+ u.s = tmp.u.s;
+ }
+ else
+ {
+ u.l.d->dispose();
+ initEmpty();
+ }
+ }
+ else // resize long string
+ {
+ u.l.d = u.l.d->resize(u.l.d,newlen);
+ }
+ return TRUE;
+ }
+ bool fill( char c, int len )
+ {
+ if (len<0) len=length();
+ if (len!=(int)length())
+ {
+ if (len>0)
+ {
+ resize(len+1);
+ }
+ else
+ {
+ if (!u.s.isShort)
+ {
+ u.l.d->dispose();
+ }
+ initEmpty();
+ }
+ }
+ if (len>0)
+ {
+ memset(data(),c,len);
+ }
+ return TRUE;
+ }
+ private:
+ union ShortOrLongStringSelector
+ {
+ ShortStringRep s;
+ LongStringRep l;
+ } u;
+ };
+ StringRep m_rep;
-inline QCString &QCString::duplicate( const char *str, int)
-{
- if (m_data==str) return *this;
- if (m_data) free(m_data);
- duplicate(str);
- return *this;
-}
+};
/*****************************************************************************
QCString stream functions
@@ -327,56 +686,6 @@ Q_EXPORT QDataStream &operator>>( QDataStream &, QCString & );
#endif
/*****************************************************************************
- QCString inline functions
- *****************************************************************************/
-
-inline QCString &QCString::operator=( const QCString &s )
-{ return (QCString&)assign( s ); }
-
-inline QCString &QCString::operator=( const char *str )
-{ return (QCString&)duplicate( str, qstrlen(str)+1 ); }
-
-inline bool QCString::isNull() const
-{ return data() == 0; }
-
-inline bool QCString::isEmpty() const
-{ return data() == 0 || *data() == '\0'; }
-
-inline uint QCString::length() const
-{ return qstrlen( data() ); }
-
-inline bool QCString::truncate( uint pos )
-{ return resize(pos+1); }
-
-inline QCString QCString::copy() const
-{ return QCString( data() ); }
-
-inline QCString &QCString::prepend( const char *s )
-{ return insert(0,s); }
-
-inline QCString &QCString::append( const char *s )
-{ return operator+=(s); }
-
-inline QCString &QCString::setNum( short n )
-{ return setNum((long)n); }
-
-inline QCString &QCString::setNum( ushort n )
-{ return setNum((ulong)n); }
-
-inline QCString &QCString::setNum( int n )
-{ return setNum((long)n); }
-
-inline QCString &QCString::setNum( uint n )
-{ return setNum((ulong)n); }
-
-inline QCString &QCString::setNum( float n, char f, int prec )
-{ return setNum((double)n,f,prec); }
-
-inline QCString::operator const char *() const
-{ return (const char *)data(); }
-
-
-/*****************************************************************************
QCString non-member operators
*****************************************************************************/
@@ -476,5 +785,4 @@ inline const char *qPrint(const QCString &s)
if (!s.isEmpty()) return s.data(); else return "";
}
-
#endif // QCSTRING_H
diff --git a/qtools/qtools.pro.in b/qtools/qtools.pro.in
index f287d34..ba8a086 100644
--- a/qtools/qtools.pro.in
+++ b/qtools/qtools.pro.in
@@ -7,7 +7,6 @@ HEADERS = qarray.h \
qcollection.h \
qconfig.h \
qcstring.h \
- scstring.h \
qdatastream.h \
qdatetime.h \
qdict.h \
@@ -54,7 +53,7 @@ HEADERS = qarray.h \
SOURCES = qbuffer.cpp \
qcollection.cpp \
- scstring.cpp \
+ qcstring.cpp \
qdatastream.cpp \
qdatetime.cpp \
qdir.cpp \
diff --git a/qtools/scstring.cpp b/qtools/scstring.cpp
deleted file mode 100644
index 26d3a52..0000000
--- a/qtools/scstring.cpp
+++ /dev/null
@@ -1,798 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 1997-2004 by Dimitri van Heesch.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation under the terms of the GNU General Public License is hereby
- * granted. No representations are made about the suitability of this software
- * for any purpose. It is provided "as is" without express or implied warranty.
- * See the GNU General Public License for more details.
- *
- * Documents produced by Doxygen are derivative works derived from the
- * input used in their production; they are not affected by this license.
- *
- */
-
-// with this switch you can choose between the original qcstring implementation,
-// which implicitly shares data so copying is faster, but requires at least 12 bytes, and
-// the new implementation in this file, which has a smaller footprint (only 4 bytes for
-// an empty string), but always copies strings.
-#define SMALLSTRING
-
-#include "qcstring.h"
-#ifndef SMALLSTRING
-#include "qcstring.cpp"
-#else
-#define SCString QCString
-
-#include <qstring.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <qregexp.h>
-#include <qdatastream.h>
-
-
-SCString::SCString(int size)
-{
- if (size>0)
- {
- m_data = (char *)malloc(size);
- if (m_data)
- {
- if (size>1) memset(m_data,' ',size-1);
- m_data[size-1]='\0';
- }
- }
- else
- {
- m_data=0;
- }
-}
-
-SCString::SCString( const SCString &s )
-{
- duplicate(s);
-}
-
-SCString::SCString( const char *str )
-{
- duplicate(str);
-}
-
-SCString::SCString( const char *str, uint maxlen )
-{
- uint l;
- if (str && ( l = QMIN(qstrlen(str),maxlen) ))
- {
- m_data=(char *)malloc(l+1);
- strncpy(m_data,str,l+1);
- m_data[l]='\0';
- }
- else
- {
- m_data=0;
- }
-}
-
-SCString::~SCString()
-{
- if (m_data) free(m_data);
- m_data=0;
-}
-
-SCString &SCString::assign( const char *str )
-{
- if (m_data==str) return *this;
- if (m_data) free(m_data);
- duplicate(str);
- return *this;
-}
-
-bool SCString::resize( uint newlen )
-{
- if (newlen==0)
- {
- if (m_data) { free(m_data); m_data=0; }
- return TRUE;
- }
- if (m_data==0) // newlen>0
- {
- m_data = (char *)malloc(newlen);
- }
- else
- {
- m_data = (char *)realloc(m_data,newlen);
- }
- if (m_data==0) return FALSE;
- m_data[newlen-1]='\0';
- return TRUE;
-}
-
-bool SCString::fill( char c, int len )
-{
- uint l=length();
- if (len<0) len=l;
- if ((uint)len!=l)
- {
- if (m_data) free(m_data);
- if (len>0)
- {
- m_data=(char *)malloc(len+1);
- if (m_data==0) return FALSE;
- m_data[len]='\0';
- }
- else
- {
- m_data=0;
- }
- }
- if (len>0)
- {
- uint i;
- for (i=0;i<(uint)len;i++) m_data[i]=c;
- }
- return TRUE;
-}
-
-SCString &SCString::sprintf( const char *format, ... )
-{
- va_list ap;
- va_start( ap, format );
- uint l = length();
- const uint minlen=4095;
- if (l<minlen)
- {
- if (m_data)
- m_data = (char *)realloc(m_data,minlen+1);
- else
- m_data = (char *)malloc(minlen+1);
- m_data[minlen]='\0';
- }
- vsnprintf( m_data, minlen, format, ap );
- resize( qstrlen(m_data) + 1 ); // truncate
- va_end( ap );
- return *this;
-}
-
-
-int SCString::find( char c, int index, bool cs ) const
-{
- uint len = length();
- if ( m_data==0 || (uint)index>len ) // index outside string
- return -1;
- register const char *d;
- if ( cs ) // case sensitive
- {
- d = strchr( m_data+index, c );
- }
- else
- {
- d = m_data+index;
- c = tolower( (uchar) c );
- while ( *d && tolower((uchar) *d) != c )
- d++;
- if ( !*d && c ) // not found
- d = 0;
- }
- return d ? (int)(d - m_data) : -1;
-}
-
-int SCString::find( const char *str, int index, bool cs ) const
-{
- uint l = length();
- if ( m_data==0 || (uint)index > l ) // index outside string
- return -1;
- if ( !str ) // no search string
- return -1;
- if ( !*str ) // zero-length search string
- return index;
- register const char *d;
- if ( cs ) // case sensitive
- {
- d = strstr( m_data+index, str );
- }
- else // case insensitive
- {
- d = m_data+index;
- int len = qstrlen( str );
- while ( *d )
- {
- if ( qstrnicmp(d, str, len) == 0 )
- break;
- d++;
- }
- if ( !*d ) // not found
- d = 0;
- }
- return d ? (int)(d - m_data) : -1;
-}
-
-int SCString::find( const QCString &str, int index, bool cs ) const
-{
- return find(str.data(),index,cs);
-}
-
-int SCString::find( const QRegExp &rx, int index ) const
-{
- QString d = QString::fromLatin1( m_data );
- return d.find( rx, index );
-}
-
-int SCString::findRev( char c, int index, bool cs) const
-{
- const char *b = m_data;
- const char *d;
- uint len = length();
- if ( b == 0 ) return -1; // empty string
- if ( index < 0 ) // neg index ==> start from end
- {
- if ( len == 0 ) return -1;
- if ( cs )
- {
- d = strrchr( b, c );
- return d ? (int)(d - b) : -1;
- }
- index = len;
- }
- else if ( (uint)index > len ) // bad index
- {
- return -1;
- }
- d = b+index;
- if ( cs ) // case sensitive
- {
- while ( d >= b && *d != c )
- d--;
- }
- else // case insensitive
- {
- c = tolower( (uchar) c );
- while ( d >= b && tolower((uchar) *d) != c )
- d--;
- }
- return d >= b ? (int)(d - b) : -1;
-}
-
-int SCString::findRev( const char *str, int index, bool cs) const
-{
- int slen = qstrlen(str);
- uint len = length();
- if ( index < 0 ) // neg index ==> start from end
- index = len-slen;
- else if ( (uint)index > len ) // bad index
- return -1;
- else if ( (uint)(index + slen) > len ) // str would be too long
- index = len - slen;
- if ( index < 0 )
- return -1;
-
- register char *d = m_data + index;
- if ( cs ) // case sensitive
- {
- for ( int i=index; i>=0; i-- )
- if ( qstrncmp(d--,str,slen)==0 )
- return i;
- }
- else // case insensitive
- {
- for ( int i=index; i>=0; i-- )
- if ( qstrnicmp(d--,str,slen)==0 )
- return i;
- }
- return -1;
-
-}
-
-int SCString::findRev( const QRegExp &rx, int index ) const
-{
- QString d = QString::fromLatin1( m_data );
- return d.findRev( rx, index );
-}
-
-int SCString::contains( char c, bool cs ) const
-{
- int count = 0;
- char *d = m_data;
- if ( !d )
- return 0;
- if ( cs ) // case sensitive
- {
- while ( *d )
- if ( *d++ == c )
- count++;
- }
- else // case insensitive
- {
- c = tolower( (uchar) c );
- while ( *d ) {
- if ( tolower((uchar) *d) == c )
- count++;
- d++;
- }
- }
- return count;
-}
-
-int SCString::contains( const char *str, bool cs ) const
-{
- int count = 0;
- char *d = data();
- if ( !d )
- return 0;
- int len = qstrlen( str );
- while ( *d ) // counts overlapping strings
- {
- if ( cs )
- {
- if ( qstrncmp( d, str, len ) == 0 )
- count++;
- }
- else
- {
- if ( qstrnicmp(d, str, len) == 0 )
- count++;
- }
- d++;
- }
- return count;
-}
-
-int SCString::contains( const QRegExp &rx ) const
-{
- QString d = QString::fromLatin1( m_data );
- return d.contains( rx );
-}
-
-SCString SCString::left( uint len ) const
-{
- if ( isEmpty() )
- {
- return SCString();
- }
- else if ( len >= length() )
- {
- return *this;
- }
- else
- {
- SCString s( len+1 );
- strncpy( s.data(), m_data, len );
- *(s.data()+len) = '\0';
- return s;
- }
-}
-
-SCString SCString::right( uint len ) const
-{
- if ( isEmpty() )
- {
- return SCString();
- }
- else
- {
- uint l = length();
- if ( len > l ) len = l;
- char *p = m_data + (l - len);
- return SCString( p );
- }
-}
-
-SCString SCString::mid( uint index, uint len) const
-{
- uint slen = length();
- if ( len == 0xffffffff ) len = slen-index;
- if ( isEmpty() || index >= slen )
- {
- return SCString();
- }
- else
- {
- register char *p = data()+index;
- SCString s( len+1 );
- strncpy( s.data(), p, len );
- *(s.data()+len) = '\0';
- return s;
- }
-}
-
-SCString SCString::lower() const
-{
- SCString s( m_data );
- register char *p = s.data();
- if ( p )
- {
- while ( *p )
- {
- *p = tolower((uchar) *p);
- p++;
- }
- }
- return s;
-}
-
-SCString SCString::upper() const
-{
- SCString s( m_data );
- register char *p = s.data();
- if ( p ) {
- while ( *p ) {
- *p = toupper((uchar)*p);
- p++;
- }
- }
- return s;
-}
-
-SCString SCString::stripWhiteSpace() const
-{
- if ( isEmpty() ) // nothing to do
- return *this;
-
- register char *s = m_data;
- int reslen = length();
- if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
- return *this; // returns a copy
-
- SCString result(s);
- s = result.data();
- int start = 0;
- int end = reslen - 1;
- while ( isspace((uchar) s[start]) ) // skip white space from start
- start++;
- if ( s[start] == '\0' )
- { // only white space
- return SCString();
- }
- while ( end && isspace((uchar) s[end]) ) // skip white space from end
- end--;
- end -= start - 1;
- memmove( result.data(), &s[start], end );
- result.resize( end + 1 );
- return result;
-}
-
-SCString SCString::simplifyWhiteSpace() const
-{
- if ( isEmpty() ) // nothing to do
- return *this;
-
- SCString result( length()+1 );
- char *from = data();
- char *to = result.data();
- char *first = to;
- while ( TRUE )
- {
- while ( *from && isspace((uchar) *from) )
- from++;
- while ( *from && !isspace((uchar)*from) )
- *to++ = *from++;
- if ( *from )
- *to++ = 0x20; // ' '
- else
- break;
- }
- if ( to > first && *(to-1) == 0x20 )
- to--;
- *to = '\0';
- result.resize( (int)((long)to - (long)result.data()) + 1 );
- return result;
-}
-
-SCString &SCString::insert( uint index, const char *s )
-{
- int len = qstrlen(s);
- if ( len == 0 )
- return *this;
- uint olen = length();
- int nlen = olen + len;
- if ( index >= olen ) // insert after end of string
- {
- m_data = (char *)realloc(m_data,nlen+index-olen+1);
- if ( m_data )
- {
- memset( m_data+olen, ' ', index-olen );
- memcpy( m_data+index, s, len+1 );
- }
- }
- else if ( (m_data = (char *)realloc(m_data,nlen+1)) ) // normal insert
- {
- memmove( m_data+index+len, m_data+index, olen-index+1 );
- memcpy( m_data+index, s, len );
- }
- return *this;
-}
-
-SCString &SCString::insert( uint index, char c ) // insert char
-{
- char buf[2];
- buf[0] = c;
- buf[1] = '\0';
- return insert( index, buf );
-}
-
-SCString& SCString::operator+=( const char *str )
-{
- if ( !str ) return *this; // nothing to append
- uint len1 = length();
- uint len2 = qstrlen(str);
- char *newData = (char *)realloc( m_data, len1 + len2 + 1 );
- if (newData)
- {
- m_data = newData;
- memcpy( m_data + len1, str, len2 + 1 );
- }
- return *this;
-}
-
-SCString &SCString::operator+=( char c )
-{
- uint len = length();
- char *newData = (char *)realloc( m_data, length()+2 );
- if (newData)
- {
- m_data = newData;
- m_data[len] = c;
- m_data[len+1] = '\0';
- }
- return *this;
-}
-
-SCString &SCString::remove( uint index, uint len )
-{
- uint olen = length();
- if ( index + len >= olen ) // range problems
- {
- if ( index < olen ) // index ok
- {
- resize( index+1 );
- }
- }
- else if ( len != 0 )
- {
- memmove( m_data+index, m_data+index+len, olen-index-len+1 );
- resize( olen-len+1 );
- }
- return *this;
-}
-
-SCString &SCString::replace( uint index, uint len, const char *s )
-{
- remove( index, len );
- insert( index, s );
- return *this;
-}
-
-SCString &SCString::replace( const QRegExp &rx, const char *str )
-{
- QString d = QString::fromLatin1( m_data );
- QString r = QString::fromLatin1( str );
- d.replace( rx, r );
- return assign(d.ascii());
-}
-
-long SCString::toLong( bool *ok ) const
-{
- QString s(m_data);
- return s.toLong(ok);
-}
-
-ulong SCString::toULong( bool *ok ) const
-{
- QString s(m_data);
- return s.toULong(ok);
-}
-
-short SCString::toShort( bool *ok ) const
-{
- QString s(m_data);
- return s.toShort(ok);
-}
-
-ushort SCString::toUShort( bool *ok ) const
-{
- QString s(m_data);
- return s.toUShort(ok);
-}
-
-int SCString::toInt( bool *ok ) const
-{
- QString s(m_data);
- return s.toInt(ok);
-}
-
-uint SCString::toUInt( bool *ok ) const
-{
- QString s(m_data);
- return s.toUInt(ok);
-}
-
-SCString &SCString::setNum( long n )
-{
- char buf[20];
- register char *p = &buf[19];
- bool neg;
- if ( n < 0 )
- {
- neg = TRUE;
- n = -n;
- }
- else
- {
- neg = FALSE;
- }
- *p = '\0';
- do
- {
- *--p = ((int)(n%10)) + '0';
- n /= 10;
- } while ( n );
- if ( neg ) *--p = '-';
- operator=( p );
- return *this;
-}
-
-SCString &SCString::setNum( ulong n )
-{
- char buf[20];
- register char *p = &buf[19];
- *p = '\0';
- do
- {
- *--p = ((int)(n%10)) + '0';
- n /= 10;
- } while ( n );
- operator=( p );
- return *this;
-}
-
-void SCString::msg_index( uint index )
-{
-#if defined(CHECK_RANGE)
- qWarning( "SCString::at: Absolute index %d out of range", index );
-#else
- Q_UNUSED( index )
-#endif
-}
-
-bool SCString::stripPrefix(const char *prefix)
-{
- if (prefix==0) return FALSE;
- uint plen = qstrlen(prefix);
- if (m_data && qstrncmp(prefix,m_data,plen)==0) // prefix matches
- {
- uint len = qstrlen(m_data);
- uint newlen = len-plen+1;
- qmemmove(m_data,m_data+plen,newlen);
- resize(newlen);
- return TRUE;
- }
- return FALSE;
-}
-
-//---------------------------------------------------------------------------
-
-void *qmemmove( void *dst, const void *src, uint len )
-{
- register char *d;
- register char *s;
- if ( dst > src ) {
- d = (char *)dst + len - 1;
- s = (char *)src + len - 1;
- while ( len-- )
- *d-- = *s--;
- } else if ( dst < src ) {
- d = (char *)dst;
- s = (char *)src;
- while ( len-- )
- *d++ = *s++;
- }
- return dst;
-}
-
-char *qstrdup( const char *str )
-{
- if ( !str )
- return 0;
- char *dst = new char[strlen(str)+1];
- CHECK_PTR( dst );
- return strcpy( dst, str );
-}
-
-char *qstrncpy( char *dst, const char *src, uint len )
-{
- if ( !src )
- return 0;
- strncpy( dst, src, len );
- if ( len > 0 )
- dst[len-1] = '\0';
- return dst;
-}
-
-int qstricmp( const char *str1, const char *str2 )
-{
- register const uchar *s1 = (const uchar *)str1;
- register const uchar *s2 = (const uchar *)str2;
- int res;
- uchar c;
- if ( !s1 || !s2 )
- return s1 == s2 ? 0 : (int)((long)s2 - (long)s1);
- for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
- if ( !c ) // strings are equal
- break;
- return res;
-}
-
-int qstrnicmp( const char *str1, const char *str2, uint len )
-{
- register const uchar *s1 = (const uchar *)str1;
- register const uchar *s2 = (const uchar *)str2;
- int res;
- uchar c;
- if ( !s1 || !s2 )
- return (int)((long)s2 - (long)s1);
- for ( ; len--; s1++, s2++ ) {
- if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
- return res;
- if ( !c ) // strings are equal
- break;
- }
- return 0;
-}
-
-#ifndef QT_NO_DATASTREAM
-
-QDataStream &operator<<( QDataStream &s, const QByteArray &a )
-{
- return s.writeBytes( a.data(), a.size() );
-}
-
-QDataStream &operator>>( QDataStream &s, QByteArray &a )
-{
- Q_UINT32 len;
- s >> len; // read size of array
- if ( len == 0 || s.eof() ) { // end of file reached
- a.resize( 0 );
- return s;
- }
- if ( !a.resize( (uint)len ) ) { // resize array
-#if defined(CHECK_NULL)
- qWarning( "QDataStream: Not enough memory to read QByteArray" );
-#endif
- len = 0;
- }
- if ( len > 0 ) // not null array
- s.readRawBytes( a.data(), (uint)len );
- return s;
-}
-
-QDataStream &operator<<( QDataStream &s, const SCString &str )
-{
- return s.writeBytes( str.data(), str.size() );
-}
-
-QDataStream &operator>>( QDataStream &s, SCString &str )
-{
- Q_UINT32 len;
- s >> len; // read size of string
- if ( len == 0 || s.eof() ) { // end of file reached
- str.resize( 0 );
- return s;
- }
- if ( !str.resize( (uint)len )) {// resize string
-#if defined(CHECK_NULL)
- qWarning( "QDataStream: Not enough memory to read QCString" );
-#endif
- len = 0;
- }
- if ( len > 0 ) // not null array
- s.readRawBytes( str.data(), (uint)len );
- return s;
-}
-
-#endif //QT_NO_DATASTREAM
-
-
-
-#endif
diff --git a/qtools/scstring.h b/qtools/scstring.h
deleted file mode 100644
index a9b462c..0000000
--- a/qtools/scstring.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 1997-2004 by Dimitri van Heesch.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation under the terms of the GNU General Public License is hereby
- * granted. No representations are made about the suitability of this software
- * for any purpose. It is provided "as is" without express or implied warranty.
- * See the GNU General Public License for more details.
- *
- * Documents produced by Doxygen are derivative works derived from the
- * input used in their production; they are not affected by this license.
- *
- */
-
-#ifndef SCSTRING_H
-#define SCSTRING_H
-
-#include <stdlib.h>
-
-class QRegExp;
-
-/** This is an alternative implementation of QCString. It provides basically
- * the same functions but uses less memory for administration. This class
- * is just a wrapper around a plain C string requiring only 4 bytes "overhead".
- * QCString features sharing of data and stores the string length, but
- * requires 4 + 12 bytes for this (even for the empty string). As doxygen
- * uses a LOT of string during a run it saves a lot of memory to use a
- * more memory efficient implementation at the cost of relatively low
- * runtime overhead.
- */
-class SCString
-{
-public:
- SCString() : m_data(0) {} // make null string
- SCString( const SCString &s );
- SCString( int size );
- SCString( const char *str );
- SCString( const char *str, uint maxlen );
- ~SCString();
-
- SCString &operator=( const SCString &s );// deep copy
- SCString &operator=( const char *str ); // deep copy
-
- bool isNull() const;
- bool isEmpty() const;
- uint length() const;
- uint size() const { return m_data ? length()+1 : 0; }
- char * data() const { return m_data; }
- bool resize( uint newlen );
- bool truncate( uint pos );
- bool fill( char c, int len = -1 );
-
- SCString copy() const;
-
- SCString &sprintf( const char *format, ... );
-
- int find( char c, int index=0, bool cs=TRUE ) const;
- int find( const char *str, int index=0, bool cs=TRUE ) const;
- int find( const QRegExp &, int index=0 ) const;
- int find( const QCString &str, int index, bool cs ) const;
- int findRev( char c, int index=-1, bool cs=TRUE) const;
- int findRev( const char *str, int index=-1, bool cs=TRUE) const;
- int findRev( const QRegExp &, int index=-1 ) const;
- int contains( char c, bool cs=TRUE ) const;
- int contains( const char *str, bool cs=TRUE ) const;
- int contains( const QRegExp & ) const;
- bool stripPrefix(const char *prefix);
-
- SCString left( uint len ) const;
- SCString right( uint len ) const;
- SCString mid( uint index, uint len=0xffffffff) const;
-
- SCString lower() const;
- SCString upper() const;
-
- SCString stripWhiteSpace() const;
- SCString simplifyWhiteSpace() const;
-
- SCString &assign( const char *str );
- SCString &insert( uint index, const char * );
- SCString &insert( uint index, char );
- SCString &append( const char *s );
- SCString &prepend( const char *s );
- SCString &remove( uint index, uint len );
- SCString &replace( uint index, uint len, const char * );
- SCString &replace( const QRegExp &, const char * );
-
- short toShort( bool *ok=0 ) const;
- ushort toUShort( bool *ok=0 ) const;
- int toInt( bool *ok=0 ) const;
- uint toUInt( bool *ok=0 ) const;
- long toLong( bool *ok=0 ) const;
- ulong toULong( bool *ok=0 ) const;
-
- SCString &setNum( short );
- SCString &setNum( ushort );
- SCString &setNum( int );
- SCString &setNum( uint );
- SCString &setNum( long );
- SCString &setNum( ulong );
- QCString &setNum( float, char f='g', int prec=6 );
- QCString &setNum( double, char f='g', int prec=6 );
-
- operator const char *() const;
- SCString &operator+=( const char *str );
- SCString &operator+=( char c );
- char &at( uint index ) const;
- char &operator[]( int i ) const { return at(i); }
-
- private:
- static void msg_index( uint );
- void duplicate( const SCString &s );
- void duplicate( const char *str);
- SCString &duplicate( const char *str, int);
-
- char * m_data;
-};
-
-inline char &SCString::at( uint index ) const
-{
- return m_data[index];
-}
-
-inline void SCString::duplicate( const SCString &s )
-{
- if (!s.isEmpty())
- {
- uint l = strlen(s.data());
- m_data = (char *)malloc(l+1);
- if (m_data) memcpy(m_data,s.data(),l+1);
- }
- else
- m_data=0;
-}
-inline void SCString::duplicate( const char *str)
-{
- if (str && str[0]!='\0')
- {
- uint l = strlen(str);
- m_data = (char *)malloc(l+1);
- if (m_data) memcpy(m_data,str,l+1);
- }
- else
- m_data=0;
-}
-inline SCString &SCString::duplicate( const char *str, int)
-{
- if (m_data) free(m_data);
- duplicate(str);
- return *this;
-}
-
-#endif
-
diff --git a/src/definition.cpp b/src/definition.cpp
index 3c11916..4a8c65d 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -890,16 +890,17 @@ QCString Definition::getSourceFileBase() const
QCString Definition::getSourceAnchor() const
{
- QCString anchorStr;
+ const int maxAnchorStrLen = 20;
+ char anchorStr[maxAnchorStrLen];
if (m_impl->body && m_impl->body->startLine!=-1)
{
if (Htags::useHtags)
{
- anchorStr.sprintf("L%d",m_impl->body->startLine);
+ snprintf(anchorStr,maxAnchorStrLen,"L%d",m_impl->body->startLine);
}
else
{
- anchorStr.sprintf("l%05d",m_impl->body->startLine);
+ snprintf(anchorStr,maxAnchorStrLen,"l%05d",m_impl->body->startLine);
}
}
return anchorStr;
@@ -1163,8 +1164,9 @@ void Definition::_writeSourceRefList(OutputList &ol,const char *scopeName,
{
ol.disable(OutputGenerator::Latex);
}
- QCString lineStr,anchorStr;
- anchorStr.sprintf("l%05d",md->getStartBodyLine());
+ const int maxLineNrStr = 10;
+ char anchorStr[maxLineNrStr];
+ snprintf(anchorStr,maxLineNrStr,"l%05d",md->getStartBodyLine());
//printf("Write object link to %s\n",md->getBodyDef()->getSourceFileBase().data());
ol.writeObjectLink(0,md->getBodyDef()->getSourceFileBase(),anchorStr,name);
ol.popGeneratorState();
diff --git a/src/dirdef.h b/src/dirdef.h
index 1a9f40c..9a8a5ad 100644
--- a/src/dirdef.h
+++ b/src/dirdef.h
@@ -54,7 +54,7 @@ class DirDef : public Definition
bool isLinkableInProject() const;
bool isLinkable() const;
QCString displayName(bool=TRUE) const { return m_dispName; }
- QCString shortName() const { return m_shortName; }
+ const QCString &shortName() const { return m_shortName; }
void addSubDir(DirDef *subdir);
FileList * getFiles() const { return m_fileList; }
void addFile(FileDef *fd);
diff --git a/src/filedef.h b/src/filedef.h
index 8cd5703..33eae35 100644
--- a/src/filedef.h
+++ b/src/filedef.h
@@ -96,7 +96,7 @@ class FileDef : public Definition
QCString absFilePath() const { return m_filePath; }
/*! Returns the name as it is used in the documentation */
- QCString docName() const { return m_docname; }
+ const QCString &docName() const { return m_docname; }
/*! Returns TRUE if this file is a source file. */
bool isSource() const { return m_isSource; }
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 62ae1c7..b459446 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -912,40 +912,6 @@ static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlig
//------------------------------------------------------------------------
-/// substitute all occurrences of \a src in \a s by \a dst
-QCString substitute(const char *s,const char *src,const char *dst)
-{
- if (s==0 || src==0) return s;
- const char *p, *q;
- int srcLen = qstrlen(src);
- int dstLen = dst ? qstrlen(dst) : 0;
- int resLen;
- if (srcLen!=dstLen)
- {
- int count;
- for (count=0, p=s; (q=strstr(p,src))!=0; p=q+srcLen) count++;
- resLen = (int)(p-s)+qstrlen(p)+count*(dstLen-srcLen);
- }
- else // result has same size as s
- {
- resLen = qstrlen(s);
- }
- QCString result(resLen+1);
- char *r;
- for (r=result.data(), p=s; (q=strstr(p,src))!=0; p=q+srcLen)
- {
- int l = (int)(q-p);
- memcpy(r,p,l);
- r+=l;
- if (dst) memcpy(r,dst,dstLen);
- r+=dstLen;
- }
- qstrcpy(r,p);
- //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data());
- return result;
-}
-//----------------------------------------------------------------------
-
/// Clear a text block \a s from \a begin to \a end markers
QCString clearBlock(const char *s,const char *begin,const char *end)
{
@@ -989,6 +955,7 @@ QCString clearBlock(const char *s,const char *begin,const char *end)
QCString selectBlock(const QCString& s,const QCString &name,bool enable)
{
+ // TODO: this is an expensive function that is called a lot -> optimize it
const QCString begin = "<!--BEGIN " + name + "-->";
const QCString end = "<!--END " + name + "-->";
const QCString nobegin = "<!--BEGIN !" + name + "-->";
@@ -1341,9 +1308,11 @@ void HtmlCodeGenerator::writeLineNumber(const char *ref,const char *filename,
const char *anchor,int l)
{
if (!m_streamSet) return;
- QCString lineNumber,lineAnchor;
- lineNumber.sprintf("%5d",l);
- lineAnchor.sprintf("l%05d",l);
+ const int maxLineNrStr = 10;
+ char lineNumber[maxLineNrStr];
+ char lineAnchor[maxLineNrStr];
+ snprintf(lineNumber,maxLineNrStr,"%5d",l);
+ snprintf(lineAnchor,maxLineNrStr,"l%05d",l);
m_t << "<div class=\"line\">";
m_t << "<a name=\"" << lineAnchor << "\"></a><span class=\"lineno\">";
diff --git a/src/membergroup.h b/src/membergroup.h
index e3f6c0f..daf8ccb 100644
--- a/src/membergroup.h
+++ b/src/membergroup.h
@@ -63,7 +63,7 @@ class MemberGroup
MemberListType lt,
ClassDef *inheritedFrom,const QCString &inheritId);
- QCString documentation() const { return doc; }
+ const QCString &documentation() const { return doc; }
bool allMembersInSameSection() const { return inSameSection; }
void addToDeclarationSection();
int countDecMembers(GroupDef *gd=0);
diff --git a/src/util.cpp b/src/util.cpp
index b313b86..666fd04 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -264,8 +264,9 @@ void writePageRef(OutputDocInterface &od,const char *cn,const char *mn)
*/
QCString generateMarker(int id)
{
- QCString result;
- result.sprintf("@%d",id);
+ const int maxMarkerStrLen = 20;
+ char result[maxMarkerStrLen];
+ snprintf(result,maxMarkerStrLen,"@%d",id);
return result;
}
@@ -4913,8 +4914,10 @@ FileDef *findFileDef(const FileNameDict *fnDict,const char *n,bool &ambig)
ambig=FALSE;
if (n==0) return 0;
- QCString key;
- key.sprintf("%p:",fnDict);
+ const int maxAddrSize = 20;
+ char addr[maxAddrSize];
+ snprintf(addr,maxAddrSize,"%p:",fnDict);
+ QCString key = addr;
key+=n;
g_findFileDefCache.setAutoDelete(TRUE);
@@ -5030,6 +5033,41 @@ QCString showFileDefMatches(const FileNameDict *fnDict,const char *n)
//----------------------------------------------------------------------
+/// substitute all occurrences of \a src in \a s by \a dst
+QCString substitute(const QCString &s,const QCString &src,const QCString &dst)
+{
+ if (s.isEmpty() || src.isEmpty()) return s;
+ const char *p, *q;
+ int srcLen = src.length();
+ int dstLen = dst.length();
+ int resLen;
+ if (srcLen!=dstLen)
+ {
+ int count;
+ for (count=0, p=s.data(); (q=strstr(p,src))!=0; p=q+srcLen) count++;
+ resLen = s.length()+count*(dstLen-srcLen);
+ }
+ else // result has same size as s
+ {
+ resLen = s.length();
+ }
+ QCString result(resLen+1);
+ char *r;
+ for (r=result.data(), p=s; (q=strstr(p,src))!=0; p=q+srcLen)
+ {
+ int l = (int)(q-p);
+ memcpy(r,p,l);
+ r+=l;
+ if (dst) memcpy(r,dst,dstLen);
+ r+=dstLen;
+ }
+ qstrcpy(r,p);
+ //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data());
+ return result;
+}
+
+//----------------------------------------------------------------------
+
QCString substituteKeywords(const QCString &s,const char *title,
const char *projName,const char *projNum,const char *projBrief)
{
diff --git a/src/util.h b/src/util.h
index 2fc71ce..07744ca 100644
--- a/src/util.h
+++ b/src/util.h
@@ -192,7 +192,7 @@ void mergeArguments(ArgumentList *,ArgumentList *,bool forceNameOverwrite=FALSE)
QCString substituteClassNames(const QCString &s);
-QCString substitute(const char *s,const char *src,const char *dst);
+QCString substitute(const QCString &s,const QCString &src,const QCString &dst);
QCString clearBlock(const char *s,const char *begin,const char *end);
diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp
index ad95fd1..50127f8 100644
--- a/src/vhdldocgen.cpp
+++ b/src/vhdldocgen.cpp
@@ -1445,7 +1445,7 @@ bool VhdlDocGen::isNumber(const QCString& s)
void VhdlDocGen::formatString(const QCString &s, OutputList& ol,const MemberDef* mdef)
{
QCString qcs = s;
- QCString temp(qcs.length());
+ QCString temp;
qcs.stripPrefix(":");
qcs.stripPrefix("is");
qcs.stripPrefix("IS");
@@ -1464,7 +1464,7 @@ void VhdlDocGen::formatString(const QCString &s, OutputList& ol,const MemberDef*
if (j>0) b=qcs[j-1];
if (c=='"' || c==',' || c=='\''|| c=='(' || c==')' || c==':' || c=='[' || c==']' ) // || (c==':' && b!='=')) // || (c=='=' && b!='>'))
{
- if (temp.at(index-1) != ' ')
+ if (temp.length()>=index && temp.at(index-1) != ' ')
{
temp+=" ";
}
@@ -2322,6 +2322,7 @@ void VhdlDocGen::writePlainVHDLDeclarations(
{
SDict<QCString> pack(1009);
+ pack.setAutoDelete(TRUE);
bool first=TRUE;
MemberDef *md;
diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp
index f31c9fb..d79c260 100644
--- a/src/vhdljjparser.cpp
+++ b/src/vhdljjparser.cpp
@@ -92,7 +92,7 @@ int VhdlParser::levelCounter;
static QList<VhdlConfNode> configL;
-struct
+static struct
{
QCString doc;
bool brief;
@@ -217,7 +217,7 @@ void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,En
VhdlParser::current=new Entry();
VhdlParser::initEntry(VhdlParser::current);
groupEnterFile(fileName,yyLineNr);
- lineParse=new int[200];
+ lineParse=new int[200]; // Dimitri: dangerous constant: should be bigger than largest token id in VhdlParserConstants.h
VhdlParserIF::parseVhdlfile(fileBuf,inLine);
delete VhdlParser::current;
@@ -226,7 +226,7 @@ void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,En
if (!inLine)
VhdlParser::mapLibPackage(root);
- delete lineParse;
+ delete[] lineParse;
yyFileName.resize(0);
libUse.clear();
VhdlDocGen::resetCodeVhdlParserState();
diff --git a/tmake/lib/linux-g++/tmake.conf b/tmake/lib/linux-g++/tmake.conf
index 193fadd..e100bce 100644
--- a/tmake/lib/linux-g++/tmake.conf
+++ b/tmake/lib/linux-g++/tmake.conf
@@ -11,7 +11,7 @@ TMAKE_CC = gcc
TMAKE_CFLAGS = -pipe -fsigned-char
TMAKE_CFLAGS_WARN_ON = -Wall -W
TMAKE_CFLAGS_WARN_OFF =
-TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_RELEASE = -O3
TMAKE_CFLAGS_DEBUG = -g
TMAKE_CFLAGS_SHLIB = -fPIC
TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
diff --git a/tmake/lib/macosx-c++/tmake.conf b/tmake/lib/macosx-c++/tmake.conf
index ade3437..377b06f 100644
--- a/tmake/lib/macosx-c++/tmake.conf
+++ b/tmake/lib/macosx-c++/tmake.conf
@@ -11,7 +11,7 @@ TMAKE_CC = cc
TMAKE_CFLAGS = -pipe
TMAKE_CFLAGS_WARN_ON = -Wall -W -Wno-deprecated-declarations
TMAKE_CFLAGS_WARN_OFF =
-TMAKE_CFLAGS_RELEASE = -O2
+TMAKE_CFLAGS_RELEASE = -O3
TMAKE_CFLAGS_DEBUG = -g -fstack-protector
TMAKE_CFLAGS_SHLIB = -fPIC
TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
diff --git a/vhdlparser/VhdlParserIF.cpp b/vhdlparser/VhdlParserIF.cpp
index e8768ee..f9f689b 100644
--- a/vhdlparser/VhdlParserIF.cpp
+++ b/vhdlparser/VhdlParserIF.cpp
@@ -32,6 +32,7 @@ void VhdlParserIF::parseVhdlfile(const char* inputBuffer,bool inLine)
// fprintf(stderr,"\n\nparsed lines: %d\n",yyLineNr);
// fprintf(stderr,"\n\nerrors : %d\n\n",myErr->getErrorCount());
delete myParser;
+ delete myErr;
}