static char *sccsid
= "@(#)error.c 34.3 11/7/80";
/* error ****************************************************************/
/* this routine is always called on a non-fatal error. The first argu- */
/* ment is printed out. The second a boolean flag indicating if the */
/* error routine is permitted to return a pointer to a lisp value if */
/* the "cont" command is executed. */
/* error from lisp C code, this temporarily replaces the old error
* allowing us to interface with the new errset scheme with minimum
* difficulty. We assume that an error which comes to this routine
* is of an "undefined error type" ER%misc . Soon all calls to this
* routine will be removed.
return(errorh(Vermisc
,mesg
,nil
,contvl
,0));
/* new error handler, works with errset
* call is errorh(type,message,valret,contuab) where
* type is an atom which classifys the error, and whose clb, if not nil
* is the name of a function to call to handle the error.
* message is a character string to print to describe the error
* valret is the value to return to an errset if one is found,
* and contuab is non nil if this error is continuable.
errorh(type
,message
,valret
,contuab
,uniqid
)
register struct catchfr
*curp
; /* must be first register decl */
lispval
*work
= 1 + (lispval
*) &uniqid
; int limit
= nargs() - 5;
lispval
Lread(), calhan();
struct argent
*savedlbot
= lbot
;
struct nament
* savedbnp
= bnp
;
int curdep
; /* error depth */
typedef struct catchfr
*cp
;
long myerrp
= errp
, what
;
contatm
= (contuab
== TRUE
? tatom
: nil
);
/* if there is a catch every error handler */
if((handy
= Verall
->a
.clb
) != nil
)
Verall
->a
.clb
= nil
; /* turn off before calling */
handy
= calhan(limit
,work
,type
,uniqid
,contatm
,message
,handy
);
if(contuab
&& (TYPE(handy
) == DTPR
))
if((handy
= type
->a
.clb
) != nil
) /* if there is an error handler */
handy
= calhan(limit
,work
,type
,uniqid
,contatm
,message
,handy
);
if(contuab
&& (TYPE(handy
) == DTPR
))
/* search stack for error catcher */
for (curp
= (cp
) errp
; curp
!= (cp
) nil
; curp
= curp
->link
)
if(curp
->labl
== Veruwpt
) founduw
= TRUE
;
if(((pass
== 2) && founduw
)
|| ( (TYPE(curp
->labl
) == DTPR
) && (curp
->labl
->d
.car
== Verall
)))
if((pass
== 1) && founduw
)
{ protect(handy2
= newdot());
handy
= handy2
->d
.cdr
= newdot();
handy
->d
.car
= nil
; /* indicates error */
handy
= handy
->d
.cdr
= newdot();
handy
= handy
->d
.cdr
= newdot();
handy
->d
.car
= matom(message
);
handy
= handy
->d
.cdr
= newdot();
handy
= handy
->d
.cdr
= newdot();
handy
->d
.car
= inewint(uniqid
);
handy
= handy
->d
.cdr
= newdot();
handy
->d
.car
= inewint(contuab
);
while (limit
-- > 0) /* put in optional args */
{ handy
= handy
->d
.cdr
= newdot();
valret
= handy2
; /* return this as value */
else if( (curp
->flag
!= nil
)
/* print the full error message */
if(!founduw
&& ((handy
=Verrset
->a
.clb
) != nil
))
calhan(limit
,work
,type
,uniqid
,contatm
,message
,handy
);
popnames(curp
->svbnp
); /* un shallow bind */
errp
= (int) curp
->link
; /* set error to next frame */
* return value goes into r7 until after movc3 instruction
asm(" movl 12(ap),r7"); /* set return value (valret)*/
asm(" addl3 $16,r11,sp"); /* skip link,flag,labl,svbnp */
asm(" movc3 $44,(sp),_setsav");/*restore (return) context*/
asm(" movab 44(sp),sp"); /* skip past "" "" */
asm(" popr $0x2540"); /* restore registers */
asm(" rsb"); /* return to errset */
/* no one will catch this error, we must see if there is an
error-goes-to-top-level catcher */
if (Vertpl
->a
.clb
!= nil
)
handy
= calhan(limit
,work
,type
,uniqid
,contatm
,message
,Vertpl
->a
.clb
);
if( contuab
&& (TYPE(handy
) == DTPR
))
/* at this point, print error mssage and break, just like
the current error scheme */
/* If automatic-reset is set
we will now jump to top level, calling the reset function
if it exists, or using the c rest function if it does not
if ((handy
= reseta
->a
.fnbnd
) != nil
)
while(what
= setexit()) {
if (curdep
== (int) contval
) {
printf("CAN'T CONTINUE\n");
depth
= curdep
; /* In case of freturn, reset this global */
fprintf(stdout
,"\n%d:>",curdep
);
if(vtemp
== eofa
) exit(0);
printr(eval(vtemp
),stdout
);
calhan(limit
,work
,type
,uniqid
,contuab
,message
,handler
)
lispval handler
,type
,contuab
;
register struct argent
*lbot
, *np
;
protect(handler
); /* funcall the handler */
protect(handy
= newdot()); /* with a list consisting of */
handy
->d
.car
= type
; /* type, */
handy
= (handy
->d
.cdr
= newdot());
handy
->d
.car
= inewint(uniqid
); /* identifying number, */
handy
= (handy
->d
.cdr
= newdot());
handy
= (handy
->d
.cdr
= newdot());
handy
->d
.car
= matom(message
); /* message to be typed out, */
handy
= handy
->d
.cdr
= newdot();
/* lispend **************************************************************/
/* Fatal errors come here, with their epitaph. */
fprintf(errport
,"%s\n",mesg
);
/* namerr ***************************************************************/
/* handles namestack overflow, at present by simply giving a message */
if((nplim
= np
+ NAMINC
) > orgnp
+ NAMESIZE
)
printf("Unrecoverable Namestack Overflow, (reset) is forced\n");
nplim
= orgnp
+ NAMESIZE
- 4*NAMINC
;
lbot
= np
= nplim
- NAMINC
;
error("NAMESTACK OVERFLOW",FALSE
);
error("Bindstack overflow.",FALSE
);
bindfix(Vreadtable
,strtab
,nil
);
error("Illegal read table.",FALSE
);
error("Attempt to allocate beyond static structures.",FALSE
);
errorh(Vermisc
,"incorrect number of args to",