source: trunk/src/opengl/glide/cvg/init/gdebug.c

Last change on this file was 6653, checked in by bird, 24 years ago

Added $Id:$ keyword.

File size: 12.6 KB
Line 
1/*-*-c++-*-*/
2/* $Id: gdebug.c,v 1.2 2001-09-05 14:30:37 bird Exp $ */
3#include "vxd.h"
4
5/*
6** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
7** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
8** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
9** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
10** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
11** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
12** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
13** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
14**
15** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
16** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
17** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
18** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
19** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
20** THE UNITED STATES.
21**
22** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
23**
24** $Revision: 1.2 $
25** $Date: 2001-09-05 14:30:37 $
26*/
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <stdarg.h>
31#include <string.h>
32
33#include <3dfx.h>
34
35#if __MWERKS__
36/* Dork w/ the console window */
37#include <sioux.h>
38
39/* So the debug level comes from the right place */
40#include <cvg.h>
41#include <sst1init.h>
42#endif /* __MWERKS__ */
43
44#define FX_DLL_DEFINITION
45#include <fxdll.h>
46#include <fxpci.h>
47#include <gdebug.h>
48
49#if defined(__WIN32__) && !defined(KERNEL)
50#include <windows.h>
51#endif /* defined(__WIN32__) && !defined(KERNEL) */
52
53#define USE_DEBUG_STRING (__DOS32__ || __WIN32__)
54#if USE_DEBUG_STRING
55static FxBool UseDebugString = 0;
56#endif /* USE_DEBUG_STRING */
57
58#ifdef KERNEL_NT
59
60void __stdcall
61EngDebugPrint(
62 char * StandardPrefix,
63 const char * DebugMessage,
64 va_list ap
65 );
66
67#endif
68
69static char *gdbg_myname = "gd"; // default library name
70static char gdbg_debuglevel[GDBG_MAX_LEVELS]; // array of debuglevel controls
71
72static long gdbg_errors = 0;
73
74
75#ifdef KERNEL
76// gdbgout is array to store strings for debug output
77//#include <windows.h>
78static char gdbgout[512];
79
80// for setting levels interactively through the debugger while you're
81// running in the KERNEL mode
82void setLevel(int level, int value)
83{
84 if (level >= GDBG_MAX_LEVELS)
85 level = GDBG_MAX_LEVELS - 1;
86
87 gdbg_debuglevel[level] = value;
88}
89
90
91#ifndef KERNEL_NT
92// we need to call a kernal printf.
93extern int __cdecl klvfprintf(FILE *stream,
94 const char *format,
95 va_list arg ) ;
96#endif
97
98static FILE *gdbg_msgfile; // GDBG info/error file
99#else /* #ifdef KERNEL */
100
101static FILE *gdbg_msgfile = NULL; /*stdout;*/ // GDBG info/error file
102
103//----------------------------------------------------------------------
104// initialize gdbg_level from an environment variable
105//----------------------------------------------------------------------
106static const char *setRange(const char *buf, int val)
107{
108 int r0,r1,pos;
109
110 sscanf(buf,"%i%n",&r0,&pos); // parse the first integer
111 if (buf[pos]=='-' || buf[pos]==':') { // if there's a second
112 buf += pos+1;
113 sscanf(buf,"%i%n",&r1,&pos); // then parse it
114 }
115 else
116 r1 = r0;
117
118 if (r0 < 0) r0 = 0; // sanity checks
119 if (r1 >= GDBG_MAX_LEVELS) r1 = GDBG_MAX_LEVELS-1;
120 if (r1 < r0) r1 = r0;
121
122 while (r0 <= r1) // now set the debuglevel levels
123 gdbg_debuglevel[r0++] = val;
124
125 return buf + pos; // and return rest of string
126}
127
128FX_EXPORT void FX_CSTYLE
129gdbg_parse(const char *env)
130{
131 int level, pos;
132
133 do {
134 if (env[0] == ',') // advance past commas
135 env++;
136 if (env[0] == '+') // if + then enable a range
137 env = setRange(env+1,1);
138 else if (env[0] == '-') // if - then disable a range
139 env = setRange(env+1,0);
140 else { // else just a number
141 if (sscanf(env,"%i%n",&level,&pos) <= 0) return;
142 if (pos==0) return; // oops, guess not
143 if (level >= GDBG_MAX_LEVELS) level = GDBG_MAX_LEVELS-1;
144 while (level >= 0) // enable the range [0,#]
145 gdbg_debuglevel[level--] = 1;
146 env += pos;
147 }
148 } while (env[0] == ',');
149}
150
151#endif /* #ifndef KERNEL */
152
153FX_EXPORT void FX_CSTYLE
154gdbg_init(void)
155{
156 static int done=0; // only execute once
157 char *env;
158
159 if (done) return;
160
161 /* I can't init gdbg_msgfile to stdout since it isn't constant so
162 * I do it now */
163 gdbg_msgfile = stdout;
164
165#if __MWERKS__
166 SIOUXSettings.standalone = false;
167 SIOUXSettings.setupmenus = false;
168 SIOUXSettings.autocloseonquit = true;
169 SIOUXSettings.asktosaveonclose = false;
170#endif
171
172#ifdef KERNEL
173 // put code in here to set the default level
174 gdbg_debuglevel[0] = 1; // always enable level 0
175 gdbg_debuglevel[120] = 1; // always enable level 0
176 done = 1;
177 env = 0;
178 return;
179#else /* #ifdef KERNEL */
180 done = 1;
181 gdbg_debuglevel[0] = 1; // always enable level 0
182 env = GETENV("GDBG_FILE");
183 if (env != NULL) GDBG_SET_FILE(env);
184 env = GETENV("GDBG_LEVEL");
185 if (env == NULL) env = "0";
186 gdbg_parse(env);
187 gdbg_info(1,"gdbg_init(): debug level = %s\n",env);
188#endif /* #ifndef KERNEL */
189}
190
191FX_EXPORT void FX_CSTYLE
192gdbg_shutdown(void)
193{
194 gdbg_info(1,"gdbg_shutdown()\n");
195#ifndef KERNEL
196 if (gdbg_msgfile != stdout) { // close any existing output file
197#if USE_DEBUG_STRING
198 if (!UseDebugString)
199#endif /* USE_DEBUG_STRING */
200 fclose(gdbg_msgfile);
201 gdbg_msgfile = stdout;
202 }
203#endif /* #ifndef KERNEL */
204}
205
206#if defined(KERNEL) && !defined(KERNEL_NT)
207 extern void MyPrintf();
208#endif /* #ifdef KERNEL */
209
210#ifdef KERNEL_NT
211//----------------------------------------------------------------------
212// NT Debug print helper routine
213//----------------------------------------------------------------------
214static void gdbg_NTPrint( const char *format, ... )
215{
216 va_list arglist;
217
218 va_start(arglist, format);
219 EngDebugPrint( "\nHAL: ", format, arglist );
220 va_end(arglist);
221}
222#endif // KERNEL_NT
223
224static GDBGKeepAliveProc keepAliveProc;
225
226FX_EXPORT void FX_CSTYLE gdbg_set_keepalive(GDBGKeepAliveProc p)
227{
228 keepAliveProc = p;
229}
230
231//----------------------------------------------------------------------
232// the MAIN message display suboutine - ALL messages come thru here
233//----------------------------------------------------------------------
234FX_EXPORT void FX_CSTYLE
235gdbg_vprintf (const char *format,va_list args)
236{
237 if (gdbg_msgfile != NULL) {
238#ifdef KERNEL
239 // shouldn't get here now
240 //commented out for now -KMW
241 //nwvsprintf(gdbgout,format,args);
242 //OutputDebugString("\n");
243 //OutputDebugString("HAL: ");
244 //OutputDebugString(gdbgout);
245#else
246#if USE_DEBUG_STRING
247 if (UseDebugString) {
248 static char msgBuf[1024];
249
250 vsprintf(msgBuf, format, args);
251
252#if __DOS32__
253 pciOutputDebugString(msgBuf);
254#else
255 OutputDebugString(msgBuf);
256#endif /* !__DOS32__ */
257 } else
258#endif /* USE_DEBUG_STRING */
259 {
260 vfprintf(gdbg_msgfile,format,args);
261 // if there is a keepAlive callback, then call it
262 fflush(gdbg_msgfile);
263 }
264
265 if (keepAliveProc) keepAliveProc(100);
266#endif /* !KERNEL */
267 }
268}
269
270FX_EXPORT void FX_CSTYLE
271gdbg_printf (const char *format, ...)
272{
273#ifndef KERNEL
274 va_list args;
275
276 va_start(args, format);
277 gdbg_vprintf(format,args);
278 va_end(args);
279#elif defined( KERNEL_NT )
280 va_list args;
281
282 va_start(args, format);
283 EngDebugPrint( "\nHAL: ", format, args );
284 va_end(args);
285#else
286 __asm lea eax, (format+4);
287 __asm mov ebx, format;
288 MyPrintf();
289#endif /* #ifndef KERNEL */
290
291}
292
293//----------------------------------------------------------------------
294// INFO message subroutines
295//----------------------------------------------------------------------
296
297//----------------------------------------------------------------------
298// display an INFO message if level <= debug level and return whether
299// debug level high enough to allow display
300//----------------------------------------------------------------------
301FX_EXPORT int FX_CSTYLE
302gdbg_info (const int level, const char *format, ...)
303{
304 va_list args;
305#ifndef KERNEL_NT
306 char newformat[4095];
307#endif
308
309 if (!gdbg_debuglevel[level>=GDBG_MAX_LEVELS ? GDBG_MAX_LEVELS-1 : level])
310 return(0);
311#ifndef KERNEL
312 va_start(args, format);
313 sprintf(newformat, "%s.%d:\t", gdbg_myname,level);
314 strcat(newformat,format);
315 gdbg_vprintf(newformat,args);
316 va_end(args);
317#elif defined( KERNEL_NT )
318 gdbg_NTPrint( "%s.%d:\t", gdbg_myname, level );
319 va_start(args, format);
320 EngDebugPrint( "", format, args );
321 va_end(args);
322#else /* #ifndef KERNEL */
323 Debug_Printf("%s.%d:\t", gdbg_myname, level);
324 __asm lea eax, (format+4);
325 __asm mov ebx, format;
326 MyPrintf();
327 FXUNUSED(args);
328 FXUNUSED(newformat[0]);
329#endif /* #ifndef KERNEL */
330
331 return (1);
332}
333
334
335//----------------------------------------------------------------------
336// same as gdbg_info but does not display INFO header
337//----------------------------------------------------------------------
338FX_EXPORT int FX_CSTYLE
339gdbg_info_more (const int level, const char *format, ...)
340{
341 va_list args;
342
343 if (!gdbg_debuglevel[level>=GDBG_MAX_LEVELS ? GDBG_MAX_LEVELS-1 : level])
344 return(0);
345#ifndef KERNEL
346 va_start(args, format);
347 gdbg_vprintf(format,args);
348 va_end(args);
349#elif defined( KERNEL_NT )
350 va_start(args, format);
351 EngDebugPrint( "\nHAL: ", format, args );
352 va_end(args);
353#else
354 __asm lea eax, (format+4);
355 __asm mov ebx, format;
356 MyPrintf();
357 FXUNUSED(args);
358#endif /* #ifndef KERNEL */
359 return (1);
360}
361
362
363static GDBGErrorProc errorProcList[3];
364
365FX_EXPORT int FX_CSTYLE gdbg_error_set_callback(GDBGErrorProc p)
366{
367 int i;
368 const int count = sizeof(errorProcList) / sizeof(errorProcList[0]);
369
370 for(i = 0; i < count; i++) {
371 if (errorProcList[i] == p) {
372 break;
373 } else if (errorProcList[i] == NULL) {
374 errorProcList[i] = p;
375 break;
376 }
377 }
378
379 return (i < count);
380}
381
382FX_EXPORT void FX_CSTYLE gdbg_error_clear_callback(GDBGErrorProc p)
383{
384 int i;
385 const int count = sizeof(errorProcList) / sizeof(errorProcList[0]);
386
387 for(i = 0; i < count; i++) {
388 if (errorProcList[i] == p) {
389 errorProcList[i] = NULL;
390 break;
391 }
392 }
393}
394
395//----------------------------------------------------------------------
396// ALL errors must come thru here, this subroutine adds a preamble
397// and then displays the message and increments the error counter
398//----------------------------------------------------------------------
399FX_EXPORT void FX_CSTYLE
400gdbg_error (const char *kind, const char *format, ...)
401{
402#ifndef KERNEL
403 va_list args;
404
405 char newformat[1024];
406
407 va_start(args, format);
408 sprintf(newformat, "%s error (%s): ", gdbg_myname,kind);
409 strcat(newformat,format); // add a preamble to message
410 gdbg_vprintf(newformat,args);
411 gdbg_errors++; // increment the error counter
412 va_end(args);
413
414 {
415 int i;
416 const int count = sizeof(errorProcList) / sizeof(errorProcList[0]);
417
418 for(i = 0; i < count; i++) {
419 if (errorProcList[i] != NULL) {
420 va_start(args, format);
421 (*errorProcList[i])(kind, newformat, args);
422 va_end(args);
423 }
424 }
425 }
426#elif defined( KERNEL_NT )
427 va_list args;
428
429 gdbg_NTPrint( "%s error (%s): ", gdbg_myname, kind);
430 va_start(args, format);
431 EngDebugPrint( "", format, args );
432 va_end(args);
433#else
434 Debug_Printf("%s error (%s): ", gdbg_myname, kind);
435 __asm lea eax, (format+4);
436 __asm mov ebx, format;
437 MyPrintf();
438#endif /* #ifndef KERNEL */
439}
440
441// return the error counter
442FX_EXPORT int FX_CSTYLE
443gdbg_get_errors(void)
444{
445 return gdbg_errors;
446}
447
448// return a debuglevel level
449FX_EXPORT int FX_CSTYLE
450gdbg_get_debuglevel(const int level)
451{
452 return gdbg_debuglevel[level>=GDBG_MAX_LEVELS ? GDBG_MAX_LEVELS-1 : level];
453}
454
455// set a debuglevel level
456FX_EXPORT void FX_CSTYLE
457gdbg_set_debuglevel(const int level, const int value)
458{
459 gdbg_debuglevel[level>=GDBG_MAX_LEVELS ? GDBG_MAX_LEVELS-1 : level] = value;
460}
461
462// open up a new output file
463FX_EXPORT int FX_CSTYLE
464gdbg_set_file(const char *name)
465{
466#ifndef KERNEL
467 FILE *outf;
468
469 if (gdbg_msgfile != stdout) { // close any existing output file
470 fclose(gdbg_msgfile);
471 gdbg_msgfile = stdout;
472 }
473
474#if USE_DEBUG_STRING
475 if (!strcmp(name, "DEBUG")) {
476 gdbg_msgfile = (FILE *) 1;
477 UseDebugString = 1;
478 } else
479#endif /* USE_DEBUG_STRING */
480 {
481 outf = fopen(name,"w"); // open up a new one
482 if (outf) gdbg_msgfile = outf;
483 }
484
485 return (outf != NULL);
486#else /* #ifndef KERNEL */
487 return 0;
488#endif /* #ifndef KERNEL */
489}
Note: See TracBrowser for help on using the repository browser.