Diagnostic Macros
Home Up

 

Default Macros

Header File
    <owl/private/checks.h>     - alwas included

Default macros provide straightforward value checking and message output.

IFDBG
    Syntax
       IFDBG(<expr>)
    Description
        If    DEBUG <= 0  -> <expr> evaluates to ().
IFNDBG
    Syntax
       IFNDBG(<expr>)
    Description
        If    DEBUG > 0  -> <expr> evaluates to ().  
IFDIAG
    Syntax
       IFDIAG(<expr>)
    Description
        If  not defined  __TRACE  and __WARN  -> <expr> evaluates to ().
IFNDIAG
    Syntax
       IFNDIAG(<expr>)
    Description
        If  defined  __TRACE  and __WARN   -> <expr> evaluates to ().
CHECK
    Syntax
       CHECK(<cond>)
    Description
        Throws a CHECK exception if <cond> equals 0. Use CHECK to perform value checking within a function.
PRECONDITION
    Syntax
        PRECONDITION(<cond>)
    Description
        Throws a PRECONDITION exception if <cond> equals 0. Use PRECONDITION on entry to a function to check the validity of the arguments and to do any other checking to determine if the function has been invoked correctly.
TRACE
    Syntax
        TRACE(<msg>)
    Description
        Outputs <msg>. TRACE is used to output general messages that are not dependent upon a particular condition.
TRACE_FUNCTION
    Syntax
        TRACE_FUNCTION(<f>)
    Description
        Declares an object on the stack that will ouput the function name f in its ctor and again its dtor. The output would be:
          >> Foo
         << Foo
TRACE_FUNCTIONP
    Syntax
        TRACE_FUNCTIONP(<f>,<p>)
    Description
        Similar to TRACE_FUNCTION except that it add parameter.
VERIFY
    Syntax
        VERIFY(<p>)
    Description
        Same as CHECK except that the expression remains for release builds. This is ideal for an expression that has side-effects. Eg: VERIFY(LoadString(...)).
WARN
    Syntax
        WARN(<cond>,<msg>)
    Description
        Outputs <msg> if <cond> is nonzero. It is used to output conditional messages.

Extended macros

The extended macros CHECKX and PRECONDITIONX augment CHECK and PRECONDITION by letting you provide a message to be output when the condition fails.
The extended macros TRACEX and WARNX augment TRACE and WARN by providing a way to specify macro groups that can be independently enabled or disabled. TRACEX and WARNX require additional arguments that specify the group to which the macros belongs, and the threshold level at which the macro should be executed. The macro is excuted only if the specified group is enabled and has a threshold level which is greater than or equal to the threshhold level argument used in the macro.

Header File
    <owl/private/checks.h>     - alwas included

CHECKX
    Syntax
        CHECKX(<cond>,<msg>)
    Description
        Outputs <msg> and throws an exception if <cond> equals 0. Use CHECKX to perform value checking within a function.
PRECONDITIONX
   Syntax
        PRECONDITIONX(<cond>,<msg>)
    Description
        Outputs <msg> and throws an exception if <cond> equals 0. Use PRECONDITIONX on entry to a function to check the validity of the arguments and to do any other checking to determine if the function has been invoked correctly.
TRACEX
   Syntax
        TRACEX(<group>,<level>,<msg>)
    Description
        Trace only if <group> and <level> are enabled.
TRACE_FUNCTIONX
    Syntax
        TRACE_FUNCTIONX(<g>,<f>)
    Description
        Declares an object on the stack that will ouput the function name f  in its ctor and again its dtor. The output would be:
          >> Foo
         << Foo
TRACE_FUNCTIONXP
    Syntax
        TRACE_FUNCTIONXP(<g>,<f>,<p>)
    Description
        Similar to TRACE_FUNCTIONX except that it add parameter.
VERIFYX
    Syntax
        VERIFYX(<p>,<msg>)
    Description
        Outputs <msg>. TRACE is used to output general messages that are not dependent upon a particular condition.
WARNX
   Syntax
        WARNX(<group>,<cond>,<level>,<msg>)
    Description
        Warn only if <group> and <level> are enabled.
DIAG_DECLARE_GROUP
    Syntax
        DIAG_DECLARE_GROUP(<name>)
    Description
        Declare a group named <name>. You cannot use DIAG_DECLARE_GROUP and DIAG_DEFINE_GROUP in the same compilation unit.
