1
0
Fork 0

Initial revision.

This commit is contained in:
curt 1998-01-27 02:54:43 +00:00
parent 3680a11148
commit c11b4357ed
2 changed files with 340 additions and 0 deletions

211
Main/fg_debug.c Normal file
View file

@ -0,0 +1,211 @@
/**************************************************************************
* fg_debug.c -- Flight Gear debug utility functions
*
* Written by Paul Bleisch, started January 1998.
*
* Copyright (C) 1998 Paul Bleisch, pbleisch@acm.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* (Log is kept at end of this file)
**************************************************************************/
#include <Main/fg_debug.h>
#include <varargs.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h> /* probably not portable */
static int fg_DebugSem = 1;
static fgDebugClass fg_DebugClass = FG_ALL;
static fgDebugPriority fg_DebugPriority = FG_INFO;
static fgDebugCallback fg_DebugCallback = NULL;
static FILE *fg_DebugOutput = stderr;
/* TODO: Actually make this thing thread safe */
#ifdef USETHREADS
#define FG_GRABDEBUGSEM while( --fg_DebugSem < 0 ) { fg_DebugSem++; }
#define FG_RELEASEDEBUGSEM fg_DebugSem++;
#else
#define FG_GRABDEBUGSEM
#define FG_RELEASEDEBUGSEM
#endif
/* Used for convienence initialization from env variables.
*/
static struct {
char *str;
fgDebugClass class;
} fg_DebugClasses[] = {
{ "FG_NONE", 0x00000000 },
{ "FG_TERRAIN", 0x00000001 },
{ "FG_ASTRO", 0x00000002 },
{ "FG_FLIGHT", 0x00000004 },
{ "FG_INPUT", 0x00000008 },
{ "FG_GL", 0x00000010 },
{ "FG_VIEW", 0x00000020 },
{ "FG_COCKPIT", 0x00000040 },
{ "FG_GENERAL", 0x00000080 },
{ "FG_MATH", 0x00000100 },
{ "FG_EVENT", 0x00000200 },
/* Do not edit below here, last entry should be null */
{ "FG_ALL", 0xFFFFFFFF },
{ NULL, 0 } };
static fgDebugClass fgDebugStrToClass( char *str );
/* fgInitDebug =============================================================*/
void fgInitDebug( void )
{
char *pszClass, *pszPrio;
FG_GRABDEBUGSEM;
fg_DebugSem=fg_DebugSem; /* shut up GCC */
pszPrio = getenv( "FG_DEBUGPRIORITY" );
if( pszPrio ) {
fg_DebugPriority = atoi( pszPrio );
fprintf( stderr, "fg_debug.c: Environment overrides default debug priority (%d)\n",
fg_DebugPriority );
}
pszClass = getenv( "FG_DEBUGCLASS" );
if( pszClass ) {
fg_DebugClass = fgDebugStrToClass( pszClass );
fprintf( stderr, "fg_debug.c: Environment overrides default debug class (0x%08X)\n",
fg_DebugClass );
}
FG_RELEASEDEBUGSEM;
}
/* fgDebugStrToClass ======================================================*/
fgDebugClass fgDebugStrToClass( char *str )
{
char *hex = "0123456789ABCDEF";
char *hexl = "0123456789abcdef";
char *pt, *p, *ph, ps=1;
unsigned int val = 0, i;
if( str == NULL ) {
return 0;
}
/* Check for 0xXXXXXX notation */
if( (p = strstr( str, "0x")) ) {
p++; p++;
while (*p) {
if( (ph = strchr(hex,*p)) || (ph = strchr(hexl,*p)) ){
val <<= 4;
val += ph-hex;
p++;
}
else {
/* fprintf( stderr, "Error in hex string '%s'\n", str );
*/
return FG_NONE;
}
}
}
else {
/* Must be in string format */
p = str;
ps = 1;
while( ps ) {
while( *p && (*p==' ' || *p=='\t') ) p++; /* remove whitespace */
pt = p; /* mark token */
while( *p && (*p!='|') ) p++; /* find OR or EOS */
ps = *p; /* save value at p so we can attempt to be bounds safe */
*p++ = 0; /* terminate token */
/* determine value for token */
i=0;
while( fg_DebugClasses[i].str &&
strncmp( fg_DebugClasses[i].str, pt, strlen(fg_DebugClasses[i].str)) ) i++;
if( fg_DebugClasses[i].str == NULL ) {
fprintf( stderr, "fg_debug.c: Could not find message class '%s'\n", pt );
} else {
val |= fg_DebugClasses[i].class;
}
}
}
return (fgDebugClass)val;
}
/* fgSetDebugOutput =======================================================*/
void fgSetDebugOutput( FILE *out )
{
FG_GRABDEBUGSEM;
fflush( fg_DebugOutput );
fg_DebugOutput = out;
FG_RELEASEDEBUGSEM;
}
/* fgSetDebugLevels =======================================================*/
void fgSetDebugLevels( fgDebugClass class, fgDebugPriority prio )
{
FG_GRABDEBUGSEM;
fg_DebugClass = class;
fg_DebugPriority = prio;
FG_RELEASEDEBUGSEM;
}
/* fgRegisterDebugCallback ================================================*/
fgDebugCallback fgRegisterDebugCallback( fgDebugCallback callback )
{
fgDebugCallback old;
FG_GRABDEBUGSEM;
old = fg_DebugCallback;
fg_DebugCallback = callback;
FG_RELEASEDEBUGSEM;
return old;
}
/* fgPrintf ===============================================================*/
int fgPrintf( fgDebugClass class, fgDebugPriority prio, char *fmt, ... )
{
char szOut[1024+1];
int ret = 0;
FG_GRABDEBUGSEM;
if( !(class & fg_DebugClass) || (prio < fg_DebugPriority) ) {
FG_RELEASEDEBUGSEM;
return 0;
}
ret = vsprintf( szOut, fmt, (&fmt+1));
if( fg_DebugCallback!=NULL && fg_DebugCallback(class, prio, szOut) ) {
FG_RELEASEDEBUGSEM;
return ret;
}
else {
fprintf( fg_DebugOutput, szOut );
FG_RELEASEDEBUGSEM;
if( prio == FG_EXIT ) {
exit(0);
}
else if( prio == FG_ABORT ) {
abort();
}
}
return ret;
}

