summaryrefslogtreecommitdiff
path: root/qmake/tools
Unidiff
Diffstat (limited to 'qmake/tools') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qbitarray.cpp3
-rw-r--r--qmake/tools/qbuffer.cpp4
-rw-r--r--qmake/tools/qcomlibrary.cpp43
-rw-r--r--qmake/tools/qconfig.cpp14
-rw-r--r--qmake/tools/qcriticalsection_p.cpp2
-rw-r--r--qmake/tools/qcstring.cpp107
-rw-r--r--qmake/tools/qdatastream.cpp24
-rw-r--r--qmake/tools/qdatetime.cpp70
-rw-r--r--qmake/tools/qdir.cpp94
-rw-r--r--qmake/tools/qdir_unix.cpp54
-rw-r--r--qmake/tools/qfile.cpp3
-rw-r--r--qmake/tools/qfile_unix.cpp13
-rw-r--r--qmake/tools/qfileinfo.cpp4
-rw-r--r--qmake/tools/qfileinfo_unix.cpp4
-rw-r--r--qmake/tools/qgarray.cpp97
-rw-r--r--qmake/tools/qgdict.cpp5
-rw-r--r--qmake/tools/qglist.cpp6
-rw-r--r--qmake/tools/qglobal.cpp45
-rw-r--r--qmake/tools/qgpluginmanager.cpp4
-rw-r--r--qmake/tools/qgvector.cpp9
-rw-r--r--qmake/tools/qlibrary.cpp13
-rw-r--r--qmake/tools/qlibrary_unix.cpp21
-rw-r--r--qmake/tools/qmutex_unix.cpp8
-rw-r--r--qmake/tools/qmutexpool.cpp78
-rw-r--r--qmake/tools/qregexp.cpp70
-rw-r--r--qmake/tools/qsemaphore_unix.cpp26
-rw-r--r--qmake/tools/qsettings.cpp387
-rw-r--r--qmake/tools/qstring.cpp434
-rw-r--r--qmake/tools/qtextstream.cpp2
-rw-r--r--qmake/tools/qucom.cpp136
-rw-r--r--qmake/tools/qwaitcondition_unix.cpp13
31 files changed, 1115 insertions, 678 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
@@ -194,13 +194,14 @@ void QBitArray::pad0()
194 194
195 \sa resize() 195 \sa resize()
196*/ 196*/
197 197
198/*! 198/*!
199 Resizes the bit array to \a size bits and returns TRUE if the bit 199 Resizes the bit array to \a size bits and returns TRUE if the bit
200 array could be resized; otherwise returns FALSE. 200 array could be resized; otherwise returns FALSE. The array becomes
201 a null array if \a size == 0.
201 202
202 If the array is expanded, the new bits are set to 0. 203 If the array is expanded, the new bits are set to 0.
203 204
204 \sa size() 205 \sa size()
205*/ 206*/
206 207
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
@@ -193,14 +193,14 @@ bool QBuffer::open( int m )
193 qWarning( "QBuffer::open: Buffer already open" ); 193 qWarning( "QBuffer::open: Buffer already open" );
194#endif 194#endif
195 return FALSE; 195 return FALSE;
196 } 196 }
197 setMode( m ); 197 setMode( m );
198 if ( m & IO_Truncate ) { // truncate buffer 198 if ( m & IO_Truncate ) { // truncate buffer
199 a.resize( 0 ); 199 a.resize( 1 );
200 a_len = 0; 200 a_len = 1;
201 } 201 }
202 if ( m & IO_Append ) { // append to end of buffer 202 if ( m & IO_Append ) { // append to end of buffer
203 ioIndex = a.size(); 203 ioIndex = a.size();
204 } else { 204 } else {
205 ioIndex = 0; 205 ioIndex = 0;
206 } 206 }
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
@@ -60,12 +60,16 @@ QComLibrary::QComLibrary( const QString &filename )
60} 60}
61 61
62QComLibrary::~QComLibrary() 62QComLibrary::~QComLibrary()
63{ 63{
64 if ( autoUnload() ) 64 if ( autoUnload() )
65 unload(); 65 unload();
66 if ( libiface )
67 libiface->release();
68 if ( entry )
69 entry->release();
66} 70}
67 71
68bool QComLibrary::unload() 72bool QComLibrary::unload()
69{ 73{
70 if ( libiface ) { 74 if ( libiface ) {
71 libiface->cleanup(); 75 libiface->cleanup();
@@ -388,35 +392,33 @@ void QComLibrary::createInstanceInternal()
388 QStringList reg; 392 QStringList reg;
389 uint flags = 0; 393 uint flags = 0;
390 QCString key; 394 QCString key;
391 bool query_done = FALSE; 395 bool query_done = FALSE;
392 bool warn_mismatch = TRUE; 396 bool warn_mismatch = TRUE;
393 397
394 if ( ! query_done ) {
395
396#ifdef QT_THREAD_SUPPORT 398#ifdef QT_THREAD_SUPPORT
397 QMutexLocker locker( qt_global_mutexpool->get( &cache ) ); 399 QMutexLocker locker( qt_global_mutexpool ?
400 qt_global_mutexpool->get( &cache ) : 0 );
398#endif // QT_THREAD_SUPPORT 401#endif // QT_THREAD_SUPPORT
399 402
400 if ( ! cache ) { 403 if ( ! cache ) {
401 cache = new QSettings; 404 cache = new QSettings;
402 cache->insertSearchPath( QSettings::Windows, "/Trolltech" ); 405 cache->insertSearchPath( QSettings::Windows, "/Trolltech" );
403 cleanup_cache.set( &cache ); 406 cleanup_cache.set( &cache );
404 } 407 }
405 408
406 reg = cache->readListEntry( regkey ); 409 reg = cache->readListEntry( regkey );
407 if ( reg.count() == 4 ) { 410 if ( reg.count() == 4 ) {
408 // check timestamp 411 // check timestamp
409 if ( lastModified == reg[3] ) { 412 if ( lastModified == reg[3] ) {
410 qt_version = reg[0].toUInt(0, 16); 413 qt_version = reg[0].toUInt(0, 16);
411 flags = reg[1].toUInt(0, 16); 414 flags = reg[1].toUInt(0, 16);
412 key = reg[2].latin1(); 415 key = reg[2].latin1();
413 416
414 query_done = TRUE; 417 query_done = TRUE;
415 warn_mismatch = FALSE; 418 warn_mismatch = FALSE;
416 }
417 } 419 }
418 } 420 }
419 421
420#if defined(Q_OS_UNIX) 422#if defined(Q_OS_UNIX)
421 if ( ! query_done ) { 423 if ( ! query_done ) {
422 // get the query information directly from the plugin without loading 424 // get the query information directly from the plugin without loading
@@ -458,17 +460,12 @@ void QComLibrary::createInstanceInternal()
458 queried << QString::number( qt_version,16 ) 460 queried << QString::number( qt_version,16 )
459 << QString::number( flags, 16 ) 461 << QString::number( flags, 16 )
460 << key 462 << key
461 << lastModified; 463 << lastModified;
462 464
463 if ( queried != reg ) { 465 if ( queried != reg ) {
464
465#ifdef QT_THREAD_SUPPORT
466 QMutexLocker locker( qt_global_mutexpool->get( &cache ) );
467#endif // QT_THREAD_SUPPORT
468
469 cache->writeEntry( regkey, queried ); 466 cache->writeEntry( regkey, queried );
470 // delete the cache, which forces the settings to be written 467 // delete the cache, which forces the settings to be written
471 delete cache; 468 delete cache;
472 cache = 0; 469 cache = 0;
473 } 470 }
474 471
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,15 +1,15 @@
1/* Install paths from configure */ 1/* Install paths from configure */
2 2
3static const char QT_INSTALL_PREFIX [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2"; 3static const char QT_INSTALL_PREFIX [256] = "/opt/qt-x11-free-3.1.2";
4static const char QT_INSTALL_BINS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/bin"; 4static const char QT_INSTALL_BINS [256] = "/opt/qt-x11-free-3.1.2/bin";
5static const char QT_INSTALL_DOCS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/doc"; 5static const char QT_INSTALL_DOCS [256] = "/opt/qt-x11-free-3.1.2/doc";
6static const char QT_INSTALL_HEADERS[256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/include"; 6static const char QT_INSTALL_HEADERS[256] = "/opt/qt-x11-free-3.1.2/include";
7static const char QT_INSTALL_LIBS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/lib"; 7static const char QT_INSTALL_LIBS [256] = "/opt/qt-x11-free-3.1.2/lib";
8static const char QT_INSTALL_PLUGINS[256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/plugins"; 8static const char QT_INSTALL_PLUGINS[256] = "/opt/qt-x11-free-3.1.2/plugins";
9static const char QT_INSTALL_DATA [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2"; 9static const char QT_INSTALL_DATA [256] = "/opt/qt-x11-free-3.1.2";
10 10
11const char *qInstallPath() { return QT_INSTALL_PREFIX; } 11const char *qInstallPath() { return QT_INSTALL_PREFIX; }
12const char *qInstallPathDocs() { return QT_INSTALL_DOCS; } 12const char *qInstallPathDocs() { return QT_INSTALL_DOCS; }
13const char *qInstallPathHeaders() { return QT_INSTALL_HEADERS; } 13const char *qInstallPathHeaders() { return QT_INSTALL_HEADERS; }
14const char *qInstallPathLibs() { return QT_INSTALL_LIBS; } 14const char *qInstallPathLibs() { return QT_INSTALL_LIBS; }
15const char *qInstallPathBins() { return QT_INSTALL_BINS; } 15const char *qInstallPathBins() { return QT_INSTALL_BINS; }
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
@@ -1,13 +1,11 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$ 2** $Id$
3** 3**
4** Implementation of QCriticalSection class 4** Implementation of QCriticalSection class
5** 5**
6** Created :
7**
8** Copyright (C) 2001 Trolltech AS. All rights reserved. 6** Copyright (C) 2001 Trolltech AS. All rights reserved.
9** 7**
10** This file is part of the tools module of the Qt GUI Toolkit. 8** This file is part of the tools module of the Qt GUI Toolkit.
11** 9**
12** This file may be distributed under the terms of the Q Public License 10** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file 11** as defined by Trolltech AS of Norway and appearing in the file
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
@@ -138,12 +138,23 @@ char *qstrncpy( char *dst, const char *src, uint len )
138 if ( len > 0 ) 138 if ( len > 0 )
139 dst[len-1] = '\0'; 139 dst[len-1] = '\0';
140 return dst; 140 return dst;
141} 141}
142 142
143/*! 143/*!
144 \fn uint qstrlen( const char *str );
145
146 \relates QCString
147
148 A safe strlen function.
149
150 Returns the number of characters that precede the terminating '\0'.
151 or 0 if \a str is 0.
152*/
153
154/*!
144 \fn int qstrcmp( const char *str1, const char *str2 ); 155 \fn int qstrcmp( const char *str1, const char *str2 );
145 156
146 \relates QCString 157 \relates QCString
147 158
148 A safe strcmp() function. 159 A safe strcmp() function.
149 160
@@ -296,13 +307,14 @@ static void createCRC16Table() // build CRC16 lookup table
296 307
297Q_UINT16 qChecksum( const char *data, uint len ) 308Q_UINT16 qChecksum( const char *data, uint len )
298{ 309{
299 if ( !crc_tbl_init ) { // create lookup table 310 if ( !crc_tbl_init ) { // create lookup table
300 311
301#ifdef QT_THREAD_SUPPORT 312#ifdef QT_THREAD_SUPPORT
302 QMutexLocker locker( qt_global_mutexpool->get( &crc_tbl_init ) ); 313 QMutexLocker locker( qt_global_mutexpool ?
314 qt_global_mutexpool->get( &crc_tbl_init ) : 0 );
303#endif // QT_THREAD_SUPPORT 315#endif // QT_THREAD_SUPPORT
304 316
305 if ( !crc_tbl_init ) { 317 if ( !crc_tbl_init ) {
306 createCRC16Table(); 318 createCRC16Table();
307 crc_tbl_init = TRUE; 319 crc_tbl_init = TRUE;
308 } 320 }
@@ -316,24 +328,30 @@ Q_UINT16 qChecksum( const char *data, uint len )
316 c >>= 4; 328 c >>= 4;
317 crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)]; 329 crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)];
318 } 330 }
319 return ~crc & 0xffff; 331 return ~crc & 0xffff;
320} 332}
321 333
322/*! \fn QByteArray qCompress( const QByteArray& data) 334/*!
323 \relates QByteArray 335 \fn QByteArray qCompress( const QByteArray& data )
324 \overload 336
337 \relates QByteArray
338
339 Compresses the array \a data and returns the compressed byte
340 array.
341
342 \sa qUncompress()
325*/ 343*/
326 344
327/*! 345/*!
328 \relates QByteArray 346 \relates QByteArray
329 347
330 Compresses the array \a data which is \a nbytes long and returns the 348 \overload
331 compressed byte array.
332 349
333 \sa qUncompress() 350 Compresses the array \a data which is \a nbytes long and returns the
351 compressed byte array.
334*/ 352*/
335 353
336#ifndef QT_NO_COMPRESS 354#ifndef QT_NO_COMPRESS
337QByteArray qCompress( const uchar* data, int nbytes ) 355QByteArray qCompress( const uchar* data, int nbytes )
338{ 356{
339 if ( nbytes == 0 ) { 357 if ( nbytes == 0 ) {
@@ -376,26 +394,38 @@ QByteArray qCompress( const uchar* data, int nbytes )
376 } while ( res == Z_BUF_ERROR ); 394 } while ( res == Z_BUF_ERROR );
377 395
378 return bazip; 396 return bazip;
379} 397}
380#endif 398#endif
381 399
382/*! \fn QByteArray qUncompress( const QByteArray& data ) 400/*!
383 \relates QByteArray 401 \fn QByteArray qUncompress( const QByteArray& data )
384 \overload 402
403 \relates QByteArray
404
405 Uncompresses the array \a data and returns the uncompressed byte
406 array.
407
408 Returns an empty QByteArray if the input data was corrupt.
409 \omit
410 ADD THE FOLLOWING FOR Qt 4.0
411 This function will uncompress data compressed with qCompress()
412 from this and any earlier Qt version, back to Qt 3.1 when this
413 feature was added.
414 \endomit
415
416 \sa qCompress()
385*/ 417*/
386 418
387/*! 419/*!
388 \relates QByteArray 420 \relates QByteArray
389
390 Uncompresses the array \a data which is \a nbytes long and returns
391 the uncompressed byte array.
392 421
393 Returns an empty QByteArray if the input data was corrupt. 422 \overload
394 423
395 \sa qCompress() 424 Uncompresses the array \a data which is \a nbytes long and returns
425 the uncompressed byte array.
396*/ 426*/
397 427
398#ifndef QT_NO_COMPRESS 428#ifndef QT_NO_COMPRESS
399QByteArray qUncompress( const uchar* data, int nbytes ) 429QByteArray qUncompress( const uchar* data, int nbytes )
400{ 430{
401 if ( !data ) { 431 if ( !data ) {
@@ -933,19 +963,23 @@ int QCString::find( char c, int index, bool cs ) const
933 963
934 \sa \link #asciinotion Note on character comparisons \endlink 964 \sa \link #asciinotion Note on character comparisons \endlink
935*/ 965*/
936 966
937int QCString::find( const char *str, int index, bool cs ) const 967int QCString::find( const char *str, int index, bool cs ) const
938{ 968{
969 return find( str, index, cs, length() );
970}
971
972int QCString::find( const char *str, int index, bool cs, uint l ) const
973{
939 if ( (uint)index >= size() ) 974 if ( (uint)index >= size() )
940 return -1; 975 return -1;
941 if ( !str ) 976 if ( !str )
942 return -1; 977 return -1;
943 if ( !*str ) 978 if ( !*str )
944 return index; 979 return index;
945 const uint l = length();
946 const uint sl = qstrlen( str ); 980 const uint sl = qstrlen( str );
947 if ( sl + index > l ) 981 if ( sl + index > l )
948 return -1; 982 return -1;
949 983
950 if ( sl == 1 ) 984 if ( sl == 1 )
951 return find( *str, index, cs ); 985 return find( *str, index, cs );
@@ -1149,14 +1183,15 @@ int QCString::contains( char c, bool cs ) const
1149*/ 1183*/
1150 1184
1151int QCString::contains( const char *str, bool cs ) const 1185int QCString::contains( const char *str, bool cs ) const
1152{ 1186{
1153 int count = 0; 1187 int count = 0;
1154 int i = -1; 1188 int i = -1;
1189 uint l = length();
1155 // use find for the faster hashing algorithm 1190 // use find for the faster hashing algorithm
1156 while ( ( i = find ( str, i+1, cs ) ) != -1 ) 1191 while ( ( i = find ( str, i+1, cs, l ) ) != -1 )
1157 count++; 1192 count++;
1158 return count; 1193 return count;
1159} 1194}
1160 1195
1161/*! 1196/*!
1162 Returns a substring that contains the \a len leftmost characters 1197 Returns a substring that contains the \a len leftmost characters
@@ -1170,13 +1205,12 @@ int QCString::contains( const char *str, bool cs ) const
1170 QCString s = "Pineapple"; 1205 QCString s = "Pineapple";
1171 QCString t = s.left( 4 ); // t == "Pine" 1206 QCString t = s.left( 4 ); // t == "Pine"
1172 \endcode 1207 \endcode
1173 1208
1174 \sa right(), mid() 1209 \sa right(), mid()
1175*/ 1210*/
1176
1177QCString QCString::left( uint len ) const 1211QCString QCString::left( uint len ) const
1178{ 1212{
1179 if ( isEmpty() ) { 1213 if ( isEmpty() ) {
1180 QCString empty; 1214 QCString empty;
1181 return empty; 1215 return empty;
1182 } else if ( len >= size() ) { 1216 } else if ( len >= size() ) {
@@ -1494,20 +1528,22 @@ QCString &QCString::insert( uint index, const char *s )
1494 if ( len == 0 ) 1528 if ( len == 0 )
1495 return *this; 1529 return *this;
1496 uint olen = length(); 1530 uint olen = length();
1497 int nlen = olen + len; 1531 int nlen = olen + len;
1498 if ( index >= olen ) { // insert after end of string 1532 if ( index >= olen ) { // insert after end of string
1499 detach(); 1533 detach();
1500 if ( QByteArray::resize(nlen+index-olen+1) ) { 1534 if ( QByteArray::resize(nlen+index-olen+1, QByteArray::SpeedOptim ) ) {
1501 memset( data()+olen, ' ', index-olen ); 1535 memset( data()+olen, ' ', index-olen );
1502 memcpy( data()+index, s, len+1 ); 1536 memcpy( data()+index, s, len+1 );
1503 } 1537 }
1504 } else if ( QByteArray::resize(nlen+1) ) {// normal insert 1538 } else {
1505 detach(); 1539 detach();
1506 memmove( data()+index+len, data()+index, olen-index+1 ); 1540 if ( QByteArray::resize(nlen+1, QByteArray::SpeedOptim ) ) {// normal insert
1507 memcpy( data()+index, s, len ); 1541 memmove( data()+index+len, data()+index, olen-index+1 );
1542 memcpy( data()+index, s, len );
1543 }
1508 } 1544 }
1509 return *this; 1545 return *this;
1510} 1546}
1511 1547
1512/*! 1548/*!
1513 Inserts character \a c into the string at position \a index and 1549 Inserts character \a c into the string at position \a index and
@@ -1566,13 +1602,13 @@ QCString &QCString::remove( uint index, uint len )
1566 detach(); 1602 detach();
1567 resize( index+1 ); 1603 resize( index+1 );
1568 } 1604 }
1569 } else if ( len != 0 ) { 1605 } else if ( len != 0 ) {
1570 detach(); 1606 detach();
1571 memmove( data()+index, data()+index+len, olen-index-len+1 ); 1607 memmove( data()+index, data()+index+len, olen-index-len+1 );
1572 QByteArray::resize(olen-len+1); 1608 QByteArray::resize(olen-len+1, QByteArray::SpeedOptim );
1573 } 1609 }
1574 return *this; 1610 return *this;
1575} 1611}
1576 1612
1577/*! 1613/*!
1578 Replaces \a len characters from the string, starting at position 1614 Replaces \a len characters from the string, starting at position
@@ -1628,12 +1664,13 @@ QCString &QCString::replace( char c, const char *after )
1628 \code 1664 \code
1629 QCString s = "Greek is Greek"; 1665 QCString s = "Greek is Greek";
1630 s.replace( "Greek", "English" ); 1666 s.replace( "Greek", "English" );
1631 // s == "English is English" 1667 // s == "English is English"
1632 \endcode 1668 \endcode
1633*/ 1669*/
1670
1634QCString &QCString::replace( const char *before, const char *after ) 1671QCString &QCString::replace( const char *before, const char *after )
1635{ 1672{
1636 if ( before == after || isNull() ) 1673 if ( before == after || isNull() )
1637 return *this; 1674 return *this;
1638 1675
1639 detach(); 1676 detach();
@@ -1643,22 +1680,22 @@ QCString &QCString::replace( const char *before, const char *after )
1643 const int al = after ? strlen( after ) : 0; 1680 const int al = after ? strlen( after ) : 0;
1644 char *d = data(); 1681 char *d = data();
1645 uint len = length(); 1682 uint len = length();
1646 1683
1647 if ( bl == al ) { 1684 if ( bl == al ) {
1648 if ( bl ) { 1685 if ( bl ) {
1649 while( (index = find( before, index ) ) != -1 ) { 1686 while( (index = find( before, index, TRUE, len ) ) != -1 ) {
1650 memcpy( d+index, after, al ); 1687 memcpy( d+index, after, al );
1651 index += bl; 1688 index += bl;
1652 } 1689 }
1653 } 1690 }
1654 } else if ( al < bl ) { 1691 } else if ( al < bl ) {
1655 uint to = 0; 1692 uint to = 0;
1656 uint movestart = 0; 1693 uint movestart = 0;
1657 uint num = 0; 1694 uint num = 0;
1658 while( (index = find( before, index ) ) != -1 ) { 1695 while( (index = find( before, index, TRUE, len ) ) != -1 ) {
1659 if ( num ) { 1696 if ( num ) {
1660 int msize = index - movestart; 1697 int msize = index - movestart;
1661 if ( msize > 0 ) { 1698 if ( msize > 0 ) {
1662 memmove( d + to, d + movestart, msize ); 1699 memmove( d + to, d + movestart, msize );
1663 to += msize; 1700 to += msize;
1664 } 1701 }
@@ -1683,13 +1720,13 @@ QCString &QCString::replace( const char *before, const char *after )
1683 // the most complex case. We don't want to loose performance by doing repeated 1720 // the most complex case. We don't want to loose performance by doing repeated
1684 // copies and reallocs of the string. 1721 // copies and reallocs of the string.
1685 while( index != -1 ) { 1722 while( index != -1 ) {
1686 uint indices[4096]; 1723 uint indices[4096];
1687 uint pos = 0; 1724 uint pos = 0;
1688 while( pos < 4095 ) { 1725 while( pos < 4095 ) {
1689 index = find(before, index); 1726 index = find(before, index, TRUE, len);
1690 if ( index == -1 ) 1727 if ( index == -1 )
1691 break; 1728 break;
1692 indices[pos++] = index; 1729 indices[pos++] = index;
1693 index += bl; 1730 index += bl;
1694 // avoid infinite loop 1731 // avoid infinite loop
1695 if ( !bl ) 1732 if ( !bl )
@@ -1760,13 +1797,13 @@ QCString &QCString::replace( char c1, char c2 )
1760 string it is more efficient to convert the string to a QString and 1797 string it is more efficient to convert the string to a QString and
1761 apply the function to that. 1798 apply the function to that.
1762*/ 1799*/
1763 1800
1764int QCString::find( const QRegExp& rx, int index ) const 1801int QCString::find( const QRegExp& rx, int index ) const
1765{ 1802{
1766 QString d = QString::fromLatin1( data() ); 1803 QString d = QString::fromAscii( data() );
1767 return d.find( rx, index ); 1804 return d.find( rx, index );
1768} 1805}
1769 1806
1770/*! 1807/*!
1771 \overload 1808 \overload
1772 1809
@@ -1780,13 +1817,13 @@ int QCString::find( const QRegExp& rx, int index ) const
1780 string it is more efficient to convert the string to a QString and 1817 string it is more efficient to convert the string to a QString and
1781 apply the function to that. 1818 apply the function to that.
1782*/ 1819*/
1783 1820
1784int QCString::findRev( const QRegExp& rx, int index ) const 1821int QCString::findRev( const QRegExp& rx, int index ) const
1785{ 1822{
1786 QString d = QString::fromLatin1( data() ); 1823 QString d = QString::fromAscii( data() );
1787 return d.findRev( rx, index ); 1824 return d.findRev( rx, index );
1788} 1825}
1789 1826
1790/*! 1827/*!
1791 \overload 1828 \overload
1792 1829
@@ -1805,13 +1842,13 @@ int QCString::findRev( const QRegExp& rx, int index ) const
1805 string it is more efficient to convert the string to a QString and 1842 string it is more efficient to convert the string to a QString and
1806 apply the function to that. 1843 apply the function to that.
1807*/ 1844*/
1808 1845
1809int QCString::contains( const QRegExp &rx ) const 1846int QCString::contains( const QRegExp &rx ) const
1810{ 1847{
1811 QString d = QString::fromLatin1( data() ); 1848 QString d = QString::fromAscii( data() );
1812 return d.contains( rx ); 1849 return d.contains( rx );
1813} 1850}
1814 1851
1815 1852
1816/*! 1853/*!
1817 \overload 1854 \overload
@@ -1835,14 +1872,14 @@ int QCString::contains( const QRegExp &rx ) const
1835 string it is more efficient to convert the string to a QString and 1872 string it is more efficient to convert the string to a QString and
1836 apply the function to that. 1873 apply the function to that.
1837*/ 1874*/
1838 1875
1839QCString &QCString::replace( const QRegExp &rx, const char *str ) 1876QCString &QCString::replace( const QRegExp &rx, const char *str )
1840{ 1877{
1841 QString d = QString::fromLatin1( data() ); 1878 QString d = QString::fromAscii( data() );
1842 QString r = QString::fromLatin1( str ); 1879 QString r = QString::fromAscii( str );
1843 d.replace( rx, r ); 1880 d.replace( rx, r );
1844 setStr( d.ascii() ); 1881 setStr( d.ascii() );
1845 return *this; 1882 return *this;
1846} 1883}
1847#endif //QT_NO_REGEXP 1884#endif //QT_NO_REGEXP
1848 1885
@@ -2196,13 +2233,13 @@ QCString& QCString::operator+=( const char *str )
2196{ 2233{
2197 if ( !str ) 2234 if ( !str )
2198 return *this; // nothing to append 2235 return *this; // nothing to append
2199 detach(); 2236 detach();
2200 uint len1 = length(); 2237 uint len1 = length();
2201 uint len2 = qstrlen(str); 2238 uint len2 = qstrlen(str);
2202 if ( !QByteArray::resize( len1 + len2 + 1 ) ) 2239 if ( !QByteArray::resize( len1 + len2 + 1, QByteArray::SpeedOptim ) )
2203 return *this; // no memory 2240 return *this; // no memory
2204 memcpy( data() + len1, str, len2 + 1 ); 2241 memcpy( data() + len1, str, len2 + 1 );
2205 return *this; 2242 return *this;
2206} 2243}
2207 2244
2208/*! 2245/*!
@@ -2212,13 +2249,13 @@ QCString& QCString::operator+=( const char *str )
2212*/ 2249*/
2213 2250
2214QCString &QCString::operator+=( char c ) 2251QCString &QCString::operator+=( char c )
2215{ 2252{
2216 detach(); 2253 detach();
2217 uint len = length(); 2254 uint len = length();
2218 if ( !QByteArray::resize( len + 2 ) ) 2255 if ( !QByteArray::resize( len + 2, QByteArray::SpeedOptim ) )
2219 return *this; // no memory 2256 return *this; // no memory
2220 *(data() + len) = c; 2257 *(data() + len) = c;
2221 *(data() + len+1) = '\0'; 2258 *(data() + len+1) = '\0';
2222 return *this; 2259 return *this;
2223} 2260}
2224 2261
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
@@ -747,14 +747,22 @@ QDataStream &QDataStream::readBytes( char *&s, uint &l )
747 747
748QDataStream &QDataStream::readRawBytes( char *s, uint len ) 748QDataStream &QDataStream::readRawBytes( char *s, uint len )
749{ 749{
750 CHECK_STREAM_PRECOND 750 CHECK_STREAM_PRECOND
751 if ( printable ) { // printable data 751 if ( printable ) { // printable data
752 register Q_INT8 *p = (Q_INT8*)s; 752 register Q_INT8 *p = (Q_INT8*)s;
753 while ( len-- ) 753 if ( version() < 4 ) {
754 *this >> *p++; 754 while ( len-- ) {
755 Q_INT32 tmp;
756 *this >> tmp;
757 *p++ = tmp;
758 }
759 } else {
760 while ( len-- )
761 *this >> *p++;
762 }
755 } else { // read data char array 763 } else { // read data char array
756 dev->readBlock( s, len ); 764 dev->readBlock( s, len );
757 } 765 }
758 return *this; 766 return *this;
759} 767}
760 768
@@ -1009,15 +1017,21 @@ QDataStream &QDataStream::writeBytes(const char *s, uint len)
1009*/ 1017*/
1010 1018
1011QDataStream &QDataStream::writeRawBytes( const char *s, uint len ) 1019QDataStream &QDataStream::writeRawBytes( const char *s, uint len )
1012{ 1020{
1013 CHECK_STREAM_PRECOND 1021 CHECK_STREAM_PRECOND
1014 if ( printable ) { // write printable 1022 if ( printable ) { // write printable
1015 register Q_INT8 *p = (Q_INT8*)s; 1023 if ( version() < 4 ) {
1016 while ( len-- ) 1024 register char *p = (char *)s;
1017 *this << *p++; 1025 while ( len-- )
1026 *this << *p++;
1027 } else {
1028 register Q_INT8 *p = (Q_INT8*)s;
1029 while ( len-- )
1030 *this << *p++;
1031 }
1018 } else { // write data char array 1032 } else { // write data char array
1019 dev->writeBlock( s, len ); 1033 dev->writeBlock( s, len );
1020 } 1034 }
1021 return *this; 1035 return *this;
1022} 1036}
1023 1037
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
@@ -2,13 +2,13 @@
2** $Id$ 2** $Id$
3** 3**
4** Implementation of date and time classes 4** Implementation of date and time classes
5** 5**
6** Created : 940124 6** Created : 940124
7** 7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. 8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the tools module of the Qt GUI Toolkit. 10** This file is part of the tools module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file 13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file. 14** LICENSE.QPL included in the packaging of this file.
@@ -32,13 +32,12 @@
32** 32**
33** Contact info@trolltech.com if any conditions of this licensing are 33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you. 34** not clear to you.
35** 35**
36**********************************************************************/ 36**********************************************************************/
37 37
38// Get the system specific includes and defines
39#include "qplatformdefs.h" 38#include "qplatformdefs.h"
40 39
41#include "qdatetime.h" 40#include "qdatetime.h"
42#include "qdatastream.h" 41#include "qdatastream.h"
43#include "qregexp.h" 42#include "qregexp.h"
44 43
@@ -892,12 +891,18 @@ QDate QDate::addMonths( int nmonths ) const
892 891
893QDate QDate::addYears( int nyears ) const 892QDate QDate::addYears( int nyears ) const
894{ 893{
895 int y, m, d; 894 int y, m, d;
896 julianToGregorian( jd, y, m, d ); 895 julianToGregorian( jd, y, m, d );
897 y += nyears; 896 y += nyears;
897
898 QDate tmp(y,m,1);
899
900 if( d > tmp.daysInMonth() )
901 d = tmp.daysInMonth();
902
898 QDate date(y, m, d); 903 QDate date(y, m, d);
899 return date; 904 return date;
900} 905}
901 906
902 907
903 908
@@ -987,19 +992,31 @@ QDate QDate::currentDate( Qt::TimeSpec ts )
987 if ( ts == Qt::LocalTime ) 992 if ( ts == Qt::LocalTime )
988 GetLocalTime( &t ); 993 GetLocalTime( &t );
989 else 994 else
990 GetSystemTime( &t ); 995 GetSystemTime( &t );
991 d.jd = gregorianToJulian( t.wYear, t.wMonth, t.wDay ); 996 d.jd = gregorianToJulian( t.wYear, t.wMonth, t.wDay );
992#else 997#else
998 // posix compliant system
993 time_t ltime; 999 time_t ltime;
994 time( &ltime ); 1000 time( &ltime );
995 tm *t; 1001 tm *t;
1002
1003# if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
1004 // use the reentrant versions of localtime() and gmtime() where available
1005 tm res;
1006 if ( ts == Qt::LocalTime )
1007 t = localtime_r( &ltime, &res );
1008 else
1009 t = gmtime_r( &ltime, &res );
1010# else
996 if ( ts == Qt::LocalTime ) 1011 if ( ts == Qt::LocalTime )
997 t = localtime( &ltime ); 1012 t = localtime( &ltime );
998 else 1013 else
999 t = gmtime( &ltime ); 1014 t = gmtime( &ltime );
1015# endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
1016
1000 d.jd = gregorianToJulian( t->tm_year + 1900, t->tm_mon + 1, t->tm_mday ); 1017 d.jd = gregorianToJulian( t->tm_year + 1900, t->tm_mon + 1, t->tm_mday );
1001#endif 1018#endif
1002 return d; 1019 return d;
1003} 1020}
1004 1021
1005#ifndef QT_NO_DATESTRING 1022#ifndef QT_NO_DATESTRING
@@ -1552,13 +1569,13 @@ int QTime::msecsTo( const QTime &t ) const
1552 Returns TRUE if this time is later than or equal to \a t; 1569 Returns TRUE if this time is later than or equal to \a t;
1553 otherwise returns FALSE. 1570 otherwise returns FALSE.
1554*/ 1571*/
1555 1572
1556 1573
1557 1574
1558/*! 1575/*!
1559 \overload 1576 \overload
1560 1577
1561 Returns the current time as reported by the system clock. 1578 Returns the current time as reported by the system clock.
1562 1579
1563 Note that the accuracy depends on the accuracy of the underlying 1580 Note that the accuracy depends on the accuracy of the underlying
1564 operating system; not all systems provide 1-millisecond accuracy. 1581 operating system; not all systems provide 1-millisecond accuracy.
@@ -1650,28 +1667,39 @@ bool QTime::currentTime( QTime *ct, Qt::TimeSpec ts )
1650 } else { 1667 } else {
1651 GetSystemTime( &t ); 1668 GetSystemTime( &t );
1652 } 1669 }
1653 ct->ds = (uint)( MSECS_PER_HOUR*t.wHour + MSECS_PER_MIN*t.wMinute + 1670 ct->ds = (uint)( MSECS_PER_HOUR*t.wHour + MSECS_PER_MIN*t.wMinute +
1654 1000*t.wSecond + t.wMilliseconds ); 1671 1000*t.wSecond + t.wMilliseconds );
1655#elif defined(Q_OS_UNIX) 1672#elif defined(Q_OS_UNIX)
1673 // posix compliant system
1656 struct timeval tv; 1674 struct timeval tv;
1657 gettimeofday( &tv, 0 ); 1675 gettimeofday( &tv, 0 );
1658 time_t ltime = tv.tv_sec; 1676 time_t ltime = tv.tv_sec;
1659 tm *t; 1677 tm *t;
1660 if ( ts == Qt::LocalTime ) { 1678
1679# if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
1680 // use the reentrant versions of localtime() and gmtime() where available
1681 tm res;
1682 if ( ts == Qt::LocalTime )
1683 t = localtime_r( &ltime, &res );
1684 else
1685 t = gmtime_r( &ltime, &res );
1686# else
1687 if ( ts == Qt::LocalTime )
1661 t = localtime( &ltime ); 1688 t = localtime( &ltime );
1662 } else { 1689 else
1663 t = gmtime( &ltime ); 1690 t = gmtime( &ltime );
1664 } 1691# endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
1692
1665 ct->ds = (uint)( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1693 ct->ds = (uint)( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min +
1666 1000 * t->tm_sec + tv.tv_usec / 1000 ); 1694 1000 * t->tm_sec + tv.tv_usec / 1000 );
1667#else 1695#else
1668 time_t ltime; // no millisecond resolution 1696 time_t ltime; // no millisecond resolution
1669 ::time( &ltime ); 1697 ::time( &ltime );
1670 tm *t; 1698 tm *t;
1671 if ( ts == Qt::LocalTime ) 1699 if ( ts == Qt::LocalTime )
1672 localtime( &ltime ); 1700 localtime( &ltime );
1673 else 1701 else
1674 gmtime( &ltime ); 1702 gmtime( &ltime );
1675 ct->ds = (uint) ( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1703 ct->ds = (uint) ( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min +
1676 1000 * t->tm_sec ); 1704 1000 * t->tm_sec );
1677#endif 1705#endif
@@ -1703,15 +1731,15 @@ bool QTime::isValid( int h, int m, int s, int ms )
1703 1731
1704/*! 1732/*!
1705 Sets this time to the current time. This is practical for timing: 1733 Sets this time to the current time. This is practical for timing:
1706 1734
1707 \code 1735 \code
1708 QTime t; 1736 QTime t;
1709 t.start(); // start clock 1737 t.start();
1710 ... // some lengthy task 1738 some_lengthy_task();
1711 qDebug( "%d\n", t.elapsed() ); // prints the number of msecs elapsed 1739 qDebug( "Time elapsed: %d ms", t.elapsed() );
1712 \endcode 1740 \endcode
1713 1741
1714 \sa restart(), elapsed(), currentTime() 1742 \sa restart(), elapsed(), currentTime()
1715*/ 1743*/
1716 1744
1717void QTime::start() 1745void QTime::start()
@@ -1957,22 +1985,40 @@ void QDateTime::setTime_t( uint secsSince1Jan1970UTC )
1957 \sa toTime_t() 1985 \sa toTime_t()
1958*/ 1986*/
1959void QDateTime::setTime_t( uint secsSince1Jan1970UTC, Qt::TimeSpec ts ) 1987void QDateTime::setTime_t( uint secsSince1Jan1970UTC, Qt::TimeSpec ts )
1960{ 1988{
1961 time_t tmp = (time_t) secsSince1Jan1970UTC; 1989 time_t tmp = (time_t) secsSince1Jan1970UTC;
1962 tm *brokenDown = 0; 1990 tm *brokenDown = 0;
1991
1992#if defined(Q_OS_UNIX) && defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
1993 // posix compliant system
1994 // use the reentrant versions of localtime() and gmtime() where available
1995 tm res;
1996 if ( ts == Qt::LocalTime )
1997 brokenDown = localtime_r( &tmp, &res );
1998 if ( !brokenDown ) {
1999 brokenDown = gmtime_r( &tmp, &res );
2000 if ( !brokenDown ) {
2001 d.jd = QDate::gregorianToJulian( 1970, 1, 1 );
2002 t.ds = 0;
2003 return;
2004 }
2005 }
2006#else
1963 if ( ts == Qt::LocalTime ) 2007 if ( ts == Qt::LocalTime )
1964 brokenDown = localtime( &tmp ); 2008 brokenDown = localtime( &tmp );
1965 if ( !brokenDown ) { 2009 if ( !brokenDown ) {
1966 brokenDown = gmtime( &tmp ); 2010 brokenDown = gmtime( &tmp );
1967 if ( !brokenDown ) { 2011 if ( !brokenDown ) {
1968 d.jd = QDate::gregorianToJulian( 1970, 1, 1 ); 2012 d.jd = QDate::gregorianToJulian( 1970, 1, 1 );
1969 t.ds = 0; 2013 t.ds = 0;
1970 return; 2014 return;
1971 } 2015 }
1972 } 2016 }
2017#endif
2018
1973 d.jd = QDate::gregorianToJulian( brokenDown->tm_year + 1900, 2019 d.jd = QDate::gregorianToJulian( brokenDown->tm_year + 1900,
1974 brokenDown->tm_mon + 1, 2020 brokenDown->tm_mon + 1,
1975 brokenDown->tm_mday ); 2021 brokenDown->tm_mday );
1976 t.ds = MSECS_PER_HOUR * brokenDown->tm_hour + 2022 t.ds = MSECS_PER_HOUR * brokenDown->tm_hour +
1977 MSECS_PER_MIN * brokenDown->tm_min + 2023 MSECS_PER_MIN * brokenDown->tm_min +
1978 1000 * brokenDown->tm_sec; 2024 1000 * brokenDown->tm_sec;
@@ -2297,13 +2343,13 @@ bool QDateTime::operator>=( const QDateTime &dt ) const
2297 return TRUE; 2343 return TRUE;
2298 return d == dt.d ? t >= dt.t : FALSE; 2344 return d == dt.d ? t >= dt.t : FALSE;
2299} 2345}
2300 2346
2301/*! 2347/*!
2302 \overload 2348 \overload
2303 2349
2304 Returns the current datetime, as reported by the system clock. 2350 Returns the current datetime, as reported by the system clock.
2305 2351
2306 \sa QDate::currentDate(), QTime::currentTime() 2352 \sa QDate::currentDate(), QTime::currentTime()
2307*/ 2353*/
2308 2354
2309QDateTime QDateTime::currentDateTime() 2355QDateTime QDateTime::currentDateTime()
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
@@ -2,13 +2,13 @@
2** $Id$ 2** $Id$
3** 3**
4** Implementation of QDir class 4** Implementation of QDir class
5** 5**
6** Created : 950427 6** Created : 950427
7** 7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. 8** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the tools module of the Qt GUI Toolkit. 10** This file is part of the tools module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file 13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file. 14** LICENSE.QPL included in the packaging of this file.
@@ -40,19 +40,24 @@
40 40
41#ifndef QT_NO_DIR 41#ifndef QT_NO_DIR
42#include <private/qdir_p.h> 42#include <private/qdir_p.h>
43#include "qfileinfo.h" 43#include "qfileinfo.h"
44#include "qregexp.h" 44#include "qregexp.h"
45#include "qstringlist.h" 45#include "qstringlist.h"
46#include <stdlib.h> 46#include <limits.h>
47#include <ctype.h>
48 47
48#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX)
49const bool CaseSensitiveFS = FALSE;
50#else
51const bool CaseSensitiveFS = TRUE;
52#endif
49 53
50 54
51/*! 55/*!
52 \class QDir 56 \class QDir
57 \reentrant
53 \brief The QDir class provides access to directory structures and their contents in a platform-independent way. 58 \brief The QDir class provides access to directory structures and their contents in a platform-independent way.
54 59
55 \ingroup io 60 \ingroup io
56 \mainclass 61 \mainclass
57 62
58 A QDir is used to manipulate path names, access information 63 A QDir is used to manipulate path names, access information
@@ -227,12 +232,20 @@ QDir::QDir( const QDir &d )
227 dirty = TRUE; 232 dirty = TRUE;
228 allDirs = d.allDirs; 233 allDirs = d.allDirs;
229 filtS = d.filtS; 234 filtS = d.filtS;
230 sortS = d.sortS; 235 sortS = d.sortS;
231} 236}
232 237
238/*!
239 Refreshes the directory information.
240*/
241void QDir::refresh() const
242{
243 QDir* that = (QDir*) this;
244 that->dirty = TRUE;
245}
233 246
234void QDir::init() 247void QDir::init()
235{ 248{
236 fList = 0; 249 fList = 0;
237 fiList = 0; 250 fiList = 0;
238 nameFilt = QString::fromLatin1("*"); 251 nameFilt = QString::fromLatin1("*");
@@ -379,16 +392,42 @@ QString QDir::absFilePath( const QString &fileName,
379 bool acceptAbsPath ) const 392 bool acceptAbsPath ) const
380{ 393{
381 if ( acceptAbsPath && !isRelativePath( fileName ) ) 394 if ( acceptAbsPath && !isRelativePath( fileName ) )
382 return fileName; 395 return fileName;
383 396
384 QString tmp = absPath(); 397 QString tmp = absPath();
385 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName && 398#ifdef Q_OS_WIN32
386 fileName[0] != '/') ) 399 if ( fileName[0].isLetter() && fileName[1] == ':' ) {
387 tmp += '/'; 400 int drv = fileName.upper()[0].latin1() - 'A' + 1;
388 tmp += fileName; 401 if ( _getdrive() != drv ) {
402 if ( qt_winunicode ) {
403 TCHAR buf[PATH_MAX];
404 ::_tgetdcwd( drv, buf, PATH_MAX );
405 tmp.setUnicodeCodes( (ushort*)buf, ::_tcslen(buf) );
406 } else {
407 char buf[PATH_MAX];
408 ::_getdcwd( drv, buf, PATH_MAX );
409 tmp = buf;
410 }
411 if ( !tmp.endsWith("\\") )
412 tmp += "\\";
413 tmp += fileName.right( fileName.length() - 2 );
414 int x;
415 for ( x = 0; x < (int) tmp.length(); x++ ) {
416 if ( tmp[x] == '\\' )
417 tmp[x] = '/';
418 }
419 }
420 } else
421#endif
422 {
423 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
424 fileName[0] != '/') )
425 tmp += '/';
426 tmp += fileName;
427 }
389 return tmp; 428 return tmp;
390} 429}
391 430
392 431
393/*! 432/*!
394 Returns \a pathName with the '/' separators converted to 433 Returns \a pathName with the '/' separators converted to
@@ -931,13 +970,14 @@ QDir &QDir::operator=( const QString &path )
931 970
932 Example: 971 Example:
933 \code 972 \code
934 // The current directory is "/usr/local" 973 // The current directory is "/usr/local"
935 QDir d1( "/usr/local/bin" ); 974 QDir d1( "/usr/local/bin" );
936 QDir d2( "bin" ); 975 QDir d2( "bin" );
937 if ( d1 != d2 ) qDebug( "They differ\n" ); // This is printed 976 if ( d1 != d2 )
977 qDebug( "They differ" );
938 \endcode 978 \endcode
939*/ 979*/
940 980
941/*! 981/*!
942 Returns TRUE if directory \a d and this directory have the same 982 Returns TRUE if directory \a d and this directory have the same
943 path and their sort and filter settings are the same; otherwise 983 path and their sort and filter settings are the same; otherwise
@@ -946,13 +986,14 @@ QDir &QDir::operator=( const QString &path )
946 Example: 986 Example:
947 \code 987 \code
948 // The current directory is "/usr/local" 988 // The current directory is "/usr/local"
949 QDir d1( "/usr/local/bin" ); 989 QDir d1( "/usr/local/bin" );
950 QDir d2( "bin" ); 990 QDir d2( "bin" );
951 d2.convertToAbs(); 991 d2.convertToAbs();
952 if ( d1 == d2 ) qDebug( "They're the same\n" ); // This is printed 992 if ( d1 == d2 )
993 qDebug( "They're the same" );
953 \endcode 994 \endcode
954*/ 995*/
955 996
956bool QDir::operator==( const QDir &d ) const 997bool QDir::operator==( const QDir &d ) const
957{ 998{
958 return dPath == d.dPath && 999 return dPath == d.dPath &&
@@ -1084,33 +1125,45 @@ QDir QDir::root()
1084 1125
1085 Returns the absolute path of the user's home directory. 1126 Returns the absolute path of the user's home directory.
1086 1127
1087 \sa home() 1128 \sa home()
1088*/ 1129*/
1089 1130
1090QStringList qt_makeFilterList( const QString &filter ) 1131QValueList<QRegExp> qt_makeFilterList( const QString &filter )
1091{ 1132{
1133 QValueList<QRegExp> regExps;
1092 if ( filter.isEmpty() ) 1134 if ( filter.isEmpty() )
1093 return QStringList(); 1135 return regExps;
1094 1136
1095 QChar sep( ';' ); 1137 QChar sep( ';' );
1096 int i = filter.find( sep, 0 ); 1138 int i = filter.find( sep, 0 );
1097 if ( i == -1 && filter.find( ' ', 0 ) != -1 ) 1139 if ( i == -1 && filter.find( ' ', 0 ) != -1 )
1098 sep = QChar( ' ' ); 1140 sep = QChar( ' ' );
1099 1141
1100 QStringList list = QStringList::split( sep, filter ); 1142 QStringList list = QStringList::split( sep, filter );
1101 QStringList::Iterator it = list.begin(); 1143 QStringList::Iterator it = list.begin();
1102 QStringList list2; 1144 while ( it != list.end() ) {
1145 regExps << QRegExp( (*it).stripWhiteSpace(), CaseSensitiveFS, TRUE );
1146 ++it;
1147 }
1148 return regExps;
1149}
1103 1150
1104 for ( ; it != list.end(); ++it ) { 1151bool qt_matchFilterList( const QValueList<QRegExp>& filters,
1105 QString s = *it; 1152 const QString &fileName )
1106 list2 << s.stripWhiteSpace(); 1153{
1154 QValueList<QRegExp>::ConstIterator rit = filters.begin();
1155 while ( rit != filters.end() ) {
1156 if ( (*rit).exactMatch(fileName) )
1157 return TRUE;
1158 ++rit;
1107 } 1159 }
1108 return list2; 1160 return FALSE;
1109} 1161}
1110 1162
1163
1111/*! 1164/*!
1112 \overload 1165 \overload
1113 1166
1114 Returns TRUE if the \a fileName matches any of the wildcard (glob) 1167 Returns TRUE if the \a fileName matches any of the wildcard (glob)
1115 patterns in the list of \a filters; otherwise returns FALSE. 1168 patterns in the list of \a filters; otherwise returns FALSE.
1116 1169
@@ -1120,17 +1173,13 @@ QStringList qt_makeFilterList( const QString &filter )
1120*/ 1173*/
1121 1174
1122bool QDir::match( const QStringList &filters, const QString &fileName ) 1175bool QDir::match( const QStringList &filters, const QString &fileName )
1123{ 1176{
1124 QStringList::ConstIterator sit = filters.begin(); 1177 QStringList::ConstIterator sit = filters.begin();
1125 while ( sit != filters.end() ) { 1178 while ( sit != filters.end() ) {
1126#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX) 1179 QRegExp rx( *sit, CaseSensitiveFS, TRUE );
1127 QRegExp rx( *sit, FALSE, TRUE ); // The FAT FS is not case sensitive..
1128#else
1129 QRegExp rx( *sit, TRUE, TRUE ); // ..while others are.
1130#endif
1131 if ( rx.exactMatch(fileName) ) 1180 if ( rx.exactMatch(fileName) )
1132 return TRUE; 1181 return TRUE;
1133 ++sit; 1182 ++sit;
1134 } 1183 }
1135 return FALSE; 1184 return FALSE;
1136} 1185}
@@ -1144,14 +1193,13 @@ bool QDir::match( const QStringList &filters, const QString &fileName )
1144 matching.\endlink) 1193 matching.\endlink)
1145 \sa QRegExp::match() 1194 \sa QRegExp::match()
1146*/ 1195*/
1147 1196
1148bool QDir::match( const QString &filter, const QString &fileName ) 1197bool QDir::match( const QString &filter, const QString &fileName )
1149{ 1198{
1150 QStringList lst = qt_makeFilterList( filter ); 1199 return qt_matchFilterList( qt_makeFilterList(filter), fileName );
1151 return match( lst, fileName );
1152} 1200}
1153 1201
1154 1202
1155/*! 1203/*!
1156 Removes all multiple directory separators "/" and resolves any 1204 Removes all multiple directory separators "/" and resolves any
1157 "."s or ".."s found in the path, \a filePath. 1205 "."s or ".."s found in the path, \a filePath.
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
@@ -2,13 +2,13 @@
2** $Id$ 2** $Id$
3** 3**
4** Implementation of QDir class 4** Implementation of QDir class
5** 5**
6** Created : 950628 6** Created : 950628
7** 7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. 8** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the tools module of the Qt GUI Toolkit. 10** This file is part of the tools module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file 13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file. 14** LICENSE.QPL included in the packaging of this file.
@@ -48,12 +48,13 @@
48#ifdef QT_THREAD_SUPPORT 48#ifdef QT_THREAD_SUPPORT
49# include <private/qmutexpool_p.h> 49# include <private/qmutexpool_p.h>
50#endif // QT_THREAD_SUPPORT 50#endif // QT_THREAD_SUPPORT
51 51
52#include <stdlib.h> 52#include <stdlib.h>
53#include <limits.h> 53#include <limits.h>
54#include <errno.h>
54 55
55 56
56void QDir::slashify( QString& ) 57void QDir::slashify( QString& )
57{ 58{
58} 59}
59 60
@@ -67,38 +68,38 @@ QString QDir::homeDirPath()
67 return d; 68 return d;
68} 69}
69 70
70QString QDir::canonicalPath() const 71QString QDir::canonicalPath() const
71{ 72{
72 QString r; 73 QString r;
73
74 char cur[PATH_MAX+1]; 74 char cur[PATH_MAX+1];
75 if ( ::getcwd( cur, PATH_MAX ) ) 75 if ( ::getcwd( cur, PATH_MAX ) ) {
76 if ( ::chdir(QFile::encodeName(dPath)) >= 0 ) { 76 char tmp[PATH_MAX+1];
77 char tmp[PATH_MAX+1]; 77 if( ::realpath( QFile::encodeName( dPath ), tmp ) )
78 if ( ::getcwd( tmp, PATH_MAX ) ) 78 r = QFile::decodeName( tmp );
79 r = QFile::decodeName(tmp); 79 slashify( r );
80 ::chdir( cur ); 80
81 } 81 // always make sure we go back to the current dir
82 82 ::chdir( cur );
83 slashify( r ); 83 }
84 return r; 84 return r;
85} 85}
86 86
87bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const 87bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const
88{ 88{
89#if defined(Q_OS_MACX) // Mac X doesn't support trailing /'s 89#if defined(Q_OS_MACX) // Mac X doesn't support trailing /'s
90 QString name = dirName; 90 QString name = dirName;
91 if (dirName[dirName.length() - 1] == "/") 91 if (dirName[dirName.length() - 1] == "/")
92 name = dirName.left( dirName.length() - 1 ); 92 name = dirName.left( dirName.length() - 1 );
93 return ::mkdir( QFile::encodeName(filePath(name,acceptAbsPath)), 0777 ) 93 int status =
94 == 0; 94 ::mkdir( QFile::encodeName(filePath(name,acceptAbsPath)), 0777 );
95#else 95#else
96 return ::mkdir( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 ) 96 int status =
97 == 0; 97 ::mkdir( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 );
98#endif 98#endif
99 return status == 0;
99} 100}
100 101
101bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const 102bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const
102{ 103{
103 return ::rmdir( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0; 104 return ::rmdir( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
104} 105}
@@ -183,40 +184,44 @@ bool QDir::readDirEntries( const QString &nameFilter,
183 fiList->setAutoDelete( TRUE ); 184 fiList->setAutoDelete( TRUE );
184 } else { 185 } else {
185 fList->clear(); 186 fList->clear();
186 fiList->clear(); 187 fiList->clear();
187 } 188 }
188 189
189 QStringList filters = qt_makeFilterList( nameFilter ); 190 QValueList<QRegExp> filters = qt_makeFilterList( nameFilter );
190 191
191 bool doDirs = (filterSpec & Dirs)!= 0; 192 bool doDirs = (filterSpec & Dirs)!= 0;
192 bool doFiles = (filterSpec & Files)!= 0; 193 bool doFiles = (filterSpec & Files)!= 0;
193 bool noSymLinks = (filterSpec & NoSymLinks) != 0; 194 bool noSymLinks = (filterSpec & NoSymLinks) != 0;
194 bool doReadable = (filterSpec & Readable)!= 0; 195 bool doReadable = (filterSpec & Readable)!= 0;
195 bool doWritable = (filterSpec & Writable)!= 0; 196 bool doWritable = (filterSpec & Writable)!= 0;
196 bool doExecable = (filterSpec & Executable) != 0; 197 bool doExecable = (filterSpec & Executable) != 0;
197 bool doHidden = (filterSpec & Hidden)!= 0; 198 bool doHidden = (filterSpec & Hidden)!= 0;
198 bool doSystem = (filterSpec & System) != 0; 199 bool doSystem = (filterSpec & System) != 0;
199 200
200#if defined(Q_OS_OS2EMX)
201 //QRegExp wc( nameFilter, FALSE, TRUE );// wild card, case insensitive
202#else
203 //QRegExp wc( nameFilter, TRUE, TRUE );// wild card, case sensitive
204#endif
205 QFileInfo fi; 201 QFileInfo fi;
206 DIR *dir; 202 DIR *dir;
207 dirent *file; 203 dirent *file;
208 204
209 dir = opendir( QFile::encodeName(dPath) ); 205 dir = opendir( QFile::encodeName(dPath) );
210 if ( !dir ) 206 if ( !dir )
211 return FALSE; // cannot read the directory 207 return FALSE; // cannot read the directory
212 208
213 while ( (file = readdir(dir)) ) { 209#if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN)
210 union {
211 struct dirent mt_file;
212 char b[sizeof(struct dirent) + MAXNAMLEN + 1];
213 } u;
214 while ( readdir_r(dir, &u.mt_file, &file ) == 0 && file )
215#else
216 while ( (file = readdir(dir)) )
217#endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
218 {
214 QString fn = QFile::decodeName(file->d_name); 219 QString fn = QFile::decodeName(file->d_name);
215 fi.setFile( *this, fn ); 220 fi.setFile( *this, fn );
216 if ( !match( filters, fn ) && !(allDirs && fi.isDir()) ) 221 if ( !qt_matchFilterList(filters, fn) && !(allDirs && fi.isDir()) )
217 continue; 222 continue;
218 if ( (doDirs && fi.isDir()) || (doFiles && fi.isFile()) || 223 if ( (doDirs && fi.isDir()) || (doFiles && fi.isFile()) ||
219 (doSystem && (!fi.isFile() && !fi.isDir())) ) { 224 (doSystem && (!fi.isFile() && !fi.isDir())) ) {
220 if ( noSymLinks && fi.isSymLink() ) 225 if ( noSymLinks && fi.isSymLink() )
221 continue; 226 continue;
222 if ( (filterSpec & RWEMask) != 0 ) 227 if ( (filterSpec & RWEMask) != 0 )
@@ -273,13 +278,14 @@ const QFileInfoList * QDir::drives()
273 // points to that list 278 // points to that list
274 static QFileInfoList * knownMemoryLeak = 0; 279 static QFileInfoList * knownMemoryLeak = 0;
275 280
276 if ( !knownMemoryLeak ) { 281 if ( !knownMemoryLeak ) {
277 282
278#ifdef QT_THREAD_SUPPORT 283#ifdef QT_THREAD_SUPPORT
279 QMutexLocker locker( qt_global_mutexpool->get( &knownMemoryLeak ) ); 284 QMutexLocker locker( qt_global_mutexpool ?
285 qt_global_mutexpool->get( &knownMemoryLeak ) : 0 );
280#endif // QT_THREAD_SUPPORT 286#endif // QT_THREAD_SUPPORT
281 287
282 if ( !knownMemoryLeak ) { 288 if ( !knownMemoryLeak ) {
283 knownMemoryLeak = new QFileInfoList; 289 knownMemoryLeak = new QFileInfoList;
284 // non-win32 versions both use just one root directory 290 // non-win32 versions both use just one root directory
285 knownMemoryLeak->append( new QFileInfo( rootDirPath() ) ); 291 knownMemoryLeak->append( new QFileInfo( rootDirPath() ) );
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
@@ -85,13 +85,13 @@ extern bool qt_file_access( const QString& fn, int t );
85 QStringList lines; 85 QStringList lines;
86 QFile file( "file.txt" ); 86 QFile file( "file.txt" );
87 if ( file.open( IO_ReadOnly ) ) { 87 if ( file.open( IO_ReadOnly ) ) {
88 QTextStream stream( &file ); 88 QTextStream stream( &file );
89 QString line; 89 QString line;
90 int i = 1; 90 int i = 1;
91 while ( !stream.eof() ) { 91 while ( !stream.atEnd() ) {
92 line = stream.readLine(); // line of text excluding '\n' 92 line = stream.readLine(); // line of text excluding '\n'
93 printf( "%3d: %s\n", i++, line.latin1() ); 93 printf( "%3d: %s\n", i++, line.latin1() );
94 lines += line; 94 lines += line;
95 } 95 }
96 file.close(); 96 file.close();
97 } 97 }
@@ -287,12 +287,13 @@ void QFile::flush()
287/*! \reimp 287/*! \reimp
288 \fn QIODevice::Offset QFile::at() const 288 \fn QIODevice::Offset QFile::at() const
289*/ 289*/
290 290
291/*! 291/*!
292 Returns TRUE if the end of file has been reached; otherwise returns FALSE. 292 Returns TRUE if the end of file has been reached; otherwise returns FALSE.
293 If QFile has not been open()'d, then the behavior is undefined.
293 294
294 \sa size() 295 \sa size()
295*/ 296*/
296 297
297bool QFile::atEnd() const 298bool QFile::atEnd() const
298{ 299{
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
@@ -432,17 +432,20 @@ bool QFile::open( int m, int f )
432 \sa at() 432 \sa at()
433*/ 433*/
434 434
435QIODevice::Offset QFile::size() const 435QIODevice::Offset QFile::size() const
436{ 436{
437 struct stat st; 437 struct stat st;
438 int ret = 0;
438 if ( isOpen() ) { 439 if ( isOpen() ) {
439 ::fstat( fh ? fileno(fh) : fd, &st ); 440 ret = ::fstat( fh ? fileno(fh) : fd, &st );
440 } else { 441 } else {
441 ::stat( QFile::encodeName(fn), &st ); 442 ret = ::stat( QFile::encodeName(fn), &st );
442 } 443 }
444 if ( ret == -1 )
445 return 0;
443#if defined(QT_LARGEFILE_SUPPORT) && !defined(QT_ABI_64BITOFFSET) 446#if defined(QT_LARGEFILE_SUPPORT) && !defined(QT_ABI_64BITOFFSET)
444 return (uint)st.st_size > UINT_MAX ? UINT_MAX : (QIODevice::Offset)st.st_size; 447 return (uint)st.st_size > UINT_MAX ? UINT_MAX : (QIODevice::Offset)st.st_size;
445#else 448#else
446 return st.st_size; 449 return st.st_size;
447#endif 450#endif
448} 451}
@@ -535,13 +538,13 @@ Q_LONG QFile::readBlock( char *p, Q_ULONG len )
535#endif 538#endif
536 Q_ULONG nread = 0; // number of bytes read 539 Q_ULONG nread = 0; // number of bytes read
537 if ( !ungetchBuffer.isEmpty() ) { 540 if ( !ungetchBuffer.isEmpty() ) {
538 // need to add these to the returned string. 541 // need to add these to the returned string.
539 uint l = ungetchBuffer.length(); 542 uint l = ungetchBuffer.length();
540 while( nread < l ) { 543 while( nread < l ) {
541 *p = ungetchBuffer[ l - nread - 1 ]; 544 *p = ungetchBuffer.at( l - nread - 1 );
542 p++; 545 p++;
543 nread++; 546 nread++;
544 } 547 }
545 ungetchBuffer.truncate( l - nread ); 548 ungetchBuffer.truncate( l - nread );
546 } 549 }
547 550
@@ -626,13 +629,15 @@ Q_LONG QFile::writeBlock( const char *p, Q_ULONG len )
626} 629}
627 630
628/*! 631/*!
629 Returns the file handle of the file. 632 Returns the file handle of the file.
630 633
631 This is a small positive integer, suitable for use with C library 634 This is a small positive integer, suitable for use with C library
632 functions such as fdopen() and fcntl(), as well as with QSocketNotifier. 635 functions such as fdopen() and fcntl(). On systems that use file
636 descriptors for sockets (ie. Unix systems, but not Windows) the handle
637 can be used with QSocketNotifier as well.
633 638
634 If the file is not open or there is an error, handle() returns -1. 639 If the file is not open or there is an error, handle() returns -1.
635 640
636 \sa QSocketNotifier 641 \sa QSocketNotifier
637*/ 642*/
638 643
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
@@ -632,22 +632,24 @@ QDateTime QFileInfo::lastRead() const
632 drive letter, except for network shares that are not mapped to a 632 drive letter, except for network shares that are not mapped to a
633 drive letter, in which case the path will begin '//sharename/'. 633 drive letter, in which case the path will begin '//sharename/'.
634 634
635 This function returns the same as filePath(), unless isRelative() 635 This function returns the same as filePath(), unless isRelative()
636 is TRUE. 636 is TRUE.
637 637
638 If the QFileInfo is empty it returns QDir::currentDirPath().
639
638 This function can be time consuming under Unix (in the order of 640 This function can be time consuming under Unix (in the order of
639 milliseconds). 641 milliseconds).
640 642
641 \sa isRelative(), filePath() 643 \sa isRelative(), filePath()
642*/ 644*/
643QString QFileInfo::absFilePath() const 645QString QFileInfo::absFilePath() const
644{ 646{
645 QString tmp; 647 QString tmp;
646 if ( QDir::isRelativePath(fn) 648 if ( QDir::isRelativePath(fn)
647#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) 649#if defined(Q_OS_WIN32)
648 && fn[1] != ':' 650 && fn[1] != ':'
649#endif 651#endif
650 ) { 652 ) {
651 tmp = QDir::currentDirPath(); 653 tmp = QDir::currentDirPath();
652 tmp += '/'; 654 tmp += '/';
653 } 655 }
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
@@ -211,15 +211,15 @@ uint QFileInfo::groupId() const
211 always returns TRUE. 211 always returns TRUE.
212 212
213 Example: 213 Example:
214 \code 214 \code
215 QFileInfo fi( "/tmp/archive.tar.gz" ); 215 QFileInfo fi( "/tmp/archive.tar.gz" );
216 if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) ) 216 if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) )
217 qWarning( "I can change the file; my group can read the file."); 217 qWarning( "I can change the file; my group can read the file" );
218 if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) ) 218 if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) )
219 qWarning( "The group or others can change the file!" ); 219 qWarning( "The group or others can change the file" );
220 \endcode 220 \endcode
221 221
222 \sa isReadable(), isWritable(), isExecutable() 222 \sa isReadable(), isWritable(), isExecutable()
223*/ 223*/
224 224
225bool QFileInfo::permission( int permissionSpec ) const 225bool QFileInfo::permission( int permissionSpec ) const
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
@@ -32,27 +32,37 @@
32** 32**
33** Contact info@trolltech.com if any conditions of this licensing are 33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you. 34** not clear to you.
35** 35**
36**********************************************************************/ 36**********************************************************************/
37 37
38 #include "qglobal.h" // needed to define Q_WS_WIN 38#include "qglobal.h"
39#ifdef Q_WS_WIN 39#if defined(Q_CC_BOR)
40 #include "qt_windows.h" // needed for bsearch on some platforms 40 // needed for qsort() because of a std namespace problem on Borland
41# include "qplatformdefs.h"
42#elif defined(Q_WS_WIN)
43 // needed for bsearch on some platforms
44# include "qt_windows.h"
41#endif 45#endif
42 46
43 #define QGARRAY_CPP 47 #define QGARRAY_CPP
44#include "qgarray.h" 48#include "qgarray.h"
45#include <stdlib.h> 49#include <stdlib.h>
46#include <string.h> 50#include <string.h>
47 51
48#ifdef QT_THREAD_SUPPORT 52#ifdef QT_THREAD_SUPPORT
49# include <private/qmutexpool_p.h> 53# include <private/qmutexpool_p.h>
50#endif // QT_THREAD_SUPPORT 54#endif // QT_THREAD_SUPPORT
51 55
52 #define USE_MALLOC // comment to use new/delete 56/*
57 If USE_MALLOC isn't defined, we use new[] and delete[] to allocate
58 memory. The documentation for QMemArray<T>::assign() explicitly
59 mentions that the array is freed using free(), so don't mess around
60 with USE_MALLOC unless you know what you're doing.
61*/
62#define USE_MALLOC
53 63
54#undef NEW 64#undef NEW
55#undef DELETE 65#undef DELETE
56 66
57#if defined(USE_MALLOC) 67#if defined(USE_MALLOC)
58 #define NEW(type,size)((type*)malloc(size*sizeof(type))) 68 #define NEW(type,size)((type*)malloc(size*sizeof(type)))
@@ -132,13 +142,17 @@ QGArray::QGArray( int size )
132 shd = newData(); 142 shd = newData();
133 Q_CHECK_PTR( shd ); 143 Q_CHECK_PTR( shd );
134 if ( size == 0 ) // zero length 144 if ( size == 0 ) // zero length
135 return; 145 return;
136 shd->data = NEW(char,size); 146 shd->data = NEW(char,size);
137 Q_CHECK_PTR( shd->data ); 147 Q_CHECK_PTR( shd->data );
138 shd->len = size; 148 shd->len =
149#ifdef QT_QGARRAY_SPEED_OPTIM
150 shd->maxl =
151#endif
152 size;
139} 153}
140 154
141/*! 155/*!
142 Constructs a shallow copy of \a a. 156 Constructs a shallow copy of \a a.
143*/ 157*/
144 158
@@ -209,41 +223,76 @@ bool QGArray::isEqual( const QGArray &a ) const
209 return TRUE; 223 return TRUE;
210 return (size() ? memcmp( data(), a.data(), size() ) : 0) == 0; 224 return (size() ? memcmp( data(), a.data(), size() ) : 0) == 0;
211} 225}
212 226
213 227
214/*! 228/*!
215 Resizes the array to \a newsize bytes. 229 Resizes the array to \a newsize bytes. \a optim is either
230 MemOptim (the default) or SpeedOptim.
216*/ 231*/
217 232bool QGArray::resize( uint newsize, Optimization optim )
218bool QGArray::resize( uint newsize )
219{ 233{
220 if ( newsize == shd->len ) // nothing to do 234#ifndef QT_QGARRAY_SPEED_OPTIM
235 Q_UNUSED(optim);
236#endif
237
238 if ( newsize == shd->len
239#ifdef QT_QGARRAY_SPEED_OPTIM
240 && newsize == shd->maxl
241#endif
242 ) // nothing to do
221 return TRUE; 243 return TRUE;
222 if ( newsize == 0 ) { // remove array 244 if ( newsize == 0 ) { // remove array
223 duplicate( 0, 0 ); 245 duplicate( 0, 0 );
224 return TRUE; 246 return TRUE;
225 } 247 }
248
249 uint newmaxl = newsize;
250#ifdef QT_QGARRAY_SPEED_OPTIM
251 if ( optim == SpeedOptim ) {
252 if ( newsize <= shd->maxl &&
253 ( newsize * 4 > shd->maxl || shd->maxl <= 4 ) ) {
254 shd->len = newsize;
255 return TRUE;
256 }
257 newmaxl = 4;
258 while ( newmaxl < newsize )
259 newmaxl *= 2;
260 // try to spare some memory
261 if ( newmaxl >= 1024 * 1024 && newsize <= newmaxl - (newmaxl >> 2) )
262 newmaxl -= newmaxl >> 2;
263 }
264 shd->maxl = newmaxl;
265#endif
266
226 if ( shd->data ) { // existing data 267 if ( shd->data ) { // existing data
227#if defined(DONT_USE_REALLOC) 268#if defined(DONT_USE_REALLOC)
228 char *newdata = NEW(char,newsize);// manual realloc 269 char *newdata = NEW(char,newsize);// manual realloc
229 memcpy( newdata, shd->data, QMIN(shd->len,newsize) ); 270 memcpy( newdata, shd->data, QMIN(shd->len,newmaxl) );
230 DELETE(shd->data); 271 DELETE(shd->data);
231 shd->data = newdata; 272 shd->data = newdata;
232#else 273#else
233 shd->data = (char *)realloc( shd->data, newsize ); 274 shd->data = (char *)realloc( shd->data, newmaxl );
234#endif 275#endif
235 } else { 276 } else {
236 shd->data = NEW(char,newsize); 277 shd->data = NEW(char,newmaxl);
237 } 278 }
238 if ( !shd->data ) // no memory 279 if ( !shd->data ) // no memory
239 return FALSE; 280 return FALSE;
240 shd->len = newsize; 281 shd->len = newsize;
241 return TRUE; 282 return TRUE;
242} 283}
243 284
285/*!\overload
286*/
287bool QGArray::resize( uint newsize )
288{
289 return resize( newsize, MemOptim );
290}
291
292
244/*! 293/*!
245 Fills the array with the repeated occurrences of \a d, which is 294 Fills the array with the repeated occurrences of \a d, which is
246 \a sz bytes long. 295 \a sz bytes long.
247 If \a len is specified as different from -1, then the array will be 296 If \a len is specified as different from -1, then the array will be
248 resized to \a len*sz before it is filled. 297 resized to \a len*sz before it is filled.
249 298
@@ -316,13 +365,17 @@ QGArray &QGArray::assign( const char *d, uint len )
316 Q_CHECK_PTR( shd ); 365 Q_CHECK_PTR( shd );
317 } else { 366 } else {
318 if ( shd->data ) 367 if ( shd->data )
319 DELETE(shd->data); 368 DELETE(shd->data);
320 } 369 }
321 shd->data = (char *)d; 370 shd->data = (char *)d;
322 shd->len = len; 371 shd->len =
372#ifdef QT_QGARRAY_SPEED_OPTIM
373 shd->maxl =
374#endif
375 len;
323 return *this; 376 return *this;
324} 377}
325 378
326/*! 379/*!
327 Deep copy. Dereference the current array and obtains a copy of the data 380 Deep copy. Dereference the current array and obtains a copy of the data
328 contained in \a a instead. Returns a reference to this array. 381 contained in \a a instead. Returns a reference to this array.
@@ -361,13 +414,17 @@ QGArray &QGArray::duplicate( const QGArray &a )
361 Q_CHECK_PTR( shd->data ); 414 Q_CHECK_PTR( shd->data );
362 if ( shd->data ) 415 if ( shd->data )
363 memcpy( shd->data, a.shd->data, a.shd->len ); 416 memcpy( shd->data, a.shd->data, a.shd->len );
364 } else { 417 } else {
365 shd->data = 0; 418 shd->data = 0;
366 } 419 }
367 shd->len = a.shd->len; 420 shd->len =
421#ifdef QT_QGARRAY_SPEED_OPTIM
422 shd->maxl =
423#endif
424 a.shd->len;
368 if ( oldptr ) 425 if ( oldptr )
369 DELETE(oldptr); 426 DELETE(oldptr);
370 return *this; 427 return *this;
371} 428}
372 429
373/*! 430/*!
@@ -399,13 +456,17 @@ QGArray &QGArray::duplicate( const char *d, uint len )
399 Q_CHECK_PTR( shd ); 456 Q_CHECK_PTR( shd );
400 } else { // just a single reference 457 } else { // just a single reference
401 if ( shd->data ) 458 if ( shd->data )
402 DELETE(shd->data); 459 DELETE(shd->data);
403 } 460 }
404 shd->data = data; 461 shd->data = data;
405 shd->len = len; 462 shd->len =
463#ifdef QT_QGARRAY_SPEED_OPTIM
464 shd->maxl =
465#endif
466 len;
406 return *this; 467 return *this;
407} 468}
408 469
409/*! 470/*!
410 Resizes this array to \a len bytes and copies the \a len bytes at 471 Resizes this array to \a len bytes and copies the \a len bytes at
411 address \a d into it. 472 address \a d into it.
@@ -656,13 +717,14 @@ void QGArray::sort( uint sz )
656{ 717{
657 int numItems = size() / sz; 718 int numItems = size() / sz;
658 if ( numItems < 2 ) 719 if ( numItems < 2 )
659 return; 720 return;
660 721
661#ifdef QT_THREAD_SUPPORT 722#ifdef QT_THREAD_SUPPORT
662 QMutexLocker locker( qt_global_mutexpool->get( &cmp_item_size ) ); 723 QMutexLocker locker( qt_global_mutexpool ?
724 qt_global_mutexpool->get( &cmp_item_size ) : 0 );
663#endif // QT_THREAD_SUPPORT 725#endif // QT_THREAD_SUPPORT
664 726
665 cmp_item_size = sz; 727 cmp_item_size = sz;
666 qsort( shd->data, numItems, sz, cmp_arr ); 728 qsort( shd->data, numItems, sz, cmp_arr );
667} 729}
668 730
@@ -674,13 +736,14 @@ int QGArray::bsearch( const char *d, uint sz ) const
674{ 736{
675 int numItems = size() / sz; 737 int numItems = size() / sz;
676 if ( !numItems ) 738 if ( !numItems )
677 return -1; 739 return -1;
678 740
679#ifdef QT_THREAD_SUPPORT 741#ifdef QT_THREAD_SUPPORT
680 QMutexLocker locker( qt_global_mutexpool->get( &cmp_item_size ) ); 742 QMutexLocker locker( qt_global_mutexpool ?
743 qt_global_mutexpool->get( &cmp_item_size ) : 0 );
681#endif // QT_THREAD_SUPPORT 744#endif // QT_THREAD_SUPPORT
682 745
683 cmp_item_size = sz; 746 cmp_item_size = sz;
684 char* r = (char*)::bsearch( d, shd->data, numItems, sz, cmp_arr ); 747 char* r = (char*)::bsearch( d, shd->data, numItems, sz, cmp_arr );
685 if ( !r ) 748 if ( !r )
686 return -1; 749 return -1;
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
@@ -201,13 +201,16 @@ QGDict::QGDict( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
201 init( len, kt, caseSensitive, copyKeys ); 201 init( len, kt, caseSensitive, copyKeys );
202} 202}
203 203
204 204
205void QGDict::init( uint len, KeyType kt, bool caseSensitive, bool copyKeys ) 205void QGDict::init( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
206{ 206{
207 vec = new QBaseBucket *[vlen = len]; // allocate hash table 207 vlen = len;
208 if ( vlen == 0 )
209 vlen = 17;
210 vec = new QBaseBucket *[vlen];
208 Q_CHECK_PTR( vec ); 211 Q_CHECK_PTR( vec );
209 memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) ); 212 memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) );
210 numItems = 0; 213 numItems = 0;
211 iterators = 0; 214 iterators = 0;
212 // The caseSensitive and copyKey options don't make sense for 215 // The caseSensitive and copyKey options don't make sense for
213 // all dict types. 216 // all dict types.
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
@@ -326,18 +326,14 @@ QLNode *QGList::locate( uint index )
326 curIndex = 0; 326 curIndex = 0;
327 } 327 }
328 register QLNode *node; 328 register QLNode *node;
329 int distance = index - curIndex; // node distance to cur node 329 int distance = index - curIndex; // node distance to cur node
330 bool forward; // direction to traverse 330 bool forward; // direction to traverse
331 331
332 if ( index >= numNodes ) { 332 if ( index >= numNodes )
333#if defined(QT_CHECK_RANGE)
334 qWarning( "QGList::locate: Index %d out of range", index );
335#endif
336 return 0; 333 return 0;
337 }
338 334
339 if ( distance < 0 ) 335 if ( distance < 0 )
340 distance = -distance; 336 distance = -distance;
341 if ( (uint)distance < index && (uint)distance < numNodes - index ) { 337 if ( (uint)distance < index && (uint)distance < numNodes - index ) {
342 node = curNode; // start from current node 338 node = curNode; // start from current node
343 forward = index > (uint)curIndex; 339 forward = index > (uint)curIndex;
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
@@ -146,13 +146,34 @@ bool qSysInfo( int *wordSize, bool *bigEndian )
146 146
147 *bigEndian = si_bigEndian = be32; 147 *bigEndian = si_bigEndian = be32;
148 si_alreadyDone = TRUE; 148 si_alreadyDone = TRUE;
149 return TRUE; 149 return TRUE;
150} 150}
151 151
152#if defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN) 152#if !defined(QWS) && defined(Q_OS_MAC)
153
154#include "qt_mac.h"
155
156int qMacVersion()
157{
158 static int macver = Qt::MV_Unknown;
159 static bool first = TRUE;
160 if(first) {
161 first = FALSE;
162 long gestalt_version;
163 if(Gestalt(gestaltSystemVersion, &gestalt_version) == noErr) {
164 if(gestalt_version >= 0x1020 && gestalt_version < 0x1030)
165 macver = Qt::MV_10_DOT_2;
166 else if(gestalt_version >= 0x1010 && gestalt_version < 0x1020)
167 macver = Qt::MV_10_DOT_1;
168 }
169 }
170 return macver;
171}
172Qt::MacintoshVersion qt_macver = (Qt::MacintoshVersion)qMacVersion();
173#elif defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN)
153bool qt_winunicode; 174bool qt_winunicode;
154 175
155#include "qt_windows.h" 176#include "qt_windows.h"
156 177
157int qWinVersion() 178int qWinVersion()
158{ 179{
@@ -318,13 +339,25 @@ Qt::WindowsVersion qt_winver = (Qt::WindowsVersion)qWinVersion();
318 339
319 static QtMsgHandler handler = 0; // pointer to debug handler 340 static QtMsgHandler handler = 0; // pointer to debug handler
320 static const int QT_BUFFER_LENGTH = 8196;// internal buffer length 341 static const int QT_BUFFER_LENGTH = 8196;// internal buffer length
321 342
322 343
323#ifdef Q_OS_MAC 344#ifdef Q_OS_MAC
324const unsigned char * p_str(const char * c, int len=-1) 345QString cfstring2qstring(CFStringRef str)
346{
347 CFIndex length = CFStringGetLength(str);
348 if(const UniChar *chars = CFStringGetCharactersPtr(str))
349 return QString((QChar *)chars, length);
350 UniChar *buffer = (UniChar*)malloc(length * sizeof(UniChar));
351 CFStringGetCharacters(str, CFRangeMake(0, length), buffer);
352 QString ret((QChar *)buffer, length);
353 free(buffer);
354 return ret;
355}
356
357unsigned char * p_str(const char * c, int len=-1)
325{ 358{
326 const int maxlen = 255; 359 const int maxlen = 255;
327 if(len == -1) 360 if(len == -1)
328 len = qstrlen(c); 361 len = qstrlen(c);
329 if(len > maxlen) { 362 if(len > maxlen) {
330 qWarning( "p_str len must never exceed %d", maxlen ); 363 qWarning( "p_str len must never exceed %d", maxlen );
@@ -334,13 +367,13 @@ const unsigned char * p_str(const char * c, int len=-1)
334 *ret=len; 367 *ret=len;
335 memcpy(((char *)ret)+1,c,len); 368 memcpy(((char *)ret)+1,c,len);
336 *(ret+len+1) = '\0'; 369 *(ret+len+1) = '\0';
337 return ret; 370 return ret;
338} 371}
339 372
340const unsigned char * p_str(const QString &s) 373unsigned char * p_str(const QString &s)
341{ 374{
342 return p_str(s, s.length()); 375 return p_str(s, s.length());
343} 376}
344 377
345QCString p2qstring(const unsigned char *c) { 378QCString p2qstring(const unsigned char *c) {
346 char *arr = (char *)malloc(c[0] + 1); 379 char *arr = (char *)malloc(c[0] + 1);
@@ -638,24 +671,24 @@ void qSystemWarning( const char* msg, int code )
638 671
639/*! 672/*!
640 \fn void Q_CHECK_PTR( void *p ) 673 \fn void Q_CHECK_PTR( void *p )
641 674
642 \relates QApplication 675 \relates QApplication
643 676
644 If \a p is null, a fatal messages says that the program ran out of 677 If \a p is 0, a fatal messages says that the program ran out of
645 memory and exits. If \e p is not null, nothing happens. 678 memory and exits. If \e p is not 0, nothing happens.
646 679
647 This is really a macro defined in \c qglobal.h. 680 This is really a macro defined in \c qglobal.h.
648 681
649 Example: 682 Example:
650 \code 683 \code
651 int *a; 684 int *a;
652 685
653 Q_CHECK_PTR( a = new int[80] ); // WRONG! 686 Q_CHECK_PTR( a = new int[80] ); // WRONG!
654 687
655 a = new int[80]; // Right 688 a = new (nothrow) int[80]; // Right
656 Q_CHECK_PTR( a ); 689 Q_CHECK_PTR( a );
657 \endcode 690 \endcode
658 691
659 \sa qFatal(), \link debug.html Debugging\endlink 692 \sa qFatal(), \link debug.html Debugging\endlink
660*/ 693*/
661 694
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
@@ -1,12 +1,12 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$ 2** $Id$
3** 3**
4** Implementation of QGPluginManager class 4** Implementation of QGPluginManager class
5** 5**
6** Copyright (C) 2000-2001 Trolltech AS. All rights reserved. 6** Copyright (C) 2000-2003 Trolltech AS. All rights reserved.
7** 7**
8** This file is part of the tools module of the Qt GUI Toolkit. 8** This file is part of the tools module of the Qt GUI Toolkit.
9** 9**
10** This file may be distributed under the terms of the Q Public License 10** This file may be distributed under the terms of the Q Public License
11** as defined by Trolltech AS of Norway and appearing in the file 11** as defined by Trolltech AS of Norway and appearing in the file
12** LICENSE.QPL included in the packaging of this file. 12** LICENSE.QPL included in the packaging of this file.
@@ -472,13 +472,13 @@ bool QGPluginManager::addLibrary( QLibrary* lib )
472 if ( fliFace ) 472 if ( fliFace )
473 // Map all found features to the library 473 // Map all found features to the library
474 fl = fliFace->featureList(); 474 fl = fliFace->featureList();
475 else if ( cpiFace ) 475 else if ( cpiFace )
476 fl << cpiFace->name(); 476 fl << cpiFace->name();
477 477
478 for ( QStringList::Iterator f = fl.begin(); f != fl.end(); f++ ) { 478 for ( QStringList::Iterator f = fl.begin(); f != fl.end(); ++f ) {
479 QLibrary *old = plugDict[*f]; 479 QLibrary *old = plugDict[*f];
480 if ( !old ) { 480 if ( !old ) {
481 useful = TRUE; 481 useful = TRUE;
482 plugDict.replace( *f, plugin ); 482 plugDict.replace( *f, plugin );
483 } else { 483 } else {
484 // we have old *and* plugin, which one to pick? 484 // we have old *and* plugin, which one to pick?
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
@@ -32,12 +32,18 @@
32** 32**
33** Contact info@trolltech.com if any conditions of this licensing are 33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you. 34** not clear to you.
35** 35**
36**********************************************************************/ 36**********************************************************************/
37 37
38#include "qglobal.h"
39#if defined(Q_CC_BOR)
40// needed for qsort() because of a std namespace problem on Borland
41#include "qplatformdefs.h"
42#endif
43
38 #define QGVECTOR_CPP 44 #define QGVECTOR_CPP
39#include "qgvector.h" 45#include "qgvector.h"
40#include "qglist.h" 46#include "qglist.h"
41#include "qstring.h" 47#include "qstring.h"
42#include "qdatastream.h" 48#include "qdatastream.h"
43#include <stdlib.h> 49#include <stdlib.h>
@@ -390,13 +396,14 @@ void QGVector::sort() // sort vector
390 } else { 396 } else {
391 break; 397 break;
392 } 398 }
393 } 399 }
394 400
395#ifdef QT_THREAD_SUPPORT 401#ifdef QT_THREAD_SUPPORT
396 QMutexLocker locker( qt_global_mutexpool->get( &sort_vec ) ); 402 QMutexLocker locker( qt_global_mutexpool ?
403 qt_global_mutexpool->get( &sort_vec ) : 0 );
397#endif // QT_THREAD_SUPPORT 404#endif // QT_THREAD_SUPPORT
398 405
399 sort_vec = (QGVector*)this; 406 sort_vec = (QGVector*)this;
400 qsort( vec, count(), sizeof(Item), cmp_vec ); 407 qsort( vec, count(), sizeof(Item), cmp_vec );
401 sort_vec = 0; 408 sort_vec = 0;
402} 409}
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
@@ -1,14 +1,14 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$ 2** $Id$
3** 3**
4** Implementation of QLibrary class 4** Implementation of QLibrary class
5** 5**
6** Created : 2000-01-01 6** Created : 000101
7** 7**
8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 8** Copyright (C) 2000-2003 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the tools module of the Qt GUI Toolkit. 10** This file is part of the tools module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file 13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file. 14** LICENSE.QPL included in the packaging of this file.
@@ -68,13 +68,13 @@ QLibraryPrivate::QLibraryPrivate( QLibrary *lib )
68/*! 68/*!
69 \class QLibrary qlibrary.h 69 \class QLibrary qlibrary.h
70 \reentrant 70 \reentrant
71 \brief The QLibrary class provides a wrapper for handling shared libraries. 71 \brief The QLibrary class provides a wrapper for handling shared libraries.
72 72
73 \mainclass 73 \mainclass
74 \group plugins 74 \ingroup plugins
75 75
76 An instance of a QLibrary object can handle a single shared 76 An instance of a QLibrary object can handle a single shared
77 library and provide access to the functionality in the library in 77 library and provide access to the functionality in the library in
78 a platform independent way. If the library is a component server, 78 a platform independent way. If the library is a component server,
79 QLibrary provides access to the exported component and can 79 QLibrary provides access to the exported component and can
80 directly query this component for interfaces. 80 directly query this component for interfaces.
@@ -323,20 +323,21 @@ QString QLibrary::library() const
323 if ( filename.findRev( '.' ) <= filename.findRev( '/' ) ) 323 if ( filename.findRev( '.' ) <= filename.findRev( '/' ) )
324 filename += ".dll"; 324 filename += ".dll";
325#elif defined(Q_OS_MACX) 325#elif defined(Q_OS_MACX)
326 if ( filename.find( ".dylib" ) == -1 ) 326 if ( filename.find( ".dylib" ) == -1 )
327 filename += ".dylib"; 327 filename += ".dylib";
328#else 328#else
329 if ( filename.find( ".so" ) == -1 ) { 329 QString filter = ".so";
330 if ( filename.find(filter) == -1 ) {
330 const int x = filename.findRev( "/" ); 331 const int x = filename.findRev( "/" );
331 if ( x != -1 ) { 332 if ( x != -1 ) {
332 QString path = filename.left( x + 1 ); 333 QString path = filename.left( x + 1 );
333 QString file = filename.right( filename.length() - x - 1 ); 334 QString file = filename.right( filename.length() - x - 1 );
334 filename = QString( "%1lib%2.so" ).arg( path ).arg( file ); 335 filename = QString( "%1lib%2.%3" ).arg( path ).arg( file ).arg( filter );
335 } else { 336 } else {
336 filename = QString( "lib%1.so" ).arg( filename ); 337 filename = QString( "lib%1.%2" ).arg( filename ).arg( filter );
337 } 338 }
338 } 339 }
339#endif 340#endif
340 341
341 return filename; 342 return filename;
342} 343}
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
@@ -1,12 +1,12 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$ 2** $Id$
3** 3**
4** Implementation of QLibraryPrivate class 4** Implementation of QLibraryPrivate class
5** 5**
6** Created : 2000-01-01 6** Created : 000101
7** 7**
8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the tools module of the Qt GUI Toolkit. 10** This file is part of the tools module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 12** This file may be distributed under the terms of the Q Public License
@@ -50,13 +50,30 @@
50 - freeLibrary 50 - freeLibrary
51 - resolveSymbol 51 - resolveSymbol
52 52
53 It's not too hard to guess what the functions do. 53 It's not too hard to guess what the functions do.
54*/ 54*/
55 55
56#if defined(QT_HPUX_LD) // for HP-UX < 11.x and 32 bit 56#if defined(Q_OS_MAC)
57
58bool QLibraryPrivate::loadLibrary()
59{
60 return FALSE;
61}
62
63bool QLibraryPrivate::freeLibrary()
64{
65 return FALSE;
66}
67
68void* QLibraryPrivate::resolveSymbol( const char* )
69{
70 return 0;
71}
72
73#elif defined(QT_HPUX_LD) // for HP-UX < 11.x and 32 bit
57 74
58bool QLibraryPrivate::loadLibrary() 75bool QLibraryPrivate::loadLibrary()
59{ 76{
60 if ( pHnd ) 77 if ( pHnd )
61 return TRUE; 78 return TRUE;
62 79
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
@@ -40,14 +40,15 @@
40#include "qplatformdefs.h" 40#include "qplatformdefs.h"
41 41
42typedef pthread_mutex_t Q_MUTEX_T; 42typedef pthread_mutex_t Q_MUTEX_T;
43 43
44// POSIX threads mutex types 44// POSIX threads mutex types
45#if ((defined(PTHREAD_MUTEX_RECURSIVE) && defined(PTHREAD_MUTEX_DEFAULT)) || \ 45#if ((defined(PTHREAD_MUTEX_RECURSIVE) && defined(PTHREAD_MUTEX_DEFAULT)) || \
46 defined(Q_OS_FREEBSD)) && !defined(Q_OS_UNIXWARE) && !defined(Q_OS_SOLARIS) 46 defined(Q_OS_FREEBSD)) && !defined(Q_OS_UNIXWARE) && !defined(Q_OS_SOLARIS) && \
47 // POSIX 1003.1c-1995 - We love this OS 47 !defined(Q_OS_MAC)
48// POSIX 1003.1c-1995 - We love this OS
48# define Q_MUTEX_SET_TYPE(a, b) pthread_mutexattr_settype((a), (b)) 49# define Q_MUTEX_SET_TYPE(a, b) pthread_mutexattr_settype((a), (b))
49# if defined(QT_CHECK_RANGE) 50# if defined(QT_CHECK_RANGE)
50# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK 51# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK
51# else 52# else
52# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT 53# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT
53# endif 54# endif
@@ -658,13 +659,14 @@ bool QMutex::tryLock()
658*/ 659*/
659 660
660/*! 661/*!
661 \fn QMutexLocker::QMutexLocker( QMutex *mutex ) 662 \fn QMutexLocker::QMutexLocker( QMutex *mutex )
662 663
663 Constructs a QMutexLocker and locks \a mutex. The mutex will be 664 Constructs a QMutexLocker and locks \a mutex. The mutex will be
664 unlocked when the QMutexLocker is destroyed. 665 unlocked when the QMutexLocker is destroyed. If \a mutex is zero,
666 QMutexLocker does nothing.
665 667
666 \sa QMutex::lock() 668 \sa QMutex::lock()
667*/ 669*/
668 670
669/*! 671/*!
670 \fn QMutexLocker::~QMutexLocker() 672 \fn QMutexLocker::~QMutexLocker()
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,30 +1,49 @@
1/****************************************************************************
2** $Id$
3**
4** ...
5**
6** Copyright (C) 2002 Trolltech AS. All rights reserved.
7**
8** This file is part of the tools module of the Qt GUI Toolkit.
9**
10** This file may be distributed under the terms of the Q Public License
11** as defined by Trolltech AS of Norway and appearing in the file
12** LICENSE.QPL included in the packaging of this file.
13**
14** This file may be distributed and/or modified under the terms of the
15** GNU General Public License version 2 as published by the Free Software
16** Foundation and appearing in the file LICENSE.GPL included in the
17** packaging of this file.
18**
19** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
20** licenses may use this file in accordance with the Qt Commercial License
21** Agreement provided with the Software.
22**
23** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
24** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25**
26** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
27** information about Qt Commercial License Agreements.
28** See http://www.trolltech.com/qpl/ for QPL licensing information.
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
1#include "qmutexpool_p.h" 36#include "qmutexpool_p.h"
2 37
3#ifdef QT_THREAD_SUPPORT 38#ifdef QT_THREAD_SUPPORT
4 39
5#include <qthread.h> 40#include <qthread.h>
6#include <stdio.h>
7 41
8QMutexPool *qt_global_mutexpool = 0; 42QMutexPool *qt_global_mutexpool = 0;
9 43
10// this is an internal class used only for inititalizing the global mutexpool
11class QGlobalMutexPoolInitializer
12{
13public:
14 inline QGlobalMutexPoolInitializer()
15 {
16 /*
17 Purify will report a leak here. However, this mutex pool must be alive
18 until *everything* in Qt has been destructed. Unfortunately there is
19 no way to guarantee this, so we never destroy this mutex pool.
20 */
21 qt_global_mutexpool = new QMutexPool( TRUE );
22 }
23};
24QGlobalMutexPoolInitializer qt_global_mutexpool_initializer;
25 44
26/*! 45/*!
27 \class QMutexPool qmutexpool_p.h 46 \class QMutexPool qmutexpool_p.h
28 \brief The QMutexPool class provides a pool of QMutex objects. 47 \brief The QMutexPool class provides a pool of QMutex objects.
29 48
30 \internal 49 \internal
@@ -82,49 +101,52 @@ QGlobalMutexPoolInitializer qt_global_mutexpool_initializer;
82 mutexes; otherwise they will all be non-recursive (the default). 101 mutexes; otherwise they will all be non-recursive (the default).
83 102
84 The QMutexes are created when needed, and deleted when the 103 The QMutexes are created when needed, and deleted when the
85 QMutexPool is destructed. 104 QMutexPool is destructed.
86*/ 105*/
87QMutexPool::QMutexPool( bool recursive, int size ) 106QMutexPool::QMutexPool( bool recursive, int size )
88 : mutex( FALSE ), mutexes( size ), recurs( recursive ) 107 : mutex( FALSE ), count( size ), recurs( recursive )
89{ 108{
90 mutexes.fill( 0 ); 109 mutexes = new QMutex*[count];
110 for ( int index = 0; index < count; ++index ) {
111 mutexes[index] = 0;
112 }
91} 113}
92 114
93/*! 115/*!
94 Destructs a QMutexPool. All QMutexes that were created by the pool 116 Destructs a QMutexPool. All QMutexes that were created by the pool
95 are deleted. 117 are deleted.
96*/ 118*/
97QMutexPool::~QMutexPool() 119QMutexPool::~QMutexPool()
98{ 120{
99 QMutexLocker locker( &mutex ); 121 QMutexLocker locker( &mutex );
100 QMutex **d = mutexes.data(); 122 for ( int index = 0; index < count; ++index ) {
101 for ( int index = 0; (uint) index < mutexes.size(); index++ ) { 123 delete mutexes[index];
102 delete d[index]; 124 mutexes[index] = 0;
103 d[index] = 0;
104 } 125 }
126 delete [] mutexes;
127 mutexes = 0;
105} 128}
106 129
107/*! 130/*!
108 Returns a QMutex from the pool. QMutexPool uses the value \a 131 Returns a QMutex from the pool. QMutexPool uses the value \a
109 address to determine which mutex is retured from the pool. 132 address to determine which mutex is retured from the pool.
110*/ 133*/
111QMutex *QMutexPool::get( void *address ) 134QMutex *QMutexPool::get( void *address )
112{ 135{
113 QMutex **d = mutexes.data(); 136 int index = (int) ( (unsigned long) address % count );
114 int index = (int)( (ulong) address % mutexes.size() );
115 137
116 if ( ! d[index] ) { 138 if ( ! mutexes[index] ) {
117 // mutex not created, create one 139 // mutex not created, create one
118 140
119 QMutexLocker locker( &mutex ); 141 QMutexLocker locker( &mutex );
120 // we need to check once again that the mutex hasn't been created, since 142 // we need to check once again that the mutex hasn't been created, since
121 // 2 threads could be trying to create a mutex as the same index... 143 // 2 threads could be trying to create a mutex as the same index...
122 if ( ! d[index] ) { 144 if ( ! mutexes[index] ) {
123 d[index] = new QMutex( recurs ); 145 mutexes[index] = new QMutex( recurs );
124 } 146 }
125 } 147 }
126 148
127 return d[index]; 149 return mutexes[index];
128} 150}
129 151
130#endif 152#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
@@ -260,21 +260,21 @@
260 hexadecimal number hhhh (between 0x0000 and 0xFFFF). \0ooo 260 hexadecimal number hhhh (between 0x0000 and 0xFFFF). \0ooo
261 (i.e., \zero ooo) matches the ASCII/Latin-1 character 261 (i.e., \zero ooo) matches the ASCII/Latin-1 character
262 corresponding to the octal number ooo (between 0 and 0377). 262 corresponding to the octal number ooo (between 0 and 0377).
263 \row \i <b>. (dot)</b> 263 \row \i <b>. (dot)</b>
264 \i This matches any character (including newline). 264 \i This matches any character (including newline).
265 \row \i <b>\\d</b> 265 \row \i <b>\\d</b>
266 \i This matches a digit (see QChar::isDigit()). 266 \i This matches a digit (QChar::isDigit()).
267 \row \i <b>\\D</b> 267 \row \i <b>\\D</b>
268 \i This matches a non-digit. 268 \i This matches a non-digit.
269 \row \i <b>\\s</b> 269 \row \i <b>\\s</b>
270 \i This matches a whitespace (see QChar::isSpace()). 270 \i This matches a whitespace (QChar::isSpace()).
271 \row \i <b>\\S</b> 271 \row \i <b>\\S</b>
272 \i This matches a non-whitespace. 272 \i This matches a non-whitespace.
273 \row \i <b>\\w</b> 273 \row \i <b>\\w</b>
274 \i This matches a word character (see QChar::isLetterOrNumber()). 274 \i This matches a word character (QChar::isLetterOrNumber() or '_').
275 \row \i <b>\\W</b> 275 \row \i <b>\\W</b>
276 \i This matches a non-word character. 276 \i This matches a non-word character.
277 \row \i <b>\\n</b> 277 \row \i <b>\\n</b>
278 \i The n-th \link #capturing-text backreference \endlink, 278 \i The n-th \link #capturing-text backreference \endlink,
279 e.g. \1, \2, etc. 279 e.g. \1, \2, etc.
280 \endtable 280 \endtable
@@ -544,13 +544,20 @@
544 ... correspond to cap(1) or capturedTexts()[1], cap(2) or 544 ... correspond to cap(1) or capturedTexts()[1], cap(2) or
545 capturedTexts()[2], etc. 545 capturedTexts()[2], etc.
546 546
547 To substitute a pattern use QString::replace(). 547 To substitute a pattern use QString::replace().
548 548
549 Perl's extended \c{/x} syntax is not supported, nor are 549 Perl's extended \c{/x} syntax is not supported, nor are
550 regexp comments (?#comment) or directives, e.g. (?i). 550 directives, e.g. (?i), or regexp comments, e.g. (?#comment). On
551 the other hand, C++'s rules for literal strings can be used to
552 achieve the same:
553 \code
554 QRegExp mark( "\\b" // word boundary
555 "[Mm]ark" // the word we want to match
556 );
557 \endcode
551 558
552 Both zero-width positive and zero-width negative lookahead 559 Both zero-width positive and zero-width negative lookahead
553 assertions (?=pattern) and (?!pattern) are supported with the same 560 assertions (?=pattern) and (?!pattern) are supported with the same
554 syntax as Perl. Perl's lookbehind assertions, "independent" 561 syntax as Perl. Perl's lookbehind assertions, "independent"
555 subexpressions and conditional expressions are not supported. 562 subexpressions and conditional expressions are not supported.
556 563
@@ -674,17 +681,17 @@
674 681
675 Here field[0] is the company, field[1] the web address and so on. 682 Here field[0] is the company, field[1] the web address and so on.
676 683
677 To imitate the matching of a shell we can use wildcard mode. 684 To imitate the matching of a shell we can use wildcard mode.
678 685
679 \code 686 \code
680 QRegExp rx( "*.html" ); // invalid regexp: * doesn't quantify anything 687 QRegExp rx( "*.html" ); // invalid regexp: * doesn't quantify anything
681 rx.setWildcard( TRUE ); // now it's a valid wildcard regexp 688 rx.setWildcard( TRUE ); // now it's a valid wildcard regexp
682 rx.search( "index.html" ); // returns 0 (matched at position 0) 689 rx.exactMatch( "index.html" ); // returns TRUE
683 rx.search( "default.htm" ); // returns -1 (no match) 690 rx.exactMatch( "default.htm" ); // returns FALSE
684 rx.search( "readme.txt" ); // returns -1 (no match) 691 rx.exactMatch( "readme.txt" ); // returns FALSE
685 \endcode 692 \endcode
686 693
687 Wildcard matching can be convenient because of its simplicity, but 694 Wildcard matching can be convenient because of its simplicity, but
688 any wildcard regexp can be defined using full regexps, e.g. 695 any wildcard regexp can be defined using full regexps, e.g.
689 <b>.*\.html$</b>. Notice that we can't match both \c .html and \c 696 <b>.*\.html$</b>. Notice that we can't match both \c .html and \c
690 .htm files with a wildcard unless we use <b>*.htm*</b> which will 697 .htm files with a wildcard unless we use <b>*.htm*</b> which will
@@ -712,12 +719,17 @@ const int NumBadChars = 64;
712const int NoOccurrence = INT_MAX; 719const int NoOccurrence = INT_MAX;
713const int EmptyCapture = INT_MAX; 720const int EmptyCapture = INT_MAX;
714const int InftyLen = INT_MAX; 721const int InftyLen = INT_MAX;
715const int InftyRep = 1025; 722const int InftyRep = 1025;
716const int EOS = -1; 723const int EOS = -1;
717 724
725static bool isWord( QChar ch )
726{
727 return ch.isLetterOrNumber() || ch == QChar( '_' );
728}
729
718/* 730/*
719 Merges two QMemArrays of ints and puts the result into the first one. 731 Merges two QMemArrays of ints and puts the result into the first one.
720*/ 732*/
721static void mergeInto( QMemArray<int> *a, const QMemArray<int>& b ) 733static void mergeInto( QMemArray<int> *a, const QMemArray<int>& b )
722{ 734{
723 int asize = a->size(); 735 int asize = a->size();
@@ -1677,15 +1689,15 @@ bool QRegExpEngine::testAnchor( int i, int a, const int *capBegin )
1677 } 1689 }
1678#ifndef QT_NO_REGEXP_ESCAPE 1690#ifndef QT_NO_REGEXP_ESCAPE
1679 if ( (a & (Anchor_Word | Anchor_NonWord)) != 0 ) { 1691 if ( (a & (Anchor_Word | Anchor_NonWord)) != 0 ) {
1680 bool before = FALSE; 1692 bool before = FALSE;
1681 bool after = FALSE; 1693 bool after = FALSE;
1682 if ( mmPos + i != 0 ) 1694 if ( mmPos + i != 0 )
1683 before = mmIn[mmPos + i - 1].isLetterOrNumber(); 1695 before = isWord( mmIn[mmPos + i - 1] );
1684 if ( mmPos + i != mmLen ) 1696 if ( mmPos + i != mmLen )
1685 after = mmIn[mmPos + i].isLetterOrNumber(); 1697 after = isWord( mmIn[mmPos + i] );
1686 if ( (a & Anchor_Word) != 0 && (before == after) ) 1698 if ( (a & Anchor_Word) != 0 && (before == after) )
1687 return FALSE; 1699 return FALSE;
1688 if ( (a & Anchor_NonWord) != 0 && (before != after) ) 1700 if ( (a & Anchor_NonWord) != 0 && (before != after) )
1689 return FALSE; 1701 return FALSE;
1690 } 1702 }
1691#endif 1703#endif
@@ -2629,13 +2641,20 @@ int QRegExpEngine::getEscape()
2629 yyCharClass->addRange( 0x0000, 0x0008 ); 2641 yyCharClass->addRange( 0x0000, 0x0008 );
2630 yyCharClass->addRange( 0x000e, 0x001f ); 2642 yyCharClass->addRange( 0x000e, 0x001f );
2631 yyCharClass->addRange( 0x007f, 0x009f ); 2643 yyCharClass->addRange( 0x007f, 0x009f );
2632 return Tok_CharClass; 2644 return Tok_CharClass;
2633 case 'W': 2645 case 'W':
2634 // see QChar::isLetterOrNumber() 2646 // see QChar::isLetterOrNumber()
2635 yyCharClass->addCategories( 0x7ff07f8f ); 2647 yyCharClass->addCategories( 0x7fe07f8f );
2648 yyCharClass->addRange( 0x203f, 0x2040 );
2649 yyCharClass->addSingleton( 0x2040 );
2650 yyCharClass->addSingleton( 0x30fb );
2651 yyCharClass->addRange( 0xfe33, 0xfe34 );
2652 yyCharClass->addRange( 0xfe4d, 0xfe4f );
2653 yyCharClass->addSingleton( 0xff3f );
2654 yyCharClass->addSingleton( 0xff65 );
2636 return Tok_CharClass; 2655 return Tok_CharClass;
2637#endif 2656#endif
2638#ifndef QT_NO_REGEXP_ESCAPE 2657#ifndef QT_NO_REGEXP_ESCAPE
2639 case 'b': 2658 case 'b':
2640 return Tok_Word; 2659 return Tok_Word;
2641#endif 2660#endif
@@ -2649,12 +2668,13 @@ int QRegExpEngine::getEscape()
2649 yyCharClass->addCategories( 0x00000380 ); 2668 yyCharClass->addCategories( 0x00000380 );
2650 yyCharClass->addRange( 0x0009, 0x000d ); 2669 yyCharClass->addRange( 0x0009, 0x000d );
2651 return Tok_CharClass; 2670 return Tok_CharClass;
2652 case 'w': 2671 case 'w':
2653 // see QChar::isLetterOrNumber() 2672 // see QChar::isLetterOrNumber()
2654 yyCharClass->addCategories( 0x000f8070 ); 2673 yyCharClass->addCategories( 0x000f8070 );
2674 yyCharClass->addSingleton( 0x005f ); // '_'
2655 return Tok_CharClass; 2675 return Tok_CharClass;
2656#endif 2676#endif
2657#ifndef QT_NO_REGEXP_ESCAPE 2677#ifndef QT_NO_REGEXP_ESCAPE
2658 case 'x': 2678 case 'x':
2659 val = 0; 2679 val = 0;
2660 for ( i = 0; i < 4; i++ ) { 2680 for ( i = 0; i < 4; i++ ) {
@@ -3180,13 +3200,14 @@ static QSingleCleanupHandler<QCache<QRegExpEngine> > cleanup_cache;
3180 3200
3181static QRegExpEngine *newEngine( const QString& pattern, bool caseSensitive ) 3201static QRegExpEngine *newEngine( const QString& pattern, bool caseSensitive )
3182{ 3202{
3183#ifndef QT_NO_REGEXP_OPTIM 3203#ifndef QT_NO_REGEXP_OPTIM
3184 if ( engineCache != 0 ) { 3204 if ( engineCache != 0 ) {
3185#ifdef QT_THREAD_SUPPORT 3205#ifdef QT_THREAD_SUPPORT
3186 QMutexLocker locker( qt_global_mutexpool->get( &engineCache ) ); 3206 QMutexLocker locker( qt_global_mutexpool ?
3207 qt_global_mutexpool->get( &engineCache ) : 0 );
3187#endif 3208#endif
3188 QRegExpEngine *eng = engineCache->take( pattern ); 3209 QRegExpEngine *eng = engineCache->take( pattern );
3189 if ( eng == 0 || eng->caseSensitive() != caseSensitive ) { 3210 if ( eng == 0 || eng->caseSensitive() != caseSensitive ) {
3190 delete eng; 3211 delete eng;
3191 } else { 3212 } else {
3192 eng->ref(); 3213 eng->ref();
@@ -3196,17 +3217,18 @@ static QRegExpEngine *newEngine( const QString& pattern, bool caseSensitive )
3196#endif 3217#endif
3197 return new QRegExpEngine( pattern, caseSensitive ); 3218 return new QRegExpEngine( pattern, caseSensitive );
3198} 3219}
3199 3220
3200static void derefEngine( QRegExpEngine *eng, const QString& pattern ) 3221static void derefEngine( QRegExpEngine *eng, const QString& pattern )
3201{ 3222{
3202 if ( eng != 0 && eng->deref() ) {
3203#ifndef QT_NO_REGEXP_OPTIM
3204#ifdef QT_THREAD_SUPPORT 3223#ifdef QT_THREAD_SUPPORT
3205 QMutexLocker locker( qt_global_mutexpool->get( &engineCache ) ); 3224 QMutexLocker locker( qt_global_mutexpool ?
3225 qt_global_mutexpool->get( &engineCache ) : 0 );
3206#endif 3226#endif
3227 if ( eng != 0 && eng->deref() ) {
3228#ifndef QT_NO_REGEXP_OPTIM
3207 if ( engineCache == 0 ) { 3229 if ( engineCache == 0 ) {
3208 engineCache = new QCache<QRegExpEngine>; 3230 engineCache = new QCache<QRegExpEngine>;
3209 engineCache->setAutoDelete( TRUE ); 3231 engineCache->setAutoDelete( TRUE );
3210 cleanup_cache.set( &engineCache ); 3232 cleanup_cache.set( &engineCache );
3211 } 3233 }
3212 if ( !pattern.isNull() && 3234 if ( !pattern.isNull() &&
@@ -3562,19 +3584,12 @@ int QRegExp::match( const QString& str, int index, int *len,
3562 if ( len != 0 ) 3584 if ( len != 0 )
3563 *len = matchedLength(); 3585 *len = matchedLength();
3564 return pos; 3586 return pos;
3565} 3587}
3566#endif // QT_NO_COMPAT 3588#endif // QT_NO_COMPAT
3567 3589
3568/*!
3569 \overload
3570
3571 This convenience function searches with a \c CaretMode of \c
3572 CaretAtZero which is the most common usage.
3573*/
3574
3575int QRegExp::search( const QString& str, int offset ) const 3590int QRegExp::search( const QString& str, int offset ) const
3576{ 3591{
3577 return search( str, offset, CaretAtZero ); 3592 return search( str, offset, CaretAtZero );
3578} 3593}
3579 3594
3580/*! 3595/*!
@@ -3622,19 +3637,12 @@ int QRegExp::search( const QString& str, int offset, CaretMode caretMode ) const
3622 priv->captured = eng->match( str, offset, priv->min, FALSE, 3637 priv->captured = eng->match( str, offset, priv->min, FALSE,
3623 caretIndex(offset, caretMode) ); 3638 caretIndex(offset, caretMode) );
3624 return priv->captured[0]; 3639 return priv->captured[0];
3625} 3640}
3626 3641
3627 3642
3628/*!
3629 \overload
3630
3631 This convenience function searches with a \c CaretMode of \c
3632 CaretAtZero which is the most common usage.
3633*/
3634
3635int QRegExp::searchRev( const QString& str, int offset ) const 3643int QRegExp::searchRev( const QString& str, int offset ) const
3636{ 3644{
3637 return searchRev( str, offset, CaretAtZero ); 3645 return searchRev( str, offset, CaretAtZero );
3638} 3646}
3639 3647
3640/*! 3648/*!
@@ -3691,13 +3699,13 @@ int QRegExp::searchRev( const QString& str, int offset,
3691int QRegExp::matchedLength() const 3699int QRegExp::matchedLength() const
3692{ 3700{
3693 return priv->captured[1]; 3701 return priv->captured[1];
3694} 3702}
3695 3703
3696#ifndef QT_NO_REGEXP_CAPTURE 3704#ifndef QT_NO_REGEXP_CAPTURE
3697/*! 3705/*!
3698 Returns the number of captures contained in the regular expression. 3706 Returns the number of captures contained in the regular expression.
3699 */ 3707 */
3700int QRegExp::numCaptures() const 3708int QRegExp::numCaptures() const
3701{ 3709{
3702 return eng->numCaptures(); 3710 return eng->numCaptures();
3703} 3711}
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
@@ -180,24 +180,23 @@ int QSemaphore::operator--(int)
180int QSemaphore::operator+=(int n) 180int QSemaphore::operator+=(int n)
181{ 181{
182 int ret; 182 int ret;
183 183
184 d->mutex.lock(); 184 d->mutex.lock();
185 185
186 if ( n < 0 || n > d->max ) {
187#ifdef QT_CHECK_RANGE
188 qWarning( "QSemaphore::operator+=: paramter %d out of range", n );
189#endif // QT_CHECK_RANGE
190 n = n < 0 ? 0 : d->max;
191 }
192
186 while (d->value + n > d->max) 193 while (d->value + n > d->max)
187 d->cond.wait(&(d->mutex)); 194 d->cond.wait(&(d->mutex));
188 195
189 d->value += n; 196 d->value += n;
190
191#ifdef QT_CHECK_RANGE
192 if (d->value > d->max) {
193 qWarning("QSemaphore::operator+=: attempt to allocate more resources than available");
194 d->value = d->max;
195 }
196#endif
197
198 ret = d->value; 197 ret = d->value;
199 198
200 d->mutex.unlock(); 199 d->mutex.unlock();
201 200
202 return ret; 201 return ret;
203} 202}
@@ -209,21 +208,20 @@ int QSemaphore::operator+=(int n)
209int QSemaphore::operator-=(int n) 208int QSemaphore::operator-=(int n)
210{ 209{
211 int ret; 210 int ret;
212 211
213 d->mutex.lock(); 212 d->mutex.lock();
214 213
215 d->value -= n; 214 if ( n < 0 || n > d->value ) {
216
217#ifdef QT_CHECK_RANGE 215#ifdef QT_CHECK_RANGE
218 if (d->value < 0) { 216 qWarning( "QSemaphore::operator-=: paramter %d out of range", n );
219 qWarning("QSemaphore::operator-=: attempt to deallocate more resources than taken"); 217#endif // QT_CHECK_RANGE
220 d->value = 0; 218 n = n < 0 ? 0 : d->value;
221 } 219 }
222#endif
223 220
221 d->value -= n;
224 ret = d->value; 222 ret = d->value;
225 223
226 d->cond.wakeOne(); 224 d->cond.wakeOne();
227 d->mutex.unlock(); 225 d->mutex.unlock();
228 226
229 return ret; 227 return ret;
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
@@ -1,12 +1,12 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$ 2** $Id$
3** 3**
4** Implementation of QSettings class 4** Implementation of QSettings class
5** 5**
6** Created: 2000.06.26 6** Created : 000626
7** 7**
8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the tools module of the Qt GUI Toolkit. 10** This file is part of the tools module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 12** This file may be distributed under the terms of the Q Public License
@@ -60,35 +60,35 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode )
60#include "qtextstream.h" 60#include "qtextstream.h"
61#include "qregexp.h" 61#include "qregexp.h"
62#include <private/qsettings_p.h> 62#include <private/qsettings_p.h>
63#include <errno.h> 63#include <errno.h>
64 64
65/*! 65/*!
66 \class QSettings 66 \class QSettings
67 \brief The QSettings class provides persistent platform-independent application settings. 67 \brief The QSettings class provides persistent platform-independent application settings.
68 68
69 \ingroup io 69 \ingroup io
70 \ingroup misc 70 \ingroup misc
71 \mainclass 71 \mainclass
72 72
73 On Unix systems, QSettings uses text files to store settings. On Windows 73 On Unix systems, QSettings uses text files to store settings. On Windows
74 systems, QSettings uses the system registry. On Mac OS X, QSettings will 74 systems, QSettings uses the system registry. On Mac OS X, QSettings uses
75 behave as on Unix, and store to text files. 75 the Carbon preferences API.
76 76
77 Each setting comprises an identifying key and the data associated with 77 Each setting comprises an identifying key and the data associated with
78 the key. A key is a unicode string which consists of \e two or more 78 the key. A key is a unicode string which consists of \e two or more
79 subkeys. A subkey is a slash, '/', followed by one or more unicode 79 subkeys. A subkey is a slash, '/', followed by one or more unicode
80 characters (excluding slashes, newlines, carriage returns and equals, 80 characters (excluding slashes, newlines, carriage returns and equals,
81 '=', signs). The associated data, called the entry or value, may be a 81 '=', signs). The associated data, called the entry or value, may be a
82 boolean, an integer, a double, a string or a list of strings. Entry 82 boolean, an integer, a double, a string or a list of strings. Entry
83 strings may contain any unicode characters. 83 strings may contain any unicode characters.
84 84
85 If you want to save and restore the entire desktop's settings, i.e. 85 If you want to save and restore the entire desktop's settings, i.e.
86 which applications are running, use QSettings to save the settings 86 which applications are running, use QSettings to save the settings
87 for each individual application and QSessionManager to save the 87 for each individual application and QSessionManager to save the
88 desktop's session. 88 desktop's session.
89 89
90 Example settings: 90 Example settings:
91 \code 91 \code
92 /MyCompany/MyApplication/background color 92 /MyCompany/MyApplication/background color
93 /MyCompany/MyApplication/foreground color 93 /MyCompany/MyApplication/foreground color
94 /MyCompany/MyApplication/geometry/x 94 /MyCompany/MyApplication/geometry/x
@@ -98,33 +98,48 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode )
98 /MyCompany/MyApplication/recent files/1 98 /MyCompany/MyApplication/recent files/1
99 /MyCompany/MyApplication/recent files/2 99 /MyCompany/MyApplication/recent files/2
100 /MyCompany/MyApplication/recent files/3 100 /MyCompany/MyApplication/recent files/3
101 \endcode 101 \endcode
102 Each line above is a complete key, made up of subkeys. 102 Each line above is a complete key, made up of subkeys.
103 103
104 A typical usage pattern for application startup: 104 A typical usage pattern for reading application startup:
105 \code 105 \code
106 QSettings settings; 106 QSettings settings;
107 settings.insertSearchPath( QSettings::Windows, "/MyCompany" ); 107 settings.setPath( "MyCompany.com", "MyApplication" );
108 // No search path needed for Unix; see notes further on. 108
109 // Use default values if the keys don't exist 109 QString bgColor = settings.readEntry( "/colors/background", "white" );
110 QString bgColor = settings.readEntry( "/MyApplication/background color", "white" ); 110 int width = settings.readNumEntry( "/geometry/width", 640 );
111 int width = settings.readNumEntry( "/MyApplication/geometry/width", 640 );
112 // ... 111 // ...
113 \endcode 112 \endcode
114 113
115 A typical usage pattern for application exit or 'save preferences': 114 A typical usage pattern for application exit or 'save preferences':
116 \code 115 \code
117 QSettings settings; 116 QSettings settings;
118 settings.insertSearchPath( QSettings::Windows, "/MyCompany" ); 117 settings.setPath( "MyCompany.com", "MyApplication" );
119 // No search path needed for Unix; see notes further on. 118
120 settings.writeEntry( "/MyApplication/background color", bgColor ); 119 settings.writeEntry( "/colors/background", bgColor );
121 settings.writeEntry( "/MyApplication/geometry/width", width ); 120 settings.writeEntry( "/geometry/width", width );
122 // ... 121 // ...
123 \endcode 122 \endcode
124 123
124 QSettings can build a key prefix that is prepended to all keys. To
125 build the key prefix, use beginGroup() and endGroup().
126 \code
127 QSettings settings;
128
129 settings.beginGroup( "/MainWindow" );
130 settings.beginGroup( "/Geometry" );
131 int x = settings.readEntry( "/x" );
132 // ...
133 settings.endGroup();
134 settings.beginGroup( "/Toolbars" );
135 // ...
136 settings.endGroup();
137 settings.endGroup();
138 \endcode
139
125 You can get a list of entry-holding keys by calling entryList(), and 140 You can get a list of entry-holding keys by calling entryList(), and
126 a list of key-holding keys using subkeyList(). 141 a list of key-holding keys using subkeyList().
127 142
128 \code 143 \code
129 QStringList keys = entryList( "/MyApplication" ); 144 QStringList keys = entryList( "/MyApplication" );
130 // keys contains 'background color' and 'foreground color'. 145 // keys contains 'background color' and 'foreground color'.
@@ -136,26 +151,40 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode )
136 // subkeys contains 'geometry' and 'recent files' 151 // subkeys contains 'geometry' and 'recent files'
137 152
138 QStringList subkeys = subkeyList( "/MyApplication/recent files" ); 153 QStringList subkeys = subkeyList( "/MyApplication/recent files" );
139 // subkeys is empty. 154 // subkeys is empty.
140 \endcode 155 \endcode
141 156
142 If you wish to use a different search path call insertSearchPath()
143 as often as necessary to add your preferred paths. Call
144 removeSearchPath() to remove any unwanted paths.
145
146 Since settings for Windows are stored in the registry there are size 157 Since settings for Windows are stored in the registry there are size
147 limits as follows: 158 limits as follows:
148 \list 159 \list
149 \i A subkey may not exceed 255 characters. 160 \i A subkey may not exceed 255 characters.
150 \i An entry's value may not exceed 16,300 characters. 161 \i An entry's value may not exceed 16,300 characters.
151 \i All the values of a key (for example, all the 'recent files' 162 \i All the values of a key (for example, all the 'recent files'
152 subkeys values), may not exceed 65,535 characters. 163 subkeys values), may not exceed 65,535 characters.
153 \endlist 164 \endlist
154 165
155 These limitations are not enforced on Unix. 166 These limitations are not enforced on Unix or Mac OS X.
167
168 If you wish to use a different search path call insertSearchPath()
169 as often as necessary to add your preferred paths. Call
170 removeSearchPath() to remove any unwanted paths.
171
172 \section1 Notes for Mac OS X Applications
173
174 Internal to the CFPreferences API it is not defined (for Mac OS 9
175 support) where the settings will ultimitely be stored. However, at the
176 time of this writing the settings will be stored (either on a global or
177 user basis, preferring locally) into a plist file in
178 $ROOT/System/Library/Preferences (in XML format). QSettings will create
179 an appropriate plist file (com.<first group name>.plist) out of the
180 full path to a key.
181
182 For further information on CFPreferences see also
183 \link http://developer.apple.com/techpubs/macosx/CoreFoundation/PreferenceServices/preferenceservices_carbon.html
184 Apple's Specifications\endlink
156 185
157 \section1 Notes for Unix Applications 186 \section1 Notes for Unix Applications
158 187
159 There is no universally accepted place for storing application 188 There is no universally accepted place for storing application
160 settings under Unix. In the examples the settings file will be 189 settings under Unix. In the examples the settings file will be
161 searched for in the following directories: 190 searched for in the following directories:
@@ -297,26 +326,26 @@ static HANDLE openlock( const QString &name, int /*type*/ )
297 QT_WA( { 326 QT_WA( {
298 fd = CreateFileW( (TCHAR*)name.ucs2(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 327 fd = CreateFileW( (TCHAR*)name.ucs2(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
299 } , { 328 } , {
300 fd = CreateFileA( name.local8Bit(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 329 fd = CreateFileA( name.local8Bit(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
301 } ); 330 } );
302 331
303 if ( !LockFile( fd, 0, 0, -1, -1 ) ) { 332 if ( !LockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ???
304#ifdef QT_CHECK_STATE 333#ifdef QT_CHECK_STATE
305 qWarning( "QSettings: openlock failed!" ); 334 qWarning( "QSettings: openlock failed!" );
306#endif 335#endif
307 } 336 }
308 return fd; 337 return fd;
309} 338}
310 339
311void closelock( HANDLE fd ) 340static void closelock( HANDLE fd )
312{ 341{
313 if ( !fd ) 342 if ( !fd )
314 return; 343 return;
315 344
316 if ( !UnlockFile( fd, 0, 0, -1, -1 ) ) { 345 if ( !UnlockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ???
317#ifdef QT_CHECK_STATE 346#ifdef QT_CHECK_STATE
318 qWarning( "QSettings: closelock failed!"); 347 qWarning( "QSettings: closelock failed!");
319#endif 348#endif
320 } 349 }
321 CloseHandle( fd ); 350 CloseHandle( fd );
322} 351}
@@ -452,15 +481,17 @@ void QSettingsHeading::parseLine(QTextStream &stream)
452 481
453#endif 482#endif
454 483
455QSettingsPrivate::QSettingsPrivate( QSettings::Format format ) 484QSettingsPrivate::QSettingsPrivate( QSettings::Format format )
456 : groupDirty( TRUE ), modified(FALSE), globalScope(TRUE) 485 : groupDirty( TRUE ), modified(FALSE), globalScope(TRUE)
457{ 486{
458#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 487#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
459 if ( format != QSettings::Ini ) 488 if ( format != QSettings::Ini )
460 return; 489 return;
490#else
491 Q_UNUSED( format );
461#endif 492#endif
462 493
463 QString appSettings(QDir::homeDirPath() + "/.qt/"); 494 QString appSettings(QDir::homeDirPath() + "/.qt/");
464 QString defPath; 495 QString defPath;
465#ifdef Q_WS_WIN 496#ifdef Q_WS_WIN
466#ifdef Q_OS_TEMP 497#ifdef Q_OS_TEMP
@@ -503,12 +534,14 @@ QSettingsPrivate::QSettingsPrivate( QSettings::Format format )
503#endif 534#endif
504 QDir dir(appSettings); 535 QDir dir(appSettings);
505 if (! dir.exists()) { 536 if (! dir.exists()) {
506 if (! dir.mkdir(dir.path())) 537 if (! dir.mkdir(dir.path()))
507#if defined(QT_CHECK_STATE) 538#if defined(QT_CHECK_STATE)
508 qWarning("QSettings: error creating %s", dir.path().latin1()); 539 qWarning("QSettings: error creating %s", dir.path().latin1());
540#else
541 ;
509#endif 542#endif
510 } 543 }
511 544
512 if ( !!defPath ) 545 if ( !!defPath )
513 searchPaths.append(defPath); 546 searchPaths.append(defPath);
514 searchPaths.append(dir.path()); 547 searchPaths.append(dir.path());
@@ -527,12 +560,14 @@ QSettingsGroup QSettingsPrivate::readGroup()
527 if (headingsit != headings.end()) 560 if (headingsit != headings.end())
528 hd = *headingsit; 561 hd = *headingsit;
529 562
530 QSettingsHeading::Iterator grpit = hd.find(group); 563 QSettingsHeading::Iterator grpit = hd.find(group);
531 if (grpit == hd.end()) { 564 if (grpit == hd.end()) {
532 QStringList::Iterator it = searchPaths.begin(); 565 QStringList::Iterator it = searchPaths.begin();
566 if ( !globalScope )
567 ++it;
533 while (it != searchPaths.end()) { 568 while (it != searchPaths.end()) {
534 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); 569 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
535 QString fn((*it++) + "/" + filebase + "rc"); 570 QString fn((*it++) + "/" + filebase + "rc");
536 if (! hd.contains(fn + "cached")) { 571 if (! hd.contains(fn + "cached")) {
537 hd.read(fn); 572 hd.read(fn);
538 hd.insert(fn + "cached", QSettingsGroup()); 573 hd.insert(fn + "cached", QSettingsGroup());
@@ -561,12 +596,14 @@ void QSettingsPrivate::removeGroup(const QString &key)
561 if (headingsit != headings.end()) 596 if (headingsit != headings.end())
562 hd = *headingsit; 597 hd = *headingsit;
563 598
564 QSettingsHeading::Iterator grpit = hd.find(group); 599 QSettingsHeading::Iterator grpit = hd.find(group);
565 if (grpit == hd.end()) { 600 if (grpit == hd.end()) {
566 QStringList::Iterator it = searchPaths.begin(); 601 QStringList::Iterator it = searchPaths.begin();
602 if ( !globalScope )
603 ++it;
567 while (it != searchPaths.end()) { 604 while (it != searchPaths.end()) {
568 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); 605 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
569 QString fn((*it++) + "/" + filebase + "rc"); 606 QString fn((*it++) + "/" + filebase + "rc");
570 if (! hd.contains(fn + "cached")) { 607 if (! hd.contains(fn + "cached")) {
571 hd.read(fn); 608 hd.read(fn);
572 hd.insert(fn + "cached", QSettingsGroup()); 609 hd.insert(fn + "cached", QSettingsGroup());
@@ -612,12 +649,14 @@ void QSettingsPrivate::writeGroup(const QString &key, const QString &value)
612 if (headingsit != headings.end()) 649 if (headingsit != headings.end())
613 hd = *headingsit; 650 hd = *headingsit;
614 651
615 QSettingsHeading::Iterator grpit = hd.find(group); 652 QSettingsHeading::Iterator grpit = hd.find(group);
616 if (grpit == hd.end()) { 653 if (grpit == hd.end()) {
617 QStringList::Iterator it = searchPaths.begin(); 654 QStringList::Iterator it = searchPaths.begin();
655 if ( !globalScope )
656 ++it;
618 while (it != searchPaths.end()) { 657 while (it != searchPaths.end()) {
619 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); 658 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
620 QString fn((*it++) + "/" + filebase + "rc"); 659 QString fn((*it++) + "/" + filebase + "rc");
621 if (! hd.contains(fn + "cached")) { 660 if (! hd.contains(fn + "cached")) {
622 hd.read(fn); 661 hd.read(fn);
623 hd.insert(fn + "cached", QSettingsGroup()); 662 hd.insert(fn + "cached", QSettingsGroup());
@@ -646,32 +685,40 @@ QDateTime QSettingsPrivate::modificationTime()
646 QSettingsHeading hd = headings[heading]; 685 QSettingsHeading hd = headings[heading];
647 QSettingsGroup grp = hd[group]; 686 QSettingsGroup grp = hd[group];
648 687
649 QDateTime datetime; 688 QDateTime datetime;
650 689
651 QStringList::Iterator it = searchPaths.begin(); 690 QStringList::Iterator it = searchPaths.begin();
691 if ( !globalScope )
692 ++it;
652 while (it != searchPaths.end()) { 693 while (it != searchPaths.end()) {
653 QFileInfo fi((*it++) + "/" + heading + "rc"); 694 QFileInfo fi((*it++) + "/" + heading + "rc");
654 if (fi.exists() && fi.lastModified() > datetime) 695 if (fi.exists() && fi.lastModified() > datetime)
655 datetime = fi.lastModified(); 696 datetime = fi.lastModified();
656 } 697 }
657 698
658 return datetime; 699 return datetime;
659} 700}
660 701
661static bool verifyKey( const QString &key ) 702bool qt_verify_key( const QString &key )
662{ 703{
663 if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\\\r\\\\n" ) ) ) 704 if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\\\r\\\\n" ) ) )
664 return FALSE; 705 return FALSE;
665 return TRUE; 706 return TRUE;
666} 707}
667 708
668static inline QString groupKey( const QString &group, const QString &key ) 709static inline QString groupKey( const QString &group, const QString &key )
669{ 710{
670 if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) 711 if ( group.isEmpty() || ( group.length() == 1 && group[0] == '/' ) ) {
712 // group is empty, or it contains a single '/', so we just return the key
713 if ( key.startsWith( "/" ) )
714 return key;
715 return "/" + key;
716 } else if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) {
671 return group + key; 717 return group + key;
718 }
672 return group + "/" + key; 719 return group + "/" + key;
673} 720}
674 721
675/*! 722/*!
676 Inserts \a path into the settings search path. The semantics of \a 723 Inserts \a path into the settings search path. The semantics of \a
677 path depends on the system \a s. 724 path depends on the system \a s.
@@ -683,13 +730,13 @@ static inline QString groupKey( const QString &group, const QString &key )
683 When \a s is \e Windows, and the execution environment is Windows, the 730 When \a s is \e Windows, and the execution environment is Windows, the
684 search path list will be used as the first subfolder of the "Software" 731 search path list will be used as the first subfolder of the "Software"
685 folder in the registry. 732 folder in the registry.
686 733
687 When reading settings the folders are searched forwards from the 734 When reading settings the folders are searched forwards from the
688 first folder (listed below) to the last, returning the first 735 first folder (listed below) to the last, returning the first
689 settings found, and ignoring any folders for which the user doesn't 736 settings found, and ignoring any folders for which the user doesn't
690 have read permission. 737 have read permission.
691 \list 1 738 \list 1
692 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication 739 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication
693 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication 740 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication
694 \i HKEY_CURRENT_USER/Software/MyApplication 741 \i HKEY_CURRENT_USER/Software/MyApplication
695 \i HKEY_LOCAL_MACHINE/Software/MyApplication 742 \i HKEY_LOCAL_MACHINE/Software/MyApplication
@@ -707,13 +754,13 @@ static inline QString groupKey( const QString &group, const QString &key )
707 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication 754 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication
708 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication 755 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication
709 \i HKEY_LOCAL_MACHINE/Software/MyApplication 756 \i HKEY_LOCAL_MACHINE/Software/MyApplication
710 \i HKEY_CURRENT_USER/Software/MyApplication 757 \i HKEY_CURRENT_USER/Software/MyApplication
711 \endlist 758 \endlist
712 If a setting is found in the HKEY_CURRENT_USER space, this setting 759 If a setting is found in the HKEY_CURRENT_USER space, this setting
713 is overwritten independently of write permissions in the 760 is overwritten independently of write permissions in the
714 HKEY_LOCAL_MACHINE space. 761 HKEY_LOCAL_MACHINE space.
715 762
716 When \a s is \e Unix, and the execution environment is Unix, the 763 When \a s is \e Unix, and the execution environment is Unix, the
717 search path list will be used when trying to determine a suitable 764 search path list will be used when trying to determine a suitable
718 filename for reading and writing settings files. By default, there are 765 filename for reading and writing settings files. By default, there are
719 two entries in the search path: 766 two entries in the search path:
@@ -754,40 +801,55 @@ static inline QString groupKey( const QString &group, const QString &key )
754 801
755 \sa removeSearchPath() 802 \sa removeSearchPath()
756 803
757*/ 804*/
758void QSettings::insertSearchPath( System s, const QString &path) 805void QSettings::insertSearchPath( System s, const QString &path)
759{ 806{
760#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 807#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
761 if ( d->sysd ) { 808 if ( d->sysd ) {
762 d->sysInsertSearchPath( s, path ); 809 d->sysInsertSearchPath( s, path );
763 return; 810 return;
764 } 811 }
765#endif 812#endif
766 813
767 if ( !verifyKey( path ) ) { 814#if !defined(Q_WS_WIN)
815 if ( s == Windows )
816 return;
817#endif
818#if !defined(Q_WS_WIN)
819 if ( s == Mac )
820 return;
821#endif
822
823 if ( !qt_verify_key( path ) ) {
768#if defined(QT_CHECK_STATE) 824#if defined(QT_CHECK_STATE)
769 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); 825 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );
770#endif 826#endif
771 return; 827 return;
772 } 828 }
773 829
774#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 830#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
775 if ( d->sysd && s != Unix ) { 831 if ( d->sysd && s != Unix ) {
776#else 832#else
777 if ( s != Unix ) { 833 if ( s != Unix ) {
778#endif 834#endif
779#ifdef Q_OS_MAC 835#if !defined(QWS) && defined(Q_OS_MAC)
780 if(s != Mac) //mac is respected on the mac as well 836 if(s != Mac) //mac is respected on the mac as well
781#endif 837#endif
782 return; 838 return;
783 } 839 }
784 840
841 QString realPath = path;
842#if defined(Q_WS_WIN)
843 QString defPath = d->globalScope ? d->searchPaths.first() : d->searchPaths.last();
844 realPath = defPath + path;
845#endif
846
785 QStringList::Iterator it = d->searchPaths.find(d->searchPaths.last()); 847 QStringList::Iterator it = d->searchPaths.find(d->searchPaths.last());
786 if (it != d->searchPaths.end()) { 848 if (it != d->searchPaths.end()) {
787 d->searchPaths.insert(it, path); 849 d->searchPaths.insert(it, realPath);
788 } 850 }
789} 851}
790 852
791 853
792/*! 854/*!
793 Removes all occurrences of \a path (using exact matching) from the 855 Removes all occurrences of \a path (using exact matching) from the
@@ -795,31 +857,31 @@ void QSettings::insertSearchPath( System s, const QString &path)
795 paths cannot be removed. 857 paths cannot be removed.
796 858
797 \sa insertSearchPath() 859 \sa insertSearchPath()
798*/ 860*/
799void QSettings::removeSearchPath( System s, const QString &path) 861void QSettings::removeSearchPath( System s, const QString &path)
800{ 862{
801 if ( !verifyKey( path ) ) { 863 if ( !qt_verify_key( path ) ) {
802#if defined(QT_CHECK_STATE) 864#if defined(QT_CHECK_STATE)
803 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); 865 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );
804#endif 866#endif
805 return; 867 return;
806 } 868 }
807 869
808#ifdef Q_WS_WIN 870#ifdef Q_WS_WIN
809 if ( d->sysd ) { 871 if ( d->sysd ) {
810 d->sysRemoveSearchPath( s, path ); 872 d->sysRemoveSearchPath( s, path );
811 return; 873 return;
812 } 874 }
813#endif 875#endif
814#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 876#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
815 if ( d->sysd && s != Unix ) { 877 if ( d->sysd && s != Unix ) {
816#else 878#else
817 if ( s != Unix ) { 879 if ( s != Unix ) {
818#endif 880#endif
819#ifdef Q_OS_MAC 881#if !defined(QWS) && defined(Q_OS_MAC)
820 if(s != Mac) //mac is respected on the mac as well 882 if(s != Mac) //mac is respected on the mac as well
821#endif 883#endif
822 return; 884 return;
823 } 885 }
824 886
825 if (path == d->searchPaths.first() || path == d->searchPaths.last()) 887 if (path == d->searchPaths.first() || path == d->searchPaths.last())
@@ -834,13 +896,13 @@ void QSettings::removeSearchPath( System s, const QString &path)
834*/ 896*/
835QSettings::QSettings() 897QSettings::QSettings()
836{ 898{
837 d = new QSettingsPrivate( Native ); 899 d = new QSettingsPrivate( Native );
838 Q_CHECK_PTR(d); 900 Q_CHECK_PTR(d);
839 901
840#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 902#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
841 d->sysd = 0; 903 d->sysd = 0;
842 d->sysInit(); 904 d->sysInit();
843#endif 905#endif
844} 906}
845 907
846/*! 908/*!
@@ -851,13 +913,13 @@ QSettings::QSettings()
851*/ 913*/
852QSettings::QSettings( Format format ) 914QSettings::QSettings( Format format )
853{ 915{
854 d = new QSettingsPrivate( format ); 916 d = new QSettingsPrivate( format );
855 Q_CHECK_PTR(d); 917 Q_CHECK_PTR(d);
856 918
857#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 919#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
858 d->sysd = 0; 920 d->sysd = 0;
859 if ( format == Native ) 921 if ( format == Native )
860 d->sysInit(); 922 d->sysInit();
861#else 923#else
862 Q_UNUSED(format); 924 Q_UNUSED(format);
863#endif 925#endif
@@ -869,13 +931,13 @@ QSettings::QSettings( Format format )
869 931
870*/ 932*/
871QSettings::~QSettings() 933QSettings::~QSettings()
872{ 934{
873 sync(); 935 sync();
874 936
875#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 937#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
876 if ( d->sysd ) 938 if ( d->sysd )
877 d->sysClear(); 939 d->sysClear();
878#endif 940#endif
879 941
880 delete d; 942 delete d;
881} 943}
@@ -884,13 +946,13 @@ QSettings::~QSettings()
884/*! \internal 946/*! \internal
885 Writes all modifications to the settings to disk. If any errors are 947 Writes all modifications to the settings to disk. If any errors are
886 encountered, this function returns FALSE, otherwise it will return TRUE. 948 encountered, this function returns FALSE, otherwise it will return TRUE.
887*/ 949*/
888bool QSettings::sync() 950bool QSettings::sync()
889{ 951{
890#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 952#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
891 if ( d->sysd ) 953 if ( d->sysd )
892 return d->sysSync(); 954 return d->sysSync();
893#endif 955#endif
894 if (! d->modified) 956 if (! d->modified)
895 // fake success 957 // fake success
896 return TRUE; 958 return TRUE;
@@ -902,27 +964,29 @@ bool QSettings::sync()
902 // determine filename 964 // determine filename
903 QSettingsHeading hd(*it); 965 QSettingsHeading hd(*it);
904 QSettingsHeading::Iterator hdit = hd.begin(); 966 QSettingsHeading::Iterator hdit = hd.begin();
905 QFile file; 967 QFile file;
906 968
907 QStringList::Iterator pit = d->searchPaths.begin(); 969 QStringList::Iterator pit = d->searchPaths.begin();
970 if ( !d->globalScope )
971 ++pit;
908 while (pit != d->searchPaths.end()) { 972 while (pit != d->searchPaths.end()) {
909 QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_"); 973 QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_");
910 QFileInfo di(*pit); 974 QFileInfo di(*pit);
911 QFileInfo fi((*pit++) + "/" + filebase + "rc"); 975 QFileInfo fi((*pit++) + "/" + filebase + "rc");
912 976
913 if ((fi.exists() && fi.isFile() && fi.isWritable()) || 977 if ((fi.exists() && fi.isFile() && fi.isWritable()) ||
914 (! fi.exists() && di.isDir() && di.isWritable())) { 978 (! fi.exists() && di.isDir() && di.isWritable())) {
915 file.setName(fi.filePath()); 979 file.setName(fi.filePath());
916 break; 980 break;
917 } 981 }
918 } 982 }
919 983
920 it++; 984 ++it;
921 985
922 if (file.name().isNull() || file.name().isEmpty()) { 986 if ( file.name().isEmpty() ) {
923 987
924#ifdef QT_CHECK_STATE 988#ifdef QT_CHECK_STATE
925 qWarning("QSettings::sync: filename is null/empty"); 989 qWarning("QSettings::sync: filename is null/empty");
926#endif // QT_CHECK_STATE 990#endif // QT_CHECK_STATE
927 991
928 success = FALSE; 992 success = FALSE;
@@ -960,19 +1024,19 @@ bool QSettings::sync()
960 } else { 1024 } else {
961 v.replace("\\", "\\\\"); // escape backslash 1025 v.replace("\\", "\\\\"); // escape backslash
962 v.replace("\n", "\\n"); // escape newlines 1026 v.replace("\n", "\\n"); // escape newlines
963 } 1027 }
964 1028
965 stream << grpit.key() << "=" << v << endl; 1029 stream << grpit.key() << "=" << v << endl;
966 grpit++; 1030 ++grpit;
967 } 1031 }
968 1032
969 stream << endl; 1033 stream << endl;
970 } 1034 }
971 1035
972 hdit++; 1036 ++hdit;
973 } 1037 }
974 1038
975 if (file.status() != IO_Ok) { 1039 if (file.status() != IO_Ok) {
976 1040
977#ifdef QT_CHECK_STATE 1041#ifdef QT_CHECK_STATE
978 qWarning("QSettings::sync: error at end of write"); 1042 qWarning("QSettings::sync: error at end of write");
@@ -1005,29 +1069,28 @@ bool QSettings::sync()
1005 1069
1006/*! 1070/*!
1007 \internal 1071 \internal
1008*/ 1072*/
1009bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) 1073bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok )
1010{ 1074{
1011 if ( !verifyKey( key ) ) { 1075 if ( !qt_verify_key( key ) ) {
1012#if defined(QT_CHECK_STATE) 1076#if defined(QT_CHECK_STATE)
1013 qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1077 qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1014#endif 1078#endif
1015 if ( ok ) 1079 if ( ok )
1016 *ok = FALSE; 1080 *ok = FALSE;
1017 1081
1018 return def; 1082 return def;
1019 } 1083 }
1020 1084
1021 QString theKey = groupKey( group(), key ); 1085#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1022#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1023 if ( d->sysd ) 1086 if ( d->sysd )
1024 return d->sysReadBoolEntry( theKey, def, ok ); 1087 return d->sysReadBoolEntry( groupKey( group(), key ), def, ok );
1025#endif 1088#endif
1026 1089
1027 QString value = readEntry( theKey, ( def ? "true" : "false" ), ok ); 1090 QString value = readEntry( key, ( def ? "true" : "false" ), ok );
1028 1091
1029 if (value.lower() == "true") 1092 if (value.lower() == "true")
1030 return TRUE; 1093 return TRUE;
1031 else if (value.lower() == "false") 1094 else if (value.lower() == "false")
1032 return FALSE; 1095 return FALSE;
1033 else if (value == "1") 1096 else if (value == "1")
@@ -1057,29 +1120,28 @@ bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok )
1057 1120
1058/*! 1121/*!
1059 \internal 1122 \internal
1060*/ 1123*/
1061double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) 1124double QSettings::readDoubleEntry(const QString &key, double def, bool *ok )
1062{ 1125{
1063 if ( !verifyKey( key ) ) { 1126 if ( !qt_verify_key( key ) ) {
1064#if defined(QT_CHECK_STATE) 1127#if defined(QT_CHECK_STATE)
1065 qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1128 qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1066#endif 1129#endif
1067 if ( ok ) 1130 if ( ok )
1068 *ok = FALSE; 1131 *ok = FALSE;
1069 1132
1070 return def; 1133 return def;
1071 } 1134 }
1072 1135
1073 QString theKey = groupKey( group(), key ); 1136#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1074#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1075 if ( d->sysd ) 1137 if ( d->sysd )
1076 return d->sysReadDoubleEntry( theKey, def, ok ); 1138 return d->sysReadDoubleEntry( groupKey( group(), key ), def, ok );
1077#endif 1139#endif
1078 1140
1079 QString value = readEntry( theKey, QString::number(def), ok ); 1141 QString value = readEntry( key, QString::number(def), ok );
1080 bool conv_ok; 1142 bool conv_ok;
1081 double retval = value.toDouble( &conv_ok ); 1143 double retval = value.toDouble( &conv_ok );
1082 if ( conv_ok ) 1144 if ( conv_ok )
1083 return retval; 1145 return retval;
1084 if ( ! value.isEmpty() ) 1146 if ( ! value.isEmpty() )
1085 qWarning( "QSettings::readDoubleEntry: '%s' is not a number", 1147 qWarning( "QSettings::readDoubleEntry: '%s' is not a number",
@@ -1103,29 +1165,27 @@ double QSettings::readDoubleEntry(const QString &key, double def, bool *ok )
1103 1165
1104/*! 1166/*!
1105 \internal 1167 \internal
1106*/ 1168*/
1107int QSettings::readNumEntry(const QString &key, int def, bool *ok ) 1169int QSettings::readNumEntry(const QString &key, int def, bool *ok )
1108{ 1170{
1109 if ( !verifyKey( key ) ) { 1171 if ( !qt_verify_key( key ) ) {
1110#if defined(QT_CHECK_STATE) 1172#if defined(QT_CHECK_STATE)
1111 qWarning( "QSettings::readNumEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1173 qWarning( "QSettings::readNumEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1112#endif 1174#endif
1113 if ( ok ) 1175 if ( ok )
1114 *ok = FALSE; 1176 *ok = FALSE;
1115 return def; 1177 return def;
1116 } 1178 }
1117 1179
1118 QString theKey = groupKey( group(), key ); 1180#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1119
1120#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1121 if ( d->sysd ) 1181 if ( d->sysd )
1122 return d->sysReadNumEntry( theKey, def, ok ); 1182 return d->sysReadNumEntry( groupKey( group(), key ), def, ok );
1123#endif 1183#endif
1124 1184
1125 QString value = readEntry( theKey, QString::number( def ), ok ); 1185 QString value = readEntry( key, QString::number( def ), ok );
1126 bool conv_ok; 1186 bool conv_ok;
1127 int retval = value.toInt( &conv_ok ); 1187 int retval = value.toInt( &conv_ok );
1128 if ( conv_ok ) 1188 if ( conv_ok )
1129 return retval; 1189 return retval;
1130 if ( ! value.isEmpty() ) 1190 if ( ! value.isEmpty() )
1131 qWarning( "QSettings::readNumEntry: '%s' is not a number", 1191 qWarning( "QSettings::readNumEntry: '%s' is not a number",
@@ -1149,25 +1209,25 @@ int QSettings::readNumEntry(const QString &key, int def, bool *ok )
1149 1209
1150/*! 1210/*!
1151 \internal 1211 \internal
1152*/ 1212*/
1153QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) 1213QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
1154{ 1214{
1155 if ( !verifyKey( key ) ) { 1215 if ( !qt_verify_key( key ) ) {
1156#if defined(QT_CHECK_STATE) 1216#if defined(QT_CHECK_STATE)
1157 qWarning( "QSettings::readEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1217 qWarning( "QSettings::readEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1158#endif 1218#endif
1159 if ( ok ) 1219 if ( ok )
1160 *ok = FALSE; 1220 *ok = FALSE;
1161 1221
1162 return def; 1222 return def;
1163 } 1223 }
1164 1224
1165 QString theKey = groupKey( group(), key ); 1225 QString theKey = groupKey( group(), key );
1166 1226
1167#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1227#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1168 if ( d->sysd ) 1228 if ( d->sysd )
1169 return d->sysReadEntry( theKey, def, ok ); 1229 return d->sysReadEntry( theKey, def, ok );
1170#endif 1230#endif
1171 1231
1172 if ( ok ) // no, everything is not ok 1232 if ( ok ) // no, everything is not ok
1173 *ok = FALSE; 1233 *ok = FALSE;
@@ -1203,17 +1263,19 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
1203 realkey = list.join("/"); 1263 realkey = list.join("/");
1204 } 1264 }
1205 } else 1265 } else
1206 realkey = theKey; 1266 realkey = theKey;
1207 1267
1208 QSettingsGroup grp = d->readGroup(); 1268 QSettingsGroup grp = d->readGroup();
1209 QString retval = grp[realkey]; 1269 QSettingsGroup::const_iterator it = grp.find( realkey ), end = grp.end();
1210 if ( retval.isNull() ) 1270 QString retval = def;
1211 retval = def; 1271 if ( it != end ) {
1212 else if ( ok ) // everything is ok 1272 // found the value we needed
1213 *ok = TRUE; 1273 retval = *it;
1274 if ( ok ) *ok = TRUE;
1275 }
1214 return retval; 1276 return retval;
1215} 1277}
1216 1278
1217 1279
1218#if !defined(Q_NO_BOOL_TYPE) 1280#if !defined(Q_NO_BOOL_TYPE)
1219/*! 1281/*!
@@ -1225,27 +1287,25 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
1225 returned; otherwise TRUE is returned. 1287 returned; otherwise TRUE is returned.
1226 1288
1227 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1289 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1228*/ 1290*/
1229bool QSettings::writeEntry(const QString &key, bool value) 1291bool QSettings::writeEntry(const QString &key, bool value)
1230{ 1292{
1231 if ( !verifyKey( key ) ) { 1293 if ( !qt_verify_key( key ) ) {
1232#if defined(QT_CHECK_STATE) 1294#if defined(QT_CHECK_STATE)
1233 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1295 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1234#endif 1296#endif
1235 return FALSE; 1297 return FALSE;
1236 } 1298 }
1237 1299
1238 QString theKey = groupKey( group(), key ); 1300#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1239
1240#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1241 if ( d->sysd ) 1301 if ( d->sysd )
1242 return d->sysWriteEntry( theKey, value ); 1302 return d->sysWriteEntry( groupKey( group(), key ), value );
1243#endif 1303#endif
1244 QString s(value ? "true" : "false"); 1304 QString s(value ? "true" : "false");
1245 return writeEntry(theKey, s); 1305 return writeEntry(key, s);
1246} 1306}
1247#endif 1307#endif
1248 1308
1249 1309
1250/*! 1310/*!
1251 \overload 1311 \overload
@@ -1257,27 +1317,25 @@ bool QSettings::writeEntry(const QString &key, bool value)
1257 returned; otherwise TRUE is returned. 1317 returned; otherwise TRUE is returned.
1258 1318
1259 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1319 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1260*/ 1320*/
1261bool QSettings::writeEntry(const QString &key, double value) 1321bool QSettings::writeEntry(const QString &key, double value)
1262{ 1322{
1263 if ( !verifyKey( key ) ) { 1323 if ( !qt_verify_key( key ) ) {
1264#if defined(QT_CHECK_STATE) 1324#if defined(QT_CHECK_STATE)
1265 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1325 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1266#endif 1326#endif
1267 return FALSE; 1327 return FALSE;
1268 } 1328 }
1269 1329
1270 QString theKey = groupKey( group(), key ); 1330#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1271
1272#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1273 if ( d->sysd ) 1331 if ( d->sysd )
1274 return d->sysWriteEntry( theKey, value ); 1332 return d->sysWriteEntry( groupKey( group(), key ), value );
1275#endif 1333#endif
1276 QString s(QString::number(value)); 1334 QString s(QString::number(value));
1277 return writeEntry(theKey, s); 1335 return writeEntry(key, s);
1278} 1336}
1279 1337
1280 1338
1281/*! 1339/*!
1282 \overload 1340 \overload
1283 Writes the integer entry \a value into key \a key. The \a key is 1341 Writes the integer entry \a value into key \a key. The \a key is
@@ -1288,27 +1346,25 @@ bool QSettings::writeEntry(const QString &key, double value)
1288 returned; otherwise TRUE is returned. 1346 returned; otherwise TRUE is returned.
1289 1347
1290 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1348 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1291*/ 1349*/
1292bool QSettings::writeEntry(const QString &key, int value) 1350bool QSettings::writeEntry(const QString &key, int value)
1293{ 1351{
1294 if ( !verifyKey( key ) ) { 1352 if ( !qt_verify_key( key ) ) {
1295#if defined(QT_CHECK_STATE) 1353#if defined(QT_CHECK_STATE)
1296 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1354 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1297#endif 1355#endif
1298 return FALSE; 1356 return FALSE;
1299 } 1357 }
1300 1358
1301 QString theKey = groupKey( group(), key ); 1359#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1302
1303#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1304 if ( d->sysd ) 1360 if ( d->sysd )
1305 return d->sysWriteEntry( theKey, value ); 1361 return d->sysWriteEntry( groupKey( group(), key ), value );
1306#endif 1362#endif
1307 QString s(QString::number(value)); 1363 QString s(QString::number(value));
1308 return writeEntry(theKey, s); 1364 return writeEntry(key, s);
1309} 1365}
1310 1366
1311 1367
1312/*! 1368/*!
1313 \internal 1369 \internal
1314 1370
@@ -1324,22 +1380,20 @@ bool QSettings::writeEntry(const QString &key, int value)
1324 unchanged. 1380 unchanged.
1325 1381
1326 \sa readEntry(), removeEntry() 1382 \sa readEntry(), removeEntry()
1327*/ 1383*/
1328bool QSettings::writeEntry(const QString &key, const char *value) 1384bool QSettings::writeEntry(const QString &key, const char *value)
1329{ 1385{
1330 if ( !verifyKey( key ) ) { 1386 if ( !qt_verify_key( key ) ) {
1331#if defined(QT_CHECK_STATE) 1387#if defined(QT_CHECK_STATE)
1332 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1388 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1333#endif 1389#endif
1334 return FALSE; 1390 return FALSE;
1335 } 1391 }
1336 1392
1337 QString theKey = groupKey( group(), key ); 1393 return writeEntry(key, QString(value));
1338
1339 return writeEntry(theKey, QString(value));
1340} 1394}
1341 1395
1342 1396
1343/*! 1397/*!
1344 \overload 1398 \overload
1345 Writes the string entry \a value into key \a key. The \a key is 1399 Writes the string entry \a value into key \a key. The \a key is
@@ -1351,22 +1405,22 @@ bool QSettings::writeEntry(const QString &key, const char *value)
1351 returned; otherwise TRUE is returned. 1405 returned; otherwise TRUE is returned.
1352 1406
1353 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1407 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1354*/ 1408*/
1355bool QSettings::writeEntry(const QString &key, const QString &value) 1409bool QSettings::writeEntry(const QString &key, const QString &value)
1356{ 1410{
1357 if ( !verifyKey( key ) ) { 1411 if ( !qt_verify_key( key ) ) {
1358#if defined(QT_CHECK_STATE) 1412#if defined(QT_CHECK_STATE)
1359 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1413 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1360#endif 1414#endif
1361 return FALSE; 1415 return FALSE;
1362 } 1416 }
1363 1417
1364 QString theKey = groupKey( group(), key ); 1418 QString theKey = groupKey( group(), key );
1365 1419
1366#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1420#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1367 if ( d->sysd ) 1421 if ( d->sysd )
1368 return d->sysWriteEntry( theKey, value ); 1422 return d->sysWriteEntry( theKey, value );
1369#endif 1423#endif
1370 // NOTE: we *do* allow value to be a null/empty string 1424 // NOTE: we *do* allow value to be a null/empty string
1371 1425
1372 QString realkey; 1426 QString realkey;
@@ -1412,22 +1466,22 @@ bool QSettings::writeEntry(const QString &key, const QString &value)
1412 Returns TRUE if the entry existed and was removed; otherwise returns FALSE. 1466 Returns TRUE if the entry existed and was removed; otherwise returns FALSE.
1413 1467
1414 \sa readEntry(), writeEntry() 1468 \sa readEntry(), writeEntry()
1415*/ 1469*/
1416bool QSettings::removeEntry(const QString &key) 1470bool QSettings::removeEntry(const QString &key)
1417{ 1471{
1418 if ( !verifyKey( key ) ) { 1472 if ( !qt_verify_key( key ) ) {
1419#if defined(QT_CHECK_STATE) 1473#if defined(QT_CHECK_STATE)
1420 qWarning( "QSettings::removeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1474 qWarning( "QSettings::removeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1421#endif 1475#endif
1422 return FALSE; 1476 return FALSE;
1423 } 1477 }
1424 1478
1425 QString theKey = groupKey( group(), key ); 1479 QString theKey = groupKey( group(), key );
1426 1480
1427#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1481#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1428 if ( d->sysd ) 1482 if ( d->sysd )
1429 return d->sysRemoveEntry( theKey ); 1483 return d->sysRemoveEntry( theKey );
1430#endif 1484#endif
1431 1485
1432 QString realkey; 1486 QString realkey;
1433 1487
@@ -1491,22 +1545,22 @@ bool QSettings::removeEntry(const QString &key)
1491 "/MyCompany/MyApplication/geometry/y". 1545 "/MyCompany/MyApplication/geometry/y".
1492 1546
1493 \sa subkeyList() 1547 \sa subkeyList()
1494*/ 1548*/
1495QStringList QSettings::entryList(const QString &key) const 1549QStringList QSettings::entryList(const QString &key) const
1496{ 1550{
1497 if ( !verifyKey( key ) ) { 1551 if ( !qt_verify_key( key ) ) {
1498#if defined(QT_CHECK_STATE) 1552#if defined(QT_CHECK_STATE)
1499 qWarning( "QSettings::entryList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); 1553 qWarning( "QSettings::entryList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() );
1500#endif 1554#endif
1501 return QStringList(); 1555 return QStringList();
1502 } 1556 }
1503 1557
1504 QString theKey = groupKey( group(), key ); 1558 QString theKey = groupKey( group(), key );
1505 1559
1506#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1560#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1507 if ( d->sysd ) 1561 if ( d->sysd )
1508 return d->sysEntryList( theKey ); 1562 return d->sysEntryList( theKey );
1509#endif 1563#endif
1510 1564
1511 QString realkey; 1565 QString realkey;
1512 if (theKey[0] == '/') { 1566 if (theKey[0] == '/') {
@@ -1541,13 +1595,13 @@ QStringList QSettings::entryList(const QString &key) const
1541 QSettingsGroup grp = d->readGroup(); 1595 QSettingsGroup grp = d->readGroup();
1542 QSettingsGroup::Iterator it = grp.begin(); 1596 QSettingsGroup::Iterator it = grp.begin();
1543 QStringList ret; 1597 QStringList ret;
1544 QString itkey; 1598 QString itkey;
1545 while (it != grp.end()) { 1599 while (it != grp.end()) {
1546 itkey = it.key(); 1600 itkey = it.key();
1547 it++; 1601 ++it;
1548 1602
1549 if ( realkey.length() > 0 ) { 1603 if ( realkey.length() > 0 ) {
1550 if ( itkey.left( realkey.length() ) != realkey ) 1604 if ( itkey.left( realkey.length() ) != realkey )
1551 continue; 1605 continue;
1552 else 1606 else
1553 itkey.remove( 0, realkey.length() + 1 ); 1607 itkey.remove( 0, realkey.length() + 1 );
@@ -1588,39 +1642,42 @@ QStringList QSettings::entryList(const QString &key) const
1588 rather than subkeys use entryList(). 1642 rather than subkeys use entryList().
1589 1643
1590 \sa entryList() 1644 \sa entryList()
1591*/ 1645*/
1592QStringList QSettings::subkeyList(const QString &key) const 1646QStringList QSettings::subkeyList(const QString &key) const
1593{ 1647{
1594 if ( !verifyKey( key ) ) { 1648 if ( !qt_verify_key( key ) ) {
1595#if defined(QT_CHECK_STATE) 1649#if defined(QT_CHECK_STATE)
1596 qWarning( "QSettings::subkeyList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); 1650 qWarning( "QSettings::subkeyList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() );
1597#endif 1651#endif
1598 return QStringList(); 1652 return QStringList();
1599 } 1653 }
1600 1654
1601 QString theKey = groupKey( group(), key ); 1655 QString theKey = groupKey( group(), key );
1602 1656
1603#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1657#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1604 if ( d->sysd ) 1658 if ( d->sysd )
1605 return d->sysSubkeyList( theKey ); 1659 return d->sysSubkeyList( theKey );
1606#endif 1660#endif
1607 1661
1608 QString realkey; 1662 QString realkey;
1663 int subkeycount = 2;
1609 if (theKey[0] == '/') { 1664 if (theKey[0] == '/') {
1610 // parse our key 1665 // parse our key
1611 QStringList list(QStringList::split('/', theKey)); 1666 QStringList list(QStringList::split('/', theKey));
1612 1667
1613 if (list.count() < 1) { 1668 if (list.count() < 1) {
1614#ifdef QT_CHECK_STATE 1669#ifdef QT_CHECK_STATE
1615 qWarning("QSettings::subkeyList: invalid key '%s'", theKey.latin1()); 1670 qWarning("QSettings::subkeyList: invalid key '%s'", theKey.latin1());
1616#endif // QT_CHECK_STATE 1671#endif // QT_CHECK_STATE
1617 1672
1618 return QStringList(); 1673 return QStringList();
1619 } 1674 }
1620 1675
1676 subkeycount = list.count();
1677
1621 if (list.count() == 1) { 1678 if (list.count() == 1) {
1622 d->heading = list[0]; 1679 d->heading = list[0];
1623 d->group = "General"; 1680 d->group = "General";
1624 } else { 1681 } else {
1625 d->heading = list[0]; 1682 d->heading = list[0];
1626 d->group = list[1]; 1683 d->group = list[1];
@@ -1629,22 +1686,34 @@ QStringList QSettings::subkeyList(const QString &key) const
1629 list.remove(list.at(1)); 1686 list.remove(list.at(1));
1630 // remove the heading from the list 1687 // remove the heading from the list
1631 list.remove(list.at(0)); 1688 list.remove(list.at(0));
1632 1689
1633 realkey = list.join("/"); 1690 realkey = list.join("/");
1634 } 1691 }
1692
1635 } else 1693 } else
1636 realkey = theKey; 1694 realkey = theKey;
1637 1695
1696 QStringList ret;
1697 if ( subkeycount == 1 ) {
1698 QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin();
1699 while ( it != d->headings.end() ) {
1700 if ( it.key() != "General" && ! ret.contains( it.key() ) )
1701 ret << it.key();
1702 ++it;
1703 }
1704
1705 return ret;
1706 }
1707
1638 QSettingsGroup grp = d->readGroup(); 1708 QSettingsGroup grp = d->readGroup();
1639 QSettingsGroup::Iterator it = grp.begin(); 1709 QSettingsGroup::Iterator it = grp.begin();
1640 QStringList ret;
1641 QString itkey; 1710 QString itkey;
1642 while (it != grp.end()) { 1711 while (it != grp.end()) {
1643 itkey = it.key(); 1712 itkey = it.key();
1644 it++; 1713 ++it;
1645 1714
1646 if ( realkey.length() > 0 ) { 1715 if ( realkey.length() > 0 ) {
1647 if ( itkey.left( realkey.length() ) != realkey ) 1716 if ( itkey.left( realkey.length() ) != realkey )
1648 continue; 1717 continue;
1649 else 1718 else
1650 itkey.remove( 0, realkey.length() + 1 ); 1719 itkey.remove( 0, realkey.length() + 1 );
@@ -1667,22 +1736,22 @@ QStringList QSettings::subkeyList(const QString &key) const
1667 \internal 1736 \internal
1668 1737
1669 This function returns the time of last modification for \a key. 1738 This function returns the time of last modification for \a key.
1670*/ 1739*/
1671QDateTime QSettings::lastModficationTime(const QString &key) 1740QDateTime QSettings::lastModficationTime(const QString &key)
1672{ 1741{
1673 if ( !verifyKey( key ) ) { 1742 if ( !qt_verify_key( key ) ) {
1674#if defined(QT_CHECK_STATE) 1743#if defined(QT_CHECK_STATE)
1675 qWarning( "QSettings::lastModficationTime: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1744 qWarning( "QSettings::lastModficationTime: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1676#endif 1745#endif
1677 return QDateTime(); 1746 return QDateTime();
1678 } 1747 }
1679 1748
1680 QString theKey = groupKey( group(), key ); 1749 QString theKey = groupKey( group(), key );
1681 1750
1682#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1751#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1683 if ( d->sysd ) 1752 if ( d->sysd )
1684 return QDateTime(); 1753 return QDateTime();
1685#endif 1754#endif
1686 1755
1687 if (theKey[0] == '/') { 1756 if (theKey[0] == '/') {
1688 // parse our key 1757 // parse our key
@@ -1712,15 +1781,23 @@ QDateTime QSettings::lastModficationTime(const QString &key)
1712/*! 1781/*!
1713 \overload 1782 \overload
1714 1783
1715 Writes the string list entry \a value into key \a key. The \a key 1784 Writes the string list entry \a value into key \a key. The \a key
1716 is created if it doesn't exist. Any previous value is overwritten 1785 is created if it doesn't exist. Any previous value is overwritten
1717 by \a value. The list is stored as a sequence of strings separated 1786 by \a value. The list is stored as a sequence of strings separated
1718 by \a separator, so none of the strings in the list should contain 1787 by \a separator (using QStringList::join()), so none of the
1719 the separator. If the list is empty or null the key's value will 1788 strings in the list should contain the separator. If the list is
1720 be an empty string. 1789 empty or null the key's value will be an empty string.
1790
1791 \warning The list should not contain empty or null strings, as
1792 readListEntry() will use QStringList::split() to recreate the
1793 list. As the documentation states, QStringList::split() will omit
1794 empty strings from the list. Because of this, it is impossible to
1795 retrieve identical list data that is stored with this function.
1796 We recommend using the writeEntry() and readListEntry() overloads
1797 that do not take a \a separator argument.
1721 1798
1722 If an error occurs the settings are left unchanged and FALSE is 1799 If an error occurs the settings are left unchanged and FALSE is
1723 returned; otherwise returns TRUE. 1800 returned; otherwise returns TRUE.
1724 1801
1725 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1802 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1726*/ 1803*/
@@ -1765,12 +1842,19 @@ bool QSettings::writeEntry(const QString &key, const QStringList &value)
1765 1842
1766 Reads the entry specified by \a key as a string. The \a separator 1843 Reads the entry specified by \a key as a string. The \a separator
1767 is used to create a QStringList by calling QStringList::split(\a 1844 is used to create a QStringList by calling QStringList::split(\a
1768 separator, entry). If \a ok is not 0: \a *ok is set to TRUE if the 1845 separator, entry). If \a ok is not 0: \a *ok is set to TRUE if the
1769 key was read, otherwise \a *ok is set to FALSE. 1846 key was read, otherwise \a *ok is set to FALSE.
1770 1847
1848 \warning As the documentation states, QStringList::split() will
1849 omit empty strings from the list. Because of this, it is
1850 impossible to retrieve identical list data with this function. We
1851 recommend using the readListEntry() and writeEntry() overloads
1852 that do not take a \a separator argument.
1853
1854
1771 Note that if you want to iterate over the list, you should iterate 1855 Note that if you want to iterate over the list, you should iterate
1772 over a copy, e.g. 1856 over a copy, e.g.
1773 \code 1857 \code
1774 QStringList list = mySettings.readListEntry( "size", " " ); 1858 QStringList list = mySettings.readListEntry( "size", " " );
1775 QStringList::Iterator it = list.begin(); 1859 QStringList::Iterator it = list.begin();
1776 while( it != list.end() ) { 1860 while( it != list.end() ) {
@@ -1844,25 +1928,32 @@ QStringList QSettings::readListEntry(const QString &key, bool *ok )
1844 l.append(s); 1928 l.append(s);
1845 } 1929 }
1846 } 1930 }
1847 return l; 1931 return l;
1848} 1932}
1849 1933
1934#ifdef Q_OS_MAC
1935void qt_setSettingsBasePath(const QString &); //qsettings_mac.cpp
1936#endif
1937
1850/*! 1938/*!
1851 Insert platform-dependent paths from platform-independent information. 1939 Insert platform-dependent paths from platform-independent information.
1940
1941 The \a domain should be an Internet domain name
1942 controlled by the producer of the software, eg. Trolltech products
1943 use "trolltech.com".
1852 1944
1853 The \a domain should be an Internet domain name 1945 The \a product should be the official name of the product.
1854 controlled by the producer of the software, eg. Trolltech products
1855 use "trolltech.com".
1856 1946
1857 The \a product should be the official name of the product. 1947 The \a scope should be
1948 QSettings::User for user-specific settings, or
1949 QSettings::Global for system-wide settings (generally
1950 these will be read-only to many users).
1858 1951
1859 The \a scope should be 1952 Not all information is relevant on all systems (e.g. scoping is
1860 QSettings::User for user-specific settings, or 1953 currently used only if QSettings accesses the Windows registry).
1861 QSettings::Global for system-wide settings (generally
1862 these will be read-only to many users).
1863*/ 1954*/
1864 1955
1865void QSettings::setPath( const QString &domain, const QString &product, Scope scope ) 1956void QSettings::setPath( const QString &domain, const QString &product, Scope scope )
1866{ 1957{
1867// On Windows, any trailing ".com(\..*)" is stripped from the domain. The 1958// On Windows, any trailing ".com(\..*)" is stripped from the domain. The
1868// Global scope corresponds to HKEY_LOCAL_MACHINE, and User corresponds to 1959// Global scope corresponds to HKEY_LOCAL_MACHINE, and User corresponds to
@@ -1870,51 +1961,65 @@ void QSettings::setPath( const QString &domain, const QString &product, Scope sc
1870// write to the Global scope. On UNIX, any trailing ".com(\..*)" is stripped 1961// write to the Global scope. On UNIX, any trailing ".com(\..*)" is stripped
1871// from the domain. The Global scope corresponds to "/opt" (this would be 1962// from the domain. The Global scope corresponds to "/opt" (this would be
1872// configurable at library build time - eg. to "/usr/local" or "/usr"), 1963// configurable at library build time - eg. to "/usr/local" or "/usr"),
1873// while the User scope corresponds to $HOME/.*rc. 1964// while the User scope corresponds to $HOME/.*rc.
1874// Note that on most installations, not all users can write to the System 1965// Note that on most installations, not all users can write to the System
1875// scope. 1966// scope.
1876// 1967//
1877// On MacOS X, if there is no "." in domain, append ".com", then reverse the 1968// On MacOS X, if there is no "." in domain, append ".com", then reverse the
1878// order of the elements (Mac OS uses "com.apple.finder" as domain+product). 1969// order of the elements (Mac OS uses "com.apple.finder" as domain+product).
1879// The Global scope corresponds to /Library/Preferences/*.plist, while the 1970// The Global scope corresponds to /Library/Preferences/*.plist, while the
1880// User scope corresponds to ~/Library/Preferences/*.plist. 1971// User scope corresponds to ~/Library/Preferences/*.plist.
1881// Note that on most installations, not all users can write to the System 1972// Note that on most installations, not all users can write to the System
1882// scope. 1973// scope.
1974 d->globalScope = scope == Global;
1975
1883 QString actualSearchPath; 1976 QString actualSearchPath;
1884 int lastDot = domain.findRev( '.' ); 1977 int lastDot = domain.findRev( '.' );
1885 1978
1886#if defined(Q_WS_WIN) 1979#if defined(Q_WS_WIN)
1887 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; 1980 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product;
1888 insertSearchPath( Windows, actualSearchPath ); 1981 insertSearchPath( Windows, actualSearchPath );
1889#elif defined(Q_WS_MAC) 1982#elif !defined(QWS) && defined(Q_OS_MAC)
1890 QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + "."; 1983 QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + ".";
1891 if ( topLevelDomain.isEmpty() ) 1984 if ( !topLevelDomain.isEmpty() )
1892 topLevelDomain = "com."; 1985 qt_setSettingsBasePath( topLevelDomain );
1893 actualSearchPath = "/" + topLevelDomain + domain.left( lastDot ) + product; 1986 actualSearchPath = "/" + domain.left( lastDot ) + product;
1894 insertSearchPath( Mac, actualSearchPath ); 1987 insertSearchPath( Mac, actualSearchPath );
1895#else 1988#else
1896 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; 1989 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product;
1897 insertSearchPath( Unix, actualSearchPath ); 1990 insertSearchPath( Unix, actualSearchPath );
1898#endif 1991#endif
1899
1900 d->globalScope = scope == Global;
1901} 1992}
1902 1993
1903/*! 1994/*!
1904 Appends \a group to the current key prefix. 1995 Appends \a group to the current key prefix.
1996
1997 \code
1998 QSettings settings;
1999 settings.beginGroup( "/MainWindow" );
2000 // read values
2001 settings.endGroup();
2002 \endcode
1905*/ 2003*/
1906void QSettings::beginGroup( const QString &group ) 2004void QSettings::beginGroup( const QString &group )
1907{ 2005{
1908 d->groupStack.push( group ); 2006 d->groupStack.push( group );
1909 d->groupDirty = TRUE; 2007 d->groupDirty = TRUE;
1910} 2008}
1911 2009
1912/*! 2010/*!
1913 Undo previous calls to beginGroup(). Note that a single beginGroup("a/b/c") is undone 2011 Undo previous calls to beginGroup(). Note that a single beginGroup("a/b/c") is undone
1914 by a single call to endGroup(). 2012 by a single call to endGroup().
2013
2014 \code
2015 QSettings settings;
2016 settings.beginGroup( "/MainWindow/Geometry" );
2017 // read values
2018 settings.endGroup();
2019 \endcode
1915*/ 2020*/
1916void QSettings::endGroup() 2021void QSettings::endGroup()
1917{ 2022{
1918 d->groupStack.pop(); 2023 d->groupStack.pop();
1919 d->groupDirty = TRUE; 2024 d->groupDirty = TRUE;
1920} 2025}
@@ -1942,13 +2047,13 @@ QString QSettings::group() const
1942 2047
1943 QValueStack<QString>::Iterator it = d->groupStack.begin(); 2048 QValueStack<QString>::Iterator it = d->groupStack.begin();
1944 while ( it != d->groupStack.end() ) { 2049 while ( it != d->groupStack.end() ) {
1945 QString group = *it; 2050 QString group = *it;
1946 ++it; 2051 ++it;
1947 if ( group[0] != '/' ) 2052 if ( group[0] != '/' )
1948 group = "/" + group; 2053 group.prepend( "/" );
1949 d->groupPrefix += group; 2054 d->groupPrefix += group;
1950 } 2055 }
1951 } 2056 }
1952 return d->groupPrefix; 2057 return d->groupPrefix;
1953} 2058}
1954 2059
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
@@ -2,13 +2,13 @@
2** $Id$ 2** $Id$
3** 3**
4** Implementation of the QString class and related Unicode functions 4** Implementation of the QString class and related Unicode functions
5** 5**
6** Created : 920722 6** Created : 920722
7** 7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. 8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the tools module of the Qt GUI Toolkit. 10** This file is part of the tools module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file 13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file. 14** LICENSE.QPL included in the packaging of this file.
@@ -44,24 +44,28 @@
44#include "qstring.h" 44#include "qstring.h"
45#include "qregexp.h" 45#include "qregexp.h"
46#include "qdatastream.h" 46#include "qdatastream.h"
47#ifndef QT_NO_TEXTCODEC 47#ifndef QT_NO_TEXTCODEC
48#include "qtextcodec.h" 48#include "qtextcodec.h"
49#endif 49#endif
50#include <ctype.h>
51#include <limits.h> 50#include <limits.h>
52#include <stdarg.h> 51#include <stdarg.h>
53#include <stdio.h> 52#include <stdio.h>
54#include <stdlib.h> 53#include <stdlib.h>
54#include <string.h>
55#if defined(Q_WS_WIN) 55#if defined(Q_WS_WIN)
56#include "qt_windows.h" 56#include "qt_windows.h"
57#endif 57#endif
58#if !defined( QT_NO_COMPONENT ) && !defined( QT_LITE_COMPONENT ) 58#if !defined( QT_NO_COMPONENT ) && !defined( QT_LITE_COMPONENT )
59#include "qcleanuphandler.h" 59#include "qcleanuphandler.h"
60#endif 60#endif
61 61
62#ifdef QT_NO_UNICODETABLES
63# include <ctype.h>
64#endif
65
62 66
63/* ------------------------------------------------------------------------- 67/* -------------------------------------------------------------------------
64 * unicode information 68 * unicode information
65 * these tables are generated from the unicode reference file 69 * these tables are generated from the unicode reference file
66 * ftp://ftp.unicode.org/Public/3.2-Update/UnicodeData.txt 70 * ftp://ftp.unicode.org/Public/3.2-Update/UnicodeData.txt
67 * 71 *
@@ -11784,24 +11788,26 @@ static inline QChar::Direction direction( const QChar &c )
11784{ 11788{
11785#ifndef QT_NO_UNICODETABLES 11789#ifndef QT_NO_UNICODETABLES
11786 const Q_UINT8 *rowp = direction_info[c.row()]; 11790 const Q_UINT8 *rowp = direction_info[c.row()];
11787 if(!rowp) return QChar::DirL; 11791 if(!rowp) return QChar::DirL;
11788 return (QChar::Direction) ( *(rowp+c.cell()) & 0x1f ); 11792 return (QChar::Direction) ( *(rowp+c.cell()) & 0x1f );
11789#else 11793#else
11794 Q_UNUSED(c);
11790 return QChar::DirL; 11795 return QChar::DirL;
11791#endif 11796#endif
11792} 11797}
11793 11798
11794static inline bool mirrored( const QChar &c ) 11799static inline bool mirrored( const QChar &c )
11795{ 11800{
11796#ifndef QT_NO_UNICODETABLES 11801#ifndef QT_NO_UNICODETABLES
11797 const Q_UINT8 *rowp = direction_info[c.row()]; 11802 const Q_UINT8 *rowp = direction_info[c.row()];
11798 if ( !rowp ) 11803 if ( !rowp )
11799 return FALSE; 11804 return FALSE;
11800 return *(rowp+c.cell())>128; 11805 return *(rowp+c.cell())>128;
11801#else 11806#else
11807 Q_UNUSED(c);
11802 return FALSE; 11808 return FALSE;
11803#endif 11809#endif
11804} 11810}
11805 11811
11806#ifndef QT_NO_UNICODETABLES 11812#ifndef QT_NO_UNICODETABLES
11807static const Q_UINT16 symmetricPairs[] = { 11813static const Q_UINT16 symmetricPairs[] = {
@@ -11897,13 +11903,13 @@ static int ucstrnicmp( const QChar *a, const QChar *b, int l )
11897 11903
11898static uint computeNewMax( uint len ) 11904static uint computeNewMax( uint len )
11899{ 11905{
11900 uint newMax = 4; 11906 uint newMax = 4;
11901 while ( newMax < len ) 11907 while ( newMax < len )
11902 newMax *= 2; 11908 newMax *= 2;
11903 // try to spare some memory 11909 // try to save some memory
11904 if ( newMax >= 1024 * 1024 && len <= newMax - (newMax >> 2) ) 11910 if ( newMax >= 1024 * 1024 && len <= newMax - (newMax >> 2) )
11905 newMax -= newMax >> 2; 11911 newMax -= newMax >> 2;
11906 return newMax; 11912 return newMax;
11907} 11913}
11908 11914
11909/*! 11915/*!
@@ -12888,13 +12894,13 @@ void QString::compose()
12888 returning the result. 12894 returning the result.
12889 12895
12890 The caller is responsible for deleting the return value with 12896 The caller is responsible for deleting the return value with
12891 delete[]. 12897 delete[].
12892*/ 12898*/
12893 12899
12894QChar* QString::asciiToUnicode( const QByteArray& ba, uint* len ) 12900QChar* QString::latin1ToUnicode( const QByteArray& ba, uint* len )
12895{ 12901{
12896 if ( ba.isNull() ) { 12902 if ( ba.isNull() ) {
12897 *len = 0; 12903 *len = 0;
12898 return 0; 12904 return 0;
12899 } 12905 }
12900 int l = 0; 12906 int l = 0;
@@ -12907,13 +12913,13 @@ QChar* QString::asciiToUnicode( const QByteArray& ba, uint* len )
12907 *len = l; 12913 *len = l;
12908 while (l--) 12914 while (l--)
12909 *uc++ = *str++; 12915 *uc++ = *str++;
12910 return result; 12916 return result;
12911} 12917}
12912 12918
12913static QChar* internalAsciiToUnicode( const QByteArray& ba, uint* len ) 12919static QChar* internalLatin1ToUnicode( const QByteArray& ba, uint* len )
12914{ 12920{
12915 if ( ba.isNull() ) { 12921 if ( ba.isNull() ) {
12916 *len = 0; 12922 *len = 0;
12917 return 0; 12923 return 0;
12918 } 12924 }
12919 int l = 0; 12925 int l = 0;
@@ -12937,47 +12943,47 @@ static QChar* internalAsciiToUnicode( const QByteArray& ba, uint* len )
12937 length of the Unicode string. 12943 length of the Unicode string.
12938 12944
12939 The caller is responsible for deleting the return value with 12945 The caller is responsible for deleting the return value with
12940 delete[]. 12946 delete[].
12941*/ 12947*/
12942 12948
12943QChar* QString::asciiToUnicode( const char *str, uint* len, uint maxlen ) 12949QChar* QString::latin1ToUnicode( const char *str, uint* len, uint maxlen )
12944{ 12950{
12945 QChar* result = 0; 12951 QChar* result = 0;
12946 uint l = 0; 12952 uint l = 0;
12947 if ( str ) { 12953 if ( str ) {
12948 if ( maxlen != (uint)-1 ) { 12954 if ( maxlen != (uint)-1 ) {
12949 while ( l < maxlen && str[l] ) 12955 while ( l < maxlen && str[l] )
12950 l++; 12956 l++;
12951 } else { 12957 } else {
12952 // Faster? 12958 // Faster?
12953 l = qstrlen(str); 12959 l = strlen( str );
12954 } 12960 }
12955 QChar *uc = new QChar[ l ]; // Can't use macro since function is public 12961 QChar *uc = new QChar[ l ]; // Can't use macro since function is public
12956 result = uc; 12962 result = uc;
12957 uint i = l; 12963 uint i = l;
12958 while ( i-- ) 12964 while ( i-- )
12959 *uc++ = *str++; 12965 *uc++ = *str++;
12960 } 12966 }
12961 if ( len ) 12967 if ( len )
12962 *len = l; 12968 *len = l;
12963 return result; 12969 return result;
12964} 12970}
12965 12971
12966static QChar* internalAsciiToUnicode( const char *str, uint* len, 12972static QChar* internalLatin1ToUnicode( const char *str, uint* len,
12967 uint maxlen = (uint)-1 ) 12973 uint maxlen = (uint)-1 )
12968{ 12974{
12969 QChar* result = 0; 12975 QChar* result = 0;
12970 uint l = 0; 12976 uint l = 0;
12971 if ( str ) { 12977 if ( str ) {
12972 if ( maxlen != (uint)-1 ) { 12978 if ( maxlen != (uint)-1 ) {
12973 while ( l < maxlen && str[l] ) 12979 while ( l < maxlen && str[l] )
12974 l++; 12980 l++;
12975 } else { 12981 } else {
12976 // Faster? 12982 // Faster?
12977 l = qstrlen(str); 12983 l = strlen( str );
12978 } 12984 }
12979 QChar *uc = QT_ALLOC_QCHAR_VEC( l ); 12985 QChar *uc = QT_ALLOC_QCHAR_VEC( l );
12980 result = uc; 12986 result = uc;
12981 uint i = l; 12987 uint i = l;
12982 while ( i-- ) 12988 while ( i-- )
12983 *uc++ = *str++; 12989 *uc++ = *str++;
@@ -12991,13 +12997,13 @@ static QChar* internalAsciiToUnicode( const char *str, uint* len,
12991 This utility function converts \a l 16-bit characters from \a uc 12997 This utility function converts \a l 16-bit characters from \a uc
12992 to ASCII, returning a '\0'-terminated string. 12998 to ASCII, returning a '\0'-terminated string.
12993 12999
12994 The caller is responsible for deleting the resultant string with 13000 The caller is responsible for deleting the resultant string with
12995 delete[]. 13001 delete[].
12996*/ 13002*/
12997char* QString::unicodeToAscii(const QChar *uc, uint l) 13003char* QString::unicodeToLatin1(const QChar *uc, uint l)
12998{ 13004{
12999 if (!uc) { 13005 if (!uc) {
13000 return 0; 13006 return 0;
13001 } 13007 }
13002 char *a = new char[l+1]; 13008 char *a = new char[l+1];
13003 char *result = a; 13009 char *result = a;
@@ -13154,41 +13160,12 @@ QStringData* QString::makeSharedNull()
13154 QString *that = const_cast<QString *>(&QString::null); 13160 QString *that = const_cast<QString *>(&QString::null);
13155 that->d = QString::shared_null; 13161 that->d = QString::shared_null;
13156#endif 13162#endif
13157 return QString::shared_null; 13163 return QString::shared_null;
13158} 13164}
13159 13165
13160// Uncomment this to get some useful statistics.
13161// #define Q2HELPER(x) x
13162
13163#ifdef Q2HELPER
13164static int stat_construct_charstar=0;
13165static int stat_construct_charstar_size=0;
13166static int stat_construct_null=0;
13167static int stat_construct_int=0;
13168static int stat_construct_int_size=0;
13169static int stat_construct_ba=0;
13170static int stat_get_ascii=0;
13171static int stat_get_ascii_size=0;
13172static int stat_copy_on_write=0;
13173static int stat_copy_on_write_size=0;
13174static int stat_fast_copy=0;
13175Q_EXPORT void qt_qstring_stats()
13176{
13177 qDebug("construct_charstar = %d (%d chars)", stat_construct_charstar, stat_construct_charstar_size);
13178 qDebug("construct_null = %d", stat_construct_null);
13179 qDebug("construct_int = %d (%d chars)", stat_construct_int, stat_construct_int_size);
13180 qDebug("construct_ba = %d", stat_construct_ba);
13181 qDebug("get_ascii = %d (%d chars)", stat_get_ascii, stat_get_ascii_size);
13182 qDebug("copy_on_write = %d (%d chars)", stat_copy_on_write, stat_copy_on_write_size);
13183 qDebug("fast_copy = %d", stat_fast_copy);
13184}
13185#else
13186#define Q2HELPER(x)
13187#endif
13188
13189/*! 13166/*!
13190 \fn QString::QString() 13167 \fn QString::QString()
13191 13168
13192 Constructs a null string, i.e. both the length and data pointer 13169 Constructs a null string, i.e. both the length and data pointer
13193 are 0. 13170 are 0.
13194 13171
@@ -13208,13 +13185,12 @@ QString::QString( QChar ch )
13208 Constructs an implicitly shared copy of \a s. This is very fast 13185 Constructs an implicitly shared copy of \a s. This is very fast
13209 since it only involves incrementing a reference count. 13186 since it only involves incrementing a reference count.
13210*/ 13187*/
13211QString::QString( const QString &s ) : 13188QString::QString( const QString &s ) :
13212 d(s.d) 13189 d(s.d)
13213{ 13190{
13214 Q2HELPER(stat_fast_copy++)
13215 d->ref(); 13191 d->ref();
13216} 13192}
13217 13193
13218/*! 13194/*!
13219 \internal 13195 \internal
13220 13196
@@ -13227,34 +13203,37 @@ QString::QString( const QString &s ) :
13227 \sa isNull() 13203 \sa isNull()
13228*/ 13204*/
13229 13205
13230QString::QString( int size, bool /*dummy*/ ) 13206QString::QString( int size, bool /*dummy*/ )
13231{ 13207{
13232 if ( size ) { 13208 if ( size ) {
13233 Q2HELPER(stat_construct_int++)
13234 int l = size; 13209 int l = size;
13235 Q2HELPER(stat_construct_int_size+=l)
13236 QChar* uc = QT_ALLOC_QCHAR_VEC( l ); 13210 QChar* uc = QT_ALLOC_QCHAR_VEC( l );
13237 d = new QStringData( uc, 0, l ); 13211 d = new QStringData( uc, 0, l );
13238 } else { 13212 } else {
13239 Q2HELPER(stat_construct_null++)
13240 d = shared_null ? shared_null : (shared_null=new QStringData); 13213 d = shared_null ? shared_null : (shared_null=new QStringData);
13241 d->ref(); 13214 d->ref();
13242 } 13215 }
13243} 13216}
13244 13217
13245/*! 13218/*!
13246 Constructs a string that is a deep copy of \a ba interpreted as a 13219 Constructs a string that is a deep copy of \a ba interpreted as a
13247 classic C string. 13220 classic C string.
13248*/ 13221*/
13249 13222
13250QString::QString( const QByteArray& ba ) 13223QString::QString( const QByteArray& ba )
13251{ 13224{
13252 Q2HELPER(stat_construct_ba++) 13225#ifndef QT_NO_TEXTCODEC
13226 if ( QTextCodec::codecForCStrings() ) {
13227 d = 0;
13228 *this = fromAscii( ba.data(), ba.size() );
13229 return;
13230 }
13231#endif
13253 uint l; 13232 uint l;
13254 QChar *uc = internalAsciiToUnicode(ba,&l); 13233 QChar *uc = internalLatin1ToUnicode(ba,&l);
13255 d = new QStringData(uc,l,l); 13234 d = new QStringData(uc,l,l);
13256} 13235}
13257 13236
13258/*! 13237/*!
13259 Constructs a string that is a deep copy of the first \a length 13238 Constructs a string that is a deep copy of the first \a length
13260 characters in the QChar array. 13239 characters in the QChar array.
@@ -13299,18 +13278,45 @@ QString::QString( const QChar* unicode, uint length )
13299 13278
13300 \sa isNull() 13279 \sa isNull()
13301*/ 13280*/
13302 13281
13303QString::QString( const char *str ) 13282QString::QString( const char *str )
13304{ 13283{
13305 Q2HELPER(stat_construct_charstar++) 13284#ifndef QT_NO_TEXTCODEC
13285 if ( QTextCodec::codecForCStrings() ) {
13286 d = 0;
13287 *this = fromAscii( str );
13288 return;
13289 }
13290#endif
13291 uint l;
13292 QChar *uc = internalLatin1ToUnicode(str,&l);
13293 d = new QStringData(uc,l,l);
13294}
13295
13296#ifndef QT_NO_STL
13297/*!
13298 Constructs a string that is a deep copy of \a str.
13299
13300 This is the same as fromAscii(\a str).
13301*/
13302
13303QString::QString( const std::string &str )
13304{
13305#ifndef QT_NO_TEXTCODEC
13306 if ( QTextCodec::codecForCStrings() ) {
13307 d = 0;
13308 *this = fromAscii( str.c_str() );
13309 return;
13310 }
13311#endif
13306 uint l; 13312 uint l;
13307 QChar *uc = internalAsciiToUnicode(str,&l); 13313 QChar *uc = internalLatin1ToUnicode(str.c_str(),&l);
13308 Q2HELPER(stat_construct_charstar_size+=l)
13309 d = new QStringData(uc,l,l); 13314 d = new QStringData(uc,l,l);
13310} 13315}
13316#endif
13311 13317
13312/*! 13318/*!
13313 \fn QString::~QString() 13319 \fn QString::~QString()
13314 13320
13315 Destroys the string and frees the string's data if this is the 13321 Destroys the string and frees the string's data if this is the
13316 last reference to the string. 13322 last reference to the string.
@@ -13330,16 +13336,16 @@ void QString::real_detach()
13330{ 13336{
13331 setLength( length() ); 13337 setLength( length() );
13332} 13338}
13333 13339
13334void QString::deref() 13340void QString::deref()
13335{ 13341{
13336 if ( d->deref() ) { 13342 if ( d && d->deref() ) {
13337 if ( d != shared_null ) 13343 if ( d != shared_null )
13338 delete d; 13344 delete d;
13339 d = 0; // helps debugging 13345 d = 0;
13340 } 13346 }
13341} 13347}
13342 13348
13343void QStringData::deleteSelf() 13349void QStringData::deleteSelf()
13344{ 13350{
13345 delete this; 13351 delete this;
@@ -13349,12 +13355,21 @@ void QStringData::deleteSelf()
13349 \fn QString& QString::operator=( QChar c ) 13355 \fn QString& QString::operator=( QChar c )
13350 13356
13351 Sets the string to contain just the single character \a c. 13357 Sets the string to contain just the single character \a c.
13352*/ 13358*/
13353 13359
13354/*! 13360/*!
13361 \fn QString& QString::operator=( const std::string& s )
13362
13363 \overload
13364
13365 Makes a deep copy of \a s and returns a reference to the deep
13366 copy.
13367*/
13368
13369/*!
13355 \fn QString& QString::operator=( char c ) 13370 \fn QString& QString::operator=( char c )
13356 13371
13357 \overload 13372 \overload
13358 13373
13359 Sets the string to contain just the single character \a c. 13374 Sets the string to contain just the single character \a c.
13360*/ 13375*/
@@ -13365,13 +13380,12 @@ void QStringData::deleteSelf()
13365 Assigns a shallow copy of \a s to this string and returns a 13380 Assigns a shallow copy of \a s to this string and returns a
13366 reference to this string. This is very fast because the string 13381 reference to this string. This is very fast because the string
13367 isn't actually copied. 13382 isn't actually copied.
13368*/ 13383*/
13369QString &QString::operator=( const QString &s ) 13384QString &QString::operator=( const QString &s )
13370{ 13385{
13371 Q2HELPER(stat_fast_copy++)
13372 s.d->ref(); 13386 s.d->ref();
13373 deref(); 13387 deref();
13374 d = s.d; 13388 d = s.d;
13375 return *this; 13389 return *this;
13376} 13390}
13377 13391
@@ -13380,13 +13394,13 @@ QString &QString::operator=( const QString &s )
13380 13394
13381 Assigns a deep copy of \a cs, interpreted as a classic C string, 13395 Assigns a deep copy of \a cs, interpreted as a classic C string,
13382 to this string and returns a reference to this string. 13396 to this string and returns a reference to this string.
13383*/ 13397*/
13384QString &QString::operator=( const QCString& cs ) 13398QString &QString::operator=( const QCString& cs )
13385{ 13399{
13386 return setLatin1(cs); 13400 return setAscii(cs);
13387} 13401}
13388 13402
13389 13403
13390/*! 13404/*!
13391 \overload 13405 \overload
13392 13406
@@ -13396,13 +13410,13 @@ QString &QString::operator=( const QCString& cs )
13396 If \a str is 0, then a null string is created. 13410 If \a str is 0, then a null string is created.
13397 13411
13398 \sa isNull() 13412 \sa isNull()
13399*/ 13413*/
13400QString &QString::operator=( const char *str ) 13414QString &QString::operator=( const char *str )
13401{ 13415{
13402 return setLatin1(str); 13416 return setAscii(str);
13403} 13417}
13404 13418
13405 13419
13406/*! 13420/*!
13407 \fn bool QString::isNull() const 13421 \fn bool QString::isNull() const
13408 13422
@@ -13468,14 +13482,13 @@ void QString::truncate( uint newLen )
13468 13482
13469/*! 13483/*!
13470 Ensures that at least \a newLen characters are allocated to the 13484 Ensures that at least \a newLen characters are allocated to the
13471 string, and sets the length of the string to \a newLen. Any new 13485 string, and sets the length of the string to \a newLen. Any new
13472 space allocated contains arbitrary data. 13486 space allocated contains arbitrary data.
13473 13487
13474 If \a newLen is 0, then the string becomes empty, unless the 13488 If \a newLen is 0, then the string becomes empty (non-null).
13475 string is null, in which case it remains null.
13476 13489
13477 If it is not possible to allocate enough memory, the string 13490 If it is not possible to allocate enough memory, the string
13478 remains unchanged. 13491 remains unchanged.
13479 13492
13480 This function always detaches the string from other references to 13493 This function always detaches the string from other references to
13481 the same data. 13494 the same data.
@@ -13483,18 +13496,18 @@ void QString::truncate( uint newLen )
13483 This function is useful for code that needs to build up a long 13496 This function is useful for code that needs to build up a long
13484 string and wants to avoid repeated reallocation. In this example, 13497 string and wants to avoid repeated reallocation. In this example,
13485 we want to add to the string until some condition is true, and 13498 we want to add to the string until some condition is true, and
13486 we're fairly sure that size is big enough: 13499 we're fairly sure that size is big enough:
13487 \code 13500 \code
13488 QString result; 13501 QString result;
13489 int resultLength = 0; 13502 int len = 0;
13490 result.setLength( newLen ) // allocate some space 13503 result.setLength( maxLen ); // allocate some space
13491 while ( ... ) { 13504 while ( ... ) {
13492 result[resultLength++] = ... // fill (part of) the space with data 13505 result[len++] = ... // fill part of the space
13493 } 13506 }
13494 result.truncate[resultLength]; // and get rid of the undefined junk 13507 result.truncate( len ); // and get rid of the rest
13495 \endcode 13508 \endcode
13496 13509
13497 If \a newLen is an underestimate, the worst that will happen is 13510 If \a newLen is an underestimate, the worst that will happen is
13498 that the loop will slow down. 13511 that the loop will slow down.
13499 13512
13500 \sa truncate(), isNull(), isEmpty(), length() 13513 \sa truncate(), isNull(), isEmpty(), length()
@@ -13502,14 +13515,12 @@ void QString::truncate( uint newLen )
13502 13515
13503void QString::setLength( uint newLen ) 13516void QString::setLength( uint newLen )
13504{ 13517{
13505 if ( d->count != 1 || newLen > d->maxl || 13518 if ( d->count != 1 || newLen > d->maxl ||
13506 ( newLen * 4 < d->maxl && d->maxl > 4 ) ) { 13519 ( newLen * 4 < d->maxl && d->maxl > 4 ) ) {
13507 // detach, grow or shrink 13520 // detach, grow or shrink
13508 Q2HELPER(stat_copy_on_write++)
13509 Q2HELPER(stat_copy_on_write_size+=d->len)
13510 uint newMax = computeNewMax( newLen ); 13521 uint newMax = computeNewMax( newLen );
13511 QChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); 13522 QChar* nd = QT_ALLOC_QCHAR_VEC( newMax );
13512 if ( nd ) { 13523 if ( nd ) {
13513 uint len = QMIN( d->len, newLen ); 13524 uint len = QMIN( d->len, newLen );
13514 if ( d->unicode ) 13525 if ( d->unicode )
13515 memcpy( nd, d->unicode, sizeof(QChar)*len ); 13526 memcpy( nd, d->unicode, sizeof(QChar)*len );
@@ -13527,27 +13538,26 @@ void QString::setLength( uint newLen )
13527 numbered occurrence of \c %1, \c %2, ..., \c %9 with \a a. 13538 numbered occurrence of \c %1, \c %2, ..., \c %9 with \a a.
13528 13539
13529 The \a fieldwidth value specifies the minimum amount of space that 13540 The \a fieldwidth value specifies the minimum amount of space that
13530 \a a is padded to. A positive value will produce right-aligned 13541 \a a is padded to. A positive value will produce right-aligned
13531 text, whereas a negative value will produce left-aligned text. 13542 text, whereas a negative value will produce left-aligned text.
13532 13543
13544 The following example shows how we could create a 'status' string
13545 when processing a list of files:
13533 \code 13546 \code
13534 QString firstName( "Joe" ); 13547 QString status = QString( "Processing file %1 of %2: %3" )
13535 QString lastName( "Bloggs" ); 13548 .arg( i ) // current file's number
13536 QString fullName; 13549 .arg( total ) // number of files to process
13537 fullName = QString( "First name is '%1', last name is '%2'" ) 13550 .arg( fileName ); // current file's name
13538 .arg( firstName )
13539 .arg( lastName );
13540
13541 // fullName == First name is 'Joe', last name is 'Bloggs'
13542 \endcode 13551 \endcode
13543 13552
13544 Note that using arg() to construct sentences as we've done in the 13553 It is generally fine to use filenames and numbers as we have done
13545 example above does not usually translate well into other languages 13554 in the example above. But note that using arg() to construct
13546 because sentence structure and word order often differ between 13555 natural language sentences does not usually translate well into
13547 languages. 13556 other languages because sentence structure and word order often
13557 differ between languages.
13548 13558
13549 If there is no place marker (\c %1 or \c %2, etc.), a warning 13559 If there is no place marker (\c %1 or \c %2, etc.), a warning
13550 message (qWarning()) is output and the text is appended at the 13560 message (qWarning()) is output and the text is appended at the
13551 end of the string. We recommend that the correct number of place 13561 end of the string. We recommend that the correct number of place
13552 markers is always used in production code. 13562 markers is always used in production code.
13553*/ 13563*/
@@ -13771,13 +13781,13 @@ QString &QString::sprintf( const char* cformat, ... )
13771 13781
13772 if ( !cformat || !*cformat ) { 13782 if ( !cformat || !*cformat ) {
13773 // Qt 1.x compat 13783 // Qt 1.x compat
13774 *this = fromLatin1( "" ); 13784 *this = fromLatin1( "" );
13775 return *this; 13785 return *this;
13776 } 13786 }
13777 QString format = fromLatin1( cformat ); 13787 QString format = fromAscii( cformat );
13778 13788
13779 QRegExp escape( "%#?0?-? ?\\+?'?[0-9*]*\\.?[0-9*]*h?l?L?q?Z?" ); 13789 QRegExp escape( "%#?0?-? ?\\+?'?[0-9*]*\\.?[0-9*]*h?l?L?q?Z?" );
13780 QString result; 13790 QString result;
13781 uint last = 0; 13791 uint last = 0;
13782 int pos; 13792 int pos;
13783 int len = 0; 13793 int len = 0;
@@ -13910,13 +13920,13 @@ QString &QString::sprintf( const char* cformat, ... )
13910 break; 13920 break;
13911 case 2: 13921 case 2:
13912 ::sprintf( out, in, width, decimals, value ); 13922 ::sprintf( out, in, width, decimals, value );
13913 } 13923 }
13914 } 13924 }
13915 } 13925 }
13916 replacement = fromLatin1( out ); 13926 replacement = fromAscii( out );
13917 } 13927 }
13918 result += replacement; 13928 result += replacement;
13919 } 13929 }
13920 *this = result; 13930 *this = result;
13921 13931
13922 va_end( ap ); 13932 va_end( ap );
@@ -14121,14 +14131,16 @@ int QString::find( const QString& str, int index, bool cs ) const
14121 index += l; 14131 index += l;
14122 if ( sl + index > l ) 14132 if ( sl + index > l )
14123 return -1; 14133 return -1;
14124 if ( !sl ) 14134 if ( !sl )
14125 return index; 14135 return index;
14126 14136
14137#ifndef MACOSX_101
14127 if ( sl == 1 ) 14138 if ( sl == 1 )
14128 return find( *str.unicode(), index, cs ); 14139 return find( *str.unicode(), index, cs );
14140#endif
14129 14141
14130 // we use the Boyer-Moore algorithm in cases where the overhead 14142 // we use the Boyer-Moore algorithm in cases where the overhead
14131 // for the hash table should pay off, otherwise we use a simple 14143 // for the hash table should pay off, otherwise we use a simple
14132 // hash function 14144 // hash function
14133 if ( l > 500 && sl > 5 ) { 14145 if ( l > 500 && sl > 5 ) {
14134 uint skiptable[0x100]; 14146 uint skiptable[0x100];
@@ -14218,12 +14230,15 @@ int QString::find( const QString& str, int index, bool cs ) const
14218 int i = string.findRev( 'a' ); // i == 5 14230 int i = string.findRev( 'a' ); // i == 5
14219 \endcode 14231 \endcode
14220*/ 14232*/
14221 14233
14222int QString::findRev( QChar c, int index, bool cs ) const 14234int QString::findRev( QChar c, int index, bool cs ) const
14223{ 14235{
14236#ifdef MACOSX_101
14237 return findRev( QString( c ), index, cs );
14238#else
14224 const uint l = length(); 14239 const uint l = length();
14225 if ( index < 0 ) 14240 if ( index < 0 )
14226 index += l; 14241 index += l;
14227 if ( (uint)index >= l ) 14242 if ( (uint)index >= l )
14228 return -1; 14243 return -1;
14229 const QChar *end = unicode(); 14244 const QChar *end = unicode();
@@ -14234,12 +14249,13 @@ int QString::findRev( QChar c, int index, bool cs ) const
14234 } else { 14249 } else {
14235 c = ::lower( c ); 14250 c = ::lower( c );
14236 while ( uc >= end && ::lower( *uc ) != c ) 14251 while ( uc >= end && ::lower( *uc ) != c )
14237 uc--; 14252 uc--;
14238 } 14253 }
14239 return uc - end; 14254 return uc - end;
14255#endif
14240} 14256}
14241 14257
14242/*! 14258/*!
14243 \overload 14259 \overload
14244 14260
14245 Finds the first occurrence of the string \a str, starting at 14261 Finds the first occurrence of the string \a str, starting at
@@ -14270,14 +14286,16 @@ int QString::findRev( const QString& str, int index, bool cs ) const
14270 int delta = l-sl; 14286 int delta = l-sl;
14271 if ( index < 0 || index > (int)l || delta < 0 ) 14287 if ( index < 0 || index > (int)l || delta < 0 )
14272 return -1; 14288 return -1;
14273 if ( index > delta ) 14289 if ( index > delta )
14274 index = delta; 14290 index = delta;
14275 14291
14292#ifndef MACOSX_101
14276 if ( sl == 1 ) 14293 if ( sl == 1 )
14277 return findRev( *str.unicode(), index, cs ); 14294 return findRev( *str.unicode(), index, cs );
14295#endif
14278 14296
14279 const QChar* needle = str.unicode(); 14297 const QChar* needle = str.unicode();
14280 const QChar* haystack = unicode() + index; 14298 const QChar* haystack = unicode() + index;
14281 const QChar* end = unicode(); 14299 const QChar* end = unicode();
14282 const uint sl_minus_1 = sl-1; 14300 const uint sl_minus_1 = sl-1;
14283 const QChar* n = needle+sl_minus_1; 14301 const QChar* n = needle+sl_minus_1;
@@ -14976,25 +14994,30 @@ QString QString::rightJustify( uint width, QChar fill, bool truncate ) const
14976 14994
14977 \sa upper() 14995 \sa upper()
14978*/ 14996*/
14979 14997
14980QString QString::lower() const 14998QString QString::lower() const
14981{ 14999{
14982 QString s(*this); 15000 int l = length();
14983 int l=length(); 15001 register QChar *p = d->unicode;
14984 if ( l ) { 15002 while ( l ) {
14985 s.real_detach(); // could do this only when we find a change 15003 if ( *p != ::lower(*p) ) {
14986 register QChar *p=s.d->unicode; 15004 QString s( *this );
14987 if ( p ) { 15005 s.real_detach();
14988 while ( l-- ) { 15006 p = s.d->unicode + ( p - d->unicode );
15007 while ( l ) {
14989 *p = ::lower( *p ); 15008 *p = ::lower( *p );
15009 l--;
14990 p++; 15010 p++;
14991 } 15011 }
15012 return s;
14992 } 15013 }
15014 l--;
15015 p++;
14993 } 15016 }
14994 return s; 15017 return *this;
14995} 15018}
14996 15019
14997/*! 15020/*!
14998 Returns an uppercase copy of the string. 15021 Returns an uppercase copy of the string.
14999 15022
15000 \code 15023 \code
@@ -15004,25 +15027,30 @@ QString QString::lower() const
15004 15027
15005 \sa lower() 15028 \sa lower()
15006*/ 15029*/
15007 15030
15008QString QString::upper() const 15031QString QString::upper() const
15009{ 15032{
15010 QString s(*this); 15033 int l = length();
15011 int l=length(); 15034 register QChar *p = d->unicode;
15012 if ( l ) { 15035 while ( l ) {
15013 s.real_detach(); // could do this only when we find a change 15036 if ( *p != ::upper(*p) ) {
15014 register QChar *p=s.d->unicode; 15037 QString s( *this );
15015 if ( p ) { 15038 s.real_detach();
15016 while ( l-- ) { 15039 p = s.d->unicode + ( p - d->unicode );
15040 while ( l ) {
15017 *p = ::upper( *p ); 15041 *p = ::upper( *p );
15042 l--;
15018 p++; 15043 p++;
15019 } 15044 }
15045 return s;
15020 } 15046 }
15047 l--;
15048 p++;
15021 } 15049 }
15022 return s; 15050 return *this;
15023} 15051}
15024 15052
15025 15053
15026/*! 15054/*!
15027 Returns a string that has whitespace removed from the start and 15055 Returns a string that has whitespace removed from the start and
15028 the end. 15056 the end.
@@ -15134,14 +15162,14 @@ QString &QString::insert( uint index, const QString &s )
15134 return insert( index, s.unicode(), s.length() ); 15162 return insert( index, s.unicode(), s.length() );
15135} 15163}
15136 15164
15137/*! 15165/*!
15138 \overload 15166 \overload
15139 15167
15140 Inserts the character in \a s into the string at position \a index 15168 Inserts the first \a len characters in \a s into the string at
15141 \a len number of times and returns a reference to the string. 15169 position \a index and returns a reference to the string.
15142*/ 15170*/
15143 15171
15144QString &QString::insert( uint index, const QChar* s, uint len ) 15172QString &QString::insert( uint index, const QChar* s, uint len )
15145{ 15173{
15146 if ( len == 0 ) 15174 if ( len == 0 )
15147 return *this; 15175 return *this;
@@ -15248,12 +15276,22 @@ QString &QString::insert( uint index, QChar c ) // insert char
15248 15276
15249 Equivalent to insert(0, \a s). 15277 Equivalent to insert(0, \a s).
15250 15278
15251 \sa insert() 15279 \sa insert()
15252 */ 15280 */
15253 15281
15282/*! \fn QString& QString::prepend( const std::string &s )
15283 \overload
15284
15285 Inserts \a s at the beginning of the string and returns a reference to the string.
15286
15287 Equivalent to insert(0, \a s).
15288
15289 \sa insert()
15290 */
15291
15254/*! 15292/*!
15255 \overload 15293 \overload
15256 15294
15257 Inserts \a s at the beginning of the string and returns a reference to the string. 15295 Inserts \a s at the beginning of the string and returns a reference to the string.
15258 15296
15259 Equivalent to insert(0, \a s). 15297 Equivalent to insert(0, \a s).
@@ -15845,15 +15883,15 @@ static bool ok_in_base( QChar c, int base )
15845 \sa number() 15883 \sa number()
15846*/ 15884*/
15847 15885
15848long QString::toLong( bool *ok, int base ) const 15886long QString::toLong( bool *ok, int base ) const
15849{ 15887{
15850 const QChar *p = unicode(); 15888 const QChar *p = unicode();
15851 long val = 0; 15889 ulong val = 0;
15852 int l = length(); 15890 int l = length();
15853 const long max_mult = INT_MAX / base; 15891 const ulong max_mult = LONG_MAX / base;
15854 bool is_ok = FALSE; 15892 bool is_ok = FALSE;
15855 int neg = 0; 15893 int neg = 0;
15856 if ( !p ) 15894 if ( !p )
15857 goto bye; 15895 goto bye;
15858 while ( l && p->isSpace() ) // skip leading space 15896 while ( l && p->isSpace() ) // skip leading space
15859 l--,p++; 15897 l--,p++;
@@ -15880,27 +15918,25 @@ long QString::toLong( bool *ok, int base ) const
15880 if ( *p >= 'a' && *p <= 'z' ) 15918 if ( *p >= 'a' && *p <= 'z' )
15881 dv = *p - 'a' + 10; 15919 dv = *p - 'a' + 10;
15882 else 15920 else
15883 dv = *p - 'A' + 10; 15921 dv = *p - 'A' + 10;
15884 } 15922 }
15885 if ( val > max_mult || 15923 if ( val > max_mult ||
15886 (val == max_mult && dv > (INT_MAX % base) + neg) ) 15924 (val == max_mult && dv > (LONG_MAX % base) + neg) )
15887 goto bye; 15925 goto bye;
15888 val = base * val + dv; 15926 val = base * val + dv;
15889 p++; 15927 p++;
15890 } 15928 }
15891 if ( neg )
15892 val = -val;
15893 while ( l && p->isSpace() ) // skip trailing space 15929 while ( l && p->isSpace() ) // skip trailing space
15894 l--,p++; 15930 l--, p++;
15895 if ( !l ) 15931 if ( !l )
15896 is_ok = TRUE; 15932 is_ok = TRUE;
15897bye: 15933bye:
15898 if ( ok ) 15934 if ( ok )
15899 *ok = is_ok; 15935 *ok = is_ok;
15900 return is_ok ? val : 0; 15936 return is_ok ? ( neg ? -( (long) val ) : (long) val ) : 0L;
15901} 15937}
15902 15938
15903/*! 15939/*!
15904 Returns the string converted to an \c {unsigned long} value to the 15940 Returns the string converted to an \c {unsigned long} value to the
15905 base \a base, which is 10 by default and must be between 2 and 36. 15941 base \a base, which is 10 by default and must be between 2 and 36.
15906 15942
@@ -15912,13 +15948,13 @@ bye:
15912 15948
15913ulong QString::toULong( bool *ok, int base ) const 15949ulong QString::toULong( bool *ok, int base ) const
15914{ 15950{
15915 const QChar *p = unicode(); 15951 const QChar *p = unicode();
15916 ulong val = 0; 15952 ulong val = 0;
15917 int l = length(); 15953 int l = length();
15918 const ulong max_mult = UINT_MAX / base; 15954 const ulong max_mult = ULONG_MAX / base;
15919 bool is_ok = FALSE; 15955 bool is_ok = FALSE;
15920 if ( !p ) 15956 if ( !p )
15921 goto bye; 15957 goto bye;
15922 while ( l && p->isSpace() ) // skip leading space 15958 while ( l && p->isSpace() ) // skip leading space
15923 l--,p++; 15959 l--,p++;
15924 if ( !l ) 15960 if ( !l )
@@ -15937,13 +15973,13 @@ ulong QString::toULong( bool *ok, int base ) const
15937 } else { 15973 } else {
15938 if ( *p >= 'a' && *p <= 'z' ) 15974 if ( *p >= 'a' && *p <= 'z' )
15939 dv = *p - 'a' + 10; 15975 dv = *p - 'a' + 10;
15940 else 15976 else
15941 dv = *p - 'A' + 10; 15977 dv = *p - 'A' + 10;
15942 } 15978 }
15943 if ( val > max_mult || (val == max_mult && dv > UINT_MAX % base) ) 15979 if ( val > max_mult || (val == max_mult && dv > ULONG_MAX % base) )
15944 goto bye; 15980 goto bye;
15945 val = base * val + dv; 15981 val = base * val + dv;
15946 p++; 15982 p++;
15947 } 15983 }
15948 15984
15949 while ( l && p->isSpace() ) // skip trailing space 15985 while ( l && p->isSpace() ) // skip trailing space
@@ -15964,13 +16000,13 @@ bye:
15964 FALSE; otherwise \a *ok is set to TRUE. 16000 FALSE; otherwise \a *ok is set to TRUE.
15965*/ 16001*/
15966 16002
15967short QString::toShort( bool *ok, int base ) const 16003short QString::toShort( bool *ok, int base ) const
15968{ 16004{
15969 long v = toLong( ok, base ); 16005 long v = toLong( ok, base );
15970 if ( ok && *ok && (v < -32768 || v > 32767) ) { 16006 if ( ok && *ok && (v < SHRT_MIN || v > SHRT_MAX) ) {
15971 *ok = FALSE; 16007 *ok = FALSE;
15972 v = 0; 16008 v = 0;
15973 } 16009 }
15974 return (short)v; 16010 return (short)v;
15975} 16011}
15976 16012
@@ -15983,13 +16019,13 @@ short QString::toShort( bool *ok, int base ) const
15983 FALSE; otherwise \a *ok is set to TRUE. 16019 FALSE; otherwise \a *ok is set to TRUE.
15984*/ 16020*/
15985 16021
15986ushort QString::toUShort( bool *ok, int base ) const 16022ushort QString::toUShort( bool *ok, int base ) const
15987{ 16023{
15988 ulong v = toULong( ok, base ); 16024 ulong v = toULong( ok, base );
15989 if ( ok && *ok && (v > 65535) ) { 16025 if ( ok && *ok && (v > USHRT_MAX) ) {
15990 *ok = FALSE; 16026 *ok = FALSE;
15991 v = 0; 16027 v = 0;
15992 } 16028 }
15993 return (ushort)v; 16029 return (ushort)v;
15994} 16030}
15995 16031
@@ -16010,13 +16046,18 @@ ushort QString::toUShort( bool *ok, int base ) const
16010 16046
16011 \sa number() 16047 \sa number()
16012*/ 16048*/
16013 16049
16014int QString::toInt( bool *ok, int base ) const 16050int QString::toInt( bool *ok, int base ) const
16015{ 16051{
16016 return (int)toLong( ok, base ); 16052 long v = toLong( ok, base );
16053 if ( ok && *ok && (v < INT_MIN || v > INT_MAX) ) {
16054 *ok = FALSE;
16055 v = 0;
16056 }
16057 return (int)v;
16017} 16058}
16018 16059
16019/*! 16060/*!
16020 Returns the string converted to an \c{unsigned int} value to the 16061 Returns the string converted to an \c{unsigned int} value to the
16021 base \a base, which is 10 by default and must be between 2 and 36. 16062 base \a base, which is 10 by default and must be between 2 and 36.
16022 16063
@@ -16025,13 +16066,18 @@ int QString::toInt( bool *ok, int base ) const
16025 16066
16026 \sa number() 16067 \sa number()
16027*/ 16068*/
16028 16069
16029uint QString::toUInt( bool *ok, int base ) const 16070uint QString::toUInt( bool *ok, int base ) const
16030{ 16071{
16031 return (uint)toULong( ok, base ); 16072 ulong v = toULong( ok, base );
16073 if ( ok && *ok && (v > UINT_MAX) ) {
16074 *ok = FALSE;
16075 v = 0;
16076 }
16077 return (uint)v;
16032} 16078}
16033 16079
16034/*! 16080/*!
16035 Returns the string converted to a \c double value. 16081 Returns the string converted to a \c double value.
16036 16082
16037 If \a ok is not 0: if a conversion error occurs, \a *ok is set to 16083 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
@@ -16049,13 +16095,13 @@ double QString::toDouble( bool *ok ) const
16049{ 16095{
16050 char *end; 16096 char *end;
16051 16097
16052 const char *a = latin1(); 16098 const char *a = latin1();
16053 double val = strtod( a ? a : "", &end ); 16099 double val = strtod( a ? a : "", &end );
16054 if ( ok ) 16100 if ( ok )
16055 *ok = ( a && *a && (end == 0 || (end - a) == (int)length()) ); 16101 *ok = ( a && *a && (end == 0 || *end == '\0') );
16056 return val; 16102 return val;
16057} 16103}
16058 16104
16059/*! 16105/*!
16060 Returns the string converted to a \c float value. 16106 Returns the string converted to a \c float value.
16061 16107
@@ -16095,17 +16141,17 @@ QString &QString::setNum( long n, int base )
16095 QChar *buf = (QChar*)charbuf; 16141 QChar *buf = (QChar*)charbuf;
16096 QChar *p = &buf[64]; 16142 QChar *p = &buf[64];
16097 int len = 0; 16143 int len = 0;
16098 bool neg; 16144 bool neg;
16099 if ( n < 0 ) { 16145 if ( n < 0 ) {
16100 neg = TRUE; 16146 neg = TRUE;
16101 if ( n == INT_MIN ) { 16147 if ( n == LONG_MIN ) {
16102 // Cannot always negate this special case 16148 // Cannot always negate this special case
16103 QString s1, s2; 16149 QString s1, s2;
16104 s1.setNum(n/base); 16150 s1.setNum(n/base, base );
16105 s2.setNum((-(n+base))%base); 16151 s2.setNum((-(n+base))%base, base );
16106 *this = s1 + s2; 16152 *this = s1 + s2;
16107 return *this; 16153 return *this;
16108 } 16154 }
16109 n = -n; 16155 n = -n;
16110 } else { 16156 } else {
16111 neg = FALSE; 16157 neg = FALSE;
@@ -16458,12 +16504,21 @@ void QString::setExpand( uint index, QChar c )
16458 16504
16459 Appends \a str to the string and returns a reference to the result. 16505 Appends \a str to the string and returns a reference to the result.
16460 16506
16461 Equivalent to operator+=(). 16507 Equivalent to operator+=().
16462 */ 16508 */
16463 16509
16510/*! \fn QString& QString::append( const std::string &str )
16511 \overload
16512
16513 Appends \a str to the string and returns a reference to the result.
16514
16515 Equivalent to operator+=().
16516 */
16517
16518
16464/*! \fn QString& QString::append( const char *str ) 16519/*! \fn QString& QString::append( const char *str )
16465 \overload 16520 \overload
16466 16521
16467 Appends \a str to the string and returns a reference to the result. 16522 Appends \a str to the string and returns a reference to the result.
16468 16523
16469 Equivalent to operator+=(). 16524 Equivalent to operator+=().
@@ -16487,15 +16542,21 @@ QString& QString::operator+=( const QString &str )
16487 16542
16488/*! 16543/*!
16489 \overload 16544 \overload
16490 16545
16491 Appends \a str to the string and returns a reference to the string. 16546 Appends \a str to the string and returns a reference to the string.
16492*/ 16547*/
16548#ifndef QT_NO_CAST_ASCII
16493QString& QString::operator+=( const char *str ) 16549QString& QString::operator+=( const char *str )
16494{ 16550{
16495 if ( str ) { 16551 if ( str ) {
16552#ifndef QT_NO_TEXTCODEC
16553 if ( QTextCodec::codecForCStrings() )
16554 return operator+=( fromAscii( str ) );
16555#endif
16556
16496 uint len1 = length(); 16557 uint len1 = length();
16497 uint len2 = strlen( str ); 16558 uint len2 = strlen( str );
16498 if ( len2 ) { 16559 if ( len2 ) {
16499 setLength(len1+len2); 16560 setLength(len1+len2);
16500 uint i = 0; 16561 uint i = 0;
16501 while( i < len2 ) { 16562 while( i < len2 ) {
@@ -16505,12 +16566,13 @@ QString& QString::operator+=( const char *str )
16505 } else if ( isNull() ) { // ## just for 1.x compat: 16566 } else if ( isNull() ) { // ## just for 1.x compat:
16506 *this = fromLatin1( "" ); 16567 *this = fromLatin1( "" );
16507 } 16568 }
16508 } 16569 }
16509 return *this; 16570 return *this;
16510} 16571}
16572#endif
16511 16573
16512/*! \overload 16574/*! \overload
16513 16575
16514 Appends \a c to the string and returns a reference to the string. 16576 Appends \a c to the string and returns a reference to the string.
16515*/ 16577*/
16516 16578
@@ -16526,71 +16588,100 @@ QString &QString::operator+=( QChar c )
16526 16588
16527 Appends \a c to the string and returns a reference to the string. 16589 Appends \a c to the string and returns a reference to the string.
16528*/ 16590*/
16529 16591
16530QString &QString::operator+=( char c ) 16592QString &QString::operator+=( char c )
16531{ 16593{
16594#ifndef QT_NO_TEXTCODEC
16595 if ( QTextCodec::codecForCStrings() )
16596 return operator+=( fromAscii( &c, 1 ) );
16597#endif
16532 setLength(length()+1); 16598 setLength(length()+1);
16533 d->unicode[length()-1] = c; 16599 d->unicode[length()-1] = c;
16534 return *this; 16600 return *this;
16535} 16601}
16536 16602
16537/*! 16603/*!
16538 \fn QString &QString::operator+=( const QByteArray &str ) 16604 \fn QString &QString::operator+=( const QByteArray &str )
16539 \overload 16605 \overload
16540 16606
16541 Appends \a str to the string and returns a reference to the string. 16607 Appends \a str to the string and returns a reference to the string.
16542*/ 16608*/
16543 16609
16610/*!
16611 \fn QString &QString::operator+=( const std::string &str )
16612 \overload
16613
16614 Appends \a str to the string and returns a reference to the string.
16615*/
16616
16544 16617
16545 16618
16546/*! 16619/*!
16547 \fn char QChar::latin1() const 16620 \fn char QChar::latin1() const
16548 16621
16549 Returns a latin-1 copy of this character, if this character is in 16622 Returns the Latin-1 value of this character, or 0 if it
16550 the latin-1 character set. If not, this function returns 0. 16623 cannot be represented in Latin-1.
16551*/ 16624*/
16552 16625
16553 16626
16554/*! 16627/*!
16555 Returns a Latin-1 representation of the string. Note that the 16628 Returns a Latin-1 representation of the string. The
16556 returned value is undefined if the string contains non-Latin-1 16629 returned value is undefined if the string contains non-Latin-1
16557 characters. If you want to convert strings into formats other than 16630 characters. If you want to convert strings into formats other than
16558 Unicode, see the QTextCodec classes. 16631 Unicode, see the QTextCodec classes.
16559 16632
16560 This function is mainly useful for boot-strapping legacy code to 16633 This function is mainly useful for boot-strapping legacy code to
16561 use Unicode. 16634 use Unicode.
16562 16635
16563 The result remains valid so long as one unmodified copy of the 16636 The result remains valid so long as one unmodified copy of the
16564 source string exists. 16637 source string exists.
16565 16638
16566 \sa utf8(), local8Bit() 16639 \sa fromLatin1(), ascii(), utf8(), local8Bit()
16567*/ 16640*/
16568const char* QString::latin1() const 16641const char* QString::latin1() const
16569{ 16642{
16570 if ( !d->ascii ) { 16643 if ( !d->ascii || !d->islatin1 ) {
16571 Q2HELPER(stat_get_ascii++) 16644 d->ascii = unicodeToLatin1( d->unicode, d->len );
16572 Q2HELPER(stat_get_ascii_size+=d->len) 16645 d->islatin1 = TRUE;
16573 d->ascii = unicodeToAscii( d->unicode, d->len );
16574 } 16646 }
16575 return d->ascii; 16647 return d->ascii;
16576} 16648}
16577 16649
16578/*! 16650/*!
16579 \fn const char* QString::ascii() const 16651 Returns an 8-bit ASCII representation of the string.
16580 \obsolete
16581 16652
16582 This function simply calls latin1() and returns the result. 16653 If a codec has been set using QTextCodec::codecForCStrings(),
16654 it is used to convert Unicode to 8-bit char. Otherwise, this function
16655 does the same as latin1().
16656
16657 \sa fromAscii(), latin1(), utf8(), local8Bit()
16583*/ 16658*/
16659const char* QString::ascii() const
16660{
16661#ifndef QT_NO_TEXTCODEC
16662 if ( QTextCodec::codecForCStrings() ) {
16663 if ( !d->ascii || d->islatin1 ) {
16664 QCString s = QTextCodec::codecForCStrings()->fromUnicode( *this );
16665 s.detach();
16666 d->ascii = s.data();
16667 d->islatin1 = FALSE;
16668 s.resetRawData( s.data(), s.size() ); // we have stolen the data
16669 }
16670 return d->ascii;
16671 }
16672#endif // QT_NO_TEXTCODEC
16673 return latin1();
16674}
16584 16675
16585/*! 16676/*!
16586 Returns the string encoded in UTF8 format. 16677 Returns the string encoded in UTF-8 format.
16587 16678
16588 See QTextCodec for more diverse coding/decoding of Unicode strings. 16679 See QTextCodec for more diverse coding/decoding of Unicode strings.
16589 16680
16590 \sa QString::fromUtf8(), local8Bit(), latin1() 16681 \sa fromUtf8(), ascii(), latin1(), local8Bit()
16591*/ 16682*/
16592QCString QString::utf8() const 16683QCString QString::utf8() const
16593{ 16684{
16594 int l = length(); 16685 int l = length();
16595 int rlen = l*3+1; 16686 int rlen = l*3+1;
16596 QCString rstr(rlen); 16687 QCString rstr(rlen);
@@ -16630,13 +16721,14 @@ QCString QString::utf8() const
16630*/ 16721*/
16631QString QString::fromUtf8( const char* utf8, int len ) 16722QString QString::fromUtf8( const char* utf8, int len )
16632{ 16723{
16633 if ( !utf8 ) 16724 if ( !utf8 )
16634 return QString::null; 16725 return QString::null;
16635 16726
16636 if ( len < 0 ) len = qstrlen( utf8 ); 16727 if ( len < 0 )
16728 len = strlen( utf8 );
16637 QString result; 16729 QString result;
16638 result.setLength( len ); // worst case 16730 result.setLength( len ); // worst case
16639 QChar *qch = (QChar *)result.unicode(); 16731 QChar *qch = (QChar *)result.unicode();
16640 ushort uc = 0; 16732 ushort uc = 0;
16641 int need = 0; 16733 int need = 0;
16642 for (int i=0; i<len; i++) { 16734 for (int i=0; i<len; i++) {
@@ -16671,34 +16763,64 @@ QString QString::fromUtf8( const char* utf8, int len )
16671 result.truncate( qch - result.unicode() ); 16763 result.truncate( qch - result.unicode() );
16672 return result; 16764 return result;
16673} 16765}
16674 16766
16675/*! 16767/*!
16676 Returns the Unicode string decoded from the first \a len 16768 Returns the Unicode string decoded from the first \a len
16677 characters of \a chars, ignoring the rest of \a chars. If \a len 16769 characters of \a ascii, ignoring the rest of \a ascii. If \a len
16678 is -1 then the length of \a chars is used. If \a len is bigger 16770 is -1 then the length of \a ascii is used. If \a len is bigger
16679 than the length of \a chars then it will use the length of \a 16771 than the length of \a ascii then it will use the length of \a
16680 chars. 16772 ascii.
16773
16774 If a codec has been set using QTextCodec::codecForCStrings(),
16775 it is used to convert Unicode to 8-bit char. Otherwise, this function
16776 does the same as fromLatin1().
16681 16777
16682 This is the same as the QString(const char*) constructor, but you 16778 This is the same as the QString(const char*) constructor, but you
16683 can make that constructor invisible if you compile with the define 16779 can make that constructor invisible if you compile with the define
16684 \c QT_NO_CAST_ASCII, in which case you can explicitly create a 16780 \c QT_NO_CAST_ASCII, in which case you can explicitly create a
16685 QString from Latin-1 text using this function. 16781 QString from 8-bit ASCII text using this function.
16686 16782
16687 \code 16783 \code
16688 QString str = QString::fromLatin1( "123456789", 5 ); 16784 QString str = QString::fromAscii( "123456789", 5 );
16689 // str == "12345" 16785 // str == "12345"
16690 \endcode 16786 \endcode
16787 */
16788QString QString::fromAscii( const char* ascii, int len )
16789{
16790#ifndef QT_NO_TEXTCODEC
16791 if ( QTextCodec::codecForCStrings() ) {
16792 if ( !ascii )
16793 return QString::null;
16794 if ( len < 0 )
16795 len = strlen( ascii );
16796 if ( len == 0 || *ascii == '\0' )
16797 return QString::fromLatin1( "" );
16798 return QTextCodec::codecForCStrings()->toUnicode( ascii, len );
16799 }
16800#endif
16801 return fromLatin1( ascii, len );
16802}
16803
16804
16805/*!
16806 Returns the Unicode string decoded from the first \a len
16807 characters of \a chars, ignoring the rest of \a chars. If \a len
16808 is -1 then the length of \a chars is used. If \a len is bigger
16809 than the length of \a chars then it will use the length of \a
16810 chars.
16811
16812 \sa fromAscii()
16691*/ 16813*/
16692QString QString::fromLatin1( const char* chars, int len ) 16814QString QString::fromLatin1( const char* chars, int len )
16693{ 16815{
16694 uint l; 16816 uint l;
16695 QChar *uc; 16817 QChar *uc;
16696 if ( len < 0 ) 16818 if ( len < 0 )
16697 len = -1; 16819 len = -1;
16698 uc = internalAsciiToUnicode( chars, &l, len ); 16820 uc = internalLatin1ToUnicode( chars, &l, len );
16699 return QString( new QStringData(uc, l, l), TRUE ); 16821 return QString( new QStringData(uc, l, l), TRUE );
16700} 16822}
16701 16823
16702/*! 16824/*!
16703 \fn const QChar* QString::unicode() const 16825 \fn const QChar* QString::unicode() const
16704 16826
@@ -16706,22 +16828,21 @@ QString QString::fromLatin1( const char* chars, int len )
16706 remains valid until the string is modified. 16828 remains valid until the string is modified.
16707*/ 16829*/
16708 16830
16709/*! 16831/*!
16710 Returns the string encoded in a locale-specific format. On X11, 16832 Returns the string encoded in a locale-specific format. On X11,
16711 this is the QTextCodec::codecForLocale(). On Windows, it is a 16833 this is the QTextCodec::codecForLocale(). On Windows, it is a
16712 system-defined encoding. On Mac OS X, this always uses utf8 as the 16834 system-defined encoding. On Mac OS X, this always uses UTF-8 as
16713 encoding. 16835 the encoding.
16714 16836
16715 See QTextCodec for more diverse coding/decoding of Unicode 16837 See QTextCodec for more diverse coding/decoding of Unicode
16716 strings. 16838 strings.
16717 16839
16718 \sa QString::fromLocal8Bit(), latin1(), utf8() 16840 \sa fromLocal8Bit(), ascii(), latin1(), utf8()
16719*/ 16841*/
16720 16842
16721
16722QCString QString::local8Bit() const 16843QCString QString::local8Bit() const
16723{ 16844{
16724#ifdef QT_NO_TEXTCODEC 16845#ifdef QT_NO_TEXTCODEC
16725 return latin1(); 16846 return latin1();
16726#else 16847#else
16727#ifdef Q_WS_X11 16848#ifdef Q_WS_X11
@@ -16737,13 +16858,13 @@ QCString QString::local8Bit() const
16737 return QCString(latin1()); //I'm evil.. 16858 return QCString(latin1()); //I'm evil..
16738#endif 16859#endif
16739#ifdef Q_WS_WIN 16860#ifdef Q_WS_WIN
16740 return qt_winQString2MB( *this ); 16861 return qt_winQString2MB( *this );
16741#endif 16862#endif
16742#ifdef Q_WS_QWS 16863#ifdef Q_WS_QWS
16743 return utf8(); // ##### if there is ANY 8 bit format supported? 16864 return utf8(); // ### if there is any 8 bit format supported?
16744#endif 16865#endif
16745#endif 16866#endif
16746} 16867}
16747 16868
16748/*! 16869/*!
16749 Returns the Unicode string decoded from the first \a len 16870 Returns the Unicode string decoded from the first \a len
@@ -16768,13 +16889,14 @@ QString QString::fromLocal8Bit( const char* local8Bit, int len )
16768#else 16889#else
16769 16890
16770 if ( !local8Bit ) 16891 if ( !local8Bit )
16771 return QString::null; 16892 return QString::null;
16772#ifdef Q_WS_X11 16893#ifdef Q_WS_X11
16773 QTextCodec* codec = QTextCodec::codecForLocale(); 16894 QTextCodec* codec = QTextCodec::codecForLocale();
16774 if ( len < 0 ) len = qstrlen(local8Bit); 16895 if ( len < 0 )
16896 len = strlen( local8Bit );
16775 return codec 16897 return codec
16776 ? codec->toUnicode( local8Bit, len ) 16898 ? codec->toUnicode( local8Bit, len )
16777 : fromLatin1( local8Bit, len ); 16899 : fromLatin1( local8Bit, len );
16778#endif 16900#endif
16779#if defined( Q_WS_MAC ) 16901#if defined( Q_WS_MAC )
16780 return fromUtf8(local8Bit,len); 16902 return fromUtf8(local8Bit,len);
@@ -16801,12 +16923,18 @@ QString QString::fromLocal8Bit( const char* local8Bit, int len )
16801 strictly Unicode-clean, you can define the macro \c 16923 strictly Unicode-clean, you can define the macro \c
16802 QT_NO_ASCII_CAST when compiling your code to hide this function so 16924 QT_NO_ASCII_CAST when compiling your code to hide this function so
16803 that automatic casts are not done. This has the added advantage 16925 that automatic casts are not done. This has the added advantage
16804 that you catch the programming error described in operator!(). 16926 that you catch the programming error described in operator!().
16805*/ 16927*/
16806 16928
16929/*!
16930 \fn QString::operator std::string() const
16931
16932 Returns ascii().
16933*/
16934
16807 16935
16808/*! 16936/*!
16809 Returns the QString as a zero terminated array of unsigned shorts 16937 Returns the QString as a zero terminated array of unsigned shorts
16810 if the string is not null; otherwise returns zero. 16938 if the string is not null; otherwise returns zero.
16811 16939
16812 The result remains valid so long as one unmodified 16940 The result remains valid so long as one unmodified
@@ -16816,14 +16944,12 @@ const unsigned short *QString::ucs2() const
16816{ 16944{
16817 if ( ! d->unicode ) 16945 if ( ! d->unicode )
16818 return 0; 16946 return 0;
16819 unsigned int len = d->len; 16947 unsigned int len = d->len;
16820 if ( d->maxl < len + 1 ) { 16948 if ( d->maxl < len + 1 ) {
16821 // detach, grow or shrink 16949 // detach, grow or shrink
16822 Q2HELPER(stat_copy_on_write++)
16823 Q2HELPER(stat_copy_on_write_size += len)
16824 uint newMax = computeNewMax( len + 1 ); 16950 uint newMax = computeNewMax( len + 1 );
16825 QChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); 16951 QChar* nd = QT_ALLOC_QCHAR_VEC( newMax );
16826 if ( nd ) { 16952 if ( nd ) {
16827 if ( d->unicode ) 16953 if ( d->unicode )
16828 memcpy( nd, d->unicode, sizeof(QChar)*len ); 16954 memcpy( nd, d->unicode, sizeof(QChar)*len );
16829 ((QString *)this)->deref(); 16955 ((QString *)this)->deref();
@@ -16980,14 +17106,12 @@ QString& QString::setUnicode( const QChar *unicode, uint len )
16980 d = shared_null ? shared_null : makeSharedNull(); 17106 d = shared_null ? shared_null : makeSharedNull();
16981 d->ref(); 17107 d->ref();
16982 } 17108 }
16983 } else if ( d->count != 1 || len > d->maxl || 17109 } else if ( d->count != 1 || len > d->maxl ||
16984 ( len * 4 < d->maxl && d->maxl > 4 ) ) { 17110 ( len * 4 < d->maxl && d->maxl > 4 ) ) {
16985 // detach, grown or shrink 17111 // detach, grown or shrink
16986 Q2HELPER(stat_copy_on_write++)
16987 Q2HELPER(stat_copy_on_write_size+=d->len)
16988 uint newMax = computeNewMax( len ); 17112 uint newMax = computeNewMax( len );
16989 QChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); 17113 QChar* nd = QT_ALLOC_QCHAR_VEC( newMax );
16990 if ( unicode ) 17114 if ( unicode )
16991 memcpy( nd, unicode, sizeof(QChar)*len ); 17115 memcpy( nd, unicode, sizeof(QChar)*len );
16992 deref(); 17116 deref();
16993 d = new QStringData( nd, len, newMax ); 17117 d = new QStringData( nd, len, newMax );
@@ -17015,12 +17139,34 @@ QString& QString::setUnicodeCodes( const ushort* unicode_as_ushorts, uint len )
17015{ 17139{
17016 return setUnicode((const QChar*)unicode_as_ushorts, len); 17140 return setUnicode((const QChar*)unicode_as_ushorts, len);
17017} 17141}
17018 17142
17019 17143
17020/*! 17144/*!
17145 Sets this string to \a str, interpreted as a classic 8-bit ASCII C
17146 string. If \a len is -1 (the default), then it is set to
17147 strlen(str).
17148
17149 If \a str is 0 a null string is created. If \a str is "", an empty
17150 string is created.
17151
17152 \sa isNull(), isEmpty()
17153*/
17154
17155QString &QString::setAscii( const char *str, int len )
17156{
17157#ifndef QT_NO_TEXTCODEC
17158 if ( QTextCodec::codecForCStrings() ) {
17159 *this = QString::fromAscii( str, len );
17160 return *this;
17161 }
17162#endif // QT_NO_TEXTCODEC
17163 return setLatin1( str, len );
17164}
17165
17166/*!
17021 Sets this string to \a str, interpreted as a classic Latin1 C 17167 Sets this string to \a str, interpreted as a classic Latin1 C
17022 string. If \a len is -1 (the default), then it is set to 17168 string. If \a len is -1 (the default), then it is set to
17023 strlen(str). 17169 strlen(str).
17024 17170
17025 If \a str is 0 a null string is created. If \a str is "", an empty 17171 If \a str is 0 a null string is created. If \a str is "", an empty
17026 string is created. 17172 string is created.
@@ -17030,13 +17176,13 @@ QString& QString::setUnicodeCodes( const ushort* unicode_as_ushorts, uint len )
17030 17176
17031QString &QString::setLatin1( const char *str, int len ) 17177QString &QString::setLatin1( const char *str, int len )
17032{ 17178{
17033 if ( str == 0 ) 17179 if ( str == 0 )
17034 return setUnicode(0,0); 17180 return setUnicode(0,0);
17035 if ( len < 0 ) 17181 if ( len < 0 )
17036 len = qstrlen(str); 17182 len = strlen( str );
17037 if ( len == 0 ) { // won't make a null string 17183 if ( len == 0 ) { // won't make a null string
17038 *this = QString::fromLatin1( "" ); 17184 *this = QString::fromLatin1( "" );
17039 } else { 17185 } else {
17040 setUnicode( 0, len ); // resize but not copy 17186 setUnicode( 0, len ); // resize but not copy
17041 QChar *p = d->unicode; 17187 QChar *p = d->unicode;
17042 while ( len-- ) 17188 while ( len-- )
@@ -17048,22 +17194,22 @@ QString &QString::setLatin1( const char *str, int len )
17048/*! \internal 17194/*! \internal
17049 */ 17195 */
17050void QString::checkSimpleText() const 17196void QString::checkSimpleText() const
17051{ 17197{
17052 QChar *p = d->unicode; 17198 QChar *p = d->unicode;
17053 QChar *end = p + d->len; 17199 QChar *end = p + d->len;
17054 d->simpletext = 1;
17055 while( p < end ) { 17200 while( p < end ) {
17056 ushort uc = p->unicode(); 17201 ushort uc = p->unicode();
17057 // sort out regions of complex text formatting 17202 // sort out regions of complex text formatting
17058 if ( uc > 0x058f && ( uc < 0x1100 || uc > 0xfb0f ) ) { 17203 if ( uc > 0x058f && ( uc < 0x1100 || uc > 0xfb0f ) ) {
17059 d->simpletext = 0; 17204 d->issimpletext = FALSE;
17060 return; 17205 return;
17061 } 17206 }
17062 p++; 17207 p++;
17063 } 17208 }
17209 d->issimpletext = TRUE;
17064} 17210}
17065 17211
17066/*! \fn bool QString::simpleText() const 17212/*! \fn bool QString::simpleText() const
17067 \internal 17213 \internal
17068*/ 17214*/
17069 17215
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
@@ -1086,13 +1086,13 @@ QTextStream &QTextStream::writeBlock( const QChar* p, uint len )
1086 int l = len; 1086 int l = len;
1087 QCString block = d->encoder->fromUnicode( s.string(), l ); 1087 QCString block = d->encoder->fromUnicode( s.string(), l );
1088 dev->writeBlock( block, l ); 1088 dev->writeBlock( block, l );
1089 } else 1089 } else
1090#endif 1090#endif
1091 if ( latin1 ) { 1091 if ( latin1 ) {
1092 char *str = QString::unicodeToAscii( p, len ); 1092 char *str = QString::unicodeToLatin1( p, len );
1093 dev->writeBlock( str, len ); 1093 dev->writeBlock( str, len );
1094 delete [] str; 1094 delete [] str;
1095 } else if ( internalOrder ) { 1095 } else if ( internalOrder ) {
1096 if ( doUnicodeHeader ) { 1096 if ( doUnicodeHeader ) {
1097 doUnicodeHeader = FALSE; 1097 doUnicodeHeader = FALSE;
1098 ts_putc( QChar::byteOrderMark ); 1098 ts_putc( QChar::byteOrderMark );
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
@@ -293,46 +293,39 @@ void QUType_int::set( QUObject *o, int v )
293 o->payload.i = v; 293 o->payload.i = v;
294 o->type = this; 294 o->type = this;
295} 295}
296 296
297bool QUType_int::canConvertFrom( QUObject *o, QUType *t ) 297bool QUType_int::canConvertFrom( QUObject *o, QUType *t )
298{ 298{
299 if ( isEqual( t, &static_QUType_double ) || 299 if ( isEqual( t, &static_QUType_double ) )
300 isEqual( t, &static_QUType_float ) )
301 return TRUE; 300 return TRUE;
302 301
303 return t->canConvertTo( o, this ); 302 return t->canConvertTo( o, this );
304} 303}
305 304
306bool QUType_int::canConvertTo( QUObject * /*o*/, QUType *t ) 305bool QUType_int::canConvertTo( QUObject * /*o*/, QUType *t )
307{ 306{
308 return isEqual( t, &static_QUType_double ) || 307 return isEqual( t, &static_QUType_double );
309 isEqual( t, &static_QUType_float );
310} 308}
311 309
312bool QUType_int::convertFrom( QUObject *o, QUType *t ) 310bool QUType_int::convertFrom( QUObject *o, QUType *t )
313{ 311{
314 if ( isEqual( t, &static_QUType_double ) ) 312 if ( isEqual( t, &static_QUType_double ) )
315 o->payload.i = (long)o->payload.d; 313 o->payload.i = (long)o->payload.d;
316 else if ( isEqual( t, &static_QUType_float ) )
317 o->payload.i = (long)o->payload.f;
318 else 314 else
319 return t->convertTo( o, this ); 315 return t->convertTo( o, this );
320 316
321 o->type = this; 317 o->type = this;
322 return TRUE; 318 return TRUE;
323} 319}
324 320
325bool QUType_int::convertTo( QUObject *o, QUType *t ) 321bool QUType_int::convertTo( QUObject *o, QUType *t )
326{ 322{
327 if ( isEqual( t, &static_QUType_double ) ) { 323 if ( isEqual( t, &static_QUType_double ) ) {
328 o->payload.d = (double)o->payload.i; 324 o->payload.d = (double)o->payload.i;
329 o->type = &static_QUType_double; 325 o->type = &static_QUType_double;
330 } else if ( isEqual( t, &static_QUType_float ) ) {
331 o->payload.f = (float)o->payload.i;
332 o->type = &static_QUType_float;
333 } else 326 } else
334 return FALSE; 327 return FALSE;
335 return TRUE; 328 return TRUE;
336} 329}
337 330
338int QUType_int::serializeTo( QUObject *, QUBuffer * ) 331int QUType_int::serializeTo( QUObject *, QUBuffer * )
@@ -342,54 +335,12 @@ int QUType_int::serializeTo( QUObject *, QUBuffer * )
342 335
343int QUType_int::serializeFrom( QUObject *, QUBuffer * ) 336int QUType_int::serializeFrom( QUObject *, QUBuffer * )
344{ 337{
345 return 0; 338 return 0;
346} 339}
347 340
348// {5938712A-C496-11D5-8CB2-00C0F03BC0F3}
349const QUuid TID_QUType_uint( 0x5938712a, 0xc496, 0x11d5, 0x8c, 0xb2, 0x00, 0xc0, 0xf0, 0x3b, 0xc0, 0xf3);
350QUType_uint static_QUType_uint;
351const QUuid *QUType_uint::uuid() const { return &TID_QUType_uint; }
352const char *QUType_uint::desc() const { return "uint"; }
353
354void QUType_uint::set( QUObject *o, uint v )
355{
356 o->payload.ui = v;
357 o->type = this;
358}
359
360bool QUType_uint::canConvertFrom( QUObject *o, QUType *t )
361{
362 return t->canConvertTo( o, this );
363}
364
365bool QUType_uint::canConvertTo( QUObject * /*o*/, QUType * /*t*/ )
366{
367 return FALSE;
368}
369
370bool QUType_uint::convertFrom( QUObject *o, QUType *t )
371{
372 return t->convertTo( o, this );
373}
374
375bool QUType_uint::convertTo( QUObject * /*o*/, QUType * /*t*/ )
376{
377 return FALSE;
378}
379
380int QUType_uint::serializeTo( QUObject *, QUBuffer * )
381{
382 return 0;
383}
384
385int QUType_uint::serializeFrom( QUObject *, QUBuffer * )
386{
387 return 0;
388}
389
390// {2D0974E5-0BA6-4ec2-8837-C198972CB48C} 341// {2D0974E5-0BA6-4ec2-8837-C198972CB48C}
391const QUuid TID_QUType_double( 0x2d0974e5, 0xba6, 0x4ec2, 0x88, 0x37, 0xc1, 0x98, 0x97, 0x2c, 0xb4, 0x8c ); 342const QUuid TID_QUType_double( 0x2d0974e5, 0xba6, 0x4ec2, 0x88, 0x37, 0xc1, 0x98, 0x97, 0x2c, 0xb4, 0x8c );
392QUType_double static_QUType_double; 343QUType_double static_QUType_double;
393const QUuid *QUType_double::uuid() const { return &TID_QUType_double; } 344const QUuid *QUType_double::uuid() const { return &TID_QUType_double; }
394const char *QUType_double::desc() const {return "double"; } 345const char *QUType_double::desc() const {return "double"; }
395 346
@@ -398,32 +349,28 @@ void QUType_double::set( QUObject *o, double v )
398 o->payload.d = v; 349 o->payload.d = v;
399 o->type = this; 350 o->type = this;
400} 351}
401 352
402bool QUType_double::canConvertFrom( QUObject *o, QUType *t ) 353bool QUType_double::canConvertFrom( QUObject *o, QUType *t )
403{ 354{
404 if ( isEqual( t, &static_QUType_int ) || 355 if ( isEqual( t, &static_QUType_int ) )
405 isEqual( t, &static_QUType_float) )
406 return TRUE; 356 return TRUE;
407 357
408 return t->canConvertTo( o, this ); 358 return t->canConvertTo( o, this );
409} 359}
410 360
411bool QUType_double::canConvertTo( QUObject * /*o*/, QUType *t ) 361bool QUType_double::canConvertTo( QUObject * /*o*/, QUType *t )
412{ 362{
413 return isEqual( t, &static_QUType_int ) || 363 return isEqual( t, &static_QUType_int );
414 isEqual( t, &static_QUType_float );
415} 364}
416 365
417bool QUType_double::convertFrom( QUObject *o, QUType *t ) 366bool QUType_double::convertFrom( QUObject *o, QUType *t )
418{ 367{
419 if ( isEqual( t, &static_QUType_int ) ) 368 if ( isEqual( t, &static_QUType_int ) )
420 o->payload.d = (double)o->payload.i; 369 o->payload.d = (double)o->payload.i;
421 else if ( isEqual( t, &static_QUType_float ) ) 370 else
422 o->payload.d = (double)o->payload.f;
423 else
424 return t->convertTo( o, this ); 371 return t->convertTo( o, this );
425 372
426 o->type = this; 373 o->type = this;
427 return TRUE; 374 return TRUE;
428} 375}
429 376
@@ -447,76 +394,12 @@ int QUType_double::serializeTo( QUObject *, QUBuffer * )
447 394
448int QUType_double::serializeFrom( QUObject *, QUBuffer * ) 395int QUType_double::serializeFrom( QUObject *, QUBuffer * )
449{ 396{
450 return 0; 397 return 0;
451} 398}
452 399
453
454// {544C5175-6993-4486-B04D-CEC4D21BF4B9 }
455const QUuid TID_QUType_float( 0x544c5175, 0x6993, 0x4486, 0xb0, 0x4d, 0xce, 0xc4, 0xd2, 0x1b, 0xf4, 0xb9 );
456QUType_float static_QUType_float;
457const QUuid *QUType_float::uuid() const { return &TID_QUType_float; }
458const char *QUType_float::desc() const {return "float"; }
459
460void QUType_float::set( QUObject *o, float v )
461{
462 o->payload.f = v;
463 o->type = this;
464}
465
466bool QUType_float::canConvertFrom( QUObject *o, QUType *t )
467{
468 if ( isEqual( t, &static_QUType_int ) ||
469 isEqual( t, &static_QUType_double ) )
470 return TRUE;
471
472 return t->canConvertTo( o, this );
473}
474
475bool QUType_float::canConvertTo( QUObject * /*o*/, QUType *t )
476{
477 return isEqual( t, &static_QUType_int ) ||
478 isEqual( t, &static_QUType_double );
479}
480
481bool QUType_float::convertFrom( QUObject *o, QUType *t )
482{
483 if ( isEqual( t, &static_QUType_int ) )
484 o->payload.f = (float)o->payload.i;
485 else if ( isEqual( t, &static_QUType_double ) )
486 o->payload.f = (float)o->payload.d;
487 else
488 return t->convertTo( o, this );
489
490 o->type = this;
491 return TRUE;
492}
493
494bool QUType_float::convertTo( QUObject *o, QUType *t )
495{
496 if ( isEqual( t, &static_QUType_int ) ) {
497 o->payload.i = (int) o->payload.f;
498 o->type = &static_QUType_int;
499 } else if ( isEqual( t, &static_QUType_double ) ) {
500 o->payload.d = (double) o->payload.f;
501 o->type = &static_QUType_double;
502 } else
503 return FALSE;
504 return TRUE;
505}
506
507int QUType_float::serializeTo( QUObject *, QUBuffer * )
508{
509 return 0;
510}
511
512int QUType_float::serializeFrom( QUObject *, QUBuffer * )
513{
514 return 0;
515}
516
517// {EFCDD1D4-77A3-4b8e-8D46-DC14B8D393E9} 400// {EFCDD1D4-77A3-4b8e-8D46-DC14B8D393E9}
518const QUuid TID_QUType_charstar( 0xefcdd1d4, 0x77a3, 0x4b8e, 0x8d, 0x46, 0xdc, 0x14, 0xb8, 0xd3, 0x93, 0xe9 ); 401const QUuid TID_QUType_charstar( 0xefcdd1d4, 0x77a3, 0x4b8e, 0x8d, 0x46, 0xdc, 0x14, 0xb8, 0xd3, 0x93, 0xe9 );
519QUType_charstar static_QUType_charstar; 402QUType_charstar static_QUType_charstar;
520const QUuid *QUType_charstar::uuid() const { return &TID_QUType_charstar; } 403const QUuid *QUType_charstar::uuid() const { return &TID_QUType_charstar; }
521const char *QUType_charstar::desc() const { return "char*"; } 404const char *QUType_charstar::desc() const { return "char*"; }
522 405
@@ -590,36 +473,32 @@ void QUType_QString::set( QUObject *o, const QString& v )
590} 473}
591 474
592bool QUType_QString::canConvertFrom( QUObject *o, QUType *t ) 475bool QUType_QString::canConvertFrom( QUObject *o, QUType *t )
593{ 476{
594 if ( isEqual( t, &static_QUType_charstar ) || 477 if ( isEqual( t, &static_QUType_charstar ) ||
595 isEqual( t, &static_QUType_double ) || 478 isEqual( t, &static_QUType_double ) ||
596 isEqual( t, &static_QUType_float ) ||
597 isEqual( t, &static_QUType_int ) ) 479 isEqual( t, &static_QUType_int ) )
598 return TRUE; 480 return TRUE;
599 481
600 return t->canConvertTo( o, this ); 482 return t->canConvertTo( o, this );
601} 483}
602 484
603bool QUType_QString::canConvertTo( QUObject * /*o*/, QUType *t ) 485bool QUType_QString::canConvertTo( QUObject * /*o*/, QUType *t )
604{ 486{
605 return isEqual( t, &static_QUType_charstar ) || 487 return isEqual( t, &static_QUType_charstar ) ||
606 isEqual( t, &static_QUType_int ) || 488 isEqual( t, &static_QUType_int ) ||
607 isEqual( t, &static_QUType_double ) || 489 isEqual( t, &static_QUType_double );
608 isEqual( t, &static_QUType_float );
609} 490}
610 491
611bool QUType_QString::convertFrom( QUObject *o, QUType *t ) 492bool QUType_QString::convertFrom( QUObject *o, QUType *t )
612{ 493{
613 QString *str = 0; 494 QString *str = 0;
614 if ( isEqual( t, &static_QUType_charstar ) ) 495 if ( isEqual( t, &static_QUType_charstar ) )
615 str = new QString( o->payload.charstar.ptr ); 496 str = new QString( o->payload.charstar.ptr );
616 else if ( isEqual( t, &static_QUType_double ) ) 497 else if ( isEqual( t, &static_QUType_double ) )
617 str = new QString( QString::number( o->payload.d ) ); 498 str = new QString( QString::number( o->payload.d ) );
618 else if ( isEqual( t, &static_QUType_float ) )
619 str = new QString( QString::number( o->payload.f ) );
620 else if ( isEqual( t, &static_QUType_int ) ) 499 else if ( isEqual( t, &static_QUType_int ) )
621 str = new QString( QString::number( o->payload.i ) ); 500 str = new QString( QString::number( o->payload.i ) );
622 else 501 else
623 return t->convertTo( o, this ); 502 return t->convertTo( o, this );
624 503
625 o->type->clear( o ); 504 o->type->clear( o );
@@ -638,15 +517,12 @@ bool QUType_QString::convertTo( QUObject *o, QUType *t )
638 } else if ( isEqual( t, &static_QUType_int ) ) { 517 } else if ( isEqual( t, &static_QUType_int ) ) {
639 o->payload.l = str->toLong(); 518 o->payload.l = str->toLong();
640 o->type = &static_QUType_int; 519 o->type = &static_QUType_int;
641 } else if ( isEqual( t, &static_QUType_double ) ) { 520 } else if ( isEqual( t, &static_QUType_double ) ) {
642 o->payload.d = str->toDouble(); 521 o->payload.d = str->toDouble();
643 o->type = &static_QUType_double; 522 o->type = &static_QUType_double;
644 } else if ( isEqual( t, &static_QUType_float ) ) {
645 o->payload.d = str->toFloat();
646 o->type = &static_QUType_float;
647 } else { 523 } else {
648 return FALSE; 524 return FALSE;
649 } 525 }
650 delete str; 526 delete str;
651 return TRUE; 527 return TRUE;
652} 528}
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
@@ -121,13 +121,13 @@ struct QWaitConditionPrivate {
121 121
122 // Key reading thread code 122 // Key reading thread code
123 for (;;) { 123 for (;;) {
124 getchar(); 124 getchar();
125 mymutex.lock(); 125 mymutex.lock();
126 // Sleep until there are no busy worker threads 126 // Sleep until there are no busy worker threads
127 while( count > 0 ) { 127 while( mycount > 0 ) {
128 mymutex.unlock(); 128 mymutex.unlock();
129 sleep( 1 ); 129 sleep( 1 );
130 mymutex.lock(); 130 mymutex.lock();
131 } 131 }
132 mymutex.unlock(); 132 mymutex.unlock();
133 key_pressed.wakeAll(); 133 key_pressed.wakeAll();
@@ -221,33 +221,38 @@ void QWaitCondition::wakeAll()
221 \endlist 221 \endlist
222 222
223 \sa wakeOne(), wakeAll() 223 \sa wakeOne(), wakeAll()
224*/ 224*/
225bool QWaitCondition::wait(unsigned long time) 225bool QWaitCondition::wait(unsigned long time)
226{ 226{
227 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 227 pthread_mutex_t mutex;
228 pthread_mutex_init( &mutex, 0 );
229 pthread_mutex_lock( &mutex );
228 230
229 int ret; 231 int ret;
230 if (time != ULONG_MAX) { 232 if (time != ULONG_MAX) {
231 struct timeval tv; 233 struct timeval tv;
232 gettimeofday(&tv, 0); 234 gettimeofday(&tv, 0);
233 235
234 timespec ti; 236 timespec ti;
235 ti.tv_nsec = (tv.tv_usec * 1000) + (time % 1000) * 1000; 237 ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000;
236 ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); 238 ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 );
237 ti.tv_nsec %= 1000000000; 239 ti.tv_nsec %= 1000000000;
238 240
239 ret = pthread_cond_timedwait(&d->cond, &mutex, &ti); 241 ret = pthread_cond_timedwait(&d->cond, &mutex, &ti);
240 } else 242 } else
241 ret = pthread_cond_wait(&d->cond, &mutex); 243 ret = pthread_cond_wait(&d->cond, &mutex);
242 244
243#ifdef QT_CHECK_RANGE 245#ifdef QT_CHECK_RANGE
244 if (ret && ret != ETIMEDOUT) 246 if (ret && ret != ETIMEDOUT)
245 qWarning("Wait condition wait failure: %s",strerror(ret)); 247 qWarning("Wait condition wait failure: %s",strerror(ret));
246#endif 248#endif
247 249
250 pthread_mutex_unlock( &mutex );
251 pthread_mutex_destroy( &mutex );
252
248 return (ret == 0); 253 return (ret == 0);
249} 254}
250 255
251/*! 256/*!
252 \overload 257 \overload
253 258
@@ -288,13 +293,13 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
288 int ret; 293 int ret;
289 if (time != ULONG_MAX) { 294 if (time != ULONG_MAX) {
290 struct timeval tv; 295 struct timeval tv;
291 gettimeofday(&tv, 0); 296 gettimeofday(&tv, 0);
292 297
293 timespec ti; 298 timespec ti;
294 ti.tv_nsec = (tv.tv_usec * 1000) + (time % 1000) * 1000; 299 ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000;
295 ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); 300 ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 );
296 ti.tv_nsec %= 1000000000; 301 ti.tv_nsec %= 1000000000;
297 302
298 ret = pthread_cond_timedwait(&d->cond, &mutex->d->handle, &ti); 303 ret = pthread_cond_timedwait(&d->cond, &mutex->d->handle, &ti);
299 } else 304 } else
300 ret = pthread_cond_wait(&d->cond, &mutex->d->handle); 305 ret = pthread_cond_wait(&d->cond, &mutex->d->handle);