266 lines
7.7 KiB
C
266 lines
7.7 KiB
C
/*
|
||
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
|
||
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
|
||
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
|
||
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
|
||
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
|
||
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
|
||
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
|
||
**
|
||
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
|
||
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
|
||
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
|
||
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
|
||
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
|
||
** THE UNITED STATES.
|
||
**
|
||
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
|
||
**
|
||
** $Revision$
|
||
** $Date$
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
|
||
#include <stdarg.h>
|
||
#include <string.h>
|
||
|
||
#ifdef __WIN32__
|
||
#define WIN32_LEAN_AND_MEAN
|
||
#include <windows.h>
|
||
#endif
|
||
|
||
#include <3dfx.h>
|
||
#define FX_DLL_DEFINITION
|
||
#include <fxdll.h>
|
||
#include "gdebug.h"
|
||
|
||
#define GETENV getenv
|
||
|
||
static char *gdbg_myname = "gd"; // default library name
|
||
static char gdbg_debuglevel[GDBG_MAX_LEVELS]; // array of debuglevel controls
|
||
|
||
static long gdbg_errors = 0;
|
||
|
||
static FxBool UseDebugString;
|
||
|
||
static FILE *gdbg_msgfile = NULL; /*stdout;*/ // GDBG info/error file
|
||
|
||
//----------------------------------------------------------------------
|
||
// initialize gdbg_level from an environment variable
|
||
//----------------------------------------------------------------------
|
||
static char *setRange(char *buf, int val)
|
||
{
|
||
int r0,r1,pos;
|
||
|
||
sscanf(buf,"%i%n",&r0,&pos); // parse the first integer
|
||
if (buf[pos]=='-' || buf[pos]==':') // if there's a second
|
||
sscanf(buf+pos+1,"%i%n",&r1,&pos); // then parse it
|
||
else
|
||
r1 = r0;
|
||
|
||
if (r0 < 0) r0 = 0; // sanity checks
|
||
if (r1 >= GDBG_MAX_LEVELS) r1 = GDBG_MAX_LEVELS-1;
|
||
if (r1 < r0) r1 = r0;
|
||
|
||
while (r0 <= r1) // now set the debuglevel levels
|
||
gdbg_debuglevel[r0++] = val;
|
||
|
||
return buf + pos; // and return rest of string
|
||
}
|
||
|
||
static void parse(char *env)
|
||
{
|
||
int level, pos;
|
||
|
||
do {
|
||
if (env[0] == ',') // advance past commas
|
||
env++;
|
||
if (env[0] == '+') // if + then enable a range
|
||
env = setRange(env+1,1);
|
||
else if (env[0] == '-') // if - then disable a range
|
||
env = setRange(env+1,0);
|
||
else { // else just a number
|
||
if (EOF == sscanf(env,"%i%n",&level,&pos)) return;
|
||
if (pos==0) return; // oops, guess not
|
||
if (level >= GDBG_MAX_LEVELS) level = GDBG_MAX_LEVELS-1;
|
||
while (level >= 0) // enable the range [0,#]
|
||
gdbg_debuglevel[level--] = 1;
|
||
env += pos;
|
||
}
|
||
} while (env[0] == ',');
|
||
}
|
||
|
||
void FX_EXPORT FX_CSTYLE
|
||
gdbg_init(void)
|
||
{
|
||
static int done=0; // only execute once
|
||
char *env;
|
||
|
||
if (done) return;
|
||
|
||
/* I can't init gdbg_msgfile to stdout since it isn't constant so
|
||
* I do it now */
|
||
gdbg_msgfile = stdout;
|
||
|
||
done = 1;
|
||
gdbg_debuglevel[0] = 1; // always enable level 0
|
||
env = GETENV("GDBG_FILE");
|
||
if (env != NULL) GDBG_SET_FILE(env);
|
||
env = GETENV("GDBG_LEVEL");
|
||
if (env == NULL) env = "0";
|
||
parse(env);
|
||
gdbg_info(1,"gdbg_init(): debug level = %s\n",env);
|
||
}
|
||
|
||
void FX_EXPORT FX_CSTYLE
|
||
gdbg_shutdown(void)
|
||
{
|
||
gdbg_info(1,"gdbg_shutdown()\n");
|
||
if (gdbg_msgfile != stdout) { // close any existing output file
|
||
fclose(gdbg_msgfile);
|
||
gdbg_msgfile = stdout;
|
||
}
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// the MAIN message display suboutine - ALL messages come thru here
|
||
//----------------------------------------------------------------------
|
||
void FX_EXPORT FX_CSTYLE
|
||
gdbg_vprintf (const char *format,va_list args)
|
||
{
|
||
|
||
if (gdbg_msgfile != NULL) {
|
||
if (!UseDebugString) {
|
||
|
||
vfprintf(gdbg_msgfile,format,args);
|
||
|
||
fflush(gdbg_msgfile);
|
||
}
|
||
#ifdef __WIN32__
|
||
else {
|
||
char msgString[1024];
|
||
|
||
vsprintf(msgString, format, args);
|
||
OutputDebugString(msgString);
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
void FX_EXPORT FX_CSTYLE
|
||
gdbg_printf (const char *format, ...)
|
||
{
|
||
va_list args;
|
||
|
||
va_start(args, format);
|
||
gdbg_vprintf(format,args);
|
||
va_end(args);
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// INFO message subroutines
|
||
//----------------------------------------------------------------------
|
||
|
||
//----------------------------------------------------------------------
|
||
// display an INFO message if level <= debug level and return whether
|
||
// debug level high enough to allow display
|
||
//----------------------------------------------------------------------
|
||
int FX_EXPORT FX_CSTYLE
|
||
gdbg_info (const int level, const char *format, ...)
|
||
{
|
||
va_list args;
|
||
char newformat[4095];
|
||
|
||
if (!gdbg_debuglevel[level>=GDBG_MAX_LEVELS ? GDBG_MAX_LEVELS-1 : level])
|
||
return(0);
|
||
va_start(args, format);
|
||
sprintf(newformat, "%s.%d:\t", gdbg_myname,level);
|
||
strcat(newformat,format);
|
||
gdbg_vprintf(newformat,args);
|
||
va_end(args);
|
||
return (1);
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// same as gdbg_info but does not display INFO header
|
||
//----------------------------------------------------------------------
|
||
int FX_EXPORT FX_CSTYLE
|
||
gdbg_info_more (const int level, const char *format, ...)
|
||
{
|
||
va_list args;
|
||
|
||
if (!gdbg_debuglevel[level>=GDBG_MAX_LEVELS ? GDBG_MAX_LEVELS-1 : level])
|
||
return(0);
|
||
va_start(args, format);
|
||
gdbg_vprintf(format,args);
|
||
va_end(args);
|
||
return (1);
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// ALL errors must come thru here, this subroutine adds a preamble
|
||
// and then displays the message and increments the error counter
|
||
//----------------------------------------------------------------------
|
||
void FX_EXPORT FX_CSTYLE
|
||
gdbg_error (const char *kind, const char *format, ...)
|
||
{
|
||
va_list args;
|
||
|
||
char newformat[1024];
|
||
|
||
va_start(args, format);
|
||
sprintf(newformat, "%s error (%s): ", gdbg_myname,kind);
|
||
strcat(newformat,format); // add a preamble to message
|
||
gdbg_vprintf(newformat,args);
|
||
gdbg_errors++; // increment the error counter
|
||
va_end(args);
|
||
}
|
||
|
||
// return the error counter
|
||
int FX_EXPORT FX_CSTYLE
|
||
gdbg_get_errors(void)
|
||
{
|
||
return gdbg_errors;
|
||
}
|
||
|
||
// return a debuglevel level
|
||
int FX_EXPORT FX_CSTYLE
|
||
gdbg_get_debuglevel(const int level)
|
||
{
|
||
return gdbg_debuglevel[level>=GDBG_MAX_LEVELS ? GDBG_MAX_LEVELS-1 : level];
|
||
}
|
||
|
||
// set a debuglevel level
|
||
void FX_EXPORT FX_CSTYLE
|
||
gdbg_set_debuglevel(const int level, const int value)
|
||
{
|
||
gdbg_debuglevel[level>=GDBG_MAX_LEVELS ? GDBG_MAX_LEVELS-1 : level] = value;
|
||
}
|
||
|
||
// open up a new output file
|
||
int FX_EXPORT FX_CSTYLE
|
||
gdbg_set_file(const char *name)
|
||
{
|
||
FILE *outf;
|
||
|
||
if (gdbg_msgfile != stdout) { // close any existing output file
|
||
fclose(gdbg_msgfile);
|
||
gdbg_msgfile = stdout;
|
||
}
|
||
#ifdef __WIN32__
|
||
else if (!strcmp(name, "DEBUG")) {
|
||
gdbg_msgfile = (FILE *) 1;
|
||
UseDebugString = 1;
|
||
}
|
||
#endif
|
||
else {
|
||
outf = fopen(name,"w"); // open up a new one
|
||
if (outf) gdbg_msgfile = outf;
|
||
return outf != NULL;
|
||
}
|
||
return FXTRUE;
|
||
}
|