Annotation of 43BSDReno/pgrm/m4/eval.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1989 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Ozan Yigit.
                      7:  *
                      8:  * Redistribution and use in source and binary forms are permitted
                      9:  * provided that: (1) source distributions retain this entire copyright
                     10:  * notice and comment, and (2) distributions including binaries display
                     11:  * the following acknowledgement:  ``This product includes software
                     12:  * developed by the University of California, Berkeley and its contributors''
                     13:  * in the documentation or other materials provided with the distribution
                     14:  * and in all advertising materials mentioning features or use of this
                     15:  * software. Neither the name of the University nor the names of its
                     16:  * contributors may be used to endorse or promote products derived
                     17:  * from this software without specific prior written permission.
                     18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     20:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     21:  */
                     22: 
                     23: #ifndef lint
                     24: static char sccsid[] = "@(#)eval.c     5.3 (Berkeley) 6/1/90";
                     25: #endif /* not lint */
                     26: 
                     27: /*
                     28:  * eval.c
                     29:  * Facility: m4 macro processor
                     30:  * by: oz
                     31:  */
                     32: 
                     33: #include "mdef.h"
                     34: #include "extr.h"
                     35: 
                     36: extern ndptr lookup();
                     37: extern char *strsave();
                     38: extern char *mktemp();
                     39: 
                     40: /*
                     41:  * eval - evaluate built-in macros.
                     42:  *       argc - number of elements in argv.
                     43:  *       argv - element vector :
                     44:  *                     argv[0] = definition of a user
                     45:  *                               macro or nil if built-in.
                     46:  *                     argv[1] = name of the macro or
                     47:  *                               built-in.
                     48:  *                     argv[2] = parameters to user-defined
                     49:  *                        .      macro or built-in.
                     50:  *                        .
                     51:  *
                     52:  * Note that the minimum value for argc is 3. A call in the form
                     53:  * of macro-or-builtin() will result in:
                     54:  *                     argv[0] = nullstr
                     55:  *                     argv[1] = macro-or-builtin
                     56:  *                     argv[2] = nullstr
                     57:  *
                     58:  */
                     59: 
                     60: eval (argv, argc, td)
                     61: register char *argv[];
                     62: register int argc;
                     63: register int  td;
                     64: {
                     65:        register int c, n;
                     66:        static int sysval;
                     67: 
                     68: #ifdef DEBUG
                     69:        printf("argc = %d\n", argc);
                     70:        for (n = 0; n < argc; n++)
                     71:                printf("argv[%d] = %s\n", n, argv[n]);
                     72: #endif
                     73:        /*
                     74:         * if argc == 3 and argv[2] is null,
                     75:         * then we have macro-or-builtin() type call.
                     76:         * We adjust argc to avoid further checking..
                     77:         *
                     78:         */
                     79:        if (argc == 3 && !*(argv[2]))
                     80:                argc--;
                     81: 
                     82:        switch (td & ~STATIC) {
                     83: 
                     84:        case DEFITYPE:
                     85:                if (argc > 2)
                     86:                        dodefine(argv[2], (argc > 3) ? argv[3] : null);
                     87:                break;
                     88: 
                     89:        case PUSDTYPE:
                     90:                if (argc > 2)
                     91:                        dopushdef(argv[2], (argc > 3) ? argv[3] : null);
                     92:                break;
                     93: 
                     94:        case DUMPTYPE:
                     95:                dodump(argv, argc);
                     96:                break;
                     97: 
                     98:        case EXPRTYPE:
                     99:                /*
                    100:                 * doexpr - evaluate arithmetic expression
                    101:                 *
                    102:                 */
                    103:                if (argc > 2)
                    104:                        pbnum(expr(argv[2]));
                    105:                break;
                    106: 
                    107:        case IFELTYPE:
                    108:                if (argc > 4)
                    109:                        doifelse(argv, argc);
                    110:                break;
                    111: 
                    112:        case IFDFTYPE:
                    113:                /*
                    114:                 * doifdef - select one of two alternatives based
                    115:                 *           on the existence of another definition
                    116:                 */
                    117:                if (argc > 3) {
                    118:                        if (lookup(argv[2]) != nil)
                    119:                                pbstr(argv[3]);
                    120:                        else if (argc > 4)
                    121:                                pbstr(argv[4]);
                    122:                }
                    123:                break;
                    124: 
                    125:        case LENGTYPE:
                    126:                /*
                    127:                 * dolen - find the length of the argument
                    128:                 *
                    129:                 */
                    130:                if (argc > 2)
                    131:                        pbnum((argc > 2) ? strlen(argv[2]) : 0);
                    132:                break;
                    133: 
                    134:        case INCRTYPE:
                    135:                /*
                    136:                 * doincr - increment the value of the argument
                    137:                 *
                    138:                 */
                    139:                if (argc > 2)
                    140:                        pbnum(atoi(argv[2]) + 1);
                    141:                break;
                    142: 
                    143:        case DECRTYPE:
                    144:                /*
                    145:                 * dodecr - decrement the value of the argument
                    146:                 *
                    147:                 */
                    148:                if (argc > 2)
                    149:                        pbnum(atoi(argv[2]) - 1);
                    150:                break;
                    151: 
                    152:        case SYSCTYPE:
                    153:                /*
                    154:                 * dosys - execute system command
                    155:                 *
                    156:                 */
                    157:                if (argc > 2)
                    158:                        sysval = system(argv[2]);
                    159:                break;
                    160: 
                    161:        case SYSVTYPE:
                    162:                /*
                    163:                 * dosysval - return value of the last system call.
                    164:                 *
                    165:                 */
                    166:                pbnum(sysval);
                    167:                break;
                    168: 
                    169:        case INCLTYPE:
                    170:                if (argc > 2)
                    171:                        if (!doincl(argv[2])) {
                    172:                                fprintf(stderr,"m4: %s: ",argv[2]);
                    173:                                error("cannot open for read.");
                    174:                        }
                    175:                break;
                    176: 
                    177:        case SINCTYPE:
                    178:                if (argc > 2)
                    179:                        (void) doincl(argv[2]);
                    180:                break;
                    181: #ifdef EXTENDED
                    182:        case PASTTYPE:
                    183:                if (argc > 2)
                    184:                        if (!dopaste(argv[2])) {
                    185:                                fprintf(stderr,"m4: %s: ",argv[2]);
                    186:                                error("cannot open for read.");
                    187:                        }
                    188:                break;
                    189: 
                    190:        case SPASTYPE:
                    191:                if (argc > 2)
                    192:                        (void) dopaste(argv[2]);
                    193:                break;
                    194: #endif
                    195:        case CHNQTYPE:
                    196:                dochq(argv, argc);
                    197:                break;
                    198: 
                    199:        case CHNCTYPE:
                    200:                dochc(argv, argc);
                    201:                break;
                    202: 
                    203:        case SUBSTYPE:
                    204:                /*
                    205:                 * dosub - select substring
                    206:                 *
                    207:                 */
                    208:                if (argc > 3)
                    209:                        dosub(argv,argc);
                    210:                break;
                    211: 
                    212:        case SHIFTYPE:
                    213:                /*
                    214:                 * doshift - push back all arguments except the
                    215:                 *           first one (i.e. skip argv[2])
                    216:                 */
                    217:                if (argc > 3) {
                    218:                        for (n = argc-1; n > 3; n--) {
                    219:                                putback(rquote);
                    220:                                pbstr(argv[n]);
                    221:                                putback(lquote);
                    222:                                putback(',');
                    223:                        }
                    224:                        putback(rquote);
                    225:                        pbstr(argv[3]);
                    226:                        putback(lquote);
                    227:                }
                    228:                break;
                    229: 
                    230:        case DIVRTYPE:
                    231:                if (argc > 2 && (n = atoi(argv[2])) != 0)
                    232:                        dodiv(n);
                    233:                else {
                    234:                        active = stdout;
                    235:                        oindex = 0;
                    236:                }
                    237:                break;
                    238: 
                    239:        case UNDVTYPE:
                    240:                doundiv(argv, argc);
                    241:                break;
                    242: 
                    243:        case DIVNTYPE:
                    244:                /*
                    245:                 * dodivnum - return the number of current
                    246:                 * output diversion
                    247:                 *
                    248:                 */
                    249:                pbnum(oindex);
                    250:                break;
                    251: 
                    252:        case UNDFTYPE:
                    253:                /*
                    254:                 * doundefine - undefine a previously defined
                    255:                 *              macro(s) or m4 keyword(s).
                    256:                 */
                    257:                if (argc > 2)
                    258:                        for (n = 2; n < argc; n++)
                    259:                                remhash(argv[n], ALL);
                    260:                break;
                    261: 
                    262:        case POPDTYPE:
                    263:                /*
                    264:                 * dopopdef - remove the topmost definitions of
                    265:                 *            macro(s) or m4 keyword(s).
                    266:                 */
                    267:                if (argc > 2)
                    268:                        for (n = 2; n < argc; n++)
                    269:                                remhash(argv[n], TOP);
                    270:                break;
                    271: 
                    272:        case MKTMTYPE:
                    273:                /*
                    274:                 * dotemp - create a temporary file
                    275:                 *
                    276:                 */
                    277:                if (argc > 2)
                    278:                        pbstr(mktemp(argv[2]));
                    279:                break;
                    280: 
                    281:        case TRNLTYPE:
                    282:                /*
                    283:                 * dotranslit - replace all characters in the
                    284:                 *              source string that appears in
                    285:                 *              the "from" string with the corresponding
                    286:                 *              characters in the "to" string.
                    287:                 *
                    288:                 */
                    289:                if (argc > 3) {
                    290:                        char temp[MAXTOK];
                    291:                        if (argc > 4)
                    292:                                map(temp, argv[2], argv[3], argv[4]);
                    293:                        else
                    294:                                map(temp, argv[2], argv[3], null);
                    295:                        pbstr(temp);
                    296:                }
                    297:                else
                    298:                    if (argc > 2)
                    299:                        pbstr(argv[2]);
                    300:                break;
                    301: 
                    302:        case INDXTYPE:
                    303:                /*
                    304:                 * doindex - find the index of the second argument
                    305:                 *           string in the first argument string.
                    306:                 *           -1 if not present.
                    307:                 */
                    308:                pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
                    309:                break;
                    310: 
                    311:        case ERRPTYPE:
                    312:                /*
                    313:                 * doerrp - print the arguments to stderr file
                    314:                 *
                    315:                 */
                    316:                if (argc > 2) {
                    317:                        for (n = 2; n < argc; n++)
                    318:                                fprintf(stderr,"%s ", argv[n]);
                    319:                        fprintf(stderr, "\n");
                    320:                }
                    321:                break;
                    322: 
                    323:        case DNLNTYPE:
                    324:                /*
                    325:                 * dodnl - eat-up-to and including newline
                    326:                 *
                    327:                 */
                    328:                while ((c = gpbc()) != '\n' && c != EOF)
                    329:                        ;
                    330:                break;
                    331: 
                    332:        case M4WRTYPE:
                    333:                /*
                    334:                 * dom4wrap - set up for wrap-up/wind-down activity
                    335:                 *
                    336:                 */
                    337:                m4wraps = (argc > 2) ? strsave(argv[2]) : null;
                    338:                break;
                    339: 
                    340:        case EXITTYPE:
                    341:                /*
                    342:                 * doexit - immediate exit from m4.
                    343:                 *
                    344:                 */
                    345:                exit((argc > 2) ? atoi(argv[2]) : 0);
                    346:                break;
                    347: 
                    348:        case DEFNTYPE:
                    349:                if (argc > 2)
                    350:                        for (n = 2; n < argc; n++)
                    351:                                dodefn(argv[n]);
                    352:                break;
                    353: 
                    354:        default:
                    355:                error("m4: major botch in eval.");
                    356:                break;
                    357:        }
                    358: }

unix.superglobalmegacorp.com

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