/* DEBUG.H                      CIC Proprietary
 *-----------------------------------------------------------------------------
 * SCCS VERSION 1.1, 12:34:25 3/5/96
 *-----------------------------------------------------------------------------
 *
 * DESCRIPTION
 *
 *      Debugging macros allowing different systems to write to a debug
 *      file. When debugging is not enabled enabled by default if NDEBUG
 *      is not defined, this file will expand the macros into NULL macros
 *      (except for SPRINTF) so that the macros themselves need not be
 *      surrounded by RT_DIAG or DEBUG in the source code.
 *
 * MACRO EXPANSION OPTIONS
 *
 *      "PUBLIC"
 *
 *          When the symbol PUBLIC is defined, this header will also
 *          expand to include the definitions required for the global
 *          storage used by it debugging macros. This should only be
 *          defined once in a main module.
 *
 *      "DBGFILENAME"
 *
 *          When this symbol is defined, the global storage area will
 *          expand and use this filename as the output file for debugging
 *          trace file.
 *
 *      "APPEND"
 *
 *          This symbol defines the FOPEN flag that should be used when
 *          implicitly openning the debug output file. It should be "w"
 *          for writing a new file each time, or "a" for appending to any
 *          existing file. By default the flag uses the append option.
 *
 *      "ENABLE_LOGGING"
 *      "ENABLE_BREAKPOINTS"
 *      "ENABLE_TRACE"
 *
 *          These flags may optionally be set in order to set the initial
 *          runtime state of some control booleans. These states may be
 *          changed later on in the interactive debugger.
 *
 *      "DEBUG_STRLEN"
 *
 *          Maximum string length to use for dbgS. This value can be
 *          set by the caller, or more commonly used when building a
 *          special debug string to check for out of bounds conditions.
 *
 * PUBLIC MACROS
 *
 *      This header file defines the following publicly available macros
 *      that may be used on any platform.
 *
 *      CR                    Available only for debugging builds
 *      DEBUG_OPEN            Available only for debugging builds
 *      DEBUG_APPEND          Available only for debugging builds
 *      DEBUG_CLOSE           Available only for debugging builds
 *      DEBUG_OUTPUT          Available only for debugging builds
 *      ERROR_OUTPUT          Available only for debugging builds
 *      DEBUG_TRACE           Available only for debugging builds
 *      ERROR_EXIT            Available only for debugging builds
 *      SPRINTF               Available only for debugging builds
 *      BREAK_POINT           Available only for debugging builds
 *
 * HISTORY
 *
 *  JP Shipherd     04-Nov-92   Initial.
 *  B. Paulsen      16-Feb-93   Added DOS definitions.
 *  JP Shipherd     23-Apr-93   Differentiated between DEBUG_OUTPUT
 *                                  and ERROR_OUTPUT
 *  D. C. Foyt      10-May-93   Setup so that including DEBUG.H with
 *                                  PUBLIC set to true - you get the
 *                                  required globals declared.
 *  PL Spoltore     09-Aug-93   Updated file to function under Windows
 *  PL Spoltore     11-Aug-93   Added NULL macro expansion for
 *                                  non-debugging environment defs
 *                                  (!RT_MACRO & !DEBUG)
 *  JP Shipherd     24-Dec-93   Added support for seperate debug and
 *                                  profile files
 *  PL Spoltore     21-Jul-94   Similified file by removing some macros
 *                                  that seemed like a good idea at the
 *                                  the time but just never caught on.
 *  PL Spoltore     21-Jul-94   Updated for the required OS/2 features.
 *  PL Spoltore     02-Feb-95   Updated for the required Win95 features.
 *
 *-----------------------------------------------------------------------------
 */

#ifndef DEBUG_H           /* Protection against re-including this file     */
#define DEBUG_H

/***************************************************************************/
/* ENABLE DEBUGGING EXPANSIONS                                             */
/***************************************************************************/

#ifndef NDEBUG            /* Only use this file for debugging              */

/*-------------------------------------------------------------------------*/
/* Include Dependent Header Files                                          */
/*-------------------------------------------------------------------------*/

#include <stdio.h>         /* include fprintf() prototype                  */

#if OS2
#define INCL_DOS
#include <os2.h>
#endif

#include <stdtyp.h>

/*-------------------------------------------------------------------------*/
/* Declare any of the Global Definitions Required                          */
/*-------------------------------------------------------------------------*/

