error()
function. These macros can be extremely useful in situtations where the usual debugging
factilites can't be used for whatever reason.
The SET_TRACE
and SET_DEBUG
macros control the settings of the active macros
(trace and condition checking macros expand to nothing at all if these macros are
not set):
MTRACE(ID,ID), MTRACEOUT(ID,ID)
is used at the start (end) of a member function:
MTRACE(
class,member_function)
MDEBUG(EXP)
is used anyware, typlically: MDEBUG(error(-1,'D',"result is '%x',res))
the NDEBUG
macro controls the expansion of other debugging facilities
The outline of a class using these facilities is as follows:
class C [: public P] { MDEBUG_DECL[_VIRTUAL](C); //declares a sentinal value [ C() | MCONSTRUCTOR_IMP[_VIRTUAL](C) ]; [ ~C() | MDESTRUCTOR_IMP[_VIRTUAL](C) ]; void x(); } void C::classInvarient(char* file, int line) const { //you must include this code MCLASSINVTEST(); ... [P::classInvarient(file,line);] } C::C() { MTRACE(C,C); //can't check class invarient because object isn't valid yet MPRECONDITION( ); ... MCONSTRUCTOR_IMP_CODE[_VIRTUAL](C) //initializes the sentinal value POSTCONDITION( ); ... MEXIT_CODE(C,C); //check sentinal, call the invarient } C::~C() { MTRACE(C,~C); MPRECONDITION( ); ... MDESTRUCTOR_IMP_CODE[_VIRTUAL](C) POSTCONDITION( ); ... MTRACEOUT(C,~C); //can't check class invarient because object isn't valid anymore } void C::x() { MENTRY_CODE(C,x); //check sentinal, call the invarient MPRECONDITION( ); ... POSTCONDITION( ); ... MEXIT_CODE(C,x); } //check sentinal, call the invarient
ObjectCounter
increment a static counter in ObjectCounter
whenever they are constructed and
decrement the counter whenever they are destructed. In addition, by making use
of run-time typing, ObjectCounter
keeps separate counts for each child
class.
You may get a get a report on the counts of each object type by calling
The type of the
Your overriding class should return 0 if it handles the message and non-zero if
it doesn't handle the message (in which case it will be posted by
The observer module is modeled on the observer pattern in [Gamma 95].
ObjectCounter::report()
; the report will be output via the
error()
function in the error module.
Error Module
error() function
The error()
function provides an simple interface for custom
handling messages for your application. The arguments of the error()
function follow the same conventions as those of the printf()
family
in the standard C library. The format is
void error([platform specific] handle, char severity, const char* format, ...);
handle
argument is platform specific, for example it
it a HWND
under MS Windows and an int
under DOS. The
severity
argument controls how error()
handles the
message and also acts as in indicator to the user about the kind of message it is.
The remaider of the arguments are identical to those of printf()
and
constitute the actual message.
error()
behaves as follows:
A severity
is not 'z' or 'Z' (interpret as "don't log" -- for
messages only intented for the run-time user or to communicate with your
MessageHandler
[eg: blank out the status line]), the message is appended to a log
file together with a timestamp. The name of the file will be same as that of the
program file, but with a ".log" extention; if error()
can't find
the file name, it will use "error.log". Under DOS and MS Windows, this file will
be placed in the C:\ directory.
(int)handle
returns -1, then the message is output to stdout
under command line systems or posted through a message window under windowing systems.
severity
is 'F', the message is posted as above and
the user is queried to abort the program; if the user chooses the abort, the
program is terminated through a call to exit(1)
.
ErrorHandler
:
severty
argument is
sent to the calling object.
true
), error()
terminates.
stdout
or a message window.
severity
of 'T' or 't' is used for formating of tracing to the
log file. A 'T' is a trace-in and indentation to be incremented by single character
space on subsequent traces. A 't' is a trace-out and decrements the indentation.
class ErrorHandler (abstract)
This class is used be error
for custom handling of messages. It only
has one public method:
virtual int postError(char severity, char* errorMessage) = 0;
error()
.
class ErrorMsgException
A base class for exception classes that contain internal messages and
use error()
to send these to the application.
DECL_EXCEPT_CLASS and DECL_EXCEPT_ABS_CLASS Macros
These macros can be used to easily declare and impliment exception which are
subclasses of ErrorMsgException
.
References Module
class Ref2 (concrete)
The Ref2
class is used to support polymorphism in STL container. Since STL is
designed around direct containment, one cannot, for example, put various polymorphic Shape
classes (such as Rectangle
or Ellipse
and expect them to maintain
their exact type. One could instantiate an STL container with a pointer type, and this often
is appropriate, but destruction of the referenced objects is often problematic: one can define
destroy()
as whether or not to destroy the referenced objects, but only one way or
the other for all pointers of that type.
Ref2
behaves a lot like a pointer, but allows the programmer to control whether the
referenced object is destructed for each instance of the Ref2
"pointer".
Version Module
class Version (concrete)
The Version
class is used as a common way capture versions of programs. It is useful
to write out the version of a program when one is storing data to disk, or transmitting data
to another program. The format is simply a 32 bit wordk, but Version
has methods for
setting and extracting the major version number, the minor version number, the patch level, and
the operating system of the program. Comparison operators == , < , > , < = , and >= are defined
(but don't take the OS into account). The string
cast operator is also defined
which returns a formatted string in the format "M.m[.patch][ (platform)]".
Lexer Module
The Lexer
class isn't really a legitimate class: its only a name space for a set of
static methods used for writing and reading common types. This class will probably be redesigned
to the strategy pattern [Pree 95]. Besides encapsulating these methods, this class is useful
for easily enabling your program to change details of storage or transmission: you might change the
storage format between pure-text and binary just by sustituting different versions of the
Lexer
class.
Observer Module
(.h,
.cpp)class Subject (concrete)
class Observer (abstract)
Command Module
(.h,
.cpp)
The command module is modeled on the command pattern in [Pree 95]. The command pattern is rather over-simplified though, so the implementation found here is considerably more complex.
TYPE IDENTIFIER | DESCRIPTION |
---|---|
DEVICE | Device context type used as first argument to most drawing functions. In MS Windows, HDC. |
WINDOWHANDLE | Handle for a window. In MS Windows, HWND. |
MENU | Handle for a menu. In MS Windows, HMENU. |
CURSOR | Handle for a cursor. In MS Windows, HCURSOR. |
COORINATE_INDICI | The type of a coordinate element used in POINT and RECTANGLE. Usually long or short. |
POINT | Point structure. Must contain public data members x and y. |
RECTANGLE | Rectangle structure. Must contain public data members left, top, right, and bottom. |
COLOR | Color type. In MS Windows, long. |
CONSTANT IDENTIFIER | DESCRIPTION |
---|---|
RECTANGLE_EMPTY | An empty rectange. In MS Windows, {0,0,0,0} |
MAXRECTANGLE | The maximum possible RECTANGLE. In MS Windows, {-MAXLONG,-MAXLONG,MAXLONG,MAXLONG}. |
COLOR_WHITE | White. In MS Windows, 0xFFFFFFL. |
COLOR_BLACK | Black. In MS Windows, 0L. |
FUNCTION IDENTIFIER | DESCRIPTION |
---|---|
int MRectangle(DEVICE, RECTANGLE, COLOR* fill=NULL, COLOR* border=NULL, int width=1, unsigned long style=PS_SOLID); | Draw a rectangle. Returns 0 for success. |
MEllipse(DEVICE, RECTANGLE, COLOR* fill=NULL, COLOR* border=NULL, int width=1, unsigned long style=PS_SOLID); | Draw an ellipse. Returns 0 for success. |
int MRoundRect(DEVICE, RECTANGLE, COORDINATE_INDICI w, COORDINATE_INDICI h, COLOR* fill=NULL, COLOR* border=NULL, int width=1, unsigned long style=PS_SOLID); | Draw a rounded rectangle. Returns 0 for success. |
int MPolygon(DEVICE, POINT* pVector, int count, COLOR* fill=NULL, COLOR* border=NULL, int width=1, unsigned long style=PS_SOLID); | Draw a closed polygon. Returns 0 for success. |
int MDrawLine(DEVICE,POINT,POINT, COLOR* color=NULL, int width=1, unsigned long style=PS_SOLID); | Draw a line. Returns 0 for success. |
bool MIsPointInRectangle(POINT, RECTANGLE); | Compute whether POINT is in RECTANGLE |
bool MIsPointInEllipse(POINT, RECTANGLE); | Compute whether POINT is in in an ellipse defined by RECTANGLE |
bool MIsPointInRoundRect(POINT, RECTANGLE, COORDINATE_INDICI w, COORDINATE_INDICI h); | Compute whether POINT is in the given rounded rectangle |
bool MIsPointInPolygon(POINT, POINT* pVector, int count); | Compute whether POINT is in the given polygon |
MENU createPopupMenu(void) | Returns a blank popup menu |
bool appendMenu_String(MENU, int id, char*) | Adds a string item to a the bottom of menu |
bool appendMenu_Popup(MENU, MENU subMenu, char*) | Adds a submenu item to a the bottom of menu |
bool appendMenu_Separator(MENU) | Adds a separator item to a the bottom of menu |
bool destroyMenu(MENU) | Destroys a menu |
int trackPopupMenu(MENU& menu, POINT& pt, char* menuName, int len); | displays a menu for selection at pt, returns the identifier of any selected item (or 0 if none selected). menuName if filled with text of the selected item. |
RECTANGLE trackRectangle(RECTANGLE r, COMPASEPOINTS p=SE, WINDOWHANDLE hwnd=0); | displays a rectangle and allows the user to resize it; returns the new, resized rectangle. |
POINT trackElasticLine(POINT anchor, POINT movePoint, WINDOWHANDLE hwnd=0); | Allows the user to reset one endpoint of the line defined by anchor and movePoint. |
The following structures are defined for every OS:
IDENTIFIER | DESCRIPTION |
---|---|
typedef enum {N=0x1, E=0x2, S=0x4, W=0x8, NE=0x3, NW=0x9, SW=0xC, SE=0x6} COMPASEPOINTS; | Edge points of a rectangle, ellipse, rounded rectangle, etc. |