summaryrefslogtreecommitdiffstats
path: root/qtools
diff options
context:
space:
mode:
Diffstat (limited to 'qtools')
-rw-r--r--qtools/Doxyfile2
-rw-r--r--qtools/qcstring.cpp2333
-rw-r--r--qtools/qcstring.h118
-rw-r--r--qtools/qfile.h3
-rw-r--r--qtools/qfile_unix.cpp13
-rw-r--r--qtools/qfile_win32.cpp13
-rw-r--r--qtools/qgstring.cpp200
-rw-r--r--qtools/qgstring.h137
-rw-r--r--qtools/qtools.pro.in2
9 files changed, 1054 insertions, 1767 deletions
diff --git a/qtools/Doxyfile b/qtools/Doxyfile
index ff08b16..45f4765 100644
--- a/qtools/Doxyfile
+++ b/qtools/Doxyfile
@@ -829,7 +829,7 @@ MAN_LINKS = NO
# generate an XML file that captures the structure of
# the code including all documentation.
-GENERATE_XML = YES
+GENERATE_XML = NO
# The XML_OUTPUT tag is used to specify where the XML pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
diff --git a/qtools/qcstring.cpp b/qtools/qcstring.cpp
index 44324c2..1bd7c7f 100644
--- a/qtools/qcstring.cpp
+++ b/qtools/qcstring.cpp
@@ -1,1760 +1,771 @@
-/****************************************************************************
-**
-**
-** Implementation of extended char array operations, and QByteArray and
-** QCString classes
-**
-** Created : 920722
-**
-** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
-**
-** This file is part of the tools module of the Qt GUI Toolkit.
-**
-** This file may be distributed under the terms of the Q Public License
-** as defined by Trolltech AS of Norway and appearing in the file
-** LICENSE.QPL included in the packaging of this file.
-**
-** This file may be distributed and/or modified under the terms of the
-** GNU General Public License version 2 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.
-**
-** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
-** licenses may use this file in accordance with the Qt Commercial License
-** Agreement provided with the Software.
-**
-** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-**
-** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
-** information about Qt Commercial License Agreements.
-** See http://www.trolltech.com/qpl/ for QPL licensing information.
-** See http://www.trolltech.com/gpl/ for GPL licensing information.
-**
-** Contact info@trolltech.com if any conditions of this licensing are
-** not clear to you.
-**
-**********************************************************************/
-
-#include "qstring.h"
-#include "qregexp.h"
-#include "qdatastream.h"
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2004 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "qcstring.h"
+#include "qgstring.h"
+
+#include <qstring.h>
+#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
-#include <stdlib.h>
#include <ctype.h>
+#include <qregexp.h>
+#include <qdatastream.h>
-/*****************************************************************************
- Safe and portable C string functions; extensions to standard string.h
- *****************************************************************************/
-
-/*!
- \fn void *memmove( void *dst, const void *src, uint len )
- \relates QCString
-
- This function is normally part of the C library. Qt implements
- memmove() for platforms that do not have it.
-
- memmove() copies \e len bytes from \e src into \e dst. The data is
- copied correctly even if \e src and \e dst overlap.
-*/
-
-void *qmemmove( void *dst, const void *src, uint len )
-{
- register char *d;
- register char *s;
- if ( dst > src ) {
- d = (char *)dst + len - 1;
- s = (char *)src + len - 1;
- while ( len-- )
- *d-- = *s--;
- } else if ( dst < src ) {
- d = (char *)dst;
- s = (char *)src;
- while ( len-- )
- *d++ = *s++;
- }
- return dst;
-}
-
-/*!
- \relates QCString
-
- Returns a duplicate string.
-
- Allocates space for a copy of \e str (using \c new), copies it, and returns
- a pointer to the copy.
- If \e src is null, it immediately returns 0.
-*/
-
-char *qstrdup( const char *str )
-{
- if ( !str )
- return 0;
- char *dst = new char[strlen(str)+1];
- CHECK_PTR( dst );
- return strcpy( dst, str );
-}
-
-/*!
- \relates QCString
-
- A safe strncpy() function.
-
- Copies all characters up to \e len bytes from \e str into \e dst and returns
- a pointer to \e dst. Guarantees that \e dst is \0-terminated.
- If \e src is null, it immediately returns 0.
-
- \sa qstrcpy()
-*/
-
-char *qstrncpy( char *dst, const char *src, uint len )
-{
- if ( !src )
- return 0;
- strncpy( dst, src, len );
- if ( len > 0 )
- dst[len-1] = '\0';
- return dst;
-}
-
-/*!
- \fn int qstrcmp( const char *str1, const char *str2 )
- \relates QCString
-
- A safe strcmp() function.
-
- Compares \e str1 and \e str2. Returns a negative value if \e str1
- is less than \e str2, 0 if \e str1 is equal to \e str2 or a positive
- value if \e str1 is greater than \e str2.
-
- Special case I: Returns 0 if \e str1 and \e str2 are both null.
-
- Special case II: Returns a random nonzero value if \e str1 is null
- or \e str2 is null (but not both).
-
- \sa qstrncmp(), qstricmp(), qstrnicmp()
-*/
-
-/*!
- \fn int qstrncmp( const char *str1, const char *str2, uint len )
- \relates QCString
-
- A safe strncmp() function.
-
- Compares \e str1 and \e str2 up to \e len bytes.
-
- Returns a negative value if \e str1 is less than \e str2, 0 if \e str1
- is equal to \e str2 or a positive value if \e str1 is greater than \e
- str2.
-
- Special case I: Returns 0 if \e str1 and \e str2 are both null.
-
- Special case II: Returns a random nonzero value if \e str1 is null
- or \e str2 is null (but not both).
-
- \sa qstrcmp(), qstricmp(), qstrnicmp()
-*/
-
-/*!
- \fn int qstricmp( const char *str1, const char *str2 )
- \relates QCString
- A safe stricmp() function.
-
- Compares \e str1 and \e str2 ignoring the case.
-
- Returns a negative value if \e str1 is less than \e str2, 0 if \e str1
- is equal to \e str2 or a positive value if \e str1 is greater than \e
- str2.
-
- Special case I: Returns 0 if \e str1 and \e str2 are both null.
-
- Special case II: Returns a random nonzero value if \e str1 is null
- or \e str2 is null (but not both).
-
- \sa qstrcmp(), qstrncmp(), qstrnicmp()
-*/
-
-int qstricmp( const char *str1, const char *str2 )
-{
- register const uchar *s1 = (const uchar *)str1;
- register const uchar *s2 = (const uchar *)str2;
- int res;
- uchar c;
- if ( !s1 || !s2 )
- return s1 == s2 ? 0 : (int)((long)s2 - (long)s1);
- for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
- if ( !c ) // strings are equal
- break;
- return res;
-}
-
-/*!
- \fn int strnicmp( const char *str1, const char *str2, uint len )
- \relates QCString
-
- A safe strnicmp() function.
-
- Compares \e str1 and \e str2 up to \e len bytes ignoring the case.
-
- Returns a negative value if \e str1 is less than \e str2, 0 if \e str1
- is equal to \e str2 or a positive value if \e str1 is greater than \e
- str2.
-
- Special case I: Returns 0 if \e str1 and \e str2 are both null.
-
- Special case II: Returns a random nonzero value if \e str1 is null
- or \e str2 is null (but not both).
-
- \sa qstrcmp(), qstrncmp() qstricmp()
-*/
-
-int qstrnicmp( const char *str1, const char *str2, uint len )
-{
- register const uchar *s1 = (const uchar *)str1;
- register const uchar *s2 = (const uchar *)str2;
- int res;
- uchar c;
- if ( !s1 || !s2 )
- return (int)((long)s2 - (long)s1);
- for ( ; len--; s1++, s2++ ) {
- if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
- return res;
- if ( !c ) // strings are equal
- break;
- }
- return 0;
-}
-
-
-static Q_UINT16 crc_tbl[16];
-static bool crc_tbl_init = FALSE;
-
-static void createCRC16Table() // build CRC16 lookup table
+QCString::QCString(int size)
{
- register uint i;
- register uint j;
- uint v0, v1, v2, v3;
- for ( i=0; i<16; i++ ) {
- v0 = i & 1;
- v1 = (i >> 1) & 1;
- v2 = (i >> 2) & 1;
- v3 = (i >> 3) & 1;
- j = 0;
-#undef SET_BIT
-#define SET_BIT(x,b,v) x |= v << b
- SET_BIT(j, 0,v0);
- SET_BIT(j, 7,v0);
- SET_BIT(j,12,v0);
- SET_BIT(j, 1,v1);
- SET_BIT(j, 8,v1);
- SET_BIT(j,13,v1);
- SET_BIT(j, 2,v2);
- SET_BIT(j, 9,v2);
- SET_BIT(j,14,v2);
- SET_BIT(j, 3,v3);
- SET_BIT(j,10,v3);
- SET_BIT(j,15,v3);
- crc_tbl[i] = j;
+ 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;
+ }
}
-/*!
- \relates QByteArray
- Returns the CRC-16 checksum of \e len bytes starting at \e data.
-
- The checksum is independent of the byte order (endianness).
-*/
-
-Q_UINT16 qChecksum( const char *data, uint len )
-{
- if ( !crc_tbl_init ) { // create lookup table
- createCRC16Table();
- crc_tbl_init = TRUE;
- }
- register Q_UINT16 crc = 0xffff;
- uchar c;
- uchar *p = (uchar *)data;
- while ( len-- ) {
- c = *p++;
- crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
- c >>= 4;
- crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
- }
- return (~crc & 0xffff);
+QCString::QCString( const QCString &s )
+{
+ duplicate(s);
}
-
-/*****************************************************************************
- QByteArray member functions
- *****************************************************************************/
-
-// NOT REVISED
-/*! \class QByteArray qcstring.h
-
- \brief The QByteArray class provides an array of bytes.
-
- \inherit QArray
- \ingroup tools
- \ingroup shared
-
- QByteArray is defined as QArray\<char\>.
-*/
-
-
-/*****************************************************************************
- QByteArray stream functions
- *****************************************************************************/
-
-/*!
- \relates QByteArray
- Writes a byte array to a stream and returns a reference to the stream.
-
- \sa \link datastreamformat.html Format of the QDataStream operators \endlink
-*/
-#ifndef QT_NO_DATASTREAM
-
-QDataStream &operator<<( QDataStream &s, const QByteArray &a )
-{
- return s.writeBytes( a.data(), a.size() );
+QCString::QCString( const char *str )
+{
+ duplicate(str);
}
-/*!
- \relates QByteArray
- Reads a byte array from a stream and returns a reference to the stream.
-
- \sa \link datastreamformat.html Format of the QDataStream operators \endlink
-*/
-
-QDataStream &operator>>( QDataStream &s, QByteArray &a )
-{
- Q_UINT32 len;
- s >> len; // read size of array
- if ( len == 0 || s.eof() ) { // end of file reached
- a.resize( 0 );
- return s;
- }
- if ( !a.resize( (uint)len ) ) { // resize array
-#if defined(CHECK_NULL)
- qWarning( "QDataStream: Not enough memory to read QByteArray" );
-#endif
- len = 0;
- }
- if ( len > 0 ) // not null array
- s.readRawBytes( a.data(), (uint)len );
- return s;
+QCString::QCString( const char *str, uint maxlen )
+{
+ uint l;
+ if (str && ( l = QMIN(qstrlen(str),maxlen) ))
+ {
+ m_data=(char *)malloc(l+1);
+ strncpy(m_data,str,maxlen);
+ m_data[l]='\0';
+ }
+ else
+ {
+ m_data=0;
+ }
}
-#endif //QT_NO_DATASTREAM
-
-/*****************************************************************************
- QCString member functions
- *****************************************************************************/
-
-/*!
- \class QCString qcstring.h
-
- \brief The QCString class provides an abstraction of the classic C
- zero-terminated char array (<var>char*</var>).
-
- \ingroup tools
- \ingroup shared
-
- QCString inherits QByteArray, which is defined as QArray\<char\>.
-
- Since QCString is a QArray, it uses \e explicit
- \link shclass.html sharing\endlink with a reference count.
-
- You might use QCString for text that is never exposed to the user,
- but for text the user sees, you should use QString (which provides
- implicit sharing, Unicode and other internationalization support).
-
- Note that QCString is one of the weaker classes in Qt; its design is
- flawed (it tries to behave like a more convenient const char *) and
- as a result, algorithms that use QCString heavily all too often
- perform badly. For example, append() is O(length()) since it scans
- for a null terminator, which makes many algorithms that use QCString
- scale even worse.
-
- Note that for the QCString methods that take a <var>const char *</var>
- parameter the results are undefined if the QCString is not
- zero-terminated. It is legal for the <var>const char *</var> parameter
- to be 0.
-
- A QCString that has not been assigned to anything is \e null, i.e. both
- the length and data pointer is 0. A QCString that references the empty
- string ("", a single '\0' char) is \e empty. Both null and empty
- QCStrings are legal parameters to the methods. Assigning <var>const char
- * 0</var> to QCString gives a null QCString.
-
- \sa \link shclass.html Shared classes\endlink
-*/
-
-
-/*
- Implementation note: The QCString methods for QRegExp searching are
- implemented by converting the QCString to a QString and performing
- the search on that. This implies a deep copy of the QCString
- data. Therefore, if you are giong to perform many QRegExp searches
- on one and the same, large QCString, you will get better performance
- by converting the QCString to a QString yourself, and do the
- searches on that. The results will be of course be identical.
-*/
-
-
-
-/*!
- \fn QCString::QCString()
- Constructs a null string.
- \sa isNull()
-*/
-
-/*!
- \fn QCString::QCString( const QCString &s )
- Constructs a shallow copy \e s.
- \sa assign()
-*/
-
-/*!
- Constructs a string with room for \e size characters, including the
- '\0'-terminator. Makes a null string if \e size == 0.
-
- If \e size \> 0, then the first and last characters in the string are
- initialized to '\0'. All other characters are uninitialized.
-
- \sa resize(), isNull()
-*/
-
-QCString::QCString( int size )
- : QByteArray( size )
+QCString::~QCString()
{
- if ( size > 0 ) {
- *data() = '\0'; // set terminator
- *(data()+(size-1)) = '\0';
- }
+ if (m_data) free(m_data);
+ m_data=0;
}
-/*!
- Constructs a string that is a deep copy of \e str.
-
- If \a str is 0 a null string is created.
-
- \sa isNull()
-*/
-
-QCString::QCString( const char *str )
+QCString &QCString::assign( const char *str )
{
- duplicate( str, qstrlen(str) + 1 );
+ if (m_data) free(m_data);
+ duplicate(str);
+ return *this;
}
-
-/*!
- Constructs a string that is a deep copy of \e str, that is no more
- than \a maxsize bytes long including the '\0'-terminator.
-
- Example:
- \code
- QCString str( "helloworld", 6 ); // Assigns "hello" to str.
- \endcode
-
- If \a str contains a 0 byte within the first \a maxsize bytes, the
- resulting QCString will be terminated by the 0. If \a str is 0 a
- null string is created.
-
- \sa isNull()
-*/
-
-QCString::QCString( const char *str, uint maxsize )
+bool QCString::resize( uint newlen )
{
- if ( str == 0 )
- return;
- uint len; // index of first '\0'
- for ( len = 0; len < maxsize - 1; len++ ) {
- if ( str[len] == '\0' )
- break;
- }
- QByteArray::resize( len + 1 );
- memcpy( data(), str, len );
- data()[len] = 0;
-}
-
-/*!
- \fn QCString &QCString::operator=( const QCString &s )
- Assigns a shallow copy of \e s to this string and returns a reference to
- this string.
-*/
-
-/*!
- \fn QCString &QCString::operator=( const char *str )
- Assigns a deep copy of \a str to this string and returns a reference to
- this string.
-
- If \a str is 0 a null string is created.
-
- \sa isNull()
-*/
-
-/*!
- \fn bool QCString::isNull() const
- Returns TRUE if the string is null, i.e. if data() == 0.
- A null string is also an empty string.
-
- Example:
- \code
- QCString a; // a.data() == 0, a.size() == 0, a.length() == 0
- QCString b == ""; // b.data() == "", b.size() == 1, b.length() == 0
- a.isNull(); // TRUE, because a.data() == 0
- a.isEmpty(); // TRUE, because a.length() == 0
- b.isNull(); // FALSE, because b.data() == ""
- b.isEmpty(); // TRUE, because b.length() == 0
- \endcode
-
- \sa isEmpty(), length(), size()
-*/
-
-/*!
- \fn bool QCString::isEmpty() const
-
- Returns TRUE if the string is empty, i.e. if length() == 0.
- An empty string is not always a null string.
-
- See example in isNull().
-
- \sa isNull(), length(), size()
-*/
-
-/*!
- \fn uint QCString::length() const
- Returns the length of the string, excluding the '\0'-terminator.
- Equivalent to calling \c strlen(data()).
-
- Null strings and empty strings have zero length.
-
- \sa size(), isNull(), isEmpty()
-*/
-
-/*!
- \fn bool QCString::truncate( uint pos )
- Truncates the string at position \e pos.
-
- Equivalent to calling \c resize(pos+1).
-
- Example:
- \code
- QCString s = "truncate this string";
- s.truncate( 5 ); // s == "trunc"
- \endcode
-
- \sa resize()
-*/
-
-/*!
- Extends or shrinks the string to \e len bytes, including the
- '\0'-terminator.
-
- A \0-terminator is set at position <code>len - 1</code> unless
- <code>len == 0</code>.
-
- Example:
- \code
- QCString s = "resize this string";
- s.resize( 7 ); // s == "resize"
- \endcode
-
- \sa truncate()
-*/
-
-bool QCString::resize( uint len )
-{
- detach();
- if ( !QByteArray::resize(len) )
- return FALSE;
- if ( len )
- *(data()+len-1) = '\0';
+ 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;
}
-
-/*!
- Implemented as a call to the native vsprintf() (see your C-library
- manual).
-
- If your string is shorter than 256 characters, this sprintf() calls
- resize(256) to decrease the chance of memory corruption. The string is
- resized back to its natural length before sprintf() returns.
-
- Example:
- \code
- QCString s;
- s.sprintf( "%d - %s", 1, "first" ); // result < 256 chars
-
- QCString big( 25000 ); // very long string
- big.sprintf( "%d - %s", 2, longString ); // result < 25000 chars
- \endcode
-
- \warning All vsprintf() implementations will write past the end of
- the target string (*this) if the format specification and arguments
- happen to be longer than the target string, and some will also fail
- if the target string is longer than some arbitrary implementation
- limit.
-
- Giving user-supplied arguments to sprintf() is begging for trouble.
- Sooner or later someone \e will paste a 3000-character line into
- your application.
-*/
-
-QCString &QCString::sprintf( const char *format, ... )
+bool QCString::fill( char c, int len )
{
- detach();
- va_list ap;
- va_start( ap, format );
- if ( size() < 256 )
- QByteArray::resize( 256 ); // make string big enough
- vsprintf( data(), format, ap );
- resize( qstrlen(data()) + 1 ); // truncate
- va_end( ap );
- return *this;
+ 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;
}
-
-/*!
- Fills the string with \e len bytes of value \e c, followed by a
- '\0'-terminator.
-
- If \e len is negative, then the current string length is used.
-
- Returns FALSE is \e len is nonnegative and there is no memory to
- resize the string, otherwise TRUE is returned.
-*/
-
-bool QCString::fill( char c, int len )
+QCString &QCString::sprintf( const char *format, ... )
{
- detach();
- if ( len < 0 )
- len = length();
- if ( !QByteArray::fill(c,len+1) )
- return FALSE;
- *(data()+len) = '\0';
- return TRUE;
+ 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;
}
-/*!
- \fn QCString QCString::copy() const
- Returns a deep copy of this string.
- \sa detach()
-*/
-
-
-/*!
- Finds the first occurrence of the character \e c, starting at
- position \e index.
-
- The search is case sensitive if \e cs is TRUE, or case insensitive if \e
- cs is FALSE.
-
- Returns the position of \e c, or -1 if \e c could not be found.
-*/
-
int QCString::find( char c, int index, bool cs ) const
{
- if ( (uint)index >= size() ) // index outside string
- return -1;
- register const char *d;
- if ( cs ) { // case sensitive
- d = strchr( data()+index, c );
- } else {
- d = data()+index;
- c = tolower( (uchar) c );
- while ( *d && tolower((uchar) *d) != c )
- d++;
- if ( !*d && c ) // not found
- d = 0;
- }
- return d ? (int)(d - data()) : -1;
+ 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;
}
-/*!
- Finds the first occurrence of the string \e str, starting at position
- \e index.
-
- The search is case sensitive if \e cs is TRUE, or case insensitive if \e
- cs is FALSE.
-
- Returns the position of \e str, or -1 if \e str could not be found.
-*/
-
int QCString::find( const char *str, int index, bool cs ) const
{
- if ( (uint)index >= size() ) // index outside string
- return -1;
- if ( !str ) // no search string
- return -1;
- if ( !*str ) // zero-length search string
- return index;
- register const char *d;
- if ( cs ) { // case sensitive
- d = strstr( data()+index, str );
- } else { // case insensitive
- d = data()+index;
- int len = qstrlen( str );
- while ( *d ) {
- if ( qstrnicmp(d, str, len) == 0 )
- break;
- d++;
- }
- if ( !*d ) // not found
- d = 0;
+ 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++;
}
- return d ? (int)(d - data()) : -1;
+ if ( !*d ) // not found
+ d = 0;
+ }
+ return d ? (int)(d - m_data) : -1;
}
-/*!
- Finds the first occurrence of the character \e c, starting at
- position \e index and searching backwards.
-
- The search is case sensitive if \e cs is TRUE, or case insensitive if \e
- cs is FALSE.
-
- Returns the position of \e c, or -1 if \e c could not be found.
-*/
-
-int QCString::findRev( char c, int index, bool cs ) const
+int QCString::find( const QRegExp &rx, int index ) const
{
- const char *b = data();
- const char *d;
- if ( index < 0 ) { // neg index ==> start from end
- if ( size() == 0 )
- return -1;
- if ( cs ) {
- d = strrchr( b, c );
- return d ? (int)(d - b) : -1;
- }
- index = length();
- } else if ( (uint)index >= size() ) { // bad index
- return -1;
- }
- d = b+index;
- if ( cs ) { // case sensitive
- while ( d >= b && *d != c )
- d--;
- } else { // case insensitive
- c = tolower( (uchar) c );
- while ( d >= b && tolower((uchar) *d) != c )
- d--;
- }
- return d >= b ? (int)(d - b) : -1;
+ QString d = QString::fromLatin1( m_data );
+ return d.find( rx, index );
}
-/*!
- Finds the first occurrence of the string \e str, starting at
- position \e index and searching backwards.
-
- The search is case sensitive if \e cs is TRUE, or case insensitive if \e
- cs is FALSE.
-
- Returns the position of \e str, or -1 if \e str could not be found.
-*/
-
-int QCString::findRev( const char *str, int index, bool cs ) const
+int QCString::findRev( char c, int index, bool cs) const
{
- int slen = qstrlen(str);
- if ( index < 0 ) // neg index ==> start from end
- index = length()-slen;
- else if ( (uint)index >= size() ) // bad index
- return -1;
- else if ( (uint)(index + slen) > length() ) // str would be too long
- index = length() - slen;
- if ( index < 0 )
- return -1;
-
- register char *d = data() + index;
- if ( cs ) { // case sensitive
- for ( int i=index; i>=0; i-- )
- if ( qstrncmp(d--,str,slen)==0 )
- return i;
- } else { // case insensitive
- for ( int i=index; i>=0; i-- )
- if ( qstrnicmp(d--,str,slen)==0 )
- return i;
+ const char *b = m_data;
+ const char *d;
+ uint len = length();
+ if ( b == 0 ) return -1; // empty string
+ if ( index < 0 ) // neg index ==> start from end
+ {
+ if ( len == 0 ) return -1;
+ if ( cs )
+ {
+ d = strrchr( b, c );
+ return d ? (int)(d - b) : -1;
}
+ index = len;
+ }
+ else if ( (uint)index > len ) // bad index
+ {
+ return -1;
+ }
+ d = b+index;
+ if ( cs ) // case sensitive
+ {
+ while ( d >= b && *d != c )
+ d--;
+ }
+ else // case insensitive
+ {
+ c = tolower( (uchar) c );
+ while ( d >= b && tolower((uchar) *d) != c )
+ d--;
+ }
+ return d >= b ? (int)(d - b) : -1;
+}
+
+int QCString::findRev( const char *str, int index, bool cs) const
+{
+ int slen = qstrlen(str);
+ uint len = length();
+ if ( index < 0 ) // neg index ==> start from end
+ index = len-slen;
+ else if ( (uint)index > len ) // bad index
+ return -1;
+ else if ( (uint)(index + slen) > len ) // str would be too long
+ index = len - slen;
+ if ( index < 0 )
return -1;
-}
-
-
-/*!
- Returns the number of times the character \e c occurs in the string.
- The match is case sensitive if \e cs is TRUE, or case insensitive if \e cs
- if FALSE.
-*/
+ 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 QCString::contains( char c, bool cs ) const
-{
- int count = 0;
- char *d = data();
- if ( !d )
- return 0;
- if ( cs ) { // case sensitive
- while ( *d )
- if ( *d++ == c )
- count++;
- } else { // case insensitive
- c = tolower( (uchar) c );
- while ( *d ) {
- if ( tolower((uchar) *d) == c )
- count++;
- d++;
- }
- }
- return count;
}
-/*!
- Returns the number of times \e str occurs in the string.
-
- The match is case sensitive if \e cs is TRUE, or case insensitive if \e
- cs if FALSE.
-
- This function counts overlapping substrings, for example, "banana"
- contains two occurrences of "ana".
-
- \sa findRev()
-*/
-
-int QCString::contains( const char *str, bool cs ) const
+int QCString::findRev( const QRegExp &rx, int index ) 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;
+ QString d = QString::fromLatin1( m_data );
+ return d.findRev( rx, index );
}
-/*!
- Returns a substring that contains the \e len leftmost characters
- of the string.
-
- The whole string is returned if \e len exceeds the length of the string.
-
- Example:
- \code
- QCString s = "Pineapple";
- QCString t = s.left( 4 ); // t == "Pine"
- \endcode
-
- \sa right(), mid()
-*/
-
-QCString QCString::left( uint len ) const
+int QCString::contains( char c, bool cs ) const
{
- if ( isEmpty() ) {
- QCString empty;
- return empty;
- } else if ( len >= size() ) {
- QCString same( data() );
- return same;
- } else {
- QCString s( len+1 );
- strncpy( s.data(), data(), len );
- *(s.data()+len) = '\0';
- return s;
- }
+ 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;
}
-/*!
- Returns a substring that contains the \e len rightmost characters
- of the string.
-
- The whole string is returned if \e len exceeds the length of the string.
-
- Example:
- \code
- QCString s = "Pineapple";
- QCString t = s.right( 5 ); // t == "apple"
- \endcode
-
- \sa left(), mid()
-*/
-
-QCString QCString::right( uint len ) const
+int QCString::contains( const char *str, bool cs ) const
{
- if ( isEmpty() ) {
- QCString empty;
- return empty;
- } else {
- uint l = length();
- if ( len > l )
- len = l;
- char *p = data() + (l - len);
- return QCString( p );
- }
+ int count = 0;
+ char *d = data();
+ if ( !d )
+ return 0;
+ int len = qstrlen( str );
+ while ( *d ) // counts overlapping strings
+ {
+ if ( cs )
+ {
+ if ( qstrncmp( d, str, len ) == 0 )
+ count++;
+ }
+ else
+ {
+ if ( qstrnicmp(d, str, len) == 0 )
+ count++;
+ }
+ d++;
+ }
+ return count;
}
-/*!
- Returns a substring that contains the \e len characters of this
- string, starting at position \e index.
-
- Returns a null string if the string is empty or \e index is out
- of range. Returns the whole string from \e index if \e index+len exceeds
- the length of the string.
-
- Example:
- \code
- QCString s = "Two pineapples";
- QCString t = s.mid( 4, 4 ); // t == "pine"
- \endcode
-
- \sa left(), right()
-*/
-
-QCString QCString::mid( uint index, uint len ) const
-{
- if ( len == 0xffffffff ) len = length()-index;
- uint slen = qstrlen( data() );
- if ( isEmpty() || index >= slen ) {
- QCString empty;
- return empty;
- } else {
- register char *p = data()+index;
- QCString s( len+1 );
- strncpy( s.data(), p, len );
- *(s.data()+len) = '\0';
- return s;
- }
+int QCString::contains( const QRegExp &rx ) const
+{
+ QString d = QString::fromLatin1( m_data );
+ return d.contains( rx );
}
-/*!
- Returns a string of length \e width (plus '\0') that contains this
- string and padded by the \e fill character.
-
- If the length of the string exceeds \e width and \e truncate is FALSE,
- then the returned string is a copy of the string.
- If the length of the string exceeds \e width and \e truncate is TRUE,
- then the returned string is a left(\e width).
-
- Example:
- \code
- QCString s("apple");
- QCString t = s.leftJustify(8, '.'); // t == "apple..."
- \endcode
-
- \sa rightJustify()
-*/
-
-QCString QCString::leftJustify( uint width, char fill, bool truncate ) const
+QCString QCString::left( uint len ) const
{
- QCString result;
- int len = qstrlen(data());
- int padlen = width - len;
- if ( padlen > 0 ) {
- result.QByteArray::resize( len+padlen+1 );
- memcpy( result.data(), data(), len );
- memset( result.data()+len, fill, padlen );
- result[len+padlen] = '\0';
- } else {
- if ( truncate )
- result = left( width );
- else
- result = copy();
- }
- return result;
+ if ( isEmpty() )
+ {
+ return QCString();
+ }
+ else if ( len >= length() )
+ {
+ return *this;
+ }
+ else
+ {
+ QCString s( len+1 );
+ strncpy( s.data(), m_data, len );
+ *(s.data()+len) = '\0';
+ return s;
+ }
}
-/*!
- Returns a string of length \e width (plus '\0') that contains pad
- characters followed by the string.
-
- If the length of the string exceeds \e width and \e truncate is FALSE,
- then the returned string is a copy of the string.
- If the length of the string exceeds \e width and \e truncate is TRUE,
- then the returned string is a left(\e width).
-
- Example:
- \code
- QCString s("pie");
- QCString t = s.rightJustify(8, '.'); // t == ".....pie"
- \endcode
-
- \sa leftJustify()
-*/
-
-QCString QCString::rightJustify( uint width, char fill, bool truncate ) const
+QCString QCString::right( uint len ) const
{
- QCString result;
- int len = qstrlen(data());
- int padlen = width - len;
- if ( padlen > 0 ) {
- result.QByteArray::resize( len+padlen+1 );
- memset( result.data(), fill, padlen );
- memcpy( result.data()+padlen, data(), len );
- result[len+padlen] = '\0';
- } else {
- if ( truncate )
- result = left( width );
- else
- result = copy();
- }
- return result;
+ if ( isEmpty() )
+ {
+ return QCString();
+ }
+ else
+ {
+ uint l = length();
+ if ( len > l ) len = l;
+ char *p = m_data + (l - len);
+ return QCString( p );
+ }
+}
+
+QCString QCString::mid( uint index, uint len) const
+{
+ uint slen = length();
+ if ( len == 0xffffffff ) len = slen-index;
+ if ( isEmpty() || index >= slen )
+ {
+ return QCString();
+ }
+ else
+ {
+ register char *p = data()+index;
+ QCString s( len+1 );
+ strncpy( s.data(), p, len );
+ *(s.data()+len) = '\0';
+ return s;
+ }
}
-/*!
- Returns a new string that is the string converted to lower case.
-
- Presently it only handles 7-bit ASCII, or whatever tolower()
- handles (if $LC_CTYPE is set, most UNIX systems do the Right Thing).
-
- Example:
- \code
- QCString s("TeX");
- QCString t = s.lower(); // t == "tex"
- \endcode
-
- \sa upper()
-*/
-
QCString QCString::lower() const
{
- QCString s( data() );
- register char *p = s.data();
- if ( p ) {
- while ( *p ) {
- *p = tolower((uchar) *p);
- p++;
- }
+ QCString s( m_data );
+ register char *p = s.data();
+ if ( p )
+ {
+ while ( *p )
+ {
+ *p = tolower((uchar) *p);
+ p++;
}
- return s;
+ }
+ return s;
}
-/*!
- Returns a new string that is the string converted to upper case.
-
- Presently it only handles 7-bit ASCII, or whatever toupper()
- handles (if $LC_CTYPE is set, most UNIX systems do the Right Thing).
-
- Example:
- \code
- QCString s("TeX");
- QCString t = s.upper(); // t == "TEX"
- \endcode
-
- \sa lower()
-*/
-
QCString QCString::upper() const
{
- QCString s( data() );
- register char *p = s.data();
- if ( p ) {
- while ( *p ) {
- *p = toupper((uchar)*p);
- p++;
- }
+ QCString s( m_data );
+ register char *p = s.data();
+ if ( p ) {
+ while ( *p ) {
+ *p = toupper((uchar)*p);
+ p++;
}
- return s;
+ }
+ return s;
}
-
-/*!
- Returns a new string that has white space removed from the start and the end.
-
- White space means any ASCII code 9, 10, 11, 12, 13 or 32.
-
- Example:
- \code
- QCString s = " space ";
- QCString t = s.stripWhiteSpace(); // t == "space"
- \endcode
-
- \sa simplifyWhiteSpace()
-*/
-
-QCString QCString::stripWhiteSpace() const
+QCString QCString::stripWhiteSpace() const
{
- if ( isEmpty() ) // nothing to do
- return copy();
-
- register char *s = data();
- QCString result = s;
- int reslen = result.length();
- if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
- return result; // returns a copy
-
- s = result.data();
- int start = 0;
- int end = reslen - 1;
- while ( isspace((uchar) s[start]) ) // skip white space from start
- start++;
- if ( s[start] == '\0' ) { // only white space
- result.resize( 1 );
- return result;
- }
- 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;
-}
-
-
-/*!
- Returns a new string that has white space removed from the start and the end,
- plus any sequence of internal white space replaced with a single space
- (ASCII 32).
-
- White space means any ASCII code 9, 10, 11, 12, 13 or 32.
-
- \code
- QCString s = " lots\t of\nwhite space ";
- QCString t = s.simplifyWhiteSpace(); // t == "lots of white space"
- \endcode
+ if ( isEmpty() ) // nothing to do
+ return *this;
- \sa stripWhiteSpace()
-*/
+ register char *s = m_data;
+ int reslen = length();
+ if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
+ return *this; // returns a copy
+
+ QCString result(s);
+ s = result.data();
+ int start = 0;
+ int end = reslen - 1;
+ while ( isspace((uchar) s[start]) ) // skip white space from start
+ start++;
+ if ( s[start] == '\0' )
+ { // only white space
+ return QCString();
+ }
+ while ( end && isspace((uchar) s[end]) ) // skip white space from end
+ end--;
+ end -= start - 1;
+ memmove( result.data(), &s[start], end );
+ result.resize( end + 1 );
+ return result;
+}
QCString QCString::simplifyWhiteSpace() const
{
- if ( isEmpty() ) // nothing to do
- return copy();
- QCString result( size() );
- char *from = data();
- char *to = result.data();
- char *first = to;
- while ( TRUE ) {
- while ( *from && isspace((uchar) *from) )
- from++;
- while ( *from && !isspace((uchar)*from) )
- *to++ = *from++;
- if ( *from )
- *to++ = 0x20; // ' '
- else
- break;
- }
- if ( to > first && *(to-1) == 0x20 )
- to--;
- *to = '\0';
- result.resize( (int)((long)to - (long)result.data()) + 1 );
- return result;
-}
-
-
-/*!
- Insert \e s into the string before position \e index.
-
- If \e index is beyond the end of the string, the string is extended with
- spaces (ASCII 32) to length \e index and \e s is then appended.
+ if ( isEmpty() ) // nothing to do
+ return *this;
- \code
- QCString s = "I like fish";
- s.insert( 2, "don't "); // s == "I don't like fish"
- s = "x";
- s.insert( 3, "yz" ); // s == "x yz"
- \endcode
-*/
+ QCString result( length()+1 );
+ char *from = data();
+ char *to = result.data();
+ char *first = to;
+ while ( TRUE )
+ {
+ while ( *from && isspace((uchar) *from) )
+ from++;
+ while ( *from && !isspace((uchar)*from) )
+ *to++ = *from++;
+ if ( *from )
+ *to++ = 0x20; // ' '
+ else
+ break;
+ }
+ if ( to > first && *(to-1) == 0x20 )
+ to--;
+ *to = '\0';
+ result.resize( (int)((long)to - (long)result.data()) + 1 );
+ return result;
+}
QCString &QCString::insert( uint index, const char *s )
-{
- int len = qstrlen(s);
- if ( len == 0 )
- return *this;
- uint olen = length();
- int nlen = olen + len;
- if ( index >= olen ) { // insert after end of string
- detach();
- if ( QByteArray::resize(nlen+index-olen+1) ) {
- memset( data()+olen, ' ', index-olen );
- memcpy( data()+index, s, len+1 );
- }
- } else if ( QByteArray::resize(nlen+1) ) { // normal insert
- detach();
- memmove( data()+index+len, data()+index, olen-index+1 );
- memcpy( data()+index, s, len );
- }
+{
+ 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;
}
-/*!
- Insert \e c into the string at (before) position \e index and returns
- a reference to the string.
-
- If \e index is beyond the end of the string, the string is extended with
- spaces (ASCII 32) to length \e index and \e c is then appended.
-
- Example:
- \code
- QCString s = "Yes";
- s.insert( 3, '!'); // s == "Yes!"
- \endcode
-
- \sa remove(), replace()
-*/
-
-QCString &QCString::insert( uint index, char c ) // insert char
+QCString &QCString::insert( uint index, char c ) // insert char
{
- char buf[2];
- buf[0] = c;
- buf[1] = '\0';
- return insert( index, buf );
+ char buf[2];
+ buf[0] = c;
+ buf[1] = '\0';
+ return insert( index, buf );
}
-/*!
- \fn QCString &QCString::prepend( const char *s )
-
- Prepend \a s to the string. Equivalent to insert(0,s).
-
- \sa insert()
-*/
-
-/*!
- Removes \e len characters starting at position \e index from the
- string and returns a reference to the string.
-
- If \e index is too big, nothing happens. If \e index is valid, but
- \e len is too large, the rest of the string is removed.
-
- \code
- QCString s = "Montreal";
- s.remove( 1, 4 );
- // s == "Meal"
- \endcode
-
- \sa insert(), replace()
-*/
-
-QCString &QCString::remove( uint index, uint len )
+QCString& QCString::operator+=( const char *str )
{
- uint olen = length();
- if ( index + len >= olen ) { // range problems
- if ( index < olen ) { // index ok
- detach();
- resize( index+1 );
- }
- } else if ( len != 0 ) {
- detach();
- memmove( data()+index, data()+index+len, olen-index-len+1 );
- QByteArray::resize(olen-len+1);
- }
- return *this;
+ 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;
}
-/*!
- Replaces \e len characters starting at position \e index from the
- string with \e s, and returns a reference to the string.
-
- If \e index is too big, nothing is deleted and \e s is inserted at the
- end of the string. If \e index is valid, but \e len is too large, \e
- str replaces the rest of the string.
-
- \code
- QCString s = "Say yes!";
- s.replace( 4, 3, "NO" ); // s == "Say NO!"
- \endcode
-
- \sa insert(), remove()
-*/
-
-QCString &QCString::replace( uint index, uint len, const char *s )
-{
- remove( index, len );
- insert( index, s );
- return *this;
-}
-
-
-/*!
- Finds the first occurrence of the regular expression \e rx, starting at
- position \e index.
-
- Returns the position of the next match, or -1 if \e rx was not found.
-*/
-
-int QCString::find( const QRegExp &rx, int index ) const
+QCString &QCString::operator+=( char c )
{
- QString d = QString::fromLatin1( data() );
- return d.find( rx, index );
+ 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;
}
-/*!
- Finds the first occurrence of the regular expression \e rx, starting at
- position \e index and searching backwards.
-
- The search will start from the end of the string if \e index is negative.
-
- Returns the position of the next match (backwards), or -1 if \e rx was not
- found.
-*/
-
-int QCString::findRev( const QRegExp &rx, int index ) const
+QCString &QCString::remove( uint index, uint len )
{
- QString d = QString::fromLatin1( data() );
- return d.findRev( rx, index );
+ 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;
}
-/*!
- Counts the number of overlapping occurrences of \e rx in the string.
-
- Example:
- \code
- QString s = "banana and panama";
- QRegExp r = QRegExp("a[nm]a", TRUE, FALSE);
- s.contains( r ); // 4 matches
- \endcode
-
- \sa find(), findRev()
-*/
-
-int QCString::contains( const QRegExp &rx ) const
+QCString &QCString::replace( uint index, uint len, const char *s )
{
- QString d = QString::fromLatin1( data() );
- return d.contains( rx );
+ remove( index, len );
+ insert( index, s );
+ return *this;
}
-
-/*!
- Replaces every occurrence of \e rx in the string with \e str.
- Returns a reference to the string.
-
- Example:
- \code
- QString s = "banana";
- s.replace( QRegExp("a.*a"), "" ); // becomes "b"
-
- QString s = "banana";
- s.replace( QRegExp("^[bn]a"), " " ); // becomes " nana"
-
- QString s = "banana";
- s.replace( QRegExp("^[bn]a"), "" ); // NOTE! becomes ""
- \endcode
-
-*/
-
QCString &QCString::replace( const QRegExp &rx, const char *str )
{
- QString d = QString::fromLatin1( data() );
- QString r = QString::fromLatin1( str );
- d.replace( rx, r );
- setStr( d.ascii() );
- return *this;
+ QString d = QString::fromLatin1( m_data );
+ QString r = QString::fromLatin1( str );
+ d.replace( rx, r );
+ operator=( d.ascii() );
+ return *this;
}
-/*!
- Returns the string converted to a <code>long</code> value.
-
- If \e ok is non-null, \e *ok is set to TRUE if there are no
- conceivable errors, and FALSE if the string is not a number at all, or if
- it has trailing garbage.
-*/
-
-long QCString::toLong( bool *ok ) const
+long QCString::toLong( bool *ok ) const
{
- char *p = data();
- long val=0;
- const long max_mult = 214748364;
- bool is_ok = FALSE;
- int neg = 0;
- if ( !p )
- goto bye;
- while ( isspace((uchar)*p) ) // skip leading space
- p++;
- if ( *p == '-' ) {
- p++;
- neg = 1;
- } else if ( *p == '+' ) {
- p++;
- }
- if ( !isdigit((uchar)*p) )
- goto bye;
- while ( isdigit((uchar)*p) ) {
- if ( val > max_mult || (val == max_mult && (*p-'0') > 7+neg) )
- goto bye;
- val = 10*val + (*p++ - '0');
- }
- if ( neg )
- val = -val;
- while ( isspace((uchar)*p) ) // skip trailing space
- p++;
- if ( *p == '\0' )
- is_ok = TRUE;
-bye:
- if ( ok )
- *ok = is_ok;
- return is_ok ? val : 0;
+ QString s(m_data);
+ return s.toLong(ok);
}
-/*!
- Returns the string converted to an <code>unsigned long</code>
- value.
-
- If \e ok is non-null, \e *ok is set to TRUE if there are no
- conceivable errors, and FALSE if the string is not a number at all,
- or if it has trailing garbage.
-*/
-
ulong QCString::toULong( bool *ok ) const
{
- char *p = data();
- ulong val=0;
- const ulong max_mult = 429496729;
- bool is_ok = FALSE;
- if ( !p )
- goto bye;
- while ( isspace((uchar)*p) ) // skip leading space
- p++;
- if ( *p == '+' )
- p++;
- if ( !isdigit((uchar)*p) )
- goto bye;
- while ( isdigit((uchar)*p) ) {
- if ( val > max_mult || (val == max_mult && (*p-'0') > 5) )
- goto bye;
- val = 10*val + (*p++ - '0');
- }
- while ( isspace((uchar)*p) ) // skip trailing space
- p++;
- if ( *p == '\0' )
- is_ok = TRUE;
-bye:
- if ( ok )
- *ok = is_ok;
- return is_ok ? val : 0;
+ QString s(m_data);
+ return s.toULong(ok);
}
-/*!
- Returns the string converted to a <code>short</code> value.
-
- If \e ok is non-null, \e *ok is set to TRUE if there are no
- conceivable errors, and FALSE if the string is not a number at all, or if
- it has trailing garbage.
-*/
-
-short QCString::toShort( bool *ok ) const
+short QCString::toShort( bool *ok ) const
{
- long v = toLong( ok );
- if ( ok && *ok && (v < -32768 || v > 32767) )
- *ok = FALSE;
- return (short)v;
+ QString s(m_data);
+ return s.toShort(ok);
}
-/*!
- Returns the string converted to an <code>unsigned short</code> value.
-
- If \e ok is non-null, \e *ok is set to TRUE if there are no
- conceivable errors, and FALSE if the string is not a number at all, or if
- it has trailing garbage.
-*/
-
ushort QCString::toUShort( bool *ok ) const
{
- ulong v = toULong( ok );
- if ( ok && *ok && (v > 65535) )
- *ok = FALSE;
- return (ushort)v;
+ QString s(m_data);
+ return s.toUShort(ok);
}
-
-/*!
- Returns the string converted to a <code>int</code> value.
-
- If \e ok is non-null, \e *ok is set to TRUE if there are no
- conceivable errors, and FALSE if the string is not a number at all,
- or if it has trailing garbage.
-*/
-
int QCString::toInt( bool *ok ) const
{
- return (int)toLong( ok );
+ QString s(m_data);
+ return s.toInt(ok);
}
-/*!
- Returns the string converted to an <code>unsigned int</code> value.
-
- If \e ok is non-null, \e *ok is set to TRUE if there are no
- conceivable errors, and FALSE if the string is not a number at all,
- or if it has trailing garbage.
-*/
-
uint QCString::toUInt( bool *ok ) const
{
- return (uint)toULong( ok );
+ QString s(m_data);
+ return s.toUInt(ok);
}
-/*!
- Returns the string converted to a <code>double</code> value.
-
- If \e ok is non-null, \e *ok is set to TRUE if there are no conceivable
- errors, and FALSE if the string is not a number at all, or if it has
- trailing garbage.
-*/
-
-double QCString::toDouble( bool *ok ) const
+QCString &QCString::setNum( long n )
{
- char *end;
- double val = strtod( data() ? data() : "", &end );
- if ( ok )
- *ok = ( data() && *data() && ( end == 0 || *end == '\0' ) );
- return val;
+ char buf[20];
+ register char *p = &buf[19];
+ bool neg;
+ if ( n < 0 )
+ {
+ neg = TRUE;
+ n = -n;
+ }
+ else
+ {
+ neg = FALSE;
+ }
+ *p = '\0';
+ do
+ {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ if ( neg ) *--p = '-';
+ operator=( p );
+ return *this;
}
-/*!
- Returns the string converted to a <code>float</code> value.
-
- If \e ok is non-null, \e *ok is set to TRUE if there are no
- conceivable errors, and FALSE if the string is not a number at all,
- or if it has trailing garbage.
-*/
-
-float QCString::toFloat( bool *ok ) const
+QCString &QCString::setNum( ulong n )
{
- return (float)toDouble( ok );
+ char buf[20];
+ register char *p = &buf[19];
+ *p = '\0';
+ do
+ {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ operator=( p );
+ return *this;
}
+void QCString::msg_index( uint index )
+{
+#if defined(CHECK_RANGE)
+ qWarning( "QCString::at: Absolute index %d out of range", index );
+#else
+ Q_UNUSED( index )
+#endif
+}
-/*!
- Makes a deep copy of \e str.
- Returns a reference to the string.
-*/
-
-QCString &QCString::setStr( const char *str )
+bool QCString::stripPrefix(const char *prefix)
{
- detach();
- if ( str ) // valid string
- store( str, qstrlen(str)+1 );
- else // empty
- resize( 0 );
- return *this;
+ if (prefix==0) return FALSE;
+ uint plen = qstrlen(prefix);
+ if (m_data && qstrncmp(prefix,m_data,plen)==0) // prefix matches
+ {
+ uint len = qstrlen(m_data);
+ uint newlen = len-plen+1;
+ qmemmove(m_data,m_data+plen,newlen);
+ resize(newlen);
+ return TRUE;
+ }
+ return FALSE;
}
-/*!
- Sets the string to the printed value of \e n and returns a
- reference to the string.
-*/
+//---------------------------------------------------------------------------
-QCString &QCString::setNum( long n )
+void *qmemmove( void *dst, const void *src, uint len )
{
- detach();
- char buf[20];
- register char *p = &buf[19];
- bool neg;
- if ( n < 0 ) {
- neg = TRUE;
- n = -n;
- } else {
- neg = FALSE;
+ register char *d;
+ register char *s;
+ if ( dst > src ) {
+ d = (char *)dst + len - 1;
+ s = (char *)src + len - 1;
+ while ( len-- )
+ *d-- = *s--;
+ } else if ( dst < src ) {
+ d = (char *)dst;
+ s = (char *)src;
+ while ( len-- )
+ *d++ = *s++;
}
- *p = '\0';
- do {
- *--p = ((int)(n%10)) + '0';
- n /= 10;
- } while ( n );
- if ( neg )
- *--p = '-';
- store( p, qstrlen(p)+1 );
- return *this;
+ return dst;
}
-/*!
- Sets the string to the printed unsigned value of \e n and
- returns a reference to the string.
-*/
-
-QCString &QCString::setNum( ulong n )
+char *qstrdup( const char *str )
{
- detach();
- char buf[20];
- register char *p = &buf[19];
- *p = '\0';
- do {
- *--p = ((int)(n%10)) + '0';
- n /= 10;
- } while ( n );
- store( p, qstrlen(p)+1 );
- return *this;
+ if ( !str )
+ return 0;
+ char *dst = new char[strlen(str)+1];
+ CHECK_PTR( dst );
+ return strcpy( dst, str );
}
-/*!
- \fn QCString &QCString::setNum( int n )
- Sets the string to the printed value of \e n and returns a reference
- to the string.
-*/
-
-/*!
- \fn QCString &QCString::setNum( uint n )
- Sets the string to the printed unsigned value of \e n and returns a
- reference to the string.
-*/
-
-/*!
- \fn QCString &QCString::setNum( short n )
- Sets the string to the printed value of \e n and returns a reference
- to the string.
-*/
-
-/*!
- \fn QCString &QCString::setNum( ushort n )
- Sets the string to the printed unsigned value of \e n and returns a
- reference to the string.
-*/
-
-/*!
- Sets the string to the printed value of \e n.
-
- \arg \e f is the format specifier: 'f', 'F', 'e', 'E', 'g', 'G' (same
- as sprintf()).
- \arg \e prec is the precision.
-
- Returns a reference to the string.
-*/
-
-QCString &QCString::setNum( double n, char f, int prec )
+char *qstrncpy( char *dst, const char *src, uint len )
{
-#if defined(CHECK_RANGE)
- if ( !(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G') )
- qWarning( "QCString::setNum: Invalid format char '%c'", f );
-#endif
- char format[20];
- register char *fs = format; // generate format string
- *fs++ = '%'; // "%.<prec>l<f>"
- if ( prec > 99 )
- prec = 99;
- *fs++ = '.';
- if ( prec >= 10 ) {
- *fs++ = prec / 10 + '0';
- *fs++ = prec % 10 + '0';
- } else {
- *fs++ = prec + '0';
- }
- *fs++ = 'l';
- *fs++ = f;
- *fs = '\0';
- return sprintf( format, n );
+ if ( !src )
+ return 0;
+ strncpy( dst, src, len );
+ if ( len > 0 )
+ dst[len-1] = '\0';
+ return dst;
}
-/*!
- \fn QCString &QCString::setNum( float n, char f, int prec )
- Sets the string to the printed value of \e n.
-
- \arg \e f is the format specifier: 'f', 'F', 'e', 'E', 'g', 'G' (same
- as sprintf()).
- \arg \e prec is the precision.
-
- Returns a reference to the string.
-*/
-
-
-/*!
- Sets the character at position \e index to \e c and expands the
- string if necessary, filling with spaces.
-
- Returns FALSE if this \e index was out of range and the string could
- not be expanded, otherwise TRUE.
-*/
+int qstricmp( const char *str1, const char *str2 )
+{
+ register const uchar *s1 = (const uchar *)str1;
+ register const uchar *s2 = (const uchar *)str2;
+ int res;
+ uchar c;
+ if ( !s1 || !s2 )
+ return s1 == s2 ? 0 : (int)((long)s2 - (long)s1);
+ for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
+ if ( !c ) // strings are equal
+ break;
+ return res;
+}
-bool QCString::setExpand( uint index, char c )
+int qstrnicmp( const char *str1, const char *str2, uint len )
{
- detach();
- uint oldlen = length();
- if ( index >= oldlen ) {
- if ( !QByteArray::resize( index+2 ) ) // no memory
- return FALSE;
- if ( index > oldlen )
- memset( data() + oldlen, ' ', index - oldlen );
- *(data() + index+1) = '\0'; // terminate padded string
+ register const uchar *s1 = (const uchar *)str1;
+ register const uchar *s2 = (const uchar *)str2;
+ int res;
+ uchar c;
+ if ( !s1 || !s2 )
+ return (int)((long)s2 - (long)s1);
+ for ( ; len--; s1++, s2++ ) {
+ if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
+ return res;
+ if ( !c ) // strings are equal
+ break;
}
- *(data() + index) = c;
- return TRUE;
+ return 0;
}
+#ifndef QT_NO_DATASTREAM
-/*!
- \fn QCString::operator const char *() const
- Returns the string data.
-*/
-
-
-/*!
- \fn QCString& QCString::append( const char *str )
- Appends \e str to the string and returns a reference to the string.
- Equivalent to operator+=().
- */
-
-/*!
- Appends \e str to the string and returns a reference to the string.
-*/
-
-QCString& QCString::operator+=( const char *str )
+QDataStream &operator<<( QDataStream &s, const QByteArray &a )
{
- if ( !str )
- return *this; // nothing to append
- detach();
- uint len1 = length();
- uint len2 = qstrlen(str);
- if ( !QByteArray::resize( len1 + len2 + 1 ) )
- return *this; // no memory
- memcpy( data() + len1, str, len2 + 1 );
- return *this;
+ return s.writeBytes( a.data(), a.size() );
}
-/*!
- Appends \e c to the string and returns a reference to the string.
-*/
-
-QCString &QCString::operator+=( char c )
+QDataStream &operator>>( QDataStream &s, QByteArray &a )
{
- detach();
- uint len = length();
- if ( !QByteArray::resize( len + 2 ) )
- return *this; // no memory
- *(data() + len) = c;
- *(data() + len+1) = '\0';
- return *this;
+ Q_UINT32 len;
+ s >> len; // read size of array
+ if ( len == 0 || s.eof() ) { // end of file reached
+ a.resize( 0 );
+ return s;
+ }
+ if ( !a.resize( (uint)len ) ) { // resize array
+#if defined(CHECK_NULL)
+ qWarning( "QDataStream: Not enough memory to read QByteArray" );
+#endif
+ len = 0;
+ }
+ if ( len > 0 ) // not null array
+ s.readRawBytes( a.data(), (uint)len );
+ return s;
}
-
-/*****************************************************************************
- QCString stream functions
- *****************************************************************************/
-#ifndef QT_NO_DATASTREAM
-/*!
- \relates QCString
- Writes a string to the stream.
-
- \sa \link datastreamformat.html Format of the QDataStream operators \endlink
-*/
QDataStream &operator<<( QDataStream &s, const QCString &str )
{
return s.writeBytes( str.data(), str.size() );
}
-/*!
- \relates QCString
- Reads a string from the stream.
-
- \sa \link datastreamformat.html Format of the QDataStream operators \endlink
-*/
-
QDataStream &operator>>( QDataStream &s, QCString &str )
{
- str.detach();
Q_UINT32 len;
s >> len; // read size of string
if ( len == 0 || s.eof() ) { // end of file reached
str.resize( 0 );
return s;
}
- if ( !str.QByteArray::resize( (uint)len )) {// resize string
+ if ( !str.resize( (uint)len )) {// resize string
#if defined(CHECK_NULL)
qWarning( "QDataStream: Not enough memory to read QCString" );
#endif
@@ -1764,154 +775,20 @@ QDataStream &operator>>( QDataStream &s, QCString &str )
s.readRawBytes( str.data(), (uint)len );
return s;
}
-#endif //QT_NO_DATASTREAM
-
-/*****************************************************************************
- Documentation for related functions
- *****************************************************************************/
-/*!
- \fn bool operator==( const QCString &s1, const QCString &s2 )
- \relates QCString
- Returns TRUE if the two strings are equal, or FALSE if they are different.
-
- Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
-*/
+#endif //QT_NO_DATASTREAM
-/*!
- \fn bool operator==( const QCString &s1, const char *s2 )
- \relates QCString
- Returns TRUE if the two strings are equal, or FALSE if they are different.
+inline QCString operator+( const QCString &s1, const QGString &s2 )
+{
+ QCString tmp(s1);
+ tmp += s2.data();
+ return tmp;
+}
- Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
-*/
+inline QCString operator+( const QGString &s1, const QCString &s2 )
+{
+ QCString tmp(s1.data());
+ tmp += s2;
+ return tmp;
+}
-/*!
- \fn bool operator==( const char *s1, const QCString &s2 )
- \relates QCString
- Returns TRUE if the two strings are equal, or FALSE if they are different.
-
- Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
-*/
-
-/*!
- \fn bool operator!=( const QCString &s1, const QCString &s2 )
- \relates QCString
- Returns TRUE if the two strings are different, or FALSE if they are equal.
-
- Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
-*/
-
-/*!
- \fn bool operator!=( const QCString &s1, const char *s2 )
- \relates QCString
- Returns TRUE if the two strings are different, or FALSE if they are equal.
-
- Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
-*/
-
-/*!
- \fn bool operator!=( const char *s1, const QCString &s2 )
- \relates QCString
- Returns TRUE if the two strings are different, or FALSE if they are equal.
-
- Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
-*/
-
-/*!
- \fn bool operator<( const QCString &s1, const char *s2 )
- \relates QCString
- Returns TRUE if \e s1 is alphabetically less than \e s2, otherwise FALSE.
-
- Equivalent to <code>qstrcmp(s1,s2) \< 0</code>.
-*/
-
-/*!
- \fn bool operator<( const char *s1, const QCString &s2 )
- \relates QCString
- Returns TRUE if \e s1 is alphabetically less than \e s2, otherwise FALSE.
-
- Equivalent to <code>qstrcmp(s1,s2) \< 0</code>.
-*/
-
-/*!
- \fn bool operator<=( const QCString &s1, const char *s2 )
- \relates QCString
- Returns TRUE if \e s1 is alphabetically less than or equal to \e s2,
- otherwise FALSE.
-
- Equivalent to <code>qstrcmp(s1,s2) \<= 0</code>.
-*/
-
-/*!
- \fn bool operator<=( const char *s1, const QCString &s2 )
- \relates QCString
- Returns TRUE if \e s1 is alphabetically less than or equal to \e s2,
- otherwise FALSE.
-
- Equivalent to <code>qstrcmp(s1,s2) \<= 0</code>.
-*/
-
-/*!
- \fn bool operator>( const QCString &s1, const char *s2 )
- \relates QCString
- Returns TRUE if \e s1 is alphabetically greater than \e s2, otherwise FALSE.
-
- Equivalent to <code>qstrcmp(s1,s2) \> 0</code>.
-*/
-
-/*!
- \fn bool operator>( const char *s1, const QCString &s2 )
- \relates QCString
- Returns TRUE if \e s1 is alphabetically greater than \e s2, otherwise FALSE.
-
- Equivalent to <code>qstrcmp(s1,s2) \> 0</code>.
-*/
-
-/*!
- \fn bool operator>=( const QCString &s1, const char *s2 )
- \relates QCString
- Returns TRUE if \e s1 is alphabetically greater than or equal to \e s2,
- otherwise FALSE.
-
- Equivalent to <code>qstrcmp(s1,s2) \>= 0</code>.
-*/
-
-/*!
- \fn bool operator>=( const char *s1, const QCString &s2 )
- \relates QCString
- Returns TRUE if \e s1 is alphabetically greater than or equal to \e s2,
- otherwise FALSE.
-
- Equivalent to <code>qstrcmp(s1,s2) \>= 0</code>.
-*/
-
-/*!
- \fn QCString operator+( const QCString &s1, const QCString &s2 )
- \relates QCString
- Returns the concatenated string of s1 and s2.
-*/
-
-/*!
- \fn QCString operator+( const QCString &s1, const char *s2 )
- \relates QCString
- Returns the concatenated string of s1 and s2.
-*/
-
-/*!
- \fn QCString operator+( const char *s1, const QCString &s2 )
- \relates QCString
- Returns the concatenated string of s1 and s2.
-*/
-
-/*!
- \fn QCString operator+( const QCString &s, char c )
- \relates QCString
- Returns the concatenated string of s and c.
-*/
-
-/*!
- \fn QCString operator+( char c, const QCString &s )
- \relates QCString
- Returns the concatenated string of c and s.
-*/
diff --git a/qtools/qcstring.h b/qtools/qcstring.h
index e735462..e56b1e4 100644
--- a/qtools/qcstring.h
+++ b/qtools/qcstring.h
@@ -43,14 +43,14 @@
#include "qarray.h"
#endif // QT_H
+#include <stdlib.h>
#include <string.h>
#if defined(_OS_SUN_) && defined(_CC_GNU_)
#include <strings.h>
#endif
-//#undef SMALLSTRING
-#define SMALLSTRING
+class QGString;
/*****************************************************************************
Fixes and workarounds for some platforms
@@ -143,7 +143,6 @@ Q_EXPORT int qstrnicmp( const char *, const char *, uint len );
#endif
-
// qChecksum: Internet checksum
Q_EXPORT Q_UINT16 qChecksum( const char *s, uint len );
@@ -166,34 +165,35 @@ Q_EXPORT QDataStream &operator<<( QDataStream &, const QByteArray & );
Q_EXPORT QDataStream &operator>>( QDataStream &, QByteArray & );
#endif
-
-
-#ifdef SMALLSTRING
-#define SCString QCString
-#include "scstring.h"
-#else
-
-/*****************************************************************************
- QCString class
- *****************************************************************************/
-
class QRegExp;
-class Q_EXPORT QCString : public QByteArray // C string class
+/** This is an alternative implementation of QCString. It provides basically
+ * the same functions but uses less memory for administration. This class
+ * is just a wrapper around a plain C string requiring only 4 bytes "overhead".
+ * QCString features sharing of data and stores the string length, but
+ * requires 4 + 12 bytes for this (even for the empty string). As doxygen
+ * uses a LOT of string during a run it saves a lot of memory to use a
+ * more memory efficient implementation at the cost of relatively low
+ * runtime overhead.
+ */
+class QCString
{
public:
- QCString() {} // make null string
- QCString( int size ); // allocate size incl. \0
- QCString( const QCString &s ) : QByteArray( s ) {}
- QCString( const char *str ); // deep copy
- QCString( const char *str, uint maxlen ); // deep copy, max length
-
- QCString &operator=( const QCString &s );// shallow copy
+ QCString() : m_data(0) {} // make null string
+ QCString( const QCString &s );
+ QCString( int size );
+ QCString( const char *str );
+ QCString( const char *str, uint maxlen );
+ ~QCString();
+
+ QCString &operator=( const QCString &s );// deep copy
QCString &operator=( const char *str ); // deep copy
- bool isNull() const;
+ bool isNull() const;
bool isEmpty() const;
uint length() const;
+ uint size() const { return m_data ? length()+1 : 0; }
+ char * data() const { return m_data; }
bool resize( uint newlen );
bool truncate( uint pos );
bool fill( char c, int len = -1 );
@@ -211,24 +211,23 @@ public:
int contains( char c, bool cs=TRUE ) const;
int contains( const char *str, bool cs=TRUE ) const;
int contains( const QRegExp & ) const;
+ bool stripPrefix(const char *prefix);
QCString left( uint len ) const;
QCString right( uint len ) const;
QCString mid( uint index, uint len=0xffffffff) const;
- QCString leftJustify( uint width, char fill=' ', bool trunc=FALSE)const;
- QCString rightJustify( uint width, char fill=' ',bool trunc=FALSE)const;
-
QCString lower() const;
QCString upper() const;
QCString stripWhiteSpace() const;
QCString simplifyWhiteSpace() const;
+ QCString &assign( const char *str );
QCString &insert( uint index, const char * );
QCString &insert( uint index, char );
- QCString &append( const char * );
- QCString &prepend( const char * );
+ QCString &append( const char *s );
+ QCString &prepend( const char *s );
QCString &remove( uint index, uint len );
QCString &replace( uint index, uint len, const char * );
QCString &replace( const QRegExp &, const char * );
@@ -239,10 +238,7 @@ public:
uint toUInt( bool *ok=0 ) const;
long toLong( bool *ok=0 ) const;
ulong toULong( bool *ok=0 ) const;
- float toFloat( bool *ok=0 ) const;
- double toDouble( bool *ok=0 ) const;
- QCString &setStr( const char *s );
QCString &setNum( short );
QCString &setNum( ushort );
QCString &setNum( int );
@@ -252,14 +248,56 @@ public:
QCString &setNum( float, char f='g', int prec=6 );
QCString &setNum( double, char f='g', int prec=6 );
- bool setExpand( uint index, char c );
-
operator const char *() const;
QCString &operator+=( const char *str );
QCString &operator+=( char c );
+ char &at( uint index ) const;
+ char &operator[]( int i ) const { return at(i); }
+
+ private:
+ static void msg_index( uint );
+ void duplicate( const QCString &s );
+ void duplicate( const char *str);
+ QCString &duplicate( const char *str, int);
+
+ char * m_data;
};
-#endif
+inline char &QCString::at( uint index ) const
+{
+ return m_data[index];
+}
+
+inline void QCString::duplicate( const QCString &s )
+{
+ if (!s.isEmpty())
+ {
+ uint l = strlen(s.data());
+ m_data = (char *)malloc(l+1);
+ if (m_data) memcpy(m_data,s.data(),l+1);
+ }
+ else
+ m_data=0;
+}
+
+inline void QCString::duplicate( const char *str)
+{
+ if (str && str[0]!='\0')
+ {
+ uint l = strlen(str);
+ m_data = (char *)malloc(l+1);
+ if (m_data) memcpy(m_data,str,l+1);
+ }
+ else
+ m_data=0;
+}
+
+inline QCString &QCString::duplicate( const char *str, int)
+{
+ if (m_data) free(m_data);
+ duplicate(str);
+ return *this;
+}
/*****************************************************************************
QCString stream functions
@@ -370,21 +408,26 @@ Q_EXPORT inline bool operator>=( const char *s1, const QCString &s2 )
Q_EXPORT inline QCString operator+( const QCString &s1, const QCString &s2 )
{
- QCString tmp( s1.data() );
+ QCString tmp(s1);
tmp += s2;
return tmp;
}
+
+inline QCString operator+( const QCString &s1, const QGString &s2 );
+inline QCString operator+( const QGString &s1, const QCString &s2 );
+
+
Q_EXPORT inline QCString operator+( const QCString &s1, const char *s2 )
{
- QCString tmp( s1.data() );
+ QCString tmp(s1);
tmp += s2;
return tmp;
}
Q_EXPORT inline QCString operator+( const char *s1, const QCString &s2 )
{
- QCString tmp( s1 );
+ QCString tmp(s1);
tmp += s2;
return tmp;
}
@@ -404,4 +447,5 @@ Q_EXPORT inline QCString operator+( char c1, const QCString &s2 )
return tmp;
}
+
#endif // QCSTRING_H
diff --git a/qtools/qfile.h b/qtools/qfile.h
index cfd357b..a447d2f 100644
--- a/qtools/qfile.h
+++ b/qtools/qfile.h
@@ -52,7 +52,7 @@ class Q_EXPORT QFile : public QIODevice // file I/O device class
public:
QFile();
QFile( const QString &name );
- ~QFile();
+ virtual ~QFile();
QString name() const;
void setName( const QString &name );
@@ -95,6 +95,7 @@ public:
int handle() const;
int64 pos() const;
+ int64 toEnd();
bool seek(int64 pos);
protected:
diff --git a/qtools/qfile_unix.cpp b/qtools/qfile_unix.cpp
index fbf6acf..4d3a51b 100644
--- a/qtools/qfile_unix.cpp
+++ b/qtools/qfile_unix.cpp
@@ -643,6 +643,19 @@ int64 QFile::pos() const
return -1;
}
+int64 QFile::toEnd()
+{
+ if (isOpen())
+ {
+ // TODO: support 64 bit size
+ if (fseek( fh, 0, SEEK_END )!=-1)
+ {
+ return ftell( fh );
+ }
+ }
+ return -1;
+}
+
bool QFile::seek( int64 pos )
{
if (isOpen())
diff --git a/qtools/qfile_win32.cpp b/qtools/qfile_win32.cpp
index 83c8c8d..0cc91de 100644
--- a/qtools/qfile_win32.cpp
+++ b/qtools/qfile_win32.cpp
@@ -602,6 +602,19 @@ int64 QFile::pos() const
return -1;
}
+int64 QFile::toEnd()
+{
+ if (isOpen())
+ {
+ // TODO: support 64 bit size
+ if (fseek( fh, 0, SEEK_END )!=-1)
+ {
+ return ftell( fh );
+ }
+ }
+ return -1;
+}
+
bool QFile::seek( int64 pos )
{
if (isOpen())
diff --git a/qtools/qgstring.cpp b/qtools/qgstring.cpp
new file mode 100644
index 0000000..a19d747
--- /dev/null
+++ b/qtools/qgstring.cpp
@@ -0,0 +1,200 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2004 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "qgstring.h"
+
+#include <assert.h>
+
+#define BLOCK_SIZE 64
+#define ROUND_SIZE(x) ((x)+BLOCK_SIZE-1)&~(BLOCK_SIZE-1)
+
+QGString::QGString() // make null string
+ : m_data(0), m_len(0), m_memSize(0)
+{
+}
+
+QGString::QGString(uint size)
+{
+ m_memSize = ROUND_SIZE(size);
+ if (m_memSize==0)
+ {
+ m_data=0;
+ m_len=0;
+ }
+ else
+ {
+ m_data = (char*)malloc(m_memSize);
+ m_data[0]='\0';
+ m_len=0;
+ }
+}
+
+QGString::QGString( const QGString &s )
+{
+ if (s.m_memSize==0)
+ {
+ m_data = 0;
+ m_len = 0;
+ m_memSize = 0;
+ }
+ else
+ {
+ m_data = (char *)malloc(s.m_memSize);
+ m_len = s.m_len;
+ m_memSize = s.m_memSize;
+ qstrcpy(m_data,s.m_data);
+ }
+}
+
+QGString::QGString( const char *str )
+{
+ if (str==0)
+ {
+ m_data=0;
+ m_len=0;
+ m_memSize=0;
+ }
+ else
+ {
+ m_len = qstrlen(str);
+ m_memSize = ROUND_SIZE(m_len+1);
+ assert(m_memSize>=m_len+1);
+ m_data = (char *)malloc(m_memSize);
+ qstrcpy(m_data,str);
+ }
+}
+
+QGString::~QGString()
+{
+ free(m_data);
+ m_data=0;
+}
+
+bool QGString::resize( uint newlen )
+{
+ m_len = 0;
+ if (newlen==0)
+ {
+ if (m_data) { free(m_data); m_data=0; }
+ m_memSize=0;
+ return TRUE;
+ }
+ m_memSize = ROUND_SIZE(newlen+1);
+ assert(m_memSize>=newlen+1);
+ if (m_data==0)
+ {
+ m_data = (char *)malloc(m_memSize);
+ }
+ else
+ {
+ m_data = (char *)realloc(m_data,m_memSize);
+ }
+ if (m_data==0) return FALSE;
+ m_data[newlen-1]='\0';
+ m_len = qstrlen(m_data);
+ return TRUE;
+}
+
+QGString &QGString::operator=( const QGString &s )
+{
+ if (m_data) free(m_data);
+ if (s.m_memSize==0) // null string
+ {
+ m_data = 0;
+ m_len = 0;
+ m_memSize = 0;
+ }
+ else
+ {
+ m_len = s.m_len;
+ m_memSize = s.m_memSize;
+ m_data = (char*)malloc(m_memSize);
+ qstrcpy(m_data,s.m_data);
+ }
+ return *this;
+}
+
+QGString &QGString::operator=( const char *str )
+{
+ if (m_data) free(m_data);
+ if (str==0) // null string
+ {
+ m_data = 0;
+ m_len = 0;
+ m_memSize = 0;
+ }
+ else
+ {
+ m_len = qstrlen(str);
+ m_memSize = ROUND_SIZE(m_len+1);
+ assert(m_memSize>=m_len+1);
+ m_data = (char*)malloc(m_memSize);
+ qstrcpy(m_data,str);
+ }
+ return *this;
+}
+
+QGString &QGString::operator+=( const QGString &s )
+{
+ if (s.m_memSize==0) return *this;
+ uint len1 = length();
+ uint len2 = s.length();
+ uint memSize = ROUND_SIZE(len1 + len2 + 1);
+ assert(memSize>=len1+len2+1);
+ char *newData = memSize!=m_memSize ? (char*)realloc( m_data, memSize ) : m_data;
+ m_memSize = memSize;
+ if (m_data)
+ {
+ m_data = newData;
+ memcpy( m_data + len1, s, len2 + 1 );
+ }
+ return *this;
+}
+
+QGString &QGString::operator+=( const char *str )
+{
+ if (!str) return *this;
+ uint len1 = length();
+ uint len2 = qstrlen(str);
+ uint memSize = ROUND_SIZE(len1 + len2 + 1);
+ assert(memSize>=len1+len2+1);
+ char *newData = memSize!=m_memSize ? (char *)realloc( m_data, memSize ) : m_data;
+ m_memSize = memSize;
+ if (newData)
+ {
+ m_data = newData;
+ memcpy( m_data + len1, str, len2 + 1 );
+ }
+ m_len+=len2;
+ return *this;
+}
+
+QGString &QGString::operator+=( char c )
+{
+ uint len = m_len;
+ uint memSize = ROUND_SIZE(len+2);
+ assert(memSize>=len+2);
+ char *newData = memSize!=m_memSize ? (char *)realloc( m_data, memSize ) : m_data;
+ m_memSize = memSize;
+ if (newData)
+ {
+ m_data = newData;
+ m_data[len] = c;
+ m_data[len+1] = '\0';
+ }
+ m_len++;
+ return *this;
+}
+
diff --git a/qtools/qgstring.h b/qtools/qgstring.h
new file mode 100644
index 0000000..d3b997f
--- /dev/null
+++ b/qtools/qgstring.h
@@ -0,0 +1,137 @@
+#ifndef QGSTRING_H
+#define QGSTRING_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(_OS_SUN_) && defined(_CC_GNU_)
+#include <strings.h>
+#endif
+
+#include "qcstring.h"
+
+/*****************************************************************************
+ Fixes and workarounds for some platforms
+ *****************************************************************************/
+
+/** This is an alternative implementation of QCString.
+ */
+class QGString
+{
+ public:
+ QGString(); // make null string
+ QGString(uint size);
+ QGString( const QGString &s );
+ QGString( const char *str );
+ ~QGString() ;
+
+ bool resize( uint newlen );
+
+ QGString &operator=( const QGString &s );
+ QGString &operator=( const char *str );
+ QGString &operator+=( const QGString &s );
+ QGString &operator+=( const char *str );
+ QGString &operator+=( char c );
+
+ bool isNull() const { return m_data==0; }
+ bool isEmpty() const { return m_len==0; }
+ uint length() const { return m_len; }
+ uint size() const { return m_memSize; }
+ char * data() const { return m_data; }
+ bool truncate( uint pos ) { return resize(pos+1); }
+ operator const char *() const { return (const char *)data(); }
+ char &at( uint index ) const { return m_data[index]; }
+ char &operator[]( int i ) const { return at(i); }
+
+ private:
+ char * m_data;
+ uint m_len;
+ uint m_memSize;
+};
+
+/*****************************************************************************
+ QGString non-member operators
+ *****************************************************************************/
+
+Q_EXPORT inline bool operator==( const QGString &s1, const QGString &s2 )
+{ return qstrcmp(s1.data(),s2.data()) == 0; }
+
+Q_EXPORT inline bool operator==( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) == 0; }
+
+Q_EXPORT inline bool operator==( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) == 0; }
+
+Q_EXPORT inline bool operator!=( const QGString &s1, const QGString &s2 )
+{ return qstrcmp(s1.data(),s2.data()) != 0; }
+
+Q_EXPORT inline bool operator!=( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) != 0; }
+
+Q_EXPORT inline bool operator!=( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) != 0; }
+
+Q_EXPORT inline bool operator<( const QGString &s1, const QGString& s2 )
+{ return qstrcmp(s1.data(),s2.data()) < 0; }
+
+Q_EXPORT inline bool operator<( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) < 0; }
+
+Q_EXPORT inline bool operator<( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) < 0; }
+
+Q_EXPORT inline bool operator<=( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) <= 0; }
+
+Q_EXPORT inline bool operator<=( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) <= 0; }
+
+Q_EXPORT inline bool operator>( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) > 0; }
+
+Q_EXPORT inline bool operator>( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) > 0; }
+
+Q_EXPORT inline bool operator>=( const QGString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) >= 0; }
+
+Q_EXPORT inline bool operator>=( const char *s1, const QGString &s2 )
+{ return qstrcmp(s1,s2.data()) >= 0; }
+
+Q_EXPORT inline QGString operator+( const QGString &s1, const QGString &s2 )
+{
+ QGString tmp( s1.data() );
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QGString operator+( const QGString &s1, const char *s2 )
+{
+ QGString tmp( s1.data() );
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QGString operator+( const char *s1, const QGString &s2 )
+{
+ QGString tmp( s1 );
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QGString operator+( const QGString &s1, char c2 )
+{
+ QGString tmp( s1.data() );
+ tmp += c2;
+ return tmp;
+}
+
+Q_EXPORT inline QGString operator+( char c1, const QGString &s2 )
+{
+ QGString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+#endif // QGSTRING_H
diff --git a/qtools/qtools.pro.in b/qtools/qtools.pro.in
index 718803e..d2550f6 100644
--- a/qtools/qtools.pro.in
+++ b/qtools/qtools.pro.in
@@ -22,6 +22,7 @@ HEADERS = qarray.h \
qgeneric.h \
qglist.h \
qglobal.h \
+ qgstring.h \
qgvector.h \
qintdict.h \
qiodevice.h \
@@ -57,6 +58,7 @@ SOURCES = qbuffer.cpp \
qgdict.cpp \
qglist.cpp \
qglobal.cpp \
+ qgstring.cpp \
qgvector.cpp \
qiodevice.cpp \
qregexp.cpp \