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
@@ -188,25 +188,26 @@ void QBitArray::pad0()
188 188
189 189
190/*! 190/*!
191 \fn uint QBitArray::size() const 191 \fn uint QBitArray::size() const
192 192
193 Returns the bit array's size (number of bits). 193 Returns the bit array's size (number of bits).
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
207bool QBitArray::resize( uint size ) 208bool QBitArray::resize( uint size )
208{ 209{
209 uint s = this->size(); 210 uint s = this->size();
210 if ( !QByteArray::resize( (size+7)/8 ) ) 211 if ( !QByteArray::resize( (size+7)/8 ) )
211 return FALSE; // cannot resize 212 return FALSE; // cannot resize
212 SHBLOCK->nbits = size; 213 SHBLOCK->nbits = size;
diff --git a/qmake/tools/qbuffer.cpp b/qmake/tools/qbuffer.cpp
index b213dd9..0fc90e4 100644
--- a/qmake/tools/qbuffer.cpp
+++ b/qmake/tools/qbuffer.cpp
@@ -187,26 +187,26 @@ bool QBuffer::setBuffer( QByteArray buf )
187*/ 187*/
188 188
189bool QBuffer::open( int m ) 189bool QBuffer::open( int m )
190{ 190{
191 if ( isOpen() ) { // buffer already open 191 if ( isOpen() ) { // buffer already open
192#if defined(QT_CHECK_STATE) 192#if defined(QT_CHECK_STATE)
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 }
207 a_inc = 16; 207 a_inc = 16;
208 setState( IO_Open ); 208 setState( IO_Open );
209 setStatus( 0 ); 209 setStatus( 0 );
210 return TRUE; 210 return TRUE;
211} 211}
212 212
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
@@ -54,24 +54,28 @@
54#endif 54#endif
55 55
56 56
57QComLibrary::QComLibrary( const QString &filename ) 57QComLibrary::QComLibrary( const QString &filename )
58 : QLibrary( filename ), entry( 0 ), libiface( 0 ), qt_version( 0 ) 58 : QLibrary( filename ), entry( 0 ), libiface( 0 ), qt_version( 0 )
59{ 59{
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();
72 if ( !libiface->canUnload() ) 76 if ( !libiface->canUnload() )
73 return FALSE; 77 return FALSE;
74 libiface->release(); 78 libiface->release();
75 libiface = 0; 79 libiface = 0;
76 } 80 }
77 int refs = entry ? entry->release() : 0; 81 int refs = entry ? entry->release() : 0;
@@ -382,47 +386,45 @@ void QComLibrary::createInstanceInternal()
382 QFileInfo fileinfo( library() ); 386 QFileInfo fileinfo( library() );
383 QString lastModified = fileinfo.lastModified().toString(); 387 QString lastModified = fileinfo.lastModified().toString();
384 QString regkey = QString("/Qt Plugins %1.%2/%3") 388 QString regkey = QString("/Qt Plugins %1.%2/%3")
385 .arg( ( QT_VERSION & 0xff0000 ) >> 16 ) 389 .arg( ( QT_VERSION & 0xff0000 ) >> 16 )
386 .arg( ( QT_VERSION & 0xff00 ) >> 8 ) 390 .arg( ( QT_VERSION & 0xff00 ) >> 8 )
387 .arg( library() ); 391 .arg( library() );
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
423 if ( qt_unix_query( library(), &qt_version, &flags, &key ) ) { 425 if ( qt_unix_query( library(), &qt_version, &flags, &key ) ) {
424 // info read succesfully from library 426 // info read succesfully from library
425 query_done = TRUE; 427 query_done = TRUE;
426 } 428 }
427 } 429 }
428#else // !Q_OS_UNIX 430#else // !Q_OS_UNIX
@@ -452,29 +454,24 @@ void QComLibrary::createInstanceInternal()
452 query_done = TRUE; 454 query_done = TRUE;
453 } 455 }
454 } 456 }
455#endif // Q_OS_UNIX 457#endif // Q_OS_UNIX
456 458
457 QStringList queried; 459 QStringList queried;
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
475 if ( ! query_done ) { 472 if ( ! query_done ) {
476 if ( warn_mismatch ) { 473 if ( warn_mismatch ) {
477 qWarning( "Conflict in %s:\n Plugin cannot be queried successfully!", 474 qWarning( "Conflict in %s:\n Plugin cannot be queried successfully!",
478 (const char*) QFile::encodeName( library() ) ); 475 (const char*) QFile::encodeName( library() ) );
479 } 476 }
480 unload(); 477 unload();
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,17 +1,17 @@
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; }
16const char *qInstallPathPlugins() { return QT_INSTALL_PLUGINS; } 16const char *qInstallPathPlugins() { return QT_INSTALL_PLUGINS; }
17const char *qInstallPathData() { return QT_INSTALL_DATA; } 17const char *qInstallPathData() { return QT_INSTALL_DATA; }
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,19 +1,17 @@
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
14** LICENSE.QPL included in the packaging of this file. 12** LICENSE.QPL included in the packaging of this file.
15** 13**
16** This file may be distributed and/or modified under the terms of the 14** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software 15** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the 16** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file. 17** packaging of this 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
@@ -132,24 +132,35 @@ char *qstrdup( const char *src )
132 132
133char *qstrncpy( char *dst, const char *src, uint len ) 133char *qstrncpy( char *dst, const char *src, uint len )
134{ 134{
135 if ( !src || !dst ) 135 if ( !src || !dst )
136 return 0; 136 return 0;
137 strncpy( dst, src, len ); 137 strncpy( dst, src, 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
150 Compares \a str1 and \a str2. Returns a negative value if \a str1 161 Compares \a str1 and \a str2. Returns a negative value if \a str1
151 is less than \a str2, 0 if \a str1 is equal to \a str2 or a 162 is less than \a str2, 0 if \a str1 is equal to \a str2 or a
152 positive value if \a str1 is greater than \a str2. 163 positive value if \a str1 is greater than \a str2.
153 164
154 Special case I: Returns 0 if \a str1 and \a str2 are both 0. 165 Special case I: Returns 0 if \a str1 and \a str2 are both 0.
155 166
@@ -290,56 +301,63 @@ static void createCRC16Table() // build CRC16 lookup table
290 \relates QMemArray 301 \relates QMemArray
291 302
292 Returns the CRC-16 checksum of \a len bytes starting at \a data. 303 Returns the CRC-16 checksum of \a len bytes starting at \a data.
293 304
294 The checksum is independent of the byte order (endianness). 305 The checksum is independent of the byte order (endianness).
295*/ 306*/
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 }
309 } 321 }
310 register Q_UINT16 crc = 0xffff; 322 register Q_UINT16 crc = 0xffff;
311 uchar c; 323 uchar c;
312 uchar *p = (uchar *)data; 324 uchar *p = (uchar *)data;
313 while ( len-- ) { 325 while ( len-- ) {
314 c = *p++; 326 c = *p++;
315 crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)]; 327 crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)];
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 ) {
340 QByteArray tmp( 4 ); 358 QByteArray tmp( 4 );
341 tmp.fill( 0 ); 359 tmp.fill( 0 );
342 return tmp; 360 return tmp;
343 } 361 }
344 if ( !data ) { 362 if ( !data ) {
345#if defined(QT_CHECK_RANGE) 363#if defined(QT_CHECK_RANGE)
@@ -370,38 +388,50 @@ QByteArray qCompress( const uchar* data, int nbytes )
370 bazip.resize( 0 ); 388 bazip.resize( 0 );
371 break; 389 break;
372 case Z_BUF_ERROR: 390 case Z_BUF_ERROR:
373 len *= 2; 391 len *= 2;
374 break; 392 break;
375 } 393 }
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 ) {
402#if defined(QT_CHECK_RANGE) 432#if defined(QT_CHECK_RANGE)
403 qWarning( "qUncompress: data is NULL." ); 433 qWarning( "qUncompress: data is NULL." );
404#endif 434#endif
405 return QByteArray(); 435 return QByteArray();
406 } 436 }
407 if ( nbytes <= 4 ) { 437 if ( nbytes <= 4 ) {
@@ -927,31 +957,35 @@ int QCString::find( char c, int index, bool cs ) const
927 957
928 The search is case sensitive if \a cs is TRUE, or case insensitive 958 The search is case sensitive if \a cs is TRUE, or case insensitive
929 if \a cs is FALSE. 959 if \a cs is FALSE.
930 960
931 Returns the position of \a str, or -1 if \a str could not be 961 Returns the position of \a str, or -1 if \a str could not be
932 found. 962 found.
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 );
952 986
953 /* 987 /*
954 See QString::find() for details. 988 See QString::find() for details.
955 */ 989 */
956 const char* needle = str; 990 const char* needle = str;
957 const char* haystack = data() + index; 991 const char* haystack = data() + index;
@@ -1143,46 +1177,46 @@ int QCString::contains( char c, bool cs ) const
1143 1177
1144 This function counts overlapping substrings, for example, "banana" 1178 This function counts overlapping substrings, for example, "banana"
1145 contains two occurrences of "ana". 1179 contains two occurrences of "ana".
1146 1180
1147 \sa findRev() 1181 \sa findRev()
1148 \link #asciinotion Note on character comparisons \endlink 1182 \link #asciinotion Note on character comparisons \endlink
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
1163 of the string. 1198 of the string.
1164 1199
1165 The whole string is returned if \a len exceeds the length of the 1200 The whole string is returned if \a len exceeds the length of the
1166 string. 1201 string.
1167 1202
1168 Example: 1203 Example:
1169 \code 1204 \code
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() ) {
1183 QCString same( data() ); 1217 QCString same( data() );
1184 return same; 1218 return same;
1185 } else { 1219 } else {
1186 QCString s( len+1 ); 1220 QCString s( len+1 );
1187 strncpy( s.data(), data(), len ); 1221 strncpy( s.data(), data(), len );
1188 *(s.data()+len) = '\0'; 1222 *(s.data()+len) = '\0';
@@ -1488,32 +1522,34 @@ QCString QCString::simplifyWhiteSpace() const
1488 \endcode 1522 \endcode
1489*/ 1523*/
1490 1524
1491QCString &QCString::insert( uint index, const char *s ) 1525QCString &QCString::insert( uint index, const char *s )
1492{ 1526{
1493 int len = qstrlen(s); 1527 int len = qstrlen(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
1514 returns a reference to the string. 1550 returns a reference to the string.
1515 1551
1516 If \a index is beyond the end of the string, the string is 1552 If \a index is beyond the end of the string, the string is
1517 padded with spaces (ASCII 32) to length \a index and then \a c 1553 padded with spaces (ASCII 32) to length \a index and then \a c
1518 is appended. 1554 is appended.
1519 1555
@@ -1560,25 +1596,25 @@ QCString &QCString::insert( uint index, char c ) // insert char
1560 1596
1561QCString &QCString::remove( uint index, uint len ) 1597QCString &QCString::remove( uint index, uint len )
1562{ 1598{
1563 uint olen = length(); 1599 uint olen = length();
1564 if ( index + len >= olen ) { // range problems 1600 if ( index + len >= olen ) { // range problems
1565 if ( index < olen ) { // index ok 1601 if ( index < olen ) { // index ok
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
1579 \a index, with \a str, and returns a reference to the string. 1615 \a index, with \a str, and returns a reference to the string.
1580 1616
1581 If \a index is out of range, nothing is removed and \a str is 1617 If \a index is out of range, nothing is removed and \a str is
1582 appended at the end of the string. If \a index is valid, but \a 1618 appended at the end of the string. If \a index is valid, but \a
1583 index + \a len is larger than the length of the string, \a str 1619 index + \a len is larger than the length of the string, \a str
1584 replaces the rest of the string from position \a index. 1620 replaces the rest of the string from position \a index.
@@ -1622,49 +1658,50 @@ QCString &QCString::replace( char c, const char *after )
1622/*! \overload 1658/*! \overload
1623 1659
1624 Replaces every occurrence of the string \a before in the string 1660 Replaces every occurrence of the string \a before in the string
1625 with the string \a after. Returns a reference to the string. 1661 with the string \a after. Returns a reference to the string.
1626 1662
1627 Example: 1663 Example:
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();
1640 1677
1641 int index = 0; 1678 int index = 0;
1642 const int bl = before ? strlen( before ) : 0; 1679 const int bl = before ? strlen( before ) : 0;
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 }
1665 } else { 1702 } else {
1666 to = index; 1703 to = index;
1667 } 1704 }
1668 if ( al ) { 1705 if ( al ) {
1669 memcpy( d + to, after, al ); 1706 memcpy( d + to, after, al );
1670 to += al; 1707 to += al;
@@ -1677,25 +1714,25 @@ QCString &QCString::replace( const char *before, const char *after )
1677 int msize = len - movestart; 1714 int msize = len - movestart;
1678 if ( msize > 0 ) 1715 if ( msize > 0 )
1679 memmove( d + to, d + movestart, msize ); 1716 memmove( d + to, d + movestart, msize );
1680 resize( len - num*(bl-al) + 1 ); 1717 resize( len - num*(bl-al) + 1 );
1681 } 1718 }
1682 } else { 1719 } else {
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 )
1696 index++; 1733 index++;
1697 } 1734 }
1698 if ( !pos ) 1735 if ( !pos )
1699 break; 1736 break;
1700 1737
1701 // we have a table of replacement positions, use them for fast replacing 1738 // we have a table of replacement positions, use them for fast replacing
@@ -1754,70 +1791,70 @@ QCString &QCString::replace( char c1, char c2 )
1754 starting at position \a index. 1791 starting at position \a index.
1755 1792
1756 Returns the position of the next match, or -1 if \a rx was not 1793 Returns the position of the next match, or -1 if \a rx was not
1757 found. 1794 found.
1758 1795
1759 \warning If you want to apply this function repeatedly to the same 1796 \warning If you want to apply this function repeatedly to the same
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
1773 Finds the first occurrence of the regular expression \a rx, 1810 Finds the first occurrence of the regular expression \a rx,
1774 starting at position \a index and searching backwards. 1811 starting at position \a index and searching backwards.
1775 1812
1776 Returns the position of the next match (backwards), or -1 if \a rx 1813 Returns the position of the next match (backwards), or -1 if \a rx
1777 was not found. 1814 was not found.
1778 1815
1779 \warning If you want to apply this function repeatedly to the same 1816 \warning If you want to apply this function repeatedly to the same
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
1793 Counts the number of overlapping occurrences of \a rx in the string. 1830 Counts the number of overlapping occurrences of \a rx in the string.
1794 1831
1795 Example: 1832 Example:
1796 \code 1833 \code
1797 QString s = "banana and panama"; 1834 QString s = "banana and panama";
1798 QRegExp r = QRegExp( "a[nm]a", TRUE, FALSE ); 1835 QRegExp r = QRegExp( "a[nm]a", TRUE, FALSE );
1799 s.contains( r ); // 4 matches 1836 s.contains( r ); // 4 matches
1800 \endcode 1837 \endcode
1801 1838
1802 \sa find(), findRev() 1839 \sa find(), findRev()
1803 1840
1804 \warning If you want to apply this function repeatedly to the same 1841 \warning If you want to apply this function repeatedly to the same
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
1818 1855
1819 Replaces every occurrence of \a rx in the string with \a str. 1856 Replaces every occurrence of \a rx in the string with \a str.
1820 Returns a reference to the string. 1857 Returns a reference to the string.
1821 1858
1822 Example: 1859 Example:
1823 \code 1860 \code
@@ -1829,26 +1866,26 @@ int QCString::contains( const QRegExp &rx ) const
1829 1866
1830 s = "banana"; 1867 s = "banana";
1831 s.replace( QRegExp("^[bn]a"), "" ); // becomes "nana" 1868 s.replace( QRegExp("^[bn]a"), "" ); // becomes "nana"
1832 \endcode 1869 \endcode
1833 1870
1834 \warning If you want to apply this function repeatedly to the same 1871 \warning If you want to apply this function repeatedly to the same
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
1849/*! 1886/*!
1850 Returns the string converted to a \c long value. 1887 Returns the string converted to a \c long value.
1851 1888
1852 If \a ok is not 0: \a *ok is set to FALSE if the string is not a 1889 If \a ok is not 0: \a *ok is set to FALSE if the string is not a
1853 number, or if it has trailing garbage; otherwise \a *ok is set to 1890 number, or if it has trailing garbage; otherwise \a *ok is set to
1854 TRUE. 1891 TRUE.
@@ -2190,41 +2227,41 @@ bool QCString::setExpand( uint index, char c )
2190 2227
2191/*! 2228/*!
2192 Appends string \a str to the string and returns a reference to the string. 2229 Appends string \a str to the string and returns a reference to the string.
2193*/ 2230*/
2194 2231
2195QCString& QCString::operator+=( const char *str ) 2232QCString& 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/*!
2209 \overload 2246 \overload
2210 2247
2211 Appends character \a c to the string and returns a reference to the string. 2248 Appends character \a c to the string and returns a reference to the string.
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
2225 2262
2226/***************************************************************************** 2263/*****************************************************************************
2227 QCString stream functions 2264 QCString stream functions
2228 *****************************************************************************/ 2265 *****************************************************************************/
2229#ifndef QT_NO_DATASTREAM 2266#ifndef QT_NO_DATASTREAM
2230/*! 2267/*!
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
@@ -741,26 +741,34 @@ QDataStream &QDataStream::readBytes( char *&s, uint &l )
741 reference to the stream. 741 reference to the stream.
742 742
743 The buffer \a s must be preallocated. The data is \e not encoded. 743 The buffer \a s must be preallocated. The data is \e not encoded.
744 744
745 \sa readBytes(), QIODevice::readBlock(), writeRawBytes() 745 \sa readBytes(), QIODevice::readBlock(), writeRawBytes()
746*/ 746*/
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
761 769
762/***************************************************************************** 770/*****************************************************************************
763 QDataStream write functions 771 QDataStream write functions
764 *****************************************************************************/ 772 *****************************************************************************/
765 773
766 774
@@ -1003,22 +1011,28 @@ QDataStream &QDataStream::writeBytes(const char *s, uint len)
1003 1011
1004/*! 1012/*!
1005 Writes \a len bytes from \a s to the stream and returns a 1013 Writes \a len bytes from \a s to the stream and returns a
1006 reference to the stream. The data is \e not encoded. 1014 reference to the stream. The data is \e not encoded.
1007 1015
1008 \sa writeBytes(), QIODevice::writeBlock(), readRawBytes() 1016 \sa writeBytes(), QIODevice::writeBlock(), readRawBytes()
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
1024#endif // QT_NO_DATASTREAM 1038#endif // QT_NO_DATASTREAM
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
@@ -1,20 +1,20 @@
1/**************************************************************************** 1/****************************************************************************
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.
15** 15**
16** This file may be distributed and/or modified under the terms of the 16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software 17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the 18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file. 19** packaging of this file.
20** 20**
@@ -26,25 +26,24 @@
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27** 27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for 28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements. 29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information. 30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information. 31** See http://www.trolltech.com/gpl/ for GPL licensing information.
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
45#include <stdio.h> 44#include <stdio.h>
46#ifndef Q_OS_TEMP 45#ifndef Q_OS_TEMP
47#include <time.h> 46#include <time.h>
48#endif 47#endif
49 48
50#if defined(Q_OS_WIN32) 49#if defined(Q_OS_WIN32)
@@ -886,24 +885,30 @@ QDate QDate::addMonths( int nmonths ) const
886/*! 885/*!
887 Returns a QDate object containing a date \a nyears later than the 886 Returns a QDate object containing a date \a nyears later than the
888 date of this object (or earlier if \a nyears is negative). 887 date of this object (or earlier if \a nyears is negative).
889 888
890 \sa addDays(), addMonths() 889 \sa addDays(), addMonths()
891*/ 890*/
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
904/*! 909/*!
905 Returns the number of days from this date to \a d (which is 910 Returns the number of days from this date to \a d (which is
906 negative if \a d is earlier than this date). 911 negative if \a d is earlier than this date).
907 912
908 Example: 913 Example:
909 \code 914 \code
@@ -981,31 +986,43 @@ QDate QDate::currentDate()
981QDate QDate::currentDate( Qt::TimeSpec ts ) 986QDate QDate::currentDate( Qt::TimeSpec ts )
982{ 987{
983 QDate d; 988 QDate d;
984#if defined(Q_OS_WIN32) 989#if defined(Q_OS_WIN32)
985 SYSTEMTIME t; 990 SYSTEMTIME t;
986 memset( &t, 0, sizeof(SYSTEMTIME) ); 991 memset( &t, 0, sizeof(SYSTEMTIME) );
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
1006/*! 1023/*!
1007 Returns the QDate represented by the string \a s, using the format 1024 Returns the QDate represented by the string \a s, using the format
1008 \a f, or an invalid date if the string cannot be parsed. 1025 \a f, or an invalid date if the string cannot be parsed.
1009 1026
1010 Note for \c Qt::TextDate: It is recommended that you use the 1027 Note for \c Qt::TextDate: It is recommended that you use the
1011 English short month names (e.g. "Jan"). Although localized month 1028 English short month names (e.g. "Jan"). Although localized month
@@ -1546,25 +1563,25 @@ int QTime::msecsTo( const QTime &t ) const
1546 Returns TRUE if this time is later than \a t; otherwise returns FALSE. 1563 Returns TRUE if this time is later than \a t; otherwise returns FALSE.
1547*/ 1564*/
1548 1565
1549/*! 1566/*!
1550 \fn bool QTime::operator>=( const QTime &t ) const 1567 \fn bool QTime::operator>=( const QTime &t ) const
1551 1568
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.
1565*/ 1582*/
1566 1583
1567QTime QTime::currentTime() 1584QTime QTime::currentTime()
1568{ 1585{
1569 return currentTime( Qt::LocalTime ); 1586 return currentTime( Qt::LocalTime );
1570} 1587}
@@ -1644,40 +1661,51 @@ bool QTime::currentTime( QTime *ct, Qt::TimeSpec ts )
1644 } 1661 }
1645 1662
1646#if defined(Q_OS_WIN32) 1663#if defined(Q_OS_WIN32)
1647 SYSTEMTIME t; 1664 SYSTEMTIME t;
1648 if ( ts == Qt::LocalTime ) { 1665 if ( ts == Qt::LocalTime ) {
1649 GetLocalTime( &t ); 1666 GetLocalTime( &t );
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
1678 // 00:00.00 to 00:00.59.999 is considered as "midnight or right after" 1706 // 00:00.00 to 00:00.59.999 is considered as "midnight or right after"
1679 return ct->ds < (uint) MSECS_PER_MIN; 1707 return ct->ds < (uint) MSECS_PER_MIN;
1680} 1708}
1681 1709
1682/*! 1710/*!
1683 \overload 1711 \overload
@@ -1697,27 +1725,27 @@ bool QTime::currentTime( QTime *ct, Qt::TimeSpec ts )
1697 1725
1698bool QTime::isValid( int h, int m, int s, int ms ) 1726bool QTime::isValid( int h, int m, int s, int ms )
1699{ 1727{
1700 return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000; 1728 return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
1701} 1729}
1702 1730
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()
1718{ 1746{
1719 *this = currentTime(); 1747 *this = currentTime();
1720} 1748}
1721 1749
1722/*! 1750/*!
1723 Sets this time to the current time and returns the number of 1751 Sets this time to the current time and returns the number of
@@ -1951,34 +1979,52 @@ void QDateTime::setTime_t( uint secsSince1Jan1970UTC )
1951 that do not support timezones this function will behave as if 1979 that do not support timezones this function will behave as if
1952 local time were UTC. 1980 local time were UTC.
1953 1981
1954 On Windows, only a subset of \a secsSince1Jan1970UTC values are 1982 On Windows, only a subset of \a secsSince1Jan1970UTC values are
1955 supported, as Windows starts counting from 1980. 1983 supported, as Windows starts counting from 1980.
1956 1984
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;
1979} 2025}
1980#ifndef QT_NO_DATESTRING 2026#ifndef QT_NO_DATESTRING
1981#ifndef QT_NO_SPRINTF 2027#ifndef QT_NO_SPRINTF
1982/*! 2028/*!
1983 \overload 2029 \overload
1984 2030
@@ -2291,25 +2337,25 @@ bool QDateTime::operator>( const QDateTime &dt ) const
2291 otherwise returns FALSE. 2337 otherwise returns FALSE.
2292*/ 2338*/
2293 2339
2294bool QDateTime::operator>=( const QDateTime &dt ) const 2340bool QDateTime::operator>=( const QDateTime &dt ) const
2295{ 2341{
2296 if ( d > dt.d ) 2342 if ( d > dt.d )
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()
2310{ 2356{
2311 return currentDateTime( Qt::LocalTime ); 2357 return currentDateTime( Qt::LocalTime );
2312} 2358}
2313 2359
2314/*! 2360/*!
2315 Returns the current datetime, as reported by the system clock, for the 2361 Returns the current datetime, as reported by the system clock, for the
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
@@ -1,20 +1,20 @@
1/**************************************************************************** 1/****************************************************************************
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.
15** 15**
16** This file may be distributed and/or modified under the terms of the 16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software 17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the 18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file. 19** packaging of this file.
20** 20**
@@ -34,31 +34,36 @@
34** not clear to you. 34** not clear to you.
35** 35**
36**********************************************************************/ 36**********************************************************************/
37 37
38#include "qplatformdefs.h" 38#include "qplatformdefs.h"
39#include "qdir.h" 39#include "qdir.h"
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
59 regarding paths and files, and manipulate the underlying file 64 regarding paths and files, and manipulate the underlying file
60 system. 65 system.
61 66
62 A QDir can point to a file using either a relative or an absolute 67 A QDir can point to a file using either a relative or an absolute
63 path. Absolute paths begin with the directory separator "/" 68 path. Absolute paths begin with the directory separator "/"
64 (optionally preceded by a drive specification under Windows). If 69 (optionally preceded by a drive specification under Windows). If
@@ -221,24 +226,32 @@ QDir::QDir( const QString &path, const QString &nameFilter,
221QDir::QDir( const QDir &d ) 226QDir::QDir( const QDir &d )
222{ 227{
223 dPath = d.dPath; 228 dPath = d.dPath;
224 fList = 0; 229 fList = 0;
225 fiList = 0; 230 fiList = 0;
226 nameFilt = d.nameFilt; 231 nameFilt = d.nameFilt;
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("*");
239 dirty = TRUE; 252 dirty = TRUE;
240 allDirs = FALSE; 253 allDirs = FALSE;
241 filtS = All; 254 filtS = All;
242 sortS = SortSpec(Name | IgnoreCase); 255 sortS = SortSpec(Name | IgnoreCase);
243} 256}
244 257
@@ -373,28 +386,54 @@ QString QDir::filePath( const QString &fileName,
373 the resultant string returned. 386 the resultant string returned.
374 387
375 \sa filePath() 388 \sa filePath()
376*/ 389*/
377 390
378QString QDir::absFilePath( const QString &fileName, 391QString 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
395 separators that are appropriate for the underlying operating 434 separators that are appropriate for the underlying operating
396 system. 435 system.
397 436
398 On Windows, convertSeparators("c:/winnt/system32") returns 437 On Windows, convertSeparators("c:/winnt/system32") returns
399 "c:\winnt\system32". 438 "c:\winnt\system32".
400 439
@@ -925,40 +964,42 @@ QDir &QDir::operator=( const QString &path )
925/*! 964/*!
926 \fn bool QDir::operator!=( const QDir &d ) const 965 \fn bool QDir::operator!=( const QDir &d ) const
927 966
928 Returns TRUE if directory \a d and this directory have different 967 Returns TRUE if directory \a d and this directory have different
929 paths or different sort or filter settings; otherwise returns 968 paths or different sort or filter settings; otherwise returns
930 FALSE. 969 FALSE.
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
944 returns FALSE. 984 returns FALSE.
945 985
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 &&
959 nameFilt == d.nameFilt && 1000 nameFilt == d.nameFilt &&
960 allDirs == d.allDirs && 1001 allDirs == d.allDirs &&
961 filtS == d.filtS && 1002 filtS == d.filtS &&
962 sortS == d.sortS; 1003 sortS == d.sortS;
963} 1004}
964 1005
@@ -1078,86 +1119,93 @@ QDir QDir::root()
1078{ 1119{
1079 return QDir( rootDirPath() ); 1120 return QDir( rootDirPath() );
1080} 1121}
1081 1122
1082/*! 1123/*!
1083 \fn QString QDir::homeDirPath() 1124 \fn QString QDir::homeDirPath()
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
1117 (See \link qregexp.html#wildcard-matching QRegExp wildcard 1170 (See \link qregexp.html#wildcard-matching QRegExp wildcard
1118 matching.\endlink) 1171 matching.\endlink)
1119 \sa QRegExp::match() 1172 \sa QRegExp::match()
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}
1137 1186
1138/*! 1187/*!
1139 Returns TRUE if the \a fileName matches the wildcard (glob) 1188 Returns TRUE if the \a fileName matches the wildcard (glob)
1140 pattern \a filter; otherwise returns FALSE. The \a filter may 1189 pattern \a filter; otherwise returns FALSE. The \a filter may
1141 contain multiple patterns separated by spaces or semicolons. 1190 contain multiple patterns separated by spaces or semicolons.
1142 1191
1143 (See \link qregexp.html#wildcard-matching QRegExp wildcard 1192 (See \link qregexp.html#wildcard-matching QRegExp wildcard
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.
1158 1206
1159 Symbolic links are kept. This function does not return the 1207 Symbolic links are kept. This function does not return the
1160 canonical path, but rather the simplest version of the input. 1208 canonical path, but rather the simplest version of the input.
1161 For example, "./local" becomes "local", "local/../bin" becomes 1209 For example, "./local" becomes "local", "local/../bin" becomes
1162 "bin" and "/local/usr/../bin" becomes "/local/bin". 1210 "bin" and "/local/usr/../bin" becomes "/local/bin".
1163 1211
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
@@ -1,20 +1,20 @@
1/**************************************************************************** 1/****************************************************************************
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.
15** 15**
16** This file may be distributed and/or modified under the terms of the 16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software 17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the 18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file. 19** packaging of this file.
20** 20**
@@ -42,69 +42,70 @@
42 42
43#include "qdir_p.h" 43#include "qdir_p.h"
44#include "qfileinfo.h" 44#include "qfileinfo.h"
45#include "qregexp.h" 45#include "qregexp.h"
46#include "qstringlist.h" 46#include "qstringlist.h"
47 47
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
60QString QDir::homeDirPath() 61QString QDir::homeDirPath()
61{ 62{
62 QString d; 63 QString d;
63 d = QFile::decodeName(getenv("HOME")); 64 d = QFile::decodeName(getenv("HOME"));
64 slashify( d ); 65 slashify( d );
65 if ( d.isNull() ) 66 if ( d.isNull() )
66 d = rootDirPath(); 67 d = rootDirPath();
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}
105 106
106bool QDir::isReadable() const 107bool QDir::isReadable() const
107{ 108{
108 return ::access( QFile::encodeName(dPath), R_OK | X_OK ) == 0; 109 return ::access( QFile::encodeName(dPath), R_OK | X_OK ) == 0;
109} 110}
110 111
@@ -177,52 +178,56 @@ bool QDir::readDirEntries( const QString &nameFilter,
177 int i; 178 int i;
178 if ( !fList ) { 179 if ( !fList ) {
179 fList = new QStringList; 180 fList = new QStringList;
180 Q_CHECK_PTR( fList ); 181 Q_CHECK_PTR( fList );
181 fiList = new QFileInfoList; 182 fiList = new QFileInfoList;
182 Q_CHECK_PTR( fiList ); 183 Q_CHECK_PTR( fiList );
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 )
223 if ( (doReadable && !fi.isReadable()) || 228 if ( (doReadable && !fi.isReadable()) ||
224 (doWritable && !fi.isWritable()) || 229 (doWritable && !fi.isWritable()) ||
225 (doExecable && !fi.isExecutable()) ) 230 (doExecable && !fi.isExecutable()) )
226 continue; 231 continue;
227 if ( !doHidden && fn[0] == '.' && 232 if ( !doHidden && fn[0] == '.' &&
228 fn != QString::fromLatin1(".") 233 fn != QString::fromLatin1(".")
@@ -267,25 +272,26 @@ bool QDir::readDirEntries( const QString &nameFilter,
267 return TRUE; 272 return TRUE;
268} 273}
269 274
270const QFileInfoList * QDir::drives() 275const QFileInfoList * QDir::drives()
271{ 276{
272 // at most one instance of QFileInfoList is leaked, and this variable 277 // at most one instance of QFileInfoList is leaked, and this variable
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() ) );
286 } 292 }
287 } 293 }
288 294
289 return knownMemoryLeak; 295 return knownMemoryLeak;
290} 296}
291#endif //QT_NO_DIR 297#endif //QT_NO_DIR
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
@@ -79,25 +79,25 @@ extern bool qt_file_access( const QString& fn, int t );
79 at() functions. If you've reached the end of the file, atEnd() 79 at() functions. If you've reached the end of the file, atEnd()
80 returns TRUE. The file handle is returned by handle(). 80 returns TRUE. The file handle is returned by handle().
81 81
82 Here is a code fragment that uses QTextStream to read a text file 82 Here is a code fragment that uses QTextStream to read a text file
83 line by line. It prints each line with a line number. 83 line by line. It prints each line with a line number.
84 \code 84 \code
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 }
98 \endcode 98 \endcode
99 99
100 Writing text is just as easy. The following example shows how to 100 Writing text is just as easy. The following example shows how to
101 write the data we read into the string list from the previous 101 write the data we read into the string list from the previous
102 example: 102 example:
103 \code 103 \code
@@ -281,24 +281,25 @@ bool QFile::remove()
281void QFile::flush() 281void QFile::flush()
282{ 282{
283 if ( isOpen() && fh ) // can only flush open/buffered 283 if ( isOpen() && fh ) // can only flush open/buffered
284 fflush( fh ); // file 284 fflush( fh ); // file
285} 285}
286 286
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{
299 if ( !isOpen() ) { 300 if ( !isOpen() ) {
300#if defined(QT_CHECK_STATE) 301#if defined(QT_CHECK_STATE)
301 qWarning( "QFile::atEnd: File is not open" ); 302 qWarning( "QFile::atEnd: File is not open" );
302#endif 303#endif
303 return FALSE; 304 return FALSE;
304 } 305 }
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
@@ -426,29 +426,32 @@ bool QFile::open( int m, int f )
426 } 426 }
427 return TRUE; 427 return TRUE;
428} 428}
429 429
430/*! 430/*!
431 Returns the file size. 431 Returns the file size.
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}
449 452
450 453
451/*! 454/*!
452 \overload 455 \overload
453 456
454 Sets the file index to \a pos. Returns TRUE if successful; 457 Sets the file index to \a pos. Returns TRUE if successful;
@@ -529,25 +532,25 @@ Q_LONG QFile::readBlock( char *p, Q_ULONG len )
529 return -1; 532 return -1;
530 } 533 }
531 if ( !isReadable() ) { 534 if ( !isReadable() ) {
532 qWarning( "QFile::readBlock: Read operation not permitted" ); 535 qWarning( "QFile::readBlock: Read operation not permitted" );
533 return -1; 536 return -1;
534 } 537 }
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
548 if ( nread < len ) { 551 if ( nread < len ) {
549 if ( isRaw() ) { // raw file 552 if ( isRaw() ) { // raw file
550 nread += ::read( fd, p, len-nread ); 553 nread += ::read( fd, p, len-nread );
551 if ( len && nread <= 0 ) { 554 if ( len && nread <= 0 ) {
552 nread = 0; 555 nread = 0;
553 setStatus(IO_ReadError); 556 setStatus(IO_ReadError);
@@ -620,25 +623,27 @@ Q_LONG QFile::writeBlock( const char *p, Q_ULONG len )
620 if ( !isSequentialAccess() ) 623 if ( !isSequentialAccess() )
621 ioIndex += nwritten; 624 ioIndex += nwritten;
622 } 625 }
623 if ( ioIndex > length ) // update file length 626 if ( ioIndex > length ) // update file length
624 length = ioIndex; 627 length = ioIndex;
625 return nwritten; 628 return nwritten;
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
639int QFile::handle() const 644int QFile::handle() const
640{ 645{
641 if ( !isOpen() ) 646 if ( !isOpen() )
642 return -1; 647 return -1;
643 else if ( fh ) 648 else if ( fh )
644 return fileno( fh ); 649 return fileno( fh );
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
@@ -626,34 +626,36 @@ QDateTime QFileInfo::lastRead() const
626/*! 626/*!
627 Returns the absolute path including the file name. 627 Returns the absolute path including the file name.
628 628
629 The absolute path name consists of the full path and the file 629 The absolute path name consists of the full path and the file
630 name. On Unix this will always begin with the root, '/', 630 name. On Unix this will always begin with the root, '/',
631 directory. On Windows this will always begin 'D:/' where D is a 631 directory. On Windows this will always begin 'D:/' where D is a
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 }
654 tmp += fn; 656 tmp += fn;
655 makeAbs( tmp ); 657 makeAbs( tmp );
656 return QDir::cleanDirPath( tmp ); 658 return QDir::cleanDirPath( tmp );
657} 659}
658 660
659#endif 661#endif
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
@@ -205,27 +205,27 @@ uint QFileInfo::groupId() const
205/*! 205/*!
206 Tests for file permissions. The \a permissionSpec argument can be 206 Tests for file permissions. The \a permissionSpec argument can be
207 several flags of type \c PermissionSpec OR-ed together to check 207 several flags of type \c PermissionSpec OR-ed together to check
208 for permission combinations. 208 for permission combinations.
209 209
210 On systems where files do not have permissions this function 210 On systems where files do not have permissions this function
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
226{ 226{
227 if ( !fic || !cache ) 227 if ( !fic || !cache )
228 doStat(); 228 doStat();
229 if ( fic ) { 229 if ( fic ) {
230 uint mask = 0; 230 uint mask = 0;
231 if ( permissionSpec & ReadUser ) 231 if ( permissionSpec & ReadUser )
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
@@ -26,39 +26,49 @@
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27** 27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for 28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements. 29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information. 30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information. 31** See http://www.trolltech.com/gpl/ for GPL licensing information.
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)))
59 #define DELETE(array)(free((char*)array)) 69 #define DELETE(array)(free((char*)array))
60#else 70#else
61 #define NEW(type,size)(new type[size]) 71 #define NEW(type,size)(new type[size])
62 #define DELETE(array)(delete[] array) 72 #define DELETE(array)(delete[] array)
63 #define DONT_USE_REALLOC // comment to use realloc() 73 #define DONT_USE_REALLOC // comment to use realloc()
64#endif 74#endif
@@ -126,25 +136,29 @@ QGArray::QGArray( int size )
126 if ( size < 0 ) { 136 if ( size < 0 ) {
127#if defined(QT_CHECK_RANGE) 137#if defined(QT_CHECK_RANGE)
128 qWarning( "QGArray: Cannot allocate array with negative length" ); 138 qWarning( "QGArray: Cannot allocate array with negative length" );
129#endif 139#endif
130 size = 0; 140 size = 0;
131 } 141 }
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
145QGArray::QGArray( const QGArray &a ) 159QGArray::QGArray( const QGArray &a )
146{ 160{
147 shd = a.shd; 161 shd = a.shd;
148 shd->ref(); 162 shd->ref();
149} 163}
150 164
@@ -203,53 +217,88 @@ QGArray::~QGArray()
203 217
204bool QGArray::isEqual( const QGArray &a ) const 218bool QGArray::isEqual( const QGArray &a ) const
205{ 219{
206 if ( size() != a.size() ) // different size 220 if ( size() != a.size() ) // different size
207 return FALSE; 221 return FALSE;
208 if ( data() == a.data() ) // has same data 222 if ( data() == a.data() ) // has same data
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
250 Returns TRUE if successful, or FALSE if the memory cannot be allocated 299 Returns TRUE if successful, or FALSE if the memory cannot be allocated
251 (only when \a len != -1). 300 (only when \a len != -1).
252 301
253 \sa resize() 302 \sa resize()
254*/ 303*/
255 304
@@ -310,25 +359,29 @@ QGArray &QGArray::assign( const QGArray &a )
310 359
311QGArray &QGArray::assign( const char *d, uint len ) 360QGArray &QGArray::assign( const char *d, uint len )
312{ 361{
313 if ( shd->count > 1 ) { // disconnect this 362 if ( shd->count > 1 ) { // disconnect this
314 shd->count--; 363 shd->count--;
315 shd = newData(); 364 shd = newData();
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.
329 \sa assign(), operator=() 382 \sa assign(), operator=()
330*/ 383*/
331 384
332QGArray &QGArray::duplicate( const QGArray &a ) 385QGArray &QGArray::duplicate( const QGArray &a )
333{ 386{
334 if ( a.shd == shd ) { // a.duplicate(a) ! 387 if ( a.shd == shd ) { // a.duplicate(a) !
@@ -355,25 +408,29 @@ QGArray &QGArray::duplicate( const QGArray &a )
355 Q_CHECK_PTR( shd ); 408 Q_CHECK_PTR( shd );
356 } else { // delete after copy was made 409 } else { // delete after copy was made
357 oldptr = shd->data; 410 oldptr = shd->data;
358 } 411 }
359 if ( a.shd->len ) { // duplicate data 412 if ( a.shd->len ) { // duplicate data
360 shd->data = NEW(char,a.shd->len); 413 shd->data = NEW(char,a.shd->len);
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/*!
374 \overload 431 \overload
375 Deep copy. Dereferences the current array and obtains a copy of 432 Deep copy. Dereferences the current array and obtains a copy of
376 \a len characters from array data \a d instead. Returns a reference 433 \a len characters from array data \a d instead. Returns a reference
377 to this array. 434 to this array.
378 \sa assign(), operator=() 435 \sa assign(), operator=()
379*/ 436*/
@@ -393,25 +450,29 @@ QGArray &QGArray::duplicate( const char *d, uint len )
393 Q_CHECK_PTR( data ); 450 Q_CHECK_PTR( data );
394 memcpy( data, d, len ); 451 memcpy( data, d, len );
395 } 452 }
396 if ( shd->count > 1 ) { // detach 453 if ( shd->count > 1 ) { // detach
397 shd->count--; 454 shd->count--;
398 shd = newData(); 455 shd = newData();
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.
412 473
413 \warning This function disregards the reference count mechanism. If 474 \warning This function disregards the reference count mechanism. If
414 other QGArrays reference the same data as this, all will be updated. 475 other QGArrays reference the same data as this, all will be updated.
415*/ 476*/
416 477
417void QGArray::store( const char *d, uint len ) 478void QGArray::store( const char *d, uint len )
@@ -650,43 +711,45 @@ static int cmp_arr( const void *n1, const void *n2 )
650 711
651/*! 712/*!
652 Sorts the first \a sz items of the array. 713 Sorts the first \a sz items of the array.
653*/ 714*/
654 715
655void QGArray::sort( uint sz ) 716void 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
669/*! 731/*!
670 Binary search; assumes that \a d is a sorted array of size \a sz. 732 Binary search; assumes that \a d is a sorted array of size \a sz.
671*/ 733*/
672 734
673int QGArray::bsearch( const char *d, uint sz ) const 735int 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;
687 while( (r >= shd->data + sz) && (cmp_arr( r - sz, d ) == 0) ) 750 while( (r >= shd->data + sz) && (cmp_arr( r - sz, d ) == 0) )
688 r -= sz;// search to first of equal elements; bsearch is undef 751 r -= sz;// search to first of equal elements; bsearch is undef
689 return (int)(( r - shd->data ) / sz); 752 return (int)(( r - shd->data ) / sz);
690} 753}
691 754
692 755
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
@@ -195,25 +195,28 @@ QDataStream& QGDict::write( QDataStream &s, QPtrCollection::Item ) const
195 \c IntKey or \c PtrKey. The case-sensitivity of lookups is set with 195 \c IntKey or \c PtrKey. The case-sensitivity of lookups is set with
196 \a caseSensitive. Keys are copied if \a copyKeys is TRUE. 196 \a caseSensitive. Keys are copied if \a copyKeys is TRUE.
197*/ 197*/
198 198
199QGDict::QGDict( uint len, KeyType kt, bool caseSensitive, bool copyKeys ) 199QGDict::QGDict( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
200{ 200{
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.
214 switch ( (keytype = (uint)kt) ) { 217 switch ( (keytype = (uint)kt) ) {
215 case StringKey: 218 case StringKey:
216 cases = caseSensitive; 219 cases = caseSensitive;
217 copyk = FALSE; 220 copyk = FALSE;
218 break; 221 break;
219 case AsciiKey: 222 case AsciiKey:
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
@@ -320,30 +320,26 @@ bool QGList::operator==( const QGList &list ) const
320QLNode *QGList::locate( uint index ) 320QLNode *QGList::locate( uint index )
321{ 321{
322 if ( index == (uint)curIndex ) // current node ? 322 if ( index == (uint)curIndex ) // current node ?
323 return curNode; 323 return curNode;
324 if ( !curNode && firstNode ) { // set current node 324 if ( !curNode && firstNode ) { // set current node
325 curNode = firstNode; 325 curNode = firstNode;
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;
344 } else if ( index < numNodes - index ) {// start from first node 340 } else if ( index < numNodes - index ) {// start from first node
345 node = firstNode; 341 node = firstNode;
346 distance = index; 342 distance = index;
347 forward = TRUE; 343 forward = TRUE;
348 } else { // start from last node 344 } else { // start from last node
349 node = lastNode; 345 node = lastNode;
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
@@ -140,25 +140,46 @@ bool qSysInfo( int *wordSize, bool *bigEndian )
140 if ( be16 != be32 ) { // strange machine! 140 if ( be16 != be32 ) { // strange machine!
141#if defined(QT_CHECK_RANGE) 141#if defined(QT_CHECK_RANGE)
142 qFatal( "qSysInfo: Inconsistent system byte order" ); 142 qFatal( "qSysInfo: Inconsistent system byte order" );
143#endif 143#endif
144 return FALSE; 144 return FALSE;
145 } 145 }
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{
159#ifndef VER_PLATFORM_WIN32s 180#ifndef VER_PLATFORM_WIN32s
160 #define VER_PLATFORM_WIN32s 0 181 #define VER_PLATFORM_WIN32s 0
161#endif 182#endif
162#ifndef VER_PLATFORM_WIN32_WINDOWS 183#ifndef VER_PLATFORM_WIN32_WINDOWS
163#define VER_PLATFORM_WIN32_WINDOWS 1 184#define VER_PLATFORM_WIN32_WINDOWS 1
164#endif 185#endif
@@ -312,41 +333,53 @@ Qt::WindowsVersion qt_winver = (Qt::WindowsVersion)qWinVersion();
312 to crashes on certain platforms due to the platforms printf implementation. 333 to crashes on certain platforms due to the platforms printf implementation.
313 334
314 \sa qDebug(), qWarning(), qInstallMsgHandler(), 335 \sa qDebug(), qWarning(), qInstallMsgHandler(),
315 \link debug.html Debugging\endlink 336 \link debug.html Debugging\endlink
316*/ 337*/
317 338
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 );
331 len = maxlen; 364 len = maxlen;
332 } 365 }
333 unsigned char *ret = (unsigned char*)malloc(len+2); 366 unsigned char *ret = (unsigned char*)malloc(len+2);
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);
347 memcpy(arr, c+1, c[0]); 380 memcpy(arr, c+1, c[0]);
348 arr[c[0]] = '\0'; 381 arr[c[0]] = '\0';
349 QCString ret = arr; 382 QCString ret = arr;
350 delete arr; 383 delete arr;
351 return ret; 384 return ret;
352} 385}
@@ -632,36 +665,36 @@ void qSystemWarning( const char* msg, int code )
632 ASSERT: "b == 0" in div.cpp (9) 665 ASSERT: "b == 0" in div.cpp (9)
633 \endcode 666 \endcode
634 667
635 \sa qWarning(), \link debug.html Debugging\endlink 668 \sa qWarning(), \link debug.html Debugging\endlink
636*/ 669*/
637 670
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
662 695
663// 696//
664// The Q_CHECK_PTR macro calls this function to check if an allocation went ok. 697// The Q_CHECK_PTR macro calls this function to check if an allocation went ok.
665// 698//
666#if (QT_VERSION-0 >= 0x040000) 699#if (QT_VERSION-0 >= 0x040000)
667#if defined(Q_CC_GNU) 700#if defined(Q_CC_GNU)
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,18 +1,18 @@
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.
13** 13**
14** This file may be distributed and/or modified under the terms of the 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 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 16** Foundation and appearing in the file LICENSE.GPL included in the
17** packaging of this file. 17** packaging of this file.
18** 18**
@@ -466,25 +466,25 @@ bool QGPluginManager::addLibrary( QLibrary* lib )
466 if ( !fliFace ) { 466 if ( !fliFace ) {
467 iFace->queryInterface( IID_QComponentInformation, (QUnknownInterface**)&cpiFace ); 467 iFace->queryInterface( IID_QComponentInformation, (QUnknownInterface**)&cpiFace );
468 if ( !cpiFace ) 468 if ( !cpiFace )
469 plugin->queryInterface( IID_QComponentInformation, (QUnknownInterface**)&cpiFace ); 469 plugin->queryInterface( IID_QComponentInformation, (QUnknownInterface**)&cpiFace );
470 } 470 }
471 QStringList fl; 471 QStringList fl;
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?
485 QComLibrary* first = (QComLibrary*)old; 485 QComLibrary* first = (QComLibrary*)old;
486 QComLibrary* second = (QComLibrary*)plugin; 486 QComLibrary* second = (QComLibrary*)plugin;
487 bool takeFirst = TRUE; 487 bool takeFirst = TRUE;
488 if ( first->qtVersion() != QT_VERSION ) { 488 if ( first->qtVersion() != QT_VERSION ) {
489 if ( second->qtVersion() == QT_VERSION ) 489 if ( second->qtVersion() == QT_VERSION )
490 takeFirst = FALSE; 490 takeFirst = FALSE;
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
@@ -26,24 +26,30 @@
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27** 27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for 28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements. 29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information. 30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information. 31** See http://www.trolltech.com/gpl/ for GPL licensing information.
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>
44 50
45#ifdef QT_THREAD_SUPPORT 51#ifdef QT_THREAD_SUPPORT
46# include <private/qmutexpool_p.h> 52# include <private/qmutexpool_p.h>
47#endif // QT_THREAD_SUPPORT 53#endif // QT_THREAD_SUPPORT
48 54
49 #define USE_MALLOC // comment to use new/delete 55 #define USE_MALLOC // comment to use new/delete
@@ -384,25 +390,26 @@ void QGVector::sort() // sort vector
384 while ( end > start && *end == 0 ) 390 while ( end > start && *end == 0 )
385 end--; 391 end--;
386 if ( start < end ) { 392 if ( start < end ) {
387 tmp = *start; 393 tmp = *start;
388 *start = *end; 394 *start = *end;
389 *end = tmp; 395 *end = tmp;
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}
403 410
404 int QGVector::bsearch( Item d ) const // binary search; when sorted 411 int QGVector::bsearch( Item d ) const // binary search; when sorted
405{ 412{
406 if ( !len ) 413 if ( !len )
407 return -1; 414 return -1;
408 if ( !d ) { 415 if ( !d ) {
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,20 +1,20 @@
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.
15** 15**
16** This file may be distributed and/or modified under the terms of the 16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software 17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the 18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file. 19** packaging of this file.
20** 20**
@@ -62,25 +62,25 @@
62QLibraryPrivate::QLibraryPrivate( QLibrary *lib ) 62QLibraryPrivate::QLibraryPrivate( QLibrary *lib )
63 : pHnd( 0 ), library( lib ) 63 : pHnd( 0 ), library( lib )
64{ 64{
65} 65}
66 66
67 67
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.
81 81
82 QLibrary ensures that the shared library is loaded and stays in 82 QLibrary ensures that the shared library is loaded and stays in
83 memory whilst it is in use. QLibrary can also unload the library 83 memory whilst it is in use. QLibrary can also unload the library
84 on destruction and release unused resources. 84 on destruction and release unused resources.
85 85
86 A typical use of QLibrary is to resolve an exported symbol in a 86 A typical use of QLibrary is to resolve an exported symbol in a
@@ -317,27 +317,28 @@ QString QLibrary::library() const
317 if ( libfile.isEmpty() ) 317 if ( libfile.isEmpty() )
318 return libfile; 318 return libfile;
319 319
320 QString filename = libfile; 320 QString filename = libfile;
321 321
322#if defined(Q_WS_WIN) 322#if defined(Q_WS_WIN)
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}
343#endif //QT_NO_LIBRARY 344#endif //QT_NO_LIBRARY
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,18 +1,18 @@
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
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.
15** 15**
16** This file may be distributed and/or modified under the terms of the 16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software 17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the 18** Foundation and appearing in the file LICENSE.GPL included in the
@@ -44,25 +44,42 @@
44#include <string.h> 44#include <string.h>
45#endif 45#endif
46 46
47/* 47/*
48 The platform dependent implementations of 48 The platform dependent implementations of
49 - loadLibrary 49 - loadLibrary
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
63 QString filename = library->library(); 80 QString filename = library->library();
64 81
65 pHnd = (void*)shl_load( filename.latin1(), BIND_DEFERRED | BIND_NONFATAL | DYNAMIC_PATH, 0 ); 82 pHnd = (void*)shl_load( filename.latin1(), BIND_DEFERRED | BIND_NONFATAL | DYNAMIC_PATH, 0 );
66#if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT) 83#if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT)
67 if ( !pHnd ) 84 if ( !pHnd )
68 qWarning( "%s: failed to load library!", filename.latin1() ); 85 qWarning( "%s: failed to load library!", filename.latin1() );
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
@@ -34,26 +34,27 @@
34** not clear to you. 34** not clear to you.
35** 35**
36**********************************************************************/ 36**********************************************************************/
37 37
38#if defined(QT_THREAD_SUPPORT) 38#if defined(QT_THREAD_SUPPORT)
39 39
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
54# define Q_RECURSIVE_MUTEX_TYPE PTHREAD_MUTEX_RECURSIVE 55# define Q_RECURSIVE_MUTEX_TYPE PTHREAD_MUTEX_RECURSIVE
55#elif defined(MUTEX_NONRECURSIVE_NP) && defined(MUTEX_RECURSIVE_NP) 56#elif defined(MUTEX_NONRECURSIVE_NP) && defined(MUTEX_RECURSIVE_NP)
56// POSIX 1003.4a pthreads draft extensions 57// POSIX 1003.4a pthreads draft extensions
57# define Q_MUTEX_SET_TYPE(a, b) pthread_mutexattr_setkind_np((a), (b)); 58# define Q_MUTEX_SET_TYPE(a, b) pthread_mutexattr_setkind_np((a), (b));
58# define Q_NORMAL_MUTEX_TYPE MUTEX_NONRECURSIVE_NP 59# define Q_NORMAL_MUTEX_TYPE MUTEX_NONRECURSIVE_NP
59# define Q_RECURSIVE_MUTEX_TYPE MUTEX_RECURSIVE_NP 60# define Q_RECURSIVE_MUTEX_TYPE MUTEX_RECURSIVE_NP
@@ -652,25 +653,26 @@ bool QMutex::tryLock()
652 ... 653 ...
653 } 654 }
654 }; 655 };
655 \endcode 656 \endcode
656 657
657 \sa QMutex, QWaitCondition 658 \sa QMutex, QWaitCondition
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()
671 673
672 Destroys the QMutexLocker and unlocks the mutex which was locked 674 Destroys the QMutexLocker and unlocks the mutex which was locked
673 in the constructor. 675 in the constructor.
674 676
675 \sa QMutexLocker::QMutexLocker(), QMutex::unlock() 677 \sa QMutexLocker::QMutexLocker(), QMutex::unlock()
676*/ 678*/
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,36 +1,55 @@
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
31 50
32 \ingroup thread 51 \ingroup thread
33 52
34 QMutexPool is a convenience class that provides access to a fixed 53 QMutexPool is a convenience class that provides access to a fixed
35 number of QMutex objects. 54 number of QMutex objects.
36 55
@@ -76,55 +95,58 @@ QGlobalMutexPoolInitializer qt_global_mutexpool_initializer;
76 QMutexLocker documentation for more details. 95 QMutexLocker documentation for more details.
77*/ 96*/
78 97
79/*! 98/*!
80 Constructs a QMutexPool, reserving space for \a size QMutexes. If 99 Constructs a QMutexPool, reserving space for \a size QMutexes. If
81 \a recursive is TRUE, all QMutexes in the pool will be recursive 100 \a recursive is TRUE, all QMutexes in the pool will be recursive
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
@@ -254,33 +254,33 @@
254 \row \i <b>\\t</b> 254 \row \i <b>\\t</b>
255 \i This matches the ASCII horizontal tab character (HT, 0x09). 255 \i This matches the ASCII horizontal tab character (HT, 0x09).
256 \row \i <b>\\v</b> 256 \row \i <b>\\v</b>
257 \i This matches the ASCII vertical tab character (VT, 0x0B). 257 \i This matches the ASCII vertical tab character (VT, 0x0B).
258 \row \i <b>\\xhhhh</b> 258 \row \i <b>\\xhhhh</b>
259 \i This matches the Unicode character corresponding to the 259 \i This matches the Unicode character corresponding to the
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
281 281
282 \e {Note that the C++ compiler transforms backslashes in strings 282 \e {Note that the C++ compiler transforms backslashes in strings
283 so to include a <b>\\</b> in a regexp you will need to enter it 283 so to include a <b>\\</b> in a regexp you will need to enter it
284 twice, i.e. <b>\\\\</b>.} 284 twice, i.e. <b>\\\\</b>.}
285 285
286 \target sets-of-characters 286 \target sets-of-characters
@@ -538,25 +538,32 @@
538 Because QRegExp is string oriented there are no \A, \Z or \z 538 Because QRegExp is string oriented there are no \A, \Z or \z
539 assertions. The \G assertion is not supported but can be emulated 539 assertions. The \G assertion is not supported but can be emulated
540 in a loop. 540 in a loop.
541 541
542 Perl's $& is cap(0) or capturedTexts()[0]. There are no QRegExp 542 Perl's $& is cap(0) or capturedTexts()[0]. There are no QRegExp
543 equivalents for $`, $' or $+. Perl's capturing variables, $1, $2, 543 equivalents for $`, $' or $+. Perl's capturing variables, $1, $2,
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
557 Non-capturing parentheses are also supported, with the same 564 Non-capturing parentheses are also supported, with the same
558 (?:pattern) syntax. 565 (?:pattern) syntax.
559 566
560 See QStringList::split() and QStringList::join() for equivalents 567 See QStringList::split() and QStringList::join() for equivalents
561 to Perl's split and join functions. 568 to Perl's split and join functions.
562 569
@@ -668,29 +675,29 @@
668 QStringList split() function can take a separator string or regexp 675 QStringList split() function can take a separator string or regexp
669 as an argument and split a string accordingly. 676 as an argument and split a string accordingly.
670 677
671 \code 678 \code
672 QStringList field = QStringList::split( "\t", str ); 679 QStringList field = QStringList::split( "\t", str );
673 \endcode 680 \endcode
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
691 also match 'test.html.bak'. A full regexp gives us the precision 698 also match 'test.html.bak'. A full regexp gives us the precision
692 we need, <b>.*\\.html?$</b>. 699 we need, <b>.*\\.html?$</b>.
693 700
694 QRegExp can match case insensitively using setCaseSensitive(), and 701 QRegExp can match case insensitively using setCaseSensitive(), and
695 can use non-greedy matching, see setMinimal(). By default QRegExp 702 can use non-greedy matching, see setMinimal(). By default QRegExp
696 uses full regexps but this can be changed with setWildcard(). 703 uses full regexps but this can be changed with setWildcard().
@@ -706,24 +713,29 @@
706 \target member-function-documentation 713 \target member-function-documentation
707*/ 714*/
708 715
709const int NumBadChars = 64; 716const int NumBadChars = 64;
710#define BadChar( ch ) ( (ch).unicode() % NumBadChars ) 717#define BadChar( ch ) ( (ch).unicode() % NumBadChars )
711 718
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();
724 int bsize = b.size(); 736 int bsize = b.size();
725 if ( asize == 0 ) { 737 if ( asize == 0 ) {
726 *a = b.copy(); 738 *a = b.copy();
727#ifndef QT_NO_REGEXP_OPTIM 739#ifndef QT_NO_REGEXP_OPTIM
728 } else if ( bsize == 1 && (*a)[asize - 1] < b[0] ) { 740 } else if ( bsize == 1 && (*a)[asize - 1] < b[0] ) {
729 a->resize( asize + 1 ); 741 a->resize( asize + 1 );
@@ -1671,27 +1683,27 @@ bool QRegExpEngine::testAnchor( int i, int a, const int *capBegin )
1671 if ( mmPos + i != mmCaretPos ) 1683 if ( mmPos + i != mmCaretPos )
1672 return FALSE; 1684 return FALSE;
1673 } 1685 }
1674 if ( (a & Anchor_Dollar) != 0 ) { 1686 if ( (a & Anchor_Dollar) != 0 ) {
1675 if ( mmPos + i != mmLen ) 1687 if ( mmPos + i != mmLen )
1676 return FALSE; 1688 return FALSE;
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
1692#ifndef QT_NO_REGEXP_LOOKAHEAD 1704#ifndef QT_NO_REGEXP_LOOKAHEAD
1693 bool catchx = TRUE; 1705 bool catchx = TRUE;
1694 1706
1695 if ( (a & Anchor_LookaheadMask) != 0 ) { 1707 if ( (a & Anchor_LookaheadMask) != 0 ) {
1696 QConstString cstr = QConstString( (QChar *) mmIn + mmPos + i, 1708 QConstString cstr = QConstString( (QChar *) mmIn + mmPos + i,
1697 mmLen - mmPos - i ); 1709 mmLen - mmPos - i );
@@ -2623,44 +2635,52 @@ int QRegExpEngine::getEscape()
2623 // see QChar::isDigit() 2635 // see QChar::isDigit()
2624 yyCharClass->addCategories( 0x7fffffef ); 2636 yyCharClass->addCategories( 0x7fffffef );
2625 return Tok_CharClass; 2637 return Tok_CharClass;
2626 case 'S': 2638 case 'S':
2627 // see QChar::isSpace() 2639 // see QChar::isSpace()
2628 yyCharClass->addCategories( 0x7ffff87f ); 2640 yyCharClass->addCategories( 0x7ffff87f );
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
2642#ifndef QT_NO_REGEXP_CCLASS 2661#ifndef QT_NO_REGEXP_CCLASS
2643 case 'd': 2662 case 'd':
2644 // see QChar::isDigit() 2663 // see QChar::isDigit()
2645 yyCharClass->addCategories( 0x00000010 ); 2664 yyCharClass->addCategories( 0x00000010 );
2646 return Tok_CharClass; 2665 return Tok_CharClass;
2647 case 's': 2666 case 's':
2648 // see QChar::isSpace() 2667 // see QChar::isSpace()
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++ ) {
2661 low = QChar( yyCh ).lower(); 2681 low = QChar( yyCh ).lower();
2662 if ( low >= '0' && low <= '9' ) 2682 if ( low >= '0' && low <= '9' )
2663 val = ( val << 4 ) | ( low - '0' ); 2683 val = ( val << 4 ) | ( low - '0' );
2664 else if ( low >= 'a' && low <= 'f' ) 2684 else if ( low >= 'a' && low <= 'f' )
2665 val = ( val << 4 ) | ( low - 'a' + 10 ); 2685 val = ( val << 4 ) | ( low - 'a' + 10 );
2666 else 2686 else
@@ -3174,45 +3194,47 @@ struct QRegExpPrivate
3174}; 3194};
3175 3195
3176#ifndef QT_NO_REGEXP_OPTIM 3196#ifndef QT_NO_REGEXP_OPTIM
3177static QCache<QRegExpEngine> *engineCache = 0; 3197static QCache<QRegExpEngine> *engineCache = 0;
3178static QSingleCleanupHandler<QCache<QRegExpEngine> > cleanup_cache; 3198static QSingleCleanupHandler<QCache<QRegExpEngine> > cleanup_cache;
3179#endif 3199#endif
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();
3193 return eng; 3214 return eng;
3194 } 3215 }
3195 } 3216 }
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() &&
3213 engineCache->insert(pattern, eng, 4 + pattern.length() / 4) ) 3235 engineCache->insert(pattern, eng, 4 + pattern.length() / 4) )
3214 return; 3236 return;
3215#else 3237#else
3216 Q_UNUSED( pattern ); 3238 Q_UNUSED( pattern );
3217#endif 3239#endif
3218 delete eng; 3240 delete eng;
@@ -3556,31 +3578,24 @@ bool QRegExp::exactMatch( const QString& str ) const
3556 \sa QString::mid() QConstString 3578 \sa QString::mid() QConstString
3557*/ 3579*/
3558int QRegExp::match( const QString& str, int index, int *len, 3580int QRegExp::match( const QString& str, int index, int *len,
3559 bool indexIsStart ) const 3581 bool indexIsStart ) const
3560{ 3582{
3561 int pos = search( str, index, indexIsStart ? CaretAtOffset : CaretAtZero ); 3583 int pos = search( str, index, indexIsStart ? CaretAtOffset : CaretAtZero );
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/*!
3581 Attempts to find a match in \a str from position \a offset (0 by 3596 Attempts to find a match in \a str from position \a offset (0 by
3582 default). If \a offset is -1, the search starts at the last 3597 default). If \a offset is -1, the search starts at the last
3583 character; if -2, at the next to last character; etc. 3598 character; if -2, at the next to last character; etc.
3584 3599
3585 Returns the position of the first match, or -1 if there was no 3600 Returns the position of the first match, or -1 if there was no
3586 match. 3601 match.
@@ -3616,31 +3631,24 @@ int QRegExp::search( const QString& str, int offset, CaretMode caretMode ) const
3616 if ( offset < 0 ) 3631 if ( offset < 0 )
3617 offset += str.length(); 3632 offset += str.length();
3618#ifndef QT_NO_REGEXP_CAPTURE 3633#ifndef QT_NO_REGEXP_CAPTURE
3619 priv->t = str; 3634 priv->t = str;
3620 priv->capturedCache.clear(); 3635 priv->capturedCache.clear();
3621#endif 3636#endif
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/*!
3641 Attempts to find a match backwards in \a str from position \a 3649 Attempts to find a match backwards in \a str from position \a
3642 offset. If \a offset is -1 (the default), the search starts at the 3650 offset. If \a offset is -1 (the default), the search starts at the
3643 last character; if -2, at the next to last character; etc. 3651 last character; if -2, at the next to last character; etc.
3644 3652
3645 Returns the position of the first match, or -1 if there was no 3653 Returns the position of the first match, or -1 if there was no
3646 match. 3654 match.
@@ -3685,25 +3693,25 @@ int QRegExp::searchRev( const QString& str, int offset,
3685/*! 3693/*!
3686 Returns the length of the last matched string, or -1 if there was 3694 Returns the length of the last matched string, or -1 if there was
3687 no match. 3695 no match.
3688 3696
3689 \sa exactMatch() search() searchRev() 3697 \sa exactMatch() search() searchRev()
3690*/ 3698*/
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}
3704 3712
3705 3713
3706 3714
3707/*! 3715/*!
3708 Returns a list of the captured text strings. 3716 Returns a list of the captured text strings.
3709 3717
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
@@ -174,62 +174,60 @@ int QSemaphore::operator--(int)
174 174
175/*! 175/*!
176 Try to get access to the semaphore. If \l available() \< \a n, this 176 Try to get access to the semaphore. If \l available() \< \a n, this
177 call will block until it can get all the accesses it wants, i.e. 177 call will block until it can get all the accesses it wants, i.e.
178 until available() \>= \a n. 178 until available() \>= \a n.
179*/ 179*/
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}
204 203
205 204
206/*! 205/*!
207 Release \a n accesses to the semaphore. 206 Release \a n accesses to the semaphore.
208*/ 207*/
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;
230} 228}
231 229
232 230
233/*! 231/*!
234 Returns the number of accesses currently available to the 232 Returns the number of accesses currently available to the
235 semaphore. 233 semaphore.
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,18 +1,18 @@
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
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.
15** 15**
16** This file may be distributed and/or modified under the terms of the 16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software 17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the 18** Foundation and appearing in the file LICENSE.GPL included in the
@@ -54,114 +54,143 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode )
54#ifndef QT_NO_SETTINGS 54#ifndef QT_NO_SETTINGS
55 55
56#include "qdir.h" 56#include "qdir.h"
57#include "qfile.h" 57#include "qfile.h"
58#include "qfileinfo.h" 58#include "qfileinfo.h"
59#include "qmap.h" 59#include "qmap.h"
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
95 /MyCompany/MyApplication/geometry/y 95 /MyCompany/MyApplication/geometry/y
96 /MyCompany/MyApplication/geometry/width 96 /MyCompany/MyApplication/geometry/width
97 /MyCompany/MyApplication/geometry/height 97 /MyCompany/MyApplication/geometry/height
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'.
131 146
132 QStringList keys = entryList( "/MyApplication/recent files" ); 147 QStringList keys = entryList( "/MyApplication/recent files" );
133 // keys contains '1', '2' and '3'. 148 // keys contains '1', '2' and '3'.
134 149
135 QStringList subkeys = subkeyList( "/MyApplication" ); 150 QStringList subkeys = subkeyList( "/MyApplication" );
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:
162 \list 1 191 \list 1
163 \i INSTALL/etc/settings 192 \i INSTALL/etc/settings
164 \i /opt/MyCompany/share/etc 193 \i /opt/MyCompany/share/etc
165 \i /opt/MyCompany/share/MyApplication/etc 194 \i /opt/MyCompany/share/MyApplication/etc
166 \i $HOME/.qt 195 \i $HOME/.qt
167 \endlist 196 \endlist
@@ -291,38 +320,38 @@ static HANDLE openlock( const QString &name, int /*type*/ )
291 return 0; 320 return 0;
292 321
293 return 0; 322 return 0;
294 323
295 HANDLE fd = 0; 324 HANDLE fd = 0;
296 325
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}
323#endif 352#endif
324 353
325 354
326QSettingsGroup::QSettingsGroup() 355QSettingsGroup::QSettingsGroup()
327 : modified(FALSE) 356 : modified(FALSE)
328{ 357{
@@ -446,27 +475,29 @@ void QSettingsHeading::parseLine(QTextStream &stream)
446#ifndef CSIDL_APPDATA 475#ifndef CSIDL_APPDATA
447#define CSIDL_APPDATA 0x001a // <user name>\Application Data 476#define CSIDL_APPDATA 0x001a // <user name>\Application Data
448#endif 477#endif
449#ifndef CSIDL_COMMON_APPDATA 478#ifndef CSIDL_COMMON_APPDATA
450#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data 479#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
451#endif 480#endif
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
467 TCHAR path[MAX_PATH]; 498 TCHAR path[MAX_PATH];
468 SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE ); 499 SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE );
469 appSettings = QString::fromUcs2( path ); 500 appSettings = QString::fromUcs2( path );
470 SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE ); 501 SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE );
471 defPath = QString::fromUcs2( path ); 502 defPath = QString::fromUcs2( path );
472#else 503#else
@@ -497,48 +528,52 @@ QSettingsPrivate::QSettingsPrivate( QSettings::Format format )
497#else 528#else
498// for now 529// for now
499#define QSETTINGS_DEFAULT_PATH_SUFFIX "/etc/settings" 530#define QSETTINGS_DEFAULT_PATH_SUFFIX "/etc/settings"
500 531
501 defPath = qInstallPath(); 532 defPath = qInstallPath();
502 defPath += QSETTINGS_DEFAULT_PATH_SUFFIX; 533 defPath += QSETTINGS_DEFAULT_PATH_SUFFIX;
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());
515} 548}
516 549
517QSettingsPrivate::~QSettingsPrivate() 550QSettingsPrivate::~QSettingsPrivate()
518{ 551{
519} 552}
520 553
521QSettingsGroup QSettingsPrivate::readGroup() 554QSettingsGroup QSettingsPrivate::readGroup()
522{ 555{
523 QSettingsHeading hd; 556 QSettingsHeading hd;
524 QSettingsGroup grp; 557 QSettingsGroup grp;
525 558
526 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading); 559 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading);
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());
539 } 574 }
540 } 575 }
541 576
542 headings.replace(heading, hd); 577 headings.replace(heading, hd);
543 578
544 grpit = hd.find(group); 579 grpit = hd.find(group);
@@ -555,24 +590,26 @@ void QSettingsPrivate::removeGroup(const QString &key)
555{ 590{
556 QSettingsHeading hd; 591 QSettingsHeading hd;
557 QSettingsGroup grp; 592 QSettingsGroup grp;
558 bool found = FALSE; 593 bool found = FALSE;
559 594
560 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading); 595 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading);
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());
573 } 610 }
574 } 611 }
575 612
576 headings.replace(heading, hd); 613 headings.replace(heading, hd);
577 614
578 grpit = hd.find(group); 615 grpit = hd.find(group);
@@ -606,24 +643,26 @@ void QSettingsPrivate::removeGroup(const QString &key)
606void QSettingsPrivate::writeGroup(const QString &key, const QString &value) 643void QSettingsPrivate::writeGroup(const QString &key, const QString &value)
607{ 644{
608 QSettingsHeading hd; 645 QSettingsHeading hd;
609 QSettingsGroup grp; 646 QSettingsGroup grp;
610 647
611 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading); 648 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading);
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());
624 } 663 }
625 } 664 }
626 665
627 headings.replace(heading, hd); 666 headings.replace(heading, hd);
628 667
629 grpit = hd.find(group); 668 grpit = hd.find(group);
@@ -640,86 +679,94 @@ void QSettingsPrivate::writeGroup(const QString &key, const QString &value)
640 modified = TRUE; 679 modified = TRUE;
641} 680}
642 681
643 682
644QDateTime QSettingsPrivate::modificationTime() 683QDateTime QSettingsPrivate::modificationTime()
645{ 684{
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.
678 725
679 When \a s is \e Windows and the execution environment is \e not 726 When \a s is \e Windows and the execution environment is \e not
680 Windows the function does nothing. Similarly when \a s is \e Unix and 727 Windows the function does nothing. Similarly when \a s is \e Unix and
681 the execution environment is \e not Unix the function does nothing. 728 the execution environment is \e not Unix the function does nothing.
682 729
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
696 \endlist 743 \endlist
697 744
698 \code 745 \code
699 QSettings settings; 746 QSettings settings;
700 settings.insertSearchPath( QSettings::Windows, "/MyCompany" ); 747 settings.insertSearchPath( QSettings::Windows, "/MyCompany" );
701 settings.writeEntry( "/MyApplication/Tip of the day", TRUE ); 748 settings.writeEntry( "/MyApplication/Tip of the day", TRUE );
702 \endcode 749 \endcode
703 The code above will write the subkey "Tip of the day" into the \e 750 The code above will write the subkey "Tip of the day" into the \e
704 first of the registry folders listed below that is found and for 751 first of the registry folders listed below that is found and for
705 which the user has write permission. 752 which the user has write permission.
706 \list 1 753 \list 1
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:
720 767
721 \list 1 768 \list 1
722 \i INSTALL/etc - where \c INSTALL is the directory where Qt was installed. 769 \i INSTALL/etc - where \c INSTALL is the directory where Qt was installed.
723 \i $HOME/.qt/ - where \c $HOME is the user's home directory. 770 \i $HOME/.qt/ - where \c $HOME is the user's home directory.
724 \endlist 771 \endlist
725 772
@@ -748,187 +795,204 @@ static inline QString groupKey( const QString &group, const QString &key )
748 first subkey of the key (not including the search path). The algorithm 795 first subkey of the key (not including the search path). The algorithm
749 for creating names is essentially: lowercase the first subkey, replace 796 for creating names is essentially: lowercase the first subkey, replace
750 spaces with underscores and add 'rc', e.g. 797 spaces with underscores and add 'rc', e.g.
751 <tt>/MyCompany/MyApplication/background color</tt> will be stored in 798 <tt>/MyCompany/MyApplication/background color</tt> will be stored in
752 <tt>myapplicationrc</tt> (assuming that <tt>/MyCompany</tt> is part of 799 <tt>myapplicationrc</tt> (assuming that <tt>/MyCompany</tt> is part of
753 the search path). 800 the search path).
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
794 settings search path for system \a s. Note that the default search 856 settings search path for system \a s. Note that the default search
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())
826 return; 888 return;
827 889
828 d->searchPaths.remove(path); 890 d->searchPaths.remove(path);
829} 891}
830 892
831 893
832/*! 894/*!
833 Creates a settings object. 895 Creates a settings object.
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/*!
847 Creates a settings object. If \a format is 'Ini' the settings will 909 Creates a settings object. If \a format is 'Ini' the settings will
848 be stored in a text file, using the Unix strategy (see above). If \a format 910 be stored in a text file, using the Unix strategy (see above). If \a format
849 is 'Native', the settings will be stored in a platform specific way 911 is 'Native', the settings will be stored in a platform specific way
850 (ie. the Windows registry). 912 (ie. the Windows registry).
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
864} 926}
865 927
866/*! 928/*!
867 Destroys the settings object. All modifications made to the settings 929 Destroys the settings object. All modifications made to the settings
868 will automatically be saved. 930 will automatically be saved.
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}
882 944
883 945
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;
897 959
898 bool success = TRUE; 960 bool success = TRUE;
899 QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin(); 961 QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin();
900 962
901 while (it != d->headings.end()) { 963 while (it != d->headings.end()) {
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;
929 continue; 993 continue;
930 } 994 }
931 995
932 HANDLE lockfd = openlock( file.name(), Q_LOCKWRITE ); 996 HANDLE lockfd = openlock( file.name(), Q_LOCKWRITE );
933 997
934 if (! file.open(IO_WriteOnly)) { 998 if (! file.open(IO_WriteOnly)) {
@@ -954,31 +1018,31 @@ bool QSettings::sync()
954 QSettingsGroup::Iterator grpit = grp.begin(); 1018 QSettingsGroup::Iterator grpit = grp.begin();
955 1019
956 while (grpit != grp.end()) { 1020 while (grpit != grp.end()) {
957 QString v = grpit.data(); 1021 QString v = grpit.data();
958 if ( v.isNull() ) { 1022 if ( v.isNull() ) {
959 v = "\\0"; // escape null string 1023 v = "\\0"; // escape null string
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");
979#endif // QT_CHECK_STATE 1043#endif // QT_CHECK_STATE
980 1044
981 success = FALSE; 1045 success = FALSE;
982 } 1046 }
983 1047
984 file.close(); 1048 file.close();
@@ -999,41 +1063,40 @@ bool QSettings::sync()
999 default value, \a def, if the entry couldn't be read. 1063 default value, \a def, if the entry couldn't be read.
1000 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE 1064 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
1001 otherwise. 1065 otherwise.
1002 1066
1003 \sa readEntry(), readNumEntry(), readDoubleEntry(), writeEntry(), removeEntry() 1067 \sa readEntry(), readNumEntry(), readDoubleEntry(), writeEntry(), removeEntry()
1004*/ 1068*/
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")
1034 return TRUE; 1097 return TRUE;
1035 else if (value == "0") 1098 else if (value == "0")
1036 return FALSE; 1099 return FALSE;
1037 1100
1038 if (! value.isEmpty()) 1101 if (! value.isEmpty())
1039 qWarning("QSettings::readBoolEntry: '%s' is not 'true' or 'false'", 1102 qWarning("QSettings::readBoolEntry: '%s' is not 'true' or 'false'",
@@ -1051,41 +1114,40 @@ bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok )
1051 default value, \a def, if the entry couldn't be read. 1114 default value, \a def, if the entry couldn't be read.
1052 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE 1115 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
1053 otherwise. 1116 otherwise.
1054 1117
1055 \sa readEntry(), readNumEntry(), readBoolEntry(), writeEntry(), removeEntry() 1118 \sa readEntry(), readNumEntry(), readBoolEntry(), writeEntry(), removeEntry()
1056*/ 1119*/
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",
1086 value.latin1() ); 1148 value.latin1() );
1087 if ( ok ) 1149 if ( ok )
1088 *ok = FALSE; 1150 *ok = FALSE;
1089 return def; 1151 return def;
1090} 1152}
1091 1153
@@ -1097,41 +1159,39 @@ double QSettings::readDoubleEntry(const QString &key, double def, bool *ok )
1097 default value, \a def, if the entry couldn't be read. 1159 default value, \a def, if the entry couldn't be read.
1098 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE 1160 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
1099 otherwise. 1161 otherwise.
1100 1162
1101 \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry() 1163 \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry()
1102*/ 1164*/
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",
1132 value.latin1() ); 1192 value.latin1() );
1133 if ( ok ) 1193 if ( ok )
1134 *ok = FALSE; 1194 *ok = FALSE;
1135 return def; 1195 return def;
1136} 1196}
1137 1197
@@ -1143,37 +1203,37 @@ int QSettings::readNumEntry(const QString &key, int def, bool *ok )
1143 default value, \a def, if the entry couldn't be read. 1203 default value, \a def, if the entry couldn't be read.
1144 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE 1204 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
1145 otherwise. 1205 otherwise.
1146 1206
1147 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry() 1207 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry()
1148*/ 1208*/
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;
1174 1234
1175 QString realkey; 1235 QString realkey;
1176 1236
1177 if (theKey[0] == '/') { 1237 if (theKey[0] == '/') {
1178 // parse our key 1238 // parse our key
1179 QStringList list(QStringList::split('/', theKey)); 1239 QStringList list(QStringList::split('/', theKey));
@@ -1197,182 +1257,176 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
1197 1257
1198 // remove the group from the list 1258 // remove the group from the list
1199 list.remove(list.at(1)); 1259 list.remove(list.at(1));
1200 // remove the heading from the list 1260 // remove the heading from the list
1201 list.remove(list.at(0)); 1261 list.remove(list.at(0));
1202 1262
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/*!
1220 Writes the boolean entry \a value into key \a key. The \a key is 1282 Writes the boolean entry \a value into key \a key. The \a key is
1221 created if it doesn't exist. Any previous value is overwritten by \a 1283 created if it doesn't exist. Any previous value is overwritten by \a
1222 value. 1284 value.
1223 1285
1224 If an error occurs the settings are left unchanged and FALSE is 1286 If an error occurs the settings are left unchanged and FALSE is
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
1252 Writes the double entry \a value into key \a key. The \a key is 1312 Writes the double entry \a value into key \a key. The \a key is
1253 created if it doesn't exist. Any previous value is overwritten by \a 1313 created if it doesn't exist. Any previous value is overwritten by \a
1254 value. 1314 value.
1255 1315
1256 If an error occurs the settings are left unchanged and FALSE is 1316 If an error occurs the settings are left unchanged and FALSE is
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
1284 created if it doesn't exist. Any previous value is overwritten by \a 1342 created if it doesn't exist. Any previous value is overwritten by \a
1285 value. 1343 value.
1286 1344
1287 If an error occurs the settings are left unchanged and FALSE is 1345 If an error occurs the settings are left unchanged and FALSE is
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
1315 Writes the entry specified by \a key with the string-literal \a value, 1371 Writes the entry specified by \a key with the string-literal \a value,
1316 replacing any previous setting. If \a value is zero-length or null, the 1372 replacing any previous setting. If \a value is zero-length or null, the
1317 entry is replaced by an empty setting. 1373 entry is replaced by an empty setting.
1318 1374
1319 \e NOTE: This function is provided because some compilers use the 1375 \e NOTE: This function is provided because some compilers use the
1320 writeEntry (const QString &, bool) overload for this code: 1376 writeEntry (const QString &, bool) overload for this code:
1321 writeEntry ("/foo/bar", "baz") 1377 writeEntry ("/foo/bar", "baz")
1322 1378
1323 If an error occurs, this functions returns FALSE and the object is left 1379 If an error occurs, this functions returns FALSE and the object is left
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
1346 created if it doesn't exist. Any previous value is overwritten by \a 1400 created if it doesn't exist. Any previous value is overwritten by \a
1347 value. If \a value is an empty string or a null string the key's 1401 value. If \a value is an empty string or a null string the key's
1348 value will be an empty string. 1402 value will be an empty string.
1349 1403
1350 If an error occurs the settings are left unchanged and FALSE is 1404 If an error occurs the settings are left unchanged and FALSE is
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;
1373 1427
1374 if (theKey[0] == '/') { 1428 if (theKey[0] == '/') {
1375 // parse our key 1429 // parse our key
1376 QStringList list(QStringList::split('/', theKey)); 1430 QStringList list(QStringList::split('/', theKey));
1377 1431
1378 if (list.count() < 2) { 1432 if (list.count() < 2) {
@@ -1406,34 +1460,34 @@ bool QSettings::writeEntry(const QString &key, const QString &value)
1406} 1460}
1407 1461
1408 1462
1409/*! 1463/*!
1410 Removes the entry specified by \a key. 1464 Removes the entry specified by \a key.
1411 1465
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
1434 if (theKey[0] == '/') { 1488 if (theKey[0] == '/') {
1435 // parse our key 1489 // parse our key
1436 QStringList list(QStringList::split('/', theKey)); 1490 QStringList list(QStringList::split('/', theKey));
1437 1491
1438 if (list.count() < 2) { 1492 if (list.count() < 2) {
1439#ifdef QT_CHECK_STATE 1493#ifdef QT_CHECK_STATE
@@ -1485,34 +1539,34 @@ bool QSettings::removeEntry(const QString &key)
1485 \c keys contains 'background color' and 'foreground color'. It does 1539 \c keys contains 'background color' and 'foreground color'. It does
1486 not contain 'geometry' because this key contains keys not entries. 1540 not contain 'geometry' because this key contains keys not entries.
1487 1541
1488 To access the geometry values could either use subkeyList() to read 1542 To access the geometry values could either use subkeyList() to read
1489 the keys and then read each entry, or simply read each entry 1543 the keys and then read each entry, or simply read each entry
1490 directly by specifying its full key, e.g. 1544 directly by specifying its full key, e.g.
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] == '/') {
1513 // parse our key 1567 // parse our key
1514 QStringList list(QStringList::split('/', theKey)); 1568 QStringList list(QStringList::split('/', theKey));
1515 1569
1516 if (list.count() < 1) { 1570 if (list.count() < 1) {
1517#ifdef QT_CHECK_STATE 1571#ifdef QT_CHECK_STATE
1518 qWarning("QSettings::listEntries: invalid key '%s'", theKey.latin1()); 1572 qWarning("QSettings::listEntries: invalid key '%s'", theKey.latin1());
@@ -1535,25 +1589,25 @@ QStringList QSettings::entryList(const QString &key) const
1535 1589
1536 realkey = list.join("/"); 1590 realkey = list.join("/");
1537 } 1591 }
1538 } else 1592 } else
1539 realkey = theKey; 1593 realkey = theKey;
1540 1594
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 );
1554 } 1608 }
1555 1609
1556 if ( itkey.find( '/' ) != -1 ) 1610 if ( itkey.find( '/' ) != -1 )
1557 continue; 1611 continue;
1558 1612
1559 ret << itkey; 1613 ret << itkey;
@@ -1582,75 +1636,90 @@ QStringList QSettings::entryList(const QString &key) const
1582 \code 1636 \code
1583 QStringList keys = subkeyList( "/MyCompany/MyApplication" ); 1637 QStringList keys = subkeyList( "/MyCompany/MyApplication" );
1584 \endcode 1638 \endcode
1585 \c keys contains 'geometry' and 'recent files'. It does not contain 1639 \c keys contains 'geometry' and 'recent files'. It does not contain
1586 'background color' or 'foreground color' because they are keys which 1640 'background color' or 'foreground color' because they are keys which
1587 contain entries not keys. To get a list of keys that have values 1641 contain entries not keys. To get a list of keys that have values
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];
1627 1684
1628 // remove the group from the list 1685 // remove the group from the list
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 );
1651 } 1720 }
1652 1721
1653 int slash = itkey.find( '/' ); 1722 int slash = itkey.find( '/' );
1654 if ( slash == -1 ) 1723 if ( slash == -1 )
1655 continue; 1724 continue;
1656 itkey.truncate( slash ); 1725 itkey.truncate( slash );
@@ -1661,34 +1730,34 @@ QStringList QSettings::subkeyList(const QString &key) const
1661 1730
1662 return ret; 1731 return ret;
1663} 1732}
1664 1733
1665 1734
1666/*! 1735/*!
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
1689 QStringList list(QStringList::split('/', theKey)); 1758 QStringList list(QStringList::split('/', theKey));
1690 1759
1691 if (list.count() < 2) { 1760 if (list.count() < 2) {
1692#ifdef QT_CHECK_STATE 1761#ifdef QT_CHECK_STATE
1693 qWarning("QSettings::lastModficationTime: invalid key '%s'", theKey.latin1()); 1762 qWarning("QSettings::lastModficationTime: invalid key '%s'", theKey.latin1());
1694#endif // QT_CHECK_STATE 1763#endif // QT_CHECK_STATE
@@ -1706,27 +1775,35 @@ QDateTime QSettings::lastModficationTime(const QString &key)
1706 } 1775 }
1707 1776
1708 return d->modificationTime(); 1777 return d->modificationTime();
1709} 1778}
1710 1779
1711 1780
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*/
1727bool QSettings::writeEntry(const QString &key, const QStringList &value, 1804bool QSettings::writeEntry(const QString &key, const QStringList &value,
1728 const QChar &separator) 1805 const QChar &separator)
1729{ 1806{
1730 QString s(value.join(separator)); 1807 QString s(value.join(separator));
1731 return writeEntry(key, s); 1808 return writeEntry(key, s);
1732} 1809}
@@ -1759,24 +1836,31 @@ bool QSettings::writeEntry(const QString &key, const QStringList &value)
1759 return writeEntry(key, s); 1836 return writeEntry(key, s);
1760} 1837}
1761 1838
1762 1839
1763/*! 1840/*!
1764 \overload QStringList QSettings::readListEntry(const QString &key, const QChar &separator, bool *ok ) const 1841 \overload QStringList QSettings::readListEntry(const QString &key, const QChar &separator, bool *ok ) const
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() ) {
1777 myProcessing( *it ); 1861 myProcessing( *it );
1778 ++it; 1862 ++it;
1779 } 1863 }
1780 \endcode 1864 \endcode
1781 1865
1782 \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry(), QStringList::split() 1866 \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry(), QStringList::split()
@@ -1838,89 +1922,110 @@ QStringList QSettings::readListEntry(const QString &key, bool *ok )
1838 esc=FALSE; 1922 esc=FALSE;
1839 } else if ( value[i] == '^' ) { 1923 } else if ( value[i] == '^' ) {
1840 esc = TRUE; 1924 esc = TRUE;
1841 } else { 1925 } else {
1842 s.append(value[i]); 1926 s.append(value[i]);
1843 if ( i == (int)value.length()-1 ) 1927 if ( i == (int)value.length()-1 )
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
1869// HKEY_CURRENT_USER. Note that on some installations, not all users can 1960// HKEY_CURRENT_USER. Note that on some installations, not all users can
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}
1921 2026
1922/*! 2027/*!
1923 Set the current key prefix to the empty string. 2028 Set the current key prefix to the empty string.
1924*/ 2029*/
1925void QSettings::resetGroup() 2030void QSettings::resetGroup()
1926{ 2031{
@@ -1936,20 +2041,20 @@ void QSettings::resetGroup()
1936*/ 2041*/
1937QString QSettings::group() const 2042QString QSettings::group() const
1938{ 2043{
1939 if ( d->groupDirty ) { 2044 if ( d->groupDirty ) {
1940 d->groupDirty = FALSE; 2045 d->groupDirty = FALSE;
1941 d->groupPrefix = QString::null; 2046 d->groupPrefix = QString::null;
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
1955#endif 2060#endif
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
@@ -1,20 +1,20 @@
1/**************************************************************************** 1/****************************************************************************
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.
15** 15**
16** This file may be distributed and/or modified under the terms of the 16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software 17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the 18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file. 19** packaging of this file.
20** 20**
@@ -38,36 +38,40 @@
38// Don't define it while compiling this module, or USERS of Qt will 38// Don't define it while compiling this module, or USERS of Qt will
39// not be able to link. 39// not be able to link.
40#ifdef QT_NO_CAST_ASCII 40#ifdef QT_NO_CAST_ASCII
41#undef QT_NO_CAST_ASCII 41#undef QT_NO_CAST_ASCII
42#endif 42#endif
43 43
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 *
68 * Lars 72 * Lars
69 * ------------------------------------------------------------------------- 73 * -------------------------------------------------------------------------
70 */ 74 */
71 75
72/* Perl script to generate (run perl -x tools/qstring.cpp) 76/* Perl script to generate (run perl -x tools/qstring.cpp)
73 77
@@ -11778,36 +11782,38 @@ static inline QChar upper( const QChar &c )
11778 else 11782 else
11779 return QChar( toupper((uchar) c.latin1()) ); 11783 return QChar( toupper((uchar) c.latin1()) );
11780#endif 11784#endif
11781} 11785}
11782 11786
11783static inline QChar::Direction direction( const QChar &c ) 11787static 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[] = {
11808 0x0028, 0x0029, 0x003C, 0x003E, 0x005B, 0x005D, 0x007B, 0x007D, 11814 0x0028, 0x0029, 0x003C, 0x003E, 0x005B, 0x005D, 0x007B, 0x007D,
11809 0x00AB, 0x00BB, 0x2039, 0x203A, 0x2045, 0x2046, 0x207D, 0x207E, 11815 0x00AB, 0x00BB, 0x2039, 0x203A, 0x2045, 0x2046, 0x207D, 0x207E,
11810 0x208D, 0x208E, 0x2208, 0x220B, 0x2209, 0x220C, 0x220A, 0x220D, 11816 0x208D, 0x208E, 0x2208, 0x220B, 0x2209, 0x220C, 0x220A, 0x220D,
11811 0x2215, 0x29F5, 0x223C, 0x223D, 0x2243, 0x22CD, 0x2252, 0x2253, 11817 0x2215, 0x29F5, 0x223C, 0x223D, 0x2243, 0x22CD, 0x2252, 0x2253,
11812 0x2254, 0x2255, 0x2264, 0x2265, 0x2266, 0x2267, 0x2268, 0x2269, 11818 0x2254, 0x2255, 0x2264, 0x2265, 0x2266, 0x2267, 0x2268, 0x2269,
11813 0x226A, 0x226B, 0x226E, 0x226F, 0x2270, 0x2271, 0x2272, 0x2273, 11819 0x226A, 0x226B, 0x226E, 0x226F, 0x2270, 0x2271, 0x2272, 0x2273,
@@ -11891,25 +11897,25 @@ static int ucstrnicmp( const QChar *a, const QChar *b, int l )
11891 while ( l-- && ::lower( *a ) == ::lower( *b ) ) 11897 while ( l-- && ::lower( *a ) == ::lower( *b ) )
11892 a++,b++; 11898 a++,b++;
11893 if ( l==-1 ) 11899 if ( l==-1 )
11894 return 0; 11900 return 0;
11895 return ::lower( *a ).unicode() - ::lower( *b ).unicode(); 11901 return ::lower( *a ).unicode() - ::lower( *b ).unicode();
11896} 11902}
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/*!
11910 \class QCharRef qstring.h 11916 \class QCharRef qstring.h
11911 \reentrant 11917 \reentrant
11912 \brief The QCharRef class is a helper class for QString. 11918 \brief The QCharRef class is a helper class for QString.
11913 11919
11914 \ingroup text 11920 \ingroup text
11915 11921
@@ -12882,44 +12888,44 @@ void QString::compose()
12882#define QT_ALLOC_QCHAR_VEC( N ) (QChar*) new char[ sizeof(QChar)*( N ) ] 12888#define QT_ALLOC_QCHAR_VEC( N ) (QChar*) new char[ sizeof(QChar)*( N ) ]
12883#define QT_DELETE_QCHAR_VEC( P ) delete[] ((char*)( P )) 12889#define QT_DELETE_QCHAR_VEC( P ) delete[] ((char*)( P ))
12884 12890
12885 12891
12886/*! 12892/*!
12887 This utility function converts the 8-bit string \a ba to Unicode, 12893 This utility function converts the 8-bit string \a ba to Unicode,
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;
12901 while ( l < (int)ba.size() && ba[l] ) 12907 while ( l < (int)ba.size() && ba[l] )
12902 l++; 12908 l++;
12903 char* str = ba.data(); 12909 char* str = ba.data();
12904 QChar *uc = new QChar[ l ]; // Can't use macro, since function is public 12910 QChar *uc = new QChar[ l ]; // Can't use macro, since function is public
12905 QChar *result = uc; 12911 QChar *result = uc;
12906 if ( len ) 12912 if ( 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;
12920 while ( l < (int)ba.size() && ba[l] ) 12926 while ( l < (int)ba.size() && ba[l] )
12921 l++; 12927 l++;
12922 char* str = ba.data(); 12928 char* str = ba.data();
12923 QChar *uc = QT_ALLOC_QCHAR_VEC( l ); 12929 QChar *uc = QT_ALLOC_QCHAR_VEC( l );
12924 QChar *result = uc; 12930 QChar *result = uc;
12925 if ( len ) 12931 if ( len )
@@ -12931,79 +12937,79 @@ static QChar* internalAsciiToUnicode( const QByteArray& ba, uint* len )
12931 12937
12932/*! 12938/*!
12933 \overload 12939 \overload
12934 12940
12935 This utility function converts the '\0'-terminated 8-bit string \a 12941 This utility function converts the '\0'-terminated 8-bit string \a
12936 str to Unicode, returning the result and setting \a *len to the 12942 str to Unicode, returning the result and setting \a *len to the
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++;
12984 } 12990 }
12985 if ( len ) 12991 if ( len )
12986 *len = l; 12992 *len = l;
12987 return result; 12993 return result;
12988} 12994}
12989 12995
12990/*! 12996/*!
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;
13004 while (l--) { 13010 while (l--) {
13005 *a++ = (uc->unicode() > 0xff) ? '?' : (char)uc->unicode(); 13011 *a++ = (uc->unicode() > 0xff) ? '?' : (char)uc->unicode();
13006 uc++; 13012 uc++;
13007 } 13013 }
13008 *a = '\0'; 13014 *a = '\0';
13009 return result; 13015 return result;
@@ -13148,53 +13154,24 @@ QT_STATIC_CONST_IMPL QChar QChar::byteOrderSwapped((ushort)0xfffe);
13148QT_STATIC_CONST_IMPL QChar QChar::nbsp((ushort)0x00a0); 13154QT_STATIC_CONST_IMPL QChar QChar::nbsp((ushort)0x00a0);
13149 13155
13150QStringData* QString::makeSharedNull() 13156QStringData* QString::makeSharedNull()
13151{ 13157{
13152 QString::shared_null = new QStringData; 13158 QString::shared_null = new QStringData;
13153#if defined( Q_OS_MAC ) 13159#if defined( Q_OS_MAC )
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
13195 \sa isNull() 13172 \sa isNull()
13196*/ 13173*/
13197 13174
13198/*! 13175/*!
13199 Constructs a string of length one, containing the character \a ch. 13176 Constructs a string of length one, containing the character \a ch.
13200*/ 13177*/
@@ -13202,65 +13179,67 @@ QString::QString( QChar ch )
13202{ 13179{
13203 d = new QStringData( QT_ALLOC_QCHAR_VEC( 1 ), 1, 1 ); 13180 d = new QStringData( QT_ALLOC_QCHAR_VEC( 1 ), 1, 1 );
13204 d->unicode[0] = ch; 13181 d->unicode[0] = ch;
13205} 13182}
13206 13183
13207/*! 13184/*!
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
13221 Private function. 13197 Private function.
13222 13198
13223 Constructs a string with preallocated space for \a size characters. 13199 Constructs a string with preallocated space for \a size characters.
13224 13200
13225 The string is empty. 13201 The string is empty.
13226 13202
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.
13261 13240
13262 If \a unicode and \a length are 0, then a null string is created. 13241 If \a unicode and \a length are 0, then a null string is created.
13263 13242
13264 If only \a unicode is 0, the string is empty but has \a length 13243 If only \a unicode is 0, the string is empty but has \a length
13265 characters of space preallocated: QString expands automatically 13244 characters of space preallocated: QString expands automatically
13266 anyway, but this may speed up some cases a little. We recommend 13245 anyway, but this may speed up some cases a little. We recommend
@@ -13293,30 +13272,57 @@ QString::QString( const QChar* unicode, uint length )
13293 Latin1 const char* to QString preserves all the information. You 13272 Latin1 const char* to QString preserves all the information. You
13294 can disable this constructor by defining \c QT_NO_CAST_ASCII when 13273 can disable this constructor by defining \c QT_NO_CAST_ASCII when
13295 you compile your applications. You can also make QString objects 13274 you compile your applications. You can also make QString objects
13296 by using setLatin1(), fromLatin1(), fromLocal8Bit(), and 13275 by using setLatin1(), fromLatin1(), fromLocal8Bit(), and
13297 fromUtf8(). Or whatever encoding is appropriate for the 8-bit data 13276 fromUtf8(). Or whatever encoding is appropriate for the 8-bit data
13298 you have. 13277 you have.
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.
13317*/ 13323*/
13318 13324
13319 13325
13320/*! 13326/*!
13321 Deallocates any space reserved solely by this QString. 13327 Deallocates any space reserved solely by this QString.
13322 13328
@@ -13324,91 +13330,99 @@ QString::QString( const char *str )
13324 instance, nothing happens; otherwise the function creates a new, 13330 instance, nothing happens; otherwise the function creates a new,
13325 unique copy of this string. This function is called whenever the 13331 unique copy of this string. This function is called whenever the
13326 string is modified. 13332 string is modified.
13327*/ 13333*/
13328 13334
13329void QString::real_detach() 13335void 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;
13346} 13352}
13347 13353
13348/*! 13354/*!
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*/
13361 13376
13362/*! 13377/*!
13363 \overload 13378 \overload
13364 13379
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
13378/*! 13392/*!
13379 \overload 13393 \overload
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
13393 Assigns a deep copy of \a str, interpreted as a classic C string 13407 Assigns a deep copy of \a str, interpreted as a classic C string
13394 to this string and returns a reference to this string. 13408 to this string and returns a reference to this string.
13395 13409
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
13409 Returns TRUE if the string is null; otherwise returns FALSE. A 13423 Returns TRUE if the string is null; otherwise returns FALSE. A
13410 null string is always empty. 13424 null string is always empty.
13411 13425
13412 \code 13426 \code
13413 QString a; // a.unicode() == 0, a.length() == 0 13427 QString a; // a.unicode() == 0, a.length() == 0
13414 a.isNull(); // TRUE, because a.unicode() == 0 13428 a.isNull(); // TRUE, because a.unicode() == 0
@@ -13462,98 +13476,94 @@ QString &QString::operator=( const char *str )
13462 13476
13463void QString::truncate( uint newLen ) 13477void QString::truncate( uint newLen )
13464{ 13478{
13465 if ( newLen < d->len ) 13479 if ( newLen < d->len )
13466 setLength( newLen ); 13480 setLength( newLen );
13467} 13481}
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.
13482 13495
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()
13501*/ 13514*/
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 );
13516 deref(); 13527 deref();
13517 d = new QStringData( nd, newLen, newMax ); 13528 d = new QStringData( nd, newLen, newMax );
13518 } 13529 }
13519 } else { 13530 } else {
13520 d->len = newLen; 13531 d->len = newLen;
13521 d->setDirty(); 13532 d->setDirty();
13522 } 13533 }
13523} 13534}
13524 13535
13525/*! 13536/*!
13526 This function will return a string that replaces the lowest 13537 This function will return a string that replaces the lowest
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*/
13554QString QString::arg( const QString& a, int fieldwidth ) const 13564QString QString::arg( const QString& a, int fieldwidth ) const
13555{ 13565{
13556 int pos, len; 13566 int pos, len;
13557 QString r = *this; 13567 QString r = *this;
13558 13568
13559 if ( !findArg( pos, len ) ) { 13569 if ( !findArg( pos, len ) ) {
@@ -13765,25 +13775,25 @@ bool QString::findArg( int& pos, int& len ) const
13765 13775
13766#ifndef QT_NO_SPRINTF 13776#ifndef QT_NO_SPRINTF
13767QString &QString::sprintf( const char* cformat, ... ) 13777QString &QString::sprintf( const char* cformat, ... )
13768{ 13778{
13769 va_list ap; 13779 va_list ap;
13770 va_start( ap, cformat ); 13780 va_start( ap, 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;
13784 13794
13785 for (;;) { 13795 for (;;) {
13786 pos = escape.search( format, last ); 13796 pos = escape.search( format, last );
13787 len = escape.matchedLength(); 13797 len = escape.matchedLength();
13788 // Non-escaped text 13798 // Non-escaped text
13789 if ( pos > (int)last ) 13799 if ( pos > (int)last )
@@ -13904,25 +13914,25 @@ QString &QString::sprintf( const char* cformat, ... )
13904 switch ( params ) { 13914 switch ( params ) {
13905 case 0: 13915 case 0:
13906 ::sprintf( out, in, value ); 13916 ::sprintf( out, in, value );
13907 break; 13917 break;
13908 case 1: 13918 case 1:
13909 ::sprintf( out, in, width, value ); 13919 ::sprintf( out, in, width, value );
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 );
13923 return *this; 13933 return *this;
13924} 13934}
13925#endif 13935#endif
13926 13936
13927/*! 13937/*!
13928 Fills the string with \a len characters of value \a c, and returns 13938 Fills the string with \a len characters of value \a c, and returns
@@ -14115,26 +14125,28 @@ static int bm_find( const QString &str, int index, const QString &pattern, uint
14115 14125
14116int QString::find( const QString& str, int index, bool cs ) const 14126int QString::find( const QString& str, int index, bool cs ) const
14117{ 14127{
14118 const uint l = length(); 14128 const uint l = length();
14119 const uint sl = str.length(); 14129 const uint sl = str.length();
14120 if ( index < 0 ) 14130 if ( index < 0 )
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];
14135 bm_init_skiptable( str, skiptable, cs ); 14147 bm_init_skiptable( str, skiptable, cs );
14136 return bm_find( *this, index, str, skiptable, cs ); 14148 return bm_find( *this, index, str, skiptable, cs );
14137 } 14149 }
14138 14150
14139 /* 14151 /*
14140 We use some hashing for efficiency's sake. Instead of 14152 We use some hashing for efficiency's sake. Instead of
@@ -14212,40 +14224,44 @@ int QString::find( const QString& str, int index, bool cs ) const
14212 14224
14213 If \a cs is TRUE, the search is case sensitive; otherwise the 14225 If \a cs is TRUE, the search is case sensitive; otherwise the
14214 search is case insensitive. 14226 search is case insensitive.
14215 14227
14216 \code 14228 \code
14217 QString string( "bananas" ); 14229 QString string( "bananas" );
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();
14230 register const QChar *uc = end + index; 14245 register const QChar *uc = end + index;
14231 if ( cs ) { 14246 if ( cs ) {
14232 while ( uc >= end && *uc != c ) 14247 while ( uc >= end && *uc != c )
14233 uc--; 14248 uc--;
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
14246 position \a index and searching backwards. If the index is -1, the 14262 position \a index and searching backwards. If the index is -1, the
14247 search starts at the last character, if it is -2, at the next to 14263 search starts at the last character, if it is -2, at the next to
14248 last character and so on. 14264 last character and so on.
14249 14265
14250 Returns the position of \a str or -1 if \a str could not be found. 14266 Returns the position of \a str or -1 if \a str could not be found.
14251 14267
@@ -14264,26 +14280,28 @@ int QString::findRev( const QString& str, int index, bool cs ) const
14264 See QString::find() for explanations. 14280 See QString::find() for explanations.
14265 */ 14281 */
14266 const uint l = length(); 14282 const uint l = length();
14267 if ( index < 0 ) 14283 if ( index < 0 )
14268 index += l; 14284 index += l;
14269 const uint sl = str.length(); 14285 const uint sl = str.length();
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;
14284 const QChar* h = haystack+sl_minus_1; 14302 const QChar* h = haystack+sl_minus_1;
14285 uint hashNeedle = 0, hashHaystack = 0, i; 14303 uint hashNeedle = 0, hashHaystack = 0, i;
14286 14304
14287 if ( cs ) { 14305 if ( cs ) {
14288 for ( i = 0; i < sl; ++i ) { 14306 for ( i = 0; i < sl; ++i ) {
14289 hashNeedle = ((hashNeedle<<1) + (n-i)->unicode() ); 14307 hashNeedle = ((hashNeedle<<1) + (n-i)->unicode() );
@@ -14970,65 +14988,75 @@ QString QString::rightJustify( uint width, QChar fill, bool truncate ) const
14970 Returns a lowercase copy of the string. 14988 Returns a lowercase copy of the string.
14971 14989
14972 \code 14990 \code
14973 QString string( "TROlltECH" ); 14991 QString string( "TROlltECH" );
14974 str = string.lower(); // str == "trolltech" 14992 str = string.lower(); // str == "trolltech"
14975 \endcode 14993 \endcode
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
15001 QString string( "TeXt" ); 15024 QString string( "TeXt" );
15002 str = string.upper(); // t == "TEXT" 15025 str = string.upper(); // t == "TEXT"
15003 \endcode 15026 \endcode
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.
15029 15057
15030 Whitespace means any character for which QChar::isSpace() returns 15058 Whitespace means any character for which QChar::isSpace() returns
15031 TRUE. This includes Unicode characters with decimal values 9 15059 TRUE. This includes Unicode characters with decimal values 9
15032 (TAB), 10 (LF), 11 (VT), 12 (FF), 13 (CR) and 32 (Space), and may 15060 (TAB), 10 (LF), 11 (VT), 12 (FF), 13 (CR) and 32 (Space), and may
15033 also include other Unicode characters. 15061 also include other Unicode characters.
15034 15062
@@ -15128,26 +15156,26 @@ QString QString::simplifyWhiteSpace() const
15128 \sa remove(), replace() 15156 \sa remove(), replace()
15129*/ 15157*/
15130 15158
15131QString &QString::insert( uint index, const QString &s ) 15159QString &QString::insert( uint index, const QString &s )
15132{ 15160{
15133 // the sub function takes care of &s == this case. 15161 // the sub function takes care of &s == this case.
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;
15148 uint olen = length(); 15176 uint olen = length();
15149 int nlen = olen + len; 15177 int nlen = olen + len;
15150 15178
15151 if ( s >= d->unicode && (uint)(s - d->unicode) < d->maxl ) { 15179 if ( s >= d->unicode && (uint)(s - d->unicode) < d->maxl ) {
15152 // Part of me - take a copy. 15180 // Part of me - take a copy.
15153 QChar *tmp = QT_ALLOC_QCHAR_VEC( len ); 15181 QChar *tmp = QT_ALLOC_QCHAR_VEC( len );
@@ -15242,24 +15270,34 @@ QString &QString::insert( uint index, QChar c ) // insert char
15242*/ 15270*/
15243 15271
15244/*! \fn QString& QString::prepend( const QByteArray &s ) 15272/*! \fn QString& QString::prepend( const QByteArray &s )
15245 \overload 15273 \overload
15246 15274
15247 Inserts \a s at the beginning of the string and returns a reference to the string. 15275 Inserts \a s at the beginning of the string and returns a reference to the string.
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).
15260 15298
15261 \sa insert() 15299 \sa insert()
15262 */ 15300 */
15263QString &QString::prepend( const char *s ) 15301QString &QString::prepend( const char *s )
15264{ 15302{
15265 return insert( 0, QString(s) ); 15303 return insert( 0, QString(s) );
@@ -15839,27 +15877,27 @@ static bool ok_in_base( QChar c, int base )
15839 Returns the string converted to a \c long value to the base \a 15877 Returns the string converted to a \c long value to the base \a
15840 base, which is 10 by default and must be between 2 and 36. 15878 base, which is 10 by default and must be between 2 and 36.
15841 15879
15842 If \a ok is not 0: if a conversion error occurs, \a *ok is set to 15880 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
15843 FALSE; otherwise \a *ok is set to TRUE. 15881 FALSE; otherwise \a *ok is set to TRUE.
15844 15882
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++;
15860 if ( !l ) 15898 if ( !l )
15861 goto bye; 15899 goto bye;
15862 if ( *p == '-' ) { 15900 if ( *p == '-' ) {
15863 l--; 15901 l--;
15864 p++; 15902 p++;
15865 neg = 1; 15903 neg = 1;
@@ -15874,82 +15912,80 @@ long QString::toLong( bool *ok, int base ) const
15874 while ( l && ok_in_base(*p,base) ) { 15912 while ( l && ok_in_base(*p,base) ) {
15875 l--; 15913 l--;
15876 int dv; 15914 int dv;
15877 if ( p->isDigit() ) { 15915 if ( p->isDigit() ) {
15878 dv = p->digitValue(); 15916 dv = p->digitValue();
15879 } else { 15917 } else {
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
15907 If \a ok is not 0: if a conversion error occurs, \a *ok is set to 15943 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
15908 FALSE; otherwise \a *ok is set to TRUE. 15944 FALSE; otherwise \a *ok is set to TRUE.
15909 15945
15910 \sa number() 15946 \sa number()
15911*/ 15947*/
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 )
15925 goto bye; 15961 goto bye;
15926 if ( *p == '+' ) 15962 if ( *p == '+' )
15927 l--,p++; 15963 l--,p++;
15928 15964
15929 // NOTE: toLong() code is similar 15965 // NOTE: toLong() code is similar
15930 if ( !l || !ok_in_base(*p,base) ) 15966 if ( !l || !ok_in_base(*p,base) )
15931 goto bye; 15967 goto bye;
15932 while ( l && ok_in_base(*p,base) ) { 15968 while ( l && ok_in_base(*p,base) ) {
15933 l--; 15969 l--;
15934 uint dv; 15970 uint dv;
15935 if ( p->isDigit() ) { 15971 if ( p->isDigit() ) {
15936 dv = p->digitValue(); 15972 dv = p->digitValue();
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
15950 l--,p++; 15986 l--,p++;
15951 if ( !l ) 15987 if ( !l )
15952 is_ok = TRUE; 15988 is_ok = TRUE;
15953bye: 15989bye:
15954 if ( ok ) 15990 if ( ok )
15955 *ok = is_ok; 15991 *ok = is_ok;
@@ -15958,44 +15994,44 @@ bye:
15958 15994
15959/*! 15995/*!
15960 Returns the string converted to a \c short value to the base \a 15996 Returns the string converted to a \c short value to the base \a
15961 base, which is 10 by default and must be between 2 and 36. 15997 base, which is 10 by default and must be between 2 and 36.
15962 15998
15963 If \a ok is not 0: if a conversion error occurs, \a *ok is set to 15999 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
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
15977/*! 16013/*!
15978 Returns the string converted to an \c {unsigned short} value to 16014 Returns the string converted to an \c {unsigned short} value to
15979 the base \a base, which is 10 by default and must be between 2 and 16015 the base \a base, which is 10 by default and must be between 2 and
15980 36. 16016 36.
15981 16017
15982 If \a ok is not 0: if a conversion error occurs, \a *ok is set to 16018 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
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
15996 16032
15997/*! 16033/*!
15998 Returns the string converted to an \c int value to the base \a 16034 Returns the string converted to an \c int value to the base \a
15999 base, which is 10 by default and must be between 2 and 36. 16035 base, which is 10 by default and must be between 2 and 36.
16000 16036
16001 If \a ok is not 0: if a conversion error occurs, \a *ok is set to 16037 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
@@ -16004,64 +16040,74 @@ ushort QString::toUShort( bool *ok, int base ) const
16004 \code 16040 \code
16005 QString str( "FF" ); 16041 QString str( "FF" );
16006 bool ok; 16042 bool ok;
16007 int hex = str.toInt( &ok, 16 ); // hex == 255, ok == TRUE 16043 int hex = str.toInt( &ok, 16 ); // hex == 255, ok == TRUE
16008 int dec = str.toInt( &ok, 10 ); // dec == 0, ok == FALSE 16044 int dec = str.toInt( &ok, 10 ); // dec == 0, ok == FALSE
16009 \endcode 16045 \endcode
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
16023 If \a ok is not 0: if a conversion error occurs, \a *ok is set to 16064 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
16024 FALSE; otherwise \a *ok is set to TRUE. 16065 FALSE; otherwise \a *ok is set to TRUE.
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
16038 FALSE; otherwise \a *ok is set to TRUE. 16084 FALSE; otherwise \a *ok is set to TRUE.
16039 16085
16040 \code 16086 \code
16041 QString string( "1234.56" ); 16087 QString string( "1234.56" );
16042 double a = string.toDouble(); // a == 1234.56 16088 double a = string.toDouble(); // a == 1234.56
16043 \endcode 16089 \endcode
16044 16090
16045 \sa number() 16091 \sa number()
16046*/ 16092*/
16047 16093
16048double QString::toDouble( bool *ok ) const 16094double 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
16062 If \a ok is not 0: if a conversion error occurs, \a *ok is set to 16108 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
16063 FALSE; otherwise \a *ok is set to TRUE. 16109 FALSE; otherwise \a *ok is set to TRUE.
16064 16110
16065 \sa number() 16111 \sa number()
16066*/ 16112*/
16067 16113
@@ -16089,29 +16135,29 @@ QString &QString::setNum( long n, int base )
16089 if ( base < 2 || base > 36 ) { 16135 if ( base < 2 || base > 36 ) {
16090 qWarning( "QString::setNum: Invalid base %d", base ); 16136 qWarning( "QString::setNum: Invalid base %d", base );
16091 base = 10; 16137 base = 10;
16092 } 16138 }
16093#endif 16139#endif
16094 char charbuf[65*sizeof(QChar)]; 16140 char charbuf[65*sizeof(QChar)];
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;
16112 } 16158 }
16113 do { 16159 do {
16114 *--p = "0123456789abcdefghijklmnopqrstuvwxyz"[((int)(n%base))]; 16160 *--p = "0123456789abcdefghijklmnopqrstuvwxyz"[((int)(n%base))];
16115 n /= base; 16161 n /= base;
16116 ++len; 16162 ++len;
16117 } while ( n ); 16163 } while ( n );
@@ -16452,24 +16498,33 @@ void QString::setExpand( uint index, QChar c )
16452 16498
16453 Equivalent to operator+=(). 16499 Equivalent to operator+=().
16454*/ 16500*/
16455 16501
16456/*! \fn QString& QString::append( const QByteArray &str ) 16502/*! \fn QString& QString::append( const QByteArray &str )
16457 \overload 16503 \overload
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+=().
16470 */ 16525 */
16471 16526
16472/*! 16527/*!
16473 Appends \a str to the string and returns a reference to the string. 16528 Appends \a str to the string and returns a reference to the string.
16474*/ 16529*/
16475QString& QString::operator+=( const QString &str ) 16530QString& QString::operator+=( const QString &str )
@@ -16481,122 +16536,158 @@ QString& QString::operator+=( const QString &str )
16481 memcpy( d->unicode+len1, str.unicode(), sizeof(QChar)*len2 ); 16536 memcpy( d->unicode+len1, str.unicode(), sizeof(QChar)*len2 );
16482 } else if ( isNull() && !str.isNull() ) { // ## just for 1.x compat: 16537 } else if ( isNull() && !str.isNull() ) { // ## just for 1.x compat:
16483 *this = fromLatin1( "" ); 16538 *this = fromLatin1( "" );
16484 } 16539 }
16485 return *this; 16540 return *this;
16486} 16541}
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 ) {
16502 d->unicode[len1+i] = str[i]; 16563 d->unicode[len1+i] = str[i];
16503 i++; 16564 i++;
16504 } 16565 }
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
16517QString &QString::operator+=( QChar c ) 16579QString &QString::operator+=( QChar c )
16518{ 16580{
16519 setLength(length()+1); 16581 setLength(length()+1);
16520 d->unicode[length()-1] = c; 16582 d->unicode[length()-1] = c;
16521 return *this; 16583 return *this;
16522} 16584}
16523 16585
16524/*! 16586/*!
16525 \overload 16587 \overload
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);
16597 uchar* cursor = (uchar*)rstr.data(); 16688 uchar* cursor = (uchar*)rstr.data();
16598 const QChar *ch = d->unicode; 16689 const QChar *ch = d->unicode;
16599 for (int i=0; i<l; i++) { 16690 for (int i=0; i<l; i++) {
16600 ushort u = ch->unicode(); 16691 ushort u = ch->unicode();
16601 if ( u < 0x80 ) { 16692 if ( u < 0x80 ) {
16602 *cursor++ = (uchar)u; 16693 *cursor++ = (uchar)u;
@@ -16624,25 +16715,26 @@ QCString QString::utf8() const
16624 \code 16715 \code
16625 QString str = QString::fromUtf8( "123456789", 5 ); 16716 QString str = QString::fromUtf8( "123456789", 5 );
16626 // str == "12345" 16717 // str == "12345"
16627 \endcode 16718 \endcode
16628 16719
16629 See QTextCodec for more diverse coding/decoding of Unicode strings. 16720 See QTextCodec for more diverse coding/decoding of Unicode strings.
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++) {
16643 uchar ch = utf8[i]; 16735 uchar ch = utf8[i];
16644 if (need) { 16736 if (need) {
16645 if ( (ch&0xc0) == 0x80 ) { 16737 if ( (ch&0xc0) == 0x80 ) {
16646 uc = (uc << 6) | (ch & 0x3f); 16738 uc = (uc << 6) | (ch & 0x3f);
16647 need--; 16739 need--;
16648 if ( !need ) { 16740 if ( !need ) {
@@ -16665,91 +16757,120 @@ QString QString::fromUtf8( const char* utf8, int len )
16665 } else if ( (ch&0xf0) == 0xe0 ) { 16757 } else if ( (ch&0xf0) == 0xe0 ) {
16666 uc = ch &0x0f; 16758 uc = ch &0x0f;
16667 need = 2; 16759 need = 2;
16668 } 16760 }
16669 } 16761 }
16670 } 16762 }
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
16705 Returns the Unicode representation of the string. The result 16827 Returns the Unicode representation of the string. The result
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
16728 QTextCodec* codec = QTextCodec::codecForLocale(); 16849 QTextCodec* codec = QTextCodec::codecForLocale();
16729 return codec 16850 return codec
16730 ? codec->fromUnicode(*this) 16851 ? codec->fromUnicode(*this)
16731 : QCString(latin1()); 16852 : QCString(latin1());
16732#endif 16853#endif
16733#if defined( Q_WS_MACX ) 16854#if defined( Q_WS_MACX )
16734 return utf8(); 16855 return utf8();
16735#endif 16856#endif
16736#if defined( Q_WS_MAC9 ) 16857#if defined( Q_WS_MAC9 )
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
16750 characters of \a local8Bit, ignoring the rest of \a local8Bit. If 16871 characters of \a local8Bit, ignoring the rest of \a local8Bit. If
16751 \a len is -1 then the length of \a local8Bit is used. If \a len is 16872 \a len is -1 then the length of \a local8Bit is used. If \a len is
16752 bigger than the length of \a local8Bit then it will use the length 16873 bigger than the length of \a local8Bit then it will use the length
16753 of \a local8Bit. 16874 of \a local8Bit.
16754 16875
16755 \code 16876 \code
@@ -16762,25 +16883,26 @@ QCString QString::local8Bit() const
16762 See QTextCodec for more diverse coding/decoding of Unicode strings. 16883 See QTextCodec for more diverse coding/decoding of Unicode strings.
16763*/ 16884*/
16764QString QString::fromLocal8Bit( const char* local8Bit, int len ) 16885QString QString::fromLocal8Bit( const char* local8Bit, int len )
16765{ 16886{
16766#ifdef QT_NO_TEXTCODEC 16887#ifdef QT_NO_TEXTCODEC
16767 return fromLatin1( local8Bit, len ); 16888 return fromLatin1( local8Bit, 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);
16781#endif 16903#endif
16782// Should this be OS_WIN32? 16904// Should this be OS_WIN32?
16783#ifdef Q_WS_WIN 16905#ifdef Q_WS_WIN
16784 if ( len >= 0 ) { 16906 if ( len >= 0 ) {
16785 QCString s(local8Bit,len+1); 16907 QCString s(local8Bit,len+1);
16786 return qt_winMB2QString(s); 16908 return qt_winMB2QString(s);
@@ -16795,41 +16917,45 @@ QString QString::fromLocal8Bit( const char* local8Bit, int len )
16795 16917
16796/*! 16918/*!
16797 \fn QString::operator const char *() const 16919 \fn QString::operator const char *() const
16798 16920
16799 Returns latin1(). Be sure to see the warnings documented in the 16921 Returns latin1(). Be sure to see the warnings documented in the
16800 latin1() function. Note that for new code which you wish to be 16922 latin1() function. Note that for new code which you wish to be
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
16813 copy of the source string exists. 16941 copy of the source string exists.
16814*/ 16942*/
16815const unsigned short *QString::ucs2() const 16943const 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();
16830 ((QString *)this)->d = new QStringData( nd, len, newMax ); 16956 ((QString *)this)->d = new QStringData( nd, len, newMax );
16831 } 16957 }
16832 } 16958 }
16833 d->unicode[len] = 0; 16959 d->unicode[len] = 0;
16834 return (unsigned short *) d->unicode; 16960 return (unsigned short *) d->unicode;
16835} 16961}
@@ -16974,26 +17100,24 @@ void QString::subat( uint i )
16974 17100
16975QString& QString::setUnicode( const QChar *unicode, uint len ) 17101QString& QString::setUnicode( const QChar *unicode, uint len )
16976{ 17102{
16977 if ( len == 0 ) { // set to null string 17103 if ( len == 0 ) { // set to null string
16978 if ( d != shared_null ) { // beware of nullstring being set to nullstring 17104 if ( d != shared_null ) { // beware of nullstring being set to nullstring
16979 deref(); 17105 deref();
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 );
16994 } else { 17118 } else {
16995 d->len = len; 17119 d->len = len;
16996 d->setDirty(); 17120 d->setDirty();
16997 if ( unicode ) 17121 if ( unicode )
16998 memcpy( d->unicode, unicode, sizeof(QChar)*len ); 17122 memcpy( d->unicode, unicode, sizeof(QChar)*len );
16999 } 17123 }
@@ -17009,67 +17133,89 @@ QString& QString::setUnicode( const QChar *unicode, uint len )
17009 is still resized to \a len. If \a len is zero, the string becomes 17133 is still resized to \a len. If \a len is zero, the string becomes
17010 a \link isNull() null\endlink string. 17134 a \link isNull() null\endlink string.
17011 17135
17012 \sa setLatin1(), isNull() 17136 \sa setLatin1(), isNull()
17013*/ 17137*/
17014QString& QString::setUnicodeCodes( const ushort* unicode_as_ushorts, uint len ) 17138QString& 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.
17027 17173
17028 \sa isNull(), isEmpty() 17174 \sa isNull(), isEmpty()
17029*/ 17175*/
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-- )
17043 *p++ = *str++; 17189 *p++ = *str++;
17044 } 17190 }
17045 return *this; 17191 return *this;
17046} 17192}
17047 17193
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
17070/*! \internal 17216/*! \internal
17071 */ 17217 */
17072bool QString::isRightToLeft() const 17218bool QString::isRightToLeft() const
17073{ 17219{
17074 int len = length(); 17220 int len = length();
17075 QChar *p = d->unicode; 17221 QChar *p = d->unicode;
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
@@ -1080,25 +1080,25 @@ QTextStream &QTextStream::writeBlock( const QChar* p, uint len )
1080{ 1080{
1081#ifndef QT_NO_TEXTCODEC 1081#ifndef QT_NO_TEXTCODEC
1082 if ( mapper ) { 1082 if ( mapper ) {
1083 if ( !d->encoder ) 1083 if ( !d->encoder )
1084 d->encoder = mapper->makeEncoder(); 1084 d->encoder = mapper->makeEncoder();
1085 QConstString s( p, len ); 1085 QConstString s( p, 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 );
1099 } 1099 }
1100 dev->writeBlock( (char*)p, sizeof(QChar)*len ); 1100 dev->writeBlock( (char*)p, sizeof(QChar)*len );
1101 } else { 1101 } else {
1102 for (uint i=0; i<len; i++) 1102 for (uint i=0; i<len; i++)
1103 ts_putc( p[i] ); 1103 ts_putc( p[i] );
1104 } 1104 }
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
@@ -287,149 +287,96 @@ const QUuid TID_QUType_int( 0x53c1f3be, 0x73c3, 0x4c7d, 0x9e, 0x5, 0xcc, 0xf0, 0
287QUType_int static_QUType_int; 287QUType_int static_QUType_int;
288const QUuid *QUType_int::uuid() const { return &TID_QUType_int; } 288const QUuid *QUType_int::uuid() const { return &TID_QUType_int; }
289const char *QUType_int::desc() const { return "int"; } 289const char *QUType_int::desc() const { return "int"; }
290 290
291void QUType_int::set( QUObject *o, int v ) 291void QUType_int::set( QUObject *o, int v )
292{ 292{
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 * )
339{ 332{
340 return 0; 333 return 0;
341} 334}
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
396void QUType_double::set( QUObject *o, double v ) 347void QUType_double::set( QUObject *o, double v )
397{ 348{
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
430bool QUType_double::convertTo( QUObject *o, QUType *t ) 377bool QUType_double::convertTo( QUObject *o, QUType *t )
431{ 378{
432 if ( isEqual( t, &static_QUType_int ) ) { 379 if ( isEqual( t, &static_QUType_int ) ) {
433 o->payload.i = (int) o->payload.d; 380 o->payload.i = (int) o->payload.d;
434 o->type = &static_QUType_int; 381 o->type = &static_QUType_int;
435 } else if ( isEqual( t, &static_QUType_double ) ) { 382 } else if ( isEqual( t, &static_QUType_double ) ) {
@@ -441,88 +388,24 @@ bool QUType_double::convertTo( QUObject *o, QUType *t )
441} 388}
442 389
443int QUType_double::serializeTo( QUObject *, QUBuffer * ) 390int QUType_double::serializeTo( QUObject *, QUBuffer * )
444{ 391{
445 return 0; 392 return 0;
446} 393}
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
523void QUType_charstar::set( QUObject *o, const char* v, bool take ) 406void QUType_charstar::set( QUObject *o, const char* v, bool take )
524{ 407{
525 if ( take ) { 408 if ( take ) {
526 if ( v ) { 409 if ( v ) {
527 o->payload.charstar.ptr = new char[ strlen(v) + 1 ]; 410 o->payload.charstar.ptr = new char[ strlen(v) + 1 ];
528 strcpy( o->payload.charstar.ptr, v ); 411 strcpy( o->payload.charstar.ptr, v );
@@ -584,75 +467,68 @@ const QUuid *QUType_QString::uuid() const { return &TID_QUType_QString; }
584const char *QUType_QString::desc() const { return "QString"; } 467const char *QUType_QString::desc() const { return "QString"; }
585 468
586void QUType_QString::set( QUObject *o, const QString& v ) 469void QUType_QString::set( QUObject *o, const QString& v )
587{ 470{
588 o->payload.ptr = new QString( v ); 471 o->payload.ptr = new QString( v );
589 o->type = this; 472 o->type = this;
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 );
626 o->payload.ptr = str; 505 o->payload.ptr = str;
627 o->type = this; 506 o->type = this;
628 return TRUE; 507 return TRUE;
629} 508}
630 509
631bool QUType_QString::convertTo( QUObject *o, QUType *t ) 510bool QUType_QString::convertTo( QUObject *o, QUType *t )
632{ 511{
633 QString *str = (QString *)o->payload.ptr; 512 QString *str = (QString *)o->payload.ptr;
634 if ( isEqual( t, &static_QUType_charstar ) ) { 513 if ( isEqual( t, &static_QUType_charstar ) ) {
635 o->payload.charstar.ptr = qstrdup( str->local8Bit().data() ); 514 o->payload.charstar.ptr = qstrdup( str->local8Bit().data() );
636 o->payload.charstar.owner = TRUE; 515 o->payload.charstar.owner = TRUE;
637 o->type = &static_QUType_charstar; 516 o->type = &static_QUType_charstar;
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}
653 529
654int QUType_QString::serializeTo( QUObject *, QUBuffer * ) 530int QUType_QString::serializeTo( QUObject *, QUBuffer * )
655{ 531{
656 return 0; 532 return 0;
657} 533}
658 534
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
@@ -115,25 +115,25 @@ struct QWaitConditionPrivate {
115 mymutex.unlock(); 115 mymutex.unlock();
116 do_something(); 116 do_something();
117 mymutex.lock(); 117 mymutex.lock();
118 mycount--; 118 mycount--;
119 mymutex.unlock(); 119 mymutex.unlock();
120 } 120 }
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();
134 } 134 }
135 \endcode 135 \endcode
136 136
137 The mutexes are necessary because the results of two threads 137 The mutexes are necessary because the results of two threads
138 attempting to change the value of the same variable simultaneously 138 attempting to change the value of the same variable simultaneously
139 are unpredictable. 139 are unpredictable.
@@ -215,45 +215,50 @@ void QWaitCondition::wakeAll()
215 \i Another thread signals it using wakeOne() or wakeAll(). This 215 \i Another thread signals it using wakeOne() or wakeAll(). This
216 function will return TRUE in this case. 216 function will return TRUE in this case.
217 \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the 217 \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the
218 default), then the wait will never timeout (the event must be 218 default), then the wait will never timeout (the event must be
219 signalled). This function will return FALSE if the wait timed 219 signalled). This function will return FALSE if the wait timed
220 out. 220 out.
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
254 Release the locked \a mutex and wait on the thread event object. 259 Release the locked \a mutex and wait on the thread event object.
255 The \a mutex must be initially locked by the calling thread. If \a 260 The \a mutex must be initially locked by the calling thread. If \a
256 mutex is not in a locked state, this function returns immediately. 261 mutex is not in a locked state, this function returns immediately.
257 If \a mutex is a recursive mutex, this function returns 262 If \a mutex is a recursive mutex, this function returns
258 immediately. The \a mutex will be unlocked, and the calling thread 263 immediately. The \a mutex will be unlocked, and the calling thread
259 will block until either of these conditions is met: 264 will block until either of these conditions is met:
@@ -282,25 +287,25 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
282 qWarning("Wait condition warning: using recursive mutexes with\n" 287 qWarning("Wait condition warning: using recursive mutexes with\n"
283 " wait conditions is undefined!"); 288 " wait conditions is undefined!");
284#endif 289#endif
285 return FALSE; 290 return FALSE;
286 } 291 }
287 292
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);
301 306
302#ifdef QT_CHECK_RANGE 307#ifdef QT_CHECK_RANGE
303 if (ret && ret != ETIMEDOUT) 308 if (ret && ret != ETIMEDOUT)
304 qWarning("Wait condition wait failure: %s",strerror(ret)); 309 qWarning("Wait condition wait failure: %s",strerror(ret));
305#endif 310#endif
306 311