Initial revision.
This commit is contained in:
parent
3680a11148
commit
c11b4357ed
2 changed files with 340 additions and 0 deletions
211
Main/fg_debug.c
Normal file
211
Main/fg_debug.c
Normal 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
129
Main/fg_debug.h
Normal 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 */
|
||||||
|
|
Loading…
Reference in a new issue