Annotation of coherent/d/bin/awk/awk3.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * AWK
                      3:  * Part 3 - execution of the compiled code.
                      4:  */
                      5: 
                      6: #include "awk.h"
                      7: #include "y.tab.h"
                      8: 
                      9: static CHAR    *sb;            /* String beginning -- evalre */
                     10: static CHAR    toodeep[] = "For/while nesting too deep";
                     11: CHAR   *reexec();
                     12: 
                     13: /*
                     14:  * Called for each input file
                     15:  * Also, called before the first file
                     16:  * and after the last file.
                     17:  * This routine executes the code for
                     18:  * each input line.
                     19:  */
                     20: awk(np, fp, fn)
                     21: register NODE *np;
                     22: register FILE *fp;
                     23: CHAR *fn;
                     24: {
                     25:        CHAR ibuf[MAXRECORD];
                     26: 
                     27:        sassign(FILENAMEp, fn);
                     28:        if (fp == NULL) {
                     29:                lineno = 0;
                     30:                execute(np, NULL);
                     31:        } else {
                     32:                if (fp != stdin)
                     33:                        setbuf(fp, inbuf);
                     34:                lineno = 1;
                     35:                setjmp(nextenv);
                     36:                while (awkinput(ibuf, MAXRECORD, fp) != NULL) {
                     37:                        iassign(NRp, NRp->t_INT+1);
                     38:                        execute(np, ibuf);
                     39:                }
                     40:                if (fp != stdin)
                     41:                        fclose(fp);
                     42:        }
                     43: }
                     44: 
                     45: /*
                     46:  * Read a record in for
                     47:  * awk.
                     48:  */
                     49: STRING
                     50: awkinput(as, lim, fp)
                     51: STRING as;
                     52: unsigned lim;
                     53: register FILE *fp;
                     54: {
                     55:        register int c;
                     56:        register CHAR *s;
                     57:        register int rs;
                     58:        register STRING ret;
                     59:        register int nf = 0;
                     60:        register int spcflag = 0;
                     61: 
                     62:        if ((rs = RS[0]) == '\0') {
                     63:                rs = '\n';
                     64:                spcflag++;
                     65:        }
                     66:        s = as;
                     67:        while (--lim>0 && (c = getc(fp))!=EOF) {
                     68:                if (c == '\n')
                     69:                        lineno++;
                     70:                if (c == rs)
                     71:                        if (!spcflag || s==as || s[-1]=='\n')
                     72:                                break;
                     73:                *s++ = c;
                     74:        }
                     75:        *s = '\0';
                     76:        ret = c==EOF && s==as ? NULL : as;
                     77:        s = as;
                     78:        if (whitesw) {
                     79:                for (;;) {
                     80:                        while (FSMAP[c = *s])   /* pass spaces */
                     81:                                s++;
                     82:                        if (c == '\0')          /* if end of line no field */
                     83:                                break;
                     84:                        nf++;
                     85:                        while ((c = *s) != '\0' && !FSMAP[c]) /* pass field */
                     86:                                s++;
                     87:                        if (c == '\0')
                     88:                                break;
                     89:                }
                     90:        }
                     91:        else if (*s) {
                     92:                for (;;) {
                     93:                        nf++;
                     94:                        while ((c = *s) != '\0' && !FSMAP[c])
                     95:                                s++;
                     96:                        if (c == '\0')
                     97:                                break;
                     98:                        if (FSMAP[c = *s])      /* pass delimeter */
                     99:                                s++;
                    100:                        if (c == '\0')
                    101:                                break;
                    102:                }
                    103:        }
                    104:        iassign(NFp, (INT)nf);
                    105:        return (ret);
                    106: }
                    107: 
                    108: /*
                    109:  * This is the root of the execution tree
                    110:  * that handles patterns and actions
                    111:  * and lists of the above.
                    112:  * `s' is the input string.
                    113:  * Free all outstanding nodes accumulated
                    114:  * during execution at the end of this
                    115:  * routine (each input line).
                    116:  */
                    117: execute(np, s)
                    118: register NODE *np;
                    119: register STRING s;
                    120: {
                    121:        register NODE *xp;
                    122: 
                    123:        inline = s;
                    124:        while (np != NULL) {
                    125:                if (np->n_op == ALIST) {
                    126:                        xp = np->n_O1;
                    127:                        np = np->n_O2;
                    128:                } else {
                    129:                        xp = np;
                    130:                        np = NULL;
                    131:                }
                    132:                if (xp->n_op != AROOT)
                    133:                        awkerr("Bad op in execute %d", xp->n_op);
                    134:                if (xp->n_O1 != NULL) {
                    135:                        if (evalpat(xp->n_O1))
                    136:                                if (xp->n_O2 == NULL) {
                    137:                                        if (!beginflag && !endflag)
                    138:                                                xprint(&xfield0, NULL);
                    139:                                } else
                    140:                                        evalact(xp->n_O2);
                    141:                } else if (!beginflag && !endflag)
                    142:                        evalact(xp->n_O2);
                    143:        }
                    144:        while ((np = tempnodes) != NULL) {
                    145:                tempnodes = np->t_next;
                    146:                freenode(np);
                    147:        }
                    148:        if (inline != s)
                    149:                free(inline);
                    150: }
                    151: 
                    152: /*
                    153:  * Evaluate the pattern half
                    154:  * of the expression.
                    155:  */
                    156: evalpat(np)
                    157: register NODE *np;
                    158: {
                    159:        register int ret = 0;
                    160: 
                    161:        if ((beginflag && np->n_op==ABEGIN) || (endflag && np->n_op==AEND))
                    162:                return (1);
                    163:        if (beginflag || endflag)
                    164:                return (0);
                    165:        switch (np->n_op) {
                    166:        case ABEGIN:
                    167:        case AEND:
                    168:                return (0);
                    169: 
                    170:        case ARANGE:
                    171:                if (np->n_flag==0 && evalpat(np->n_O1)) {
                    172:                        np->n_flag++;
                    173:                        ret = 1;
                    174:                } else if (np->n_flag == 1) {
                    175:                        if (evalpat(np->n_O2))
                    176:                                np->n_flag = 0;
                    177:                        ret = 1;
                    178:                }
                    179:                break;
                    180: 
                    181:        default:
                    182:                ret = evalint(np);
                    183:                break;
                    184:        }
                    185:        return (ret);
                    186: }
                    187: 
                    188: /*
                    189:  * Evaluate the action part of the
                    190:  * statement.
                    191:  */
                    192: evalact(anp)
                    193: register NODE *anp;
                    194: {
                    195:        register NODE *np;
                    196:        register int i;
                    197: 
                    198: again:
                    199:        if (anp == NULL)
                    200:                return;
                    201:        if (anp->n_op == ALIST) {
                    202:                np = anp->n_O1;
                    203:                anp = anp->n_O2;
                    204:        } else {
                    205:                np = anp;
                    206:                anp = NULL;
                    207:        }
                    208:        switch (np->n_op) {
                    209:        case AIF:
                    210:                if (evalint(np->n_O1) != 0)
                    211:                        evalact(np->n_O2);
                    212:                else if (np->n_O3 != NULL)
                    213:                        evalact(np->n_O3);
                    214:                break;
                    215: 
                    216:        case AWHILE:
                    217:                if (++fwlevel >= NNEST)
                    218:                        awkerr(toodeep);
                    219:                while (evalint(np->n_O1) != 0) {
                    220:                        if ((i = setjmp(fwenv[fwlevel])) == ABREAK)
                    221:                                break;
                    222:                        else if (i == ACONTIN)
                    223:                                continue;
                    224:                        evalact(np->n_O2);
                    225:                }
                    226:                fwlevel--;
                    227:                break;
                    228: 
                    229:        case AFOR:
                    230:                if (++fwlevel >= NNEST)
                    231:                        awkerr(toodeep);
                    232:                if (np->n_O1 != NULL)
                    233:                        evalact(np->n_O1);
                    234:                for ( ; evalint(np->n_O2); evalact(np->n_O3)) {
                    235:                        if ((i = setjmp(fwenv[fwlevel])) == ABREAK)
                    236:                                break;
                    237:                        else if (i == ACONTIN)
                    238:                                continue;
                    239:                        evalact(np->n_O4);
                    240:                }
                    241:                fwlevel--;
                    242:                break;
                    243: 
                    244:        case AFORIN:
                    245:                if (++fwlevel >= NNEST)
                    246:                        awkerr(toodeep);
                    247:                xforin(np->n_O1, np->n_O2, np->n_O3);
                    248:                fwlevel--;
                    249:                break;
                    250: 
                    251:        case ABREAK:
                    252:        case ACONTIN:
                    253:                i = np->n_op;
                    254:                if (fwlevel < 0)
                    255:                        awkwarn("No for or while for %s",
                    256:                            i==ABREAK ? "break" : "continue");
                    257:                else
                    258:                        longjmp(fwenv[fwlevel], i);
                    259:                break;
                    260: 
                    261:        case ANEXT:
                    262:                longjmp(nextenv, 1);
                    263:                break;
                    264: 
                    265:        case AEXIT:
                    266:                if (!exitflag)
                    267:                        awkexit(0);
                    268:                break;
                    269: 
                    270:        case APRINT:
                    271:                xprint(np->n_O1, np->n_O2);
                    272:                break;
                    273: 
                    274:        case APRINTF:
                    275:                xprintf(np->n_O1, np->n_O2, NULL);
                    276:                break;
                    277: 
                    278:        default:
                    279:                evalexpr(np);
                    280:        }
                    281:        while ((np = tempnodes) != NULL) {
                    282:                tempnodes = np->t_next;
                    283:                freenode(np);
                    284:        }
                    285:        goto again;
                    286: }
                    287: 
                    288: /*
                    289:  * Evaluate an expression.
                    290:  */
                    291: NODE *
                    292: evalexpr(np)
                    293: register NODE *np;
                    294: {
                    295:        register NODE *tnp;
                    296:        register int i;
                    297: 
                    298:        switch (np->n_op) {
                    299:        case ATERM:
                    300:                break;
                    301: 
                    302:        case AARRAY:
                    303:                np = xarray(np->n_O1, np->n_O2);
                    304:                break;
                    305: 
                    306:        case AFIELD:
                    307:                np = xfield((int)evalint(np->n_O1), NULL);
                    308:                break;
                    309: 
                    310:        case AFUNC:
                    311:                i = fnargs(tnp = np->n_O2);
                    312:                np = np->n_O1;
                    313:                if (i<np->t_MINARG || (np->t_MAXARG!=-1 && i>np->t_MAXARG))
                    314:                        awkerr("Too %s arguments: %s",
                    315:                            i<np->t_MINARG ? "few" : "many", np->t_name);
                    316:                np = (*np->t_FUNC)(tnp, i);
                    317:                break;
                    318: 
                    319:        case AREMAT:
                    320:        case ARENMAT:
                    321:                i = evalre(np->n_O2, evalstring(np->n_O1));
                    322:                if (np->n_op == ARENMAT)
                    323:                        i = !i;
                    324:                np = inode((INT)i);
                    325:                break;
                    326: 
                    327:        case ARE:
                    328:                np = inode((INT)evalre(np->n_O1, inline));
                    329:                break;
                    330: 
                    331:        case ACONC:
                    332:                np = xconc(np->n_O1, np->n_O2);
                    333:                break;
                    334: 
                    335:        case AADD:
                    336:                np = xadd(evalexpr(np->n_O1), evalexpr(np->n_O2));
                    337:                break;
                    338: 
                    339:        case ASUB:
                    340:                np = xsub(evalexpr(np->n_O1), evalexpr(np->n_O2));
                    341:                break;
                    342: 
                    343:        case AMUL:
                    344:                np = xmul(evalexpr(np->n_O1), evalexpr(np->n_O2));
                    345:                break;
                    346: 
                    347:        case ANEG:
                    348:                np = xneg(evalexpr(np->n_O1));
                    349:                break;
                    350: 
                    351:        case ADIV:
                    352:                np = xdiv(evalexpr(np->n_O1), evalexpr(np->n_O2));
                    353:                break;
                    354: 
                    355:        case AMOD:
                    356:                np = xmod(evalexpr(np->n_O1), evalexpr(np->n_O2));
                    357:                break;
                    358: 
                    359:        case AEQ:
                    360:        case ANE:
                    361:        case AGT:
                    362:        case AGE:
                    363:        case ALT:
                    364:        case ALE:
                    365:                np = xcmp(np->n_O1, np->n_O2, np->n_op);
                    366:                break;
                    367: 
                    368:        case AOROR:
                    369:                np = inode((INT)(evalint(np->n_O1) || evalint(np->n_O2)));
                    370:                break;
                    371: 
                    372:        case AANDAND:
                    373:                np = inode((INT)(evalint(np->n_O1) && evalint(np->n_O2)));
                    374:                break;
                    375: 
                    376:        case ANOT:
                    377:                np = inode((INT)(!evalint(np->n_O1)));
                    378:                break;
                    379: 
                    380:        case AASGN:
                    381:                np = xassign(np->n_O1, evalexpr(np->n_O2));
                    382:                break;
                    383: 
                    384:        case AINCA:
                    385:                np = xinca(np->n_O1);
                    386:                break;
                    387: 
                    388:        case ADECA:
                    389:                np = xdeca(np->n_O1);
                    390:                break;
                    391: 
                    392:        default:
                    393:                awkerr("Bad op in evalexpr %d", np->n_op);
                    394:        }
                    395:        return (np);
                    396: }
                    397: 
                    398: /*
                    399:  * Evaluate an expression and
                    400:  * return the resultant string.
                    401:  */
                    402: CHAR *
                    403: evalstring(np)
                    404: register NODE *np;
                    405: {
                    406:        static CHAR numbuf[100];
                    407: 
                    408:        np = evalexpr(np);
                    409:        if (np->n_flag & T_NUM) {
                    410:                if (np->n_flag & T_INT)
                    411:                        sprintf(numbuf, "%ld", np->t_INT);
                    412:                else
                    413:                        sprintf(numbuf, "%.6g", np->t_FLOAT);
                    414:                return (numbuf);
                    415:        } else
                    416:                return (np->t_STRING);
                    417: }
                    418: 
                    419: /*
                    420:  * Evaluate an expression and
                    421:  * return the resultant INT.
                    422:  */
                    423: INT
                    424: evalint(np)
                    425: register NODE *np;
                    426: {
                    427:        np = evalexpr(np);
                    428:        if (np->n_flag & T_NUM) {
                    429:                if (np->n_flag & T_INT)
                    430:                        return (np->t_INT); else
                    431:                        return (np->t_FLOAT);
                    432:        } else
                    433:                return (stoi(np->t_STRING));
                    434: }
                    435: 
                    436: /*
                    437:  * Evaluate an expression and
                    438:  * return the resultant FLOAT.
                    439:  */
                    440: FLOAT
                    441: evalfloat(np)
                    442: register NODE *np;
                    443: {
                    444:        np = evalexpr(np);
                    445:        if (np->n_flag & T_NUM) {
                    446:                if (np->n_flag & T_INT)
                    447:                        return (np->t_INT); else
                    448:                        return (np->t_FLOAT);
                    449:        } else
                    450:                return (stof(np->t_STRING));
                    451: }
                    452: 
                    453: /*
                    454:  * Called to evaluate a regular expression
                    455:  * with the given string.
                    456:  */
                    457: evalre(np, s)
                    458: register NODE *np;
                    459: register CHAR *s;
                    460: {
                    461:        sb = s;
                    462:        if (np!=NULL && np->n_op==ARBOL)
                    463:                return (reexec(np, s) != NULL);
                    464:        s--;
                    465:        do {
                    466:                if (reexec(np, ++s) != NULL)
                    467:                        return (1);
                    468:        } while (*s!='\n' && *s!='\0');
                    469:        return (0);
                    470: }
                    471: 
                    472: /*
                    473:  * Internal regular expression
                    474:  * execution routines
                    475:  */
                    476: CHAR *
                    477: reexec(np, s)
                    478: register NODE *np;
                    479: register CHAR *s;
                    480: {
                    481:        register c;
                    482:        register CHAR *ss, *es;
                    483: 
                    484:        for ( ; np != NULL; np = np->n_O3)
                    485:                switch (np->n_op) {
                    486:                case ARBOL:
                    487:                        if (s != sb)
                    488:                                return (NULL);
                    489:                        break;
                    490:        
                    491:                case AREOL:
                    492:                        if (*s!='\n' && *s!='\0')
                    493:                                return (NULL);
                    494:                        break;
                    495:        
                    496:                case ARANY:
                    497:                        c = *s++;
                    498:                        if (c=='\n' || c=='\0')
                    499:                                return (NULL);
                    500:                        break;
                    501:        
                    502:                case ARDCHAR:
                    503:                        if (islower(np->n_o1.n_char)) {
                    504:                                if (isupper(c = *s++))
                    505:                                        c = tolower(c);
                    506:                                if (c != np->n_o1.n_char)
                    507:                                        return (NULL);
                    508:                                break;
                    509:                        }
                    510:                case ARCHAR:
                    511:                        c = *s++;
                    512:                        if (c != np->n_o1.n_char)
                    513:                                return (NULL);
                    514:                        break;
                    515:        
                    516:                case ARDCLASS:
                    517:                        if (isupper(c = *s++))
                    518:                                c = tolower(c);
                    519:                        if ((np->n_o1.n_charp[c/NBPC] & (1<<(c%NBPC))) == 0)
                    520:                                return (NULL);
                    521:                        break;
                    522: 
                    523:                case ARCLASS:
                    524:                        c = *s++;
                    525:                        if ((np->n_o1.n_charp[c/NBPC] & (1<<(c%NBPC))) == 0)
                    526:                                return (NULL);
                    527:                        break;
                    528:        
                    529:                case AROR:
                    530:                        ss = s;
                    531:                        if ((s = reexec(np->n_O1, s)) == NULL)
                    532:                                if ((s = reexec(np->n_O2, ss))==NULL)
                    533:                                        return (NULL);
                    534:                        break;
                    535:        
                    536:                case ARCLOS:
                    537:                        ss = s;
                    538:                        while ((es = reexec(np->n_O1, s)) != NULL)
                    539:                                s = es;
                    540:                        while (s >= ss)
                    541:                                if ((es = reexec(np->n_O3, s--))!=NULL)
                    542:                                        return (es);
                    543:                        return (NULL);
                    544:        
                    545:                case ARNECL:
                    546:                        ss = s;
                    547:                        while ((es = reexec(np->n_O1, s)) != NULL)
                    548:                                s = es;
                    549:                        while (s > ss)
                    550:                                if ((es = reexec(np->n_O3, s--))!=NULL)
                    551:                                        return (es);
                    552:                        return (NULL);
                    553:        
                    554:                case ARZOCL:
                    555:                        ss = s;
                    556:                        if ((es = reexec(np->n_O1, s)) != NULL)
                    557:                                s = es;
                    558:                        while (s >= ss)
                    559:                                if ((es = reexec(np->n_O3, s--))!=NULL)
                    560:                                        return (es);
                    561:                        return (NULL);
                    562:        
                    563:                default:
                    564:                        awkerr("RE bad op %d", np->n_op);
                    565:                }
                    566:        return (s);
                    567: }

unix.superglobalmegacorp.com

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