#ifndef APPEND
#define APPEND  "a"
#endif

#ifndef DEBUG_STRLEN
#define DEBUG_STRLEN 256
#endif

#ifndef FILENAME_MAX
#define FILENAME_MAX 128
#endif

#ifndef DBGFILENAME
#define DBGFILENAME "debug.log"
#endif

#ifndef ENABLE_TRACE
#define ENABLE_TRACE YES
#endif

#ifndef ENABLE_BREAKPOINTS
#define ENABLE_BREAKPOINTS YES
#endif

#ifndef ENABLE_LOGGING
#define ENABLE_LOGGING YES
#endif

/*-------------------------------------------------------------------------*/
/* Declare any of the Public Data Structures that are Required             */
/*-------------------------------------------------------------------------*/

#ifdef PUBLIC
#if PUBLIC

GLOBAL char dbgS[DEBUG_STRLEN]      = "\0";
GLOBAL char DebugFile[FILENAME_MAX] = DBGFILENAME;
GLOBAL char apFlags[16]             = APPEND;
GLOBAL FILE *hDebugFile             = NULL;
GLOBAL int  bTraceEnable            = ENABLE_TRACE;
GLOBAL int  bBreakEnable            = ENABLE_BREAKPOINTS;
GLOBAL int  bLogEnable              = ENABLE_LOGGING;

#endif
#endif

/*-------------------------------------------------------------------------*/
/* Declare a Compiler Dependent Breakpoint                                 */
/*-------------------------------------------------------------------------*/

#ifdef __WATCOMC__
extern void BreakPoint( void );
#pragma aux BreakPoint = 0xcc;
#else
#define BreakPoint()
#endif

/*-------------------------------------------------------------------------*/
/* Define Global Imports                                                   */
/*-------------------------------------------------------------------------*/

IMPORT char dbgS[DEBUG_STRLEN];

/*-------------------------------------------------------------------------*/
/* Define SUN macro expansions                                             */
/*-------------------------------------------------------------------------*/

#if SUN

#define CR  "\n"
#define DEBUG_OPEN
#define DEBUG_APPEND
#define DEBUG_CLOSE
#define DEBUG_OUTPUT \
    { \
    IMPORT char dbgS[DEBUG_STRLEN]; \
    fprintf(stderr, "%s", dbgS); \
    fflush(stderr); \
    };
#define ERROR_OUTPUT \
    { \
    IMPORT char dbgS[DEBUG_STRLEN]; \
    fprintf(stderr, "%s", dbgS); \
    fflush(stderr); \
    };
#define DEBUG_TRACE
#define ERROR_EXIT exit(-1);
#define SPRINTF sprintf
#define BREAK_POINT

#endif

/*-------------------------------------------------------------------------*/
/* Define PENDOS macro expansions                                          */
/*-------------------------------------------------------------------------*/

#if PEN_DOS

#define CR "\015\012"
#define DEBUG_OPEN
#define DEBUG_APPEND
#define DEBUG_CLOSE
#define DEBUG_OUTPUT \
    { \
    IMPORT char dbgS[DEBUG_STRLEN]; \
    fprintf(stderr, "%s", dbgS); \
    fflush(stderr); \
    };
#define ERROR_OUTPUT \
    { \
    IMPORT char dbgS[DEBUG_STRLEN]; \
    fprintf(stderr, "%s", dbgS); \
    fflush(stderr); \
    };
#define DEBUG_TRACE
#define ERROR_EXIT
#define SPRINTF sprintf
#define BREAK_POINT \
    { \
    IMPORT int bBreakEnable; \
    if ( bBreakEnable ) BreakPoint(); \
    };

#endif

/*-------------------------------------------------------------------------*/
/* Define PENWINDOWS macro expansions                                      */
/*-------------------------------------------------------------------------*/

#if WIN || WIN95

#define CR "\n"
#define DEBUG_OPEN
#define DEBUG_APPEND
#define DEBUG_CLOSE
#define DEBUG_OUTPUT \
    { \
    IMPORT char dbgS[DEBUG_STRLEN]; \
    OutputDebugString(dbgS); \
    };
#define ERROR_OUTPUT \
    { \
    IMPORT char dbgS[DEBUG_STRLEN]; \
    MessageBox(GetFocus(),dbgS,__FILE__,MB_OK|MB_SYSTEMMODAL); \
    OutputDebugString(dbgS); \
    };
