Annotation of 43BSD/contrib/apl/src/a0.c, revision 1.1.1.1

1.1       root        1: static char Sccsid[] = "a0.c @(#)a0.c  1.4     6/4/85 Berkeley ";
                      2: #include <signal.h>
                      3: #include "apl.h"
                      4: #include <math.h>
                      5: int    chartab[];
                      6: int mkcore  =   0;      /* produce core image upon fatal error */
                      7: int edmagic  =  0;      /* turn on "ed" magic characters */
                      8: 
                      9: main(argc, argp)
                     10: char **argp;
                     11: {
                     12:        register char *p;
                     13:        register a, b;
                     14:        int c;
                     15:        int fflag;
                     16:        int intr(), intprws();
                     17:        extern headline[];
                     18: #ifdef NBUF
                     19:        struct iobuf iobf[NBUF];        /* Actual buffers */
                     20: #endif
                     21: 
                     22:        time(&stime);
                     23: #ifdef NBUF
                     24:        iobuf = iobf;                   /* Set up buffer pointer */
                     25:        initbuf();                      /* Set up to run */
                     26: #endif
                     27:        /*
                     28:         * setup scratch files 
                     29:         */
                     30:        a = getpid();
                     31:        scr_file = "/tmp/apled.000000";
                     32:        ws_file =  "/tmp/aplws.000000";
                     33:        for(c=16; c > 10; c--){
                     34:                b = '0' + a%10;
                     35:                scr_file[c] = b;
                     36:                ws_file[c] = b;
                     37:                a /= 10;
                     38:        }
                     39:        offexit = isatty(0);
                     40:        echoflg = !offexit;
                     41:        a = 1;                  /* catch signals */
                     42: 
                     43:        /* Check to see if argp[0] is "prws".  If so, set prwsflg */
                     44: 
                     45:        for(p=argp[0]; *p; p++);
                     46:        while(p > argp[0] && *p != '/') p--;
                     47:        if (*p == '/') p++;
                     48:        for(c=0; c < 4; c++)
                     49:                if (!p[c] || p[c] != "prws"[c])
                     50:                        goto notprws;
                     51:        prwsflg = 1;
                     52:        CLOSEF(0);
                     53: notprws:
                     54: 
                     55:        /* other flags... */
                     56: 
                     57:        while(argc > 1 && argp[1][0] == '-'){
                     58:                argc--;
                     59:                argp++;
                     60:                while(*++*argp) switch(**argp){
                     61:                case 'e':       echoflg = 1;    break;
                     62:                case 'q':       echoflg = 0;    break;
                     63:                case 'd':
                     64:                case 'D':       a = 0;
                     65:                case 'c':
                     66:                case 'C':       mkcore = 1;     break;
                     67:                case 't':       scr_file  += 5;
                     68:                                ws_file += 5;
                     69:                case 'm':       apl_term = 1;   break;
                     70:                case 'r':       edmagic = 1;    break;
                     71:                case 'o':       offexit = 0;    break;
                     72:                }
                     73:        }
                     74: 
                     75:        if (prwsflg)
                     76:                echoflg = mkcore = a = 0;       /* "prws" settings */
                     77: 
                     78:        thread.iorg = 1;
                     79:        srand(thread.rl = 1);
                     80:        thread.width = 72;
                     81:        thread.digits = 9;
                     82:        thread.fuzz = 1.0e-13;
                     83: 
                     84:        aplmod(1);              /* Turn on APL mode */
                     85:        if (a)
                     86:                catchsigs();
                     87:        if (prwsflg)
                     88:                signal(SIGINT, intprws);
                     89:        else
                     90:                fppinit();
                     91: 
                     92:        /*
                     93:         * open ws file
                     94:         */
                     95: 
                     96:        CLOSEF(opn(WSFILE,0600));
                     97:        wfile = opn(WSFILE,2);
                     98:        zero = 0;
                     99:        one = 1;
                    100:        maxexp = 88;
                    101:        pi = 3.141592653589793238462643383;
                    102: 
                    103:        sp = stack;
                    104:        fflag = 1;
                    105:        if (!prwsflg){
                    106:                if((unsigned)signal(SIGINT, intr) & 01)
                    107:                        signal(SIGINT, 1);
                    108:                printf(headline);
                    109:        }
                    110:        setexit();
                    111:        if(fflag) {
                    112:                fflag = 0;
                    113:                if(argc > 1 && (a = opn(argp[1], 0)) > 0){
                    114:                        wsload(a);
                    115:                        printf(" %s\n", argp[1]);
                    116:                        CLOSEF(a);
                    117:                } else {
                    118:                        if((a=OPENF("continue",0)) < 0) {
                    119:                                printf("clear ws\n");
                    120:                        } else {
                    121:                                wsload(a);
                    122:                                printf(" continue\n");
                    123:                                CLOSEF(a);
                    124:                        }
                    125:                }
                    126:                if (prwsflg){
                    127:                        ex_prws();
                    128:                        term(0);
                    129:                }
                    130:                evLlx();        /* eval latent expr, if any */
                    131:        }
                    132:        mainloop();
                    133: }
                    134: 
                    135: mainloop()
                    136: {
                    137:        register char *a, *comp;
                    138:        static eotcount = MAXEOT;       /* maximum eot's on input */
                    139: 
                    140:        setexit();
                    141:        while(1){
                    142:                if(echoflg)
                    143:                        echoflg = 1;    /* enabled echo echo suppress off */
                    144:                checksp();
                    145:                if(intflg)
                    146:                        error("I");
                    147:                putchar('\t');
                    148:                a = rline(8);
                    149:                if(a == 0) {
                    150:                        offexit &= isatty(0);
                    151:                        if (offexit) {
                    152:                                if (eotcount-- > 0)
                    153:                                        printf("\ruse \')off\' to exit\n");
                    154:                                else
                    155:                                        panic(0);
                    156:                                continue;
                    157:                        } else
                    158:                                term(0);        /* close down and exit */
                    159:                }
                    160:                comp = compile(a, 0);
                    161:                free(a);
                    162:                if(comp == 0)
                    163:                        continue;
                    164:                execute(comp);
                    165:                free(comp);
                    166:                /* note that if the execute errors out, then
                    167:                 * the allocated space pointed to by comp is never
                    168:                 * freed.  This is hard to fix.
                    169:                 */
                    170:        }
                    171: }
                    172: 
                    173: intr()
                    174: {
                    175: 
                    176:        intflg = 1;
                    177:        signal(SIGINT, intr);
                    178:        SEEKF(0, 0L, 2);
                    179: }
                    180: 
                    181: intprws()
                    182: {
                    183:        /* "prws" interrupt -- restore old tty modes and exit */
                    184: 
                    185:        term(0177);
                    186: }
                    187: 
                    188: char *
                    189: rline(s)
                    190: {
                    191:        int rlcmp();
                    192:        char line[CANBS];
                    193:        register char *p;
                    194:        register c, col;
                    195:        char *cp, *retval;
                    196:        char *dp;
                    197:        int i,j;
                    198: 
                    199:        column = 0;
                    200:        col = s;
                    201:        p = line;
                    202: loop:
                    203:        c = getchar();
                    204:        if(intflg)
                    205:                error("I");
                    206:        switch(c) {
                    207: 
                    208:        case '\0':
                    209:        case -1:
                    210:                return(0);
                    211: 
                    212:        case '\b':
                    213:                if(col)
                    214:                        col--;
                    215:                goto loop;
                    216: 
                    217:        case '\t':
                    218:                col = (col+8) & ~7;
                    219:                goto loop;
                    220: 
                    221:        case ' ':
                    222:                col++;
                    223:                goto loop;
                    224: 
                    225:        case '\r':
                    226:                col = 0;
                    227:                goto loop;
                    228: 
                    229:        default:
                    230:                if (p >= line+CANBS-2 || col > 127)
                    231:                        error("line too long");
                    232:                *p++ = col;
                    233:                *p++ = c;       /* was and'ed with 0177... */
                    234:                col++;
                    235:                goto loop;
                    236: 
                    237:        case '\n':
                    238:                ;
                    239:        }
                    240:        qsort(line, (p-line)/2, 2, rlcmp);
                    241:        c = p[-2];
                    242:        if(p == line)
                    243:                c = 1;  /* check for blank line */
                    244:        *p = -1;
                    245:        col = -1;
                    246:        cp = (retval=alloc(c+3)) - 1;
                    247:        for(p=line; p[0] != -1; p+=2) {
                    248:                while(++col != p[0])
                    249:                        *++cp = ' ';
                    250:                *++cp = p[1];
                    251:                while(p[2] == col) {
                    252:                        if(p[3] != *cp) {
                    253:                                i = *cp ;
                    254:                                *cp = p[3];
                    255:                                break;
                    256:                        }
                    257:                        p += 2;
                    258:                }
                    259:                if(p[2] != col) continue;
                    260:                while(p[2] == col) {
                    261:                        if(p[3] != *cp)
                    262:                                goto yuck;
                    263:                        p += 2;
                    264:                }
                    265: #ifdef vax
                    266:                i = ((i<<8) | *cp)&0177777;
                    267: #else
                    268:                i |= *cp << 8;
                    269: #endif
                    270:                for(j=0; chartab[j]; j++){
                    271:                        if(i == chartab[j]) {
                    272:                                *cp = j | 0200;
                    273:                                j = 0;
                    274:                                break;
                    275:                        }
                    276:                }
                    277:                if(j) {
                    278: yuck:
                    279:                        *cp = '\n';
                    280:                        pline(cp,++col);
                    281:                        error("Y error");
                    282:                }
                    283:        }
                    284:        *++cp = '\n';
                    285:        return(retval);
                    286: }
                    287: 
                    288: rlcmp(a, b)
                    289: char *a, *b;
                    290: {
                    291:        register c;
                    292: 
                    293:        if(c = a[0] - b[0])
                    294:                return(c);
                    295:        return(a[1] - b[1]);
                    296: }
                    297: 
                    298: pline(str, loc)
                    299: char *str;
                    300: {
                    301:        register c, l, col;
                    302: 
                    303:        col = 0;
                    304:        l = 0;
                    305:        do {
                    306:                c = *str++;
                    307:                l++;
                    308:                if(l == loc)
                    309:                        col = column;
                    310:                putchar(c);
                    311:        } while(c != '\n');
                    312:        if(col) {
                    313:                putto(col);
                    314:                putchar('^');
                    315:                putchar('\n');
                    316:        }
                    317: }
                    318: 
                    319: putto(col)
                    320: {
                    321:        while(col > column+8)
                    322:                putchar('\t');
                    323:        while(col > column)
                    324:                putchar(' ');
                    325: }
                    326: 
                    327: term(s)
                    328: {
                    329: 
                    330:        register j;
                    331: 
                    332:        unlink(WSFILE);
                    333:        unlink(scr_file);
                    334:        putchar('\n');
                    335:        aplmod(0);                      /* turn off APL mode */
                    336:        for(j=0; j<NFDS; j++)           /* Close files */
                    337:                CLOSEF(j);
                    338:        exit(s);
                    339: }
                    340: 
                    341: fix(d)
                    342: data d;
                    343: {
                    344:        register i;
                    345: 
                    346:        i = floor(d+0.5);
                    347:        return(i);
                    348: }
                    349: 
                    350: fuzz(d1, d2)
                    351: data d1, d2;
                    352: {
                    353:        double f1, f2;
                    354: 
                    355:        f1 = d1;
                    356:        if(f1 < 0.)
                    357:                f1 = -f1;
                    358:        f2 = d2;
                    359:        if(f2 < 0.)
                    360:                f2 = -f2;
                    361:        if(f2 > f1)
                    362:                f1 = f2;
                    363:        f1 *= thread.fuzz;
                    364:        if(d1 > d2) {
                    365:                if(d2+f1 >= d1)
                    366:                        return(0);
                    367:                return(1);
                    368:        }
                    369:        if(d1+f1 >= d2)
                    370:                return(0);
                    371:        return(-1);
                    372: }
                    373: 
                    374: pop()
                    375: {
                    376: 
                    377:        if(sp <= stack)
                    378:                error("pop B");
                    379:        dealloc(*--sp);
                    380: }
                    381: 
                    382: erase(np)
                    383: struct nlist *np;
                    384: {
                    385:        register *p;
                    386: 
                    387:        p = np->itemp;
                    388:        if(p) {
                    389:                switch(np->use) {
                    390:                case NF:
                    391:                case MF:
                    392:                case DF:
                    393:                        for(; *p>0; (*p)--)
                    394:                                free(p[*p]);
                    395: 
                    396:                }
                    397:                free(p);
                    398:                np->itemp = 0;
                    399:        }
                    400:        np->use = 0;
                    401: }
                    402: 
                    403: dealloc(p)
                    404: struct item *p;
                    405: {
                    406: 
                    407:        switch(p->type) {
                    408:        default:
                    409:                printf("[dealloc botch: %d]\n", p->type);
                    410:                return;
                    411:        case LBL:
                    412:                ((struct nlist *)p)->use = 0;     /* delete label */
                    413:        case LV:
                    414:                return;
                    415: 
                    416:        case DA:
                    417:        case CH:
                    418:        case QQ:
                    419:        case QD:
                    420:        case QC:
                    421:        case EL:
                    422:        case DU:
                    423:        case QX:
                    424:                free(p);
                    425:        }
                    426: }
                    427: 
                    428: struct item *
                    429: newdat(type, rank, size)
                    430: {
                    431:        register i;
                    432:        register struct item *p;
                    433: 
                    434:        /* Allocate a new data item.  I have searched the specifications
                    435:         * for C and as far as I can tell, it should be legal to
                    436:         * declare a zero-length array inside a structure.  However,
                    437:         * the VAX C compiler (which I think is a derivative of the
                    438:         * portable C compiler) does not allow this.  The Ritchie
                    439:         * V7 PDP-11 compiler does.  I have redeclared "dim" to
                    440:         * contain MRANK elements.  When the data is allocated,
                    441:         * space is only allocated for as many dimensions as there
                    442:         * actually are.  Thus, if there are 0 dimensions, no space
                    443:         * will be allocated for "dim".  This had better make the
                    444:         * VAX happy, since it has sure made me unhappy.
                    445:         *
                    446:         * --John Bruner
                    447:         */
                    448: 
                    449: 
                    450:        if(rank > MRANK)
                    451:                error("max R");
                    452:        i = sizeof *p - SINT * (MRANK-rank);
                    453:        if(type == DA)
                    454:                i += size * SDAT; else
                    455:        if(type == CH)
                    456:                i += size;
                    457:        p = alloc(i);
                    458:        p->rank = rank;
                    459:        p->type = type;
                    460:        p->size = size;
                    461:        p->index = 0;
                    462:        if(rank == 1)
                    463:                p->dim[0] = size;
                    464:        p->datap = (data *)&p->dim[rank];
                    465:        return(p);
                    466: }
                    467: 
                    468: struct item *
                    469: dupdat(ap)
                    470: struct item *ap;
                    471: {
                    472:        register struct item *p1, *p2;
                    473:        register i;
                    474: 
                    475:        p1 = ap;
                    476:        p2 = newdat(p1->type, p1->rank, p1->size);
                    477:        for(i=0; i<p1->rank; i++)
                    478:                p2->dim[i] = p1->dim[i];
                    479:        copy(p1->type, p1->datap, p2->datap, p1->size);
                    480:        return(p2);
                    481: }
                    482: 
                    483: copy(type, from, to, size)
                    484: char *from, *to;
                    485: {
                    486:        register i;
                    487:        register char *a, *b;
                    488:        int s;
                    489: 
                    490:        if((i = size) == 0)
                    491:                return(0);
                    492:        a = from;
                    493:        b = to;
                    494:        if(type == DA)
                    495:                i *= SDAT; else
                    496:        if(type == IN)
                    497:                i *= SINT;
                    498:        s = i;
                    499:        do
                    500:                *b++ = *a++;
                    501:        while(--i);
                    502:        return(s);
                    503: }
                    504: 
                    505: struct item *
                    506: fetch1()
                    507: {
                    508:        register struct item *p;
                    509: 
                    510:        p = fetch(sp[-1]);
                    511:        sp[-1] = p;
                    512:        return(p);
                    513: }
                    514: 
                    515: struct item *
                    516: fetch2()
                    517: {
                    518:        register struct item *p;
                    519: 
                    520:        sp[-2] = fetch(sp[-2]);
                    521:        p = fetch(sp[-1]);
                    522:        sp[-1] = p;
                    523:        return(p);
                    524: }
                    525: 
                    526: struct item *
                    527: fetch(ip)
                    528: struct item *ip;
                    529: {
                    530:        register struct item *p, *q;
                    531:        register i;
                    532:        struct nlist *n;
                    533:        int c;
                    534:        struct chrstrct *cc;
                    535:        extern prolgerr;
                    536: 
                    537:        p = ip;
                    538: 
                    539: loop:
                    540:        switch(p->type) {
                    541: 
                    542:        case QX:
                    543:                free(p);
                    544:                n = nlook("Llx");
                    545:                if(n){
                    546:                        q = n->itemp;
                    547:                        p = dupdat(q);
                    548:                        copy(q->type, q->datap, p->datap, q->size);
                    549:                } else
                    550:                        p = newdat(CH, 1, 0);
                    551:                goto loop;
                    552: 
                    553:        case QQ:
                    554:                free(p);
                    555:                cc = rline(0);
                    556:                if(cc == 0)
                    557:                        error("eof");
                    558:                for(i=0; cc->c[i] != '\n'; i++)
                    559:                        ;
                    560:                p = newdat(CH, 1, i);
                    561:                copy(CH, cc, p->datap, i);
                    562:                goto loop;
                    563: 
                    564:        case QD:
                    565:        case QC:
                    566:                printf("L:\n\t");
                    567:                i = rline(8);
                    568:                if(i == 0)
                    569:                        error("eof");
                    570:                c = compile(i, 1);
                    571:                free(i);
                    572:                if(c == 0)
                    573:                        goto loop;
                    574:                i = pcp;
                    575:                execute(c);
                    576:                pcp = i;
                    577:                free(c);
                    578:                free(p);
                    579:                p = *--sp;
                    580:                goto loop;
                    581: 
                    582:        case DU:
                    583:                if(lastop != PRINT)
                    584:                        error("no fn result");
                    585: 
                    586:        case DA:
                    587:        case CH:
                    588:                p->index = 0;
                    589:                return(p);
                    590: 
                    591:        case LV:
                    592: 
                    593:                /* KLUDGE --
                    594:                 *
                    595:                 * Currently, if something prevents APL from completing
                    596:                 * execution of line 0 of a function, it leaves with
                    597:                 * the stack in an unknown state and "gsip->oldsp" is
                    598:                 * zero.  This is nasty because there is no way to
                    599:                 * reset out of it.  The principle cause of error
                    600:                 * exits from line 0 is the fetch of an undefined
                    601:                 * function argument.  The following code attempts
                    602:                 * to fix this by setting an error flag and creating
                    603:                 * a dummy variable for the stack if "used before set"
                    604:                 * occurs in the function header.  "ex_fun" then will
                    605:                 * note that the flag is high and cause an error exit
                    606:                 * AFTER all header processing has been completed.
                    607:                 */
                    608: 
                    609:                if(((struct nlist *)p)->use != DA){
                    610:                                printf("%s: used before set",
                    611:                                        ((struct nlist *)ip)->namep);
                    612:                        if ((!gsip) || gsip->funlc != 1)
                    613:                                error("");
                    614:                        q = newdat(DA, 0, 1);           /* Dummy */
                    615:                        q->datap[0] = 0;
                    616:                        prolgerr = 1;                   /* ERROR flag */
                    617:                        return(q);
                    618:                }
                    619:                p = ((struct nlist *)p)->itemp;
                    620:                i = p->type;
                    621:                if(i == LBL)
                    622:                        i = DA;         /* treat label as data */
                    623:                q = newdat(i, p->rank, p->size);
                    624:                copy(IN, p->dim, q->dim, p->rank);
                    625:                copy(i, p->datap, q->datap, p->size);
                    626:                return(q);
                    627: 
                    628:        default:
                    629:                error("fetch B");
                    630:        }
                    631: }
                    632: 
                    633: topfix()
                    634: {
                    635:        register struct item *p;
                    636:        register i;
                    637: 
                    638:        p = fetch1();
                    639:        if(p->type != DA || p->size != 1)
                    640:                error("topval C");
                    641:        i = fix(p->datap[0]);
                    642:        pop();
                    643:        return(i);
                    644: }
                    645: 
                    646: bidx(ip)
                    647: struct item *ip;
                    648: {
                    649:        register struct item *p;
                    650: 
                    651:        p = ip;
                    652:        idx.type = p->type;
                    653:        idx.rank = p->rank;
                    654:        copy(IN, p->dim, idx.dim, idx.rank);
                    655:        size();
                    656: }
                    657: 
                    658: size()
                    659: {
                    660:        register i, s;
                    661: 
                    662:        s = 1;
                    663:        for(i=idx.rank-1; i>=0; i--) {
                    664:                idx.del[i] = s;
                    665:                s *= idx.dim[i];
                    666:        }
                    667:        idx.size = s;
                    668:        return(s);
                    669: }
                    670: 
                    671: colapse(k)
                    672: {
                    673:        register i;
                    674: 
                    675:        if(k < 0 || k >= idx.rank)
                    676:                error("collapse X");
                    677:        idx.dimk = idx.dim[k];
                    678:        idx.delk = idx.del[k];
                    679:        for(i=k; i<idx.rank; i++) {
                    680:                idx.del[i] = idx.del[i+1];
                    681:                idx.dim[i] = idx.dim[i+1];
                    682:        }
                    683:        if (idx.dimk)
                    684:                idx.size /= idx.dimk;
                    685:        idx.rank--;
                    686: }
                    687: 
                    688: forloop(co, arg)
                    689: int (*co)();
                    690: {
                    691:        register i;
                    692: 
                    693:        if (idx.size == 0)
                    694:                return;         /* for null items */
                    695:        if(idx.rank == 0) {
                    696:                (*co)(arg);
                    697:                return;
                    698:        }
                    699:        for(i=0;;) {
                    700:                while(i < idx.rank)
                    701:                        idx.idx[i++] = 0;
                    702:                (*co)(arg);
                    703:                while(++idx.idx[i-1] >= idx.dim[i-1])
                    704:                        if(--i <= 0)
                    705:                                return;
                    706:        }
                    707: }
                    708: 
                    709: access()
                    710: {
                    711:        register i, n;
                    712: 
                    713:        n = 0;
                    714:        for(i=0; i<idx.rank; i++)
                    715:                n += idx.idx[i] * idx.del[i];
                    716:        return(n);
                    717: }
                    718: 
                    719: data
                    720: getdat(ip)
                    721: struct item *ip;
                    722: {
                    723:        register struct item *p;
                    724:        register i;
                    725:        data d;
                    726: 
                    727:        /* Get the data value stored at index p->index.  If the
                    728:         * index is out of range it will be wrapped around.  If
                    729:         * the data item is null, a zero or blank will be returned.
                    730:         */
                    731: 
                    732:        p = ip;
                    733:        i = p->index;
                    734:        while(i >= p->size) {
                    735:                if (p->size == 0)       /* let the caller beware */
                    736:                        return((p->type == DA) ? zero : (data)' ');
                    737:                /*
                    738:                if (i == 0)
                    739:                        error("getdat B");
                    740:                 */
                    741:                i -= p->size;
                    742:        }
                    743:        if(p->type == DA) {
                    744:                d = p->datap[i];
                    745:        } else
                    746:        if(p->type == CH) {
                    747:                d = ((struct chrstrct *)p->datap)->c[i];
                    748:        } else
                    749:                error("getdat B");
                    750:        i++;
                    751:        p->index = i;
                    752:        return(d);
                    753: }
                    754: 
                    755: putdat(ip, d)
                    756: data d;
                    757: struct item *ip;
                    758: {
                    759:        register struct item *p;
                    760:        register i;
                    761: 
                    762:        p = ip;
                    763:        i = p->index;
                    764:        if(i >= p->size)
                    765:                error("putdat B");
                    766:        if(p->type == DA) {
                    767:                p->datap[i] = d;
                    768:        } else
                    769:        if(p->type == CH) {
                    770:                ((struct chrstrct *)p->datap)->c[i] = d;
                    771:        } else
                    772:                error("putdat B");
                    773:        i++;
                    774:        p->index = i;
                    775: }
                    776: 
                    777: /* aplmod has been moved to am.c */
                    778: 
                    779: struct item *
                    780: s2vect(ap)
                    781: struct item *ap;
                    782: {
                    783:        register struct item *p, *q;
                    784: 
                    785:        p = ap;
                    786:        q = newdat(p->type, 1, 1);
                    787:        q->datap = p->datap;
                    788:        q->dim[0] = 1;
                    789:        return(q);
                    790: }
                    791: 
                    792: struct nlist *
                    793: nlook(name)
                    794: char *name;
                    795: {
                    796:        register struct nlist *np;
                    797: 
                    798:        for(np = nlist; np->namep; np++)
                    799:                if(equal(np->namep, name))
                    800:                        return(np);
                    801:        return(0);
                    802: }
                    803: 
                    804: checksp()
                    805: {
                    806:        if(sp >= &stack[STKS])
                    807:                error("stack overflow");
                    808: }
                    809: char *
                    810: concat(s1,s2)
                    811: char *s1, *s2;
                    812: {
                    813:        register i,j;
                    814:        char *p,*q;
                    815: 
                    816:        i = lsize(s1) - 1;
                    817:        j = lsize(s2) - 1;
                    818:        p = q = alloc(i+j);
                    819:        p += copy(CH, s1, p, i);
                    820:        copy(CH, s2, p, j);
                    821:        return(q);
                    822: }
                    823: 
                    824: char *
                    825: catcode(s1,s2)
                    826: char *s1, *s2;
                    827: {
                    828:        register i,j;
                    829:        char *p,*q;
                    830: 
                    831:        i = csize(s1) - 1;
                    832:        j = csize(s2);
                    833:        p = q = alloc(i+j);
                    834:        p += copy(CH, s1, p, i);
                    835:        copy(CH, s2, p, j);
                    836:        return(q);
                    837: }
                    838: 
                    839: /*
                    840:  * csize -- return size (in bytes) of a compiled string
                    841:  */
                    842: csize(s)
                    843: char *s;
                    844: {
                    845:        register c,len;
                    846:        register char *p;
                    847:        int i;
                    848: 
                    849:        len = 1;
                    850:        p = s;
                    851:        while((c = *p++) != EOF){
                    852:                len++;
                    853:                c &= 0377;
                    854:                switch(c){
                    855:                default:
                    856:                        i = 0;
                    857:                        break;
                    858: 
                    859:                case QUOT:
                    860:                        i = *p++;
                    861:                        break;
                    862: 
                    863:                case CONST:
                    864:                        i = *p++;
                    865:                        i *= SDAT;
                    866:                        len++;
                    867:                        break;
                    868: 
                    869:                case NAME:
                    870:                case FUN:
                    871:                case ARG1:
                    872:                case ARG2:
                    873:                case AUTO:
                    874:                case REST:
                    875:                case RVAL:
                    876:                        i = 2;
                    877:                        break;
                    878:                }
                    879:                p += i;
                    880:                len += i;
                    881:        }
                    882:        return(len);
                    883: }
                    884: 
                    885: opn(file, rw)
                    886: char file[];
                    887: {
                    888:        register fd, (*p)();
                    889:        char f2[100];
                    890:        extern OPENF(), CREATF();
                    891: 
                    892:        p = (rw > 2 ? CREATF : OPENF);
                    893:        if((fd = (*p)(file,rw)) < 0){
                    894:                for(fd=0; fd<13; fd++)
                    895:                        f2[fd] = LIBDIR[fd];
                    896:                for(fd=0; file[fd]; fd++)
                    897:                        f2[fd+13] = file[fd];
                    898:                f2[fd+13] = 0;
                    899:                if((fd = (*p)(f2, rw)) >= 0){
                    900:                        printf("[using %s]\n", f2);
                    901:                        return(fd);
                    902:                }
                    903:                printf("can't open file %s\n", file);
                    904:                error("");
                    905:        }
                    906:        return(fd);
                    907: }
                    908: 
                    909: catchsigs()
                    910: {
                    911:        extern panic();
                    912: 
                    913:        signal(SIGHUP, panic);
                    914:        signal(SIGQUIT, panic);
                    915:        signal(SIGILL, panic);
                    916:        signal(SIGTRAP, panic);
                    917:        signal(SIGEMT, panic);
                    918: /*     signal(SIGFPE, fpe);            /* (fppinit called by "main") */
                    919:        signal(SIGBUS, panic);
                    920:        signal(SIGSEGV, panic);
                    921:        signal(SIGSYS, panic);
                    922:        signal(SIGPIPE, panic);
                    923:        signal(SIGTERM, panic);
                    924: }
                    925: 
                    926: panic(signum)
                    927: unsigned signum;
                    928: {
                    929: 
                    930:        register fd;
                    931:        static insane = 0;                      /* if != 0, die */
                    932:        static char *abt_file = "aplws.abort";
                    933:        static char *errtbl[] = {
                    934:                "excessive eofs",
                    935:                "hangup",
                    936:                "interrupt",
                    937:                "quit",
                    938:                "illegal instruction",
                    939:                "trace trap",
                    940:                "i/o trap instruction",
                    941:                "emt trap",
                    942:                "floating exception",
                    943:                "kill",
                    944:                "bus error",
                    945:                "segmentation violation",
                    946:                "bad system call",
                    947:                "write no pipe",
                    948:                "alarm clock",
                    949:                "software termination"
                    950:        };
                    951: 
                    952:        /* Attempt to save workspace.  A signal out of here always
                    953:         * causes immediate death.
                    954:         */
                    955: 
                    956:        mencflg = 0;
                    957:        signal(signum, panic);
                    958:        printf("\nfatal signal: %s\n",
                    959:            errtbl[(signum < NSIG) ? signum : 0]);
                    960: 
                    961:        if (mkcore) abort();
                    962: 
                    963:        if (!insane++){
                    964:                if ((fd=CREATF(abt_file, 0644)) >= 0){
                    965:                        printf("[attempting ws dump]\n");
                    966:                        wssave(fd);
                    967:                        printf(" workspace saved in %s\n", abt_file);
                    968:                        CLOSEF(fd);
                    969:                } else
                    970:                        printf("workspace lost -- sorry\n");
                    971:        } else
                    972:                printf("recursive errors: unrecoverable\n");
                    973: 
                    974:        term(0);
                    975: }
                    976: #ifdef vax
                    977: abort(){
                    978:        kill(getpid(), SIGIOT);
                    979:        exit(1);
                    980: }
                    981: #endif

unix.superglobalmegacorp.com

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