BSD 3 development
[unix-history] / usr / src / cmd / lisp / error.c
CommitLineData
61e55e70
JF
1#include "global.h"
2/* error ****************************************************************/
3/* this routine is always called on a non-fatal error. The first argu- */
4/* ment is printed out. The second a boolean flag indicating if the */
5/* error routine is permitted to return a pointer to a lisp value if */
6/* the "cont" command is executed. */
7
8/* error from lisp C code, this temporarily replaces the old error
9 * allowing us to interface with the new errset scheme with minimum
10 * difficulty. We assume that an error which comes to this routine
11 * is of an "undefined error type" ER%misc . Soon all calls to this
12 * routine will be removed.
13 *
14 */
15
16lispval
17error(mesg,contvl)
18char *mesg;
19lispval contvl;
20{
21 lispval errorh();
22
23 return(errorh(Vermisc,mesg,nil,contvl,0));
24}
25
26
27/* new error handler, works with errset
28 *
29 * call is errorh(type,message,valret,contuab) where
30 * type is an atom which classifys the error, and whose clb, if not nil
31 * is the name of a function to call to handle the error.
32 * message is a character string to print to describe the error
33 * valret is the value to return to an errset if one is found,
34 * and contuab is non nil if this error is continuable.
35 */
36
37#include "catchframe.h"
38
39lispval
40errorh(type,message,valret,contuab,uniqid)
41lispval type,valret;
42int uniqid,contuab;
43char *message;
44{
45 register struct catchfr *curp; /* must be first register decl */
46 register lispval handy;
47 lispval *work = 1 + (lispval *) &uniqid; int limit = nargs() - 5;
48 lispval Lread(), calhan();
49 struct argent *savedlbot = lbot;
50 struct nament * savedbnp = bnp;
51 int curdep ; /* error depth */
52 typedef struct catchfr *cp;
53 extern int errp;
54 int myerrp = errp, what;
55 int saveme[SAVSIZE];
56 snpand(2);
57
58 if(type->clb != nil) /* if there is an error handler */
59 {
60 handy = calhan(limit,work,type->clb,uniqid,message);
61 if(contuab && (TYPE(handy) == DTPR))
62 return(handy->car);
63 }
64
65 /* search stack for error catcher */
66
67 for (curp = (cp) errp ; curp != (cp) nil ; curp = curp->link)
68 {
69 if((curp->labl == type)
70 || ( (TYPE(curp->labl) == DTPR) && (curp->labl->car == Verall)))
71 {
72 if((curp->flag != nil)
73 && (type != Vererr)) {
74 /* print the full error message */
75 printf("%s ",message);
76 while(limit-->0) {
77 printr(*work++,stdout);
78 fflush(stdout);
79 }
80 fputc('\n',stdout);
81 fflush(stdout);
82 }
83 popnames(curp->svbnp); /* un shallow bind */
84 errp = (int) curp->link; /* set error to next frame */
85 asm(" addl3 $16,r11,sp"); /* skip link,flag,labl,svbnp */
86 asm(" movc3 $40,(sp),_setsav");/*restore (return) context*/
87 asm(" movab 40(sp),sp"); /* skip past "" "" */
88 asm(" popr $0x2540"); /* restore registers */
89 asm(" movl 12(ap),r0"); /* set return value */
90 asm(" rsb"); /* return to errset */
91 /* NOT REACHED */
92 }
93 }
94
95 /* no one will catch this error, we must see if there is an
96 error-goes-to-top-level catcher */
97
98 if (Vertpl->clb != nil)
99 {
100
101 handy = calhan(limit,work,Vertpl,uniqid,message);
102 if( contuab && (TYPE(handy) == DTPR))
103 return(handy->car);
104 }
105
106 /* at this point, print error mssage and break, just like
107 the current error scheme */
108 printf("%s: ",message);
109 while(limit-->0) {
110 printr(*work++,stdout);
111 fflush(stdout);
112 }
113
114 curdep = ++depth;
115 getexit(saveme);
116 while(what = setexit()) {
117 errp = myerrp;
118 depth = curdep;
119 switch(what) {
120 case BRRETB:
121 if (curdep == (int) contval) {
122 popnames(savedbnp);
123 lbot = savedlbot;
124 continue;
125 }
126 default:
127 resexit(saveme);
128 reset(what);
129
130 case BRRETN:
131 if (contuab)
132 {
133 popnames(savedbnp);
134 lbot = savedlbot;
135 depth = curdep -1;
136 resexit(saveme);
137 return(contval);
138 }
139 printf("CAN'T CONTINUE\n");
140
141 }
142 }
143 lbot = np;
144 np++->val = P(stdin);
145 np++->val = eofa;
146 while(TRUE) {
147
148 fprintf(stdout,"\n%d:>",curdep);
149 dmpport(stdout);
150 vtemp = Lread();
151 if(vtemp == eofa) exit(0);
152 printr(eval(vtemp),stdout);
153 }
154}
155static lispval
156calhan(limit,work,handler,uniqid,message)
157register lispval *work;
158lispval handler;
159register limit;
160register char *message;
161int uniqid;
162{
163 register lispval handy;
164 register struct argent *lbot, *np;
165 lbot = np;
166 protect(handler->clb); /* funcall the handler */
167 protect(handy = newdot()); /* with a list consisting of */
168 handy->car = inewint(uniqid); /* identifying number, */
169 handy = handy->cdr = newdot();
170 handy->car = matom(message); /* message to be typed out, */
171 while(limit-- > 0)
172 { /* any other args. */
173 handy = handy->cdr = newdot();
174 handy->car = *work++;
175 }
176 handy->cdr = nil;
177
178 handy = Lfuncal();
179 np=lbot;
180}
181
182/* lispend **************************************************************/
183/* Fatal errors come here, with their epitaph. */
184lispend(mesg)
185 char mesg[];
186 {
187 dmpport(poport);
188 fprintf(errport,"%s\n",mesg);
189 dmpport(errport);
190 exit(0);
191 }
192
193/* namerr ***************************************************************/
194/* handles namestack overflow, at present by simply giving a message */
195
196namerr()
197{
198 np -= 10;
199 error("NAMESTACK OVERFLOW",FALSE);
200 /* NOT REACHED */
201}
202binderr()
203{
204 bnp -= 10;
205 error("Bindstack overflow.",FALSE);
206}
207rtaberr()
208{
209 bindfix(Vreadtable,strtab,nil);
210 error("Illegal read table.",FALSE);
211}
212badmem()
213{
214 error("Attempt to allocate beyond static structures.",FALSE);
215}