#define DEBUG_TRACE
#define ERROR_EXIT
#define SPRINTF sprintf
#define BREAK_POINT \
    { \
    IMPORT int bBreakEnable; \
    if ( bBreakEnable ) { _asm int 3; } \
    };

#endif

/*-------------------------------------------------------------------------*/
/* Define OS/2 macro expansions                                            */
/*-------------------------------------------------------------------------*/

#if OS2

#include <stdio.h>

#define CR  "\n"
#define DEBUG_OPEN
#define DEBUG_APPEND
#define DEBUG_CLOSE
#define DEBUG_OUTPUT \
    { \
    FILE *pFile; \
    IMPORT char dbgS[DEBUG_STRLEN]; \
    IMPORT char DebugFile[FILENAME_MAX]; \
    IMPORT char apFlags[16]; \
    pFile = fopen( DebugFile, apFlags ); \
    fprintf( pFile, "%s", dbgS ); \
    fclose( pFile ); \
    };
#define DEBUG_TRACE \
    { \
    IMPORT int bTraceEnable; \
    if ( bTraceEnable ) \
        { \
        FILE *pFile; \
        IMPORT char dbgS[DEBUG_STRLEN]; \
        IMPORT char DebugFile[FILENAME_MAX]; \
        IMPORT char apFlags[16]; \
        PTIB pptib; \
        PPIB pppib; \
        DosGetInfoBlocks( &pptib, &pppib ); \
        sprintf( dbgS, "Process %d Thread %d at line %d in file %s\n", \
            pppib->pib_ulpid, pptib->tib_ordinal, __LINE__, __FILE__ ); \
        pFile = fopen( DebugFile, apFlags ); \
        fprintf( pFile, dbgS ); \
        fclose( pFile ); \
        } \
    };
#define ERROR_OUTPUT \
    { \
    FILE *pFile; \
    IMPORT char dbgS[DEBUG_STRLEN]; \
    IMPORT char DebugFile[FILENAME_MAX]; \
    IMPORT char apFlags[16]; \
    pFile = fopen( DebugFile, apFlags ); \
    fprintf( pFile, "%s\n", dbgS ); \
    fclose( pFile ); \
    };
#define ERROR_EXIT exit(-1);
#define SPRINTF sprintf
#define BREAK_POINT

#endif

/*
 *-----------------------------------------------------------------------------
 * Define DOS output using the standard filelib, this may take over brads
 * functions at some point
 *-----------------------------------------------------------------------------
 */

#if CICDOS

#define CR "\015\012"
#define DEBUG_OPEN
    { \
    IMPORT int bLogEnable; \
    if ( bLogEnable ) \
        { \
        IMPORT FILE *hDebugFile; \
        IMPORT char DebugFile[FILENAME_MAX]; \
        if ( hDebugFile != NULL ) \
            { \
            fclose(hDebugFile); \
            } \
        hDebugFile = fopen( DebugFile, "w+c"); \
        if ( hDebugFile == NULL ) \
            { \
            fprintf(stderr, "Can't Open Debug File"); \
            } \
        } \
    };
#define DEBUG_APPEND \
    { \
    IMPORT int bLogEnable; \
    if ( bLogEnable ) \
        { \
        IMPORT FILE *hDebugFile; \
        IMPORT char DebugFile[FILENAME_MAX]; \
        IMPORT char apFlags[16]; \
        if ( hDebugFile != NULL ) \
            { \
            fclose(hDebugFile); \
            } \
        hDebugFile = fopen( DebugFile, apFlags ); \
        if ( hDebugFile == NULL ) \
            { \
            fprintf(stderr, "Can't Open Debug File for Appending"); \
            } \
        } \
    };
#define DEBUG_CLOSE \
    { \
    IMPORT int bLogEnable; \
    if ( bLogEnable ) \
        { \
        IMPORT FILE *hDebugFile; \
        if ( hDebugFile != NULL ) \
            { \
            fclose(hDebugFile); \
            hDebugFile = NULL; \
            } \
        } \
    };
