Annotation of 42BSD/ucb/lisp/franz/error.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char *rcsid =
        !             3:    "$Header: error.c,v 1.5 83/09/12 14:17:50 sklower Exp $";
        !             4: #endif
        !             5: 
        !             6: /*                                     -[Sun Sep  4 09:06:21 1983 by jkf]-
        !             7:  *     error.c                         $Locker:  $
        !             8:  * error handler
        !             9:  *
        !            10:  * (c) copyright 1982, Regents of the University of California
        !            11:  */
        !            12: 
        !            13: 
        !            14: #include "global.h"
        !            15: #include "frame.h"
        !            16: #include "catchfram.h"
        !            17: 
        !            18: static lispval IEargs[5];
        !            19: static int     IElimit;
        !            20: 
        !            21: /* error
        !            22:  * this routine is always called on a non-fatal error.  The first argu-
        !            23:  * ment is printed out.  The second a boolean flag indicating if the
        !            24:  * error routine is permitted to return a pointer to a lisp value if
        !            25:  * the "cont" command is executed.
        !            26:  */
        !            27:  
        !            28: /* error from lisp C code, this temporarily replaces the old error
        !            29:  * allowing us to interface with the new errset scheme with minimum
        !            30:  * difficulty.  We assume that an error which comes to this routine
        !            31:  * is of an "undefined error type" ER%misc .  Soon all calls to this
        !            32:  * routine will be removed.
        !            33:  *
        !            34:  */
        !            35: 
        !            36: lispval
        !            37: error(mesg,contvl)
        !            38: char *mesg;
        !            39: int contvl;
        !            40: {
        !            41:     lispval errorh();
        !            42: 
        !            43:     return(errorh(Vermisc,mesg,nil,contvl,0));
        !            44: }
        !            45: 
        !            46: 
        !            47: /* new error handler, works with errset 
        !            48:  * 
        !            49:  * call is errorh(type,message,valret,contuab) where
        !            50:  * type is an atom which classifys the error, and whose clb, if not nil
        !            51:  * is the name of a function to call to handle the error.
        !            52:  * message is a character string to print to describe the error
        !            53:  * valret is the value to return to an errset if one is found,
        !            54:  * and contuab is non nil if this error is continuable.
        !            55:  */
        !            56:  
        !            57: 
        !            58: /* VARARGS5 */
        !            59: static lispval
        !            60: Ierrorh(type,message,valret,contuab,uniqid)
        !            61: lispval type,valret;
        !            62: int uniqid,contuab;
        !            63: char *message;
        !            64: {
        !            65:        register struct frame *curp, *uwpframe = (struct frame *)0; 
        !            66:        register lispval handy;
        !            67:        lispval *work = IEargs; 
        !            68:        int limit = IElimit;
        !            69:        int pass, curdepth;
        !            70:        lispval Lread(), calhan();
        !            71:        lispval contatm;
        !            72:        lispval handy2;
        !            73:        extern struct frame *errp;
        !            74:        pbuf pb;
        !            75:        Savestack(2);
        !            76: 
        !            77:        contatm = (contuab == TRUE ? tatom : nil);
        !            78: 
        !            79:        /* if there is a catch every error handler */
        !            80:        if((handy = Verall->a.clb) != nil)      
        !            81:        {
        !            82:            handy = Verall->a.clb;
        !            83:            Verall->a.clb = nil;                /* turn off before calling */
        !            84:            handy = calhan(limit,work,type,uniqid,contatm,message,handy);
        !            85:            if(contuab && (TYPE(handy) == DTPR))
        !            86:                return(handy->d.car);
        !            87:        }
        !            88: 
        !            89:        if((handy = type->a.clb) != nil)        /* if there is an error handler */
        !            90:        {
        !            91:            handy = calhan(limit,work,type,uniqid,contatm,message,handy);
        !            92:            if(contuab && (TYPE(handy) == DTPR))
        !            93:                return(handy->d.car);
        !            94:        }
        !            95: 
        !            96:        pass = 1;
        !            97:        /* search stack for error catcher */
        !            98:   ps2:
        !            99: 
        !           100:        for (curp = errp ; curp != (struct frame *) 0 ; curp = curp->olderrp)
        !           101:        {
        !           102:           if(curp->class == F_CATCH) 
        !           103:           {
        !           104:                /* 
        !           105:                 * interesting catch tags are ER%unwind-protect, generated
        !           106:                 * by unwind-protect and ER%all, generated by errset
        !           107:                 */
        !           108:                if((pass == 1) && (curp->larg1 == Veruwpt))
        !           109:                {
        !           110:                    uwpframe = curp;
        !           111:                    pass = 2;
        !           112:                    goto ps2;
        !           113:                }
        !           114:                else if(curp->larg1 == Verall)
        !           115:                {
        !           116:                    /* 
        !           117:                     * have found an errset to jump to. If there is an
        !           118:                     * errset handler, first call that.
        !           119:                     */
        !           120:                    if((handy=Verrset->a.clb) != nil)
        !           121:                    {
        !           122:                        calhan(limit,work,type,uniqid,contatm,message,handy);
        !           123:                    }
        !           124: 
        !           125:                    /*
        !           126:                     * if there is an unwind-protect then go to that first.
        !           127:                     * The unwind protect will return to errorh after
        !           128:                     * it has processed its cleanup forms.
        !           129:                     * assert: if pass == 2 
        !           130:                     *          then there is a pending unwind-protect
        !           131:                     */
        !           132:                     if(uwpframe != (struct frame *)0)
        !           133:                     {
        !           134:                        /*
        !           135:                         * generate form to return to unwind-protect 
        !           136:                         */
        !           137:                        protect(handy2 = newdot());
        !           138:                        handy2->d.car = Veruwpt;
        !           139:                        handy = handy2->d.cdr = newdot();
        !           140:                        handy->d.car = nil;             /* indicates error */
        !           141:                        handy = handy->d.cdr = newdot();
        !           142:                        handy->d.car = type;
        !           143:                        handy = handy->d.cdr = newdot();
        !           144:                        handy->d.car = matom(message);
        !           145:                        handy = handy->d.cdr = newdot();
        !           146:                        handy->d.car = valret;
        !           147:                        handy = handy->d.cdr = newdot();
        !           148:                        handy->d.car = inewint(uniqid);
        !           149:                        handy = handy->d.cdr = newdot();
        !           150:                        handy->d.car = inewint(contuab);
        !           151:                        while (limit-- > 0)     /* put in optional args */
        !           152:                        {  handy = handy->d.cdr = newdot();
        !           153:                           handy->d.car = *work++;
        !           154:                        }
        !           155:                        lispretval = handy2;            /* return this as value */
        !           156:                        retval = C_THROW;
        !           157:                        Iretfromfr(uwpframe);
        !           158:                        /* NOTREACHED */
        !           159:                    }
        !           160:                    /*
        !           161:                     * Will return to errset
        !           162:                     * print message if flag on this frame is non nil
        !           163:                     */
        !           164:                    if(curp->larg2 != nil)
        !           165:                    {
        !           166:                        printf("%s  ",message);
        !           167:                        while(limit-->0) {
        !           168:                            printr(*work++,stdout);
        !           169:                            fflush(stdout);
        !           170:                        }
        !           171:                        fputc('\n',stdout);
        !           172:                        fflush(stdout);
        !           173:                    }
        !           174: 
        !           175:                    lispretval = valret;
        !           176:                    retval = C_THROW;           /* looks like a throw */
        !           177:                    Iretfromfr(curp);
        !           178:                }
        !           179:            }
        !           180:        }
        !           181:            
        !           182:        /* no one will catch this error, we must see if there is an
        !           183:           error-goes-to-top-level catcher */
        !           184:        
        !           185:        if (Vertpl->a.clb != nil)
        !           186:        {
        !           187:            
        !           188:            handy = calhan(limit,work,type,uniqid,contatm,message,Vertpl->a.clb);
        !           189:            if( contuab  && (TYPE(handy) == DTPR))
        !           190:                   return(handy->d.car);
        !           191:        }
        !           192: 
        !           193:        /* at this point, print error message and break, just like
        !           194:           the current error scheme */
        !           195:        printf("%s ",message);
        !           196:        while(limit-->0) {
        !           197:                printr(*work++,stdout);
        !           198:                fflush(stdout);
        !           199:        }
        !           200: 
        !           201: 
        !           202:        /* If automatic-reset is set
        !           203:         * we will now jump to top level, calling the reset function
        !           204:         * if it exists, or using the c rest function if it does not 
        !           205:         */
        !           206: 
        !           207:        if(Sautor)
        !           208:        {
        !           209:                if ((handy = reseta->a.fnbnd) != nil)
        !           210:                {
        !           211:                        lispval Lapply();
        !           212:                        lbot = np;
        !           213:                        protect(reseta);
        !           214:                        protect(nil);
        !           215:                        Lapply();
        !           216:                }
        !           217:                Inonlocalgo(C_RESET,inewint(0),nil);
        !           218:                /* NOTREACHED */
        !           219:        }
        !           220:        
        !           221:        /*
        !           222:         * no one wants the error.  We set up another read-eval-print
        !           223:         * loop. The user can get out of this error by typing (return 'val)
        !           224:         * if the error is continuable.  Normally this code be replaced
        !           225:         * by more clever lisp code, when the full lisp is built
        !           226:         */
        !           227: 
        !           228:        errp = Pushframe(F_PROG,nil,nil);
        !           229: 
        !           230:        if(TYPE(Verdepth->a.clb) != INT)
        !           231:        {
        !           232:                curdepth = 1;
        !           233:        }
        !           234:        else curdepth = 1 + Verdepth->a.clb->i;
        !           235:        PUSHDOWN(Verdepth,inewint(curdepth));
        !           236: 
        !           237:        switch(retval) {
        !           238:        case C_RET:     /* 
        !           239:                         * attempt to return from error
        !           240:                         */
        !           241:                        if(!contuab) error("Can't continue from this error",
        !           242:                                                  FALSE);
        !           243:                        popnames(errp->svbnp);
        !           244:                        errp = Popframe();
        !           245:                        Restorestack();
        !           246:                        return(lispretval);
        !           247: 
        !           248:        case C_GO:      /*
        !           249:                         * this may look like a valid prog, but it really
        !           250:                         * isn't, since go's are not allowed.  Let the
        !           251:                         * user know.
        !           252:                         */
        !           253:                        error("Can't 'go' through an error break",FALSE);
        !           254:                        /* NOT REACHED */
        !           255: 
        !           256:        case C_INITIAL: /*
        !           257:                          * normal case, just fall through into read-eval-print
        !           258:                          * loop
        !           259:                          */
        !           260:                        break;
        !           261:        }
        !           262:        lbot = np;
        !           263:        protect(P(stdin));
        !           264:        protect(eofa);
        !           265: 
        !           266:        while(TRUE) {
        !           267:                
        !           268:                fprintf(stdout,"\n%d:>",curdepth);
        !           269:                dmpport(stdout);
        !           270:                vtemp = Lread();
        !           271:                if(vtemp == eofa) franzexit(0);
        !           272:                printr(eval(vtemp),stdout);
        !           273:        }
        !           274:        /* NOTREACHED */
        !           275: }
        !           276: 
        !           277: lispval
        !           278: errorh(type,message,valret,contuab,uniqid)
        !           279: lispval type,valret;
        !           280: int uniqid,contuab;
        !           281: char *message;
        !           282: {
        !           283:        IElimit = 0;
        !           284:        Ierrorh(type,message,valret,contuab,uniqid);
        !           285:        /* NOTREACHED */
        !           286: }
        !           287: 
        !           288: lispval
        !           289: errorh1(type,message,valret,contuab,uniqid,arg1)
        !           290: lispval type,valret,arg1;
        !           291: int uniqid,contuab;
        !           292: char *message;
        !           293: {
        !           294:        IElimit = 1;
        !           295:        IEargs[0] = arg1;
        !           296:        Ierrorh(type,message,valret,contuab,uniqid);
        !           297:        /* NOTREACHED */
        !           298: }
        !           299: 
        !           300: lispval
        !           301: errorh2(type,message,valret,contuab,uniqid,arg1,arg2)
        !           302: lispval type,valret,arg1,arg2;
        !           303: int uniqid,contuab;
        !           304: char *message;
        !           305: {
        !           306:        IElimit = 2;
        !           307:        IEargs[0] = arg1;
        !           308:        IEargs[1] = arg2;
        !           309:        Ierrorh(type,message,valret,contuab,uniqid);
        !           310:        /* NOTREACHED */
        !           311: }
        !           312: 
        !           313: lispval
        !           314: calhan(limit,work,type,uniqid,contuab,message,handler)
        !           315: register lispval *work;
        !           316: lispval handler,type,contuab;
        !           317: register limit;
        !           318: register char *message;
        !           319: int uniqid;
        !           320: {
        !           321:            register lispval handy;
        !           322:            Savestack(4);
        !           323:            lbot = np;
        !           324:            protect(handler);           /* funcall the handler */
        !           325:            protect(handy = newdot());          /* with a list consisting of */
        !           326:            handy->d.car = type;                        /* type, */
        !           327:            handy = (handy->d.cdr = newdot());
        !           328:            handy->d.car = inewint(uniqid);     /* identifying number, */
        !           329:            handy = (handy->d.cdr = newdot());
        !           330:            handy->d.car = contuab;
        !           331:            handy = (handy->d.cdr = newdot());
        !           332:            handy->d.car = matom(message);      /* message to be typed out, */
        !           333:            while(limit-- > 0)
        !           334:            {                                   /* any other args. */
        !           335:                    handy = handy->d.cdr = newdot();
        !           336:                    handy->d.car = *work++;
        !           337:            }
        !           338:            handy->d.cdr = nil;
        !           339: 
        !           340:            handy = Lfuncal();
        !           341:            Restorestack();
        !           342:            return(handy);
        !           343: }
        !           344: 
        !           345: /* lispend **************************************************************/
        !           346: /* Fatal errors come here, with their epitaph.                         */
        !           347: lispend(mesg)
        !           348:        char    mesg[];
        !           349:        {
        !           350:        dmpport(poport);
        !           351:        fprintf(errport,"%s\n",mesg);
        !           352:        dmpport(errport);
        !           353:        franzexit(0);
        !           354:        /* NOT REACHED */
        !           355:        }
        !           356: 
        !           357: /* namerr ***************************************************************/
        !           358: /* handles namestack overflow, at present by simply giving a message   */
        !           359: 
        !           360: namerr()
        !           361: {
        !           362:        if((nplim = np + NAMINC) > orgnp + NAMESIZE) 
        !           363:        {  
        !           364:          printf("Unrecoverable Namestack Overflow, (reset) is forced\n");
        !           365:          fflush(stdout);
        !           366:          nplim = orgnp + NAMESIZE - 4*NAMINC;
        !           367:          lbot = np = nplim - NAMINC;
        !           368:          protect(matom("reset"));
        !           369:          Lfuncal();
        !           370:        }
        !           371:        error("NAMESTACK OVERFLOW",FALSE);
        !           372:        /* NOT REACHED */
        !           373: }
        !           374: 
        !           375: binderr()
        !           376: {
        !           377:        bnp -= 10;
        !           378:        error("Bindstack overflow.",FALSE);
        !           379:        /* NOT REACHED */
        !           380: }
        !           381: 
        !           382: rtaberr()
        !           383: {
        !           384:        bindfix(Vreadtable,strtab,nil);
        !           385:        error("Illegal read table.",FALSE);
        !           386:        /* NOT REACHED */
        !           387: }
        !           388: xserr()
        !           389: {
        !           390:        error("Ran out of alternate stack",FALSE);
        !           391: }
        !           392: badmem(n)
        !           393: {
        !           394:        char errbuf[256], *sprintf();
        !           395: 
        !           396:        sprintf(errbuf,"Attempt to allocate beyond static structures (%d).",n);
        !           397:        error(errbuf,FALSE);
        !           398:        /* NOT REACHED */
        !           399: }
        !           400: argerr(msg)
        !           401: char *msg;
        !           402: {
        !           403:        errorh1(Vermisc,"incorrect number of args to",
        !           404:                                  nil,FALSE,0,matom(msg));
        !           405:        /* NOT REACHED */
        !           406: }
        !           407: 
        !           408: lispval Vinterrfcn = nil;
        !           409: 
        !           410: /*
        !           411:  * wnaerr - wrong number of arguments to a compiled function hander
        !           412:  * called with the function name (symbol) and a descriptor of the
        !           413:  * number of arguments that were expected.  The form of the descriptor
        !           414:  * is (considered as a decimal number) xxyy where xx is the minumum
        !           415:  * and yy-1 is the maximum.  A maximum of -1 means that there is no
        !           416:  * maximum.
        !           417:  *
        !           418:  */
        !           419: wnaerr(fcn,wantargs)
        !           420: lispval fcn;
        !           421: {
        !           422:     if (Vinterrfcn == nil)
        !           423:     {
        !           424:        Vinterrfcn = matom("int:wrong-number-of-args-error");
        !           425:     }
        !           426:     if (Vinterrfcn->a.fnbnd != nil)
        !           427:     {
        !           428:        protect(fcn);
        !           429:        protect(inewint(wantargs / 1000));        /* min */
        !           430:        protect(inewint((wantargs % 1000) - 1));  /* max */
        !           431:        Ifuncal(Vinterrfcn);
        !           432:        error("wrong number of args function should never return ", FALSE);
        !           433:     }
        !           434: 
        !           435:     errorh1(Vermisc,"wrong number of arguments to ",nil,FALSE,0,fcn);
        !           436: }
        !           437: 
        !           438:        
        !           439:     

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.