Annotation of 40BSD/cmd/lisp/error.c, revision 1.1

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: }

unix.superglobalmegacorp.com

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