129
Main/fg_debug.h Normal file
View file

@ -0,0 +1,129 @@
/**************************************************************************
* fg_debug.h -- Flight Gear debug utility functions
*
* Written by Paul Bleisch, started January 1998.
*
* Copyright (C) 1998 Paul Bleisch, pbleisch@acm.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* (Log is kept at end of this file)
**************************************************************************/
#ifndef _FG_DEBUG_H
#define _FG_DEBUG_H
#include <stdio.h>
/* NB: To add a class, add it here, and add it to the structure
in fg_debug.c
*/
typedef enum {
FG_NONE = 0x00000000,
FG_TERRAIN = 0x00000001,
FG_ASTRO = 0x00000002,
FG_FLIGHT = 0x00000004,
FG_INPUT = 0x00000008,
FG_GL = 0x00000010,
FG_VIEW = 0x00000020,
FG_COCKPIT = 0x00000040,
FG_GENERAL = 0x00000080,
FG_MATH = 0x00000100,
FG_EVENT = 0x00000200,
FG_ALL = 0xFFFFFFFF
} fgDebugClass;
/* NB: To add a priority, add it here.
*/
typedef enum {
FG_BULK, /* For frequent messages */
FG_DEBUG, /* Less frequent debug type messages */
FG_INFO, /* Informatory messages */
FG_WARN, /* Possible impending problem */
FG_ALERT, /* Very possible impending problem */
FG_EXIT, /* Problem (no core) */
FG_ABORT /* Abandon ship (core) */
} fgDebugPriority;
/* Initialize the debuggin stuff. */
void fgInitDebug( void );
/* fgPrintf
Expects:
class fgDebugClass mask for this message.
prio fgDebugPriority of this message.
fmt printf like string format
... var args for fmt
Returns:
number of items in fmt handled.
This function works like the standard C library function printf() with
the addition of message classes and priorities (see fgDebugClasses
and fgDebugPriorities). These additions allow us to classify messages
and disable sets of messages at runtime. Only messages with a prio
greater than or equal to fg_DebugPriority and in the current debug class
(fg_DebugClass) are printed.
*/
int fgPrintf( fgDebugClass class, fgDebugPriority prio, char *fmt, ... );
/* fgSetDebugLevels()
Expects:
class Bitmask representing classes to display.
prio Minimum priority of messages to display.
*/
void fgSetDebugLevels( fgDebugClass class, fgDebugPriority prio );
/* fgSetDebugOutput()
Expects:
file A FILE* to a stream to send messages to.
It is assumed the file stream is open and writable. The system
defaults to stderr. The current stream is flushed but not
closed.
*/
void fgSetDebugOutput( FILE *out );
/* fgRegisterDebugCallback
Expects:
callback A function that takes parameters as defined by the
fgDebugCallback type.
Returns:
a pointer to the previously registered callback (if any)
Install a user defined debug log callback. This callback is called w
whenever fgPrintf is called. The parameters passed to the callback are
defined above by fgDebugCallback. outstr is the string that is to be
printed. If callback returns nonzero, it is assumed that the message
was handled fully by the callback and **fgPrintf need do no further
processing of the message.** Only one callback may be installed at a
time.
*/
typedef int (*fgDebugCallback)(fgDebugClass, fgDebugPriority, char *outstr);
fgDebugCallback fgRegisterDebugCallback( fgDebugCallback callback );
#endif /* _FG_DEBUG_H */