|
|
1.1 root 1:
2: static char *sccsid = "@(#)error.c 34.3 11/7/80";
3:
4: #include "global.h"
5: /* error ****************************************************************/
6: /* this routine is always called on a non-fatal error. The first argu- */
7: /* ment is printed out. The second a boolean flag indicating if the */
8: /* error routine is permitted to return a pointer to a lisp value if */
9: /* the "cont" command is executed. */
10:
11: /* error from lisp C code, this temporarily replaces the old error
12: * allowing us to interface with the new errset scheme with minimum
13: * difficulty. We assume that an error which comes to this routine
14: * is of an "undefined error type" ER%misc . Soon all calls to this
15: * routine will be removed.
16: *
17: */
18:
19: lispval
20: error(mesg,contvl)
21: char *mesg;
22: lispval contvl;
23: {
24: lispval errorh();
25:
26: return(errorh(Vermisc,mesg,nil,contvl,0));
27: }
28:
29:
30: /* new error handler, works with errset
31: *
32: * call is errorh(type,message,valret,contuab) where
33: * type is an atom which classifys the error, and whose clb, if not nil
34: * is the name of a function to call to handle the error.
35: * message is a character string to print to describe the error
36: * valret is the value to return to an errset if one is found,
37: * and contuab is non nil if this error is continuable.
38: */
39:
40: #include "catchfram.h"
41:
42: lispval
43: errorh(type,message,valret,contuab,uniqid)
44: lispval type,valret;
45: int uniqid,contuab;
46: char *message;
47: {
48: register struct catchfr *curp; /* must be first register decl */
49: register lispval handy;
50: lispval *work = 1 + (lispval *) &uniqid; int limit = nargs() - 5;
51: lispval Lread(), calhan();
52: lispval contatm;
53: lispval handy2;
54: struct argent *savedlbot = lbot;
55: struct nament * savedbnp = bnp;
56: int curdep ; /* error depth */
57: typedef struct catchfr *cp;
58: extern long errp;
59: long myerrp = errp, what;
60: int pass,founduw;
61: int saveme[SAVSIZE];
62: snpand(2);
63:
64: contatm = (contuab == TRUE ? tatom : nil);
65:
66: /* if there is a catch every error handler */
67: if((handy = Verall->a.clb) != nil)
68: {
69: handy = Verall->a.clb;
70: Verall->a.clb = nil; /* turn off before calling */
71: handy = calhan(limit,work,type,uniqid,contatm,message,handy);
72: if(contuab && (TYPE(handy) == DTPR))
73: return(handy->d.car);
74: }
75:
76: if((handy = type->a.clb) != nil) /* if there is an error handler */
77: {
78: handy = calhan(limit,work,type,uniqid,contatm,message,handy);
79: if(contuab && (TYPE(handy) == DTPR))
80: return(handy->d.car);
81: }
82:
83: pass = 1;
84: /* search stack for error catcher */
85: ps2:
86: founduw = FALSE;
87:
88: for (curp = (cp) errp ; curp != (cp) nil ; curp = curp->link)
89: {
90: if(curp->labl == Veruwpt) founduw = TRUE;
91: if(((pass == 2) && founduw)
92: || (curp->labl == type)
93: || ( (TYPE(curp->labl) == DTPR) && (curp->labl->d.car == Verall)))
94: {
95: if((pass == 1) && founduw)
96: { pass = 2;
97: goto ps2;
98: }
99:
100: if(founduw)
101: { protect(handy2 = newdot());
102: handy2->d.car = Veruwpt;
103: handy = handy2->d.cdr = newdot();
104: handy->d.car = nil; /* indicates error */
105: handy = handy->d.cdr = newdot();
106: handy->d.car = type;
107: handy = handy->d.cdr = newdot();
108: handy->d.car = matom(message);
109: handy = handy->d.cdr = newdot();
110: handy->d.car = valret;
111: handy = handy->d.cdr = newdot();
112: handy->d.car = inewint(uniqid);
113: handy = handy->d.cdr = newdot();
114: handy->d.car = inewint(contuab);
115: while (limit-- > 0) /* put in optional args */
116: { handy = handy->d.cdr = newdot();
117: handy->d.car = *work++;
118: }
119: valret = handy2; /* return this as value */
120: }
121: else if( (curp->flag != nil)
122: && (type != Vererr)) {
123: /* print the full error message */
124: printf("%s ",message);
125: while(limit-->0) {
126: printr(*work++,stdout);
127: fflush(stdout);
128: }
129: fputc('\n',stdout);
130: fflush(stdout);
131: }
132: if(!founduw && ((handy=Verrset->a.clb) != nil))
133: {
134: calhan(limit,work,type,uniqid,contatm,message,handy);
135: }
136: popnames(curp->svbnp); /* un shallow bind */
137: errp = (int) curp->link; /* set error to next frame */
138: /*
139: * return value goes into r7 until after movc3 instruction
140: * which clobbers r0
141: */
142: asm(" movl 12(ap),r7"); /* set return value (valret)*/
143: asm(" addl3 $16,r11,sp"); /* skip link,flag,labl,svbnp */
144: asm(" movc3 $44,(sp),_setsav");/*restore (return) context*/
145: asm(" movab 44(sp),sp"); /* skip past "" "" */
146: asm(" popr $0x2540"); /* restore registers */
147: asm(" movl r7,r0");
148: asm(" rsb"); /* return to errset */
149: /* NOT REACHED */
150: }
151: }
152:
153: /* no one will catch this error, we must see if there is an
154: error-goes-to-top-level catcher */
155:
156: if (Vertpl->a.clb != nil)
157: {
158:
159: handy = calhan(limit,work,type,uniqid,contatm,message,Vertpl->a.clb);
160: if( contuab && (TYPE(handy) == DTPR))
161: return(handy->d.car);
162: }
163:
164: /* at this point, print error mssage and break, just like
165: the current error scheme */
166: printf("%s ",message);
167: while(limit-->0) {
168: printr(*work++,stdout);
169: fflush(stdout);
170: }
171:
172:
173: /* If automatic-reset is set
174: we will now jump to top level, calling the reset function
175: if it exists, or using the c rest function if it does not
176: */
177:
178: if(Sautor)
179: {
180: if ((handy = reseta->a.fnbnd) != nil)
181: { lbot = np;
182: protect(reseta);
183: protect(nil);
184: Lapply();
185: }
186: contval = 0;
187: reset(BRRETB);
188: }
189:
190: curdep = ++depth;
191: getexit(saveme);
192: while(what = setexit()) {
193: errp = myerrp;
194: depth = curdep;
195: switch(what) {
196: case BRRETB:
197: if (curdep == (int) contval) {
198: popnames(savedbnp);
199: lbot = savedlbot;
200: continue;
201: }
202: default:
203: resexit(saveme);
204: reset(what);
205:
206: case BRRETN:
207: if (contuab)
208: {
209: popnames(savedbnp);
210: lbot = savedlbot;
211: depth = curdep -1;
212: resexit(saveme);
213: return(contval);
214: }
215: printf("CAN'T CONTINUE\n");
216:
217: }
218: }
219: lbot = np;
220: np++->val = P(stdin);
221: np++->val = eofa;
222: while(TRUE) {
223:
224: depth = curdep; /* In case of freturn, reset this global */
225: fprintf(stdout,"\n%d:>",curdep);
226: dmpport(stdout);
227: vtemp = Lread();
228: if(vtemp == eofa) exit(0);
229: printr(eval(vtemp),stdout);
230: }
231: }
232: lispval
233: calhan(limit,work,type,uniqid,contuab,message,handler)
234: register lispval *work;
235: lispval handler,type,contuab;
236: register limit;
237: register char *message;
238: int uniqid;
239: {
240: register lispval handy;
241: register struct argent *lbot, *np;
242: lbot = np;
243: protect(handler); /* funcall the handler */
244: protect(handy = newdot()); /* with a list consisting of */
245: handy->d.car = type; /* type, */
246: handy = (handy->d.cdr = newdot());
247: handy->d.car = inewint(uniqid); /* identifying number, */
248: handy = (handy->d.cdr = newdot());
249: handy->d.car = contuab;
250: handy = (handy->d.cdr = newdot());
251: handy->d.car = matom(message); /* message to be typed out, */
252: while(limit-- > 0)
253: { /* any other args. */
254: handy = handy->d.cdr = newdot();
255: handy->d.car = *work++;
256: }
257: handy->d.cdr = nil;
258:
259: handy = Lfuncal();
260: np=lbot;
261: return(handy);
262: }
263:
264: /* lispend **************************************************************/
265: /* Fatal errors come here, with their epitaph. */
266: lispend(mesg)
267: char mesg[];
268: {
269: dmpport(poport);
270: fprintf(errport,"%s\n",mesg);
271: dmpport(errport);
272: exit(0);
273: }
274:
275: /* namerr ***************************************************************/
276: /* handles namestack overflow, at present by simply giving a message */
277:
278: namerr()
279: {
280: if((nplim = np + NAMINC) > orgnp + NAMESIZE)
281: {
282: printf("Unrecoverable Namestack Overflow, (reset) is forced\n");
283: fflush(stdout);
284: nplim = orgnp + NAMESIZE - 4*NAMINC;
285: lbot = np = nplim - NAMINC;
286: protect(matom("reset"));
287: Lfuncal();
288: }
289: error("NAMESTACK OVERFLOW",FALSE);
290: /* NOT REACHED */
291: }
292: binderr()
293: {
294: bnp -= 10;
295: error("Bindstack overflow.",FALSE);
296: }
297: rtaberr()
298: {
299: bindfix(Vreadtable,strtab,nil);
300: error("Illegal read table.",FALSE);
301: }
302: badmem()
303: {
304: error("Attempt to allocate beyond static structures.",FALSE);
305: }
306: argerr(msg)
307: char *msg;
308: {
309: Lshostk();
310: errorh(Vermisc,"incorrect number of args to",
311: nil,FALSE,0,matom(msg));
312: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.