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