4 * Mother of all ancestor classes.
6 * Portable Windows Library
8 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25 * All Rights Reserved.
27 * Contributor(s): ______________________________________.
30 * Revision 1.104 2004/05/12 04:36:17 csoutheren
31 * Fixed problems with using sem_wait and friends on systems that do not
32 * support atomic integers
34 * Revision 1.103 2004/04/18 04:33:36 rjongbloed
35 * Changed all operators that return BOOL to return standard type bool. This is primarily
36 * for improved compatibility with std STL usage removing many warnings.
38 * Revision 1.102 2004/04/11 13:26:25 csoutheren
39 * Removed namespace problems and removed warnings for Windows <string>
41 * Revision 1.101 2004/04/11 03:20:41 csoutheren
42 * Added Unix implementation of PCriticalSection
44 * Revision 1.100 2004/04/11 02:55:17 csoutheren
45 * Added PCriticalSection for Windows
46 * Added compile time option for PContainer to use critical sections to provide thread safety under some circumstances
48 * Revision 1.99 2004/04/09 11:54:46 csoutheren
49 * Added configure.in check for STL streams, and tested with gcc 2.95.3,
50 * gcc 3.3.1, and gcc 3.3.3
52 * Revision 1.98 2004/04/09 07:53:51 rjongbloed
53 * Fixed backward compatibility after STL streams change
55 * Revision 1.97 2004/04/09 00:56:35 csoutheren
56 * Fixed problem with new class name code
58 * Revision 1.96 2004/04/09 00:42:58 csoutheren
59 * Changed Unix build to use slightly different method for
60 * keep class names, as GCC does not use actual class names for typeinfo
62 * Revision 1.95 2004/04/04 13:24:18 rjongbloed
63 * Changes to support native C++ Run Time Type Information
65 * Revision 1.94 2004/04/03 08:57:31 csoutheren
66 * Replaced pseudo-RTTI with real RTTI
68 * Revision 1.93 2004/04/03 08:22:20 csoutheren
69 * Remove pseudo-RTTI and replaced with real RTTI
71 * Revision 1.92 2004/04/03 07:41:00 csoutheren
72 * Fixed compile problem with ostringstream/ostrstream
74 * Revision 1.91 2004/04/03 07:16:05 rjongbloed
75 * Fixed backward compatibility with MSVC 6
77 * Revision 1.90 2004/04/03 06:54:22 rjongbloed
78 * Many and various changes to support new Visual C++ 2003
80 * Revision 1.89 2003/09/17 09:00:59 csoutheren
81 * Moved PSmartPointer and PNotifier into seperate files
82 * Added detection for system regex libraries on all platforms
84 * Revision 1.88 2003/09/17 05:41:58 csoutheren
85 * Removed recursive includes
87 * Revision 1.87 2003/09/17 01:18:02 csoutheren
88 * Removed recursive include file system and removed all references
89 * to deprecated coooperative threading support
91 * Revision 1.86 2002/10/14 21:42:37 rogerh
92 * Only use malloc.h on Windows
94 * Revision 1.85 2002/10/10 04:43:43 robertj
95 * VxWorks port, thanks Martijn Roest
97 * Revision 1.84 2002/10/08 12:41:51 robertj
98 * Changed for IPv6 support, thanks Sébastien Josset.
100 * Revision 1.83 2002/09/16 01:08:59 robertj
101 * Added #define so can select if #pragma interface/implementation is used on
102 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
104 * Revision 1.82 2002/08/06 02:27:58 robertj
105 * GNU C++ v3 compatibility.
107 * Revision 1.81 2002/06/25 02:22:47 robertj
108 * Improved assertion system to allow C++ class name to be displayed if
109 * desired, especially relevant to container classes.
111 * Revision 1.80 2002/06/14 10:29:43 rogerh
112 * STL + gcc 3.1 compile fix. Submitted by Klaus Kaempf <kkaempf@suse.de>
114 * Revision 1.79 2002/06/13 08:34:05 rogerh
115 * gcc 3.1 needs iostream instead of iostream.h
117 * Revision 1.78 2002/05/22 00:23:31 craigs
118 * Added GMTTime flag to tracing options
120 * Revision 1.77 2002/04/19 00:20:51 craigs
121 * Added option to append to log file rather than create anew each time
123 * Revision 1.76 2002/01/26 23:55:55 craigs
124 * Changed for GCC 3.0 compatibility, thanks to manty@manty.net
126 * Revision 1.75 2001/10/18 19:56:26 yurik
127 * Fixed WinCE x86 compilation problems with memory check off
129 * Revision 1.74 2001/08/12 11:26:07 robertj
130 * Put back PMEMORY_CHECK taken out by the Carbon port.
132 * Revision 1.73 2001/08/11 07:57:30 rogerh
133 * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com>
135 * Revision 1.72 2001/05/03 06:27:29 robertj
136 * Added return value to PMemoryCheck::SetIgnoreAllocations() so get previous state.
138 * Revision 1.71 2001/03/24 01:11:10 robertj
139 * Added missing PTRACE_IF define in non PTRACING mode.
141 * Revision 1.70 2001/03/23 05:34:09 robertj
142 * Added PTRACE_IF to output trace if a conditional is TRUE.
144 * Revision 1.69 2001/03/01 02:15:16 robertj
145 * Fixed PTRACE_LINE() so drops filename and line which may not be in trace otherwise.
147 * Revision 1.68 2001/02/22 08:16:41 robertj
148 * Added standard trace file setup subroutine.
150 * Revision 1.67 2001/02/13 03:27:24 robertj
151 * Added function to do heap validation.
153 * Revision 1.66 2001/02/09 04:41:27 robertj
154 * Removed added non memrycheck implementations of new/delete when using GNU C++.
156 * Revision 1.65 2001/02/07 04:47:49 robertj
157 * Added changes for possible random crashes in multi DLL environment
158 * due to memory allocation wierdness, thanks Milan Dimitrijevic.
160 * Revision 1.64 2001/01/24 06:15:44 yurik
161 * Windows CE port-related declarations
163 * Revision 1.63 2000/07/28 05:13:47 robertj
164 * Fixed silly mistake in runtime_malloc() function, should return a pointer!
166 * Revision 1.62 2000/07/20 05:46:34 robertj
167 * Added runtime_malloc() function for cases where memory check code must be bypassed.
169 * Revision 1.61 2000/07/13 15:45:35 robertj
170 * Removed #define std that causes everyone so much grief!
172 * Revision 1.60 2000/06/26 11:17:19 robertj
173 * Nucleus++ port (incomplete).
175 * Revision 1.59 2000/02/29 12:26:14 robertj
176 * Added named threads to tracing, thanks to Dave Harvey
178 * Revision 1.58 2000/01/07 12:31:12 robertj
179 * Fixed 8 byte alignment on memory heap checking.
181 * Revision 1.57 2000/01/05 00:29:12 robertj
182 * Fixed alignment problems in memory checking debug functions.
184 * Revision 1.56 1999/11/30 00:22:54 robertj
185 * Updated documentation for doc++
187 * Revision 1.55 1999/11/01 00:10:27 robertj
188 * Added override of new functions for MSVC memory check code.
190 * Revision 1.54 1999/10/19 09:21:30 robertj
191 * Added functions to get current trace options and level.
193 * Revision 1.53 1999/09/13 13:15:06 robertj
194 * Changed PTRACE so will output to system log in PServiceProcess applications.
196 * Revision 1.52 1999/08/24 08:15:23 robertj
197 * Added missing operator on smart pointer to return the pointer!
199 * Revision 1.51 1999/08/24 06:54:36 robertj
200 * Cleaned up the smart pointer code (macros).
202 * Revision 1.50 1999/08/22 13:38:39 robertj
203 * Fixed termination hang up problem with memory check code under unix pthreads.
205 * Revision 1.49 1999/08/17 03:46:40 robertj
206 * Fixed usage of inlines in optimised version.
208 * Revision 1.48 1999/08/10 10:45:09 robertj
209 * Added mutex in memory check detection code.
211 * Revision 1.47 1999/07/18 15:08:24 robertj
212 * Fixed 64 bit compatibility
214 * Revision 1.46 1999/06/14 07:59:37 robertj
215 * Enhanced tracing again to add options to trace output (timestamps etc).
217 * Revision 1.45 1999/05/01 11:29:19 robertj
218 * Alpha linux port changes.
220 * Revision 1.44 1999/04/18 12:58:39 robertj
221 * MSVC 5 backward compatibility
223 * Revision 1.43 1999/03/09 10:30:17 robertj
224 * Fixed ability to have PMEMORY_CHECK on/off on both debug/release versions.
226 * Revision 1.42 1999/03/09 02:59:50 robertj
227 * Changed comments to doc++ compatible documentation.
229 * Revision 1.41 1999/02/23 07:11:26 robertj
230 * Improved trace facility adding trace levels and #define to remove all trace code.
232 * Revision 1.40 1999/02/22 10:48:14 robertj
233 * Fixed delete operator prototypes for MSVC6 and GNU compatibility.
235 * Revision 1.39 1999/02/19 11:33:02 robertj
236 * Fixed compatibility problems with GNU/MSVC6
238 * Revision 1.38 1999/02/16 08:12:22 robertj
239 * MSVC 6.0 compatibility changes.
241 * Revision 1.37 1999/01/07 03:35:35 robertj
242 * Added default for PCHAR8 to ANSI, removes need for compiler option.
244 * Revision 1.36 1998/12/15 09:00:29 robertj
245 * Fixed 8 byte alignment problem in memory leak check code for sparc.
247 * Revision 1.35 1998/11/03 00:57:19 robertj
248 * Added allocation breakpoint variable.
250 * Revision 1.34 1998/10/26 11:05:26 robertj
251 * Added raw free for things allocated within the runtime library.
253 * Revision 1.33 1998/10/18 14:26:55 robertj
254 * Improved tracing functions.
256 * Revision 1.32 1998/10/15 07:47:21 robertj
257 * Added ability to ignore G++lib memory leaks.
259 * Revision 1.31 1998/10/15 01:53:58 robertj
262 * Revision 1.30 1998/10/13 14:23:29 robertj
263 * Complete rewrite of memory leak detection.
265 * Revision 1.29 1998/09/23 06:20:57 robertj
266 * Added open source copyright license.
268 * Revision 1.28 1998/09/14 12:29:11 robertj
269 * Fixed memory leak dump under windows to not include static globals.
270 * Fixed problem with notifier declaration not allowing implementation inline after macro.
272 * Revision 1.27 1997/07/08 13:13:45 robertj
275 * Revision 1.26 1997/04/27 05:50:11 robertj
278 * Revision 1.25 1997/02/05 11:54:10 robertj
279 * Fixed problems with memory check and leak detection.
281 * Revision 1.24 1996/09/16 12:57:23 robertj
284 * Revision 1.23 1996/08/17 10:00:23 robertj
285 * Changes for Windows DLL support.
287 * Revision 1.22 1996/07/15 10:27:51 robertj
288 * Changed endian classes to be memory mapped.
290 * Revision 1.21 1996/05/09 12:14:48 robertj
291 * Fixed up 64 bit integer class for Mac platform.
293 * Revision 1.20 1996/02/24 14:19:29 robertj
294 * Fixed bug in endian independent integer code for memory transfers.
296 * Revision 1.19 1996/01/28 02:46:43 robertj
297 * Removal of MemoryPointer classes as usage didn't work for GNU.
298 * Added missing bit shift operators to 64 bit integer class.
300 * Revision 1.18 1996/01/23 13:14:32 robertj
301 * Added const version of PMemoryPointer.
302 * Added constructor to endian classes for the base type.
304 * Revision 1.17 1996/01/02 11:54:11 robertj
305 * Mac OS compatibility changes.
307 * Revision 1.16 1995/11/09 12:17:10 robertj
308 * Added platform independent base type access classes.
310 * Revision 1.15 1995/06/17 11:12:47 robertj
311 * Documentation update.
313 * Revision 1.14 1995/06/04 12:34:19 robertj
314 * Added trace functions.
316 * Revision 1.13 1995/04/25 12:04:35 robertj
317 * Fixed borland compatibility.
318 * Fixed function hiding ancestor virtuals.
320 * Revision 1.12 1995/03/14 12:41:54 robertj
321 * Updated documentation to use HTML codes.
323 * Revision 1.11 1995/03/12 04:40:55 robertj
324 * Changed standard error code for not open from file to channel.
326 * Revision 1.10 1995/02/19 04:19:14 robertj
327 * Added dynamically linked command processing.
329 * Revision 1.9 1995/02/05 00:48:07 robertj
330 * Fixed template version.
332 * Revision 1.8 1995/01/15 04:51:31 robertj
334 * Added levels of memory checking.
336 * Revision 1.7 1995/01/09 12:38:31 robertj
337 * Changed variable names around during documentation run.
338 * Fixed smart pointer comparison.
339 * Fixed serialisation stuff.
342 * Revision 1.6 1995/01/03 09:39:06 robertj
343 * Put standard malloc style memory allocation etc into memory check system.
345 * Revision 1.5 1994/12/12 10:08:30 robertj
346 * Renamed PWrapper to PSmartPointer..
348 * Revision 1.4 1994/12/05 11:23:28 robertj
349 * Fixed PWrapper macros.
351 * Revision 1.3 1994/11/19 00:22:55 robertj
352 * Changed PInteger to be INT, ie standard type like BOOL/WORD etc.
353 * Moved null object check in notifier to construction rather than use.
354 * Added virtual to the callback function in notifier destination class.
356 * Revision 1.2 1994/11/03 09:25:30 robertj
357 * Made notifier destination object not to be descendent of PObject.
359 * Revision 1.1 1994/10/30 12:01:37 robertj
372 #include "msos/ptlib/contain.h"
374 #include "unix/ptlib/contain.h"
377 #if defined(P_VXWORKS)
378 #include <private/stdiop.h>
397 //typedef std::ostringstream ostrstream;
401 //using namespace std;
409 #include <iostream.h>
411 #include <strstream.h>
413 #include <strstrea.h>
426 typedef long _Ios_Fmtflags
;
433 ///////////////////////////////////////////////////////////////////////////////
434 // Disable inlines when debugging for faster compiles (the compiler doesn't
435 // actually inline the function with debug on any way).
437 #ifndef P_USE_INLINES
439 #define P_USE_INLINES 0
441 #define P_USE_INLINES 0
446 #define PINLINE inline
452 ///////////////////////////////////////////////////////////////////////////////
453 // Declare the debugging support
455 /// Standard assert messages for the PAssert macro.
456 enum PStandardAssertMessage
{
457 PLogicError
, // A logic error occurred.
458 POutOfMemory
, // A new or malloc failed.
459 PNullPointerReference
, // A reference was made through a NULL pointer.
460 PInvalidCast
, // An invalid cast to descendant is required.
461 PInvalidArrayIndex
, // An index into an array was negative.
462 PInvalidArrayElement
, // A NULL array element object was accessed.
463 PStackEmpty
, // A Pop() was made of a stack with no elements.
464 PUnimplementedFunction
, // Funtion is not implemented.
465 PInvalidParameter
, // Invalid parameter was passed to a function.
466 POperatingSystemError
, // Error was returned by Operating System.
467 PChannelNotOpen
, // Operation attempted when channel not open.
468 PUnsupportedFeature
, // Feature is not supported.
469 PInvalidWindow
, // Access through invalid window.
470 PMaxStandardAssertMessage
473 #define __CLASS__ NULL
475 /** This macro is used to assert that a condition must be TRUE.
476 If the condition is FALSE then an assert function is called with the source
477 file and line number the macro was instantiated on, plus the message described
478 by the #msg# parameter. This parameter may be either a standard value
479 from the #PStandardAssertMessage# enum or a literal string.
481 #define PAssert(b, m) if(b);else PAssertFunc(__FILE__, __LINE__, __CLASS__, (m))
483 /** This macro is used to assert that a condition must be TRUE.
484 If the condition is FALSE then an assert function is called with the source
485 file and line number the macro was instantiated on, plus the message described
486 by the #msg# parameter. This parameter may be either a standard value
487 from the #PStandardAssertMessage# enum or a literal string.
488 The #c# parameter specifies the class name that the error occurred in
490 #define PAssert2(b, c, m) if(b);else PAssertFunc(__FILE__, __LINE__, (c), (m))
492 /** This macro is used to assert that an operating system call succeeds.
493 If the condition is FALSE then an assert function is called with the source
494 file and line number the macro was instantiated on, plus the message
495 described by the #POperatingSystemError# value in the #PStandardAssertMessage#
498 #define PAssertOS(b) \
499 if(b);else PAssertFunc(__FILE__, __LINE__, __CLASS__, POperatingSystemError)
501 /** This macro is used to assert that a pointer must be non-null.
502 If the pointer is NULL then an assert function is called with the source file
503 and line number the macro was instantiated on, plus the message described by
504 the PNullPointerReference value in the #PStandardAssertMessage# enum.
506 Note that this evaluates the expression defined by #ptr# twice. To
507 prevent incorrect behaviour with this, the macro will assume that the
508 #ptr# parameter is an L-Value.
510 #define PAssertNULL(p) ((&(p)&&(p)!=NULL)?(p):(PAssertFunc(__FILE__, \
511 __LINE__, __CLASS__, PNullPointerReference), (p)))
513 /** This macro is used to assert immediately.
514 The assert function is called with the source file and line number the macro
515 was instantiated on, plus the message described by the #msg# parameter. This
516 parameter may be either a standard value from the #PStandardAssertMessage#
517 enum or a literal string.
519 #define PAssertAlways(m) PAssertFunc(__FILE__, __LINE__, __CLASS__, (m))
521 /** This macro is used to assert immediately.
522 The assert function is called with the source file and line number the macro
523 was instantiated on, plus the message described by the #msg# parameter. This
524 parameter may be either a standard value from the #PStandardAssertMessage#
525 enum or a literal string.
527 #define PAssertAlways2(c, m) PAssertFunc(__FILE__, __LINE__, (c), (m))
530 void PAssertFunc(const char * file
, int line
, const char * className
, PStandardAssertMessage msg
);
531 void PAssertFunc(const char * file
, int line
, const char * className
, const char * msg
);
532 void PAssertFunc(const char * full_msg
);
535 /** Get the stream being used for error output.
536 This stream is used for all trace output using the various trace functions
539 ostream
& PGetErrorStream();
541 /** Set the stream to be used for error output.
542 This stream is used for all error output using the #PError# macro.
544 void PSetErrorStream(ostream
* strm
/** New stream for error output */ );
546 /** This macro is used to access the platform specific error output stream.
547 This is to be used in preference to assuming #cerr# is always available. On
548 Unix platforms this {\bfis} #cerr# but for MS-Windows this is another stream
549 that uses the OutputDebugString() Windows API function. Note that a MS-DOS or
550 Windows NT console application would still use #cerr#.
552 The #PError# stream would normally only be used for debugging information as
553 a suitable display is not always available in windowed environments.
555 The macro is a wrapper for a global variable #PErrorStream# which is a pointer
556 to an #ostream#. The variable is initialised to #cerr# for all but MS-Windows
557 and NT GUI applications. An application could change this pointer to a
558 #ofstream# variable of #PError# output is wished to be redirected to a file.
560 #define PError (PGetErrorStream())
564 ///////////////////////////////////////////////////////////////////////////////
575 /**Class to encapsulate tracing functions.
576 This class does not require any instances and is only being used as a
577 method of grouping functions together in a name space.
582 /// Options for trace output.
584 /**Include PTrace::Block constructs in output
585 If this is bit is clear, all PTrace::Block output is inhibited
586 regardless of the trace level. If set, the PTrace::Block may occur
587 provided the trace level is greater than zero.
590 /// Include date and time in all output
592 /// Include (millisecond) timestamp in all output
594 /// Include identifier for thread trace is made from in all output
596 /// Include trace level in all output
598 /// Include the file and line for the trace call in all output
600 /// Include thread object pointer address in all trace output
602 /// Append to log file rather than resetting every time
604 /** SystemLog flag for tracing within a PServiceProcess application. Must
605 be set in conjection with SetStream(new PSystemLog).
608 /** Output timestamps in GMT time rather than local time
610 SystemLogStream
= 32768
613 /**Set the most common trace options.
614 If filename is not NULL then a PTextFile is created and attached the
615 trace output stream. This object is never closed or deleted until the
616 termination of the program.
618 A trace output of the program name version and OS is written as well.
620 static void Initialise(
622 const char * filename
= NULL
,
623 unsigned options
= Timestamp
| Thread
| Blocks
626 /** Set the trace options.
627 The PTRACE(), PTRACE_BLOCK() and PTRACE_LINE() macros output trace text that
628 may contain assorted values. These are defined by the Options enum.
630 Note this function OR's the bits included in the options parameter.
632 static void SetOptions(unsigned options
/** New level for trace */ );
634 /** Clear the trace options.
635 The PTRACE(), PTRACE_BLOCK() and PTRACE_LINE() macros output trace text that
636 may contain assorted values. These are defined by the Options enum.
638 Note this function AND's the complement of the bits included in the options
641 static void ClearOptions(unsigned options
/** New level for trace */ );
643 /** Get the current trace options.
644 The PTRACE(), PTRACE_BLOCK() and PTRACE_LINE() macros output trace text that
645 may contain assorted values. These are defined by the Options enum.
647 static unsigned GetOptions();
649 /** Set the trace level.
650 The PTRACE() macro checks to see if its level is equal to or lower then the
651 level set by this function. If so then the trace text is output to the trace
654 static void SetLevel(unsigned level
/** New level for trace */ );
656 /** Get the trace level.
657 The PTRACE() macro checks to see if its level is equal to or lower then the
658 level set by this function. If so then the trace text is output to the trace
661 static unsigned GetLevel();
663 /** Determine if the level may cause trace output.
664 This checks against the current global trace level set by #PSetTraceLevel#
665 for if the trace output may be emitted. This is used by the PTRACE macro.
667 static BOOL
CanTrace(unsigned level
/** Trace level to check */);
669 /** Set the stream to be used for trace output.
670 This stream is used for all trace output using the various trace functions
673 static void SetStream(ostream
* out
/** New output stream from trace. */ );
675 /** Begin a trace output.
676 If the trace stream output is used outside of the provided macros, it
677 should be noted that a mutex is obtained on the call to #PBeginTrace# which
678 will prevent any other threads from using the trace stream until the
679 #PEndTrace# function is called.
681 So a typical usage would be:
683 ostream & s = PTrace::Begin(3, __FILE__, __LINE__);
687 s << '!' << PTrace::End();
690 static ostream
& Begin(
691 unsigned level
, /// Log level for output
692 const char * fileName
, /// Filename of source file being traced
693 int lineNum
/// Line number of source file being traced.
696 /** End a trace output.
697 If the trace stream output is used outside of the provided macros, the
698 #PEndTrace# function must be used at the end of the section of trace
699 output. A mutex is obtained on the call to #PBeginTrace# which will prevent
700 any other threads from using the trace stream until the PEndTrace. The
701 #PEndTrace# is used in a similar manner to #::endl# or #::flush#.
703 So a typical usage would be:
705 ostream & s = PTrace::Begin();
709 s << '!' << PTrace::End();
712 static ostream
& End(ostream
& strm
/** Trace output stream being completed */);
715 /** Class to trace Execution blocks.
716 This class is used for tracing the entry and exit of program blocks. Upon
717 construction it outputs an entry trace message and on destruction outputs an
718 exit trace message. This is normally only used from in the PTRACE_BLOCK macro.
722 /** Output entry trace message. */
724 const char * fileName
, /// Filename of source file being traced
725 int lineNum
, /// Line number of source file being traced.
726 const char * traceName
727 /// String to be output with trace, typically it is the function name.
729 /// Output exit trace message.
740 #define PTRACE_BLOCK(n)
741 #define PTRACE_LINE()
742 #define PTRACE(level, arg)
743 #define PTRACE_IF(level, cond, args)
747 /** Trace an execution block.
748 This macro creates a trace variable for tracking the entry and exit of program
749 blocks. It creates an instance of the PTraceBlock class that will output a
750 trace message at the line PTRACE_BLOCK is called and then on exit from the
751 scope it is defined in.
753 #define PTRACE_BLOCK(name) PTrace::Block __trace_block_instance(__FILE__, __LINE__, name)
755 /** Trace the execution of a line.
756 This macro outputs a trace of a source file line execution.
758 #define PTRACE_LINE() \
759 if (!PTrace::CanTrace(1)) ; else \
760 PTrace::Begin(1, __FILE__, __LINE__) << __FILE__ << '(' << __LINE__ << ')' << PTrace::End
763 This macro outputs a trace of any information needed, using standard stream
764 output operators. The output is only made if the trace level set by the
765 #PSetTraceLevel# function is greater than or equal to the #level# argument.
767 #define PTRACE(level, args) \
768 if (!PTrace::CanTrace(level)) ; else \
769 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
771 /** Output trace on condition.
772 This macro outputs a trace of any information needed, using standard stream
773 output operators. The output is only made if the trace level set by the
774 #PSetTraceLevel# function is greater than or equal to the #level# argument
775 and the conditional is TRUE. Note the conditional is only evaluated if the
776 trace level is sufficient.
778 #define PTRACE_IF(level, cond, args) \
779 if (!(PTrace::CanTrace(level) && (cond))) ; else \
780 PTrace::Begin(level, __FILE__, __LINE__) << args << PTrace::End
784 // the following macros exist purely for backwards compatibility
787 #define runtime_malloc(s) malloc(s)
788 #define runtime_free(p) free(p)
790 /** Declare all the standard PWlib class information.
791 This macro is used to provide the basic run-time typing capability needed
792 by the library. All descendent classes from the #PObject# class require
793 these functions for correct operation. Either use this macro or the
794 #PDECLARE_CLASS# macro.
796 The use of the #PDECLARE_CLASS# macro is no longer recommended for reasons
797 of compatibility with documentation systems.
804 #define PCLASSINFO(cls, par) \
806 static const char * Class() \
808 virtual const char * GetClass(unsigned ancestor = 0) const \
809 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
810 virtual BOOL IsClass(const char * clsName) const \
811 { return strcmp(clsName, cls::Class()) == 0; } \
812 virtual BOOL IsDescendant(const char * clsName) const \
813 { return strcmp(clsName, cls::Class()) == 0 || par::IsDescendant(clsName); } \
814 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
815 { return (Comparison)memcmp(this, &obj, sizeof(cls)); }
821 #define PIsDescendant(ptr, cls) (dynamic_cast<const cls *>(ptr) != NULL)
822 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
827 #error "Must define PCLASSNAME"
830 #define PBASECLASSINFO(cls, par) \
832 static inline const char * Class() \
833 { return PCLASSNAME(cls); } \
834 virtual BOOL InternalIsDescendant(const char * clsName) const \
835 { return strcmp(clsName, PCLASSNAME(cls)) == 0 || par::InternalIsDescendant(clsName); } \
837 #else // P_HAS_TYPEINFO
839 #define PIsDescendant(ptr, cls) ((ptr)->InternalIsDescendant(cls::Class()))
840 #define PIsDescendantStr(ptr, str) ((ptr)->InternalIsDescendant(str))
842 #define PBASECLASSINFO(cls, par) \
844 static const char * Class() \
846 virtual BOOL InternalIsDescendant(const char * clsName) const \
847 { return strcmp(clsName, cls::Class()) == 0 || par::InternalIsDescendant(clsName); } \
849 #endif // P_HAS_TYPEINFO
852 #define PCLASSINFO(cls, par) \
853 PBASECLASSINFO(cls, par) \
854 virtual const char * GetClass(unsigned ancestor = 0) const \
855 { return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
856 virtual Comparison CompareObjectMemoryDirect(const PObject & obj) const \
857 { return (Comparison)memcmp(this, &obj, sizeof(cls)); } \
859 /** Declare a class with PWLib class information.
860 This macro is used to declare a new class with a single public ancestor. It
861 starts the class declaration and then uses the #PCLASSINFO# macro to
862 get all the run-time type functions.
864 The use of this macro is no longer recommended for reasons of compatibility
865 with documentation systems.
867 #define PDECLARE_CLASS(cls, par) class cls : public par { PCLASSINFO(cls, par)
869 } Match previous opening brace in doc
++
872 ///////////////////////////////////////////////////////////////////////////////
873 // The root of all evil ... umm classes
875 /** Ultimate parent class for all objects in the class library.
876 This provides functionality provided to all classes, eg run-time types,
877 default comparison operations, simple stream I/O and serialisation support.
882 /** Constructor for PObject, make protected so cannot ever create one on
888 /* Destructor required to get the "virtual". A PObject really has nothing
891 virtual ~PObject() { }
893 /**@name Run Time Type functions */
895 /** Get the name of the class as a C string. This is a static function which
896 returns the type of a specific class.
898 When comparing class names, always use the #strcmp()#
899 function rather than comparing pointers. The pointers are not
900 necessarily the same over compilation units depending on the compiler,
903 @return pointer to C string literal.
905 static inline const char * Class() { return PCLASSNAME(PObject
); }
907 /** Get the current dynamic type of the object instance.
909 When comparing class names, always use the #strcmp()#
910 function rather than comparing pointers. The pointers are not
911 necessarily the same over compilation units depending on the compiler,
914 The #PCLASSINFO# macro declares an override of this function for
915 the particular class. The user need not implement it.
917 @return pointer to C string literal.
919 virtual const char * GetClass(unsigned /*ancestor*/ = 0) const { return Class(); }
921 BOOL
IsClass(const char * cls
) const
922 { return strcmp(cls
, GetClass()) == 0; }
924 /** Determine if the dynamic type of the current instance is a descendent of
925 the specified class. The class name is usually provided by the
926 #Class()# static function of the desired class.
928 The #PCLASSINFO# macro declares an override of this function for
929 the particular class. The user need not implement it.
931 @return TRUE if object is descended from the class.
933 virtual BOOL
InternalIsDescendant(
934 const char * clsName
// Ancestor class name to compare against.
936 { return IsClass(clsName
); }
940 /**@name Comparison functions */
942 /** Result of the comparison operation performed by the #Compare()#
951 /** Compare the two objects and return their relative rank. This function is
952 usually overridden by descendent classes to yield the ranking according
953 to the semantics of the object.
955 The default function is to use the #CompareObjectMemoryDirect()#
956 function to do a byte wise memory comparison of the two objects.
959 #LessThan#, #EqualTo# or #GreaterThan#
960 according to the relative rank of the objects.
962 virtual Comparison
Compare(
963 const PObject
& obj
// Object to compare against.
966 /** Determine the byte wise comparison of two objects. This is the default
967 comparison operation for objects that do not explicitly override the
968 #Compare()# function.
970 The #PCLASSINFO# macro declares an override of this function for
971 the particular class. The user need not implement it.
974 #LessThan#, #EqualTo# or #GreaterThan#
975 according to the result #memcpy()# function.
977 virtual Comparison
CompareObjectMemoryDirect(
978 const PObject
& obj
// Object to compare against.
981 /** Compare the two objects.
984 TRUE if objects are equal.
987 const PObject
& obj
// Object to compare against.
988 ) const { return Compare(obj
) == EqualTo
; }
990 /** Compare the two objects.
993 TRUE if objects are not equal.
996 const PObject
& obj
// Object to compare against.
997 ) const { return Compare(obj
) != EqualTo
; }
999 /** Compare the two objects.
1002 TRUE if objects are less than.
1005 const PObject
& obj
// Object to compare against.
1006 ) const { return Compare(obj
) == LessThan
; }
1008 /** Compare the two objects.
1011 TRUE if objects are greater than.
1014 const PObject
& obj
// Object to compare against.
1015 ) const { return Compare(obj
) == GreaterThan
; }
1017 /** Compare the two objects.
1020 TRUE if objects are less than or equal.
1023 const PObject
& obj
// Object to compare against.
1024 ) const { return Compare(obj
) != GreaterThan
; }
1026 /** Compare the two objects.
1029 TRUE if objects are greater than or equal.
1032 const PObject
& obj
// Object to compare against.
1033 ) const { return Compare(obj
) != LessThan
; }
1036 /**@name I/O functions */
1038 /** Output the contents of the object to the stream. The exact output is
1039 dependent on the exact semantics of the descendent class. This is
1040 primarily used by the standard #operator<<# function.
1042 The default behaviour is to print the class name.
1044 virtual void PrintOn(
1045 ostream
&strm
// Stream to print the object into.
1048 /** Input the contents of the object from the stream. The exact input is
1049 dependent on the exact semantics of the descendent class. This is
1050 primarily used by the standard #operator>># function.
1052 The default behaviour is to do nothing.
1054 virtual void ReadFrom(
1055 istream
&strm
// Stream to read the objects contents from.
1059 /** Global function for using the standard << operator on objects descended
1060 from PObject. This simply calls the objects #PrintOn()# function.
1062 @return the #strm# parameter.
1064 inline friend ostream
& operator<<(
1065 ostream
&strm
, // Stream to print the object into.
1066 const PObject
& obj
// Object to print to the stream.
1067 ) { obj
.PrintOn(strm
); return strm
; }
1069 /** Global function for using the standard >> operator on objects descended
1070 from PObject. This simply calls the objects #ReadFrom()# function.
1072 @return the #strm# parameter.
1074 inline friend istream
& operator>>(
1075 istream
&strm
, // Stream to read the objects contents from.
1076 PObject
& obj
// Object to read inormation into.
1077 ) { obj
.ReadFrom(strm
); return strm
; }
1080 /**@name Miscellaneous functions */
1082 /** Create a copy of the class on the heap. The exact semantics of the
1083 descendent class determine what is required to make a duplicate of the
1084 instance. Not all classes can even {\bf do} a clone operation.
1086 The main user of the clone function is the #PDictionary# class as
1087 it requires copies of the dictionary keys.
1089 The default behaviour is for this function to assert.
1092 pointer to new copy of the class instance.
1094 virtual PObject
* Clone() const;
1096 /** This function yields a hash value required by the #PDictionary#
1097 class. A descendent class that is required to be the key of a dictionary
1098 should override this function. The precise values returned is dependent
1099 on the semantics of the class. For example, the #PString# class
1100 overrides it to provide a hash function for distinguishing text strings.
1102 The default behaviour is to return the value zero.
1105 hash function value for class instance.
1107 virtual PINDEX
HashFunction() const;
1111 ///////////////////////////////////////////////////////////////////////////////
1112 // Platform independent types
1114 // All these classes encapsulate primitive types such that they may be
1115 // transfered in a platform independent manner. In particular it is used to
1116 // do byte swapping for little endien and big endien processor architectures
1117 // as well as accommodating structure packing rules for memory structures.
1119 #define PANSI_CHAR 1
1120 #define PLITTLE_ENDIAN 2
1121 #define PBIG_ENDIAN 3
1126 /* Encapsulate a standard 8 bit character into a portable format. This would
1127 rarely need to do translation, only if the target platform uses EBCDIC
1128 would it do anything.
1130 The platform independent form here is always 8 bit ANSI.
1135 type newVal
// Value to initialise data in platform dependent form.
1136 ) { data
= newVal
; }
1137 /* Create a new instance of the platform independent type using platform
1138 dependent data, or platform independent streams.
1141 operator type() { return data
; }
1142 /* Get the platform dependent value for the type.
1148 friend ostream
& operator<<(ostream
& strm
, const PStandardType
& val
)
1149 { return strm
<< (type
)val
; }
1150 /* Output the platform dependent value for the type to the stream.
1153 the stream output was made to.
1156 friend istream
& operator>>(istream
& strm
, PStandardType
& val
)
1157 { type data
; strm
>> data
; val
= PStandardType(data
); return strm
; }
1158 /* Input the platform dependent value for the type from the stream.
1161 the stream input was made from.
1171 #define PI_SAME(name, type) \
1174 name(type value) { data = value; } \
1175 name(const name & value) { data = value.data; } \
1176 name & operator =(type value) { data = value; return *this; } \
1177 name & operator =(const name & value) { data = value.data; return *this; } \
1178 operator type() const { return data; } \
1179 friend ostream & operator<<(ostream & s, const name & v) { return s << v.data; } \
1180 friend istream & operator>>(istream & s, name & v) { return s >> v.data; } \
1181 private: type data; \
1184 #define PI_LOOP(src, dst) \
1185 BYTE *s = ((BYTE *)&src)+sizeof(src); BYTE *d = (BYTE *)&dst; \
1186 while (s != (BYTE *)&src) *d++ = *--s;
1188 #define PI_DIFF(name, type) \
1191 name(type value) { operator=(value); } \
1192 name(const name & value) { data = value.data; } \
1193 name & operator =(type value) { PI_LOOP(value, data); return *this; } \
1194 name & operator =(const name & value) { data = value.data; return *this; } \
1195 operator type() const { type value; PI_LOOP(data, value); return value; } \
1196 friend ostream & operator<<(ostream & s, const name & value) { return s << (type)value; } \
1197 friend istream & operator>>(istream & s, name & v) { type val; s >> val; v = val; return s; } \
1198 private: type data; \
1202 #define PCHAR8 PANSI_CHAR
1205 #if PCHAR8==PANSI_CHAR
1206 PI_SAME(PChar8
, char);
1209 PI_SAME(PInt8
, signed char);
1211 PI_SAME(PUInt8
, unsigned char);
1213 #if PBYTE_ORDER==PLITTLE_ENDIAN
1214 PI_SAME(PInt16l
, PInt16
);
1215 #elif PBYTE_ORDER==PBIG_ENDIAN
1216 PI_DIFF(PInt16l
, PInt16
);
1219 #if PBYTE_ORDER==PLITTLE_ENDIAN
1220 PI_DIFF(PInt16b
, PInt16
);
1221 #elif PBYTE_ORDER==PBIG_ENDIAN
1222 PI_SAME(PInt16b
, PInt16
);
1225 #if PBYTE_ORDER==PLITTLE_ENDIAN
1226 PI_SAME(PUInt16l
, WORD
);
1227 #elif PBYTE_ORDER==PBIG_ENDIAN
1228 PI_DIFF(PUInt16l
, WORD
);
1231 #if PBYTE_ORDER==PLITTLE_ENDIAN
1232 PI_DIFF(PUInt16b
, WORD
);
1233 #elif PBYTE_ORDER==PBIG_ENDIAN
1234 PI_SAME(PUInt16b
, WORD
);
1237 #if PBYTE_ORDER==PLITTLE_ENDIAN
1238 PI_SAME(PInt32l
, PInt32
);
1239 #elif PBYTE_ORDER==PBIG_ENDIAN
1240 PI_DIFF(PInt32l
, PInt32
);
1243 #if PBYTE_ORDER==PLITTLE_ENDIAN
1244 PI_DIFF(PInt32b
, PInt32
);
1245 #elif PBYTE_ORDER==PBIG_ENDIAN
1246 PI_SAME(PInt32b
, PInt32
);
1249 #if PBYTE_ORDER==PLITTLE_ENDIAN
1250 PI_SAME(PUInt32l
, DWORD
);
1251 #elif PBYTE_ORDER==PBIG_ENDIAN
1252 PI_DIFF(PUInt32l
, DWORD
);
1255 #if PBYTE_ORDER==PLITTLE_ENDIAN
1256 PI_DIFF(PUInt32b
, DWORD
);
1257 #elif PBYTE_ORDER==PBIG_ENDIAN
1258 PI_SAME(PUInt32b
, DWORD
);
1261 #if PBYTE_ORDER==PLITTLE_ENDIAN
1262 PI_SAME(PInt64l
, PInt64
);
1263 #elif PBYTE_ORDER==PBIG_ENDIAN
1264 PI_DIFF(PInt64l
, PInt64
);
1267 #if PBYTE_ORDER==PLITTLE_ENDIAN
1268 PI_DIFF(PInt64b
, PInt64
);
1269 #elif PBYTE_ORDER==PBIG_ENDIAN
1270 PI_SAME(PInt64b
, PInt64
);
1273 #if PBYTE_ORDER==PLITTLE_ENDIAN
1274 PI_SAME(PUInt64l
, PUInt64
);
1275 #elif PBYTE_ORDER==PBIG_ENDIAN
1276 PI_DIFF(PUInt64l
, PUInt64
);
1279 #if PBYTE_ORDER==PLITTLE_ENDIAN
1280 PI_DIFF(PUInt64b
, PUInt64
);
1281 #elif PBYTE_ORDER==PBIG_ENDIAN
1282 PI_SAME(PUInt64b
, PUInt64
);
1285 #if PBYTE_ORDER==PLITTLE_ENDIAN
1286 PI_SAME(PFloat32l
, float);
1287 #elif PBYTE_ORDER==PBIG_ENDIAN
1288 PI_DIFF(PFloat32l
, float);
1291 #if PBYTE_ORDER==PLITTLE_ENDIAN
1292 PI_DIFF(PFloat32b
, float);
1293 #elif PBYTE_ORDER==PBIG_ENDIAN
1294 PI_SAME(PFloat32b
, float);
1297 #if PBYTE_ORDER==PLITTLE_ENDIAN
1298 PI_SAME(PFloat64l
, double);
1299 #elif PBYTE_ORDER==PBIG_ENDIAN
1300 PI_DIFF(PFloat64l
, double);
1303 #if PBYTE_ORDER==PLITTLE_ENDIAN
1304 PI_DIFF(PFloat64b
, double);
1305 #elif PBYTE_ORDER==PBIG_ENDIAN
1306 PI_SAME(PFloat64b
, double);
1309 #ifndef NO_LONG_DOUBLE // stupid OSX compiler
1310 #if PBYTE_ORDER==PLITTLE_ENDIAN
1311 PI_SAME(PFloat80l
, long double);
1312 #elif PBYTE_ORDER==PBIG_ENDIAN
1313 PI_DIFF(PFloat80l
, long double);
1316 #if PBYTE_ORDER==PLITTLE_ENDIAN
1317 PI_DIFF(PFloat80b
, long double);
1318 #elif PBYTE_ORDER==PBIG_ENDIAN
1319 PI_SAME(PFloat80b
, long double);
1328 ///////////////////////////////////////////////////////////////////////////////
1331 /*$MACRO PARRAYSIZE(array)
1332 This macro is used to calculate the number of array elements in a static
1335 #define PARRAYSIZE(array) ((PINDEX)(sizeof(array)/sizeof(array[0])))
1337 /*$MACRO PMIN(v1, v2)
1338 This macro is used to calculate the minimum of two values. As this is a
1339 macro the expression in #v1# or #v2# is executed
1340 twice so extreme care should be made in its use.
1342 #define PMIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
1344 /*$MACRO PMAX(v1, v2)
1345 This macro is used to calculate the maximum of two values. As this is a
1346 macro the expression in #v1# or #v2# is executed
1347 twice so extreme care should be made in its use.
1349 #define PMAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
1352 This macro is used to calculate an absolute value. As this is a macro the
1353 expression in #val# is executed twice so extreme care should be
1356 #define PABS(v) ((v) < 0 ? -(v) : (v))
1358 #endif // _POBJECT_H
1360 // End Of File ///////////////////////////////////////////////////////////////