author | llornkcor <llornkcor> | 2003-07-10 02:40:10 (UTC) |
---|---|---|
committer | llornkcor <llornkcor> | 2003-07-10 02:40:10 (UTC) |
commit | 155d68c1e7d7dc0fed2534ac43d6d77ce2781f55 (patch) (side-by-side diff) | |
tree | e6edaa5a7040fe6c224c3943d1094dcf02e4f74c /qmake/tools | |
parent | 86703e8a5527ef114facd02c005b6b3a7e62e263 (diff) | |
download | opie-155d68c1e7d7dc0fed2534ac43d6d77ce2781f55.zip opie-155d68c1e7d7dc0fed2534ac43d6d77ce2781f55.tar.gz opie-155d68c1e7d7dc0fed2534ac43d6d77ce2781f55.tar.bz2 |
update qmake to 1.05a
31 files changed, 1035 insertions, 598 deletions
diff --git a/qmake/tools/qbitarray.cpp b/qmake/tools/qbitarray.cpp index 4f4e14b..1aaf963 100644 --- a/qmake/tools/qbitarray.cpp +++ b/qmake/tools/qbitarray.cpp @@ -196,9 +196,10 @@ void QBitArray::pad0() */ /*! Resizes the bit array to \a size bits and returns TRUE if the bit - array could be resized; otherwise returns FALSE. + array could be resized; otherwise returns FALSE. The array becomes + a null array if \a size == 0. If the array is expanded, the new bits are set to 0. \sa size() diff --git a/qmake/tools/qbuffer.cpp b/qmake/tools/qbuffer.cpp index b213dd9..0fc90e4 100644 --- a/qmake/tools/qbuffer.cpp +++ b/qmake/tools/qbuffer.cpp @@ -195,10 +195,10 @@ bool QBuffer::open( int m ) return FALSE; } setMode( m ); if ( m & IO_Truncate ) { // truncate buffer - a.resize( 0 ); - a_len = 0; + a.resize( 1 ); + a_len = 1; } if ( m & IO_Append ) { // append to end of buffer ioIndex = a.size(); } else { diff --git a/qmake/tools/qcomlibrary.cpp b/qmake/tools/qcomlibrary.cpp index a7162fc..2a1b75a 100644 --- a/qmake/tools/qcomlibrary.cpp +++ b/qmake/tools/qcomlibrary.cpp @@ -62,8 +62,12 @@ QComLibrary::QComLibrary( const QString &filename ) QComLibrary::~QComLibrary() { if ( autoUnload() ) unload(); + if ( libiface ) + libiface->release(); + if ( entry ) + entry->release(); } bool QComLibrary::unload() { @@ -390,12 +394,11 @@ void QComLibrary::createInstanceInternal() QCString key; bool query_done = FALSE; bool warn_mismatch = TRUE; - if ( ! query_done ) { - #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &cache ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &cache ) : 0 ); #endif // QT_THREAD_SUPPORT if ( ! cache ) { cache = new QSettings; @@ -414,9 +417,8 @@ void QComLibrary::createInstanceInternal() query_done = TRUE; warn_mismatch = FALSE; } } - } #if defined(Q_OS_UNIX) if ( ! query_done ) { // get the query information directly from the plugin without loading @@ -460,13 +462,8 @@ void QComLibrary::createInstanceInternal() << key << lastModified; if ( queried != reg ) { - -#ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &cache ) ); -#endif // QT_THREAD_SUPPORT - cache->writeEntry( regkey, queried ); // delete the cache, which forces the settings to be written delete cache; cache = 0; diff --git a/qmake/tools/qconfig.cpp b/qmake/tools/qconfig.cpp index 433827c..5297a4e 100644 --- a/qmake/tools/qconfig.cpp +++ b/qmake/tools/qconfig.cpp @@ -1,13 +1,13 @@ /* Install paths from configure */ -static const char QT_INSTALL_PREFIX [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2"; -static const char QT_INSTALL_BINS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/bin"; -static const char QT_INSTALL_DOCS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/doc"; -static const char QT_INSTALL_HEADERS[256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/include"; -static const char QT_INSTALL_LIBS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/lib"; -static const char QT_INSTALL_PLUGINS[256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/plugins"; -static const char QT_INSTALL_DATA [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2"; +static const char QT_INSTALL_PREFIX [256] = "/opt/qt-x11-free-3.1.2"; +static const char QT_INSTALL_BINS [256] = "/opt/qt-x11-free-3.1.2/bin"; +static const char QT_INSTALL_DOCS [256] = "/opt/qt-x11-free-3.1.2/doc"; +static const char QT_INSTALL_HEADERS[256] = "/opt/qt-x11-free-3.1.2/include"; +static const char QT_INSTALL_LIBS [256] = "/opt/qt-x11-free-3.1.2/lib"; +static const char QT_INSTALL_PLUGINS[256] = "/opt/qt-x11-free-3.1.2/plugins"; +static const char QT_INSTALL_DATA [256] = "/opt/qt-x11-free-3.1.2"; const char *qInstallPath() { return QT_INSTALL_PREFIX; } const char *qInstallPathDocs() { return QT_INSTALL_DOCS; } const char *qInstallPathHeaders() { return QT_INSTALL_HEADERS; } diff --git a/qmake/tools/qcriticalsection_p.cpp b/qmake/tools/qcriticalsection_p.cpp index 60fc8bd..c375730 100644 --- a/qmake/tools/qcriticalsection_p.cpp +++ b/qmake/tools/qcriticalsection_p.cpp @@ -2,10 +2,8 @@ ** $Id$ ** ** Implementation of QCriticalSection class ** -** Created : -** ** Copyright (C) 2001 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** diff --git a/qmake/tools/qcstring.cpp b/qmake/tools/qcstring.cpp index cf1b853..4651b97 100644 --- a/qmake/tools/qcstring.cpp +++ b/qmake/tools/qcstring.cpp @@ -140,8 +140,19 @@ char *qstrncpy( char *dst, const char *src, uint len ) return dst; } /*! + \fn uint qstrlen( const char *str ); + + \relates QCString + + A safe strlen function. + + Returns the number of characters that precede the terminating '\0'. + or 0 if \a str is 0. +*/ + +/*! \fn int qstrcmp( const char *str1, const char *str2 ); \relates QCString @@ -298,9 +309,10 @@ Q_UINT16 qChecksum( const char *data, uint len ) { if ( !crc_tbl_init ) { // create lookup table #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &crc_tbl_init ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &crc_tbl_init ) : 0 ); #endif // QT_THREAD_SUPPORT if ( !crc_tbl_init ) { createCRC16Table(); @@ -318,20 +330,26 @@ Q_UINT16 qChecksum( const char *data, uint len ) } return ~crc & 0xffff; } -/*! \fn QByteArray qCompress( const QByteArray& data) +/*! + \fn QByteArray qCompress( const QByteArray& data ) + \relates QByteArray - \overload + + Compresses the array \a data and returns the compressed byte + array. + + \sa qUncompress() */ /*! \relates QByteArray + \overload + Compresses the array \a data which is \a nbytes long and returns the compressed byte array. - - \sa qUncompress() */ #ifndef QT_NO_COMPRESS QByteArray qCompress( const uchar* data, int nbytes ) @@ -378,22 +396,34 @@ QByteArray qCompress( const uchar* data, int nbytes ) return bazip; } #endif -/*! \fn QByteArray qUncompress( const QByteArray& data ) +/*! + \fn QByteArray qUncompress( const QByteArray& data ) + \relates QByteArray - \overload + + Uncompresses the array \a data and returns the uncompressed byte + array. + + Returns an empty QByteArray if the input data was corrupt. + \omit + ADD THE FOLLOWING FOR Qt 4.0 + This function will uncompress data compressed with qCompress() + from this and any earlier Qt version, back to Qt 3.1 when this + feature was added. + \endomit + + \sa qCompress() */ /*! \relates QByteArray + \overload + Uncompresses the array \a data which is \a nbytes long and returns the uncompressed byte array. - - Returns an empty QByteArray if the input data was corrupt. - - \sa qCompress() */ #ifndef QT_NO_COMPRESS QByteArray qUncompress( const uchar* data, int nbytes ) @@ -935,15 +965,19 @@ int QCString::find( char c, int index, bool cs ) const */ int QCString::find( const char *str, int index, bool cs ) const { + return find( str, index, cs, length() ); +} + +int QCString::find( const char *str, int index, bool cs, uint l ) const +{ if ( (uint)index >= size() ) return -1; if ( !str ) return -1; if ( !*str ) return index; - const uint l = length(); const uint sl = qstrlen( str ); if ( sl + index > l ) return -1; @@ -1151,10 +1185,11 @@ int QCString::contains( char c, bool cs ) const int QCString::contains( const char *str, bool cs ) const { int count = 0; int i = -1; + uint l = length(); // use find for the faster hashing algorithm - while ( ( i = find ( str, i+1, cs ) ) != -1 ) + while ( ( i = find ( str, i+1, cs, l ) ) != -1 ) count++; return count; } @@ -1172,9 +1207,8 @@ int QCString::contains( const char *str, bool cs ) const \endcode \sa right(), mid() */ - QCString QCString::left( uint len ) const { if ( isEmpty() ) { QCString empty; @@ -1496,17 +1530,19 @@ QCString &QCString::insert( uint index, const char *s ) uint olen = length(); int nlen = olen + len; if ( index >= olen ) { // insert after end of string detach(); - if ( QByteArray::resize(nlen+index-olen+1) ) { + if ( QByteArray::resize(nlen+index-olen+1, QByteArray::SpeedOptim ) ) { memset( data()+olen, ' ', index-olen ); memcpy( data()+index, s, len+1 ); } - } else if ( QByteArray::resize(nlen+1) ) { // normal insert + } else { detach(); + if ( QByteArray::resize(nlen+1, QByteArray::SpeedOptim ) ) { // normal insert memmove( data()+index+len, data()+index, olen-index+1 ); memcpy( data()+index, s, len ); } + } return *this; } /*! @@ -1568,9 +1604,9 @@ QCString &QCString::remove( uint index, uint len ) } } else if ( len != 0 ) { detach(); memmove( data()+index, data()+index+len, olen-index-len+1 ); - QByteArray::resize(olen-len+1); + QByteArray::resize(olen-len+1, QByteArray::SpeedOptim ); } return *this; } @@ -1630,8 +1666,9 @@ QCString &QCString::replace( char c, const char *after ) s.replace( "Greek", "English" ); // s == "English is English" \endcode */ + QCString &QCString::replace( const char *before, const char *after ) { if ( before == after || isNull() ) return *this; @@ -1645,18 +1682,18 @@ QCString &QCString::replace( const char *before, const char *after ) uint len = length(); if ( bl == al ) { if ( bl ) { - while( (index = find( before, index ) ) != -1 ) { + while( (index = find( before, index, TRUE, len ) ) != -1 ) { memcpy( d+index, after, al ); index += bl; } } } else if ( al < bl ) { uint to = 0; uint movestart = 0; uint num = 0; - while( (index = find( before, index ) ) != -1 ) { + while( (index = find( before, index, TRUE, len ) ) != -1 ) { if ( num ) { int msize = index - movestart; if ( msize > 0 ) { memmove( d + to, d + movestart, msize ); @@ -1685,9 +1722,9 @@ QCString &QCString::replace( const char *before, const char *after ) while( index != -1 ) { uint indices[4096]; uint pos = 0; while( pos < 4095 ) { - index = find(before, index); + index = find(before, index, TRUE, len); if ( index == -1 ) break; indices[pos++] = index; index += bl; @@ -1762,9 +1799,9 @@ QCString &QCString::replace( char c1, char c2 ) */ int QCString::find( const QRegExp& rx, int index ) const { - QString d = QString::fromLatin1( data() ); + QString d = QString::fromAscii( data() ); return d.find( rx, index ); } /*! @@ -1782,9 +1819,9 @@ int QCString::find( const QRegExp& rx, int index ) const */ int QCString::findRev( const QRegExp& rx, int index ) const { - QString d = QString::fromLatin1( data() ); + QString d = QString::fromAscii( data() ); return d.findRev( rx, index ); } /*! @@ -1807,9 +1844,9 @@ int QCString::findRev( const QRegExp& rx, int index ) const */ int QCString::contains( const QRegExp &rx ) const { - QString d = QString::fromLatin1( data() ); + QString d = QString::fromAscii( data() ); return d.contains( rx ); } @@ -1837,10 +1874,10 @@ int QCString::contains( const QRegExp &rx ) const */ QCString &QCString::replace( const QRegExp &rx, const char *str ) { - QString d = QString::fromLatin1( data() ); - QString r = QString::fromLatin1( str ); + QString d = QString::fromAscii( data() ); + QString r = QString::fromAscii( str ); d.replace( rx, r ); setStr( d.ascii() ); return *this; } @@ -2198,9 +2235,9 @@ QCString& QCString::operator+=( const char *str ) return *this; // nothing to append detach(); uint len1 = length(); uint len2 = qstrlen(str); - if ( !QByteArray::resize( len1 + len2 + 1 ) ) + if ( !QByteArray::resize( len1 + len2 + 1, QByteArray::SpeedOptim ) ) return *this; // no memory memcpy( data() + len1, str, len2 + 1 ); return *this; } @@ -2214,9 +2251,9 @@ QCString& QCString::operator+=( const char *str ) QCString &QCString::operator+=( char c ) { detach(); uint len = length(); - if ( !QByteArray::resize( len + 2 ) ) + if ( !QByteArray::resize( len + 2, QByteArray::SpeedOptim ) ) return *this; // no memory *(data() + len) = c; *(data() + len+1) = '\0'; return *this; diff --git a/qmake/tools/qdatastream.cpp b/qmake/tools/qdatastream.cpp index 9c573c7..51a1448 100644 --- a/qmake/tools/qdatastream.cpp +++ b/qmake/tools/qdatastream.cpp @@ -749,10 +749,18 @@ QDataStream &QDataStream::readRawBytes( char *s, uint len ) { CHECK_STREAM_PRECOND if ( printable ) { // printable data register Q_INT8 *p = (Q_INT8*)s; + if ( version() < 4 ) { + while ( len-- ) { + Q_INT32 tmp; + *this >> tmp; + *p++ = tmp; + } + } else { while ( len-- ) *this >> *p++; + } } else { // read data char array dev->readBlock( s, len ); } return *this; @@ -1011,11 +1019,17 @@ QDataStream &QDataStream::writeBytes(const char *s, uint len) QDataStream &QDataStream::writeRawBytes( const char *s, uint len ) { CHECK_STREAM_PRECOND if ( printable ) { // write printable + if ( version() < 4 ) { + register char *p = (char *)s; + while ( len-- ) + *this << *p++; + } else { register Q_INT8 *p = (Q_INT8*)s; while ( len-- ) *this << *p++; + } } else { // write data char array dev->writeBlock( s, len ); } return *this; diff --git a/qmake/tools/qdatetime.cpp b/qmake/tools/qdatetime.cpp index 93e40a8..3137877 100644 --- a/qmake/tools/qdatetime.cpp +++ b/qmake/tools/qdatetime.cpp @@ -4,9 +4,9 @@ ** Implementation of date and time classes ** ** Created : 940124 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 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 @@ -34,9 +34,8 @@ ** not clear to you. ** **********************************************************************/ -// Get the system specific includes and defines #include "qplatformdefs.h" #include "qdatetime.h" #include "qdatastream.h" @@ -894,8 +893,14 @@ QDate QDate::addYears( int nyears ) const { int y, m, d; julianToGregorian( jd, y, m, d ); y += nyears; + + QDate tmp(y,m,1); + + if( d > tmp.daysInMonth() ) + d = tmp.daysInMonth(); + QDate date(y, m, d); return date; } @@ -989,15 +994,27 @@ QDate QDate::currentDate( Qt::TimeSpec ts ) else GetSystemTime( &t ); d.jd = gregorianToJulian( t.wYear, t.wMonth, t.wDay ); #else + // posix compliant system time_t ltime; time( <ime ); tm *t; + +# if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + // use the reentrant versions of localtime() and gmtime() where available + tm res; + if ( ts == Qt::LocalTime ) + t = localtime_r( <ime, &res ); + else + t = gmtime_r( <ime, &res ); +# else if ( ts == Qt::LocalTime ) t = localtime( <ime ); else t = gmtime( <ime ); +# endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS + d.jd = gregorianToJulian( t->tm_year + 1900, t->tm_mon + 1, t->tm_mday ); #endif return d; } @@ -1652,17 +1669,28 @@ bool QTime::currentTime( QTime *ct, Qt::TimeSpec ts ) } ct->ds = (uint)( MSECS_PER_HOUR*t.wHour + MSECS_PER_MIN*t.wMinute + 1000*t.wSecond + t.wMilliseconds ); #elif defined(Q_OS_UNIX) + // posix compliant system struct timeval tv; gettimeofday( &tv, 0 ); time_t ltime = tv.tv_sec; tm *t; - if ( ts == Qt::LocalTime ) { + +# if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + // use the reentrant versions of localtime() and gmtime() where available + tm res; + if ( ts == Qt::LocalTime ) + t = localtime_r( <ime, &res ); + else + t = gmtime_r( <ime, &res ); +# else + if ( ts == Qt::LocalTime ) t = localtime( <ime ); - } else { + else t = gmtime( <ime ); - } +# endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS + ct->ds = (uint)( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec + tv.tv_usec / 1000 ); #else time_t ltime; // no millisecond resolution @@ -1705,11 +1733,11 @@ bool QTime::isValid( int h, int m, int s, int ms ) Sets this time to the current time. This is practical for timing: \code QTime t; - t.start(); // start clock - ... // some lengthy task - qDebug( "%d\n", t.elapsed() ); // prints the number of msecs elapsed + t.start(); + some_lengthy_task(); + qDebug( "Time elapsed: %d ms", t.elapsed() ); \endcode \sa restart(), elapsed(), currentTime() */ @@ -1959,8 +1987,24 @@ void QDateTime::setTime_t( uint secsSince1Jan1970UTC ) void QDateTime::setTime_t( uint secsSince1Jan1970UTC, Qt::TimeSpec ts ) { time_t tmp = (time_t) secsSince1Jan1970UTC; tm *brokenDown = 0; + +#if defined(Q_OS_UNIX) && defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + // posix compliant system + // use the reentrant versions of localtime() and gmtime() where available + tm res; + if ( ts == Qt::LocalTime ) + brokenDown = localtime_r( &tmp, &res ); + if ( !brokenDown ) { + brokenDown = gmtime_r( &tmp, &res ); + if ( !brokenDown ) { + d.jd = QDate::gregorianToJulian( 1970, 1, 1 ); + t.ds = 0; + return; + } + } +#else if ( ts == Qt::LocalTime ) brokenDown = localtime( &tmp ); if ( !brokenDown ) { brokenDown = gmtime( &tmp ); @@ -1969,8 +2013,10 @@ void QDateTime::setTime_t( uint secsSince1Jan1970UTC, Qt::TimeSpec ts ) t.ds = 0; return; } } +#endif + d.jd = QDate::gregorianToJulian( brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday ); t.ds = MSECS_PER_HOUR * brokenDown->tm_hour + diff --git a/qmake/tools/qdir.cpp b/qmake/tools/qdir.cpp index 418ea49..5714878 100644 --- a/qmake/tools/qdir.cpp +++ b/qmake/tools/qdir.cpp @@ -4,9 +4,9 @@ ** Implementation of QDir class ** ** Created : 950427 ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 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 @@ -42,15 +42,20 @@ #include <private/qdir_p.h> #include "qfileinfo.h" #include "qregexp.h" #include "qstringlist.h" -#include <stdlib.h> -#include <ctype.h> +#include <limits.h> +#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX) +const bool CaseSensitiveFS = FALSE; +#else +const bool CaseSensitiveFS = TRUE; +#endif /*! \class QDir + \reentrant \brief The QDir class provides access to directory structures and their contents in a platform-independent way. \ingroup io \mainclass @@ -229,8 +234,16 @@ QDir::QDir( const QDir &d ) filtS = d.filtS; sortS = d.sortS; } +/*! + Refreshes the directory information. +*/ +void QDir::refresh() const +{ + QDir* that = (QDir*) this; + that->dirty = TRUE; +} void QDir::init() { fList = 0; @@ -381,12 +394,38 @@ QString QDir::absFilePath( const QString &fileName, if ( acceptAbsPath && !isRelativePath( fileName ) ) return fileName; QString tmp = absPath(); +#ifdef Q_OS_WIN32 + if ( fileName[0].isLetter() && fileName[1] == ':' ) { + int drv = fileName.upper()[0].latin1() - 'A' + 1; + if ( _getdrive() != drv ) { + if ( qt_winunicode ) { + TCHAR buf[PATH_MAX]; + ::_tgetdcwd( drv, buf, PATH_MAX ); + tmp.setUnicodeCodes( (ushort*)buf, ::_tcslen(buf) ); + } else { + char buf[PATH_MAX]; + ::_getdcwd( drv, buf, PATH_MAX ); + tmp = buf; + } + if ( !tmp.endsWith("\\") ) + tmp += "\\"; + tmp += fileName.right( fileName.length() - 2 ); + int x; + for ( x = 0; x < (int) tmp.length(); x++ ) { + if ( tmp[x] == '\\' ) + tmp[x] = '/'; + } + } + } else +#endif + { if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName && fileName[0] != '/') ) tmp += '/'; tmp += fileName; + } return tmp; } @@ -933,9 +972,10 @@ QDir &QDir::operator=( const QString &path ) \code // The current directory is "/usr/local" QDir d1( "/usr/local/bin" ); QDir d2( "bin" ); - if ( d1 != d2 ) qDebug( "They differ\n" ); // This is printed + if ( d1 != d2 ) + qDebug( "They differ" ); \endcode */ /*! @@ -948,9 +988,10 @@ QDir &QDir::operator=( const QString &path ) // The current directory is "/usr/local" QDir d1( "/usr/local/bin" ); QDir d2( "bin" ); d2.convertToAbs(); - if ( d1 == d2 ) qDebug( "They're the same\n" ); // This is printed + if ( d1 == d2 ) + qDebug( "They're the same" ); \endcode */ bool QDir::operator==( const QDir &d ) const @@ -1086,29 +1127,41 @@ QDir QDir::root() \sa home() */ -QStringList qt_makeFilterList( const QString &filter ) +QValueList<QRegExp> qt_makeFilterList( const QString &filter ) { + QValueList<QRegExp> regExps; if ( filter.isEmpty() ) - return QStringList(); + return regExps; QChar sep( ';' ); int i = filter.find( sep, 0 ); if ( i == -1 && filter.find( ' ', 0 ) != -1 ) sep = QChar( ' ' ); QStringList list = QStringList::split( sep, filter ); QStringList::Iterator it = list.begin(); - QStringList list2; + while ( it != list.end() ) { + regExps << QRegExp( (*it).stripWhiteSpace(), CaseSensitiveFS, TRUE ); + ++it; + } + return regExps; +} - for ( ; it != list.end(); ++it ) { - QString s = *it; - list2 << s.stripWhiteSpace(); +bool qt_matchFilterList( const QValueList<QRegExp>& filters, + const QString &fileName ) +{ + QValueList<QRegExp>::ConstIterator rit = filters.begin(); + while ( rit != filters.end() ) { + if ( (*rit).exactMatch(fileName) ) + return TRUE; + ++rit; } - return list2; + return FALSE; } + /*! \overload Returns TRUE if the \a fileName matches any of the wildcard (glob) @@ -1122,13 +1175,9 @@ QStringList qt_makeFilterList( const QString &filter ) bool QDir::match( const QStringList &filters, const QString &fileName ) { QStringList::ConstIterator sit = filters.begin(); while ( sit != filters.end() ) { -#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX) - QRegExp rx( *sit, FALSE, TRUE ); // The FAT FS is not case sensitive.. -#else - QRegExp rx( *sit, TRUE, TRUE ); // ..while others are. -#endif + QRegExp rx( *sit, CaseSensitiveFS, TRUE ); if ( rx.exactMatch(fileName) ) return TRUE; ++sit; } @@ -1146,10 +1195,9 @@ bool QDir::match( const QStringList &filters, const QString &fileName ) */ bool QDir::match( const QString &filter, const QString &fileName ) { - QStringList lst = qt_makeFilterList( filter ); - return match( lst, fileName ); + return qt_matchFilterList( qt_makeFilterList(filter), fileName ); } /*! diff --git a/qmake/tools/qdir_unix.cpp b/qmake/tools/qdir_unix.cpp index 57fe3c5..6a7adda 100644 --- a/qmake/tools/qdir_unix.cpp +++ b/qmake/tools/qdir_unix.cpp @@ -4,9 +4,9 @@ ** Implementation of QDir class ** ** Created : 950628 ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 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 @@ -50,8 +50,9 @@ #endif // QT_THREAD_SUPPORT #include <stdlib.h> #include <limits.h> +#include <errno.h> void QDir::slashify( QString& ) { @@ -69,19 +70,18 @@ QString QDir::homeDirPath() QString QDir::canonicalPath() const { QString r; - char cur[PATH_MAX+1]; - if ( ::getcwd( cur, PATH_MAX ) ) - if ( ::chdir(QFile::encodeName(dPath)) >= 0 ) { + if ( ::getcwd( cur, PATH_MAX ) ) { char tmp[PATH_MAX+1]; - if ( ::getcwd( tmp, PATH_MAX ) ) + if( ::realpath( QFile::encodeName( dPath ), tmp ) ) r = QFile::decodeName(tmp); + slashify( r ); + + // always make sure we go back to the current dir ::chdir( cur ); } - - slashify( r ); return r; } bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const @@ -89,14 +89,15 @@ bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const #if defined(Q_OS_MACX) // Mac X doesn't support trailing /'s QString name = dirName; if (dirName[dirName.length() - 1] == "/") name = dirName.left( dirName.length() - 1 ); - return ::mkdir( QFile::encodeName(filePath(name,acceptAbsPath)), 0777 ) - == 0; + int status = + ::mkdir( QFile::encodeName(filePath(name,acceptAbsPath)), 0777 ); #else - return ::mkdir( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 ) - == 0; + int status = + ::mkdir( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 ); #endif + return status == 0; } bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const { @@ -185,9 +186,9 @@ bool QDir::readDirEntries( const QString &nameFilter, fList->clear(); fiList->clear(); } - QStringList filters = qt_makeFilterList( nameFilter ); + QValueList<QRegExp> filters = qt_makeFilterList( nameFilter ); bool doDirs = (filterSpec & Dirs) != 0; bool doFiles = (filterSpec & Files) != 0; bool noSymLinks = (filterSpec & NoSymLinks) != 0; @@ -196,25 +197,29 @@ bool QDir::readDirEntries( const QString &nameFilter, bool doExecable = (filterSpec & Executable) != 0; bool doHidden = (filterSpec & Hidden) != 0; bool doSystem = (filterSpec & System) != 0; -#if defined(Q_OS_OS2EMX) - //QRegExp wc( nameFilter, FALSE, TRUE ); // wild card, case insensitive -#else - //QRegExp wc( nameFilter, TRUE, TRUE ); // wild card, case sensitive -#endif QFileInfo fi; DIR *dir; dirent *file; dir = opendir( QFile::encodeName(dPath) ); if ( !dir ) return FALSE; // cannot read the directory - while ( (file = readdir(dir)) ) { +#if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) + union { + struct dirent mt_file; + char b[sizeof(struct dirent) + MAXNAMLEN + 1]; + } u; + while ( readdir_r(dir, &u.mt_file, &file ) == 0 && file ) +#else + while ( (file = readdir(dir)) ) +#endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS + { QString fn = QFile::decodeName(file->d_name); fi.setFile( *this, fn ); - if ( !match( filters, fn ) && !(allDirs && fi.isDir()) ) + if ( !qt_matchFilterList(filters, fn) && !(allDirs && fi.isDir()) ) continue; if ( (doDirs && fi.isDir()) || (doFiles && fi.isFile()) || (doSystem && (!fi.isFile() && !fi.isDir())) ) { if ( noSymLinks && fi.isSymLink() ) @@ -275,9 +280,10 @@ const QFileInfoList * QDir::drives() if ( !knownMemoryLeak ) { #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &knownMemoryLeak ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &knownMemoryLeak ) : 0 ); #endif // QT_THREAD_SUPPORT if ( !knownMemoryLeak ) { knownMemoryLeak = new QFileInfoList; diff --git a/qmake/tools/qfile.cpp b/qmake/tools/qfile.cpp index a578b49..c088b55 100644 --- a/qmake/tools/qfile.cpp +++ b/qmake/tools/qfile.cpp @@ -87,9 +87,9 @@ extern bool qt_file_access( const QString& fn, int t ); if ( file.open( IO_ReadOnly ) ) { QTextStream stream( &file ); QString line; int i = 1; - while ( !stream.eof() ) { + while ( !stream.atEnd() ) { line = stream.readLine(); // line of text excluding '\n' printf( "%3d: %s\n", i++, line.latin1() ); lines += line; } @@ -289,8 +289,9 @@ void QFile::flush() */ /*! Returns TRUE if the end of file has been reached; otherwise returns FALSE. + If QFile has not been open()'d, then the behavior is undefined. \sa size() */ diff --git a/qmake/tools/qfile_unix.cpp b/qmake/tools/qfile_unix.cpp index 2d5a856..460bf06 100644 --- a/qmake/tools/qfile_unix.cpp +++ b/qmake/tools/qfile_unix.cpp @@ -434,13 +434,16 @@ bool QFile::open( int m, int f ) QIODevice::Offset QFile::size() const { struct stat st; + int ret = 0; if ( isOpen() ) { - ::fstat( fh ? fileno(fh) : fd, &st ); + ret = ::fstat( fh ? fileno(fh) : fd, &st ); } else { - ::stat( QFile::encodeName(fn), &st ); + ret = ::stat( QFile::encodeName(fn), &st ); } + if ( ret == -1 ) + return 0; #if defined(QT_LARGEFILE_SUPPORT) && !defined(QT_ABI_64BITOFFSET) return (uint)st.st_size > UINT_MAX ? UINT_MAX : (QIODevice::Offset)st.st_size; #else return st.st_size; @@ -537,9 +540,9 @@ Q_LONG QFile::readBlock( char *p, Q_ULONG len ) if ( !ungetchBuffer.isEmpty() ) { // need to add these to the returned string. uint l = ungetchBuffer.length(); while( nread < l ) { - *p = ungetchBuffer[ l - nread - 1 ]; + *p = ungetchBuffer.at( l - nread - 1 ); p++; nread++; } ungetchBuffer.truncate( l - nread ); @@ -628,9 +631,11 @@ Q_LONG QFile::writeBlock( const char *p, Q_ULONG len ) /*! Returns the file handle of the file. This is a small positive integer, suitable for use with C library - functions such as fdopen() and fcntl(), as well as with QSocketNotifier. + functions such as fdopen() and fcntl(). On systems that use file + descriptors for sockets (ie. Unix systems, but not Windows) the handle + can be used with QSocketNotifier as well. If the file is not open or there is an error, handle() returns -1. \sa QSocketNotifier diff --git a/qmake/tools/qfileinfo.cpp b/qmake/tools/qfileinfo.cpp index 3af7932..a78f4fa 100644 --- a/qmake/tools/qfileinfo.cpp +++ b/qmake/tools/qfileinfo.cpp @@ -634,8 +634,10 @@ QDateTime QFileInfo::lastRead() const This function returns the same as filePath(), unless isRelative() is TRUE. + If the QFileInfo is empty it returns QDir::currentDirPath(). + This function can be time consuming under Unix (in the order of milliseconds). \sa isRelative(), filePath() @@ -643,9 +645,9 @@ QDateTime QFileInfo::lastRead() const QString QFileInfo::absFilePath() const { QString tmp; if ( QDir::isRelativePath(fn) -#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) +#if defined(Q_OS_WIN32) && fn[1] != ':' #endif ) { tmp = QDir::currentDirPath(); diff --git a/qmake/tools/qfileinfo_unix.cpp b/qmake/tools/qfileinfo_unix.cpp index f7c3a97..364f219 100644 --- a/qmake/tools/qfileinfo_unix.cpp +++ b/qmake/tools/qfileinfo_unix.cpp @@ -213,11 +213,11 @@ uint QFileInfo::groupId() const Example: \code QFileInfo fi( "/tmp/archive.tar.gz" ); if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) ) - qWarning( "I can change the file; my group can read the file."); + qWarning( "I can change the file; my group can read the file" ); if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) ) - qWarning( "The group or others can change the file!" ); + qWarning( "The group or others can change the file" ); \endcode \sa isReadable(), isWritable(), isExecutable() */ diff --git a/qmake/tools/qgarray.cpp b/qmake/tools/qgarray.cpp index 45c45ce..0a522e4 100644 --- a/qmake/tools/qgarray.cpp +++ b/qmake/tools/qgarray.cpp @@ -34,11 +34,15 @@ ** not clear to you. ** **********************************************************************/ -#include "qglobal.h" // needed to define Q_WS_WIN -#ifdef Q_WS_WIN -#include "qt_windows.h" // needed for bsearch on some platforms +#include "qglobal.h" +#if defined(Q_CC_BOR) + // needed for qsort() because of a std namespace problem on Borland +# include "qplatformdefs.h" +#elif defined(Q_WS_WIN) + // needed for bsearch on some platforms +# include "qt_windows.h" #endif #define QGARRAY_CPP #include "qgarray.h" @@ -48,9 +52,15 @@ #ifdef QT_THREAD_SUPPORT # include <private/qmutexpool_p.h> #endif // QT_THREAD_SUPPORT -#define USE_MALLOC // comment to use new/delete +/* + If USE_MALLOC isn't defined, we use new[] and delete[] to allocate + memory. The documentation for QMemArray<T>::assign() explicitly + mentions that the array is freed using free(), so don't mess around + with USE_MALLOC unless you know what you're doing. +*/ +#define USE_MALLOC #undef NEW #undef DELETE @@ -134,9 +144,13 @@ QGArray::QGArray( int size ) if ( size == 0 ) // zero length return; shd->data = NEW(char,size); Q_CHECK_PTR( shd->data ); - shd->len = size; + shd->len = +#ifdef QT_QGARRAY_SPEED_OPTIM + shd->maxl = +#endif + size; } /*! Constructs a shallow copy of \a a. @@ -211,37 +225,72 @@ bool QGArray::isEqual( const QGArray &a ) const } /*! - Resizes the array to \a newsize bytes. + Resizes the array to \a newsize bytes. \a optim is either + MemOptim (the default) or SpeedOptim. */ - -bool QGArray::resize( uint newsize ) +bool QGArray::resize( uint newsize, Optimization optim ) { - if ( newsize == shd->len ) // nothing to do +#ifndef QT_QGARRAY_SPEED_OPTIM + Q_UNUSED(optim); +#endif + + if ( newsize == shd->len +#ifdef QT_QGARRAY_SPEED_OPTIM + && newsize == shd->maxl +#endif + ) // nothing to do return TRUE; if ( newsize == 0 ) { // remove array duplicate( 0, 0 ); return TRUE; } + + uint newmaxl = newsize; +#ifdef QT_QGARRAY_SPEED_OPTIM + if ( optim == SpeedOptim ) { + if ( newsize <= shd->maxl && + ( newsize * 4 > shd->maxl || shd->maxl <= 4 ) ) { + shd->len = newsize; + return TRUE; + } + newmaxl = 4; + while ( newmaxl < newsize ) + newmaxl *= 2; + // try to spare some memory + if ( newmaxl >= 1024 * 1024 && newsize <= newmaxl - (newmaxl >> 2) ) + newmaxl -= newmaxl >> 2; + } + shd->maxl = newmaxl; +#endif + if ( shd->data ) { // existing data #if defined(DONT_USE_REALLOC) char *newdata = NEW(char,newsize); // manual realloc - memcpy( newdata, shd->data, QMIN(shd->len,newsize) ); + memcpy( newdata, shd->data, QMIN(shd->len,newmaxl) ); DELETE(shd->data); shd->data = newdata; #else - shd->data = (char *)realloc( shd->data, newsize ); + shd->data = (char *)realloc( shd->data, newmaxl ); #endif } else { - shd->data = NEW(char,newsize); + shd->data = NEW(char,newmaxl); } if ( !shd->data ) // no memory return FALSE; shd->len = newsize; return TRUE; } +/*!\overload +*/ +bool QGArray::resize( uint newsize ) +{ + return resize( newsize, MemOptim ); +} + + /*! Fills the array with the repeated occurrences of \a d, which is \a sz bytes long. If \a len is specified as different from -1, then the array will be @@ -318,9 +367,13 @@ QGArray &QGArray::assign( const char *d, uint len ) if ( shd->data ) DELETE(shd->data); } shd->data = (char *)d; - shd->len = len; + shd->len = +#ifdef QT_QGARRAY_SPEED_OPTIM + shd->maxl = +#endif + len; return *this; } /*! @@ -363,9 +416,13 @@ QGArray &QGArray::duplicate( const QGArray &a ) memcpy( shd->data, a.shd->data, a.shd->len ); } else { shd->data = 0; } - shd->len = a.shd->len; + shd->len = +#ifdef QT_QGARRAY_SPEED_OPTIM + shd->maxl = +#endif + a.shd->len; if ( oldptr ) DELETE(oldptr); return *this; } @@ -401,9 +458,13 @@ QGArray &QGArray::duplicate( const char *d, uint len ) if ( shd->data ) DELETE(shd->data); } shd->data = data; - shd->len = len; + shd->len = +#ifdef QT_QGARRAY_SPEED_OPTIM + shd->maxl = +#endif + len; return *this; } /*! @@ -658,9 +719,10 @@ void QGArray::sort( uint sz ) if ( numItems < 2 ) return; #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &cmp_item_size ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &cmp_item_size ) : 0 ); #endif // QT_THREAD_SUPPORT cmp_item_size = sz; qsort( shd->data, numItems, sz, cmp_arr ); @@ -676,9 +738,10 @@ int QGArray::bsearch( const char *d, uint sz ) const if ( !numItems ) return -1; #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &cmp_item_size ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &cmp_item_size ) : 0 ); #endif // QT_THREAD_SUPPORT cmp_item_size = sz; char* r = (char*)::bsearch( d, shd->data, numItems, sz, cmp_arr ); diff --git a/qmake/tools/qgdict.cpp b/qmake/tools/qgdict.cpp index c431ff8..3d49fc7 100644 --- a/qmake/tools/qgdict.cpp +++ b/qmake/tools/qgdict.cpp @@ -203,9 +203,12 @@ QGDict::QGDict( uint len, KeyType kt, bool caseSensitive, bool copyKeys ) void QGDict::init( uint len, KeyType kt, bool caseSensitive, bool copyKeys ) { - vec = new QBaseBucket *[vlen = len]; // allocate hash table + vlen = len; + if ( vlen == 0 ) + vlen = 17; + vec = new QBaseBucket *[vlen]; Q_CHECK_PTR( vec ); memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) ); numItems = 0; iterators = 0; diff --git a/qmake/tools/qglist.cpp b/qmake/tools/qglist.cpp index 155d585..bd27f8a 100644 --- a/qmake/tools/qglist.cpp +++ b/qmake/tools/qglist.cpp @@ -328,14 +328,10 @@ QLNode *QGList::locate( uint index ) register QLNode *node; int distance = index - curIndex; // node distance to cur node bool forward; // direction to traverse - if ( index >= numNodes ) { -#if defined(QT_CHECK_RANGE) - qWarning( "QGList::locate: Index %d out of range", index ); -#endif + if ( index >= numNodes ) return 0; - } if ( distance < 0 ) distance = -distance; if ( (uint)distance < index && (uint)distance < numNodes - index ) { diff --git a/qmake/tools/qglobal.cpp b/qmake/tools/qglobal.cpp index 47cd6bd..342005d 100644 --- a/qmake/tools/qglobal.cpp +++ b/qmake/tools/qglobal.cpp @@ -148,9 +148,30 @@ bool qSysInfo( int *wordSize, bool *bigEndian ) si_alreadyDone = TRUE; return TRUE; } -#if defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN) +#if !defined(QWS) && defined(Q_OS_MAC) + +#include "qt_mac.h" + +int qMacVersion() +{ + static int macver = Qt::MV_Unknown; + static bool first = TRUE; + if(first) { + first = FALSE; + long gestalt_version; + if(Gestalt(gestaltSystemVersion, &gestalt_version) == noErr) { + if(gestalt_version >= 0x1020 && gestalt_version < 0x1030) + macver = Qt::MV_10_DOT_2; + else if(gestalt_version >= 0x1010 && gestalt_version < 0x1020) + macver = Qt::MV_10_DOT_1; + } + } + return macver; +} +Qt::MacintoshVersion qt_macver = (Qt::MacintoshVersion)qMacVersion(); +#elif defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN) bool qt_winunicode; #include "qt_windows.h" @@ -320,9 +341,21 @@ static QtMsgHandler handler = 0; // pointer to debug handler static const int QT_BUFFER_LENGTH = 8196; // internal buffer length #ifdef Q_OS_MAC -const unsigned char * p_str(const char * c, int len=-1) +QString cfstring2qstring(CFStringRef str) +{ + CFIndex length = CFStringGetLength(str); + if(const UniChar *chars = CFStringGetCharactersPtr(str)) + return QString((QChar *)chars, length); + UniChar *buffer = (UniChar*)malloc(length * sizeof(UniChar)); + CFStringGetCharacters(str, CFRangeMake(0, length), buffer); + QString ret((QChar *)buffer, length); + free(buffer); + return ret; +} + +unsigned char * p_str(const char * c, int len=-1) { const int maxlen = 255; if(len == -1) len = qstrlen(c); @@ -336,9 +369,9 @@ const unsigned char * p_str(const char * c, int len=-1) *(ret+len+1) = '\0'; return ret; } -const unsigned char * p_str(const QString &s) +unsigned char * p_str(const QString &s) { return p_str(s, s.length()); } @@ -640,10 +673,10 @@ void qSystemWarning( const char* msg, int code ) \fn void Q_CHECK_PTR( void *p ) \relates QApplication - If \a p is null, a fatal messages says that the program ran out of - memory and exits. If \e p is not null, nothing happens. + If \a p is 0, a fatal messages says that the program ran out of + memory and exits. If \e p is not 0, nothing happens. This is really a macro defined in \c qglobal.h. Example: @@ -651,9 +684,9 @@ void qSystemWarning( const char* msg, int code ) int *a; Q_CHECK_PTR( a = new int[80] ); // WRONG! - a = new int[80]; // Right + a = new (nothrow) int[80]; // Right Q_CHECK_PTR( a ); \endcode \sa qFatal(), \link debug.html Debugging\endlink diff --git a/qmake/tools/qgpluginmanager.cpp b/qmake/tools/qgpluginmanager.cpp index 46c85f5..72246ac 100644 --- a/qmake/tools/qgpluginmanager.cpp +++ b/qmake/tools/qgpluginmanager.cpp @@ -2,9 +2,9 @@ ** $Id$ ** ** Implementation of QGPluginManager class ** -** Copyright (C) 2000-2001 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2003 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 @@ -474,9 +474,9 @@ bool QGPluginManager::addLibrary( QLibrary* lib ) fl = fliFace->featureList(); else if ( cpiFace ) fl << cpiFace->name(); - for ( QStringList::Iterator f = fl.begin(); f != fl.end(); f++ ) { + for ( QStringList::Iterator f = fl.begin(); f != fl.end(); ++f ) { QLibrary *old = plugDict[*f]; if ( !old ) { useful = TRUE; plugDict.replace( *f, plugin ); diff --git a/qmake/tools/qgvector.cpp b/qmake/tools/qgvector.cpp index 1985f03..3c903ed 100644 --- a/qmake/tools/qgvector.cpp +++ b/qmake/tools/qgvector.cpp @@ -34,8 +34,14 @@ ** not clear to you. ** **********************************************************************/ +#include "qglobal.h" +#if defined(Q_CC_BOR) +// needed for qsort() because of a std namespace problem on Borland +#include "qplatformdefs.h" +#endif + #define QGVECTOR_CPP #include "qgvector.h" #include "qglist.h" #include "qstring.h" @@ -392,9 +398,10 @@ void QGVector::sort() // sort vector } } #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &sort_vec ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &sort_vec ) : 0 ); #endif // QT_THREAD_SUPPORT sort_vec = (QGVector*)this; qsort( vec, count(), sizeof(Item), cmp_vec ); diff --git a/qmake/tools/qlibrary.cpp b/qmake/tools/qlibrary.cpp index 564db30..be1d54b 100644 --- a/qmake/tools/qlibrary.cpp +++ b/qmake/tools/qlibrary.cpp @@ -2,11 +2,11 @@ ** $Id$ ** ** Implementation of QLibrary class ** -** Created : 2000-01-01 +** Created : 000101 ** -** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2003 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 @@ -70,9 +70,9 @@ QLibraryPrivate::QLibraryPrivate( QLibrary *lib ) \reentrant \brief The QLibrary class provides a wrapper for handling shared libraries. \mainclass - \group plugins + \ingroup plugins An instance of a QLibrary object can handle a single shared library and provide access to the functionality in the library in a platform independent way. If the library is a component server, @@ -325,16 +325,17 @@ QString QLibrary::library() const #elif defined(Q_OS_MACX) if ( filename.find( ".dylib" ) == -1 ) filename += ".dylib"; #else - if ( filename.find( ".so" ) == -1 ) { + QString filter = ".so"; + if ( filename.find(filter) == -1 ) { const int x = filename.findRev( "/" ); if ( x != -1 ) { QString path = filename.left( x + 1 ); QString file = filename.right( filename.length() - x - 1 ); - filename = QString( "%1lib%2.so" ).arg( path ).arg( file ); + filename = QString( "%1lib%2.%3" ).arg( path ).arg( file ).arg( filter ); } else { - filename = QString( "lib%1.so" ).arg( filename ); + filename = QString( "lib%1.%2" ).arg( filename ).arg( filter ); } } #endif diff --git a/qmake/tools/qlibrary_unix.cpp b/qmake/tools/qlibrary_unix.cpp index f0fbdf6..12b9310 100644 --- a/qmake/tools/qlibrary_unix.cpp +++ b/qmake/tools/qlibrary_unix.cpp @@ -2,9 +2,9 @@ ** $Id$ ** ** Implementation of QLibraryPrivate class ** -** Created : 2000-01-01 +** Created : 000101 ** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. @@ -52,9 +52,26 @@ It's not too hard to guess what the functions do. */ -#if defined(QT_HPUX_LD) // for HP-UX < 11.x and 32 bit +#if defined(Q_OS_MAC) + +bool QLibraryPrivate::loadLibrary() +{ + return FALSE; +} + +bool QLibraryPrivate::freeLibrary() +{ + return FALSE; +} + +void* QLibraryPrivate::resolveSymbol( const char* ) +{ + return 0; +} + +#elif defined(QT_HPUX_LD) // for HP-UX < 11.x and 32 bit bool QLibraryPrivate::loadLibrary() { if ( pHnd ) diff --git a/qmake/tools/qmutex_unix.cpp b/qmake/tools/qmutex_unix.cpp index c861b2d..3eb59cf 100644 --- a/qmake/tools/qmutex_unix.cpp +++ b/qmake/tools/qmutex_unix.cpp @@ -42,9 +42,10 @@ typedef pthread_mutex_t Q_MUTEX_T; // POSIX threads mutex types #if ((defined(PTHREAD_MUTEX_RECURSIVE) && defined(PTHREAD_MUTEX_DEFAULT)) || \ - defined(Q_OS_FREEBSD)) && !defined(Q_OS_UNIXWARE) && !defined(Q_OS_SOLARIS) + defined(Q_OS_FREEBSD)) && !defined(Q_OS_UNIXWARE) && !defined(Q_OS_SOLARIS) && \ + !defined(Q_OS_MAC) // POSIX 1003.1c-1995 - We love this OS # define Q_MUTEX_SET_TYPE(a, b) pthread_mutexattr_settype((a), (b)) # if defined(QT_CHECK_RANGE) # define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK @@ -660,9 +661,10 @@ bool QMutex::tryLock() /*! \fn QMutexLocker::QMutexLocker( QMutex *mutex ) Constructs a QMutexLocker and locks \a mutex. The mutex will be - unlocked when the QMutexLocker is destroyed. + unlocked when the QMutexLocker is destroyed. If \a mutex is zero, + QMutexLocker does nothing. \sa QMutex::lock() */ diff --git a/qmake/tools/qmutexpool.cpp b/qmake/tools/qmutexpool.cpp index 9ed2829..a8e7402 100644 --- a/qmake/tools/qmutexpool.cpp +++ b/qmake/tools/qmutexpool.cpp @@ -1,28 +1,47 @@ +/**************************************************************************** +** $Id$ +** +** ... +** +** Copyright (C) 2002 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 "qmutexpool_p.h" #ifdef QT_THREAD_SUPPORT #include <qthread.h> -#include <stdio.h> QMutexPool *qt_global_mutexpool = 0; -// this is an internal class used only for inititalizing the global mutexpool -class QGlobalMutexPoolInitializer -{ -public: - inline QGlobalMutexPoolInitializer() - { - /* - Purify will report a leak here. However, this mutex pool must be alive - until *everything* in Qt has been destructed. Unfortunately there is - no way to guarantee this, so we never destroy this mutex pool. - */ - qt_global_mutexpool = new QMutexPool( TRUE ); - } -}; -QGlobalMutexPoolInitializer qt_global_mutexpool_initializer; /*! \class QMutexPool qmutexpool_p.h \brief The QMutexPool class provides a pool of QMutex objects. @@ -84,11 +103,14 @@ QGlobalMutexPoolInitializer qt_global_mutexpool_initializer; The QMutexes are created when needed, and deleted when the QMutexPool is destructed. */ QMutexPool::QMutexPool( bool recursive, int size ) - : mutex( FALSE ), mutexes( size ), recurs( recursive ) + : mutex( FALSE ), count( size ), recurs( recursive ) { - mutexes.fill( 0 ); + mutexes = new QMutex*[count]; + for ( int index = 0; index < count; ++index ) { + mutexes[index] = 0; + } } /*! Destructs a QMutexPool. All QMutexes that were created by the pool @@ -96,35 +118,35 @@ QMutexPool::QMutexPool( bool recursive, int size ) */ QMutexPool::~QMutexPool() { QMutexLocker locker( &mutex ); - QMutex **d = mutexes.data(); - for ( int index = 0; (uint) index < mutexes.size(); index++ ) { - delete d[index]; - d[index] = 0; + for ( int index = 0; index < count; ++index ) { + delete mutexes[index]; + mutexes[index] = 0; } + delete [] mutexes; + mutexes = 0; } /*! Returns a QMutex from the pool. QMutexPool uses the value \a address to determine which mutex is retured from the pool. */ QMutex *QMutexPool::get( void *address ) { - QMutex **d = mutexes.data(); - int index = (int)( (ulong) address % mutexes.size() ); + int index = (int) ( (unsigned long) address % count ); - if ( ! d[index] ) { + if ( ! mutexes[index] ) { // mutex not created, create one QMutexLocker locker( &mutex ); // we need to check once again that the mutex hasn't been created, since // 2 threads could be trying to create a mutex as the same index... - if ( ! d[index] ) { - d[index] = new QMutex( recurs ); + if ( ! mutexes[index] ) { + mutexes[index] = new QMutex( recurs ); } } - return d[index]; + return mutexes[index]; } #endif diff --git a/qmake/tools/qregexp.cpp b/qmake/tools/qregexp.cpp index 500efed..0c1f060 100644 --- a/qmake/tools/qregexp.cpp +++ b/qmake/tools/qregexp.cpp @@ -262,17 +262,17 @@ corresponding to the octal number ooo (between 0 and 0377). \row \i <b>. (dot)</b> \i This matches any character (including newline). \row \i <b>\\d</b> - \i This matches a digit (see QChar::isDigit()). + \i This matches a digit (QChar::isDigit()). \row \i <b>\\D</b> \i This matches a non-digit. \row \i <b>\\s</b> - \i This matches a whitespace (see QChar::isSpace()). + \i This matches a whitespace (QChar::isSpace()). \row \i <b>\\S</b> \i This matches a non-whitespace. \row \i <b>\\w</b> - \i This matches a word character (see QChar::isLetterOrNumber()). + \i This matches a word character (QChar::isLetterOrNumber() or '_'). \row \i <b>\\W</b> \i This matches a non-word character. \row \i <b>\\n</b> \i The n-th \link #capturing-text backreference \endlink, @@ -546,9 +546,16 @@ To substitute a pattern use QString::replace(). Perl's extended \c{/x} syntax is not supported, nor are - regexp comments (?#comment) or directives, e.g. (?i). + directives, e.g. (?i), or regexp comments, e.g. (?#comment). On + the other hand, C++'s rules for literal strings can be used to + achieve the same: + \code + QRegExp mark( "\\b" // word boundary + "[Mm]ark" // the word we want to match + ); + \endcode Both zero-width positive and zero-width negative lookahead assertions (?=pattern) and (?!pattern) are supported with the same syntax as Perl. Perl's lookbehind assertions, "independent" @@ -678,11 +685,11 @@ \code QRegExp rx( "*.html" ); // invalid regexp: * doesn't quantify anything rx.setWildcard( TRUE ); // now it's a valid wildcard regexp - rx.search( "index.html" ); // returns 0 (matched at position 0) - rx.search( "default.htm" ); // returns -1 (no match) - rx.search( "readme.txt" ); // returns -1 (no match) + rx.exactMatch( "index.html" ); // returns TRUE + rx.exactMatch( "default.htm" ); // returns FALSE + rx.exactMatch( "readme.txt" ); // returns FALSE \endcode Wildcard matching can be convenient because of its simplicity, but any wildcard regexp can be defined using full regexps, e.g. @@ -714,8 +721,13 @@ const int EmptyCapture = INT_MAX; const int InftyLen = INT_MAX; const int InftyRep = 1025; const int EOS = -1; +static bool isWord( QChar ch ) +{ + return ch.isLetterOrNumber() || ch == QChar( '_' ); +} + /* Merges two QMemArrays of ints and puts the result into the first one. */ static void mergeInto( QMemArray<int> *a, const QMemArray<int>& b ) @@ -1679,11 +1691,11 @@ bool QRegExpEngine::testAnchor( int i, int a, const int *capBegin ) if ( (a & (Anchor_Word | Anchor_NonWord)) != 0 ) { bool before = FALSE; bool after = FALSE; if ( mmPos + i != 0 ) - before = mmIn[mmPos + i - 1].isLetterOrNumber(); + before = isWord( mmIn[mmPos + i - 1] ); if ( mmPos + i != mmLen ) - after = mmIn[mmPos + i].isLetterOrNumber(); + after = isWord( mmIn[mmPos + i] ); if ( (a & Anchor_Word) != 0 && (before == after) ) return FALSE; if ( (a & Anchor_NonWord) != 0 && (before != after) ) return FALSE; @@ -2631,9 +2643,16 @@ int QRegExpEngine::getEscape() yyCharClass->addRange( 0x007f, 0x009f ); return Tok_CharClass; case 'W': // see QChar::isLetterOrNumber() - yyCharClass->addCategories( 0x7ff07f8f ); + yyCharClass->addCategories( 0x7fe07f8f ); + yyCharClass->addRange( 0x203f, 0x2040 ); + yyCharClass->addSingleton( 0x2040 ); + yyCharClass->addSingleton( 0x30fb ); + yyCharClass->addRange( 0xfe33, 0xfe34 ); + yyCharClass->addRange( 0xfe4d, 0xfe4f ); + yyCharClass->addSingleton( 0xff3f ); + yyCharClass->addSingleton( 0xff65 ); return Tok_CharClass; #endif #ifndef QT_NO_REGEXP_ESCAPE case 'b': @@ -2651,8 +2670,9 @@ int QRegExpEngine::getEscape() return Tok_CharClass; case 'w': // see QChar::isLetterOrNumber() yyCharClass->addCategories( 0x000f8070 ); + yyCharClass->addSingleton( 0x005f ); // '_' return Tok_CharClass; #endif #ifndef QT_NO_REGEXP_ESCAPE case 'x': @@ -3182,9 +3202,10 @@ static QRegExpEngine *newEngine( const QString& pattern, bool caseSensitive ) { #ifndef QT_NO_REGEXP_OPTIM if ( engineCache != 0 ) { #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &engineCache ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &engineCache ) : 0 ); #endif QRegExpEngine *eng = engineCache->take( pattern ); if ( eng == 0 || eng->caseSensitive() != caseSensitive ) { delete eng; @@ -3198,13 +3219,14 @@ static QRegExpEngine *newEngine( const QString& pattern, bool caseSensitive ) } static void derefEngine( QRegExpEngine *eng, const QString& pattern ) { - if ( eng != 0 && eng->deref() ) { -#ifndef QT_NO_REGEXP_OPTIM #ifdef QT_THREAD_SUPPORT - QMutexLocker locker( qt_global_mutexpool->get( &engineCache ) ); + QMutexLocker locker( qt_global_mutexpool ? + qt_global_mutexpool->get( &engineCache ) : 0 ); #endif + if ( eng != 0 && eng->deref() ) { +#ifndef QT_NO_REGEXP_OPTIM if ( engineCache == 0 ) { engineCache = new QCache<QRegExpEngine>; engineCache->setAutoDelete( TRUE ); cleanup_cache.set( &engineCache ); @@ -3564,15 +3586,8 @@ int QRegExp::match( const QString& str, int index, int *len, return pos; } #endif // QT_NO_COMPAT -/*! - \overload - - This convenience function searches with a \c CaretMode of \c - CaretAtZero which is the most common usage. -*/ - int QRegExp::search( const QString& str, int offset ) const { return search( str, offset, CaretAtZero ); } @@ -3624,15 +3639,8 @@ int QRegExp::search( const QString& str, int offset, CaretMode caretMode ) const return priv->captured[0]; } -/*! - \overload - - This convenience function searches with a \c CaretMode of \c - CaretAtZero which is the most common usage. -*/ - int QRegExp::searchRev( const QString& str, int offset ) const { return searchRev( str, offset, CaretAtZero ); } diff --git a/qmake/tools/qsemaphore_unix.cpp b/qmake/tools/qsemaphore_unix.cpp index fcf28da..4516049 100644 --- a/qmake/tools/qsemaphore_unix.cpp +++ b/qmake/tools/qsemaphore_unix.cpp @@ -182,20 +182,19 @@ int QSemaphore::operator+=(int n) int ret; d->mutex.lock(); + if ( n < 0 || n > d->max ) { +#ifdef QT_CHECK_RANGE + qWarning( "QSemaphore::operator+=: paramter %d out of range", n ); +#endif // QT_CHECK_RANGE + n = n < 0 ? 0 : d->max; + } + while (d->value + n > d->max) d->cond.wait(&(d->mutex)); d->value += n; - -#ifdef QT_CHECK_RANGE - if (d->value > d->max) { - qWarning("QSemaphore::operator+=: attempt to allocate more resources than available"); - d->value = d->max; - } -#endif - ret = d->value; d->mutex.unlock(); @@ -211,17 +210,16 @@ int QSemaphore::operator-=(int n) int ret; d->mutex.lock(); - d->value -= n; - + if ( n < 0 || n > d->value ) { #ifdef QT_CHECK_RANGE - if (d->value < 0) { - qWarning("QSemaphore::operator-=: attempt to deallocate more resources than taken"); - d->value = 0; + qWarning( "QSemaphore::operator-=: paramter %d out of range", n ); +#endif // QT_CHECK_RANGE + n = n < 0 ? 0 : d->value; } -#endif + d->value -= n; ret = d->value; d->cond.wakeOne(); d->mutex.unlock(); diff --git a/qmake/tools/qsettings.cpp b/qmake/tools/qsettings.cpp index 5de105c..35fc039 100644 --- a/qmake/tools/qsettings.cpp +++ b/qmake/tools/qsettings.cpp @@ -2,9 +2,9 @@ ** $Id$ ** ** Implementation of QSettings class ** -** Created: 2000.06.26 +** Created : 000626 ** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. @@ -70,10 +70,10 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) \ingroup misc \mainclass On Unix systems, QSettings uses text files to store settings. On Windows - systems, QSettings uses the system registry. On Mac OS X, QSettings will - behave as on Unix, and store to text files. + systems, QSettings uses the system registry. On Mac OS X, QSettings uses + the Carbon preferences API. Each setting comprises an identifying key and the data associated with the key. A key is a unicode string which consists of \e two or more subkeys. A subkey is a slash, '/', followed by one or more unicode @@ -100,27 +100,42 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) /MyCompany/MyApplication/recent files/3 \endcode Each line above is a complete key, made up of subkeys. - A typical usage pattern for application startup: + A typical usage pattern for reading application startup: \code QSettings settings; - settings.insertSearchPath( QSettings::Windows, "/MyCompany" ); - // No search path needed for Unix; see notes further on. - // Use default values if the keys don't exist - QString bgColor = settings.readEntry( "/MyApplication/background color", "white" ); - int width = settings.readNumEntry( "/MyApplication/geometry/width", 640 ); + settings.setPath( "MyCompany.com", "MyApplication" ); + + QString bgColor = settings.readEntry( "/colors/background", "white" ); + int width = settings.readNumEntry( "/geometry/width", 640 ); // ... \endcode A typical usage pattern for application exit or 'save preferences': \code QSettings settings; - settings.insertSearchPath( QSettings::Windows, "/MyCompany" ); - // No search path needed for Unix; see notes further on. - settings.writeEntry( "/MyApplication/background color", bgColor ); - settings.writeEntry( "/MyApplication/geometry/width", width ); + settings.setPath( "MyCompany.com", "MyApplication" ); + + settings.writeEntry( "/colors/background", bgColor ); + settings.writeEntry( "/geometry/width", width ); + // ... + \endcode + + QSettings can build a key prefix that is prepended to all keys. To + build the key prefix, use beginGroup() and endGroup(). + \code + QSettings settings; + + settings.beginGroup( "/MainWindow" ); + settings.beginGroup( "/Geometry" ); + int x = settings.readEntry( "/x" ); + // ... + settings.endGroup(); + settings.beginGroup( "/Toolbars" ); // ... + settings.endGroup(); + settings.endGroup(); \endcode You can get a list of entry-holding keys by calling entryList(), and a list of key-holding keys using subkeyList(). @@ -138,12 +153,8 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) QStringList subkeys = subkeyList( "/MyApplication/recent files" ); // subkeys is empty. \endcode - If you wish to use a different search path call insertSearchPath() - as often as necessary to add your preferred paths. Call - removeSearchPath() to remove any unwanted paths. - Since settings for Windows are stored in the registry there are size limits as follows: \list \i A subkey may not exceed 255 characters. @@ -151,9 +162,27 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) \i All the values of a key (for example, all the 'recent files' subkeys values), may not exceed 65,535 characters. \endlist - These limitations are not enforced on Unix. + These limitations are not enforced on Unix or Mac OS X. + + If you wish to use a different search path call insertSearchPath() + as often as necessary to add your preferred paths. Call + removeSearchPath() to remove any unwanted paths. + + \section1 Notes for Mac OS X Applications + + Internal to the CFPreferences API it is not defined (for Mac OS 9 + support) where the settings will ultimitely be stored. However, at the + time of this writing the settings will be stored (either on a global or + user basis, preferring locally) into a plist file in + $ROOT/System/Library/Preferences (in XML format). QSettings will create + an appropriate plist file (com.<first group name>.plist) out of the + full path to a key. + + For further information on CFPreferences see also + \link http://developer.apple.com/techpubs/macosx/CoreFoundation/PreferenceServices/preferenceservices_carbon.html + Apple's Specifications\endlink \section1 Notes for Unix Applications There is no universally accepted place for storing application @@ -299,22 +328,22 @@ static HANDLE openlock( const QString &name, int /*type*/ ) } , { fd = CreateFileA( name.local8Bit(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); } ); - if ( !LockFile( fd, 0, 0, -1, -1 ) ) { + if ( !LockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ??? #ifdef QT_CHECK_STATE qWarning( "QSettings: openlock failed!" ); #endif } return fd; } -void closelock( HANDLE fd ) +static void closelock( HANDLE fd ) { if ( !fd ) return; - if ( !UnlockFile( fd, 0, 0, -1, -1 ) ) { + if ( !UnlockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ??? #ifdef QT_CHECK_STATE qWarning( "QSettings: closelock failed!"); #endif } @@ -454,11 +483,13 @@ void QSettingsHeading::parseLine(QTextStream &stream) QSettingsPrivate::QSettingsPrivate( QSettings::Format format ) : groupDirty( TRUE ), modified(FALSE), globalScope(TRUE) { -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( format != QSettings::Ini ) return; +#else + Q_UNUSED( format ); #endif QString appSettings(QDir::homeDirPath() + "/.qt/"); QString defPath; @@ -505,8 +536,10 @@ QSettingsPrivate::QSettingsPrivate( QSettings::Format format ) if (! dir.exists()) { if (! dir.mkdir(dir.path())) #if defined(QT_CHECK_STATE) qWarning("QSettings: error creating %s", dir.path().latin1()); +#else + ; #endif } if ( !!defPath ) @@ -529,8 +562,10 @@ QSettingsGroup QSettingsPrivate::readGroup() QSettingsHeading::Iterator grpit = hd.find(group); if (grpit == hd.end()) { QStringList::Iterator it = searchPaths.begin(); + if ( !globalScope ) + ++it; while (it != searchPaths.end()) { QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); QString fn((*it++) + "/" + filebase + "rc"); if (! hd.contains(fn + "cached")) { @@ -563,8 +598,10 @@ void QSettingsPrivate::removeGroup(const QString &key) QSettingsHeading::Iterator grpit = hd.find(group); if (grpit == hd.end()) { QStringList::Iterator it = searchPaths.begin(); + if ( !globalScope ) + ++it; while (it != searchPaths.end()) { QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); QString fn((*it++) + "/" + filebase + "rc"); if (! hd.contains(fn + "cached")) { @@ -614,8 +651,10 @@ void QSettingsPrivate::writeGroup(const QString &key, const QString &value) QSettingsHeading::Iterator grpit = hd.find(group); if (grpit == hd.end()) { QStringList::Iterator it = searchPaths.begin(); + if ( !globalScope ) + ++it; while (it != searchPaths.end()) { QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); QString fn((*it++) + "/" + filebase + "rc"); if (! hd.contains(fn + "cached")) { @@ -648,8 +687,10 @@ QDateTime QSettingsPrivate::modificationTime() QDateTime datetime; QStringList::Iterator it = searchPaths.begin(); + if ( !globalScope ) + ++it; while (it != searchPaths.end()) { QFileInfo fi((*it++) + "/" + heading + "rc"); if (fi.exists() && fi.lastModified() > datetime) datetime = fi.lastModified(); @@ -657,19 +698,25 @@ QDateTime QSettingsPrivate::modificationTime() return datetime; } -static bool verifyKey( const QString &key ) +bool qt_verify_key( const QString &key ) { if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\\\r\\\\n" ) ) ) return FALSE; return TRUE; } static inline QString groupKey( const QString &group, const QString &key ) { - if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) + if ( group.isEmpty() || ( group.length() == 1 && group[0] == '/' ) ) { + // group is empty, or it contains a single '/', so we just return the key + if ( key.startsWith( "/" ) ) + return key; + return "/" + key; + } else if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) { return group + key; + } return group + "/" + key; } /*! @@ -756,36 +803,51 @@ static inline QString groupKey( const QString &group, const QString &key ) */ void QSettings::insertSearchPath( System s, const QString &path) { -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) { d->sysInsertSearchPath( s, path ); return; } #endif - if ( !verifyKey( path ) ) { +#if !defined(Q_WS_WIN) + if ( s == Windows ) + return; +#endif +#if !defined(Q_WS_WIN) + if ( s == Mac ) + return; +#endif + + if ( !qt_verify_key( path ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); #endif return; } -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd && s != Unix ) { #else if ( s != Unix ) { #endif -#ifdef Q_OS_MAC +#if !defined(QWS) && defined(Q_OS_MAC) if(s != Mac) //mac is respected on the mac as well #endif return; } + QString realPath = path; +#if defined(Q_WS_WIN) + QString defPath = d->globalScope ? d->searchPaths.first() : d->searchPaths.last(); + realPath = defPath + path; +#endif + QStringList::Iterator it = d->searchPaths.find(d->searchPaths.last()); if (it != d->searchPaths.end()) { - d->searchPaths.insert(it, path); + d->searchPaths.insert(it, realPath); } } @@ -797,9 +859,9 @@ void QSettings::insertSearchPath( System s, const QString &path) \sa insertSearchPath() */ void QSettings::removeSearchPath( System s, const QString &path) { - if ( !verifyKey( path ) ) { + if ( !qt_verify_key( path ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); #endif return; @@ -810,14 +872,14 @@ void QSettings::removeSearchPath( System s, const QString &path) d->sysRemoveSearchPath( s, path ); return; } #endif -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd && s != Unix ) { #else if ( s != Unix ) { #endif -#ifdef Q_OS_MAC +#if !defined(QWS) && defined(Q_OS_MAC) if(s != Mac) //mac is respected on the mac as well #endif return; } @@ -836,9 +898,9 @@ QSettings::QSettings() { d = new QSettingsPrivate( Native ); Q_CHECK_PTR(d); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) d->sysd = 0; d->sysInit(); #endif } @@ -853,9 +915,9 @@ QSettings::QSettings( Format format ) { d = new QSettingsPrivate( format ); Q_CHECK_PTR(d); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) d->sysd = 0; if ( format == Native ) d->sysInit(); #else @@ -871,9 +933,9 @@ QSettings::QSettings( Format format ) QSettings::~QSettings() { sync(); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) d->sysClear(); #endif @@ -886,9 +948,9 @@ QSettings::~QSettings() encountered, this function returns FALSE, otherwise it will return TRUE. */ bool QSettings::sync() { -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysSync(); #endif if (! d->modified) @@ -904,8 +966,10 @@ bool QSettings::sync() QSettingsHeading::Iterator hdit = hd.begin(); QFile file; QStringList::Iterator pit = d->searchPaths.begin(); + if ( !d->globalScope ) + ++pit; while (pit != d->searchPaths.end()) { QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_"); QFileInfo di(*pit); QFileInfo fi((*pit++) + "/" + filebase + "rc"); @@ -916,11 +980,11 @@ bool QSettings::sync() break; } } - it++; + ++it; - if (file.name().isNull() || file.name().isEmpty()) { + if ( file.name().isEmpty() ) { #ifdef QT_CHECK_STATE qWarning("QSettings::sync: filename is null/empty"); #endif // QT_CHECK_STATE @@ -962,15 +1026,15 @@ bool QSettings::sync() v.replace("\n", "\\n"); // escape newlines } stream << grpit.key() << "=" << v << endl; - grpit++; + ++grpit; } stream << endl; } - hdit++; + ++hdit; } if (file.status() != IO_Ok) { @@ -1007,9 +1071,9 @@ bool QSettings::sync() \internal */ bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif if ( ok ) @@ -1017,15 +1081,14 @@ bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) return def; } - QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysReadBoolEntry( theKey, def, ok ); + return d->sysReadBoolEntry( groupKey( group(), key ), def, ok ); #endif - QString value = readEntry( theKey, ( def ? "true" : "false" ), ok ); + QString value = readEntry( key, ( def ? "true" : "false" ), ok ); if (value.lower() == "true") return TRUE; else if (value.lower() == "false") @@ -1059,9 +1122,9 @@ bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) \internal */ double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif if ( ok ) @@ -1069,15 +1132,14 @@ double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) return def; } - QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysReadDoubleEntry( theKey, def, ok ); + return d->sysReadDoubleEntry( groupKey( group(), key ), def, ok ); #endif - QString value = readEntry( theKey, QString::number(def), ok ); + QString value = readEntry( key, QString::number(def), ok ); bool conv_ok; double retval = value.toDouble( &conv_ok ); if ( conv_ok ) return retval; @@ -1105,25 +1167,23 @@ double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) \internal */ int QSettings::readNumEntry(const QString &key, int def, bool *ok ) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::readNumEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif if ( ok ) *ok = FALSE; return def; } - QString theKey = groupKey( group(), key ); - -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysReadNumEntry( theKey, def, ok ); + return d->sysReadNumEntry( groupKey( group(), key ), def, ok ); #endif - QString value = readEntry( theKey, QString::number( def ), ok ); + QString value = readEntry( key, QString::number( def ), ok ); bool conv_ok; int retval = value.toInt( &conv_ok ); if ( conv_ok ) return retval; @@ -1151,9 +1211,9 @@ int QSettings::readNumEntry(const QString &key, int def, bool *ok ) \internal */ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::readEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif if ( ok ) @@ -1163,9 +1223,9 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysReadEntry( theKey, def, ok ); #endif @@ -1205,13 +1265,15 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) } else realkey = theKey; QSettingsGroup grp = d->readGroup(); - QString retval = grp[realkey]; - if ( retval.isNull() ) - retval = def; - else if ( ok ) // everything is ok - *ok = TRUE; + QSettingsGroup::const_iterator it = grp.find( realkey ), end = grp.end(); + QString retval = def; + if ( it != end ) { + // found the value we needed + retval = *it; + if ( ok ) *ok = TRUE; + } return retval; } @@ -1227,23 +1289,21 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ bool QSettings::writeEntry(const QString &key, bool value) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } - QString theKey = groupKey( group(), key ); - -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysWriteEntry( theKey, value ); + return d->sysWriteEntry( groupKey( group(), key ), value ); #endif QString s(value ? "true" : "false"); - return writeEntry(theKey, s); + return writeEntry(key, s); } #endif @@ -1259,23 +1319,21 @@ bool QSettings::writeEntry(const QString &key, bool value) \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ bool QSettings::writeEntry(const QString &key, double value) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } - QString theKey = groupKey( group(), key ); - -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysWriteEntry( theKey, value ); + return d->sysWriteEntry( groupKey( group(), key ), value ); #endif QString s(QString::number(value)); - return writeEntry(theKey, s); + return writeEntry(key, s); } /*! @@ -1290,23 +1348,21 @@ bool QSettings::writeEntry(const QString &key, double value) \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ bool QSettings::writeEntry(const QString &key, int value) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } - QString theKey = groupKey( group(), key ); - -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysWriteEntry( theKey, value ); + return d->sysWriteEntry( groupKey( group(), key ), value ); #endif QString s(QString::number(value)); - return writeEntry(theKey, s); + return writeEntry(key, s); } /*! @@ -1326,18 +1382,16 @@ bool QSettings::writeEntry(const QString &key, int value) \sa readEntry(), removeEntry() */ bool QSettings::writeEntry(const QString &key, const char *value) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } - QString theKey = groupKey( group(), key ); - - return writeEntry(theKey, QString(value)); + return writeEntry(key, QString(value)); } /*! @@ -1353,18 +1407,18 @@ bool QSettings::writeEntry(const QString &key, const char *value) \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ bool QSettings::writeEntry(const QString &key, const QString &value) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysWriteEntry( theKey, value ); #endif // NOTE: we *do* allow value to be a null/empty string @@ -1414,18 +1468,18 @@ bool QSettings::writeEntry(const QString &key, const QString &value) \sa readEntry(), writeEntry() */ bool QSettings::removeEntry(const QString &key) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::removeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return FALSE; } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysRemoveEntry( theKey ); #endif @@ -1493,18 +1547,18 @@ bool QSettings::removeEntry(const QString &key) \sa subkeyList() */ QStringList QSettings::entryList(const QString &key) const { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::entryList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); #endif return QStringList(); } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysEntryList( theKey ); #endif @@ -1543,9 +1597,9 @@ QStringList QSettings::entryList(const QString &key) const QStringList ret; QString itkey; while (it != grp.end()) { itkey = it.key(); - it++; + ++it; if ( realkey.length() > 0 ) { if ( itkey.left( realkey.length() ) != realkey ) continue; @@ -1590,23 +1644,24 @@ QStringList QSettings::entryList(const QString &key) const \sa entryList() */ QStringList QSettings::subkeyList(const QString &key) const { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::subkeyList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); #endif return QStringList(); } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysSubkeyList( theKey ); #endif QString realkey; + int subkeycount = 2; if (theKey[0] == '/') { // parse our key QStringList list(QStringList::split('/', theKey)); @@ -1617,8 +1672,10 @@ QStringList QSettings::subkeyList(const QString &key) const return QStringList(); } + subkeycount = list.count(); + if (list.count() == 1) { d->heading = list[0]; d->group = "General"; } else { @@ -1631,18 +1688,30 @@ QStringList QSettings::subkeyList(const QString &key) const list.remove(list.at(0)); realkey = list.join("/"); } + } else realkey = theKey; + QStringList ret; + if ( subkeycount == 1 ) { + QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin(); + while ( it != d->headings.end() ) { + if ( it.key() != "General" && ! ret.contains( it.key() ) ) + ret << it.key(); + ++it; + } + + return ret; + } + QSettingsGroup grp = d->readGroup(); QSettingsGroup::Iterator it = grp.begin(); - QStringList ret; QString itkey; while (it != grp.end()) { itkey = it.key(); - it++; + ++it; if ( realkey.length() > 0 ) { if ( itkey.left( realkey.length() ) != realkey ) continue; @@ -1669,18 +1738,18 @@ QStringList QSettings::subkeyList(const QString &key) const This function returns the time of last modification for \a key. */ QDateTime QSettings::lastModficationTime(const QString &key) { - if ( !verifyKey( key ) ) { + if ( !qt_verify_key( key ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::lastModficationTime: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); #endif return QDateTime(); } QString theKey = groupKey( group(), key ); -#if defined(Q_WS_WIN) || defined(Q_OS_MAC) +#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return QDateTime(); #endif @@ -1714,11 +1783,19 @@ QDateTime QSettings::lastModficationTime(const QString &key) Writes the string list entry \a value into key \a key. The \a key is created if it doesn't exist. Any previous value is overwritten by \a value. The list is stored as a sequence of strings separated - by \a separator, so none of the strings in the list should contain - the separator. If the list is empty or null the key's value will - be an empty string. + by \a separator (using QStringList::join()), so none of the + strings in the list should contain the separator. If the list is + empty or null the key's value will be an empty string. + + \warning The list should not contain empty or null strings, as + readListEntry() will use QStringList::split() to recreate the + list. As the documentation states, QStringList::split() will omit + empty strings from the list. Because of this, it is impossible to + retrieve identical list data that is stored with this function. + We recommend using the writeEntry() and readListEntry() overloads + that do not take a \a separator argument. If an error occurs the settings are left unchanged and FALSE is returned; otherwise returns TRUE. @@ -1767,8 +1844,15 @@ bool QSettings::writeEntry(const QString &key, const QStringList &value) is used to create a QStringList by calling QStringList::split(\a separator, entry). If \a ok is not 0: \a *ok is set to TRUE if the key was read, otherwise \a *ok is set to FALSE. + \warning As the documentation states, QStringList::split() will + omit empty strings from the list. Because of this, it is + impossible to retrieve identical list data with this function. We + recommend using the readListEntry() and writeEntry() overloads + that do not take a \a separator argument. + + Note that if you want to iterate over the list, you should iterate over a copy, e.g. \code QStringList list = mySettings.readListEntry( "size", " " ); @@ -1846,8 +1930,12 @@ QStringList QSettings::readListEntry(const QString &key, bool *ok ) } return l; } +#ifdef Q_OS_MAC +void qt_setSettingsBasePath(const QString &); //qsettings_mac.cpp +#endif + /*! Insert platform-dependent paths from platform-independent information. The \a domain should be an Internet domain name @@ -1859,8 +1947,11 @@ QStringList QSettings::readListEntry(const QString &key, bool *ok ) The \a scope should be QSettings::User for user-specific settings, or QSettings::Global for system-wide settings (generally these will be read-only to many users). + + Not all information is relevant on all systems (e.g. scoping is + currently used only if QSettings accesses the Windows registry). */ void QSettings::setPath( const QString &domain, const QString &product, Scope scope ) { @@ -1879,30 +1970,37 @@ void QSettings::setPath( const QString &domain, const QString &product, Scope sc // The Global scope corresponds to /Library/Preferences/*.plist, while the // User scope corresponds to ~/Library/Preferences/*.plist. // Note that on most installations, not all users can write to the System // scope. + d->globalScope = scope == Global; + QString actualSearchPath; int lastDot = domain.findRev( '.' ); #if defined(Q_WS_WIN) actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; insertSearchPath( Windows, actualSearchPath ); -#elif defined(Q_WS_MAC) +#elif !defined(QWS) && defined(Q_OS_MAC) QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + "."; - if ( topLevelDomain.isEmpty() ) - topLevelDomain = "com."; - actualSearchPath = "/" + topLevelDomain + domain.left( lastDot ) + product; + if ( !topLevelDomain.isEmpty() ) + qt_setSettingsBasePath( topLevelDomain ); + actualSearchPath = "/" + domain.left( lastDot ) + product; insertSearchPath( Mac, actualSearchPath ); #else actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; insertSearchPath( Unix, actualSearchPath ); #endif - - d->globalScope = scope == Global; } /*! Appends \a group to the current key prefix. + + \code + QSettings settings; + settings.beginGroup( "/MainWindow" ); + // read values + settings.endGroup(); + \endcode */ void QSettings::beginGroup( const QString &group ) { d->groupStack.push( group ); @@ -1911,8 +2009,15 @@ void QSettings::beginGroup( const QString &group ) /*! Undo previous calls to beginGroup(). Note that a single beginGroup("a/b/c") is undone by a single call to endGroup(). + + \code + QSettings settings; + settings.beginGroup( "/MainWindow/Geometry" ); + // read values + settings.endGroup(); + \endcode */ void QSettings::endGroup() { d->groupStack.pop(); @@ -1944,9 +2049,9 @@ QString QSettings::group() const while ( it != d->groupStack.end() ) { QString group = *it; ++it; if ( group[0] != '/' ) - group = "/" + group; + group.prepend( "/" ); d->groupPrefix += group; } } return d->groupPrefix; diff --git a/qmake/tools/qstring.cpp b/qmake/tools/qstring.cpp index 56df62b..7f1fac3 100644 --- a/qmake/tools/qstring.cpp +++ b/qmake/tools/qstring.cpp @@ -4,9 +4,9 @@ ** Implementation of the QString class and related Unicode functions ** ** Created : 920722 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 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 @@ -46,20 +46,24 @@ #include "qdatastream.h" #ifndef QT_NO_TEXTCODEC #include "qtextcodec.h" #endif -#include <ctype.h> #include <limits.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #if defined(Q_WS_WIN) #include "qt_windows.h" #endif #if !defined( QT_NO_COMPONENT ) && !defined( QT_LITE_COMPONENT ) #include "qcleanuphandler.h" #endif +#ifdef QT_NO_UNICODETABLES +# include <ctype.h> +#endif + /* ------------------------------------------------------------------------- * unicode information * these tables are generated from the unicode reference file @@ -11786,8 +11790,9 @@ static inline QChar::Direction direction( const QChar &c ) const Q_UINT8 *rowp = direction_info[c.row()]; if(!rowp) return QChar::DirL; return (QChar::Direction) ( *(rowp+c.cell()) & 0x1f ); #else + Q_UNUSED(c); return QChar::DirL; #endif } @@ -11798,8 +11803,9 @@ static inline bool mirrored( const QChar &c ) if ( !rowp ) return FALSE; return *(rowp+c.cell())>128; #else + Q_UNUSED(c); return FALSE; #endif } @@ -11899,9 +11905,9 @@ static uint computeNewMax( uint len ) { uint newMax = 4; while ( newMax < len ) newMax *= 2; - // try to spare some memory + // try to save some memory if ( newMax >= 1024 * 1024 && len <= newMax - (newMax >> 2) ) newMax -= newMax >> 2; return newMax; } @@ -12890,9 +12896,9 @@ void QString::compose() The caller is responsible for deleting the return value with delete[]. */ -QChar* QString::asciiToUnicode( const QByteArray& ba, uint* len ) +QChar* QString::latin1ToUnicode( const QByteArray& ba, uint* len ) { if ( ba.isNull() ) { *len = 0; return 0; @@ -12909,9 +12915,9 @@ QChar* QString::asciiToUnicode( const QByteArray& ba, uint* len ) *uc++ = *str++; return result; } -static QChar* internalAsciiToUnicode( const QByteArray& ba, uint* len ) +static QChar* internalLatin1ToUnicode( const QByteArray& ba, uint* len ) { if ( ba.isNull() ) { *len = 0; return 0; @@ -12939,9 +12945,9 @@ static QChar* internalAsciiToUnicode( const QByteArray& ba, uint* len ) The caller is responsible for deleting the return value with delete[]. */ -QChar* QString::asciiToUnicode( const char *str, uint* len, uint maxlen ) +QChar* QString::latin1ToUnicode( const char *str, uint* len, uint maxlen ) { QChar* result = 0; uint l = 0; if ( str ) { @@ -12949,9 +12955,9 @@ QChar* QString::asciiToUnicode( const char *str, uint* len, uint maxlen ) while ( l < maxlen && str[l] ) l++; } else { // Faster? - l = qstrlen(str); + l = strlen( str ); } QChar *uc = new QChar[ l ]; // Can't use macro since function is public result = uc; uint i = l; @@ -12962,9 +12968,9 @@ QChar* QString::asciiToUnicode( const char *str, uint* len, uint maxlen ) *len = l; return result; } -static QChar* internalAsciiToUnicode( const char *str, uint* len, +static QChar* internalLatin1ToUnicode( const char *str, uint* len, uint maxlen = (uint)-1 ) { QChar* result = 0; uint l = 0; @@ -12973,9 +12979,9 @@ static QChar* internalAsciiToUnicode( const char *str, uint* len, while ( l < maxlen && str[l] ) l++; } else { // Faster? - l = qstrlen(str); + l = strlen( str ); } QChar *uc = QT_ALLOC_QCHAR_VEC( l ); result = uc; uint i = l; @@ -12993,9 +12999,9 @@ static QChar* internalAsciiToUnicode( const char *str, uint* len, The caller is responsible for deleting the resultant string with delete[]. */ -char* QString::unicodeToAscii(const QChar *uc, uint l) +char* QString::unicodeToLatin1(const QChar *uc, uint l) { if (!uc) { return 0; } @@ -13156,37 +13162,8 @@ QStringData* QString::makeSharedNull() #endif return QString::shared_null; } -// Uncomment this to get some useful statistics. -// #define Q2HELPER(x) x - -#ifdef Q2HELPER -static int stat_construct_charstar=0; -static int stat_construct_charstar_size=0; -static int stat_construct_null=0; -static int stat_construct_int=0; -static int stat_construct_int_size=0; -static int stat_construct_ba=0; -static int stat_get_ascii=0; -static int stat_get_ascii_size=0; -static int stat_copy_on_write=0; -static int stat_copy_on_write_size=0; -static int stat_fast_copy=0; -Q_EXPORT void qt_qstring_stats() -{ - qDebug("construct_charstar = %d (%d chars)", stat_construct_charstar, stat_construct_charstar_size); - qDebug("construct_null = %d", stat_construct_null); - qDebug("construct_int = %d (%d chars)", stat_construct_int, stat_construct_int_size); - qDebug("construct_ba = %d", stat_construct_ba); - qDebug("get_ascii = %d (%d chars)", stat_get_ascii, stat_get_ascii_size); - qDebug("copy_on_write = %d (%d chars)", stat_copy_on_write, stat_copy_on_write_size); - qDebug("fast_copy = %d", stat_fast_copy); -} -#else -#define Q2HELPER(x) -#endif - /*! \fn QString::QString() Constructs a null string, i.e. both the length and data pointer @@ -13210,9 +13187,8 @@ QString::QString( QChar ch ) */ QString::QString( const QString &s ) : d(s.d) { - Q2HELPER(stat_fast_copy++) d->ref(); } /*! @@ -13229,15 +13205,12 @@ QString::QString( const QString &s ) : QString::QString( int size, bool /*dummy*/ ) { if ( size ) { - Q2HELPER(stat_construct_int++) int l = size; - Q2HELPER(stat_construct_int_size+=l) QChar* uc = QT_ALLOC_QCHAR_VEC( l ); d = new QStringData( uc, 0, l ); } else { - Q2HELPER(stat_construct_null++) d = shared_null ? shared_null : (shared_null=new QStringData); d->ref(); } } @@ -13248,11 +13221,17 @@ QString::QString( int size, bool /*dummy*/ ) */ QString::QString( const QByteArray& ba ) { - Q2HELPER(stat_construct_ba++) +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + d = 0; + *this = fromAscii( ba.data(), ba.size() ); + return; + } +#endif uint l; - QChar *uc = internalAsciiToUnicode(ba,&l); + QChar *uc = internalLatin1ToUnicode(ba,&l); d = new QStringData(uc,l,l); } /*! @@ -13301,15 +13280,42 @@ QString::QString( const QChar* unicode, uint length ) */ QString::QString( const char *str ) { - Q2HELPER(stat_construct_charstar++) +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + d = 0; + *this = fromAscii( str ); + return; + } +#endif uint l; - QChar *uc = internalAsciiToUnicode(str,&l); - Q2HELPER(stat_construct_charstar_size+=l) + QChar *uc = internalLatin1ToUnicode(str,&l); d = new QStringData(uc,l,l); } +#ifndef QT_NO_STL +/*! + Constructs a string that is a deep copy of \a str. + + This is the same as fromAscii(\a str). +*/ + +QString::QString( const std::string &str ) +{ +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + d = 0; + *this = fromAscii( str.c_str() ); + return; + } +#endif + uint l; + QChar *uc = internalLatin1ToUnicode(str.c_str(),&l); + d = new QStringData(uc,l,l); +} +#endif + /*! \fn QString::~QString() Destroys the string and frees the string's data if this is the @@ -13332,12 +13338,12 @@ void QString::real_detach() } void QString::deref() { - if ( d->deref() ) { + if ( d && d->deref() ) { if ( d != shared_null ) delete d; - d = 0; // helps debugging + d = 0; } } void QStringData::deleteSelf() @@ -13351,8 +13357,17 @@ void QStringData::deleteSelf() Sets the string to contain just the single character \a c. */ /*! + \fn QString& QString::operator=( const std::string& s ) + + \overload + + Makes a deep copy of \a s and returns a reference to the deep + copy. +*/ + +/*! \fn QString& QString::operator=( char c ) \overload @@ -13367,9 +13382,8 @@ void QStringData::deleteSelf() isn't actually copied. */ QString &QString::operator=( const QString &s ) { - Q2HELPER(stat_fast_copy++) s.d->ref(); deref(); d = s.d; return *this; @@ -13382,9 +13396,9 @@ QString &QString::operator=( const QString &s ) to this string and returns a reference to this string. */ QString &QString::operator=( const QCString& cs ) { - return setLatin1(cs); + return setAscii(cs); } /*! @@ -13398,9 +13412,9 @@ QString &QString::operator=( const QCString& cs ) \sa isNull() */ QString &QString::operator=( const char *str ) { - return setLatin1(str); + return setAscii(str); } /*! @@ -13470,10 +13484,9 @@ void QString::truncate( uint newLen ) Ensures that at least \a newLen characters are allocated to the string, and sets the length of the string to \a newLen. Any new space allocated contains arbitrary data. - If \a newLen is 0, then the string becomes empty, unless the - string is null, in which case it remains null. + If \a newLen is 0, then the string becomes empty (non-null). If it is not possible to allocate enough memory, the string remains unchanged. @@ -13485,14 +13498,14 @@ void QString::truncate( uint newLen ) we want to add to the string until some condition is true, and we're fairly sure that size is big enough: \code QString result; - int resultLength = 0; - result.setLength( newLen ) // allocate some space + int len = 0; + result.setLength( maxLen ); // allocate some space while ( ... ) { - result[resultLength++] = ... // fill (part of) the space with data + result[len++] = ... // fill part of the space } - result.truncate[resultLength]; // and get rid of the undefined junk + result.truncate( len ); // and get rid of the rest \endcode If \a newLen is an underestimate, the worst that will happen is that the loop will slow down. @@ -13504,10 +13517,8 @@ void QString::setLength( uint newLen ) { if ( d->count != 1 || newLen > d->maxl || ( newLen * 4 < d->maxl && d->maxl > 4 ) ) { // detach, grow or shrink - Q2HELPER(stat_copy_on_write++) - Q2HELPER(stat_copy_on_write_size+=d->len) uint newMax = computeNewMax( newLen ); QChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); if ( nd ) { uint len = QMIN( d->len, newLen ); @@ -13529,23 +13540,22 @@ void QString::setLength( uint newLen ) The \a fieldwidth value specifies the minimum amount of space that \a a is padded to. A positive value will produce right-aligned text, whereas a negative value will produce left-aligned text. + The following example shows how we could create a 'status' string + when processing a list of files: \code - QString firstName( "Joe" ); - QString lastName( "Bloggs" ); - QString fullName; - fullName = QString( "First name is '%1', last name is '%2'" ) - .arg( firstName ) - .arg( lastName ); - - // fullName == First name is 'Joe', last name is 'Bloggs' + QString status = QString( "Processing file %1 of %2: %3" ) + .arg( i ) // current file's number + .arg( total ) // number of files to process + .arg( fileName ); // current file's name \endcode - Note that using arg() to construct sentences as we've done in the - example above does not usually translate well into other languages - because sentence structure and word order often differ between - languages. + It is generally fine to use filenames and numbers as we have done + in the example above. But note that using arg() to construct + natural language sentences does not usually translate well into + other languages because sentence structure and word order often + differ between languages. If there is no place marker (\c %1 or \c %2, etc.), a warning message (qWarning()) is output and the text is appended at the end of the string. We recommend that the correct number of place @@ -13773,9 +13783,9 @@ QString &QString::sprintf( const char* cformat, ... ) // Qt 1.x compat *this = fromLatin1( "" ); return *this; } - QString format = fromLatin1( cformat ); + QString format = fromAscii( cformat ); QRegExp escape( "%#?0?-? ?\\+?'?[0-9*]*\\.?[0-9*]*h?l?L?q?Z?" ); QString result; uint last = 0; @@ -13912,9 +13922,9 @@ QString &QString::sprintf( const char* cformat, ... ) ::sprintf( out, in, width, decimals, value ); } } } - replacement = fromLatin1( out ); + replacement = fromAscii( out ); } result += replacement; } *this = result; @@ -14123,10 +14133,12 @@ int QString::find( const QString& str, int index, bool cs ) const return -1; if ( !sl ) return index; +#ifndef MACOSX_101 if ( sl == 1 ) return find( *str.unicode(), index, cs ); +#endif // we use the Boyer-Moore algorithm in cases where the overhead // for the hash table should pay off, otherwise we use a simple // hash function @@ -14220,8 +14232,11 @@ int QString::find( const QString& str, int index, bool cs ) const */ int QString::findRev( QChar c, int index, bool cs ) const { +#ifdef MACOSX_101 + return findRev( QString( c ), index, cs ); +#else const uint l = length(); if ( index < 0 ) index += l; if ( (uint)index >= l ) @@ -14236,8 +14251,9 @@ int QString::findRev( QChar c, int index, bool cs ) const while ( uc >= end && ::lower( *uc ) != c ) uc--; } return uc - end; +#endif } /*! \overload @@ -14272,10 +14288,12 @@ int QString::findRev( const QString& str, int index, bool cs ) const return -1; if ( index > delta ) index = delta; +#ifndef MACOSX_101 if ( sl == 1 ) return findRev( *str.unicode(), index, cs ); +#endif const QChar* needle = str.unicode(); const QChar* haystack = unicode() + index; const QChar* end = unicode(); @@ -14978,21 +14996,26 @@ QString QString::rightJustify( uint width, QChar fill, bool truncate ) const */ QString QString::lower() const { - QString s(*this); int l=length(); - if ( l ) { - s.real_detach(); // could do this only when we find a change - register QChar *p=s.d->unicode; - if ( p ) { - while ( l-- ) { + register QChar *p = d->unicode; + while ( l ) { + if ( *p != ::lower(*p) ) { + QString s( *this ); + s.real_detach(); + p = s.d->unicode + ( p - d->unicode ); + while ( l ) { *p = ::lower( *p ); + l--; p++; } + return s; } + l--; + p++; } - return s; + return *this; } /*! Returns an uppercase copy of the string. @@ -15006,21 +15029,26 @@ QString QString::lower() const */ QString QString::upper() const { - QString s(*this); int l=length(); - if ( l ) { - s.real_detach(); // could do this only when we find a change - register QChar *p=s.d->unicode; - if ( p ) { - while ( l-- ) { + register QChar *p = d->unicode; + while ( l ) { + if ( *p != ::upper(*p) ) { + QString s( *this ); + s.real_detach(); + p = s.d->unicode + ( p - d->unicode ); + while ( l ) { *p = ::upper( *p ); + l--; p++; } + return s; } + l--; + p++; } - return s; + return *this; } /*! @@ -15136,10 +15164,10 @@ QString &QString::insert( uint index, const QString &s ) /*! \overload - Inserts the character in \a s into the string at position \a index - \a len number of times and returns a reference to the string. + Inserts the first \a len characters in \a s into the string at + position \a index and returns a reference to the string. */ QString &QString::insert( uint index, const QChar* s, uint len ) { @@ -15250,8 +15278,18 @@ QString &QString::insert( uint index, QChar c ) // insert char \sa insert() */ +/*! \fn QString& QString::prepend( const std::string &s ) + \overload + + Inserts \a s at the beginning of the string and returns a reference to the string. + + Equivalent to insert(0, \a s). + + \sa insert() + */ + /*! \overload Inserts \a s at the beginning of the string and returns a reference to the string. @@ -15847,11 +15885,11 @@ static bool ok_in_base( QChar c, int base ) long QString::toLong( bool *ok, int base ) const { const QChar *p = unicode(); - long val = 0; + ulong val = 0; int l = length(); - const long max_mult = INT_MAX / base; + const ulong max_mult = LONG_MAX / base; bool is_ok = FALSE; int neg = 0; if ( !p ) goto bye; @@ -15882,23 +15920,21 @@ long QString::toLong( bool *ok, int base ) const else dv = *p - 'A' + 10; } if ( val > max_mult || - (val == max_mult && dv > (INT_MAX % base) + neg) ) + (val == max_mult && dv > (LONG_MAX % base) + neg) ) goto bye; val = base * val + dv; p++; } - if ( neg ) - val = -val; while ( l && p->isSpace() ) // skip trailing space l--,p++; if ( !l ) is_ok = TRUE; bye: if ( ok ) *ok = is_ok; - return is_ok ? val : 0; + return is_ok ? ( neg ? -( (long) val ) : (long) val ) : 0L; } /*! Returns the string converted to an \c {unsigned long} value to the @@ -15914,9 +15950,9 @@ ulong QString::toULong( bool *ok, int base ) const { const QChar *p = unicode(); ulong val = 0; int l = length(); - const ulong max_mult = UINT_MAX / base; + const ulong max_mult = ULONG_MAX / base; bool is_ok = FALSE; if ( !p ) goto bye; while ( l && p->isSpace() ) // skip leading space @@ -15939,9 +15975,9 @@ ulong QString::toULong( bool *ok, int base ) const dv = *p - 'a' + 10; else dv = *p - 'A' + 10; } - if ( val > max_mult || (val == max_mult && dv > UINT_MAX % base) ) + if ( val > max_mult || (val == max_mult && dv > ULONG_MAX % base) ) goto bye; val = base * val + dv; p++; } @@ -15966,9 +16002,9 @@ bye: short QString::toShort( bool *ok, int base ) const { long v = toLong( ok, base ); - if ( ok && *ok && (v < -32768 || v > 32767) ) { + if ( ok && *ok && (v < SHRT_MIN || v > SHRT_MAX) ) { *ok = FALSE; v = 0; } return (short)v; @@ -15985,9 +16021,9 @@ short QString::toShort( bool *ok, int base ) const ushort QString::toUShort( bool *ok, int base ) const { ulong v = toULong( ok, base ); - if ( ok && *ok && (v > 65535) ) { + if ( ok && *ok && (v > USHRT_MAX) ) { *ok = FALSE; v = 0; } return (ushort)v; @@ -16012,9 +16048,14 @@ ushort QString::toUShort( bool *ok, int base ) const */ int QString::toInt( bool *ok, int base ) const { - return (int)toLong( ok, base ); + long v = toLong( ok, base ); + if ( ok && *ok && (v < INT_MIN || v > INT_MAX) ) { + *ok = FALSE; + v = 0; + } + return (int)v; } /*! Returns the string converted to an \c{unsigned int} value to the @@ -16027,9 +16068,14 @@ int QString::toInt( bool *ok, int base ) const */ uint QString::toUInt( bool *ok, int base ) const { - return (uint)toULong( ok, base ); + ulong v = toULong( ok, base ); + if ( ok && *ok && (v > UINT_MAX) ) { + *ok = FALSE; + v = 0; + } + return (uint)v; } /*! Returns the string converted to a \c double value. @@ -16051,9 +16097,9 @@ double QString::toDouble( bool *ok ) const const char *a = latin1(); double val = strtod( a ? a : "", &end ); if ( ok ) - *ok = ( a && *a && (end == 0 || (end - a) == (int)length()) ); + *ok = ( a && *a && (end == 0 || *end == '\0') ); return val; } /*! @@ -16097,13 +16143,13 @@ QString &QString::setNum( long n, int base ) int len = 0; bool neg; if ( n < 0 ) { neg = TRUE; - if ( n == INT_MIN ) { + if ( n == LONG_MIN ) { // Cannot always negate this special case QString s1, s2; - s1.setNum(n/base); - s2.setNum((-(n+base))%base); + s1.setNum(n/base, base ); + s2.setNum((-(n+base))%base, base ); *this = s1 + s2; return *this; } n = -n; @@ -16460,8 +16506,17 @@ void QString::setExpand( uint index, QChar c ) Equivalent to operator+=(). */ +/*! \fn QString& QString::append( const std::string &str ) + \overload + + Appends \a str to the string and returns a reference to the result. + + Equivalent to operator+=(). + */ + + /*! \fn QString& QString::append( const char *str ) \overload Appends \a str to the string and returns a reference to the result. @@ -16489,11 +16544,17 @@ QString& QString::operator+=( const QString &str ) \overload Appends \a str to the string and returns a reference to the string. */ +#ifndef QT_NO_CAST_ASCII QString& QString::operator+=( const char *str ) { if ( str ) { +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) + return operator+=( fromAscii( str ) ); +#endif + uint len1 = length(); uint len2 = strlen( str ); if ( len2 ) { setLength(len1+len2); @@ -16507,8 +16568,9 @@ QString& QString::operator+=( const char *str ) } } return *this; } +#endif /*! \overload Appends \a c to the string and returns a reference to the string. @@ -16528,8 +16590,12 @@ QString &QString::operator+=( QChar c ) */ QString &QString::operator+=( char c ) { +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) + return operator+=( fromAscii( &c, 1 ) ); +#endif setLength(length()+1); d->unicode[length()-1] = c; return *this; } @@ -16540,20 +16606,27 @@ QString &QString::operator+=( char c ) Appends \a str to the string and returns a reference to the string. */ +/*! + \fn QString &QString::operator+=( const std::string &str ) + \overload + + Appends \a str to the string and returns a reference to the string. +*/ + /*! \fn char QChar::latin1() const - Returns a latin-1 copy of this character, if this character is in - the latin-1 character set. If not, this function returns 0. + Returns the Latin-1 value of this character, or 0 if it + cannot be represented in Latin-1. */ /*! - Returns a Latin-1 representation of the string. Note that the + Returns a Latin-1 representation of the string. The returned value is undefined if the string contains non-Latin-1 characters. If you want to convert strings into formats other than Unicode, see the QTextCodec classes. @@ -16562,33 +16635,51 @@ QString &QString::operator+=( char c ) The result remains valid so long as one unmodified copy of the source string exists. - \sa utf8(), local8Bit() + \sa fromLatin1(), ascii(), utf8(), local8Bit() */ const char* QString::latin1() const { - if ( !d->ascii ) { - Q2HELPER(stat_get_ascii++) - Q2HELPER(stat_get_ascii_size+=d->len) - d->ascii = unicodeToAscii( d->unicode, d->len ); + if ( !d->ascii || !d->islatin1 ) { + d->ascii = unicodeToLatin1( d->unicode, d->len ); + d->islatin1 = TRUE; } return d->ascii; } /*! - \fn const char* QString::ascii() const - \obsolete + Returns an 8-bit ASCII representation of the string. + + If a codec has been set using QTextCodec::codecForCStrings(), + it is used to convert Unicode to 8-bit char. Otherwise, this function + does the same as latin1(). - This function simply calls latin1() and returns the result. + \sa fromAscii(), latin1(), utf8(), local8Bit() */ +const char* QString::ascii() const +{ +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + if ( !d->ascii || d->islatin1 ) { + QCString s = QTextCodec::codecForCStrings()->fromUnicode( *this ); + s.detach(); + d->ascii = s.data(); + d->islatin1 = FALSE; + s.resetRawData( s.data(), s.size() ); // we have stolen the data + } + return d->ascii; + } +#endif // QT_NO_TEXTCODEC + return latin1(); +} /*! - Returns the string encoded in UTF8 format. + Returns the string encoded in UTF-8 format. See QTextCodec for more diverse coding/decoding of Unicode strings. - \sa QString::fromUtf8(), local8Bit(), latin1() + \sa fromUtf8(), ascii(), latin1(), local8Bit() */ QCString QString::utf8() const { int l = length(); @@ -16632,9 +16723,10 @@ QString QString::fromUtf8( const char* utf8, int len ) { if ( !utf8 ) return QString::null; - if ( len < 0 ) len = qstrlen( utf8 ); + if ( len < 0 ) + len = strlen( utf8 ); QString result; result.setLength( len ); // worst case QChar *qch = (QChar *)result.unicode(); ushort uc = 0; @@ -16673,30 +16765,60 @@ QString QString::fromUtf8( const char* utf8, int len ) } /*! Returns the Unicode string decoded from the first \a len - characters of \a chars, ignoring the rest of \a chars. If \a len - is -1 then the length of \a chars is used. If \a len is bigger - than the length of \a chars then it will use the length of \a - chars. + characters of \a ascii, ignoring the rest of \a ascii. If \a len + is -1 then the length of \a ascii is used. If \a len is bigger + than the length of \a ascii then it will use the length of \a + ascii. + + If a codec has been set using QTextCodec::codecForCStrings(), + it is used to convert Unicode to 8-bit char. Otherwise, this function + does the same as fromLatin1(). This is the same as the QString(const char*) constructor, but you can make that constructor invisible if you compile with the define \c QT_NO_CAST_ASCII, in which case you can explicitly create a - QString from Latin-1 text using this function. + QString from 8-bit ASCII text using this function. \code - QString str = QString::fromLatin1( "123456789", 5 ); + QString str = QString::fromAscii( "123456789", 5 ); // str == "12345" \endcode */ +QString QString::fromAscii( const char* ascii, int len ) +{ +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + if ( !ascii ) + return QString::null; + if ( len < 0 ) + len = strlen( ascii ); + if ( len == 0 || *ascii == '\0' ) + return QString::fromLatin1( "" ); + return QTextCodec::codecForCStrings()->toUnicode( ascii, len ); + } +#endif + return fromLatin1( ascii, len ); +} + + +/*! + Returns the Unicode string decoded from the first \a len + characters of \a chars, ignoring the rest of \a chars. If \a len + is -1 then the length of \a chars is used. If \a len is bigger + than the length of \a chars then it will use the length of \a + chars. + + \sa fromAscii() +*/ QString QString::fromLatin1( const char* chars, int len ) { uint l; QChar *uc; if ( len < 0 ) len = -1; - uc = internalAsciiToUnicode( chars, &l, len ); + uc = internalLatin1ToUnicode( chars, &l, len ); return QString( new QStringData(uc, l, l), TRUE ); } /*! @@ -16708,18 +16830,17 @@ QString QString::fromLatin1( const char* chars, int len ) /*! Returns the string encoded in a locale-specific format. On X11, this is the QTextCodec::codecForLocale(). On Windows, it is a - system-defined encoding. On Mac OS X, this always uses utf8 as the - encoding. + system-defined encoding. On Mac OS X, this always uses UTF-8 as + the encoding. See QTextCodec for more diverse coding/decoding of Unicode strings. - \sa QString::fromLocal8Bit(), latin1(), utf8() + \sa fromLocal8Bit(), ascii(), latin1(), utf8() */ - QCString QString::local8Bit() const { #ifdef QT_NO_TEXTCODEC return latin1(); @@ -16739,9 +16860,9 @@ QCString QString::local8Bit() const #ifdef Q_WS_WIN return qt_winQString2MB( *this ); #endif #ifdef Q_WS_QWS - return utf8(); // ##### if there is ANY 8 bit format supported? + return utf8(); // ### if there is any 8 bit format supported? #endif #endif } @@ -16770,9 +16891,10 @@ QString QString::fromLocal8Bit( const char* local8Bit, int len ) if ( !local8Bit ) return QString::null; #ifdef Q_WS_X11 QTextCodec* codec = QTextCodec::codecForLocale(); - if ( len < 0 ) len = qstrlen(local8Bit); + if ( len < 0 ) + len = strlen( local8Bit ); return codec ? codec->toUnicode( local8Bit, len ) : fromLatin1( local8Bit, len ); #endif @@ -16803,8 +16925,14 @@ QString QString::fromLocal8Bit( const char* local8Bit, int len ) that automatic casts are not done. This has the added advantage that you catch the programming error described in operator!(). */ +/*! + \fn QString::operator std::string() const + + Returns ascii(). +*/ + /*! Returns the QString as a zero terminated array of unsigned shorts if the string is not null; otherwise returns zero. @@ -16818,10 +16946,8 @@ const unsigned short *QString::ucs2() const return 0; unsigned int len = d->len; if ( d->maxl < len + 1 ) { // detach, grow or shrink - Q2HELPER(stat_copy_on_write++) - Q2HELPER(stat_copy_on_write_size += len) uint newMax = computeNewMax( len + 1 ); QChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); if ( nd ) { if ( d->unicode ) @@ -16982,10 +17108,8 @@ QString& QString::setUnicode( const QChar *unicode, uint len ) } } else if ( d->count != 1 || len > d->maxl || ( len * 4 < d->maxl && d->maxl > 4 ) ) { // detach, grown or shrink - Q2HELPER(stat_copy_on_write++) - Q2HELPER(stat_copy_on_write_size+=d->len) uint newMax = computeNewMax( len ); QChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); if ( unicode ) memcpy( nd, unicode, sizeof(QChar)*len ); @@ -17017,8 +17141,30 @@ QString& QString::setUnicodeCodes( const ushort* unicode_as_ushorts, uint len ) } /*! + Sets this string to \a str, interpreted as a classic 8-bit ASCII C + string. If \a len is -1 (the default), then it is set to + strlen(str). + + If \a str is 0 a null string is created. If \a str is "", an empty + string is created. + + \sa isNull(), isEmpty() +*/ + +QString &QString::setAscii( const char *str, int len ) +{ +#ifndef QT_NO_TEXTCODEC + if ( QTextCodec::codecForCStrings() ) { + *this = QString::fromAscii( str, len ); + return *this; + } +#endif // QT_NO_TEXTCODEC + return setLatin1( str, len ); +} + +/*! Sets this string to \a str, interpreted as a classic Latin1 C string. If \a len is -1 (the default), then it is set to strlen(str). @@ -17032,9 +17178,9 @@ QString &QString::setLatin1( const char *str, int len ) { if ( str == 0 ) return setUnicode(0,0); if ( len < 0 ) - len = qstrlen(str); + len = strlen( str ); if ( len == 0 ) { // won't make a null string *this = QString::fromLatin1( "" ); } else { setUnicode( 0, len ); // resize but not copy @@ -17050,18 +17196,18 @@ QString &QString::setLatin1( const char *str, int len ) void QString::checkSimpleText() const { QChar *p = d->unicode; QChar *end = p + d->len; - d->simpletext = 1; while( p < end ) { ushort uc = p->unicode(); // sort out regions of complex text formatting if ( uc > 0x058f && ( uc < 0x1100 || uc > 0xfb0f ) ) { - d->simpletext = 0; + d->issimpletext = FALSE; return; } p++; } + d->issimpletext = TRUE; } /*! \fn bool QString::simpleText() const \internal diff --git a/qmake/tools/qtextstream.cpp b/qmake/tools/qtextstream.cpp index 75c6531..ddca5bd 100644 --- a/qmake/tools/qtextstream.cpp +++ b/qmake/tools/qtextstream.cpp @@ -1088,9 +1088,9 @@ QTextStream &QTextStream::writeBlock( const QChar* p, uint len ) dev->writeBlock( block, l ); } else #endif if ( latin1 ) { - char *str = QString::unicodeToAscii( p, len ); + char *str = QString::unicodeToLatin1( p, len ); dev->writeBlock( str, len ); delete [] str; } else if ( internalOrder ) { if ( doUnicodeHeader ) { diff --git a/qmake/tools/qucom.cpp b/qmake/tools/qucom.cpp index 6086a79..658da97 100644 --- a/qmake/tools/qucom.cpp +++ b/qmake/tools/qucom.cpp @@ -295,27 +295,23 @@ void QUType_int::set( QUObject *o, int v ) } bool QUType_int::canConvertFrom( QUObject *o, QUType *t ) { - if ( isEqual( t, &static_QUType_double ) || - isEqual( t, &static_QUType_float ) ) + if ( isEqual( t, &static_QUType_double ) ) return TRUE; return t->canConvertTo( o, this ); } bool QUType_int::canConvertTo( QUObject * /*o*/, QUType *t ) { - return isEqual( t, &static_QUType_double ) || - isEqual( t, &static_QUType_float ); + return isEqual( t, &static_QUType_double ); } bool QUType_int::convertFrom( QUObject *o, QUType *t ) { if ( isEqual( t, &static_QUType_double ) ) o->payload.i = (long)o->payload.d; - else if ( isEqual( t, &static_QUType_float ) ) - o->payload.i = (long)o->payload.f; else return t->convertTo( o, this ); o->type = this; @@ -326,11 +322,8 @@ bool QUType_int::convertTo( QUObject *o, QUType *t ) { if ( isEqual( t, &static_QUType_double ) ) { o->payload.d = (double)o->payload.i; o->type = &static_QUType_double; - } else if ( isEqual( t, &static_QUType_float ) ) { - o->payload.f = (float)o->payload.i; - o->type = &static_QUType_float; } else return FALSE; return TRUE; } @@ -344,50 +337,8 @@ int QUType_int::serializeFrom( QUObject *, QUBuffer * ) { return 0; } -// {5938712A-C496-11D5-8CB2-00C0F03BC0F3} -const QUuid TID_QUType_uint( 0x5938712a, 0xc496, 0x11d5, 0x8c, 0xb2, 0x00, 0xc0, 0xf0, 0x3b, 0xc0, 0xf3); -QUType_uint static_QUType_uint; -const QUuid *QUType_uint::uuid() const { return &TID_QUType_uint; } -const char *QUType_uint::desc() const { return "uint"; } - -void QUType_uint::set( QUObject *o, uint v ) -{ - o->payload.ui = v; - o->type = this; -} - -bool QUType_uint::canConvertFrom( QUObject *o, QUType *t ) -{ - return t->canConvertTo( o, this ); -} - -bool QUType_uint::canConvertTo( QUObject * /*o*/, QUType * /*t*/ ) -{ - return FALSE; -} - -bool QUType_uint::convertFrom( QUObject *o, QUType *t ) -{ - return t->convertTo( o, this ); -} - -bool QUType_uint::convertTo( QUObject * /*o*/, QUType * /*t*/ ) -{ - return FALSE; -} - -int QUType_uint::serializeTo( QUObject *, QUBuffer * ) -{ - return 0; -} - -int QUType_uint::serializeFrom( QUObject *, QUBuffer * ) -{ - return 0; -} - // {2D0974E5-0BA6-4ec2-8837-C198972CB48C} const QUuid TID_QUType_double( 0x2d0974e5, 0xba6, 0x4ec2, 0x88, 0x37, 0xc1, 0x98, 0x97, 0x2c, 0xb4, 0x8c ); QUType_double static_QUType_double; const QUuid *QUType_double::uuid() const { return &TID_QUType_double; } @@ -400,27 +351,23 @@ void QUType_double::set( QUObject *o, double v ) } bool QUType_double::canConvertFrom( QUObject *o, QUType *t ) { - if ( isEqual( t, &static_QUType_int ) || - isEqual( t, &static_QUType_float) ) + if ( isEqual( t, &static_QUType_int ) ) return TRUE; return t->canConvertTo( o, this ); } bool QUType_double::canConvertTo( QUObject * /*o*/, QUType *t ) { - return isEqual( t, &static_QUType_int ) || - isEqual( t, &static_QUType_float ); + return isEqual( t, &static_QUType_int ); } bool QUType_double::convertFrom( QUObject *o, QUType *t ) { if ( isEqual( t, &static_QUType_int ) ) o->payload.d = (double)o->payload.i; - else if ( isEqual( t, &static_QUType_float ) ) - o->payload.d = (double)o->payload.f; else return t->convertTo( o, this ); o->type = this; @@ -449,72 +396,8 @@ int QUType_double::serializeFrom( QUObject *, QUBuffer * ) { return 0; } - -// {544C5175-6993-4486-B04D-CEC4D21BF4B9 } -const QUuid TID_QUType_float( 0x544c5175, 0x6993, 0x4486, 0xb0, 0x4d, 0xce, 0xc4, 0xd2, 0x1b, 0xf4, 0xb9 ); -QUType_float static_QUType_float; -const QUuid *QUType_float::uuid() const { return &TID_QUType_float; } -const char *QUType_float::desc() const {return "float"; } - -void QUType_float::set( QUObject *o, float v ) -{ - o->payload.f = v; - o->type = this; -} - -bool QUType_float::canConvertFrom( QUObject *o, QUType *t ) -{ - if ( isEqual( t, &static_QUType_int ) || - isEqual( t, &static_QUType_double ) ) - return TRUE; - - return t->canConvertTo( o, this ); -} - -bool QUType_float::canConvertTo( QUObject * /*o*/, QUType *t ) -{ - return isEqual( t, &static_QUType_int ) || - isEqual( t, &static_QUType_double ); -} - -bool QUType_float::convertFrom( QUObject *o, QUType *t ) -{ - if ( isEqual( t, &static_QUType_int ) ) - o->payload.f = (float)o->payload.i; - else if ( isEqual( t, &static_QUType_double ) ) - o->payload.f = (float)o->payload.d; - else - return t->convertTo( o, this ); - - o->type = this; - return TRUE; -} - -bool QUType_float::convertTo( QUObject *o, QUType *t ) -{ - if ( isEqual( t, &static_QUType_int ) ) { - o->payload.i = (int) o->payload.f; - o->type = &static_QUType_int; - } else if ( isEqual( t, &static_QUType_double ) ) { - o->payload.d = (double) o->payload.f; - o->type = &static_QUType_double; - } else - return FALSE; - return TRUE; -} - -int QUType_float::serializeTo( QUObject *, QUBuffer * ) -{ - return 0; -} - -int QUType_float::serializeFrom( QUObject *, QUBuffer * ) -{ - return 0; -} - // {EFCDD1D4-77A3-4b8e-8D46-DC14B8D393E9} const QUuid TID_QUType_charstar( 0xefcdd1d4, 0x77a3, 0x4b8e, 0x8d, 0x46, 0xdc, 0x14, 0xb8, 0xd3, 0x93, 0xe9 ); QUType_charstar static_QUType_charstar; const QUuid *QUType_charstar::uuid() const { return &TID_QUType_charstar; } @@ -592,9 +475,8 @@ void QUType_QString::set( QUObject *o, const QString& v ) bool QUType_QString::canConvertFrom( QUObject *o, QUType *t ) { if ( isEqual( t, &static_QUType_charstar ) || isEqual( t, &static_QUType_double ) || - isEqual( t, &static_QUType_float ) || isEqual( t, &static_QUType_int ) ) return TRUE; return t->canConvertTo( o, this ); @@ -603,10 +485,9 @@ bool QUType_QString::canConvertFrom( QUObject *o, QUType *t ) bool QUType_QString::canConvertTo( QUObject * /*o*/, QUType *t ) { return isEqual( t, &static_QUType_charstar ) || isEqual( t, &static_QUType_int ) || - isEqual( t, &static_QUType_double ) || - isEqual( t, &static_QUType_float ); + isEqual( t, &static_QUType_double ); } bool QUType_QString::convertFrom( QUObject *o, QUType *t ) { @@ -614,10 +495,8 @@ bool QUType_QString::convertFrom( QUObject *o, QUType *t ) if ( isEqual( t, &static_QUType_charstar ) ) str = new QString( o->payload.charstar.ptr ); else if ( isEqual( t, &static_QUType_double ) ) str = new QString( QString::number( o->payload.d ) ); - else if ( isEqual( t, &static_QUType_float ) ) - str = new QString( QString::number( o->payload.f ) ); else if ( isEqual( t, &static_QUType_int ) ) str = new QString( QString::number( o->payload.i ) ); else return t->convertTo( o, this ); @@ -640,11 +519,8 @@ bool QUType_QString::convertTo( QUObject *o, QUType *t ) o->type = &static_QUType_int; } else if ( isEqual( t, &static_QUType_double ) ) { o->payload.d = str->toDouble(); o->type = &static_QUType_double; - } else if ( isEqual( t, &static_QUType_float ) ) { - o->payload.d = str->toFloat(); - o->type = &static_QUType_float; } else { return FALSE; } delete str; diff --git a/qmake/tools/qwaitcondition_unix.cpp b/qmake/tools/qwaitcondition_unix.cpp index 99c1014..6684617 100644 --- a/qmake/tools/qwaitcondition_unix.cpp +++ b/qmake/tools/qwaitcondition_unix.cpp @@ -123,9 +123,9 @@ struct QWaitConditionPrivate { for (;;) { getchar(); mymutex.lock(); // Sleep until there are no busy worker threads - while( count > 0 ) { + while( mycount > 0 ) { mymutex.unlock(); sleep( 1 ); mymutex.lock(); } @@ -223,17 +223,19 @@ void QWaitCondition::wakeAll() \sa wakeOne(), wakeAll() */ bool QWaitCondition::wait(unsigned long time) { - pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_t mutex; + pthread_mutex_init( &mutex, 0 ); + pthread_mutex_lock( &mutex ); int ret; if (time != ULONG_MAX) { struct timeval tv; gettimeofday(&tv, 0); timespec ti; - ti.tv_nsec = (tv.tv_usec * 1000) + (time % 1000) * 1000; + ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000; ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); ti.tv_nsec %= 1000000000; ret = pthread_cond_timedwait(&d->cond, &mutex, &ti); @@ -244,8 +246,11 @@ bool QWaitCondition::wait(unsigned long time) if (ret && ret != ETIMEDOUT) qWarning("Wait condition wait failure: %s",strerror(ret)); #endif + pthread_mutex_unlock( &mutex ); + pthread_mutex_destroy( &mutex ); + return (ret == 0); } /*! @@ -290,9 +295,9 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time) struct timeval tv; gettimeofday(&tv, 0); timespec ti; - ti.tv_nsec = (tv.tv_usec * 1000) + (time % 1000) * 1000; + ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000; ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); ti.tv_nsec %= 1000000000; ret = pthread_cond_timedwait(&d->cond, &mutex->d->handle, &ti); |