DIAG_DECLARE_EXPORTGROUP
    Syntax
        DIAG_DECLARE_EXPORTGROUP(<name>)
    Description
        Declare a group named <name> that exported from DLL. You cannot use DIAG_DECLARE_EXPORTGROUP and DIAG_DEFINE_EXPORTGROUP in the same compilation unit.
DIAG_DECLARE_IMPORTTGROUP
    Syntax
        DIAG_DECLARE_IMPORTTGROUP(<name>)
    Description
        Declare a group named <name> that imported from DLL.
DIAG_DEFINE_GROUP
    Syntax
        DIAG_DEFINE_GROUP(<name>,<enabled>,<level>)
    Description
        Define a group named <name>. You cannot use DIAG_DECLARE_GROUP and DIAG_DEFINE_GROUP in the same compilation unit.
DIAG_DEFINE_EXPORTGROUP
    Syntax
        DIAG_DEFINE_EXPORTGROUP(<name>,<enabled>,<level>)
    Description
        Define a group named <name> for exporting from DLL. You cannot use DIAG_DECLARE_EXPORTGROUP and DIAG_DEFINE_EXPORTGROUP in the same compilation unit.
_OWL_INI
    Syntax
        _OWL_INI
    Description
        Name of the file where ObjectWindows runtime options are stored. It is used mainly for diagnostic libraries.
DIAG_DEFINE_GROUP_INIT
    Syntax
        DIAG_DEFINE_GROUP_INIT(<file>,<group>,<enabled>,<level>)
    Description
        Define a group named <group>, and <file> to get setting from. You cannot use DIAG_DECLARE_GROUP and DIAG_DEFINE_GROUP_INIT in the same compilation unit.
DIAG_DEFINE_EXPORTGROUP_INIT
    Syntax
        DIAG_DEFINE_EXPORTGROUP_INIT(<file>,<group>,<enabled>,<level>)
    Description
        Define a group named <group>, and <file> to get setting from, for exporting from DLL. You cannot use DIAG_DECLARE_GROUP and DIAG_DEFINE_EXPORTGROUP_INIT in the same compilation unit.
DIAG_ENABLE
    Syntax
        DIAG_ENABLE(<group>,<state>)
    Description
        Sets <group>'s enable flag to <state>.
DIAG_ISENABLED
    Syntax
        DIAG_ISENABLED(<group>)
    Description
        Returns nonzero if <group> is enabled.
DIAG_SETLEVEL
    Syntax
        DIAG_SETLEVEL(<group>,<level>)
    Description
        Sets <group>'s threshold level to <level>.
DIAG_GETLEVEL
    Syntax
        DIAG_GETLEVEL(<group>)
    Description
        Gets <group>'s threshold level.
        Threshold levels are arbitrary numeric values that establish a threshold for enabling macros. A macro with a level greater than the group threshold level will not be executed. For example, if a group has a threshold level of 0 (the default value), all macros that belong to that group and have levels of 1 or greater are ignored.
DIAG_REDIRECT
    Syntax
        DIAG_REDIRECT(<group>,<hook>)
    Description
        Redirect <group> output to <hook>. Where: <hook> - pointer to TDiagBaseHook; If <TDiagBaseHook*> == 0, output resets to default.
TDiagBaseHook declared as:

struct TDiagBaseHook {
    virtual void Output(TDiagBase* group, LPCTSTR str) = 0;
};

Using Preprocessor Symbols

Three preprocessor symbols control diagnostic macro expansion: _ _DEBUG, _ _TRACE, and _ _WARN. If one of these symbols is defined when compiling, then the corresponding macros expand and diagnostic code is generated. If none of these symbols is defined, then the macros do not expand and no diagnostic code is generated. These symbols can be defined on the command line using the -D switch, or by using #define statements within your code.

  __DEBUG=1   __DEBUG=2 __TRACE __WARN
PRECONDITION   X   X    
PRECONDITIONX   X   X    
CHECK     X    
CHECKX     X    
TRACE     X    
TRACEX     X    
WARN     X    
WARNX     X    

To create a diagnostic version of an executable, place the diagnostic macros at strategic points within the program code and compile with the appropriate preprocessor symbols defined. Diagnostic versions of the Borland class libraries are built in a similar manner.

