home *** CD-ROM | disk | FTP | other *** search
- /* xldebug - xlisp debugging support */
- /* Copyright (c) 1985, by David Michael Betz
- All Rights Reserved
- Permission is granted for unrestricted non-commercial use */
-
- #include "xlisp.h"
-
- /* external variables */
- extern long total;
- extern int xldebug;
- extern int xltrace;
- extern int xlsample;
- extern NODE *s_unbound;
- extern NODE *s_stdin,*s_stdout;
- extern NODE *s_tracenable,*s_tlimit,*s_breakenable;
- extern NODE ***xlstack;
- extern NODE *true;
- extern NODE **trace_stack;
- extern char buf[];
-
- /* external routines */
- extern char *malloc();
-
- /* forward declarations */
- FORWARD NODE *stacktop();
-
- /* xlfail - xlisp error handler */
- xlfail(emsg)
- char *emsg;
- {
- xlerror(emsg,stacktop());
- }
-
- /* xlabort - xlisp serious error handler */
- xlabort(emsg)
- char *emsg;
- {
- xlsignal(emsg,s_unbound);
- }
-
- /* xlbreak - enter a break loop */
- xlbreak(emsg,arg)
- char *emsg; NODE *arg;
- {
- breakloop("break",NULL,emsg,arg,TRUE);
- }
-
- /* xlerror - handle a fatal error */
- xlerror(emsg,arg)
- char *emsg; NODE *arg;
- {
- doerror(NULL,emsg,arg,FALSE);
- }
-
- /* xlcerror - handle a recoverable error */
- xlcerror(cmsg,emsg,arg)
- char *cmsg,*emsg; NODE *arg;
- {
- doerror(cmsg,emsg,arg,TRUE);
- }
-
- /* xlerrprint - print an error message */
- xlerrprint(hdr,cmsg,emsg,arg)
- char *hdr,*cmsg,*emsg; NODE *arg;
- {
- sprintf(buf,"%s: %s",hdr,emsg); stdputstr(buf);
- if (arg != s_unbound) { stdputstr(" - "); stdprint(arg); }
- else xlterpri(getvalue(s_stdout));
- if (cmsg) { sprintf(buf,"if continued: %s\n",cmsg); stdputstr(buf); }
- }
-
- /* doerror - handle xlisp errors */
- LOCAL doerror(cmsg,emsg,arg,cflag)
- char *cmsg,*emsg; NODE *arg; int cflag;
- {
- /* make sure the break loop is enabled */
- if (getvalue(s_breakenable) == NIL)
- xlsignal(emsg,arg);
-
- /* call the debug read-eval-print loop */
- breakloop("error",cmsg,emsg,arg,cflag);
- }
-
- /* breakloop - the debug read-eval-print loop */
- LOCAL int breakloop(hdr,cmsg,emsg,arg,cflag)
- char *hdr,*cmsg,*emsg; NODE *arg; int cflag;
- {
- NODE ***oldstk,*expr,*val;
- CONTEXT 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);
- }
-
- /* create a new stack frame */
- oldstk = xlsave(&expr,NULL);
-
- /* increment the debug level */
- xldebug++;
-
- /* debug command processing loop */
- xlbegin(&cntxt,CF_ERROR|CF_CLEANUP|CF_CONTINUE,true);
- for (type = 0; type == 0; ) {
-
- /* setup the continue trap */
- if (type = setjmp(cntxt.c_jmpbuf))
- switch (type) {
- case CF_ERROR:
- xlflush();
- type = 0;
- continue;
- case CF_CLEANUP:
- continue;
- case CF_CONTINUE:
- if (cflag) {
- stdputstr("[ continue from break loop ]\n");
- continue;
- }
- else xlabort("this error can't be continued");
- }
-
- /* read an expression and check for eof */
- if (!xlread(getvalue(s_stdin),&expr,FALSE)) {
- type = CF_CLEANUP;
- break;
- }
-
- /* evaluate the expression */
- expr = xleval(expr);
-
- /* print it */
- xlprint(getvalue(s_stdout),expr,TRUE);
- xlterpri(getvalue(s_stdout));
- }
- xlend(&cntxt);
-
- /* decrement the debug level */
- xldebug--;
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* check for aborting to the previous level */
- if (type == CF_CLEANUP) {
- stdputstr("[ abort to previous level ]\n");
- xlsignal(NULL,NIL);
- }
- }
-
- /* stacktop - return the top node on the stack */
- LOCAL NODE *stacktop()
- {
- return (xltrace >= 0 && xltrace < TDEPTH ? trace_stack[xltrace] : s_unbound);
- }
-
- /* baktrace - do a back trace */
- xlbaktrace(n)
- int n;
- {
- int i;
-
- for (i = xltrace; (n < 0 || n--) && i >= 0; i--)
- if (i < TDEPTH)
- stdprint(trace_stack[i]);
- }
-
- /* xldinit - debug initialization routine */
- xldinit()
- {
- if ((trace_stack = (NODE **)malloc(TDEPTH * sizeof(NODE *))) == NULL) {
- printf("insufficient memory");
- exit();
- }
- total += (long)(TDEPTH * sizeof(NODE *));
- xlsample = 0;
- xltrace = -1;
- xldebug = 0;
- }
-