1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
|
/* xldebug - xlisp debugging support */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
/* CHANGE LOG
* --------------------------------------------------------------------
* 28Apr03 dm eliminate some compiler warnings
*/
#include "stdlib.h"
#include "xlisp.h"
/* forward declarations */
FORWARD LVAL stacktop(void);
FORWARD LOCAL void breakloop(const char *hdr, const char *cmsg,
const char *emsg, LVAL arg, int cflag);
/* xlabort - xlisp serious error handler */
void xlabort(const char *emsg)
{
xlsignal(emsg,s_unbound);
xlerrprint("error",(const char *) NULL,emsg,s_unbound);
xlbrklevel();
}
/* xlbreak - enter a break loop */
void xlbreak(const char *emsg, LVAL arg)
{
breakloop("break","return from BREAK",emsg,arg,TRUE);
}
/* xlfail - xlisp error handler */
void xlfail(const char *emsg)
{
xlerror(emsg,s_unbound);
}
/* close_loadingfiles - close files we were loading from */
void close_loadingfiles()
{
/* close open files that are being loaded so that user can
overwrite bug fixes immediately. (Windows locks files
until they are closed.)
*/
while (consp(getvalue(s_loadingfiles)) &&
consp(cdr(getvalue(s_loadingfiles))) &&
streamp(car(cdr(getvalue(s_loadingfiles)))) &&
getfile(car(cdr(getvalue(s_loadingfiles))))) {
osclose(getfile(car(cdr(getvalue(s_loadingfiles)))));
/* make the file NULL so GC will not close it again */
setfile(car(cdr(getvalue(s_loadingfiles))), NULL);
setvalue(s_loadingfiles, cdr(cdr(getvalue(s_loadingfiles))));
}
}
/* xlerror - handle a fatal error */
void xlerror(const char *emsg, LVAL arg)
{
close_loadingfiles();
if (getvalue(s_breakenable) != NIL)
breakloop("error",NULL,emsg,arg,FALSE);
else {
xlsignal(emsg,arg);
xlerrprint("error",NULL,emsg,arg);
xlbrklevel();
}
}
/* xlcerror - handle a recoverable error */
void xlcerror(const char *cmsg, const char *emsg, LVAL arg)
{
if (getvalue(s_breakenable) != NIL)
breakloop("error",cmsg,emsg,arg,TRUE);
else {
xlsignal(emsg,arg);
xlerrprint("error",NULL,emsg,arg);
xlbrklevel();
}
}
/* xlerrprint - print an error message */
void xlerrprint(const char *hdr, const char *cmsg, const char *emsg, LVAL arg)
{
/* print the error message */
sprintf(buf,"%s: %s",hdr,emsg);
errputstr(buf);
/* print the argument */
if (arg != s_unbound) {
errputstr(" - ");
errprint(arg);
}
/* no argument, just end the line */
else
errputstr("\n");
/* print the continuation message */
if (cmsg) {
sprintf(buf,"if continued: %s\n",cmsg);
errputstr(buf);
}
}
/* breakloop - the debug read-eval-print loop */
LOCAL void breakloop(const char *hdr, const char *cmsg,
const char *emsg, LVAL arg, int cflag)
{
LVAL expr,val;
XLCONTEXT cntxt;
int type;
/* print the error message */
xlerrprint(hdr,cmsg,emsg,arg);
/* flush the input buffer */
xlflush();
/* do the back trace */
if (getvalue(s_tracenable)) {
val = getvalue(s_tlimit);
xlbaktrace(fixp(val) ? (int)getfixnum(val) : -1);
}
/* protect some pointers */
xlsave1(expr);
/* increment the debug level */
++xldebug;
/* debug command processing loop */
xlbegin(&cntxt,CF_BRKLEVEL|CF_CLEANUP|CF_CONTINUE,s_true);
for (type = 0; type == 0; ) {
/* setup the continue trap */
if ((type = _setjmp(cntxt.c_jmpbuf)))
switch (type) {
case CF_CLEANUP:
continue;
case CF_BRKLEVEL:
type = 0;
break;
case CF_CONTINUE:
if (cflag) {
dbgputstr("[ continue from break loop ]\n");
continue;
}
else xlabort("this error can't be continued");
}
#ifndef READ_LINE
/* print a prompt */
sprintf(buf,"%d> ",xldebug);
dbgputstr(buf);
#endif
/* read an expression and check for eof */
if (!xlread(getvalue(s_debugio),&expr,FALSE)) {
type = CF_CLEANUP;
#ifdef READ_LINE
dbgputstr("\n");
#endif
break;
}
/* save the input expression */
xlrdsave(expr);
/* evaluate the expression */
expr = xleval(expr);
/* save the result */
xlevsave(expr);
/* print it */
dbgprint(expr);
}
xlend(&cntxt);
/* decrement the debug level */
--xldebug;
/* restore the stack */
xlpop();
/* check for aborting to the previous level */
if (type == CF_CLEANUP)
xlbrklevel();
}
/* baktrace - do a back trace */
void xlbaktrace(int n)
{
LVAL *fp,*p;
int argc;
for (fp = xlfp; (n < 0 || n--) && *fp; fp = fp - (int)getfixnum(*fp)) {
p = fp + 1;
errputstr("Function: ");
errprint(*p++);
if ((argc = (int)getfixnum(*p++)))
errputstr("Arguments:\n");
while (--argc >= 0) {
errputstr(" ");
errprint(*p++);
}
}
}
/* xldinit - debug initialization routine */
void xldinit(void)
{
xlsample = 0;
xldebug = 0;
}
|