#define DEBUG_OUTPUT \
    { \
    IMPORT int bLogEnable; \
    if ( bLogEnable ) \
        { \
        IMPORT char dbgS[DEBUG_STRLEN]; \
        IMPORT FILE *hDebugFile; \
        if ( hDebugFile == NULL ) \
            { \
            IMPORT char DebugFile[FILENAME_MAX]; \
            IMPORT char apFlags[16]; \
            hDebugFile = fopen( DebugFile, apFlags ); \
            if ( hDebugFile == NULL ) \
                { \
                fprintf(stderr, "Can't Open Debug File"); \
                } \
            else \
                { \
                fprintf( hDebugFile, "%s", dbgS ); \
                fflush( hDebugFile ); \
                } \
            } \
        else \
            { \
            fprintf( hDebugFile, "%s", dbgS ); \
            fflush( hDebugFile ); \
            } \
        } \
    };
#define DEBUG_TRACE
#define ERROR_OUTPUT \
    { \
    IMPORT int bLogEnable; \
    if ( bLogEnable ) \
        { \
        IMPORT char dbgS[DEBUG_STRLEN]; \
        IMPORT FILE *hDebugFile; \
        if ( hDebugFile == NULL ) \
            { \
            IMPORT char DebugFile[FILENAME_MAX]; \
            IMPORT char apFlags[16]; \
            hDebugFile = fopen( DebugFile, apFlags ); \
            if ( hDebugFile == NULL ) \
                { \
                fprintf(stderr, "Can't Open Debug File"); \
                } \
            else \
                { \
                fprintf( hDebugFile, "%s", dbgS ); \
                fflush( hDebugFile ); \
                fprintf(stderr,  dbgS, __FILE__); \
                } \
            } \
        else \
            { \
            fprintf( hDebugFile, "%s", dbgS ); \
            fflush( hDebugFile ); \
            fprintf(stderr,  dbgS, __FILE__); \
            } \
        } \
    };
#define ERROR_EXIT
#define SPRINTF wsprintf
#define BREAK_POINT \
    { \
    IMPORT int bBreakEnable; \
    if ( bBreakEnable ) BreakPoint(); \
    };

#endif

#endif /* EndIf not defined NDEBUG */

/***************************************************************************/
/* DEBUGGING DISABLED EXPANSIONS                                           */
/***************************************************************************/

#ifdef NDEBUG               /* Only use this file for non-debugging        */

#define CR
#define DEBUG_OPEN
#define DEBUG_APPEND
#define DEBUG_CLOSE
#define DEBUG_OUTPUT
#define ERROR_OUTPUT
#define SPRINTF
#define DEBUG_TRACE
#define ERROR_EXIT
#define BREAK_POINT

#endif   /* EndIf defined NDEBUG */

/***************************************************************************/
/* Final Check to be sure the Macros ALL got defined                       */
/***************************************************************************/

#ifndef DEBUG_OPEN
#define DEBUG_OPEN
#error "DEBUG_OPEN not defined on this platform"
#endif

#ifndef DEBUG_APPEND
#define DEBUG_APPEND
#error "DEBUG_APPEND not defined on this platform"
#endif

#ifndef DEBUG_CLOSE
#define DEBUG_CLOSE
#error "DEBUG_CLOSE not defined on this platform"
#endif

#ifndef DEBUG_TRACE
#define DEBUG_TRACE
#error "DEBUG_TRACE not defined on this platform"
#endif

#ifndef DEBUG_OUTPUT
#define DEBUG_OUTPUT
#error "DEBUG_OUTPUT not defined on this platform"
#endif

#ifndef ERROR_OUTPUT
#define ERROR_OUTPUT
#error "ERROR_OUTPUT not defined on this platform"
#endif

#ifndef SPRINTF
#define SPRINTF
#error "SPRINTF not defined on this platform"
#endif

#ifndef BREAK_POINT
#define BREAK_POINT
#error "BREAK_POINT not defined on this platform"
#endif

#ifndef ERROR_EXIT
#define ERROR_EXIT
#error "ERROR_EXIT not defined on this platform"
#endif

/*-------------------------------------------------------------------------*/
/* End of Include - Do not place any line below this                       */
/* End of Include - Do not place any line below this                       */
/* End of Include - Do not place any line below this                       */
/*-------------------------------------------------------------------------*/

#endif   /* ifndef DEBUG_H */

/*-------------------------------------------------------------------------*/
/* End of File                                                             */
/* End of File                                                             */
/* End of File                                                             */
/*-------------------------------------------------------------------------*/
