Annotation of 40BSD/cmd/m4/m4.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <signal.h>
                      3: 
                      4: #define ERROR NULL
                      5: #define        READ    "r"
                      6: #define        WRITE   "w"
                      7: 
                      8: #define        EOS     0
                      9: int    lpar    = '(';
                     10: #define        LPAR    lpar
                     11: #define        RPAR    ')'
                     12: #define        COMMA   ','
                     13: #define        GRAVE   '`'
                     14: #define        ACUTE   '\''
                     15: #define LBRAK  '['
                     16: #define RBRAK  ']'
                     17: #ifdef  M4
                     18: char   lquote  LBRAK;
                     19: char   rquote  RBRAK;
                     20: #endif
                     21: #ifndef M4
                     22: char   lquote  = GRAVE;
                     23: char   rquote  = ACUTE;
                     24: #endif
                     25: #define        COMMENT '#'
                     26: #define        ALPH    1
                     27: #define        DIG     2
                     28: 
                     29: #define        HSHSIZ  199     /* prime */
                     30: #define        STACKS  50
                     31: #define        SAVS    4096
                     32: #define        TOKS    128
                     33: 
                     34: #define        putbak(c)       *ip++ = c;
                     35: #define        getchr()        (ip>cur_ip?*--ip: getc(infile[infptr]))
                     36: #define        putchr(c)       if (cp==NULL) {if (curfile)putc(c,curfile);} else *op++ = c
                     37: char   type[] = {
                     38:        0,      0,      0,      0,      0,      0,      0,      0,
                     39:        0,      0,      0,      0,      0,      0,      0,      0,
                     40:        0,      0,      0,      0,      0,      0,      0,      0,
                     41:        0,      0,      0,      0,      0,      0,      0,      0,
                     42:        0,      0,      0,      0,      0,      0,      0,      0,
                     43:        0,      0,      0,      0,      0,      0,      0,      0,
                     44:        DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,
                     45:        DIG,    DIG,    0,      0,      0,      0,      0,      0,
                     46:        0,      ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                     47:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                     48:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                     49:        ALPH,   ALPH,   ALPH,   0,      0,      0,      0,      ALPH,
                     50:        0,      ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                     51:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                     52:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                     53:        ALPH,   ALPH,   ALPH,   0,      0,      0,      0,      0,
                     54: };
                     55: 
                     56: char   token[TOKS];
                     57: char   eoa[]   = "\0";
                     58: struct nlist {
                     59:        char    *name;
                     60:        char    *def;
                     61:        struct  nlist *next;
                     62: };
                     63: 
                     64: struct nlist   *hshtab[HSHSIZ];
                     65: char   ibuf[SAVS+TOKS];
                     66: char   obuf[SAVS+TOKS];
                     67: char   *op     = obuf;
                     68: char   *ip     = ibuf;
                     69: char *ip_stk[10] = {ibuf};
                     70: char *cur_ip = ibuf;
                     71: struct call {
                     72:        char    **argp;
                     73:        int     plev;
                     74: };
                     75: struct call    *cp = NULL;
                     76: 
                     77: char   *makeloc;
                     78: char   *ifdefloc;
                     79: char   *lenloc;
                     80: char   *undefloc;
                     81: char   *shiftloc;
                     82: char   *cqloc;
                     83: char   *defloc;
                     84: char   *evaloc;
                     85: char   *incrloc;
                     86: char   *substrloc;
                     87: char   *indexloc;
                     88: char   *transloc;
                     89: char   *ifloc;
                     90: char   *divloc;
                     91: char   *divnumloc;
                     92: char   *undivloc;
                     93: char   *dnlloc;
                     94: char   *inclloc;
                     95: char   *sinclloc;
                     96: char   *syscmdloc;
                     97: char   *dumploc;
                     98: char   *errploc;
                     99: 
                    100: char   *tempname;
                    101: struct nlist   *lookup();
                    102: char   *install();
                    103: char   *malloc();
                    104: char   *mktemp();
                    105: char   *copy();
                    106: long   ctol();
                    107: int    hshval;
                    108: FILE   *olist[11] = { stdout };
                    109: int    okret;
                    110: int    curout  = 0;
                    111: FILE   *curfile = { stdout };
                    112: FILE   *infile[10] = { stdin };
                    113: int    infptr  = 0;
                    114: 
                    115: main(argc, argv)
                    116: char **argv;
                    117: {
                    118:        char *argstk[STACKS+10];
                    119:        struct call callst[STACKS];
                    120:        register char *tp, **ap;
                    121:        int delexit(), catchsig();
                    122:        register t;
                    123:        int i;
                    124: 
                    125: #ifdef gcos
                    126: #ifdef M4
                    127:        install("GCOS", eoa);
                    128: #endif
                    129: #ifndef M4
                    130:        install("gcos", eoa);
                    131: #endif
                    132: #endif
                    133: #ifdef unix
                    134: #ifdef M4
                    135:        install("UNIX", eoa);
                    136: #endif
                    137: #ifndef M4
                    138:        install("unix", eoa);
                    139: #endif
                    140: #endif
                    141: 
                    142: #ifdef M4
                    143:        makeloc = install("MAKETEMP", eoa);
                    144:        ifdefloc = install("IFDEF", eoa);
                    145:        lenloc = install("LEN", eoa);
                    146:        undefloc = install("UNDEFINE", eoa);
                    147:        shiftloc = install("SHIFT", eoa);
                    148:        cqloc = install("CHANGEQUOTE", eoa);
                    149:        defloc = install("DEFINE", eoa);
                    150:        evaloc = install("EVAL", eoa);
                    151:        inclloc = install("INCLUDE", eoa);
                    152:        sinclloc = install("SINCLUDE", eoa);
                    153:        syscmdloc = install("SYSCMD", eoa);
                    154:        dumploc = install("DUMPDEF", eoa);
                    155:        errploc = install("ERRPRINT", eoa);
                    156:        incrloc = install("INCR", eoa);
                    157:        substrloc = install("SUBSTR", eoa);
                    158:        indexloc = install("INDEX", eoa);
                    159:        transloc = install("TRANSLIT", eoa);
                    160:        ifloc = install("IFELSE", eoa);
                    161:        divloc = install("DIVERT", eoa);
                    162:        divnumloc = install("DIVNUM", eoa);
                    163:        undivloc = install("UNDIVERT", eoa);
                    164:        dnlloc = install("DNL", eoa);
                    165: #endif
                    166: 
                    167: #ifndef M4
                    168:        makeloc = install("maketemp", eoa);
                    169:        ifdefloc = install("ifdef", eoa);
                    170:        lenloc = install("len", eoa);
                    171:        undefloc = install("undefine", eoa);
                    172:        shiftloc = install("shift", eoa);
                    173:        cqloc = install("changequote", eoa);
                    174:        defloc = install("define", eoa);
                    175:        evaloc = install("eval", eoa);
                    176:        inclloc = install("include", eoa);
                    177:        sinclloc = install("sinclude", eoa);
                    178:        syscmdloc = install("syscmd", eoa);
                    179:        dumploc = install("dumpdef", eoa);
                    180:        errploc = install("errprint", eoa);
                    181:        incrloc = install("incr", eoa);
                    182:        substrloc = install("substr", eoa);
                    183:        indexloc = install("index", eoa);
                    184:        transloc = install("translit", eoa);
                    185:        ifloc = install("ifelse", eoa);
                    186:        divloc = install("divert", eoa);
                    187:        divnumloc = install("divnum", eoa);
                    188:        undivloc = install("undivert", eoa);
                    189:        dnlloc = install("dnl", eoa);
                    190: #endif
                    191:        ap = argstk;
                    192: #ifndef gcos
                    193:        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                    194:                signal(SIGHUP, catchsig);
                    195:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                    196:                signal(SIGINT, catchsig);
                    197:        tempname = mktemp("/tmp/m4aXXXXX");
                    198:        close(creat(tempname, 0));
                    199: #endif
                    200: #ifdef gcos
                    201:        tempname = "m4.tempa";
                    202: #endif
                    203:        if (argc>1)
                    204:                putbak(0);
                    205:        for (;;) {
                    206:                tp = token;
                    207:                *tp++ = t = getchr();
                    208:                *tp = EOS;
                    209:                if (t<=0) {
                    210:                        if (infptr > 0) {
                    211:                                fclose(infile[infptr]);
                    212:                                infptr--;
                    213:                                cur_ip = ip_stk[infptr];
                    214:                                continue;
                    215:                        }
                    216:                        if (argc<=1)
                    217:                                break;
                    218:                        argc--;
                    219:                        argv++;
                    220:                        if (infile[infptr]!=stdin)
                    221:                                fclose(infile[infptr]);
                    222:                        if (**argv=='-')
                    223:                                infile[infptr] = stdin;
                    224:                        else if ((infile[infptr]=fopen(argv[0], READ))==ERROR) {
                    225:                                fprintf(stderr, "m4: file not found: %s\n", argv[0]);
                    226:                                delexit();
                    227:                        }
                    228:                        continue;
                    229:                }
                    230:                if (type[t]==ALPH) {
                    231:                        while ((t=type[*tp++=getchr()])==ALPH||t==DIG);
                    232:                        putbak(*--tp);
                    233:                        *tp = EOS;
                    234:                        if (*ap = lookup(token)->def) {
                    235:                                if (++ap >= &argstk[STACKS]) {
                    236:                                        fprintf(stderr, "m4: arg stack overflow\n");
                    237:                                        delexit();
                    238:                                }
                    239:                                if (cp==NULL)
                    240:                                        cp = callst;
                    241:                                else if (++cp > &callst[STACKS]) {
                    242:                                        fprintf(stderr, "m4: call stack overflow\n");
                    243:                                        delexit();
                    244:                                }
                    245:                                cp->argp = ap;
                    246:                                *ap++ = op;
                    247:                                puttok();
                    248:                                *op++ = '\0';
                    249:                                t = getchr();
                    250:                                putbak(t);
                    251:                                if (t!=LPAR) {
                    252:                                        /* if (t!=' ' && t!='\t') */
                    253:                                                putbak(')');
                    254:                                        putbak('(');
                    255:                                }
                    256:                                else    /* try to fix arg count */
                    257:                                        *ap++ = op;
                    258:                                cp->plev = 0;
                    259:                        } else
                    260:                                puttok();
                    261:                } else if (t==lquote) {
                    262:                        i = 1;
                    263:                        for (;;) {
                    264:                                t = getchr();
                    265:                                if (t==rquote) {
                    266:                                        i--;
                    267:                                        if (i==0)
                    268:                                                break;
                    269:                                } else if (t==lquote)
                    270:                                        i++;
                    271:                                else if (t<0) {
                    272:                                        fprintf(stderr, "m4: EOF in string\n");
                    273:                                        delexit();
                    274:                                }
                    275:                                putchr(t);
                    276:                        }
                    277:                } else if (t==COMMENT) {
                    278:                        putbak(t);
                    279:                        while ((t = getchr())!='\n'&& t>=0)
                    280:                                if (cp==NULL)
                    281:                                        putchr(t);
                    282:                        putbak(t);
                    283:                } else if (cp==NULL) {
                    284:                        puttok();
                    285:                } else if (t==LPAR) {
                    286:                        if (cp->plev)
                    287:                                *op++ = t;
                    288:                        cp->plev++;
                    289:                        while ( (t=getchr())==' ' || t=='\t' || t=='\n')
                    290:                                ;       /* skip leading white space during arg collection */
                    291:                        putbak(t);
                    292: /*
                    293:                } else if (t==' ' || t=='\t' || t=='\n') {
                    294:                        continue;
                    295: */
                    296:                } else if (t==RPAR) {
                    297:                        cp->plev--;
                    298:                        if (cp->plev==0) {
                    299:                                *op++ = '\0';
                    300:                                expand(cp->argp, ap-cp->argp-1);
                    301:                                op = *cp->argp;
                    302:                                ap = cp->argp-1;
                    303:                                cp--;
                    304:                                if (cp < callst)
                    305:                                        cp = NULL;
                    306:                        } else
                    307:                                *op++ = t;
                    308:                } else if (t==COMMA && cp->plev<=1) {
                    309:                        *op++ = '\0';
                    310:                        *ap++ = op;
                    311:                        while ((t=getchr())==' ' || t=='\t' || t=='\n')
                    312:                                ;       /* skip leading white space during arg collection */
                    313:                        putbak(t);
                    314:                } else
                    315:                        *op++ = t;
                    316:        }
                    317:        if (cp!=NULL) {
                    318:                fprintf(stderr, "m4: unexpected EOF\n");
                    319:                delexit();
                    320:        }
                    321:        okret = 1;
                    322:        delexit();
                    323: }
                    324: 
                    325: catchsig()
                    326: {
                    327:        okret = 0;
                    328:        delexit();
                    329: }
                    330: 
                    331: delexit()
                    332: {
                    333:        register FILE *fp;
                    334:        register i, c;
                    335: 
                    336:        if (!okret) {
                    337:                signal(SIGHUP, SIG_IGN);
                    338:                signal(SIGINT, SIG_IGN);
                    339:        }
                    340:        for (i=1; i<10; i++) {
                    341:                if (olist[i]==NULL)
                    342:                        continue;
                    343:                fclose(olist[i]);
                    344:                tempname[7] = 'a'+i;
                    345:                if (okret) {
                    346:                        fp = fopen(tempname, READ);
                    347:                        while ((c = getc(fp)) > 0)
                    348:                                putchar(c);
                    349:                        fclose(fp);
                    350:                }
                    351:                unlink(tempname);
                    352:        }
                    353:        tempname[7] = 'a';
                    354:        unlink(tempname);
                    355:        exit(1-okret);
                    356: }
                    357: 
                    358: puttok()
                    359: {
                    360:        register char *tp;
                    361: 
                    362:        tp = token;
                    363:        if (cp) {
                    364:                if (op >= &obuf[SAVS]) {
                    365:                        fprintf(stderr, "m4: argument overflow\n");
                    366:                        delexit();
                    367:                }
                    368:                while (*tp)
                    369:                        *op++ = *tp++;
                    370:        } else if (curfile)
                    371:                while (*tp)
                    372:                        putc(*tp++, curfile);
                    373: }
                    374: 
                    375: pbstr(str)
                    376: register char *str;
                    377: {
                    378:        register char *p;
                    379: 
                    380:        p = str;
                    381:        while (*p++);
                    382:        --p;
                    383:        if (ip >= &ibuf[SAVS]) {
                    384:                fprintf(stderr, "m4: pushback overflow\n");
                    385:                delexit();
                    386:        }
                    387:        while (p > str)
                    388:                putbak(*--p);
                    389: }
                    390: 
                    391: expand(a1, c)
                    392: register char **a1;
                    393: {
                    394:        register char *dp;
                    395:        register n;
                    396: 
                    397:        dp = a1[-1];
                    398:        if (dp==defloc)
                    399:                dodef(a1, c);
                    400:        else if (dp==evaloc)
                    401:                doeval(a1, c);
                    402:        else if (dp==inclloc)
                    403:                doincl(a1, c, 1);
                    404:        else if (dp==sinclloc)
                    405:                doincl(a1, c, 0);
                    406:        else if (dp==makeloc)
                    407:                domake(a1, c);
                    408:        else if (dp==syscmdloc)
                    409:                dosyscmd(a1, c);
                    410:        else if (dp==incrloc)
                    411:                doincr(a1, c);
                    412:        else if (dp==substrloc)
                    413:                dosubstr(a1, c);
                    414:        else if (dp==indexloc)
                    415:                doindex(a1, c);
                    416:        else if (dp==transloc)
                    417:                dotransl(a1, c);
                    418:        else if (dp==ifloc)
                    419:                doif(a1, c);
                    420:        else if (dp==divloc)
                    421:                dodiv(a1, c);
                    422:        else if (dp==divnumloc)
                    423:                dodivnum(a1, c);
                    424:        else if (dp==undivloc)
                    425:                doundiv(a1, c);
                    426:        else if (dp==dnlloc)
                    427:                dodnl(a1, c);
                    428:        else if (dp==dumploc)
                    429:                dodump(a1, c);
                    430:        else if (dp==errploc)
                    431:                doerrp(a1, c);
                    432:        else if (dp==lenloc)
                    433:                dolen(a1, c);
                    434:        else if (dp==ifdefloc)
                    435:                doifdef(a1, c);
                    436:        else if (dp==undefloc)
                    437:                doundef(a1, c);
                    438:        else if (dp==shiftloc)
                    439:                doshift(a1, c);
                    440:        else if (dp==cqloc)
                    441:                docq(a1, c);
                    442:        else {
                    443:                while (*dp++);
                    444:                for (dp--; dp>a1[-1]; ) {
                    445:                        if (--dp>a1[-1] && dp[-1]=='$') {
                    446:                                n = *dp-'0';
                    447:                                if (n>=0 && n<=9) {
                    448:                                        if (n <= c)
                    449:                                                pbstr(a1[n]);
                    450:                                        dp--;
                    451:                                } else
                    452:                                        putbak(*dp);
                    453:                        } else
                    454:                                putbak(*dp);
                    455:                }
                    456:        }
                    457: }
                    458: 
                    459: struct nlist *lookup(str)
                    460: char *str;
                    461: {
                    462:        register char *s1, *s2;
                    463:        register struct nlist *np;
                    464:        static struct nlist nodef;
                    465: 
                    466:        s1 = str;
                    467:        for (hshval = 0; *s1; )
                    468:                hshval += *s1++;
                    469:        hshval %= HSHSIZ;
                    470:        for (np = hshtab[hshval]; np!=NULL; np = np->next) {
                    471:                s1 = str;
                    472:                s2 = np->name;
                    473:                while (*s1++ == *s2)
                    474:                        if (*s2++ == EOS)
                    475:                                return(np);
                    476:        }
                    477:        return(&nodef);
                    478: }
                    479: 
                    480: char *install(nam, val)
                    481: char *nam, *val;
                    482: {
                    483:        register struct nlist *np;
                    484: 
                    485:        if ((np = lookup(nam))->name == NULL) {
                    486:                np = (struct nlist *)malloc(sizeof(*np));
                    487:                if (np == NULL) {
                    488:                        fprintf(stderr, "m4: no space for alloc\n");
                    489:                        exit(1);
                    490:                }
                    491:                np->name = copy(nam);
                    492:                np->def = copy(val);
                    493:                np->next = hshtab[hshval];
                    494:                hshtab[hshval] = np;
                    495:                return(np->def);
                    496:        }
                    497:        free(np->def);
                    498:        np->def = copy(val);
                    499:        return(np->def);
                    500: }
                    501: 
                    502: doundef(ap, c)
                    503: char **ap;
                    504: {
                    505:        register struct nlist *np, *tnp;
                    506: 
                    507:        if (c < 1 || (np = lookup(ap[1]))->name == NULL)
                    508:                return;
                    509:        tnp = hshtab[hshval];   /* lookup sets hshval */
                    510:        if (tnp == np)  /* it's in first place */
                    511:                hshtab[hshval] = np->next;
                    512:        else {
                    513:                for ( ; tnp->next != np; tnp = tnp->next)
                    514:                        ;
                    515:                tnp->next = np->next;
                    516:        }
                    517:        free(np->name);
                    518:        free(np->def);
                    519:        free((char *)np);
                    520: }
                    521: 
                    522: char *copy(s)
                    523: register char *s;
                    524: {
                    525:        register char *p, *s1;
                    526: 
                    527:        p = s1 = malloc((unsigned)strlen(s)+1);
                    528:        if (p == NULL) {
                    529:                fprintf(stderr, "m4: no space for alloc\n");
                    530:                exit(1);
                    531:        }
                    532:        while (*s1++ = *s++);
                    533:        return(p);
                    534: }
                    535: 
                    536: dodef(ap, c)
                    537: char **ap;
                    538: {
                    539:        if (c >= 2) {
                    540:                if (strcmp(ap[1], ap[2]) == 0) {
                    541:                        fprintf(stderr, "m4: %s defined as itself\n", ap[1]);
                    542:                        delexit();
                    543:                }
                    544:                install(ap[1], ap[2]);
                    545:        }
                    546:        else if (c == 1)
                    547:                install(ap[1], "");
                    548: }
                    549: 
                    550: doifdef(ap, c)
                    551: char **ap;
                    552: {
                    553:        register struct nlist *np;
                    554: 
                    555:        if (c < 2)
                    556:                return;
                    557:        if (lookup(ap[1])->name != NULL)
                    558:                pbstr(ap[2]);
                    559:        else if (c >= 3)
                    560:                pbstr(ap[3]);
                    561: }
                    562: 
                    563: dolen(ap, c)
                    564: char **ap;
                    565: {
                    566:        putnum((long) strlen(ap[1]));
                    567: }
                    568: 
                    569: docq(ap, c)
                    570: char **ap;
                    571: {
                    572:        if (c > 1) {
                    573:                lquote = *ap[1];
                    574:                rquote = *ap[2];
                    575:        } else if (c == 1) {
                    576:                lquote = rquote = *ap[1];
                    577:        } else {
                    578: #ifndef M4
                    579:                lquote = GRAVE;
                    580:                rquote = ACUTE;
                    581: #endif
                    582: #ifdef M4
                    583:                lquote = LBRAK;
                    584:                rquote = RBRAK;
                    585: #endif
                    586:        }
                    587: }
                    588: 
                    589: doshift(ap, c)
                    590: char **ap;
                    591: {
                    592:        fprintf(stderr, "m4: shift not yet implemented\n");
                    593: }
                    594: 
                    595: dodump(ap, c)
                    596: char **ap;
                    597: {
                    598:        int i;
                    599:        register struct nlist *np;
                    600: 
                    601:        if (c > 0)
                    602:                while (c--) {
                    603:                        if ((np = lookup(*++ap))->name != NULL)
                    604:                                fprintf(stderr, "`%s'   `%s'\n", np->name, np->def);
                    605:                }
                    606:        else
                    607:                for (i=0; i<HSHSIZ; i++)
                    608:                        for (np=hshtab[i]; np!=NULL; np=np->next)
                    609:                                fprintf(stderr, "`%s'   `%s'\n", np->name, np->def);
                    610: }
                    611: 
                    612: doerrp(ap, c)
                    613: char **ap;
                    614: {
                    615:        if (c > 0) {
                    616:                fprintf(stderr, ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]);
                    617:                fprintf(stderr, "\n");
                    618:        }
                    619: }
                    620: 
                    621: 
                    622: long   evalval;        /* return value from yacc stuff */
                    623: char   *pe;    /* used by grammar */
                    624: 
                    625: doeval(ap, c)
                    626: char **ap;
                    627: {
                    628: 
                    629:        if (c > 0) {
                    630:                pe = ap[1];
                    631:                if (yyparse() == 0)
                    632:                        putnum(evalval);
                    633:                else
                    634:                        fprintf(stderr, "m4: invalid expression in eval: %s\n", ap[1]);
                    635:        }
                    636: }
                    637: 
                    638: doincl(ap, c, noisy)
                    639: char **ap;
                    640: {
                    641:        if (c > 0 && strlen(ap[1]) > 0) {
                    642:                infptr++;
                    643:                ip_stk[infptr] = cur_ip = ip;
                    644:                if ((infile[infptr] = fopen(ap[1], READ))==ERROR) {
                    645:                        if (noisy) {
                    646:                                fprintf(stderr, "m4: file not found: %s\n", ap[1]);
                    647:                                delexit();
                    648:                        }
                    649:                        else
                    650:                                infptr--;
                    651:                }
                    652:        }
                    653: }
                    654: 
                    655: dosyscmd(ap, c)
                    656: char **ap;
                    657: {
                    658:        if (c > 0)
                    659:                system(ap[1]);
                    660: }
                    661: 
                    662: domake(ap, c)
                    663: char **ap;
                    664: {
                    665:        if (c > 0)
                    666:                pbstr(mktemp(ap[1]));
                    667: }
                    668: 
                    669: doincr(ap, c)
                    670: char **ap;
                    671: {
                    672:        if (c >= 1)
                    673:                putnum(ctol(ap[1])+1);
                    674: }
                    675: 
                    676: putnum(num)
                    677: long num;
                    678: {
                    679:        register sign;
                    680: 
                    681:        sign = (num < 0) ? '-' : '\0';
                    682:        if (num < 0)
                    683:                num = -num;
                    684:        do {
                    685:                putbak(num%10+'0');
                    686:                num = num/10;
                    687:        } while (num!=0);
                    688:        if (sign == '-')
                    689:                putbak('-');
                    690: }
                    691: 
                    692: dosubstr(ap, c)
                    693: char **ap;
                    694: {
                    695:        int nc;
                    696:        register char *sp, *fc;
                    697: 
                    698:        if (c<2)
                    699:                return;
                    700:        if (c<3)
                    701:                nc = TOKS;
                    702:        else
                    703:                nc = ctoi(ap[3]);
                    704:        fc = ap[1] + max(0, min(ctoi(ap[2]), strlen(ap[1])));
                    705:        sp = fc + min(nc, strlen(fc));
                    706:        while (sp > fc)
                    707:                putbak(*--sp);
                    708: }
                    709: 
                    710: doindex(ap, c)
                    711: char **ap;
                    712: {
                    713:        if (c >= 2)
                    714:                putnum((long) strindex(ap[1], ap[2]));
                    715: }
                    716: 
                    717: strindex(p1, p2)
                    718: char *p1, *p2;
                    719: {
                    720:        register m;
                    721:        register char *s, *t, *p;
                    722: 
                    723:        for (p=p1; *p; p++) {
                    724:                s = p;
                    725:                m = 1;
                    726:                for (t=p2; *t; )
                    727:                        if (*t++ != *s++)
                    728:                                m = 0;
                    729:                if (m == 1)
                    730:                        return(p-p1);
                    731:        }
                    732:        return(-1);
                    733: }
                    734: 
                    735: dotransl(ap, c)
                    736: char **ap;
                    737: {
                    738:        register char *s, *fr, *to;
                    739: 
                    740:        if (c <= 1) return;
                    741: 
                    742:        if (c == 2) {
                    743:                register int i;
                    744:                to = ap[1];
                    745:                for (s = ap[1]; *s; s++) {
                    746:                        i = 0;
                    747:                        for (fr = ap[2]; *fr; fr++)
                    748:                                if (*s == *fr) {
                    749:                                        i++;
                    750:                                        break;
                    751:                                }
                    752:                        if (i == 0)
                    753:                                *to++ = *s;
                    754:                }
                    755:                *to = '\0';
                    756:        }
                    757: 
                    758:        if (c >= 3) {
                    759:                for (s = ap[1]; *s; s++)
                    760:                        for (fr = ap[2], to = ap[3]; *fr && *to; fr++, to++)
                    761:                                if (*s == *fr)
                    762:                                        *s = *to;
                    763:        }
                    764: 
                    765:        pbstr(ap[1]);
                    766: }
                    767: 
                    768: doif(ap, c)
                    769: register char **ap;
                    770: {
                    771:        if (c < 3)
                    772:                return;
                    773:        while (c >= 3) {
                    774:                if (strcmp(ap[1], ap[2]) == 0) {
                    775:                        pbstr(ap[3]);
                    776:                        return;
                    777:                }
                    778:                c -= 3;
                    779:                ap += 3;
                    780:        }
                    781:        if (c > 0)
                    782:                pbstr(ap[1]);
                    783: }
                    784: 
                    785: dodiv(ap, c)
                    786: register char **ap;
                    787: {
                    788:        register int f;
                    789: 
                    790:        if (c<1)
                    791:                f = 0;
                    792:        else
                    793:                f = ctoi(ap[1]);
                    794:        if (f>=10 || f<0) {
                    795:                curfile = NULL;
                    796:                return;
                    797:        }
                    798:        tempname[7] = 'a' + f;
                    799:        if (olist[f] || (olist[f]=fopen(tempname, WRITE))) {
                    800:                curout = f;
                    801:                curfile = olist[f];
                    802:        }
                    803: }
                    804: 
                    805: doundiv(ap, c)
                    806: char **ap;
                    807: {
                    808:        register FILE *fp;
                    809:        register int i, ch;
                    810:        int j;
                    811: 
                    812:        if (c == 0) {
                    813:                for (i=1; i<10; i++) {
                    814:                        if (i==curout || olist[i]==NULL)
                    815:                                continue;
                    816:                        fclose(olist[i]);
                    817:                        tempname[7] = 'a'+i;
                    818:                        fp = fopen(tempname, READ);
                    819:                        if (curfile != NULL)
                    820:                                while ((ch = getc(fp)) > 0)
                    821:                                        putc(ch, curfile);
                    822:                        fclose(fp);
                    823:                        unlink(tempname);
                    824:                        olist[i] = NULL;
                    825:                }
                    826: 
                    827:        }
                    828:        else {
                    829:                for (j = 1; j <= c; j++) {
                    830:                        i = ctoi(*++ap);
                    831:                        if (i<1 || i>9 || i==curout || olist[i]==NULL)
                    832:                                continue;
                    833:                        fclose(olist[i]);
                    834:                        tempname[7] = 'a'+i;
                    835:                        fp = fopen(tempname, READ);
                    836:                        if (curfile != NULL)
                    837:                                while ((ch = getc(fp)) > 0)
                    838:                                        putc(ch, curfile);
                    839:                        fclose(fp);
                    840:                        unlink(tempname);
                    841:                        olist[i] = NULL;
                    842:                }
                    843:        }
                    844: }
                    845: 
                    846: dodivnum(ap, c)
                    847: char **ap;
                    848: {
                    849:        putnum((long) curout);
                    850: }
                    851: 
                    852: dodnl(ap, c)
                    853: char **ap;
                    854: {
                    855:        register t;
                    856: 
                    857:        while ((t=getchr())!='\n' && t>=0)
                    858:                ;
                    859: }
                    860: 
                    861: long ctol(str)
                    862: register char *str;
                    863: {
                    864:        register sign;
                    865:        long num;
                    866: 
                    867:        while (*str==' ' || *str=='\t' || *str=='\n')
                    868:                str++;
                    869:        num = 0;
                    870:        if (*str == '-') {
                    871:                sign = -1;
                    872:                str++;
                    873:        }
                    874:        else
                    875:                sign = 1;
                    876:        while (*str>='0' && *str<='9')
                    877:                num = num*10 + *str++ - '0';
                    878:        return(sign * num);
                    879: }
                    880: 
                    881: ctoi(s)
                    882: char *s;
                    883: {
                    884:        return(ctol(s));
                    885: }
                    886: 
                    887: min(a, b)
                    888: {
                    889:        if (a>b)
                    890:                return(b);
                    891:        return(a);
                    892: }
                    893: 
                    894: max(a, b)
                    895: {
                    896:        if (a>b)
                    897:                return(a);
                    898:        return(b);
                    899: }

unix.superglobalmegacorp.com

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