Annotation of 3BSD/cmd/lisp/io.c, revision 1.1.1.1

1.1       root        1: #include "global.h"
                      2: #include <stdio.h>
                      3: #include <ctype.h>
                      4: #include "chars.h"
                      5: 
                      6: struct readtable {
                      7: char   ctable[132];
                      8: } initread = {
                      9: /*     ^@ nul  ^A soh  ^B stx  ^C etx  ^D eot  ^E eng  ^F ack  ^G bel  */
                     10:        VERR,   VERR,   VERR,   VERR,   VERR,   VERR,   VERR,   VERR,
                     11: /*     ^H bs   ^I ht   ^J nl   ^K vt   ^L np   ^M cr   ^N so   ^O si   */
                     12:        VCHAR,  VSEP,   VSEP,   VSEP,   VSEP,   VSEP,   VERR,   VERR,
                     13: /*     ^P dle  ^Q dc1  ^R dc2  ^S dc3  ^T dc4  ^U nak  ^V syn  ^W etb  */
                     14:        VERR,   VERR,   VERR,   VERR,   VERR,   VERR,   VERR,   VERR,
                     15: /*     ^X can  ^Y em   ^Z sub  ^[ esc  ^\ fs   ^] gs   ^^ rs   ^_ us   */
                     16:        VERR,   VERR,   VERR,   VSEP,   VERR,   VERR,   VERR,   VERR,
                     17: /*     sp      !       "       #       $       %       &       '       */
                     18:        VSEP,   VCHAR,  VDQ,    VCHAR,  VCHAR,  VCHAR,  VCHAR,  VSQ,
                     19: /*     (       )       *       +       ,       -       .       /       */
                     20:        VLPARA, VRPARA, VCHAR,  VSIGN,  VCHAR,  VSIGN,  VPERD,  VCHAR,
                     21: /*     0       1       2       3       4       5       6       7       */
                     22:        VNUM,   VNUM,   VNUM,   VNUM,   VNUM,   VNUM,   VNUM,   VNUM,
                     23: /*     8       9       :       ;       <       =       >       ?       */
                     24:        VNUM,   VNUM,   VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     25: /*     @       A       B       C       D       E       F       G       */
                     26:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     27: /*     H       I       J       K       L       M       N       O       */
                     28:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     29: /*     P       Q       R       S       T       U       V       W       */
                     30:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     31: /*     X       Y       Z       [       \       ]       ^       _       */
                     32:        VCHAR,  VCHAR,  VCHAR,  VLBRCK, VESC,   VRBRCK, VCHAR,  VCHAR,
                     33: /*     `       a       b       c       d       e       f       g       */
                     34:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     35: /*     h       i       j       k       l       m       n       o       */
                     36:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     37: /*     p       q       r       s       t       u       v       w       */
                     38:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,
                     39: /*     x       y       z       {       |       }       ~       del     */
                     40:        VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VCHAR,  VEOF,
                     41: /*     unused  unused  Xesc    Xdqc                                    */
                     42:        0,      0,      '\\',   '"'
                     43: };
                     44: 
                     45: char *ctable = initread.ctable;
                     46: lispval atomval;       /* external varaible containing atom returned
                     47:                           from internal atom reading routine */
                     48: lispval protect();
                     49: lispval unprotect();
                     50: lispval readrx(); lispval readr(); lispval readry();
                     51: int keywait;
                     52: static int dbqflag;
                     53: static int macflag;
                     54: static int splflag;
                     55: static int mantisfl = 0;
                     56: lispval        lastrtab;       /* external variable designating current reader
                     57:                           table */
                     58: static char baddot1[]=
                     59: "Bad reader construction: (. <something>)\nShould be (nil . <something>)\n";
                     60: static char baddot2[]=
                     61: "Bad reader construction: (<something> .)\n\
                     62: Should be (<something> . <something>), assumed to be (<something>)";
                     63: static char baddot3[]=
                     64: "Bad reader construction: (<something> . <something> not followed by )";
                     65: 
                     66: #include "chkrtab.h"
                     67: /* readr ****************************************************************/
                     68: /* returns a s-expression read in from the port specified as the first */
                     69: /* argument.  Handles superbrackets, reader macros.                    */
                     70: lispval
                     71: readr(useport)
                     72: FILE *useport;
                     73: {
                     74:        register lispval handy = Vreadtable->clb;
                     75: 
                     76:        chkrtab(handy);
                     77:        rbktf = FALSE;
                     78:        rdrport = (FILE *) useport;
                     79:        if(useport==stdin)
                     80:                keywait = TRUE; 
                     81:        handy = readrx(Iratom());
                     82:        if(useport==stdin)
                     83:                keywait = FALSE;
                     84:        return(handy);
                     85: 
                     86: }
                     87: 
                     88: 
                     89: /* readrx **************************************************************/
                     90: /* returns a s-expression beginning with the syntax code of an atom    */
                     91: /* passed in the first */
                     92: /* argument.  Does the actual work for readr, including list, dotted   */
                     93: /* pair, and quoted atom detection                                     */
                     94: lispval
                     95: readrx(code)
                     96: register int code;
                     97: {
                     98:        register lispval work;
                     99:        register lispval *current;
                    100:        register struct argent *result;
                    101:        register struct argent *lbot, *np;
                    102:        int inlbkt = FALSE;
                    103:        lispval errorh();
                    104: 
                    105: top:
                    106:        switch(code)
                    107:        {
                    108:        case TLBKT:
                    109:                inlbkt = TRUE;
                    110:        case TLPARA:
                    111:                result = np;
                    112:                current = (lispval *)np;
                    113:                np++->val = nil; /*protect(nil);*/
                    114:                for(EVER) {
                    115:                        switch(code = Iratom())
                    116:                        {
                    117:                        case TRPARA:
                    118:                                if(rbktf && inlbkt)
                    119:                                        rbktf = FALSE;
                    120:                                return(result->val);
                    121:                        default:
                    122:                                atomval = readrx(code);
                    123:                        case TSCA:
                    124:                                np++->val=atomval;
                    125:                                *current = work = newdot();
                    126:                                work->car = atomval;
                    127:                                np--;
                    128:                                current = (lispval *) &(work->cdr);
                    129:                                break;
                    130:                        case TSPL:
                    131:                                macrox(); /* input and output in atomval */
                    132:                                *current = atomval;
                    133:                                while(*current!=nil) {
                    134:                                        if(TYPE(*current)!=DTPR)
                    135:                                                errorh(Vermisc,"Non-list returned from splicing macro",nil,FALSE,7,*current);
                    136:                                        current=(lispval *)&((*current)->cdr);
                    137:                                }
                    138:                                break;
                    139:                        case TPERD:
                    140:                                if(result->val==nil) {
                    141:                                        work = result->val=newdot();
                    142:                                        current = (lispval *) &(work->cdr);
                    143:                                        fprintf(stderr,baddot1);
                    144:                                }
                    145:                                code = Iratom();
                    146:                                if(code==TRPARA) {
                    147:                                        return(errorh(Vermisc,baddot2,nil,TRUE,58,result->val));
                    148:                                }
                    149:                                *current = readrx(code);
                    150:                                if((code = Iratom())!=TRPARA) {
                    151:                                        errorh(Vermisc,baddot3,nil,TRUE,59,result->val,atomval);
                    152:                                }
                    153:                                if(rbktf && inlbkt)
                    154:                                        rbktf = FALSE;
                    155:                                return(result->val);
                    156:                        case TEOF:
                    157:                                clearerr(rdrport);
                    158:                                error("Premature end of file.", FALSE);
                    159:                        }
                    160:                        if(rbktf) {
                    161:                                if(inlbkt)
                    162:                                        rbktf = FALSE;
                    163:                                return(result->val);
                    164:                        }
                    165:                }
                    166:        case TSCA:
                    167:                return(atomval);
                    168:        case TEOF:
                    169:                return(eofa);
                    170:        case TMAC:
                    171:                macrox();
                    172:                return(atomval);
                    173:        case TSPL:
                    174:                macrox();
                    175:                if((work = atomval)!=nil) {
                    176:                        if(TYPE(work)==DTPR && work->cdr==nil)
                    177:                                return(work->car);
                    178:                        else
                    179:                                errorh(Vermisc,
                    180: "Improper value returned from splicing macro at top-level",nil,FALSE,9,work);
                    181:                }
                    182:                code = Iratom();
                    183:                goto top;
                    184:                /* return(readrx(Iratom())); */
                    185:        case TSQ:
                    186:                result = np;
                    187:                protect(newdot());
                    188:                (work = result->val)->car = quota;
                    189:                work = work->cdr = newdot();
                    190:                work->car = readrx(Iratom());
                    191:                return(result->val);
                    192:        default:
                    193:                return(error("Readlist error",FALSE));
                    194:        }
                    195: }
                    196: macrox()
                    197: {
                    198:        lispval Lapply();
                    199: 
                    200:        snpand(0);
                    201:        lbot = np;
                    202:        protect(Iget(atomval,macro));
                    203:        protect(nil);
                    204:        atomval = Lapply();
                    205:        return;
                    206: }
                    207: 
                    208: 
                    209: 
                    210: /* ratomr ***************************************************************/
                    211: /* this routine returns a pointer to an atom read in from the port given*/
                    212: /* by the first argument                                               */
                    213: lispval
                    214: ratomr(useport)
                    215: register FILE  *useport;
                    216: {
                    217:        rdrport = useport;
                    218:        switch(Iratom())
                    219:        {
                    220:        case TEOF:
                    221:                return(eofa);
                    222:        case TSQ:
                    223:        case TRPARA:
                    224:        case TLPARA:
                    225:        case TLBKT:
                    226:        case TPERD:
                    227:                strbuf[1]=0;
                    228:                return(getatom());
                    229:        default:
                    230:                return(atomval);
                    231:        }
                    232: }
                    233: Iratom()
                    234: {
                    235:        register FILE   *useport = rdrport;
                    236:        register char   c, marker, *name;
                    237:        extern lispval finatom(), calcnum(), getnum();
                    238:        char    positv = TRUE;
                    239:        int code;
                    240:        int strflag = FALSE;
                    241: 
                    242:        name = strbuf;
                    243: 
                    244: again: c = getc(useport) & 0177;
                    245:        *name = c;
                    246: 
                    247:        switch(ctable[c] & 0377) {
                    248: 
                    249:        default:        goto again;
                    250: 
                    251:        case VNUM:
                    252: 
                    253:        case VSIGN:     *name++ = c;
                    254:                        atomval = (getnum(name));
                    255:                        return(TSCA);
                    256: 
                    257:        case VESC:
                    258:                        dbqflag = TRUE;
                    259:                        *name++ = getc(useport) & 0177;
                    260:                        atomval = (finatom(name));
                    261:                        return(TSCA);
                    262:                        
                    263:        case VCHAR:
                    264:                        *name++ = c;
                    265:                        atomval = (finatom(name));
                    266:                        return(TSCA);
                    267: 
                    268:        case VLPARA:    return(TLPARA);
                    269: 
                    270:        case VRPARA:    return(TRPARA);
                    271: 
                    272:        case VPERD:     c = peekc(useport);
                    273:                        if(VNUM!=ctable[c])
                    274:                                return(TPERD);
                    275:                        *name++ = '.';
                    276:                        mantisfl = 1;
                    277:                        atomval = (getnum(name));
                    278:                        return(TSCA);
                    279: 
                    280:        case VLBRCK:    return(TLBKT);
                    281: 
                    282:        case VRBRCK:    rbktf = TRUE;
                    283:                        return(TRPARA);
                    284: 
                    285:        case VEOF:      /*printf("returning eof atom\n");*/
                    286:                        return(TEOF);
                    287: 
                    288:        case VSQ:       return(TSQ);
                    289: 
                    290:        case VSD:       strflag = TRUE;
                    291:        case VDQ:       name = strbuf;
                    292:                        marker = c;
                    293:                        while ((c = getc(useport)) != marker) {
                    294: 
                    295:                                if(VESC==ctable[c]) c = getc(useport);
                    296:                                *name++ = c;
                    297:                                if (name >= endstrb)
                    298:                                        error("ATOM TOO LONG",FALSE);
                    299:                                if (feof(useport)) {
                    300:                                        clearerr(useport);
                    301:                                        error("EOF ecountered while reading atom", FALSE);
                    302:                                }
                    303:                        }
                    304:                        *name = NULL_CHAR;
                    305:                        if(strflag)
                    306:                                atomval = (lispval) inewstr(strbuf);
                    307:                        else
                    308:                                atomval = (getatom(name));
                    309:                        return(TSCA);
                    310: 
                    311:        case VERR:      if (c == '\0') goto same;       /* null pname */
                    312:                        fprintf(stderr,"%c (%o): ",c,(int) c);
                    313:                        error("ILLEGAL CHARACTER IN ATOM",TRUE);
                    314: 
                    315:        case VSPL:
                    316:                code = TSPL;
                    317:                goto same;
                    318:        case VMAC:
                    319:                code = TMAC;
                    320:                goto same;
                    321:        case VSCA:
                    322:                code = TSCA;
                    323:        same:
                    324:                strbuf[0] = c;
                    325:                strbuf[1] = 0;
                    326:                atomval = (getatom());
                    327:                return(code);
                    328:        }
                    329: }
                    330: 
                    331: #define push();        if(name==endstrb) error("Int too long",FALSE); else *name++=c;
                    332: #define next() (stats = ctable[c=getc(useport) & 0177])
                    333: 
                    334: lispval
                    335: getnum(name)
                    336: register char *name;
                    337: {
                    338:        register char c;
                    339:        register lispval result;
                    340:        register FILE *useport=rdrport;
                    341:        char  stats;
                    342:        double realno;
                    343:        extern lispval finatom(), calcnum(), newdoub(), dopow();
                    344: 
                    345:        if(mantisfl) {
                    346:                mantisfl = 0;
                    347:                next();
                    348:                goto mantissa;
                    349:        }
                    350:        while(VNUM==next()) {
                    351:                push();         /* recognize [0-9]*, in "ex" parlance */
                    352:        }
                    353:        if(stats==VPERD) {
                    354:                push();         /* continue */ 
                    355:        } else if(stats & SEPMASK) {
                    356:                ungetc(c,useport);
                    357:                return(calcnum(strbuf,name,ibase->clb->i));
                    358:        } else if(c=='^') {
                    359:                push();
                    360:                return(dopow(name,ibase->clb->i));
                    361:        } else if(c=='_') {
                    362:                push();
                    363:                return(dopow(name,2));
                    364:        } else{
                    365:                ungetc(c,useport);
                    366:                return(finatom(name));
                    367:        }
                    368:                                /* at this point we have [0-9]*\. , which might
                    369:                                   be a decimal int or the leading part of a
                    370:                                   float                                */
                    371:        if(next()!=VNUM) {
                    372:                if(c=='e' || c=='E' || c=='d' ||c=='D')
                    373:                        goto expt;
                    374:                else if(c=='^') {
                    375:                        push();
                    376:                        return(dopow(name,ibase->clb->i));
                    377:                } else if(c=='_') {
                    378:                        push();
                    379:                        return(dopow(name,2));
                    380:                } else {
                    381:                                /* Here we have 1.x where x not num, not sep */
                    382:                                /* Here we have decimal int. NOT FORTRAN! */
                    383:                        ungetc(c,useport);
                    384:                        return(calcnum(strbuf,name-1,10));
                    385:                }
                    386:        }
                    387: mantissa:
                    388:        do {
                    389:                push();
                    390:        } while (VNUM==next());
                    391:                                /* Here we have [0-9]*\.[0-9]* */
                    392:        if(stats & SEPMASK)
                    393:                goto last;
                    394:        else if(c!='e' && c!='E' && c!='d' && c!='D') {
                    395:                ungetc(c,useport);
                    396:                goto verylast;
                    397:        }
                    398: expt:  push();
                    399:        next();
                    400:        if(c=='+' || c =='-') {
                    401:                push();
                    402:                next();
                    403:        }
                    404:        while (VNUM==stats) {
                    405:                push();
                    406:                next();
                    407:        }
                    408: last:  ungetc(c,useport);
                    409:        if(! (stats & SEPMASK) )
                    410:                return(finatom(name));
                    411: 
                    412: verylast:
                    413:        *name=0;
                    414:        sscanf(strbuf,"%F",&realno);
                    415:        (result = newdoub())->r = realno;
                    416:        return(result);
                    417: }
                    418: 
                    419: lispval
                    420: dopow(part2,base)
                    421: lispval base;
                    422: char *part2;
                    423: {
                    424:        register char *name = part2;
                    425:        register char c;
                    426:        register FILE *useport = rdrport;
                    427:        register int power;
                    428:        register struct argent *lbot, *np;
                    429:        char stats;
                    430:        char *end1 = part2 - 1; lispval Ltimes();
                    431: 
                    432:        while(VNUM==next()) {
                    433:                push();
                    434:        }
                    435:        if(c!='.') {
                    436:                ungetc(c,useport);
                    437:        }
                    438:        if(c!='.' && !(stats & SEPMASK)) {
                    439:                return(finatom(name));
                    440:        }
                    441:        lbot = np;
                    442:        np++->val = inewint(base);
                    443:        /* calculate "mantissa"*/
                    444:        if(*end1=='.')
                    445:                np++->val = calcnum(strbuf,end1-1,10);
                    446:        else
                    447:                np++->val = calcnum(strbuf,end1,ibase->clb->i);
                    448: 
                    449:        /* calculate exponent */
                    450:        if(c=='.')
                    451:                power = calcnum(part2,name,10)->i;
                    452:        else
                    453:                power = calcnum(part2,name,ibase->clb->i)->i;
                    454:        while(power-- > 0)
                    455:                lbot[1].val = Ltimes();
                    456:        return(lbot[1].val);
                    457: }
                    458:        
                    459: 
                    460: lispval
                    461: calcnum(strbuf,name,base)
                    462: char *name;
                    463: char *strbuf;
                    464: {
                    465:        register char *p;
                    466:        register lispval result, temp;
                    467:        int negflag = 0;
                    468: 
                    469:        temp = rdrsdot;                 /* initialize sdot cell */
                    470:        temp->CDR = nil;
                    471:        temp->i   = 0;
                    472:        p = strbuf;
                    473:        if(*p=='+') p++;
                    474:        else if(*p=='-') {negflag = 1; p++;}
                    475:        *name = 0;
                    476:        if(p>=name) return(getatom());
                    477: 
                    478:        for(;p < name; p++)
                    479:                dmlad(temp,base,*p-'0');
                    480:        if(negflag)
                    481:                dmlad(temp,-1,0);
                    482: 
                    483:        if(temp->CDR==0) {
                    484:                result = inewint(temp->i);
                    485:                return(result);
                    486:        } else {
                    487:                (result = newsdot())->i = temp->i;
                    488:                result->CDR = temp->CDR;
                    489:                temp->CDR = 0;
                    490:        }
                    491:        return(result);
                    492: }
                    493: lispval
                    494: finatom(name)
                    495: register char *name;
                    496: {
                    497:        extern int uctolc;
                    498:        register FILE *useport = rdrport;
                    499:        register char c, stats;
                    500:        register char *savenm;
                    501:        savenm = name - 1;      /* remember start of name */
                    502:        while(!(next()&SEPMASK)) {
                    503: 
                    504:                if(stats == VESC) c = getc(useport) & 0177;
                    505:                *name++=c;
                    506:                if (name >= endstrb)
                    507:                        error("ATOM TOO LONG",FALSE);
                    508:        }
                    509:        *name = NULL_CHAR;
                    510:        ungetc(c,useport);
                    511:        if (uctolc) for(; *savenm ; savenm++) 
                    512:                        if( isupper(*savenm) ) *savenm = tolower(*savenm);
                    513:        return(getatom());
                    514: }
                    515: 
                    516: /* printr ***************************************************************/
                    517: /* prints the first argument onto the port specified by the second     */
                    518: printr(a,useport)
                    519: register lispval a;
                    520: register FILE *useport;
                    521: {
                    522:                register lispval temp;
                    523:                char strflag = 0;
                    524:                char Idqc = 0;
                    525: 
                    526: 
                    527: val_loop:
                    528:        if( ! VALID(a) )
                    529:                {
                    530:                error("BAD LISP DATA ENCOUNTERED BY PRINTR",TRUE);
                    531:                a = badst;
                    532:                }
                    533: 
                    534:        switch (TYPE(a))        {
                    535: 
                    536: 
                    537:        case UNBO:      fputs("<UNBOUND>",useport);
                    538:                        break;
                    539: 
                    540:        case VALUE:     fputs("(ptr to)",useport);
                    541:                        a = a->l;
                    542:                        goto val_loop;
                    543: 
                    544:        case INT:       fprintf(useport,"%d",a->i);
                    545:                        break;
                    546: 
                    547:        case DOUB:      fprintf(useport,"%0.16G",a->r);
                    548:                        break;
                    549: 
                    550:        case PORT:      fputs("port",useport);
                    551:                        break;
                    552: 
                    553:        case ARRAY:     fputs("array[",useport);
                    554:                        printr(a->length,useport);
                    555:                        fputs("]",useport);
                    556:                        break;
                    557: 
                    558:        case BCD:       fprintf(useport,"#%X-",a->entry);
                    559:                        printr(a->discipline,useport);
                    560:                        break;
                    561: 
                    562:        case SDOT:      pbignum(a,useport);
                    563:                        break;
                    564: 
                    565:        case DTPR:      if(a->car==quota && a->cdr!=nil 
                    566:                            && a->cdr->cdr==nil) {
                    567:                                putc('\'',useport);
                    568:                                printr(a->cdr->car,useport);
                    569:                                break;
                    570:                        }
                    571:                        putc('(',useport);
                    572:        morelist:       printr(a->car,useport);
                    573:                        if ((a = a->cdr) != nil)
                    574:                                {
                    575:                                putc(' ',useport);
                    576:                                if (TYPE(a) == DTPR) goto morelist;
                    577:                                fputs(". ",useport);
                    578:                                printr(a,useport);
                    579:                                }
                    580:                        fputc(')',useport);
                    581:                        break;
                    582: 
                    583:        case STRNG:     strflag = TRUE;
                    584:                        Idqc = Xsdc;
                    585: 
                    586:        case ATOM:      {
                    587:                        char    *front, *temp; int clean;
                    588:                        temp = front = (strflag ? ((char *) a) : a->pname);
                    589:                        if(Idqc==0) Idqc = Xdqc;
                    590: 
                    591:                        if(Idqc) {
                    592:                                clean = *temp;
                    593:                                if (*temp == '-') temp++;
                    594:                                clean = clean && (ctable[*temp] != VNUM);
                    595:                                while (clean && *temp)
                    596:                                        clean = (!(ctable[*temp++] & QUTMASK));
                    597:                                if (clean)
                    598:                                        fputs(front,useport);
                    599:                                else     {
                    600:                                        putc(Idqc,useport);
                    601:                                        for(temp=front;*temp;temp++) {
                    602:                                                if(  *temp==Idqc
                    603:                                                  || ctable[*temp] == VESC)
                    604:                                                        putc(Xesc,useport);
                    605:                                                putc(*temp,useport);
                    606:                                        }
                    607:                                        putc(Idqc,useport);
                    608:                                }
                    609: 
                    610:                        }  else {
                    611:                                register char *cp = front;
                    612: 
                    613:                                if(ctable[*cp]==VNUM)
                    614:                                        putc(Xesc,useport);
                    615:                                for(; *cp; cp++) {
                    616:                                        if(ctable[*cp]& QUTMASK)
                    617:                                                putc(Xesc,useport);
                    618:                                        putc(*cp,useport);
                    619:                                }
                    620:                        
                    621:                        }
                    622:                                        
                    623:                }
                    624:        }
                    625: }
                    626: 
                    627: /* dmpport ****************************************************************/
                    628: /* outputs buffer indicated by first argument whether full or not      */
                    629: dmpport(useport)
                    630: register lispval useport;
                    631:        {
                    632:        fflush(useport);
                    633: }
                    634: 
                    635: /*  protect and unprot moved to eval.c  (whr)  */

unix.superglobalmegacorp.com

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