1 /****************************************************************************
2 ** $Id: qt/qglobal.cpp 3.3.8 edited Jan 25 12:14 $
3 **
4 ** Global functions
5 **
6 ** Created : 920604
7 **
8 ** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
9 **
10 ** This file is part of the tools module of the Qt GUI Toolkit.
11 **
12 ** This file may be distributed under the terms of the Q Public License
13 ** as defined by Trolltech ASA of Norway and appearing in the file
14 ** LICENSE.QPL included in the packaging of this file.
15 **
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
18 ** Foundation and appearing in the file LICENSE.GPL included in the
19 ** packaging of this file.
20 **
21 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22 ** licenses may use this file in accordance with the Qt Commercial License
23 ** Agreement provided with the Software.
24 **
25 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27 **
28 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29 ** information about Qt Commercial License Agreements.
30 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
31 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
32 **
33 ** Contact info@trolltech.com if any conditions of this licensing are
34 ** not clear to you.
35 **
36 **********************************************************************/
37
38 #include "qplatformdefs.h"
39
40 #include "qasciidict.h"
41 #include <limits.h>
42 #include <stdio.h>
43 #include <limits.h>
44 #include <stdarg.h>
45 #include <stdlib.h>
46
47 #if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) && !defined(Q_OS_TEMP)
48 #include <crtdbg.h>
49 #endif
50
51
52 /*!
53 \relates QApplication
54
55 Returns the Qt version number as a string, for example, "2.3.0" or
56 "3.0.5".
57
58 The \c QT_VERSION define has the numeric value in the form:
59 0xmmiibb (m = major, i = minor, b = bugfix). For example, Qt
60 3.0.5's \c QT_VERSION is 0x030005.
61 */
62
qVersion()63 const char *qVersion()
64 {
65 return QT_VERSION_STR;
66 }
67
qSharedBuild()68 bool qSharedBuild()
69 {
70 #ifdef QT_SHARED
71 return TRUE;
72 #else
73 return FALSE;
74 #endif
75 }
76
77 /*****************************************************************************
78 System detection routines
79 *****************************************************************************/
80
81 static bool si_alreadyDone = FALSE;
82 static int si_wordSize;
83 static bool si_bigEndian;
84
85 /*!
86 \relates QApplication
87
88 Obtains information about the system.
89
90 The system's word size in bits (typically 32) is returned in \a
91 *wordSize. The \a *bigEndian is set to TRUE if this is a big-endian
92 machine, or to FALSE if this is a little-endian machine.
93
94 In debug mode, this function calls qFatal() with a message if the
95 computer is truly weird (i.e. different endianness for 16 bit and
96 32 bit integers); in release mode it returns FALSE.
97 */
98
qSysInfo(int * wordSize,bool * bigEndian)99 bool qSysInfo( int *wordSize, bool *bigEndian )
100 {
101 #if defined(QT_CHECK_NULL)
102 Q_ASSERT( wordSize != 0 );
103 Q_ASSERT( bigEndian != 0 );
104 #endif
105
106 if ( si_alreadyDone ) { // run it only once
107 *wordSize = si_wordSize;
108 *bigEndian = si_bigEndian;
109 return TRUE;
110 }
111
112 si_wordSize = 0;
113 Q_ULONG n = (Q_ULONG)(~0);
114 while ( n ) { // detect word size
115 si_wordSize++;
116 n /= 2;
117 }
118 *wordSize = si_wordSize;
119
120 if ( *wordSize != 64 &&
121 *wordSize != 32 &&
122 *wordSize != 16 ) { // word size: 16, 32 or 64
123 #if defined(QT_CHECK_RANGE)
124 qFatal( "qSysInfo: Unsupported system word size %d", *wordSize );
125 #endif
126 return FALSE;
127 }
128 if ( sizeof(Q_INT8) != 1 || sizeof(Q_INT16) != 2 || sizeof(Q_INT32) != 4 ||
129 sizeof(Q_ULONG)*8 != si_wordSize || sizeof(float) != 4 || sizeof(double) != 8 ) {
130 #if defined(QT_CHECK_RANGE)
131 qFatal( "qSysInfo: Unsupported system data type size" );
132 #endif
133 return FALSE;
134 }
135
136 bool be16, be32; // determine byte ordering
137 short ns = 0x1234;
138 int nl = 0x12345678;
139
140 unsigned char *p = (unsigned char *)(&ns); // 16-bit integer
141 be16 = *p == 0x12;
142
143 p = (unsigned char *)(&nl); // 32-bit integer
144 if ( p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 )
145 be32 = TRUE;
146 else
147 if ( p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] == 0x12 )
148 be32 = FALSE;
149 else
150 be32 = !be16;
151
152 if ( be16 != be32 ) { // strange machine!
153 #if defined(QT_CHECK_RANGE)
154 qFatal( "qSysInfo: Inconsistent system byte order" );
155 #endif
156 return FALSE;
157 }
158
159 *bigEndian = si_bigEndian = be32;
160 si_alreadyDone = TRUE;
161 return TRUE;
162 }
163
164 #if !defined(QWS) && defined(Q_OS_MAC)
165
166 #include "qt_mac.h"
167
168 // This function has descended from Apple Source Code (FSpLocationFromFullPath),
169 // but changes have been made. [Creates a minimal alias from the full pathname]
qt_mac_create_fsspec(const QString & file,FSSpec * spec)170 OSErr qt_mac_create_fsspec(const QString &file, FSSpec *spec)
171 {
172 FSRef fref;
173 QCString utfs = file.utf8();
174 OSErr ret = FSPathMakeRef((const UInt8 *)utfs.data(), &fref, NULL);
175 if(ret == noErr)
176 ret = FSGetCatalogInfo(&fref, kFSCatInfoNone, NULL, NULL, spec, NULL);
177 return ret;
178 }
179
qstring2cfstring(const QString & str)180 CFStringRef qstring2cfstring(const QString &str)
181 {
182 return CFStringCreateWithCharacters(0, (UniChar *)str.unicode(), str.length());
183 }
184
cfstring2qstring(CFStringRef str)185 QString cfstring2qstring(CFStringRef str)
186 {
187 if(!str)
188 return QString();
189
190 CFIndex length = CFStringGetLength(str);
191 if(const UniChar *chars = CFStringGetCharactersPtr(str))
192 return QString((QChar *)chars, length);
193 UniChar *buffer = (UniChar*)malloc(length * sizeof(UniChar));
194 CFStringGetCharacters(str, CFRangeMake(0, length), buffer);
195 QString ret((QChar *)buffer, length);
196 free(buffer);
197 return ret;
198 }
199
p_str(const QString & s)200 unsigned char *p_str(const QString &s)
201 {
202 CFStringRef cfstr = qstring2cfstring(s);
203 uchar *p = (uchar*)malloc(256);
204 CFStringGetPascalString(cfstr, p, 256, CFStringGetSystemEncoding());
205 CFRelease(cfstr);
206 return p;
207 }
208
p2qstring(const unsigned char * c)209 QString p2qstring(const unsigned char *c) {
210 CFStringRef cfstr = CFStringCreateWithPascalString(0, c, CFStringGetSystemEncoding());
211 QString str = cfstring2qstring(cfstr);
212 CFRelease(cfstr);
213 return str;
214 }
215
qMacVersion()216 int qMacVersion()
217 {
218 static int macver = Qt::MV_Unknown;
219 static bool first = TRUE;
220 if(first) {
221 first = FALSE;
222 long gestalt_version;
223 if(Gestalt(gestaltSystemVersion, &gestalt_version) == noErr) {
224 macver = ((gestalt_version & 0x00f0) >> 4) + 2;
225
226 }
227 }
228 return macver;
229 }
230 Qt::MacintoshVersion qt_macver = (Qt::MacintoshVersion)qMacVersion();
231
232 // HFS+ filesystems use decomposing unicode for certain layers in unicode
233 // In general these don't look great as a user visible string.
234 // Therefore it is a good idea to normalize them ourselves.
235 // These technotes on Apple's website:
236 // http://developer.apple.com/qa/qa2001/qa1235.html
237 // http://developer.apple.com/qa/qa2001/qa1173.html
qt_mac_precomposeFileName(const QString & str)238 QString qt_mac_precomposeFileName(const QString &str)
239 {
240 if (str.isEmpty())
241 return str;
242 int strLength = str.length();
243 CFMutableStringRef cfmstr = CFStringCreateMutable(0, strLength);
244 CFStringAppendCharacters(cfmstr, (UniChar *)str.unicode(), strLength);
245 CFStringNormalize(cfmstr, kCFStringNormalizationFormC);
246 QString newStr = cfstring2qstring(cfmstr);
247 CFRelease(cfmstr);
248 return newStr;
249 }
250 #elif defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN) || defined(Q_OS_TEMP)
251 bool qt_winunicode;
252 # ifdef Q_OS_TEMP
253 DWORD qt_cever = 0;
254 # endif // Q_OS_TEMP
255
256 #include "qt_windows.h"
257
qWinVersion()258 int qWinVersion()
259 {
260 #ifndef VER_PLATFORM_WIN32s
261 #define VER_PLATFORM_WIN32s 0
262 #endif
263 #ifndef VER_PLATFORM_WIN32_WINDOWS
264 #define VER_PLATFORM_WIN32_WINDOWS 1
265 #endif
266 #ifndef VER_PLATFORM_WIN32_NT
267 #define VER_PLATFORM_WIN32_NT 2
268 #endif
269 #ifndef VER_PLATFORM_WIN32_CE
270 #define VER_PLATFORM_WIN32_CE 3
271 #endif
272
273 static int winver = Qt::WV_NT;
274 static int t=0;
275 if ( !t ) {
276 t=1;
277 #ifndef Q_OS_TEMP
278 OSVERSIONINFOA osver;
279 osver.dwOSVersionInfoSize = sizeof(osver);
280 GetVersionExA( &osver );
281 #else
282 OSVERSIONINFOW osver;
283 osver.dwOSVersionInfoSize = sizeof(osver);
284 GetVersionEx( &osver );
285 qt_cever = osver.dwMajorVersion * 100;
286 qt_cever += osver.dwMinorVersion * 10;
287 #endif
288 switch ( osver.dwPlatformId ) {
289 case VER_PLATFORM_WIN32s:
290 winver = Qt::WV_32s;
291 break;
292 case VER_PLATFORM_WIN32_WINDOWS:
293 // We treat Windows Me (minor 90) the same as Windows 98
294 if ( osver.dwMinorVersion == 90 )
295 winver = Qt::WV_Me;
296 else if ( osver.dwMinorVersion == 10 )
297 winver = Qt::WV_98;
298 else
299 winver = Qt::WV_95;
300 break;
301 case VER_PLATFORM_WIN32_CE:
302 #ifdef Q_OS_TEMP
303 if ( qt_cever >= 400 )
304 winver = Qt::WV_CENET;
305 else
306 #endif
307 winver = Qt::WV_CE;
308 break;
309 default: // VER_PLATFORM_WIN32_NT
310 if ( osver.dwMajorVersion < 5 ) {
311 winver = Qt::WV_NT;
312 } else if (osver.dwMajorVersion == 6) {
313 winver = Qt::WV_VISTA;
314 } else if ( osver.dwMinorVersion == 0 ) {
315 winver = Qt::WV_2000;
316 } else if ( osver.dwMinorVersion == 1 ) {
317 winver = Qt::WV_XP;
318 } else if ( osver.dwMinorVersion == 2 ) {
319 winver = Qt::WV_2003;
320 } else {
321 qWarning("Untested Windows version detected!");
322 winver = Qt::WV_NT_based;
323 }
324 }
325 }
326
327 #if defined(UNICODE)
328 if ( winver & Qt::WV_NT_based )
329 qt_winunicode = TRUE;
330 else
331 #endif
332 qt_winunicode = FALSE;
333
334 return winver;
335 }
336
337 Qt::WindowsVersion qt_winver = (Qt::WindowsVersion)qWinVersion();
338 #endif
339
340
341 /*****************************************************************************
342 Debug output routines
343 *****************************************************************************/
344
345 /*!
346 \fn void qDebug( const char *msg, ... )
347
348 \relates QApplication
349
350 Prints a debug message \a msg, or calls the message handler (if it
351 has been installed).
352
353 This function takes a format string and a list of arguments,
354 similar to the C printf() function.
355
356 Example:
357 \code
358 qDebug( "my window handle = %x", myWidget->id() );
359 \endcode
360
361 Under X11, the text is printed to stderr. Under Windows, the text
362 is sent to the debugger.
363
364 \warning The internal buffer is limited to 8196 bytes (including
365 the '\0'-terminator).
366
367 \warning Passing (const char *)0 as argument to qDebug might lead
368 to crashes on certain platforms due to the platforms printf implementation.
369
370 \sa qWarning(), qFatal(), qInstallMsgHandler(),
371 \link debug.html Debugging\endlink
372 */
373
374 /*!
375 \fn void qWarning( const char *msg, ... )
376
377 \relates QApplication
378
379 Prints a warning message \a msg, or calls the message handler (if
380 it has been installed).
381
382 This function takes a format string and a list of arguments,
383 similar to the C printf() function.
384
385 Example:
386 \code
387 void f( int c )
388 {
389 if ( c > 200 )
390 qWarning( "f: bad argument, c == %d", c );
391 }
392 \endcode
393
394 Under X11, the text is printed to stderr. Under Windows, the text
395 is sent to the debugger.
396
397 \warning The internal buffer is limited to 8196 bytes (including
398 the '\0'-terminator).
399
400 \warning Passing (const char *)0 as argument to qWarning might lead
401 to crashes on certain platforms due to the platforms printf implementation.
402
403 \sa qDebug(), qFatal(), qInstallMsgHandler(),
404 \link debug.html Debugging\endlink
405 */
406
407 /*!
408 \fn void qFatal( const char *msg, ... )
409
410 \relates QApplication
411
412 Prints a fatal error message \a msg and exits, or calls the
413 message handler (if it has been installed).
414
415 This function takes a format string and a list of arguments,
416 similar to the C printf() function.
417
418 Example:
419 \code
420 int divide( int a, int b )
421 {
422 if ( b == 0 ) // program error
423 qFatal( "divide: cannot divide by zero" );
424 return a/b;
425 }
426 \endcode
427
428 Under X11, the text is printed to stderr. Under Windows, the text
429 is sent to the debugger.
430
431 \warning The internal buffer is limited to 8196 bytes (including
432 the '\0'-terminator).
433
434 \warning Passing (const char *)0 as argument to qFatal might lead
435 to crashes on certain platforms due to the platforms printf implementation.
436
437 \sa qDebug(), qWarning(), qInstallMsgHandler(),
438 \link debug.html Debugging\endlink
439 */
440
441
442 static QtMsgHandler handler = 0; // pointer to debug handler
443 static const int QT_BUFFER_LENGTH = 8196; // internal buffer length
444
445
446 #ifdef Q_CC_MWERKS
447
448 #include "qt_mac.h"
449
450 extern bool qt_is_gui_used;
mac_default_handler(const char * msg)451 static void mac_default_handler( const char *msg )
452 {
453 if ( qt_is_gui_used ) {
454 const unsigned char *p = p_str(msg);
455 DebugStr(p);
456 free((void*)p);
457 } else {
458 fprintf( stderr, msg );
459 }
460 }
461
462 #endif
463
464
qDebug(const char * msg,...)465 void qDebug( const char *msg, ... )
466 {
467 char buf[QT_BUFFER_LENGTH];
468 va_list ap;
469 va_start( ap, msg ); // use variable arg list
470 #if defined(QT_VSNPRINTF)
471 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
472 #else
473 vsprintf( buf, msg, ap );
474 #endif
475 va_end( ap );
476 if ( handler ) {
477 (*handler)( QtDebugMsg, buf );
478 } else {
479 #if defined(Q_CC_MWERKS)
480 mac_default_handler(buf);
481 #elif defined(Q_OS_TEMP)
482 QString fstr( buf );
483 OutputDebugString( (fstr + "\n").ucs2() );
484 #else
485 fprintf( stderr, "%s\n", buf ); // add newline
486 #endif
487 }
488 }
489
490 // copied... this looks really bad.
debug(const char * msg,...)491 void debug( const char *msg, ... )
492 {
493 char buf[QT_BUFFER_LENGTH];
494 va_list ap;
495 va_start( ap, msg ); // use variable arg list
496 #if defined(QT_VSNPRINTF)
497 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
498 #else
499 vsprintf( buf, msg, ap );
500 #endif
501 va_end( ap );
502 if ( handler ) {
503 (*handler)( QtDebugMsg, buf );
504 } else {
505 #if defined(Q_CC_MWERKS)
506 mac_default_handler(buf);
507 #elif defined(Q_OS_TEMP)
508 QString fstr( buf );
509 OutputDebugString( (fstr + "\n").ucs2() );
510 #else
511 fprintf( stderr, "%s\n", buf ); // add newline
512 #endif
513 }
514 }
515
qWarning(const char * msg,...)516 void qWarning( const char *msg, ... )
517 {
518 char buf[QT_BUFFER_LENGTH];
519 va_list ap;
520 va_start( ap, msg ); // use variable arg list
521 #if defined(QT_VSNPRINTF)
522 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
523 #else
524 vsprintf( buf, msg, ap );
525 #endif
526 va_end( ap );
527 if ( handler ) {
528 (*handler)( QtWarningMsg, buf );
529 } else {
530 #if defined(Q_CC_MWERKS)
531 mac_default_handler(buf);
532 #elif defined(Q_OS_TEMP)
533 QString fstr( buf );
534 OutputDebugString( (fstr + "\n").ucs2() );
535 #else
536 fprintf( stderr, "%s\n", buf ); // add newline
537 #endif
538 }
539 }
540
541
542 // again, copied
warning(const char * msg,...)543 void warning( const char *msg, ... )
544 {
545 char buf[QT_BUFFER_LENGTH];
546 va_list ap;
547 va_start( ap, msg ); // use variable arg list
548 #if defined(QT_VSNPRINTF)
549 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
550 #else
551 vsprintf( buf, msg, ap );
552 #endif
553 va_end( ap );
554 if ( handler ) {
555 (*handler)( QtWarningMsg, buf );
556 } else {
557 #if defined(Q_CC_MWERKS)
558 mac_default_handler(buf);
559 #elif defined(Q_OS_TEMP)
560 QString fstr( buf );
561 OutputDebugString( (fstr + "\n").ucs2() );
562 #else
563 fprintf( stderr, "%s\n", buf ); // add newline
564 #endif
565 }
566 }
567
qFatal(const char * msg,...)568 void qFatal( const char *msg, ... )
569 {
570 char buf[QT_BUFFER_LENGTH];
571 va_list ap;
572 va_start( ap, msg ); // use variable arg list
573 #if defined(QT_VSNPRINTF)
574 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
575 #else
576 vsprintf( buf, msg, ap );
577 #endif
578 va_end( ap );
579 if ( handler ) {
580 (*handler)( QtFatalMsg, buf );
581 } else {
582 #if defined(Q_CC_MWERKS)
583 mac_default_handler(buf);
584 #else
585 fprintf( stderr, "%s\n", buf ); // add newline
586 #endif
587 #if defined(Q_OS_UNIX) && defined(QT_DEBUG)
588 abort(); // trap; generates core dump
589 #elif defined(Q_OS_TEMP) && defined(QT_DEBUG)
590 QString fstr;
591 fstr.sprintf( "%s:%s %s %s\n", __FILE__, __LINE__, QT_VERSION_STR, buf );
592 OutputDebugString( fstr.ucs2() );
593 #elif defined(_CRT_ERROR) && defined(_DEBUG)
594 _CrtDbgReport( _CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, buf );
595 #else
596 exit( 1 ); // goodbye cruel world
597 #endif
598 }
599 }
600
601 // yet again, copied
fatal(const char * msg,...)602 void fatal( const char *msg, ... )
603 {
604 char buf[QT_BUFFER_LENGTH];
605 va_list ap;
606 va_start( ap, msg ); // use variable arg list
607 #if defined(QT_VSNPRINTF)
608 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
609 #else
610 vsprintf( buf, msg, ap );
611 #endif
612 va_end( ap );
613 if ( handler ) {
614 (*handler)( QtFatalMsg, buf );
615 } else {
616 #if defined(Q_CC_MWERKS)
617 mac_default_handler(buf);
618 #else
619 fprintf( stderr, "%s\n", buf ); // add newline
620 #endif
621 #if defined(Q_OS_UNIX) && defined(QT_DEBUG)
622 abort(); // trap; generates core dump
623 #elif defined(Q_OS_TEMP) && defined(QT_DEBUG)
624 QString fstr;
625 fstr.sprintf( "%s:%s %s %s\n", __FILE__, __LINE__, QT_VERSION_STR, buf );
626 OutputDebugString( fstr.ucs2() );
627 #elif defined(_CRT_ERROR) && defined(_DEBUG)
628 _CrtDbgReport( _CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, buf );
629 #else
630 exit( 1 ); // goodbye cruel world
631 #endif
632 }
633 }
634
635 /*!
636 \relates QApplication
637
638 Prints the message \a msg and uses \a code to get a system specific
639 error message. When \a code is -1 (the default), the system's last
640 error code will be used if possible. Use this method to handle
641 failures in platform specific API calls.
642
643 This function does nothing when Qt is built with \c QT_NO_DEBUG
644 defined.
645 */
qSystemWarning(const char * msg,int code)646 void qSystemWarning( const char* msg, int code )
647 {
648 #ifndef QT_NO_DEBUG
649 #if defined(Q_OS_WIN32)
650 if ( code == -1 )
651 code = GetLastError();
652
653 if ( !code )
654 return;
655
656 unsigned short *string;
657 QT_WA( {
658 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
659 NULL,
660 code,
661 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
662 (LPTSTR)&string,
663 0,
664 NULL );
665
666 qWarning( "%s\n\tError code %d - %s", msg, code, QString::fromUcs2(string).latin1() );
667 }, {
668 FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
669 NULL,
670 code,
671 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
672 (char*)&string,
673 0,
674 NULL );
675
676 qWarning( "%s\n\tError code %d - %s", msg, code, (const char*)string );
677 } );
678 LocalFree( (HLOCAL)string );
679 #else
680 if ( code != -1 )
681 qWarning( "%s\n\tError code %d - %s", msg, code, strerror( code ) );
682 else
683 qWarning( msg );
684 #endif
685 #else
686 Q_UNUSED( msg );
687 Q_UNUSED( code );
688 #endif
689 }
690
691 /*!
692 \fn void Q_ASSERT( bool test )
693
694 \relates QApplication
695
696 Prints a warning message containing the source code file name and
697 line number if \a test is FALSE.
698
699 This is really a macro defined in \c qglobal.h.
700
701 Q_ASSERT is useful for testing pre- and post-conditions.
702
703 Example:
704 \code
705 //
706 // File: div.cpp
707 //
708
709 #include <qglobal.h>
710
711 int divide( int a, int b )
712 {
713 Q_ASSERT( b != 0 ); // this is line 9
714 return a/b;
715 }
716 \endcode
717
718 If \c b is zero, the Q_ASSERT statement will output the following
719 message using the qWarning() function:
720 \code
721 ASSERT: "b != 0" in div.cpp (9)
722 \endcode
723
724 \sa qWarning(), \link debug.html Debugging\endlink
725 */
726
727
728 /*!
729 \fn void Q_CHECK_PTR( void *p )
730
731 \relates QApplication
732
733 If \a p is 0, prints a warning message containing the source code file
734 name and line number, saying that the program ran out of memory.
735
736 This is really a macro defined in \c qglobal.h.
737
738 Example:
739 \code
740 int *a;
741
742 Q_CHECK_PTR( a = new int[80] ); // WRONG!
743
744 a = new (nothrow) int[80]; // Right
745 Q_CHECK_PTR( a );
746 \endcode
747
748 \sa qWarning(), \link debug.html Debugging\endlink
749 */
750
751
752 //
753 // The Q_CHECK_PTR macro calls this function to check if an allocation went ok.
754 //
755 #if (QT_VERSION-0 >= 0x040000)
756 #if defined(Q_CC_GNU)
757 #warning "Change Q_CHECK_PTR to '{if ((p)==0) qt_check_pointer(__FILE__,__LINE__);}'"
758 #warning "No need for qt_check_pointer() to return a value - make it void!"
759 #endif
760 #endif
qt_check_pointer(bool c,const char * n,int l)761 bool qt_check_pointer( bool c, const char *n, int l )
762 {
763 if ( c )
764 qWarning( "In file %s, line %d: Out of memory", n, l );
765 return TRUE;
766 }
767
768
firstObsoleteWarning(const char * obj,const char * oldfunc)769 static bool firstObsoleteWarning(const char *obj, const char *oldfunc )
770 {
771 static QAsciiDict<int> *obsoleteDict = 0;
772 if ( !obsoleteDict ) { // first time func is called
773 obsoleteDict = new QAsciiDict<int>;
774 #if defined(QT_DEBUG)
775 qDebug(
776 "You are using obsolete functions in the Qt library. Call the function\n"
777 "qSuppressObsoleteWarnings() to suppress obsolete warnings.\n"
778 );
779 #endif
780 }
781 QCString s( obj );
782 s += "::";
783 s += oldfunc;
784 if ( obsoleteDict->find(s.data()) == 0 ) {
785 obsoleteDict->insert( s.data(), (int*)1 ); // anything different from 0
786 return TRUE;
787 }
788 return FALSE;
789 }
790
791 static bool suppressObsolete = FALSE;
792
qSuppressObsoleteWarnings(bool suppress)793 void qSuppressObsoleteWarnings( bool suppress )
794 {
795 suppressObsolete = suppress;
796 }
797
qObsolete(const char * obj,const char * oldfunc,const char * newfunc)798 void qObsolete( const char *obj, const char *oldfunc, const char *newfunc )
799 {
800 if ( suppressObsolete )
801 return;
802 if ( !firstObsoleteWarning(obj, oldfunc) )
803 return;
804 if ( obj )
805 qDebug( "%s::%s: This function is obsolete, use %s instead.",
806 obj, oldfunc, newfunc );
807 else
808 qDebug( "%s: This function is obsolete, use %s instead.",
809 oldfunc, newfunc );
810 }
811
qObsolete(const char * obj,const char * oldfunc)812 void qObsolete( const char *obj, const char *oldfunc )
813 {
814 if ( suppressObsolete )
815 return;
816 if ( !firstObsoleteWarning(obj, oldfunc) )
817 return;
818 if ( obj )
819 qDebug( "%s::%s: This function is obsolete.", obj, oldfunc );
820 else
821 qDebug( "%s: This function is obsolete.", oldfunc );
822 }
823
qObsolete(const char * message)824 void qObsolete( const char *message )
825 {
826 if ( suppressObsolete )
827 return;
828 if ( !firstObsoleteWarning( "Qt", message) )
829 return;
830 qDebug( "%s", message );
831 }
832
833
834 /*!
835 \relates QApplication
836
837 Installs a Qt message handler \a h. Returns a pointer to the
838 message handler previously defined.
839
840 The message handler is a function that prints out debug messages,
841 warnings and fatal error messages. The Qt library (debug version)
842 contains hundreds of warning messages that are printed when
843 internal errors (usually invalid function arguments) occur. If you
844 implement your own message handler, you get total control of these
845 messages.
846
847 The default message handler prints the message to the standard
848 output under X11 or to the debugger under Windows. If it is a
849 fatal message, the application aborts immediately.
850
851 Only one message handler can be defined, since this is usually
852 done on an application-wide basis to control debug output.
853
854 To restore the message handler, call \c qInstallMsgHandler(0).
855
856 Example:
857 \code
858 #include <qapplication.h>
859 #include <stdio.h>
860 #include <stdlib.h>
861
862 void myMessageOutput( QtMsgType type, const char *msg )
863 {
864 switch ( type ) {
865 case QtDebugMsg:
866 fprintf( stderr, "Debug: %s\n", msg );
867 break;
868 case QtWarningMsg:
869 fprintf( stderr, "Warning: %s\n", msg );
870 break;
871 case QtFatalMsg:
872 fprintf( stderr, "Fatal: %s\n", msg );
873 abort(); // deliberately core dump
874 }
875 }
876
877 int main( int argc, char **argv )
878 {
879 qInstallMsgHandler( myMessageOutput );
880 QApplication a( argc, argv );
881 ...
882 return a.exec();
883 }
884 \endcode
885
886 \sa qDebug(), qWarning(), qFatal(), \link debug.html Debugging\endlink
887 */
888
qInstallMsgHandler(QtMsgHandler h)889 QtMsgHandler qInstallMsgHandler( QtMsgHandler h )
890 {
891 QtMsgHandler old = handler;
892 handler = h;
893 return old;
894 }
895
896
897 /*
898 Dijkstra's bisection algorithm to find the square root as an integer.
899 Deliberately not exported as part of the Qt API, but used in both
900 qsimplerichtext.cpp and qgfxraster_qws.cpp
901 */
qt_int_sqrt(unsigned int n)902 unsigned int qt_int_sqrt( unsigned int n )
903 {
904 // n must be in the range 0...UINT_MAX/2-1
905 if ( n >= ( UINT_MAX>>2 ) ) {
906 unsigned int r = 2 * qt_int_sqrt( n / 4 );
907 unsigned int r2 = r + 1;
908 return ( n >= r2 * r2 ) ? r2 : r;
909 }
910 uint h, p= 0, q= 1, r= n;
911 while ( q <= n )
912 q <<= 2;
913 while ( q != 1 ) {
914 q >>= 2;
915 h= p + q;
916 p >>= 1;
917 if ( r >= h ) {
918 p += q;
919 r -= h;
920 }
921 }
922 return p;
923 }
924
925