home *** CD-ROM | disk | FTP | other *** search
- From: new@udel.EDU (Darren New)
- Newsgroups: alt.sources
- Subject: #define DEBUG (Real source in this posting! oohhh!)
- Message-ID: <18965@estelle.udel.EDU>
- Date: 9 May 90 18:19:54 GMT
-
- Since I don't have any way of making a shar file, I'm just going to
- put these all together. Split apart at the lines containing
- +=+=+=+=+ filename
-
- Note that these sources are CBM-Amiga specific to the extent that
- they do I/O to a separate window. However, changing this is not much
- of a problem. They also include their own version of "printf" which may
- need to be hacked for your system. I've found this to be incredibly
- useful but no substitute for a real symbolic debugger. Have fun. -- Darren
-
- +=+=+=+=+ DBugLib.doc
-
- These files Created 7/86 by Darren New.
- Released to the PUBLIC DOMAIN. No rights reserved.
- Do anything you want with it.
-
- Simple request: if you make a significant profit from this, or if you have
- improvements or suggestions, please contact me at
-
- new@udel.edu
-
- (the request about profit just for my curiosity)
-
- DISCLAIMER: As I am not making money from this, I am not going to be
- oblicated to support it, either. Thus, THIS IS SUPPLIED "AS IS". No
- warranty of any kind is made or implied. Lattice is a registered trademark
- of Lattice, Inc. Thus endeth the A__-covering.
-
-
- --------------------------------------------------------------------------
-
-
- This set of functions is for debugging programs.
- The function DEBUG_OPEN() opens a new console at the bottom of the screen.
- This console is read and written by DEBUGF(). DEBUG_CLOSE() will close
- this console, freeing it's memory. Eventually, I hope to write these
- things as resources or devices, or something where everyone doing debug
- output will write to the same console so that multi-tasking functions
- can be debuged more easily. (Probably shortly after I start coding
- multi-process programs myself...)
-
- The main advantages of these functions over most of the debugging macros
- already out there are these:
- They write to a separate window, so even things with no windows or that do
- ANSI stuff and so on can be debugged. Another advantage is that they are
- interactive -- pure macros must be recompiled and relinked to be disposed;
- these functions can be turned on and off at run time. Of course, a simple
- compiler switch can remove all trace of these from the object files, just
- like most of the debugging packages. The debugging info can be sent to a
- file or to the printer for really sticky problems. Also, user's functions
- can be called from the keyboard from within the debug functions. Although
- this does take a little setup, it can be worthwhile for stepping through a
- program until you start getting strange errors, and then popping back to
- your program someplace else in order to examine variables, dump files, or
- whatever; I imagine it could also be used to clean up and exit from the
- debugger. Finally, it uses AmigaDOS calls only; no Lattice library calls or
- STDIO calls or anything like that. If you have a "tiny" program, this may
- be helpful.
-
- All traces of these function will be removed from the program if the
- preprocessor symbol USE_DBUGLIB is zero. They will be compiled in if the
- preprocessor symbol USE_DBUGLIB is one. Note that this takes effect only
- when the header <DBugLib.h> is included; i.e., you can't turn them on and
- off in the same file. If USE_DBUGLIB is undefined when the header file is
- included, it's value will be one if DEBUG is defined, and zero if DEBUG
- is not defined. Note also that under Lattice, the -d switch (pass 1) will
- #define DEBUG for you.
-
- Note that in order for the macros to remove the function calls with variable
- arguments (under Lattice, at least), any arguments after the formatting
- string must be separated from the preceeding argument not by a comma, but by
- the pre-processor symbol "COMMA". This turns all of the variable args into
- one argument if "COMMA" is not defined. Credit for this technique is hereby
- given to "Dr. Bob", the author of "DEBUGC", found elsewhere.
-
-
- DEBUG_OPEN(S) ---> void
- Opens the console. All other debug functions will be ignored
- while the console is closed. If S is NULL, the default console string
- is used as the file name for the Open call. If S is not NULL, that string
- will be used as the filename. If the console can not be opened,
- DisplayBeep() in a pattern indicative of the error. Calling this is not an
- error the debugging console is already open. This automatically gets
- called whenever DEBUG_ENTER() gets called and the nesting stack is empty;
- usually, this means main() is calling it for the first time.
-
- DEBUG_CLOSE() ---> void
- Closes the console. It is not an error to call this when the console
- is already closed. The console is automatically closed when DEBUG_RETURN is
- called from the (seemingly) outermost proceedure.
-
- DEBUGF(I, SF COMMA A1 COMMA A2 COMMA ...) ---> char *
- Other arguments just like PRINTF. The output is formatted and sent
- to the debug console. One key is accepted from the keyboard, and interpreted
- as follows:
- P the debug line is sent to the PRT: device, which is opened until
- the next DEBUG_CLOSE() if not already open.
- Q DEBUG_CLOSE() will be called, causing deugging output to be disabled
- until DEBUG_OPEN is called again.
- F debugging output will be appended to :T/DEBUGOUT, which will be
- opened if not already opened. If 'f' is typed, the file will
- remain open until DEBUG_CLOSE() is called. If 'F' is typed, the
- file will be closed immediately.
- B the debugging window will be closed and reopened full size. (big)
- If 'b' is entered, the window will be 200 scan lines high.
- If 'B' is entered, the window will be 400 scan lines high.
- T DEBUG_TRACEBACK() will be called.
- C the previous action (other than T) will be repeated without pause
- until DEBUG_OPEN or DEBUG_CLOSE is called again. Good for
- CONTINUOUS output to a file or printer. Type a space to the debug
- window to regain control.
- N Nest: prompts for a digit 0 through 9. Any DEBUG_ENTER
- which causes the nesting level to exceed this will still be
- remembered, but will not generate any output on the debug console.
- Zero turns off all the reports except "main". A space typed in
- response to the prompt allows all nestings to display.
- D Detail: prompts for a digit 0 through 9. Any DEBUGF specifying an I
- larger than this number will not generate any output. A space typed
- in response to the prompt allows all details to display. Note that
- detail level of zero will always display.
- S Skip: debugging output will be discarded until a DEBUG_RETURN is
- called which restores the nesting level to the current level or
- lower. Essentially, debugging is turned off until the current
- function calls DEBUG_RETURN().
- 0 thru 9
- DEBUG_FUNC[0] thru DEBUG_FUNC[9] will be called if not NULL. Note
- that this could be ugly if the user does not fill in this global
- array with pointers to functions.
- RETURN just return
- SPACE Same as return
-
- The routine will keep scanning the keyboard until a C or a newline (return)
- or S is detected, at which point it return. Thus, several actions can be
- taken on a single debug statement.
-
- DEBUG_CONSOLE() ---> long
- Returns 0 if the debugging console is not open, otherwise returns
- a pointer to the open console, suitable for Read() and Write(). Don't
- Close() this yourself, or future calls to DEBUG may crash.
-
- DEBUG_ENTER(S, SF COMMA A1 COMMA A2 COMMA ...) ---> void
- Pass in the name of the function being entered. This will be
- remembered, even if the console is closed. If SF is not NULL, then the args
- after it (if any) are formatted as in PRINTF and displayed. If this is
- first called when the console is closed, it is assumed to be being called
- from main(), and calls DEBUG_OPEN(NULL) for you.
-
- DEBUG_RETURN(SF COMMA A1 COMMA A2 COMMA ...) ---> void
- Indicates that the most recent function to call DEBUG_ENTER is
- now returning. Automatically closes the colsole and otherwise makes sure
- that all resources have been freed if the nesting stack goes empty;
- it is assumed that you are about to exit from main(). This will
- eventually be implemented as a macro that actually returns the value of A1,
- if I can figure out how to cast the type properly; the problem is one of
- side-effects, mainly.
-
- DEBUG_EXIT() ---> void
- Frees all resources used by any of the DEBUG functions. Must be
- called before a call to Exit(), exit(), _exit(), or whatever; otherwise, you
- will be left with a console sitting around that you can't close.
-
- There will probably be much more over time, maybe including a program to
- automatically insert debugging calls into the program for you.
-
- In the future, I plan to add floating point support. If I hear requests, I
- may do it before I need it myself. If anyone is interrested in adding it
- themselves, I have the fuctions to format the numbers; they just have not
- been incorporated into the DO_PRNT function.
-
- +=+=+=+=+ DBugLib.h
- /*
- This is the header file for the DBugLib package.
- Include it while debugging.
- */
-
- #ifndef USE_DBUGLIB
- #ifdef DEBUG
- #define USE_DBUGLIB 1
- #else
- #define USE_DBUGLIB 0
- #endif
- #endif
-
- #if USE_DBUGLIB==1
- #define COMMA , /* thanks, Dr. Bob! */
- #define C ,
- extern void (*DEBUG_FUNC[10])(); /* List of debugging functions */
- extern void DEBUG_OPEN(char *);
- extern void DEBUG_CLOSE(void);
- extern void DEBUGF(int, char *, );
- extern void DEBUG_ENTER(char *, char *, );
- extern long DEBUG_CONSOLE(void);
- extern void DEBUG_RETURN(char *, );
- extern void DEBUG_EXIT(void);
- extern void DEBUG_TRACEBACK(void);
- extern void DEBUG_SETDEFS(char *, char *);
- #else
- #define DEBUG_OPEN(name) /* nothing */
- #define DEBUG_CLOSE() /* nothing */
- #define DEBUGF(lev, args) /* nothing */
- #define DEBUG_ENTER(name, args) /* nothing */
- #define DEBUG_CONSOLE() /* nothing -- shouldn't be referenced */
- #define DEBUG_RETURN(args) /* nothing */
- #define DEBUG_EXIT() /* nothing */
- #define DEBUG_TRACEBACK() /* nothing */
- #define DEBUG_SETDEFS(con, file) /* nothing */
- #endif
-
- +=+=+=+=+ DBugLib.c
- /*
-
- THIS IS "DBUGLIB.C"
-
- Written 7/86 Darren New.
- PUBLIC DOMAIN -- May be freely distributed.
- See DBugLib.Doc for instructions and details.
- To avoid loading STDIO under lattice, compile with -v
-
- */
-
- #include "exec/types.h"
- #include "exec/memory.h"
- #include "libraries/dos.h"
-
- #include "proto/exec.h"
- #include "proto/dos.h"
-
- #include "string.h"
-
- void (*DEBUG_FUNC[10])(); /* List of debugging functions */
-
- /* default default console */
- char * def_deb_console = "RAW:0/130/640/70/Debug Console ";
-
- /* default default debug output file */
- char * def_deb_file = ":t/DebugOut";
-
- static long console; /* Actually, this should be a file handle */
- #define MUL 65000 /* Multiplyer for delays between flashes */
-
- static char last_answer; /* last char typed -- used by 'C' */
- static char last_was_c; /* true if 'C'ing, false otherwise */
- static char last_was_skip; /* true if 'S'kiping, false otherwise */
- static char * nest_list; /* by TRACEBACK */
- static int nest_level; /* by TRACEBACK */
- static int skip_level; /* for SKIP */
- static long skip_con_hold; /* for SKIP */
- static int max_nest_level = 9999; /* by ENTER, RETURN */
- static int max_detail = 9999; /* by DEBUGF */
- static long db_file_handle; /* handle to debug file */
- static long db_prt_handle; /* handle to printer */
- static char * laststr; /* pointer to last string typed */
- static long laststralloc; /* space allocated for laststr */
- static char nosave; /* CONWRITE will not append to laststr */
- static char cleol; /* just to pass stuff around */
-
- static void addon(s)
- register char * s;
- {
- register char * newstr;
- /* add S to the end of laststr */
- if (nosave) return;
- again:
- if (strlen(laststr) + strlen(s) + 1 >= laststralloc) {
- newstr = (char *) AllocMem(laststralloc + strlen(s) + 125,
- MEMF_CLEAR);
- if (newstr == 0) {
- if (laststralloc == 0) {
- /* out of memory */
- return;
- }
- FreeMem(laststr, laststralloc);
- laststralloc = 0; laststr = "";
- goto again;
- }
- strcpy(newstr, laststr);
- FreeMem(laststr, laststralloc);
- laststralloc += strlen(s) + 125;
- laststr = newstr;
- }
- strcat(laststr, s);
- }
-
-
- static void conwrite(s)
- char * s;
- {
- if (console != 0) {
- Write(console, s, strlen(s));
- addon(s);
- }
- }
-
-
- static void conwriteint(i)
- register int i;
- {
- char s[10];
- if (i > 32760) i = 32760;
- s[0] = '0' + i / 10000 ;
- s[1] = '0' + i / 1000 % 10;
- s[2] = '0' + i / 100 % 10;
- s[3] = '0' + i / 10 % 10;
- s[4] = '0' + i % 10;
- s[5] = '\0';
- conwrite(s);
- }
-
-
- static void conwritechar(c)
- char c;
- {
- char buf[2];
- buf[0] = c; buf[1] = '\0';
- conwrite(buf);
- }
-
-
- static void sendto(a)
- long a;
- {
- register int i;
- if (console == 0) return;
- if (strlen(laststr) != Write(a, laststr, strlen(laststr))) {
- nosave = 1;
- last_was_c = 0;
- i = IoErr();
- conwrite("\033[1mError during output: ");
- conwriteint(i);
- conwrite("\nTry again...\033[0m\n");
- nosave = 0;
- }
- }
-
-
- static void isyt()
- {
- if (!last_was_c) {
- nosave = 1;
- cleol = 1;
- conwrite("\033[1m It's still your turn...\033[0m\r");
- nosave = 0;
- }
- }
-
-
-
- static void getresp()
- {
- char buf;
- register int i;
- register int oncet;
- extern void DEBUG_TRACEBACK();
- if (console == 0) return;
- oncet = 0;
- again:
- /* This gives him 1/10 seconds for each debug in continuous mode */
- if (! last_was_c || WaitForChar(console, 100000)) {
- last_was_c = 0;
- Read(console, &buf, 1);
- }
- else if (oncet) {
- buf = ' ';
- }
- else {
- oncet = 1;
- buf = last_answer;
- }
- if (cleol) {
- nosave = 1; conwrite("\033[0m\033[K"); nosave = 0;
- cleol = 0;
- }
- /* Process buffer here */
- switch (buf) {
- case 'N':
- case 'n':
- nosave = 1;
- conwrite("\033[1mEnter maximum nest level or ' ' for all:\033[0m ");
- Read(console, &buf, 1);
- if (buf <= '9' && buf >= '0') {
- conwritechar(buf);
- max_nest_level = buf - '0';
- }
- else if (buf == ' ')
- max_nest_level = 99999;
- else
- conwritechar('\007', NULL);
- isyt();
- goto again;
- case 'D':
- case 'd':
- nosave = 1;
- conwrite("\033[1mEnter maximum detail level or ' ' for all:\033[0m ");
- Read(console, &buf, 1);
- if (buf <= '9' && buf >= '0') {
- conwritechar(buf, NULL);
- max_detail = buf - '0';
- }
- else if (buf == ' ')
- max_detail = 9999;
- else
- conwritechar('\007', NULL);
- isyt();
- goto again;
- case 'S':
- case 's':
- skip_con_hold = console;
- last_was_skip = 1;
- skip_level = nest_level;
- console = 0; /* temp suspend debugging till return reached */
- goto outness; /* Do NOT try to attempt any more output */
- case 'P':
- case 'p':
- last_answer = buf;
- if (db_prt_handle == 0)
- db_prt_handle = Open("PRT:", MODE_OLDFILE);
- if (db_prt_handle == 0) {
- i = IoErr();
- nosave = 1;
- last_was_c = 0;
- conwrite("\033[1mError opening printer: ");
- conwriteint(i);
- conwrite("\n\033[0m\007");
- nosave = 0;
- isyt();
- goto again;
- }
- sendto(db_prt_handle);
- isyt();
- goto again;
- case 'F':
- case 'f':
- last_answer = buf;
- if (db_file_handle == 0)
- db_file_handle = Open(def_deb_file, MODE_OLDFILE);
- if (db_file_handle != 0)
- Seek(db_file_handle, 0, OFFSET_END);
- if (db_file_handle == 0) {
- i = IoErr();
- if (i == ERROR_OBJECT_NOT_FOUND)
- db_file_handle = Open(def_deb_file, MODE_NEWFILE);
- }
- if (db_file_handle == 0) {
- last_was_c = 0;
- i = IoErr();
- nosave = 1;
- conwrite("\033[1mError opening file: ");
- conwriteint(i);
- conwrite("\n\033[0m\007");
- nosave = 0;
- isyt();
- goto again;
- }
- sendto(db_file_handle);
- if (buf == 'F') {
- if (db_file_handle != 0)
- Close(db_file_handle);
- db_file_handle = 0;
- }
- isyt();
- goto again;
- case 'C':
- case 'c':
- last_was_c = 1;
- break;
- case 'Q':
- case 'q':
- Close(console);
- console = 0; last_answer = 0; last_was_c = 0;
- break;
- case 'B':
- case 'b':
- Close(console);
- if (buf == 'B')
- console = Open("RAW:0/0/640/400/Debug Console ", MODE_NEWFILE);
- else
- console = Open("RAW:0/0/640/200/Debug Console ", MODE_NEWFILE);
- if (console == 0) { /* could not open */
- long ioerr, tl1, tl2;
- ioerr = IoErr();
- /* Flash hundreds */
- for (tl1 = 0; tl1 < ioerr / 100; tl1++) {
- Write(Output(), "\007", 1);
- for (tl2 = 0; tl2 < MUL; tl2++) ;
- }
- for (tl2 = 0; tl2 < 2 * MUL; tl2++) ;
- /* Flash tens */
- for (tl1 = 0; tl1 < ioerr / 10 % 10; tl1++) {
- Write(Output(), "\007", 1);
- for (tl2 = 0; tl2 < MUL; tl2++) ;
- }
- for (tl2 = 0; tl2 < 2 * MUL; tl2++) ;
- /* Flash ones */
- for (tl1 = 0; tl1 < ioerr % 10; tl1++) {
- Write(Output(), "\007", 1);
- for (tl2 = 0; tl2 < MUL; tl2++) ;
- }
- }
- sendto(console);
- isyt();
- goto again;
- case 'T':
- case 't':
- DEBUG_TRACEBACK((long) 0xBADD1E);
- isyt();
- goto again;
- case '0': case '5':
- case '1': case '6':
- case '2': case '7':
- case '3': case '8':
- case '4': case '9':
- if (DEBUG_FUNC[(int) buf - '0'])
- (*DEBUG_FUNC[(int) buf - '0'])();
- isyt();
- break;
- case '\0': /* continuous */
- case '\r':
- case '\n':
- case ' ':
- if (!last_was_c) last_answer = buf;
- break;
- default:
- nosave = 1;
- conwrite("\033[1mI don't understand ");
- conwriteint(buf);
- conwrite("\033[0m\n\007");
- nosave = 0;
- isyt();
- goto again;
- }
- outness:
- /* if (laststralloc > 0) {
- FreeMem(laststr, laststralloc);
- laststr = "";
- laststralloc = 0;
- } */
- if (laststralloc > 0) {
- laststr[0] = '\0';
- }
- }
-
-
- /******* CODE FROM AUSTIN CODE WORKS, MODIFIED BY DHN *******/
-
- #define EOS ('\0')
- #define BITS_PER_CHAR 8
-
- /*
- * WORKSIZE is the dimension of work[] which must hold enough characters
- * to store a long integer (expanded using the %b format) + '-' and EOS
- */
- #define WORKSIZE (((sizeof (long)) * BITS_PER_CHAR) + 2)
-
- struct fmtbuf {
- char f_type; /* Format type ('d', etc.) */
- char f_width; /* Argument width (INT or LONG) */
- char f_radix; /* Argument radix (8, 10, etc.) */
- };
-
- #define INT 0
- #define LONG 1
- #define NEG 2 /* Signal for output of '-' */
-
- /*
- * formatinfo[] stores information about the "value" formats
- */
- static struct fmtbuf formatinfo[] = {
- { 'b', INT, 2 },
- { 'd', INT, 10 },
- { 'o', INT, 8 },
- { 'u', INT, 10 },
- { 'x', INT, 16 },
- { 'p', LONG, 16 },
- { 'B', LONG, 2 },
- { 'D', LONG, 10 },
- { 'O', LONG, 8 },
- { 'U', LONG, 10 },
- { 'X', LONG, 16 },
- { 'P', LONG, 16 },
- { EOS, 0, 0 },
- };
-
-
- void c_doprnt(format, argp, func)
- char *format; /* Format string */
- register int *argp; /* Argument vector pointer */
- int (*func)(); /* Output Function */
- {
- register int c;
- register struct fmtbuf * pfmt;
- register char * presult;
- char ljust; /* TRUE for left-justification */
- char work[WORKSIZE]; /* Number buffer */
- char fill; /* '0' or ' ' for fill */
- int prec; /* Precision */
- int slen; /* Field length */
- int width; /* Argument width */
- unsigned long value;
- int temp; /* Set if '-' needed. */
- short radix; /* Conversion radix */
-
- while ((c = *format++) != EOS) {
- /*
- * Check for conversion specifications.
- */
- if (c == '%') {
- /*
- * Check for various options.
- */
- c = *format++;
- ljust = 0; /* No left adjustment */
- fill = ' '; /* Fill with spaces */
- if (c == '-') { /* %- left justify */
- ljust++;
- c = *format++;
- }
- if (c == '0') { /* %0d zero fill arg. */
- fill = c;
- c = *format++;
- }
- if (c == '?' || c == '*') { /* %* width from arg */
- width = *argp++;
- c = *format++;
- }
- else { /* %n field width */
- width = 0;
- while (isdigit(c)) {
- width *= 10;
- width += (c - '0');
- c = *format++;
- }
- }
- if (c == '.') { /* %n.n precision */
- c = *format++; /* %n.* (from arg) */
- if (c == '?' || c == '*') {
- prec = *argp++;
- c = *format++;
- }
- else {
- prec = 0;
- while (isdigit(c)) {
- prec *= 10;
- prec += (c - '0');
- c = *format++;
- }
- }
- }
- else {
- prec = 32767; /* No prec. specified */
- }
- /*
- * Magic code for pointer -- dhn
- */
- if (c == 'p' || c == 'P') {
- fill = '0'; width = 6 + 2 * isupper(c);
- }
- /*
- * Process conversion chars, understanding longs.
- */
- if (c == 'l' || c == 'L') {
- switch (c = *format++) {
- case 'b':
- case 'd':
- case 'o':
- case 'u':
- case 'x':
- c = toupper(c); /* Make %lb %B */
- case 'B':
- case 'D':
- case 'O':
- case 'U':
- case 'X':
- break;
- default: /* Here on %Lfoo ==> %Ufoo */
- c = 'U';
- format--;
- break;
- }
- }
- /*
- * Search the numeric format structure for this conversion.
- */
- for (pfmt = formatinfo;
- (pfmt->f_type != c && pfmt->f_type != EOS);
- pfmt++)
- ;
- if (pfmt->f_type != EOS) {
- /*
- * A numeric conversion was found.
- * Get the value and expand it into the work area.
- */
- radix = pfmt->f_radix;
- temp = pfmt->f_width;
- presult = &work[WORKSIZE];
- *--presult = EOS; /* Terminate result */
- if (temp == INT) {
- if (c == 'd' && *argp < 0) {
- value = -*argp++;
- temp = NEG; /* Remember signal */
- }
- else
- value = (unsigned) *argp++;
- }
- else {
- value = * (long *) argp;
- argp += (sizeof(long) / sizeof(*argp));
- }
- if (value == 0)
- *--presult = '0';
- else {
- /*
- * Convert an unsigned non-zero number.
- */
- do {
- c = value % radix;
- *--presult = c + ((c < 10) ? '0' : ('A' - 10));
- } while ((value /= radix) != 0);
- if (temp == NEG)
- *--presult = '-';
- }
- }
- else {
- /*
- * String or something
- */
- switch (c) {
- case 'q': /* Funny int value */
- /*
- * Convert a word as a pair of octal bytes.
- */
- c = 16384;
- presult = work;
- temp = *argp++;
- while (c > 0) {
- *presult++ = (temp / c) + '0';
- temp %= c;
- if (c == 256) {
- c = 64;
- *presult++ = '.';
- }
- else
- c >>= 3;
- }
- *presult = EOS;
- presult = work;
- break;
-
- case 'r': /* Remote format */
- argp = (int *) *argp;
- format = (char *) *argp++;
- continue; /* No print here */
-
- case 's': /* String */
- if ((presult = (char *) *argp++) == NULL)
- presult = "{NULL}"; /* Bug hack */
- break;
-
- case 'c': /* Character */
- c = *argp++;
- /*
- * Fall through
- */
- default: /* %% or whatever */
- presult = work;
- *presult = c;
- work[1] = EOS;
- break;
- }
- }
- /*
- * presult -> first byte of string to output.
- * Reuse c as a register temp.
- */
- c = strlen(presult); /* True result length */
- slen = (c > prec) ? prec : c; /* Field length */
- if (!ljust) { /* Right justify? */
- while (--width >= slen) {
- (*func)(fill);
- }
- }
- /*
- * Output the string (up to "prec" bytes)
- */
- for (c = prec; *presult != EOS && --c >= 0;) {
- (*func)(*presult++);
- }
- if (ljust) { /* Left justify? */
- while (--width >= slen) {
- (*func)(' ');
- }
- }
- }
- else {
- /*
- * Not in a % thing, just output the byte.
- */
- (*func)(c);
- }
- }
- return;
- }
-
- /******** END CODE FROM AUSTIN CODE WORKS *********/
-
-
- void DEBUG_OPEN(s)
- register char * s;
- {
- register long tl1; /* temp loop var 1 */
- register long tl2; /* temp loop var 2 */
- register int ioerr;
-
- /* Open debugging console, if not already open. Init stuff */
- if (skip_con_hold) {
- /* open stops skipping */
- console = skip_con_hold;
- skip_con_hold = 0; last_was_skip = 0;
- skip_level = 0;
- }
- if (s == NULL) {
- s = def_deb_console;
- }
- last_answer = '\0'; last_was_c = 0;
- if (laststralloc > 0) {
- FreeMem(laststr, laststralloc);
- laststr = "";
- laststralloc = 0;
- }
- laststr = "";
- nosave = 0;
- if (console != 0) return;
-
- console = Open(s, MODE_NEWFILE);
- if (console == 0) { /* could not open */
- ioerr = IoErr();
- /* Flash hundreds */
- for (tl1 = 0; tl1 < ioerr / 100; tl1++) {
- Write(Output(), "\007", 1);
- for (tl2 = 0; tl2 < MUL; tl2++) ;
- }
- for (tl2 = 0; tl2 < 2 * MUL; tl2++) ;
- /* Flash tens */
- for (tl1 = 0; tl1 < ioerr / 10 % 10; tl1++) {
- Write(Output(), "\007", 1);
- for (tl2 = 0; tl2 < MUL; tl2++) ;
- }
- for (tl2 = 0; tl2 < 2 * MUL; tl2++) ;
- /* Flash ones */
- for (tl1 = 0; tl1 < ioerr % 10; tl1++) {
- Write(Output(), "\007", 1);
- for (tl2 = 0; tl2 < MUL; tl2++) ;
- }
- }
- else {
- conwrite("\033[1mConsole is open.\033[0m\n");
- }
- }
-
-
- void DEBUG_TRACEBACK(i)
- long i;
- {
- char * holdit;
- if (nest_level < 1) {
- conwrite("DEBUG_TRACEBACK(): Too many returns!\n");
- if (i != 0xBADD1E) getresp();
- return;
- }
- if (nest_level <= max_nest_level || i == 0xBADD1E) {
- /* Display nesting only if enters and returns showing, or if
- called directly from keyboard */
- conwrite("Stack traceback: current nest level is ");
- conwriteint(nest_level);
- holdit = nest_list;
- while(holdit != NULL) {
- conwrite("\n ");
- conwrite(holdit + sizeof(char *));
- holdit = * (char * *) holdit;
- }
- conwrite("\nEnd of stack traceback.\n");
- if (i != 0xBADD1E) getresp();
- }
- }
-
-
- void DEBUGF(sevlev, fmtstr, args)
- int sevlev;
- char * fmtstr;
- int args;
- {
- if (console == 0 || sevlev > max_detail) return;
- if (fmtstr == NULL) return;
- nosave = 1; conwrite("\033[0 p"); nosave = 0; /* turn off cursor */
- c_doprnt(fmtstr, &args, conwritechar);
- if (fmtstr[strlen(fmtstr)-1] != '\n')
- conwrite("\n");
- nosave = 1; conwrite("\033[ p"); nosave = 0; /* turn on cursor */
- getresp();
- }
-
-
-
- void DEBUG_ENTER(s, sf, args)
- register char * s;
- char * sf;
- int args;
- {
- register char * newmem;
- register int i;
- if (s == NULL) return;
- if (nest_level == 0) DEBUG_OPEN(NULL);
- if (nest_level <= max_nest_level) {
- conwriteint(nest_level);
- for (i = 0; i < nest_level; i++)
- conwrite("=");
- conwrite(">");
- conwrite(s);
- conwrite("\n");
- if (sf != NULL) {
- conwrite(" |--> ");
- c_doprnt(sf, &args, conwritechar);
- conwrite("\n");
- }
- }
- newmem = (char *) AllocMem(sizeof(char *) + strlen(s) + 2, 0);
- if (newmem == NULL) return;
- (* (char * *) newmem) = nest_list;
- strcpy(newmem + sizeof(char *), s);
- nest_list = newmem;
- nest_level += 1;
- if (nest_level - 1 <= max_nest_level) getresp();
- }
-
-
- void DEBUG_CLOSE()
- {
- last_answer = '\0'; last_was_c = 0;
- if (db_file_handle != 0) {
- Close(db_file_handle);
- conwrite("DB File is closed.\n");
- db_file_handle = 0;
- }
- if (db_prt_handle != 0) {
- Close(db_prt_handle);
- conwrite("Printer is closed.\n");
- db_prt_handle = 0;
- }
- if (skip_con_hold) {
- console = skip_con_hold;
- skip_con_hold = last_was_skip = skip_level = 0;
- }
- if (console != 0) {
- conwrite("Console is closed.\n");
- Close(console);
- console = 0;
- }
- if (laststralloc > 0) {
- FreeMem(laststr, laststralloc);
- laststr = "";
- laststralloc = 0;
- }
- }
-
-
- void DEBUG_RETURN(sf, args)
- char * sf;
- int args;
- {
- int i;
- char * holdit;
- if (nest_level < 1) {
- conwrite("DEBUG_RETURN(): Too many returns!\n");
- getresp();
- return;
- }
- nest_level -= 1;
- if (last_was_skip && nest_level < skip_level) {
- console = skip_con_hold;
- skip_con_hold = 0; last_was_skip = 0; skip_level = 0;
- }
- if (nest_level <= max_nest_level) {
- conwriteint(nest_level);
- for (i = 0; i < nest_level; i++)
- conwrite("=");
- conwrite("<");
- conwrite(nest_list + sizeof(char *));
- conwrite("\n");
- }
- if (sf != NULL && nest_level <= max_nest_level) {
- conwrite(" <---| ");
- c_doprnt(sf, &args, conwritechar);
- conwrite("\n");
- }
- if (nest_list != NULL) {
- holdit = nest_list;
- nest_list = * (char * *) nest_list;
- FreeMem(holdit, sizeof(char *) + strlen(holdit +
- sizeof(char *)) + 2);
- }
- if (nest_level <= max_nest_level) getresp();
- if (nest_level == 0) DEBUG_CLOSE();
- }
-
-
- void DEBUG_EXIT()
- {
- if (skip_con_hold) console = skip_con_hold;
- conwrite("About to DEBUG_EXIT()\n");
- getresp();
- while (nest_list != NULL) {
- char * holdit;
- holdit = nest_list;
- nest_list = * (char * *) nest_list;
- FreeMem(holdit, sizeof(char *) + strlen(holdit + sizeof(char *)) + 2);
- }
- DEBUG_CLOSE();
- }
-
- long DEBUG_CONSOLE()
- {
- return console;
- }
-
- void DEBUG_SETDEFS(con, file)
- char * con;
- char * file;
- {
- if (con != NULL)
- def_deb_console = con;
- if (file != NULL)
- def_deb_file = file;
- }
-
- +=+=+=+=+ DBTest.c
- /* This is the test program for the DBugLib package.
- It exercises all features, assuming you actually attempt to
- print, file, and so on. (put the include files where you want them)
-
- Note that for ANYTHING to happen, #define DEBUG. This can be done in
- Lattice by giving "-d" (alone) on the first pass. This also generates
- line numbers in the quad file.
-
- */
-
- #include <stdio.h>
- #include "DBugLib.h"
-
- void main(argc, argv)
- int argc; char * argv[];
- {
- extern void exit(int);
- DEBUG_ENTER("Alpha", "Decimal, then Hex: %d, %x" COMMA 123 COMMA 0x456);
- DEBUG_ENTER("Beta", NULL);
- DEBUGF(2, "If you type an 'F', this will go to a file");
- DEBUGF(4, "Making sure long negatives work: %d %X" C -1L C -1L);
- DEBUG_TRACEBACK();
- DEBUG_RETURN(NULL);
- DEBUGF(5, "Here, close the console. then, wait a while...");
- DEBUGF(5, "This should not display on a closed console");
- DEBUGF(5, "Neither should this");
- DEBUG_OPEN(NULL);
- DEBUGF(0, "This should always display");
- DEBUGF(0, "About to play with Detail levels:");
- DEBUGF(1, "ONE");
- DEBUGF(2, "TWO");
- DEBUGF(3, "THREE");
- DEBUGF(4, "FOUR");
- DEBUGF(5, "FIVE");
- DEBUGF(6, "SIX");
- DEBUGF(7, "SEVEN");
- DEBUGF(8, "EIGHT");
- DEBUGF(9, "NINE");
- DEBUGF(10, "TEN");
- DEBUGF(11, "ELEVEN");
- DEBUGF(10, "Ten");
- DEBUGF(9, "Nine");
- DEBUGF(8, "Eight");
- DEBUGF(7, "Seven");
- DEBUGF(6, "Six");
- DEBUGF(5, "Five");
- DEBUGF(4, "Four");
- DEBUGF(3, "Three");
- DEBUGF(2, "Two");
- DEBUGF(1, "One");
- DEBUGF(0, "Zero");
- DEBUG_TRACEBACK();
- DEBUGF(0, "About to play with function calls:");
- /* Level zero is Alpha */
- DEBUG_ENTER("One", NULL);
- DEBUG_ENTER("Two", NULL);
- DEBUG_ENTER("Three", NULL);
- DEBUG_ENTER("Four", NULL);
- DEBUG_ENTER("Five", NULL);
- DEBUG_ENTER("Six", NULL);
- DEBUG_ENTER("Seven", NULL);
- DEBUG_ENTER("Eight", NULL);
- DEBUG_ENTER("Nine", NULL);
- DEBUG_ENTER("Ten", NULL);
- DEBUG_ENTER("Eleven", NULL);
- DEBUGF(0, "This is a debug statement inside %d" COMMA 11);
- DEBUG_TRACEBACK();
- DEBUG_RETURN("Eleven");
- DEBUG_RETURN("Ten");
- DEBUG_RETURN("Nine");
- DEBUG_RETURN("Eight");
- DEBUG_TRACEBACK();
- DEBUG_ENTER("Eight", NULL);
- DEBUG_ENTER("Nine", NULL);
- DEBUG_ENTER("Ten", NULL);
- DEBUG_ENTER("Eleven", NULL);
- DEBUG_TRACEBACK();
- DEBUG_RETURN("Eleven");
- DEBUG_RETURN("Ten");
- DEBUG_RETURN("Nine");
- DEBUG_RETURN("Eight");
- DEBUG_TRACEBACK();
- DEBUG_RETURN("Seven");
- DEBUG_RETURN("Six");
- DEBUG_RETURN("Five");
- DEBUG_RETURN("Four");
- DEBUG_TRACEBACK();
- DEBUG_RETURN(NULL);
- DEBUG_RETURN(NULL);
- DEBUG_RETURN(NULL);
- DEBUG_RETURN("Returning a string from alpha: |%s|" COMMA "A string!");
- exit(0);
- }
-
-
- +=+=+=+=+ End of file
-