1 /**************************************************************************
2 * fg_debug.c -- Flight Gear debug utility functions
4 * Written by Paul Bleisch, started January 1998.
6 * Copyright (C) 1998 Paul Bleisch, pbleisch@acm.org
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * (Log is kept at end of this file)
23 **************************************************************************/
25 #include <Main/fg_debug.h>
29 #include <strings.h> /* probably not portable */
31 static int fg_DebugSem = 1;
32 static fgDebugClass fg_DebugClass = FG_ALL;
33 static fgDebugPriority fg_DebugPriority = FG_INFO;
34 static fgDebugCallback fg_DebugCallback = NULL;
35 static FILE *fg_DebugOutput = stderr;
37 /* TODO: Actually make this thing thread safe */
39 #define FG_GRABDEBUGSEM while( --fg_DebugSem < 0 ) { fg_DebugSem++; }
40 #define FG_RELEASEDEBUGSEM fg_DebugSem++;
42 #define FG_GRABDEBUGSEM
43 #define FG_RELEASEDEBUGSEM
46 /* Used for convienence initialization from env variables.
51 } fg_DebugClasses[] = {
52 { "FG_NONE", 0x00000000 },
53 { "FG_TERRAIN", 0x00000001 },
54 { "FG_ASTRO", 0x00000002 },
55 { "FG_FLIGHT", 0x00000004 },
56 { "FG_INPUT", 0x00000008 },
57 { "FG_GL", 0x00000010 },
58 { "FG_VIEW", 0x00000020 },
59 { "FG_COCKPIT", 0x00000040 },
60 { "FG_GENERAL", 0x00000080 },
61 { "FG_MATH", 0x00000100 },
62 { "FG_EVENT", 0x00000200 },
64 /* Do not edit below here, last entry should be null */
65 { "FG_ALL", 0xFFFFFFFF },
68 static fgDebugClass fgDebugStrToClass( char *str );
71 /* fgInitDebug =============================================================*/
72 void fgInitDebug( void )
74 char *pszClass, *pszPrio;
77 fg_DebugSem=fg_DebugSem; /* shut up GCC */
79 pszPrio = getenv( "FG_DEBUGPRIORITY" );
81 fg_DebugPriority = atoi( pszPrio );
82 fprintf( stderr, "fg_debug.c: Environment overrides default debug priority (%d)\n",
86 pszClass = getenv( "FG_DEBUGCLASS" );
88 fg_DebugClass = fgDebugStrToClass( pszClass );
89 fprintf( stderr, "fg_debug.c: Environment overrides default debug class (0x%08X)\n",
96 /* fgDebugStrToClass ======================================================*/
97 fgDebugClass fgDebugStrToClass( char *str )
99 char *hex = "0123456789ABCDEF";
100 char *hexl = "0123456789abcdef";
101 char *pt, *p, *ph, ps=1;
102 unsigned int val = 0, i;
108 /* Check for 0xXXXXXX notation */
109 if( (p = strstr( str, "0x")) ) {
112 if( (ph = strchr(hex,*p)) || (ph = strchr(hexl,*p)) ){
118 /* fprintf( stderr, "Error in hex string '%s'\n", str );
125 /* Must be in string format */
129 while( *p && (*p==' ' || *p=='\t') ) p++; /* remove whitespace */
130 pt = p; /* mark token */
131 while( *p && (*p!='|') ) p++; /* find OR or EOS */
132 ps = *p; /* save value at p so we can attempt to be bounds safe */
133 *p++ = 0; /* terminate token */
134 /* determine value for token */
136 while( fg_DebugClasses[i].str &&
137 strncmp( fg_DebugClasses[i].str, pt, strlen(fg_DebugClasses[i].str)) ) i++;
138 if( fg_DebugClasses[i].str == NULL ) {
139 fprintf( stderr, "fg_debug.c: Could not find message class '%s'\n", pt );
141 val |= fg_DebugClasses[i].class;
145 return (fgDebugClass)val;
149 /* fgSetDebugOutput =======================================================*/
150 void fgSetDebugOutput( FILE *out )
153 fflush( fg_DebugOutput );
154 fg_DebugOutput = out;
159 /* fgSetDebugLevels =======================================================*/
160 void fgSetDebugLevels( fgDebugClass class, fgDebugPriority prio )
163 fg_DebugClass = class;
164 fg_DebugPriority = prio;
169 /* fgRegisterDebugCallback ================================================*/
170 fgDebugCallback fgRegisterDebugCallback( fgDebugCallback callback )
174 old = fg_DebugCallback;
175 fg_DebugCallback = callback;
181 /* fgPrintf ===============================================================*/
182 int fgPrintf( fgDebugClass class, fgDebugPriority prio, char *fmt, ... )
189 if( !(class & fg_DebugClass) || (prio < fg_DebugPriority) ) {
193 ret = vsprintf( szOut, fmt, (&fmt+1));
195 if( fg_DebugCallback!=NULL && fg_DebugCallback(class, prio, szOut) ) {
200 fprintf( fg_DebugOutput, szOut );
202 if( prio == FG_EXIT ) {
205 else if( prio == FG_ABORT ) {