Annotation of coherent/d/bin/m4.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <ctype.h>
        !             3: 
        !             4: #ifdef MSDOS
        !             5: #define        TMPFILE "m4%dXXX"
        !             6: #define        TMPMIN  2               /* minimum temp file length */
        !             7: #else
        !             8: #define        TMPFILE "/tmp/m4%dxxxxxx"
        !             9: #define        TMPMIN  6
        !            10: #endif
        !            11: 
        !            12: #define        isletter(c)             (isalpha(c)||c=='_')
        !            13: #define        BQUOTE  '`'
        !            14: #define        EQUOTE  '\''
        !            15: #define        HASHSZ  199
        !            16: #define        STRBLK  16              /* block size for dynamic string storage */
        !            17: #if STRBLK < 12
        !            18:                                   need room for decimal rep of long int
        !            19: #endif
        !            20: 
        !            21: enum   {FUNC, MACD, DSKF, MSTR};
        !            22: enum   {EX, MY, DV, MD, AD, SB, EQ, NE, LE, GE, LT, GT, AN, OR, RP, NL};
        !            23: 
        !            24: typedef        struct {                /* for storing variable-length strings */
        !            25:        int     s_refc;         /* references--when zero space is freed */
        !            26:        int     s_hash;         /* raw hash value (sum of chars in body) */
        !            27:        char    *s_body;        /* start of contents */
        !            28:        char    *s_next;        /* end of contents */
        !            29:        char    *s_last;        /* end of storage */
        !            30: } STRING;
        !            31: 
        !            32: typedef        union   ifr {                   /* input-source stack frame */
        !            33:        struct  {
        !            34:                struct  ifr *i_back;
        !            35:                char    i_cbuf;         /* unget buffer for lookahead */
        !            36:                int     i_type;         /* if type is MSTRing */
        !            37:                STRING  *i_pstr;
        !            38:                char    *i_pchr;        /* next char */
        !            39:        } ifb;
        !            40:        struct  {
        !            41:                struct  ifr *i_back;
        !            42:                char    i_cbuf;
        !            43:                int     i_type;         /* if type is DSKFile */
        !            44:                FILE    *i_fp;
        !            45:        } ifdk;
        !            46: } IFRAME;
        !            47: 
        !            48: typedef        struct  fstk {                  /* file information stack frame */
        !            49:        struct  fstk *f_back;
        !            50:        STRING  *f_name;                /* pointer to name (NULL if stdin) */
        !            51:        int     f_flag;                 /* flag = 0 until EOF is reached */
        !            52:        int     f_line;                 /* line counter */
        !            53: } FFRAME;
        !            54: 
        !            55: typedef        struct  ofr {                   /* argument collection stack frame */
        !            56:        struct  ofr *o_back;
        !            57:        STRING  *o_pstr;
        !            58: } OFRAME;
        !            59: 
        !            60: typedef        struct  ent {                   /* symbol table entry */
        !            61:        struct  ent *e_next;
        !            62:        int     e_type;                 /* FUNC or MACD */
        !            63:        union {
        !            64:                int     (*e_pfun)();
        !            65:                STRING  *e_pstr;
        !            66:        } e_at;
        !            67:        STRING  *e_name;
        !            68: } ENTRY;
        !            69: 
        !            70: /*
        !            71:  * built in functions
        !            72:  */
        !            73: extern int     mchangequote(), mdecr(), mdefine(), mdivert(), mdivnum(), mdnl(),
        !            74:        mdumpdef(), merrprint(), meval(), mifdef(), mifelse(),
        !            75:        minclude(), mincr(), mindex(), mlen(), mmaketemp(), msinclude(),
        !            76:        msubstr(), msyscmd(), mtranslit(), mundefine(), mundivert();
        !            77:        
        !            78: /*
        !            79:  * output file info
        !            80:  */
        !            81: struct {
        !            82:        char    *name;
        !            83:        FILE    *fp;
        !            84: } outfile[10] = {{ NULL, stdout }};
        !            85: 
        !            86: /*
        !            87:  * op table for eval
        !            88:  */
        !            89: struct opdata {
        !            90:        int     optype;
        !            91:        char    keychar;
        !            92:        char    secchar;
        !            93:        int     prec;
        !            94: } optable[] = {
        !            95: #define        SI      8       /* precedence of unary + and - */
        !            96:        EX, '^', '\0', 7,       EX, '*', '*', 7,
        !            97:        MY, '*', '\0', 6,       DV, '/', '\0', 6,       MD, '%', '\0', 6,
        !            98:        AD, '+', '\0', 5,       SB, '-', '\0', 5,
        !            99:        EQ, '=', '=', 4,        GE, '>', '=', 4,        GT, '>', '\0', 4,
        !           100:        NE, '!', '=', 4,        LE, '<', '=', 4,        LT, '<', '\0', 4,
        !           101: #define        NT      3       /* precedence of unary ! */
        !           102:        AN, '&', '&', 2,        AN, '&', '\0', 2,
        !           103:        OR, '|', '|', 1,        OR, '|', '\0', 1,
        !           104:        RP, ')', '\0', 10,      NL, '\0', '\0', 0
        !           105: #define        LP      0       /* precedence of open paren */
        !           106: };
        !           107: 
        !           108: ENTRY  *e_root[HASHSZ];        /* pointers to symbol table hash buckets */
        !           109: OFRAME *ostkptr;               /* output stack pointer */
        !           110: IFRAME *istkptr;               /* input stack pointer */
        !           111: FFRAME *fstkptr;               /* file info stack pointer */
        !           112: FILE   *offp = stdout;         /* current output file pointer */
        !           113: int    ofnum;                  /* current diversion number */
        !           114: int    lstdchr = '\n';         /* last char from stdin */
        !           115: int    single;                 /* single argument flag */
        !           116: int    dnlflag;                /* delete to newline flag */
        !           117: 
        !           118: char   bqt = BQUOTE;
        !           119: char   eqt = EQUOTE;
        !           120: extern char    *alloc();
        !           121: STRING *makestr();
        !           122: 
        !           123: main(argc, argv)
        !           124: int argc;
        !           125: char *argv[];
        !           126: {
        !           127: #ifdef MSDOS
        !           128:        msdoscvt("m4", &argc, &argv);
        !           129: #endif
        !           130:        buildin("changequote", mchangequote);
        !           131:        buildin("decr", mdecr);
        !           132:        buildin("define", mdefine);
        !           133:        buildin("divert", mdivert);
        !           134:        buildin("divnum", mdivnum);
        !           135:        buildin("dnl", mdnl);
        !           136:        buildin("dumpdef", mdumpdef);
        !           137:        buildin("errprint", merrprint);
        !           138:        buildin("eval", meval);
        !           139:        buildin("ifdef", mifdef);
        !           140:        buildin("ifelse", mifelse);
        !           141:        buildin("include", minclude);
        !           142:        buildin("incr", mincr);
        !           143:        buildin("index", mindex);
        !           144:        buildin("len", mlen);
        !           145:        buildin("maketemp", mmaketemp);
        !           146:        buildin("sinclude", msinclude);
        !           147:        buildin("substr", msubstr);
        !           148:        buildin("syscmd", msyscmd);
        !           149:        buildin("translit", mtranslit);
        !           150:        buildin("undefine", mundefine);
        !           151:        buildin("undivert", mundivert);
        !           152: 
        !           153:        single = (argc == 2);
        !           154:        if (argc > 1) {
        !           155:                while (--argc)
        !           156:                        if (pushfile(*++argv))
        !           157:                                process(0);
        !           158:                        else
        !           159:                                errorp(0, "cannot open %s", *argv);
        !           160:        } else {
        !           161:                pushfile("-");
        !           162:                process(0);
        !           163:        }
        !           164:        mdivert(NULL);
        !           165:        mundivert(NULL);
        !           166:        exit(0);
        !           167: }
        !           168: 
        !           169: process(pct)
        !           170: int pct;
        !           171: {
        !           172:        char lc = '\0';
        !           173:        register int c, qct = 0;
        !           174:        int i;
        !           175:        STRING  *a[10];
        !           176:        register STRING *b;
        !           177:        ENTRY *e, *find();
        !           178: 
        !           179:        for (c=nxch(); pct && isspace(c); c=nxch())
        !           180:                ;
        !           181:        while (c != '\0') {
        !           182:                if (qct)
        !           183:                        if (c == eqt) {
        !           184:                                if (--qct)
        !           185:                                        outputc(c);
        !           186:                        } else {
        !           187:                                if (c == bqt)
        !           188:                                        ++qct;
        !           189:                                outputc(c);
        !           190:                        }
        !           191:                else if (c == bqt)
        !           192:                        ++qct;
        !           193:                else if (c==')' && pct && !--pct || c==',' && pct==1)
        !           194:                        return (c);
        !           195:                else if (isletter(c) && !isletter(lc) && !isdigit(lc)) {
        !           196:                        b = makestr();
        !           197:                        do {
        !           198:                                appendstr(b, c);
        !           199:                                lc = c;
        !           200:                                c = nxch();
        !           201:                        } while (isletter(c) || isdigit(c));
        !           202:                        if ((e=find(b)) == NULL) {
        !           203:                                outputs(b->s_body);
        !           204:                                decstr(b);
        !           205:                                continue;
        !           206:                        }
        !           207:                        for (i=9; i; a[i--]=NULL)
        !           208:                                ;
        !           209:                        a[0] = b;
        !           210:                        if (c != '(') {
        !           211:                                istkptr->i_cbuf = c;
        !           212:                                if (c=='\n' && istkptr->i_type==DSKF)
        !           213:                                        if (fstkptr->f_flag)
        !           214:                                                --fstkptr->f_back->f_line;
        !           215:                                        else
        !           216:                                                --fstkptr->f_line;
        !           217:                        } else do {
        !           218:                                pushout(b=makestr());
        !           219:                                c = process(1);
        !           220:                                if (i++<9 && strlen(b->s_body))
        !           221:                                        a[i] = b;
        !           222:                                else
        !           223:                                        decstr(b);
        !           224:                                popout();
        !           225:                        } while (c != ')');
        !           226:                        if (e->e_type == MACD)
        !           227:                                macro(e->e_at.e_pstr, a);
        !           228:                        else
        !           229:                                (*e->e_at.e_pfun)(a);
        !           230:                        for (i = 0; i < 10; i++)
        !           231:                                decstr(a[i]);
        !           232:                        c = '\0';
        !           233:                } else {
        !           234:                        if (c=='(' && pct)
        !           235:                                ++pct;
        !           236:                        outputc(c);
        !           237:                }
        !           238:                lc = c;
        !           239:                c = nxch();
        !           240:        }
        !           241:        if (pct)
        !           242:                errorp(1, "unexpected EOF");
        !           243:        return (c);
        !           244: }
        !           245: 
        !           246: macro(ps, pps)
        !           247: STRING *ps, **pps;
        !           248: {
        !           249:        STRING *x;
        !           250:        register char *b, *v;
        !           251: 
        !           252:        x = makestr();
        !           253:        b = ps->s_body;
        !           254:        while (*b) {
        !           255:                if (*b != '$')
        !           256:                        appendstr(x, *b++);
        !           257:                else if (!isdigit(*++b))
        !           258:                        appendstr(x, '$');
        !           259:                else if (ps = pps[*b++ - '0'])
        !           260:                        for (v = ps->s_body; *v; v++)
        !           261:                                appendstr(x, *v);
        !           262:        }
        !           263:        pushstr(x);
        !           264:        decstr(x);
        !           265: }
        !           266: 
        !           267: pushfile(s)
        !           268: char *s;
        !           269: {
        !           270:        FILE *fp, *fopen();
        !           271:        register STRING *a = NULL;
        !           272:        register FFRAME *ftemp = fstkptr;
        !           273:        char c;
        !           274: 
        !           275:        if (ftemp!=NULL && ftemp->f_flag) {
        !           276:                decstr(ftemp->f_name);
        !           277:                fstkptr = ftemp->f_back;
        !           278:                free(ftemp);
        !           279:        }
        !           280:        if ( strcmp(s, "-") == 0 )
        !           281:                fp = stdin;
        !           282:        else if ( (fp = fopen(s, "r")) == NULL )
        !           283:                return (0);
        !           284:        pushinp(DSKF);
        !           285:        istkptr->i_fp = fp;
        !           286:        ftemp = (FFRAME *)alloc(sizeof(FFRAME));
        !           287:        ftemp->f_back = fstkptr;
        !           288:        ftemp->f_line = 1;
        !           289:        ftemp->f_flag = 0;
        !           290:        if (fp!=stdin && !(fstkptr==NULL && single)) {
        !           291:                a = makestr();
        !           292:                while (c = *s++)
        !           293:                        appendstr(a, c);
        !           294:        }
        !           295:        ftemp->f_name = a;
        !           296:        fstkptr = ftemp;
        !           297:        return (1);
        !           298: }
        !           299: 
        !           300: pushstr(a)
        !           301: STRING *a;
        !           302: {
        !           303:        if (a==NULL || *a->s_body=='\0')
        !           304:                return;
        !           305:        pushinp(MSTR);
        !           306:        istkptr->i_pstr = a;
        !           307:        istkptr->i_pchr = a->s_body;
        !           308:        ++a->s_refc;
        !           309: }
        !           310: 
        !           311: pushnum(x)
        !           312: long x;
        !           313: {
        !           314:        register STRING *a;
        !           315: 
        !           316:        a = makestr();
        !           317:        sprintf(a->s_body, "%ld", x);
        !           318:        pushstr(a);
        !           319:        decstr(a);
        !           320: }
        !           321: 
        !           322: pushinp(t)
        !           323: char t;
        !           324: {
        !           325:        IFRAME *itemp;
        !           326: 
        !           327:        itemp = istkptr;
        !           328:        istkptr = (IFRAME *)alloc(sizeof(IFRAME));
        !           329:        istkptr->i_back = itemp;
        !           330:        istkptr->i_type = t;
        !           331:        istkptr->i_cbuf = '\0';
        !           332: }
        !           333: 
        !           334: popinp()
        !           335: {
        !           336:        IFRAME *itemp;
        !           337: 
        !           338:        itemp = istkptr;
        !           339:        switch (istkptr->i_type) {
        !           340:        case MSTR:
        !           341:                decstr(istkptr->i_pstr);
        !           342:                break;
        !           343:        case DSKF:
        !           344:                if (istkptr->i_fp != stdin)
        !           345:                        fclose(istkptr->i_fp);
        !           346:                fstkptr->f_flag = 1;
        !           347:                break;
        !           348:        }
        !           349:        istkptr = istkptr->i_back;
        !           350:        free(itemp);
        !           351:        return (istkptr != NULL);
        !           352: }
        !           353: 
        !           354: pushout(b)
        !           355: STRING *b;
        !           356: {
        !           357:        OFRAME *otemp;
        !           358: 
        !           359:        otemp = (OFRAME *)alloc(sizeof(OFRAME));
        !           360:        otemp->o_back = ostkptr;
        !           361:        otemp->o_pstr = b;
        !           362:        ostkptr = otemp;
        !           363:        ++b->s_refc;
        !           364: }
        !           365: 
        !           366: popout()
        !           367: {
        !           368:        OFRAME *otemp;
        !           369: 
        !           370:        otemp = ostkptr;
        !           371:        ostkptr = ostkptr->o_back;
        !           372:        decstr(otemp->o_pstr);
        !           373:        free(otemp);
        !           374: }
        !           375: 
        !           376: nxch()
        !           377: {
        !           378:        register int c;
        !           379:        FFRAME *ftemp;
        !           380: 
        !           381:        if (istkptr == NULL)
        !           382:                return ('\0');
        !           383:        if ((ftemp = fstkptr)->f_flag) {
        !           384:                decstr(ftemp->f_name);
        !           385:                fstkptr = ftemp->f_back;
        !           386:                free(ftemp);
        !           387:        }
        !           388:        switch (istkptr->i_type) {
        !           389:        case DSKF:
        !           390:                if (c=istkptr->i_cbuf)
        !           391:                        istkptr->i_cbuf = '\0';
        !           392:                else
        !           393:                        c = getc(istkptr->i_fp);
        !           394:                if (istkptr->i_fp == stdin)
        !           395:                        lstdchr = c;
        !           396:                if (c == EOF)
        !           397:                        c = '\0';
        !           398:                else if (c == '\n')
        !           399:                        if (fstkptr->f_flag)
        !           400:                                ++fstkptr->f_back->f_line;
        !           401:                        else
        !           402:                                ++fstkptr->f_line;
        !           403:                break;
        !           404:        case MSTR:
        !           405:                if (c=istkptr->i_cbuf)
        !           406:                        istkptr->i_cbuf = '\0';
        !           407:                else
        !           408:                        c = *istkptr->i_pchr++;
        !           409:                break;
        !           410:        }
        !           411:        if (c == '\0')
        !           412:                return (popinp()? nxch() : c);
        !           413:        else if (!dnlflag)
        !           414:                return (c);
        !           415:        if (c == '\n')
        !           416:                dnlflag = 0;
        !           417:        return (nxch());
        !           418: }
        !           419: 
        !           420: outputc(c)
        !           421: char c;
        !           422: {
        !           423:        if (ostkptr != NULL)
        !           424:                appendstr(ostkptr->o_pstr, c);
        !           425:        else
        !           426:                outc(c);
        !           427: }
        !           428: 
        !           429: outc(c)
        !           430: char c;
        !           431: {
        !           432:        if (offp != NULL)
        !           433:                putc(c, offp);
        !           434: }
        !           435: 
        !           436: 
        !           437: STRING *
        !           438: makestr()
        !           439: {
        !           440:        register STRING *a;
        !           441: 
        !           442:        a = (STRING *)alloc(sizeof(STRING));
        !           443:        a->s_body = a->s_next = (STRING *)alloc(STRBLK);
        !           444:        a->s_last = a->s_body + STRBLK - 1;
        !           445:        a->s_refc = 1;
        !           446:        a->s_hash = 0;
        !           447:        *a->s_next = '\0';
        !           448:        return (a);
        !           449: }
        !           450: 
        !           451: appendstr(a, c)
        !           452: STRING *a;
        !           453: char c;
        !           454: {
        !           455:        register char *r, *s, *t;
        !           456:        int size;
        !           457: 
        !           458:        if (a->s_next < a->s_last) {
        !           459:                *a->s_next++ = c;
        !           460:                *a->s_next = '\0';
        !           461:        } else {
        !           462:                r = s = alloc(size = a->s_last - (t = a->s_body) + 1 + STRBLK);
        !           463:                while (*s++ = *t++)
        !           464:                        ;
        !           465:                *(a->s_next = s) = '\0';
        !           466:                *--s = c;
        !           467:                free(a->s_body);
        !           468:                a->s_last = (a->s_body = r) + size - 1;
        !           469:        }
        !           470:        a->s_hash += c;
        !           471: }
        !           472: 
        !           473: decstr(a)
        !           474: STRING *a;
        !           475: {
        !           476:        if (a == NULL)
        !           477:                return;
        !           478:        if (--a->s_refc)
        !           479:                return;
        !           480:        free(a->s_body);
        !           481:        free(a);
        !           482: }
        !           483: 
        !           484: cmpstr(a, b)
        !           485: STRING *a, *b;
        !           486: {
        !           487:        if (a==NULL && b==NULL)
        !           488:                return (1);
        !           489:        if (a==NULL && b!=NULL || a!=NULL && b==NULL)
        !           490:                return (0);
        !           491:        return (!strcmp(a->s_body, b->s_body));
        !           492: }
        !           493: 
        !           494: outputs(s)
        !           495: char *s;
        !           496: {
        !           497:        register char *t, c;
        !           498: 
        !           499:        for (t = s; c = *t++; outputc(c))
        !           500:                ;
        !           501: }
        !           502: 
        !           503: ENTRY  *
        !           504: find(a)
        !           505: STRING *a;
        !           506: {
        !           507:        register ENTRY *e;
        !           508:        register int hash;
        !           509: 
        !           510:        hash = a->s_hash;
        !           511:        for (e = e_root[hash % HASHSZ]; e != NULL; e = e->e_next)
        !           512:                if (e->e_name->s_hash == hash
        !           513:                &&  strcmp(e->e_name->s_body, a->s_body) == 0)
        !           514:                        return (e);
        !           515:        return (NULL);
        !           516: }
        !           517: 
        !           518: buildin(s, f)
        !           519: char *s;
        !           520: int (*f)();
        !           521: {
        !           522:        STRING *a;
        !           523:        register int hash;
        !           524:        register ENTRY *e;
        !           525: 
        !           526:        a = makestr();
        !           527:        while (*s)
        !           528:                appendstr(a, *s++);
        !           529:        hash = a->s_hash % HASHSZ;
        !           530:        e = (ENTRY *)alloc(sizeof(ENTRY));
        !           531:        e->e_next = e_root[hash];
        !           532:        e->e_type = FUNC;
        !           533:        e->e_at.e_pfun = f;
        !           534:        e->e_name = a;
        !           535:        e_root[hash] = e;
        !           536: }
        !           537: 
        !           538: char   *
        !           539: alloc(n)
        !           540: int n;
        !           541: {
        !           542:        char *x;
        !           543: 
        !           544:        if ((x=malloc(n)) != NULL)
        !           545:                return(x);
        !           546:        errorp(1, "out of space");
        !           547: }
        !           548: 
        !           549: /* VARARGS */
        !           550: errorp(f, x)
        !           551: int f;
        !           552: {
        !           553:        fprintf(stderr, "m4: ");
        !           554:        if (fstkptr != NULL) {
        !           555:                if (fstkptr->f_name != NULL)
        !           556:                        fprintf(stderr, "%s: ", fstkptr->f_name->s_body);
        !           557:                fprintf(stderr, "%d: ", fstkptr->f_line);
        !           558:        }
        !           559:        fprintf(stderr, "%r", &x);
        !           560:        putc('\n', stderr);
        !           561:        if (f) {
        !           562:                while (lstdchr!=EOF && lstdchr!='\n')
        !           563:                        lstdchr = getchar();
        !           564:                exit(1);
        !           565:        }
        !           566: }
        !           567: 
        !           568: mchangequote(pps)
        !           569: STRING **pps;
        !           570: {
        !           571:        bqt = pps[1]? *pps[1]->s_body : BQUOTE;
        !           572:        eqt = pps[2]? *pps[2]->s_body : EQUOTE;
        !           573: }
        !           574: 
        !           575: mdefine(pps)
        !           576: STRING **pps;
        !           577: {
        !           578:        ENTRY *find();
        !           579:        register ENTRY *e;
        !           580:        register char *s;
        !           581:        register int hash;
        !           582:        int c;
        !           583:        static char illmac[] = "illegal macro name: %s";
        !           584: 
        !           585:        if (pps[1]==NULL || !isletter(*pps[1]->s_body)) {
        !           586:                errorp(0, illmac, pps[1]!=NULL? pps[1]->s_body : NULL);
        !           587:                return;
        !           588:        }
        !           589:        s = pps[1]->s_body + 1;
        !           590:        while (c = *s++)
        !           591:                if (!(isletter(c)||isdigit(c))) {
        !           592:                        errorp(0, illmac, pps[1]->s_body);
        !           593:                        return;
        !           594:                }
        !           595:        if (e = find(pps[1])) {
        !           596:                if (e->e_type == MACD)
        !           597:                        decstr(e->e_at.e_pstr);
        !           598:        } else {
        !           599:                e = (ENTRY *)alloc(sizeof(ENTRY));
        !           600:                e->e_next = e_root[hash = pps[1]->s_hash % HASHSZ];
        !           601:                e->e_name = pps[1];
        !           602:                ++pps[1]->s_refc;
        !           603:                e_root[hash] = e;
        !           604:        }
        !           605:        e->e_type = MACD;
        !           606:        if (pps[2]) {
        !           607:                e->e_at.e_pstr = pps[2];
        !           608:                ++pps[2]->s_refc;
        !           609:        } else
        !           610:                e->e_at.e_pstr = makestr();
        !           611: }
        !           612: 
        !           613: mdivert(pps)
        !           614: STRING **pps;
        !           615: {
        !           616:        char *fn;
        !           617: 
        !           618:        if (pps == NULL)
        !           619:                ofnum = 0;
        !           620:        else
        !           621:                ofnum = (pps[1] != NULL)? atoi(pps[1]->s_body) : 0;
        !           622:        if (ofnum>0 && ofnum<=9) {
        !           623:                if (outfile[ofnum].fp == NULL) {
        !           624:                        outfile[ofnum].name = fn = alloc(15);
        !           625:                        sprintf(fn, TMPFILE, ofnum);
        !           626:                        mktemp(fn);
        !           627:                        if ((outfile[ofnum].fp=fopen(fn,"w"))==NULL)
        !           628:                                errorp(1, "m4: /tmp open error\n");
        !           629:                }
        !           630:        }
        !           631:        if (ofnum>=0 && ofnum<=9)
        !           632:                offp = outfile[ofnum].fp;
        !           633:        else
        !           634:                offp = NULL;
        !           635: }
        !           636: 
        !           637: mdivnum()
        !           638: {
        !           639:        pushnum((long)ofnum);
        !           640: }
        !           641: 
        !           642: mdnl()
        !           643: {
        !           644:        dnlflag = 1;
        !           645: }
        !           646: 
        !           647: mdumpdef(pps)
        !           648: STRING **pps;
        !           649: {
        !           650:        ENTRY *find();
        !           651:        register ENTRY *e;
        !           652:        register int i, f = 0;
        !           653:        int hash;
        !           654: 
        !           655:        for (i = 1; i <= 9; ++i)
        !           656:                if (pps[i] != NULL) {
        !           657:                        if (e=find(pps[i]))
        !           658:                                outdef(e);
        !           659:                        f = 1;
        !           660:                }
        !           661:        if (!f)
        !           662:                for (hash = 0; hash < HASHSZ; ++hash)
        !           663:                        for (e = e_root[hash]; e; e = e->e_next) {
        !           664:                                outputc(bqt);
        !           665:                                outputs(e->e_name->s_body);
        !           666:                                outputc(eqt);
        !           667:                                outputc('\t');
        !           668:                                outdef(e);
        !           669:                                outputc('\n');
        !           670:                        }
        !           671: }
        !           672: 
        !           673: outdef(e)
        !           674: ENTRY *e;
        !           675: {
        !           676:        if (e->e_type == MACD) {
        !           677:                outputc(bqt);
        !           678:                outputs(e->e_at.e_pstr->s_body);
        !           679:                outputc(eqt);
        !           680:        }
        !           681: }
        !           682: 
        !           683: merrprint(pps)
        !           684: STRING **pps;
        !           685: {
        !           686:        register int i;
        !           687: 
        !           688:        for (i=1; i<=9; i++)
        !           689:                if (pps[i])
        !           690:                        fprintf(stderr, pps[i]->s_body);
        !           691: }
        !           692: 
        !           693: meval(pps)
        !           694: STRING **pps;
        !           695: {
        !           696:        long calc();
        !           697:        char *s;
        !           698: 
        !           699:        if (pps[1] == NULL)
        !           700:                pushnum((long)0);
        !           701:        else {
        !           702:                s = pps[1]->s_body;
        !           703:                pushnum(calc(0, &s));
        !           704:        }
        !           705: }
        !           706: 
        !           707: long
        !           708: calc(pr, ps)
        !           709: int pr;
        !           710: char **ps;
        !           711: {
        !           712:        register struct opdata *opptr;
        !           713:        register char c;
        !           714:        char *s;
        !           715:        long val1, val2, l;
        !           716:        int oplength;
        !           717: 
        !           718:        for (s = *ps; isspace(*s); ++s)
        !           719:                ;
        !           720:        if (isdigit(c=*s++))
        !           721:                for (val1 = c - '0'; isdigit(c = *s); ++s)
        !           722:                        val1 = 10 * val1 + c - '0';
        !           723:        else switch (c) {
        !           724:        case '+':
        !           725:                val1 = calc(SI, &s);
        !           726:                break;
        !           727:        case '-':
        !           728:                val1 =-calc(SI, &s);
        !           729:                break;
        !           730:        case '!':
        !           731:                val1 =!calc(NT, &s);
        !           732:                break;
        !           733:        case '(':
        !           734:                val1 = calc(LP, &s);
        !           735:                break;
        !           736:        default:
        !           737:                if (c == '\0')
        !           738:                        errorp(0, "eval: missing value");
        !           739:                else
        !           740:                        errorp(0, "eval: invalid expression");
        !           741:                s = NULL;
        !           742:        }
        !           743:        if ((*ps = s) == NULL)
        !           744:                return (0);
        !           745:        for (;;) {
        !           746:                while (s!=NULL && isspace(c = *s))
        !           747:                        ++s;
        !           748:                oplength = 1;
        !           749:                for (opptr = optable; s != NULL; ++opptr)
        !           750:                        if (c != opptr->keychar) {
        !           751:                                if (opptr->keychar == '\0')
        !           752:                                        s = NULL;
        !           753:                        } else if (opptr->secchar=='\0') {
        !           754:                                break;
        !           755:                        } else if (opptr->secchar == *(s+1)) {
        !           756:                                ++oplength;
        !           757:                                break;
        !           758:                        }
        !           759:                if ((*ps = s) == NULL) {
        !           760:                        errorp(0, "eval: missing or unknown operator");
        !           761:                        return (0);
        !           762:                }
        !           763:                if (opptr->prec <= pr)
        !           764:                        return (val1);
        !           765:                *ps = s += oplength;
        !           766:                if (c == ')')
        !           767:                        return (val1);
        !           768:                val2 = calc(opptr->prec, &s);
        !           769:                if ((*ps = s) == NULL)
        !           770:                        return (0);
        !           771:                switch (opptr->optype) {
        !           772:                case EX:
        !           773:                        if (val2 < 0)
        !           774:                                val1 = 0;
        !           775:                        else {
        !           776:                                for (l = 1; val2; --val2)
        !           777:                                        l *= val1;
        !           778:                                val1 = l;
        !           779:                        }
        !           780:                        break;
        !           781:                case MY:
        !           782:                        val1 *= val2;
        !           783:                        break;
        !           784:                case DV:
        !           785:                        val1 /= val2;
        !           786:                        break;
        !           787:                case MD:
        !           788:                        val1 %= val2;
        !           789:                        break;
        !           790:                case AD:
        !           791:                        val1 += val2;
        !           792:                        break;
        !           793:                case SB:
        !           794:                        val1 -= val2;
        !           795:                        break;
        !           796:                case EQ:
        !           797:                        val1 = (val1 == val2);
        !           798:                        break;
        !           799:                case NE:
        !           800:                        val1 = (val1 != val2);
        !           801:                        break;
        !           802:                case GE:
        !           803:                        val1 = (val1 >= val2);
        !           804:                        break;
        !           805:                case LE:
        !           806:                        val1 = (val1 <= val2);
        !           807:                        break;
        !           808:                case GT:
        !           809:                        val1 = (val1 > val2);
        !           810:                        break;
        !           811:                case LT:
        !           812:                        val1 = (val1 < val2);
        !           813:                        break;
        !           814:                case AN:
        !           815:                        val1 = (val1 && val2);
        !           816:                        break;
        !           817:                case OR:
        !           818:                        val1 = (val1 || val2);
        !           819:                        break;
        !           820:                }
        !           821:        }
        !           822: }
        !           823: 
        !           824: mifdef(pps)
        !           825: STRING **pps;
        !           826: {
        !           827:        ENTRY *find();
        !           828: 
        !           829:        if (pps[1] && find(pps[1])) {
        !           830:                pushstr(pps[2]);
        !           831:        } else
        !           832:                pushstr(pps[3]);
        !           833: }
        !           834: 
        !           835: mifelse(pps)
        !           836: STRING **pps;
        !           837: {
        !           838:        if (cmpstr(pps[1], pps[2]))
        !           839:                pushstr(pps[3]);
        !           840:        else if (moreargs(pps, 5))
        !           841:                if (cmpstr(pps[4], pps[5]))
        !           842:                        pushstr(pps[6]);
        !           843:                else if (moreargs(pps, 8))
        !           844:                        if (cmpstr(pps[7], pps[8]))
        !           845:                                pushstr(pps[9]);
        !           846:                        else
        !           847:                                return;
        !           848:                else
        !           849:                        pushstr(pps[7]);
        !           850:        else
        !           851:                pushstr(pps[4]);
        !           852: }
        !           853: 
        !           854: moreargs(pps, n)
        !           855: STRING **pps;
        !           856: register int n;
        !           857: {
        !           858:        register int i;
        !           859: 
        !           860:        for (i=n; i<=9; i++)
        !           861:                if (pps[i] != NULL)
        !           862:                        return (1);
        !           863:        return (0);
        !           864: }
        !           865: 
        !           866: minclude(pps)
        !           867: STRING **pps;
        !           868: {
        !           869:        if (msinclude(pps))
        !           870:                return;
        !           871:        errorp(1, "cannot open %s", pps[1]!=NULL? pps[1]->s_body : NULL);
        !           872: }
        !           873: 
        !           874: mincr(pps)
        !           875: STRING **pps;
        !           876: {
        !           877:        long atol();
        !           878: 
        !           879:        pushnum((long)((pps[1] != NULL)? atol(pps[1]->s_body)+1 : 1));
        !           880: }
        !           881: 
        !           882: mdecr(pps)
        !           883: STRING **pps;
        !           884: {
        !           885:        long atol();
        !           886: 
        !           887:        pushnum((long)((pps[1] != NULL)? atol(pps[1]->s_body)-1 : -1));
        !           888: }
        !           889: 
        !           890: mindex(pps)
        !           891: STRING **pps;
        !           892: {
        !           893:        register char *pc, *pf;
        !           894:        register int ln;
        !           895:        long v;
        !           896:        char *index();
        !           897: 
        !           898:        if (pps[2] == NULL)
        !           899:                v = 0;
        !           900:        else if (pps[1] == NULL)
        !           901:                v = -1;
        !           902:        else {
        !           903:                pc = pps[1]->s_body;
        !           904:                ln = strlen(pf = pps[2]->s_body);
        !           905:                while ((pc=index(pc, *pf))!=NULL && strncmp(pc, pf, ln))
        !           906:                        ++pc;
        !           907:                v = (pc != NULL)? (long)(pc-pps[1]->s_body) : -1;
        !           908:        }
        !           909:        pushnum(v);
        !           910: }
        !           911: 
        !           912: mlen(pps)
        !           913: STRING **pps;
        !           914: {
        !           915:        pushnum((long)((pps[1] != NULL)? pps[1]->s_next-pps[1]->s_body : 0));
        !           916: }
        !           917: 
        !           918: mmaketemp(pps)
        !           919: STRING **pps;
        !           920: {
        !           921:        register char *pc;
        !           922:        if (pps[1]==NULL || strlen(pc = pps[1]->s_body)<TMPMIN)
        !           923:                return;
        !           924:        mktemp(pc);
        !           925:        pushstr(pps[1]);
        !           926: }
        !           927: 
        !           928: msinclude(pps)
        !           929: STRING **pps;
        !           930: {
        !           931:        return (pushfile((pps[1] != NULL)? pps[1]->s_body : NULL));
        !           932: }
        !           933: 
        !           934: msubstr(pps)
        !           935: STRING **pps;
        !           936: {
        !           937:        register char *pc, *pb, *pe;
        !           938:        int len, n, s;
        !           939:        STRING *a;
        !           940: 
        !           941:        if (pps[1] == NULL)
        !           942:                return;
        !           943:        len = strlen(pc = pps[1]->s_body);
        !           944:        if (pps[2] == NULL) {
        !           945:                n = (pps[3] != NULL)? atoi(pps[3]->s_body) : len;
        !           946:                s = (n>0)? 0 : -1;
        !           947:        } else {
        !           948:                s = atoi(pps[2]->s_body);
        !           949:                n = (pps[3] != NULL)? atoi(pps[3]->s_body) : (s>0)? len : -len;
        !           950:        }
        !           951:        if (n == 0)
        !           952:                return;
        !           953:        pe = pc + len;
        !           954:        if (s < 0)
        !           955:                s += len;
        !           956:        if (n < 0) {
        !           957:                s += n + 1;
        !           958:                n = -n;
        !           959:        }
        !           960:        a = makestr();
        !           961:        for (pb = pc + s; n--; ++pb)
        !           962:                if (pb>=pc && pb<=pe)
        !           963:                        appendstr(a, *pb);
        !           964:        pushstr(a);
        !           965:        decstr(a);
        !           966: }
        !           967: 
        !           968: msyscmd(pps)
        !           969: STRING **pps;
        !           970: {
        !           971:        if (pps[1])
        !           972:                system(pps[1]->s_body);
        !           973: }
        !           974: 
        !           975: mtranslit(pps)
        !           976: STRING **pps;
        !           977: {
        !           978:        register char *pc, *pt, *pr;
        !           979:        char c = '\0';
        !           980:        STRING *a;
        !           981: 
        !           982:        if (pps[1]==NULL || pps[2]==NULL)
        !           983:                return;
        !           984:        a = makestr();
        !           985:        pc = pps[1]->s_body;
        !           986:        do {
        !           987:                pt = pps[2]->s_body;
        !           988:                pr = (pps[3] != NULL)? pps[3]->s_body : &c;
        !           989:                do {
        !           990:                        if (*pc == *pt)
        !           991:                                break;
        !           992: 
        !           993:                        if (*pr)
        !           994:                                ++pr;
        !           995:                } while (*++pt);
        !           996:                if (*pt) {
        !           997:                        if (*pr)
        !           998:                                appendstr(a, *pr);
        !           999:                } else
        !          1000:                        appendstr(a, *pc);
        !          1001:        } while (*++pc);
        !          1002:        pushstr(a);
        !          1003:        decstr(a);
        !          1004: }
        !          1005: 
        !          1006: mundefine(pps)
        !          1007: STRING **pps;
        !          1008: {
        !          1009:        register ENTRY *e, *ep = NULL;
        !          1010:        register int hash;
        !          1011: 
        !          1012:        if (pps[1] == NULL)
        !          1013:                return;
        !          1014:        hash = pps[1]->s_hash;
        !          1015:        for (e = e_root[hash % HASHSZ]; e != NULL; e = e->e_next)
        !          1016:                if (e->e_name->s_hash == hash
        !          1017:                &&  strcmp(e->e_name->s_body, pps[1]->s_body) == 0)
        !          1018:                        break;
        !          1019:                else
        !          1020:                        ep = e;
        !          1021:        if (e == NULL)
        !          1022:                return;
        !          1023:        if (e->e_type == MACD)
        !          1024:                decstr(e->e_at.e_pstr);
        !          1025:        decstr(e->e_name);
        !          1026:        if (ep != NULL)
        !          1027:                ep->e_next = e->e_next;
        !          1028:        else
        !          1029:                e_root[hash % HASHSZ] = e->e_next;
        !          1030:        free(e);
        !          1031: }
        !          1032: 
        !          1033: mundivert(pps)
        !          1034: STRING **pps;
        !          1035: {
        !          1036:        register i, f = 0;
        !          1037: 
        !          1038:        if (pps)
        !          1039:                for (i = 1; i <= 9; i++)
        !          1040:                        if (pps[i]) {
        !          1041:                                undiv(atoi(pps[i]->s_body));
        !          1042:                                f = 1;
        !          1043:                        }
        !          1044:        if (pps==NULL || f==0)
        !          1045:                for (i = 1; i <= 9; i++)
        !          1046:                        undiv(i);
        !          1047: }
        !          1048: 
        !          1049: undiv(n)
        !          1050: register int n;
        !          1051: {
        !          1052:        register int c;
        !          1053:        register FILE *fp;
        !          1054: 
        !          1055:        if (n>0 && n<=9 && (fp=outfile[n].fp) != NULL && ofnum!=n) {
        !          1056:                fclose(fp);
        !          1057:                if ((fp=fopen(outfile[n].name, "r")) == NULL)
        !          1058:                        errorp(1, "cannot open %s", outfile[n].name);
        !          1059:                while ((c=getc(fp)) != EOF)
        !          1060:                        outc(c);
        !          1061:                fclose(fp);
        !          1062:                unlink(outfile[n].name);
        !          1063:                free(outfile[n].name);
        !          1064:                outfile[n].name = outfile[n].fp = NULL;
        !          1065:        }
        !          1066: }

unix.superglobalmegacorp.com

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