source: trunk/src/tools/qglobal.cpp

Last change on this file was 173, checked in by dmik, 18 years ago

Tools: Added the new printing procedure for qDebug(), qWarning() etc. that is capable of redirecting output to a file (set by the QT_PM_DEBUG_FILE=<file_name> environment variable), to the PmPrintf queue (set by the QT_PM_DEBUG_QUEUE environment variable), or to the standard error stream as usual (by default).

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