TRACE and WARN Example

The following program illustrates the use of the default TRACE and WARN macros:

int OwlMain()
{
    TRACE( "Hello World" );
    WARN( 5 != 5, "Math is broken!" );
    WARN( 5 != 7, "Math still works!" );
    return 0;
}

When the above code is compiled with _ _TRACE and _ _WARN defined, it produces the following output when run:

Trace PROG.C 5: [Def] Hello World
Warning PROG.C 7: [Def] Math still works!

The above output indicates that the message "Hello World" was output by the default TRACE macro on line 5 of PROG.C, and the message "Math still works!" was output by the default WARN macro on line 7 of PROG.C.
Default diagnostic macros expand to extended diagnostic macros with the group set to "Def" and the level set to 0. This "Def" group controls the behavior of the default macros and is initially enabled with a threshold level of 0.

Extended Diagnostics Macros Example

The following PROG.C example defines two diagnostic groups, Group1 and Group2, which are used as arguments to extended diagnostic macros:

DIAG_DEFINE_GROUP(Group1,1,0);
DIAG_DEFINE_GROUP(Group2,1,0);

void OwlMain( int argc, char **argv )
{
    TRACE( "Always works, argc=" << argc );

    TRACEX( Group1, 0, "Hello" );
    TRACEX( Group2, 0, "Hello" );

    DIAG_DISABLE(Group1);

    TRACEX( Group1, 0, "Won't execute - group is disabled!" );
    TRACEX( Group2, 3, "Won't execute - level is too high!" );
}

When the above code is compiled with _ _TRACE defined and run, it produces the following output:

Trace PROG.C 8: [Def] Always works, argc=1
Trace PROG.C 10: [Group1] Hello
Trace PROG.C 11: [Group2] Hello

Note that the last two macros are not executed. In the first case, the group Group1 is disabled. In the second case, the macro level exceeds Group2's threshold level (set by default to 0).

Macro Message Output

The TRACE, TRACEX, WARN, and WARNX macros take a <msg> argument that is conditionally inserted into an output stream. This means a sequence of objects can be inserted in the output stream (for example TRACE( "Mouse @ " << x << "," << y ); ). The use of streams is extensible to different object types and allows for parameters within trace messages.
Diagnostic macro message output can be viewed while the program is running. If the target environment is Windows, the output is sent to the OutputDebugString function, and can be viewed with the DBWIN.EXE or OX.SYS utilities. If Turbo Debugger is running, the output will be sent to its log window.  You can also use DiagXprt.exe or OutDebg32.exe from owl/Tools. Enhanced version of  DiagXprt.exe can be downloaded from OWL NExt download page.
Output can be redirected with macro DIAG_REDIRECT

Run-Time Macro Control

Diagnostic groups can be controlled at runtime by using the control macros within your program or by directly modifying the group information within the debugger.
This group information is contained in a template class named TDiagGroup<TDiagGroupClass##Group>, where ##Group is the name of the group. This class contains a static structure Flags, which in turn contains the enabled flag and the threshold level. For example, to enable the group Group1, you would set the variable TDiagGroup<TDiagGroupClassGroup1>::Flags.Enabled to 1.

Additional Functions and Macros

_OWLBREAK
    Syntax
        _OWLBREAK
    Description
        Alwas valid. Produce Debug Break
BreakMessage
    Syntax
        BreakMessage(LPCTSTR type, LPCTSTR msg, LPCTSTR file, int line );
    Description
        For internall use by CHECK[X] and   PRECONDITION[X]. Show to user MessageBox with options Retray,Abort, Ignore
For retry executes _OWLBREAK, If Abort Throw exeption, if Ignore continue execution.
OWLGetVersion
    Syntax
        uint16 far OWLGetVersion();
    Description
        Get version of OWL (dll) at runtime
GetDiagEnabled
    Syntax
        uint8 GetDiagEnabled(LPCTSTR file, LPCTSTR name, uint8 e);
    Description
        Get 1 if Diagnostic enabled in ini file.
GetDiagLevel
    Syntax
        uint8 GetDiagLevel(LPCTSTR file, LPCTSTR name, uint8 e);
    Description
        Get Diagnostic level from ini file

 


Copyright © 1998-2001 Yura Bidus. All rights reserved.