diff options
-rwxr-xr-x | configure | 11 | ||||
-rw-r--r-- | qtools/Doxyfile | 2 | ||||
-rw-r--r-- | qtools/qcstring.cpp | 620 | ||||
-rw-r--r-- | qtools/qcstring.h | 783 | ||||
-rw-r--r-- | qtools/qtools.pro.in | 3 | ||||
-rw-r--r-- | qtools/rcstring.h | 791 | ||||
-rw-r--r-- | qtools/scstring.cpp | 798 | ||||
-rw-r--r-- | qtools/scstring.h | 155 | ||||
-rw-r--r-- | src/filedef.cpp | 9 | ||||
-rw-r--r-- | src/fortrancode.l | 11 | ||||
-rw-r--r-- | src/htmlentity.cpp | 2 | ||||
-rw-r--r-- | src/latexgen.cpp | 1 | ||||
-rw-r--r-- | src/libdoxygen.pro.in | 1 |
13 files changed, 1598 insertions, 1589 deletions
@@ -554,8 +554,13 @@ fi if test "$f_libclang" = YES; then printf " Checking for libclang ... " - libclang_hdr_dir="/usr/include /usr/local/include /opt/local/include" - libclang_lib_dir="/usr/lib /usr/local/lib /opt/local/lib /usr/lib64/llvm /usr/lib/llvm" + if llvm-config --version > /dev/null 2>&1; then + libclang_hdr_dir=$(llvm-config --includedir) + libclang_lib_dir=$(llvm-config --libdir) + else + libclang_hdr_dir="/usr/include /usr/local/include /opt/local/include" + libclang_lib_dir="/usr/lib /usr/local/lib /opt/local/lib /usr/lib64/llvm /usr/lib/llvm" + fi if test "$f_libclangstatic" = NO; then libclang_lib_name="libclang.so libclang.dylib libclang.a libclang.dll.a" else @@ -952,7 +957,7 @@ EOF #if test "$f_thread" = YES; then # realopts="$realopts thread" #fi - cat $SRC .tmakeconfig | sed -e "s/\$extraopts/$realopts/g" -e "s;%%SQLITE3_INC%%;$sqlite3_hdr_dir;g" -e "s;%%SQLITE3_LIBS%%;$sqlite3_link;g" -e "s;%%LIBCLANG_LIBS%%;$libclang_link;g" >> $DST + cat $SRC .tmakeconfig | sed -e "s/\$extraopts/$realopts/g" -e "s;%%SQLITE3_INC%%;$sqlite3_hdr_dir;g" -e "s;%%SQLITE3_LIBS%%;$sqlite3_link;g" -e "s;%%LIBCLANG_INC%%;$libclang_hdr_dir;g" -e "s;%%LIBCLANG_LIBS%%;$libclang_link;g" >> $DST echo " Created $DST from $SRC..." done diff --git a/qtools/Doxyfile b/qtools/Doxyfile index 9e9743c..644eee5 100644 --- a/qtools/Doxyfile +++ b/qtools/Doxyfile @@ -127,7 +127,7 @@ REFERENCES_LINK_SOURCE = YES SOURCE_TOOLTIPS = YES USE_HTAGS = NO VERBATIM_HEADERS = YES -CLANG_ASSISTED_PARSING = YES +CLANG_ASSISTED_PARSING = NO CLANG_OPTIONS = #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index diff --git a/qtools/qcstring.cpp b/qtools/qcstring.cpp index 4038d55..7bf6f50 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,148 @@ #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 +// printf("QCString::findRev(%d,%d,%d)\n",c,index,cs); + 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; + //printf("pos=%p b=%p diff=%d\n",pos,b,(int)(pos-b)); + 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 +173,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 +280,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 +331,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 +349,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 +417,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 +505,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 +519,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..7170455 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,143 +126,538 @@ 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); } - + /** creates an empty string */ + QCString() + { + } + + /** 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); + } + 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; + 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)-1) +#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() + { + u.s.isShort=TRUE; + u.s.len=0; + } + ~StringRep() + { + if (!u.s.isShort) + { + u.l.d->dispose(); + } + } + StringRep(const StringRep &s) + { + if (&s!=this) + { + u = s.u; + if (!u.s.isShort) + { + u.l.d->refCount++; + } + } + } + StringRep(int size) + { + u.s.isShort = size<=SHORT_STR_CAPACITY; + if (u.s.isShort) // 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_MAX_LEN; + if (u.s.isShort) + { + u.s.len = len; + memcpy(u.s.str,str,len+1); + } + else + { + u.l.d = LSData::create(len+1); + memcpy(u.l.d->toStr(),str,u.l.d->len); + } + } + else // create empty string + { + u.s.isShort=TRUE; + u.s.len=0; + } + } + 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 + { + u.s.isShort=TRUE; + u.s.len=0; + } + } + StringRep &operator=(const StringRep &s) + { + if (!u.s.isShort) + { + u.l.d->dispose(); + } + if (s.u.s.isShort) // copy by value + { + u.s = s.u.s; + } + else // copy by reference + { + u.l.isShort=FALSE; + u.l.d = s.u.l.d; + u.l.d->refCount++; + } + 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_MAX_LEN; + if (u.s.isShort) + { + u.s.len = len; + memcpy(u.s.str,str,len+1); + } + else + { + u.l.d = LSData::create(len+1); + memcpy(u.l.d->toStr(),str,u.l.d->len); + } + } + else + { + u.s.isShort=TRUE; + u.s.len=0; + } + 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 + { + u.s.len = 0; + } + } + 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(); + u.s.isShort=TRUE; + u.s.len=0; + } + } + 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(); + } + u.s.isShort=TRUE; + u.s.len=0; + } + } + if (len>0) + { + memset(data(),c,len); + } + return TRUE; + } + private: + union + { + ShortStringRep s; + LongStringRep l; + } u; + }; + StringRep m_rep; }; -inline char &QCString::at( uint index ) const -{ - return m_data[index]; -} - -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; - } -} - -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; - } -} - -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 +667,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 +766,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/rcstring.h b/qtools/rcstring.h new file mode 100644 index 0000000..01b5a5c --- /dev/null +++ b/qtools/rcstring.h @@ -0,0 +1,791 @@ +/****************************************************************************** + * + * 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 RCSTRING_H +#define RCSTRING_H + +#define RCString QCString + +#ifndef QT_H +#include "qarray.h" +#endif // QT_H + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if !defined(_OS_WIN32_) || defined(__MINGW32__) +#include <stdint.h> +#endif + +#if defined(_OS_SUN_) && defined(_CC_GNU_) +#include <strings.h> +#endif + +#include <assert.h> + +class QGString; + +/***************************************************************************** + Fixes and workarounds for some platforms + *****************************************************************************/ + +#if defined(_OS_HPUX_) +// HP-UX has badly defined strstr() etc. +// ### fix in 3.0: change hack_* to qt_hack_* +// by the way HP-UX is probably right, the standard has evolved and +// we'll have to adapt to it +inline char *hack_strstr( const char *s1, const char *s2 ) +{ return (char *)strstr(s1, s2); } +inline char *hack_strchr( const char *s, int c ) +{ return (char *)strchr(s, c); } +inline char *hack_strrchr( const char *s, int c ) +{ return (char *)strrchr(s, c); } +#define strstr(s1,s2) hack_strstr((s1),(s2)) +#define strchr(s,c) hack_strchr((s),(c)) +#define strrchr(s,c) hack_strrchr((s),(c)) +#endif + +/***************************************************************************** + Safe and portable C string functions; extensions to standard string.h + *****************************************************************************/ + +Q_EXPORT void *qmemmove( void *dst, const void *src, uint len ); + +#if defined(_OS_SUN_) || defined(_CC_OC_) +#define memmove(s1,s2,n) qmemmove((s1),(s2),(n)) +#endif + +#if defined(_OS_WIN32_) +#define qsnprintf _snprintf +#else +#define qsnprintf snprintf +#endif + +Q_EXPORT char *qstrdup( const char * ); + +Q_EXPORT inline uint cstrlen( const char *str ) +{ return (uint)strlen(str); } + +Q_EXPORT inline uint qstrlen( const char *str ) +{ return str ? (uint)strlen(str) : 0; } + +Q_EXPORT inline char *cstrcpy( char *dst, const char *src ) +{ return strcpy(dst,src); } + +Q_EXPORT inline char *qstrcpy( char *dst, const char *src ) +{ return src ? strcpy(dst, src) : 0; } + +Q_EXPORT char * qstrncpy(char *src,const char *dst, uint len); + +Q_EXPORT inline int cstrcmp( const char *str1, const char *str2 ) +{ return strcmp(str1,str2); } + +Q_EXPORT inline int qstrcmp( const char *str1, const char *str2 ) +{ return (str1 && str2) ? strcmp(str1,str2) : (int)((intptr_t)str2 - (intptr_t)str1); } + +Q_EXPORT inline int cstrncmp( const char *str1, const char *str2, uint len ) +{ return strncmp(str1,str2,len); } + +Q_EXPORT inline int qstrncmp( const char *str1, const char *str2, uint len ) +{ return (str1 && str2) ? strncmp(str1,str2,len) : + (int)((intptr_t)str2 - (intptr_t)str1); } + +Q_EXPORT int qstricmp( const char *str1, const char *str2 ); + +Q_EXPORT int qstrnicmp( const char *str1, const char *str2, uint len ); + +/***************************************************************************** + QByteArray class + *****************************************************************************/ + +#if defined(Q_TEMPLATEDLL) +template class Q_EXPORT QArray<char>; +#endif +typedef QArray<char> QByteArray; + +/***************************************************************************** + QByteArray stream functions + *****************************************************************************/ +#ifndef QT_NO_DATASTREAM +Q_EXPORT QDataStream &operator<<( QDataStream &, const QByteArray & ); +Q_EXPORT QDataStream &operator>>( QDataStream &, QByteArray & ); +#endif + +class QRegExp; + +/** This is an alternative implementation of QCString. It provides basically + * the same functions but uses reference counting and copy on write. + */ +class RCString +{ +public: + /** creates an empty string */ + RCString() + { + } + + /** destroys the string */ + ~RCString() + { + } + + /** makes a copy of a string. */ + RCString( const RCString &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) + */ + RCString( 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. + */ + RCString( const char *str ) : m_rep(str) + { + } + + /** creates a string from \a str and copies over the first \a maxlen characters. */ + RCString( const char *str, uint maxlen ) : m_rep(str,maxlen) + { + } + + /** replaces the contents by that of string \a s. */ + RCString &operator=( const RCString &s ) + { + m_rep = s.m_rep; + return *this; + } + + /** replaces the contents by that of C string \a str. */ + RCString &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. */ + RCString copy() const + { + if (length()==0) return RCString(); + RCString cs(length()+1); + memcpy(cs.data(),data(),length()); + return cs; + } + + RCString &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 RCString &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); + RCString left( uint len ) const; + RCString right( uint len ) const; + RCString mid( uint index, uint len=0xffffffff) const; + RCString lower() const; + RCString upper() const; + RCString stripWhiteSpace() const; + RCString simplifyWhiteSpace() const; + RCString &assign( const char *str ); + RCString &insert( uint index, const char *s ); + RCString &insert( uint index, char c); + RCString &append( const char *s ); + RCString &prepend( const char *s ); + RCString &remove( uint index, uint len ); + RCString &replace( uint index, uint len, const char *s); + RCString &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; + RCString &setNum(short n); + RCString &setNum(ushort n); + RCString &setNum(int n); + RCString &setNum(uint n); + RCString &setNum(long n); + RCString &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. */ + RCString &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. */ + RCString &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); + } + + private: + + 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)-1) +#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!) + // if size is zero, the string will become empty + 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() + { + //printf("%p:StringRep:empty construct\n",this); + u.s.isShort=TRUE; + u.s.len=0; + } + ~StringRep() + { + //printf("%p:StringRep:destruct(short=%d) str='%s'\n",this,u.s.isShort,data()); + if (!u.s.isShort) + { + u.l.d->dispose(); + } + } + StringRep(const StringRep &s) + { + if (&s!=this) + { + //printf("%p:StringRep:copy construct(short=%d)\n",this,s.u.s.isShort); + u = s.u; + if (!u.s.isShort) + { + u.l.d->refCount++; + } + } + } + StringRep(int size) + { + u.s.isShort = size<=SHORT_STR_CAPACITY; + //printf("%p:StringRep:size construct(size=%d,isShort=%d)\n",this,size,u.s.isShort); + if (u.s.isShort) // 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_MAX_LEN; + //printf("%p:StringRep:c_str construct(isShort=%d,str='%s')\n",this,u.s.isShort,str); + if (u.s.isShort) + { + u.s.len = len; + memcpy(u.s.str,str,len+1); + } + else + { + u.l.d = LSData::create(len+1); + memcpy(u.l.d->toStr(),str,u.l.d->len); + } + } + else // create empty string + { + //printf("%p:StringRep:empty c_str construct\n",this); + u.s.isShort=TRUE; + u.s.len=0; + } + } + 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; + //printf("%p:StringRep:c_str maxlen construct(isShort=%d)\n",this,u.s.isShort); + 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 + { + //printf("%p:StringRep:empty c_str construct\n",this); + u.s.isShort=TRUE; + u.s.len=0; + } + } + StringRep &operator=(const StringRep &s) + { + if (!u.s.isShort) + { + u.l.d->dispose(); + } + if (s.u.s.isShort) // copy by value + { + //printf("%p:StringRep:operator=(short) s='%s'\n",this,s.data()); + u.s = s.u.s; + } + else // copy by reference + { + //printf("%p:StringRep:operator=(long) s='%s'\n",this,s.data()); + u.l.isShort=FALSE; + u.l.d = s.u.l.d; + u.l.d->refCount++; + } + 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_MAX_LEN; + //printf("%p:StringRep:operator=(c_str) isShort=%d\n",this,u.s.isShort); + if (u.s.isShort) + { + u.s.len = len; + memcpy(u.s.str,str,len+1); + } + else + { + u.l.d = LSData::create(len+1); + memcpy(u.l.d->toStr(),str,u.l.d->len); + } + } + else + { + //printf("%p:StringRep:operator=(empty c_str)\n",this); + u.s.isShort=TRUE; + u.s.len=0; + } + 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) + { + //printf("%p:StringRep:resize short2short\n",this); + u.s.len = newlen-1; + u.s.str[newlen-1]='\0'; + } + else + { + //printf("%p:StringRep:resize short2empty\n",this); + u.s.len = 0; + } + } + else if (u.s.isShort) // turn short string into long string + { + //printf("%p:StringRep:resize short2long\n",this); + 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) + { + //printf("%p:StringRep:resize long2short\n",this); + 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 + { + //printf("%p:StringRep:resize long2empty\n",this); + u.l.d->dispose(); + u.s.isShort=TRUE; + u.s.len=0; + } + } + else // resize long string + { + //printf("%p:StringRep:resize long2long\n",this); + 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(); + } + u.s.isShort=TRUE; + u.s.len=0; + } + } + if (len>0) + { + memset(data(),c,len); + } + return TRUE; + } + private: + union + { + ShortStringRep s; + LongStringRep l; + } u; + }; + StringRep m_rep; +}; + +/***************************************************************************** + QCString stream functions + *****************************************************************************/ +#ifndef QT_NO_DATASTREAM +Q_EXPORT QDataStream &operator<<( QDataStream &, const QCString & ); +Q_EXPORT QDataStream &operator>>( QDataStream &, QCString & ); +#endif + +/***************************************************************************** + RCString non-member operators + *****************************************************************************/ + +Q_EXPORT inline bool operator==( const RCString &s1, const RCString &s2 ) +{ return qstrcmp(s1.data(),s2.data()) == 0; } + +Q_EXPORT inline bool operator==( const RCString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) == 0; } + +Q_EXPORT inline bool operator==( const char *s1, const RCString &s2 ) +{ return qstrcmp(s1,s2.data()) == 0; } + +Q_EXPORT inline bool operator!=( const RCString &s1, const RCString &s2 ) +{ return qstrcmp(s1.data(),s2.data()) != 0; } + +Q_EXPORT inline bool operator!=( const RCString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) != 0; } + +Q_EXPORT inline bool operator!=( const char *s1, const RCString &s2 ) +{ return qstrcmp(s1,s2.data()) != 0; } + +Q_EXPORT inline bool operator<( const RCString &s1, const RCString& s2 ) +{ return qstrcmp(s1.data(),s2.data()) < 0; } + +Q_EXPORT inline bool operator<( const RCString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) < 0; } + +Q_EXPORT inline bool operator<( const char *s1, const RCString &s2 ) +{ return qstrcmp(s1,s2.data()) < 0; } + +Q_EXPORT inline bool operator<=( const RCString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) <= 0; } + +Q_EXPORT inline bool operator<=( const char *s1, const RCString &s2 ) +{ return qstrcmp(s1,s2.data()) <= 0; } + +Q_EXPORT inline bool operator>( const RCString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) > 0; } + +Q_EXPORT inline bool operator>( const char *s1, const RCString &s2 ) +{ return qstrcmp(s1,s2.data()) > 0; } + +Q_EXPORT inline bool operator>=( const RCString &s1, const char *s2 ) +{ return qstrcmp(s1.data(),s2) >= 0; } + +Q_EXPORT inline bool operator>=( const char *s1, const RCString &s2 ) +{ return qstrcmp(s1,s2.data()) >= 0; } + +Q_EXPORT inline RCString operator+( const RCString &s1, const RCString &s2 ) +{ + RCString tmp(s1); + tmp += s2; + return tmp; +} + + +inline RCString operator+( const RCString &s1, const QGString &s2 ); +inline RCString operator+( const QGString &s1, const RCString &s2 ); + + +Q_EXPORT inline RCString operator+( const RCString &s1, const char *s2 ) +{ + RCString tmp(s1); + tmp += s2; + return tmp; +} + +Q_EXPORT inline RCString operator+( const char *s1, const RCString &s2 ) +{ + RCString tmp(s1); + tmp += s2; + return tmp; +} + +Q_EXPORT inline RCString operator+( const RCString &s1, char c2 ) +{ + RCString tmp( s1.data() ); + tmp += c2; + return tmp; +} + +Q_EXPORT inline RCString operator+( char c1, const RCString &s2 ) +{ + RCString tmp; + tmp += c1; + tmp += s2; + return tmp; +} + +inline const char *qPrint(const char *s) +{ + if (s) return s; else return ""; +} + +inline const char *qPrint(const RCString &s) +{ + if (!s.isEmpty()) return s.data(); else return ""; +} + + +#endif + 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/filedef.cpp b/src/filedef.cpp index 9c18e20..3ff69a4 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -327,6 +327,13 @@ void FileDef::writeDetailedDescription(OutputList &ol,const QCString &title) //printf("Writing source ref for file %s\n",name().data()); if (Config_getBool("SOURCE_BROWSER")) { + //if Latex enabled and LATEX_SOURCE_CODE isn't -> skip, bug_738548 + ol.pushGeneratorState(); + if (ol.isEnabled(OutputGenerator::Latex) && !Config_getBool("LATEX_SOURCE_CODE")) + { + ol.disable(OutputGenerator::Latex); + } + ol.startParagraph(); QCString refText = theTranslator->trDefinedInSourceFile(); int fileMarkerPos = refText.find("@0"); @@ -339,6 +346,8 @@ void FileDef::writeDetailedDescription(OutputList &ol,const QCString &title) refText.length()-fileMarkerPos-2)); // text right from marker 2 } ol.endParagraph(); + //Restore settings, bug_738548 + ol.popGeneratorState(); } ol.endTextBlock(); } diff --git a/src/fortrancode.l b/src/fortrancode.l index ac6a73b..101137a 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -1136,6 +1136,17 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I <*>{LOG_OPER} { // Fortran logical comparison keywords g_code->codify(yytext); } +<*><<EOF>> { + if (YY_START == DocBlock) { + if (!Config_getBool("STRIP_CODE_COMMENTS")) + { + startFontClass("comment"); + codifyLines(docBlock); + endFontClass(); + } + } + yyterminate(); + } %% /*@ ---------------------------------------------------------------------------- diff --git a/src/htmlentity.cpp b/src/htmlentity.cpp index 216b65c..a4d5914 100644 --- a/src/htmlentity.cpp +++ b/src/htmlentity.cpp @@ -193,7 +193,7 @@ static struct htmlEntityInfo { SYM(upsih), "\xcf\x92", "ϒ", "<upsih/>", "ϒ", "{$\\Upsilon$}", NULL, "\\u978?", { NULL, DocSymbol::Perl_unknown }}, { SYM(piv), "\xcf\x96", "ϖ", "<piv/>", "ϖ", "{$\\varpi$}", NULL, "\\u982?", { NULL, DocSymbol::Perl_unknown }}, { SYM(bull), "\xe2\x80\xa2", "•", "<bull/>", "•", "\\textbullet{}", NULL, "\\'95", { NULL, DocSymbol::Perl_unknown }}, - { SYM(hellip), "\xe2\x80\xa6", "…", "<hellip/>", "…", "{$\\cdots$}", NULL, "\\'85", { NULL, DocSymbol::Perl_unknown }}, + { SYM(hellip), "\xe2\x80\xa6", "…", "<hellip/>", "…", "{$\\dots$}", NULL, "\\'85", { NULL, DocSymbol::Perl_unknown }}, { SYM(prime), "\xe2\x80\xb2", "′", "<prime/>", "′", "'", NULL, "\\u8242?", { "\\\'", DocSymbol::Perl_string }}, { SYM(Prime), "\xe2\x80\xb3", "″", "<Prime/>", "″", "''", NULL, "\\u8243?", { "\"", DocSymbol::Perl_char }}, { SYM(oline), "\xe2\x80\xbe", "‾", "<oline/>", "‾", "{$\\overline{\\,}$}", NULL, "\\u8254?", { NULL, DocSymbol::Perl_unknown }}, diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 4ad577e..7cdfeaf 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -316,7 +316,6 @@ static void writeDefaultHeaderPart1(FTextStream &t) // Define default fonts t << "% Font selection\n" "\\usepackage[T1]{fontenc}\n" - "\\usepackage{mathptmx}\n" "\\usepackage[scaled=.90]{helvet}\n" "\\usepackage{courier}\n" "\\usepackage{amssymb}\n" diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in index 703b885..c5943c6 100644 --- a/src/libdoxygen.pro.in +++ b/src/libdoxygen.pro.in @@ -230,6 +230,7 @@ win32-g++:TMAKE_CXXFLAGS += -fno-exceptions linux-g++:TMAKE_CXXFLAGS += -fno-exceptions INCLUDEPATH += ../generated_src/doxygen ../src ../qtools ../libmd5 ../vhdlparser INCLUDEPATH += %%SQLITE3_INC%% +INCLUDEPATH += %%LIBCLANG_INC%% DEPENDPATH += ../generated_src/doxygen win32:INCLUDEPATH += . DESTDIR = ../lib |