Annotation of researchv8dc/cmd/awk/lib.c, revision 1.1

1.1     ! root        1: #define DEBUG
        !             2: #include <stdio.h>
        !             3: #include <ctype.h>
        !             4: #include <errno.h>
        !             5: #include "awk.h"
        !             6: #include "y.tab.h"
        !             7: 
        !             8: #define        getfval(p)      (((p)->tval & (ARR|FLD|REC|NUM)) == NUM ? (p)->fval : real_getfval(p))
        !             9: #define        getsval(p)      (((p)->tval & (ARR|FLD|REC|STR)) == STR ? (p)->sval : real_getsval(p))
        !            10: 
        !            11: extern Awkfloat real_getfval();
        !            12: extern char    *real_getsval();
        !            13: 
        !            14: FILE   *infile = NULL;
        !            15: char   *file   = "";
        !            16: char   recdata[RECSIZE];
        !            17: char   *record = recdata;
        !            18: char   fields[RECSIZE];
        !            19: 
        !            20: #define        MAXFLD  100
        !            21: int    donefld;        /* 1 = implies rec broken into fields */
        !            22: int    donerec;        /* 1 = record is valid (no flds have changed) */
        !            23: 
        !            24: #define        FINIT   { OCELL, CFLD, NULL, "", 0.0, FLD|STR|DONTFREE }
        !            25: 
        !            26: Cell fldtab[MAXFLD] = {                /* room for fields */
        !            27:        { OCELL, CFLD, "$0", recdata, 0.0, REC|STR|DONTFREE},
        !            28:        FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
        !            29:        FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
        !            30:        FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
        !            31:        FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
        !            32:        FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
        !            33:        FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
        !            34:        FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT
        !            35: };
        !            36: int    maxfld  = 0;    /* last used field */
        !            37: int    argno   = 1;    /* current input argument number */
        !            38: 
        !            39: getrec(buf)
        !            40:        char *buf;
        !            41: {
        !            42:        char *getargv();
        !            43:        int c;
        !            44:        extern Awkfloat *ARGC;
        !            45: 
        !            46:        dprintf("RS=<%s>, FS=<%s>\n", *RS, *FS);
        !            47:        donefld = 0;
        !            48:        donerec = 1;
        !            49:        buf[0] = 0;
        !            50:        while (argno < *ARGC) {
        !            51:                dprintf("argno=%d, file=|%s|\n", argno, file);
        !            52:                if (infile == NULL) {   /* have to open a new file */
        !            53:                        file = getargv(argno);
        !            54:                        if (*file == '\0') {    /* it's been zapped */
        !            55:                                argno++;
        !            56:                                continue;
        !            57:                        }
        !            58:                        if (member('=', file)) {        /* a var=value arg */
        !            59:                                setclvar(file);
        !            60:                                argno++;
        !            61:                                continue;
        !            62:                        }
        !            63:                        *FILENAME = file;
        !            64:                        dprintf("opening file %s\n", file);
        !            65:                        if (*file == '-' && *(file+1) == '\0')
        !            66:                                infile = stdin;
        !            67:                        else if ((infile = fopen(file, "r")) == NULL)
        !            68:                                error(FATAL, "can't open %s", file);
        !            69:                        setfval(fnrloc, 0.0);
        !            70:                }
        !            71:                c = readrec(buf, RECSIZE, infile);
        !            72:                if (c != 0 || buf[0] != '\0') { /* normal record */
        !            73:                        if (buf == record) {
        !            74:                                if (!(recloc->tval & DONTFREE))
        !            75:                                        xfree(recloc->sval);
        !            76:                                recloc->sval = record;
        !            77:                                recloc->tval = REC | STR | DONTFREE;
        !            78:                        }
        !            79:                        setfval(nrloc, nrloc->fval+1);
        !            80:                        setfval(fnrloc, fnrloc->fval+1);
        !            81:                        return 1;
        !            82:                }
        !            83:                /* EOF arrived on this file; set up next */
        !            84:                if (infile != stdin)
        !            85:                        fclose(infile);
        !            86:                infile = NULL;
        !            87:                argno++;
        !            88:        }
        !            89:        return 0;       /* true end of file */
        !            90: }
        !            91: 
        !            92: readrec(buf, bufsize, inf)     /* read one record into buf */
        !            93:        char *buf;
        !            94:        int bufsize;
        !            95:        FILE *inf;
        !            96: {
        !            97:        register int sep, c;
        !            98:        register char *rr;
        !            99: 
        !           100:        if ((sep = **RS) == 0) {
        !           101:                sep = '\n';
        !           102:                while ((c=getc(inf)) == '\n' && c != EOF)       /* skip leading \n's */
        !           103:                        ;
        !           104:                if (c != EOF)
        !           105:                        ungetc(c, inf);
        !           106:        }
        !           107:        for (rr = buf; ; ) {
        !           108:                for (; (c=getc(inf)) != sep && c != EOF; *rr++ = c)
        !           109:                        ;
        !           110:                if (**RS == sep || c == EOF)
        !           111:                        break;
        !           112:                if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */
        !           113:                        break;
        !           114:                *rr++ = '\n';
        !           115:                *rr++ = c;
        !           116:        }
        !           117:        if (rr > buf + bufsize)
        !           118:                error(FATAL, "input record `%.20s...' too long", buf);
        !           119:        *rr = 0;
        !           120:        dprintf("readrec saw <%s>, returns %d\n", buf, c == EOF && rr == buf ? 0 : 1);
        !           121:        return c == EOF && rr == buf ? 0 : 1;
        !           122: }
        !           123: 
        !           124: char *getargv(n)       /* get ARGV[n] */
        !           125:        int n;
        !           126: {
        !           127:        Cell *x;
        !           128:        char *s, temp[10];
        !           129:        extern Cell **ARGVtab;
        !           130: 
        !           131:        sprintf(temp, "%d", n);
        !           132:        x = setsymtab(temp, "", 0.0, STR, ARGVtab);
        !           133:        s = getsval(x);
        !           134:        dprintf("getargv(%d) returns |%s|\n", n, s, NULL);
        !           135:        return s;
        !           136: }
        !           137: 
        !           138: setclvar(s)    /* set var=value from s */
        !           139: char *s;
        !           140: {
        !           141:        char *p;
        !           142:        Cell *q;
        !           143: 
        !           144:        for (p=s; *p != '='; p++)
        !           145:                ;
        !           146:        *p++ = 0;
        !           147:        q = setsymtab(s, p, 0.0, STR, symtab);
        !           148:        setsval(q, p);
        !           149:        dprintf("command line set %s to |%s|\n", s, p, NULL);
        !           150: }
        !           151: 
        !           152: fldbld()
        !           153: {
        !           154:        register char *r, *fr, sep;
        !           155:        Cell *p, *q;
        !           156:        static char *nullstat = "";
        !           157:        int i;
        !           158: 
        !           159:        if (donefld)
        !           160:                return;
        !           161:        if (!(recloc->tval & STR))
        !           162:                getsval(recloc);
        !           163:        r = recloc->sval;       /* was record! */
        !           164:        fr = fields;
        !           165:        i = 0;  /* number of fields accumulated here */
        !           166:        if (strlen(*FS) > 1) {  /* it's a regular expression */
        !           167:                i = refldbld(r, *FS);
        !           168:        } else if ((sep = **FS) == ' ') {
        !           169:                for (i = 0; ; ) {
        !           170:                        while (*r == ' ' || *r == '\t' || *r == '\n')
        !           171:                                r++;
        !           172:                        if (*r == 0)
        !           173:                                break;
        !           174:                        i++;
        !           175:                        if (i >= MAXFLD)
        !           176:                                break;
        !           177:                        if (!(fldtab[i].tval & DONTFREE))
        !           178:                                xfree(fldtab[i].sval);
        !           179:                        fldtab[i].sval = fr;
        !           180:                        fldtab[i].tval = FLD | STR | DONTFREE;
        !           181:                        do
        !           182:                                *fr++ = *r++;
        !           183:                        while (*r != ' ' && *r != '\t' && *r != '\n' && *r != '\0');
        !           184:                        *fr++ = 0;
        !           185:                }
        !           186:                *fr = 0;
        !           187:        } else if (*r != 0) {   /* if 0, it's a null field */
        !           188:                for (;;) {
        !           189:                        i++;
        !           190:                        if (i >= MAXFLD)
        !           191:                                break;
        !           192:                        if (!(fldtab[i].tval & DONTFREE))
        !           193:                                xfree(fldtab[i].sval);
        !           194:                        fldtab[i].sval = fr;
        !           195:                        fldtab[i].tval = FLD | STR | DONTFREE;
        !           196:                        while (*r != sep && *r != '\n' && *r != '\0')   /* \n always a separator */
        !           197:                                *fr++ = *r++;
        !           198:                        *fr++ = 0;
        !           199:                        if (*r++ == 0)
        !           200:                                break;
        !           201:                }
        !           202:                *fr = 0;
        !           203:        }
        !           204:        /* clean out junk from previous record */
        !           205:        for (p = &fldtab[maxfld], q = &fldtab[i]; p > q; p--) {
        !           206:                if (!(p->tval & DONTFREE))
        !           207:                        xfree(p->sval);
        !           208:                p->tval = FLD | STR | DONTFREE;
        !           209:                p->sval = nullstat;
        !           210:        }
        !           211:        if (i >= MAXFLD)
        !           212:                error(FATAL, "record `%.20s...' has too many fields", record);
        !           213:        maxfld = i;
        !           214:        donefld = 1;
        !           215:        for (p = fldtab+1; p <= fldtab+maxfld; p++) {
        !           216:                if(isnumber(p->sval)) {
        !           217:                        p->fval = atof(p->sval);
        !           218:                        p->tval |= NUM;
        !           219:                }
        !           220:        }
        !           221:        setfval(nfloc, (Awkfloat) maxfld);
        !           222:        if (dbg)
        !           223:                for (p = fldtab; p <= fldtab+maxfld; p++)
        !           224:                        printf("field %d: |%s|\n", p-fldtab, p->sval);
        !           225: }
        !           226: 
        !           227: refldbld(rec, fs)      /* build fields from reg expr in FS */
        !           228:        char *rec, *fs;
        !           229: {
        !           230:        fa *makedfa();
        !           231:        char *fr;
        !           232:        int i, tempstat;
        !           233:        extern char *patbeg;
        !           234:        extern int patlen;
        !           235:        static fa *pfa = NULL;
        !           236:        static char *prevfs = NULL;
        !           237: 
        !           238:        fr = fields;
        !           239:        *fr = '\0';
        !           240:        if (*rec == '\0')
        !           241:                return 0;
        !           242:        if (pfa == NULL) {      /* first time thru */
        !           243:                pfa = makedfa(reparse(fs), 1);
        !           244:                prevfs = tostring(fs);
        !           245:        } else if (strcmp(fs, prevfs) != 0) {   /* new fa needed for new FS */
        !           246:                freefa(pfa);
        !           247:                Free(prevfs);
        !           248:                pfa = makedfa(reparse(fs), 1);
        !           249:                prevfs = tostring(fs);
        !           250:        }
        !           251:        dprintf("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs);
        !           252:        tempstat = pfa->initstat;
        !           253:        for (i = 1; i < MAXFLD; i++) {
        !           254:                if (!(fldtab[i].tval & DONTFREE))
        !           255:                        xfree(fldtab[i].sval);
        !           256:                fldtab[i].tval = FLD | STR | DONTFREE;
        !           257:                fldtab[i].sval = fr;
        !           258:                dprintf("refldbld: i=%d\n", i);
        !           259:                if (nematch(pfa, rec)) {
        !           260:                        pfa->initstat = 2;
        !           261:                        dprintf("match %s (%d chars)\n", patbeg, patlen);
        !           262:                        strncpy(fr, rec, patbeg-rec);
        !           263:                        fr += patbeg - rec + 1;
        !           264:                        *(fr-1) = '\0';
        !           265:                        rec = patbeg + patlen;
        !           266:                } else {
        !           267:                        dprintf("no match %s\n", rec);
        !           268:                        strcpy(fr, rec);
        !           269:                        pfa->initstat = tempstat;
        !           270:                        break;
        !           271:                }
        !           272:        }
        !           273:        return i;               
        !           274: }
        !           275: 
        !           276: recbld()
        !           277: {
        !           278:        int i;
        !           279:        register char *r, *p;
        !           280:        static char rec[RECSIZE];
        !           281: 
        !           282:        if (donerec == 1)
        !           283:                return;
        !           284:        r = rec;
        !           285:        for (i = 1; i <= *NF; i++) {
        !           286:                p = getsval(&fldtab[i]);
        !           287:                while (*r = *p++)
        !           288:                        r++;
        !           289:                if (i < *NF)
        !           290:                        for (p = *OFS; *r = *p++; )
        !           291:                                r++;
        !           292:        }
        !           293:        *r = '\0';
        !           294:        dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL);
        !           295:        recloc->tval = REC | STR | DONTFREE;
        !           296:        recloc->sval = record = rec;
        !           297:        dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL);
        !           298:        if (r > record + RECSIZE)
        !           299:                error(FATAL, "built giant record `%.20s...'", record);
        !           300:        dprintf("recbld = |%s|\n", record, NULL, NULL);
        !           301:        donerec = 1;
        !           302: }
        !           303: 
        !           304: Cell *fieldadr(n)
        !           305: {
        !           306:        if (n < 0 || n >= MAXFLD)
        !           307:                error(FATAL, "trying to access field %d", n);
        !           308:        return(&fldtab[n]);
        !           309: }
        !           310: 
        !           311: int    errorflag       = 0;
        !           312: 
        !           313: yyerror(s, a1, a2, a3, a4, a5, a6, a7)
        !           314:        char *s;
        !           315: {
        !           316:        extern char *cmdname, *curfname;
        !           317:        static int been_here = 0;
        !           318: 
        !           319:        if (been_here++ > 2)
        !           320:                return;
        !           321:        fprintf(stderr, "%s: ", cmdname);
        !           322:        fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
        !           323:        fprintf(stderr, " at source line %d", lineno);
        !           324:        if (curfname != NULL)
        !           325:                fprintf(stderr, " in function %s", curfname);
        !           326:        fprintf(stderr, "\n");
        !           327:        errorflag = 2;
        !           328:        eprint();
        !           329: }
        !           330: 
        !           331: fpecatch()
        !           332: {
        !           333:        error(FATAL, "floating point exception");
        !           334: }
        !           335: 
        !           336: bracecheck()
        !           337: {
        !           338:        extern int bracecnt, brackcnt, parencnt;
        !           339:        int c;
        !           340: 
        !           341:        while ((c = input()) != EOF && c != '\0')
        !           342:                bclass(c);
        !           343:        bcheck2(bracecnt, '{', '}');
        !           344:        bcheck2(brackcnt, '[', ']');
        !           345:        bcheck2(parencnt, '(', ')');
        !           346: }
        !           347: 
        !           348: bcheck2(n, c1, c2)
        !           349: {
        !           350:        if (n == 1)
        !           351:                fprintf(stderr, "\t1 extra %c\n", c1);
        !           352:        else if (n > 1)
        !           353:                fprintf(stderr, "\t%d extra %c's\n", n, c1);
        !           354:        else if (n == -1)
        !           355:                fprintf(stderr, "\t1 extra %c\n", c2);
        !           356:        else if (n < -1)
        !           357:                fprintf(stderr, "\t%d extra %c's\n", -n, c2);
        !           358: }
        !           359: 
        !           360: error(f, s, a1, a2, a3, a4, a5, a6, a7)
        !           361: {
        !           362:        extern Node *curnode;
        !           363:        extern char *cmdname;
        !           364: 
        !           365:        fprintf(stderr, "%s: ", cmdname);
        !           366:        fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
        !           367:        fprintf(stderr, "\n");
        !           368:        if (NR && *NR > 0) {
        !           369:                fprintf(stderr, " input record number %g", *FNR);
        !           370:                if (strcmp(*FILENAME, "-") != 0)
        !           371:                        fprintf(stderr, ", file %s", *FILENAME);
        !           372:                fprintf(stderr, "\n");
        !           373:        }
        !           374:        if (curnode)
        !           375:                fprintf(stderr, " source line number %d\n", curnode->lineno);
        !           376:        else if (lineno)
        !           377:                fprintf(stderr, " source line number %d\n", lineno);
        !           378:        eprint();
        !           379:        if (f) {
        !           380:                if (dbg)
        !           381:                        abort();
        !           382:                exit(2);
        !           383:        }
        !           384: }
        !           385: 
        !           386: eprint()       /* try to print context around error */
        !           387: {
        !           388:        char *p, *q;
        !           389:        int c;
        !           390:        static int been_here = 0;
        !           391:        extern int compile_time;
        !           392:        extern char ebuf[300], *ep;
        !           393: 
        !           394:        if (compile_time == 0 || been_here++ > 0)
        !           395:                return;
        !           396:        p = ep - 1;
        !           397:        if (p > ebuf && *p == '\n')
        !           398:                p--;
        !           399:        for ( ; p > ebuf && *p != '\n' && *p != '\0'; p--)
        !           400:                ;
        !           401:        while (*p == '\n')
        !           402:                p++;
        !           403:        fprintf(stderr, " context is\n\t");
        !           404:        for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--)
        !           405:                ;
        !           406:        while (p < q)
        !           407:                putc(*p++, stderr);
        !           408:        fprintf(stderr, " >>> ");
        !           409:        while (p < ep)
        !           410:                putc(*p++, stderr);
        !           411:        fprintf(stderr, " <<< ");
        !           412:        while ((c = input()) != '\n' && c != '\0' && c != EOF) {
        !           413:                putc(c, stderr);
        !           414:                bclass(c);
        !           415:        }
        !           416:        putc('\n', stderr);
        !           417:        ep = ebuf;
        !           418: }
        !           419: 
        !           420: bclass(c)
        !           421: {
        !           422:        switch (c) {
        !           423:        case '{': bracecnt++; break;
        !           424:        case '}': bracecnt--; break;
        !           425:        case '[': brackcnt++; break;
        !           426:        case ']': brackcnt--; break;
        !           427:        case '(': parencnt++; break;
        !           428:        case ')': parencnt--; break;
        !           429:        }
        !           430: }
        !           431: 
        !           432: double errcheck(x, s)
        !           433:        double x;
        !           434:        char *s;
        !           435: {
        !           436:        extern int errno;
        !           437: 
        !           438:        if (errno == EDOM) {
        !           439:                errno = 0;
        !           440:                error(!FATAL, "%s argument out of domain", s);
        !           441:                x = 1;
        !           442:        } else if (errno == ERANGE) {
        !           443:                errno = 0;
        !           444:                error(!FATAL, "%s result out of range", s);
        !           445:                x = 1;
        !           446:        }
        !           447:        return x;
        !           448: }
        !           449: 
        !           450: PUTS(s) char *s; {
        !           451:        dprintf("%s\n", s, NULL, NULL);
        !           452: }
        !           453: 
        !           454: #define        MAXEXPON        38      /* maximum exponenet for fp number */
        !           455: 
        !           456: isnumber(s)
        !           457: register char *s;
        !           458: {
        !           459:        register d1, d2;
        !           460:        int point;
        !           461:        char *es;
        !           462: 
        !           463:        d1 = d2 = point = 0;
        !           464:        while (*s == ' ' || *s == '\t' || *s == '\n')
        !           465:                s++;
        !           466:        if (*s == '\0')
        !           467:                return(0);      /* empty stuff isn't number */
        !           468:        if (*s == '+' || *s == '-')
        !           469:                s++;
        !           470:        if (!isdigit(*s) && *s != '.')
        !           471:                return(0);
        !           472:        if (isdigit(*s)) {
        !           473:                do {
        !           474:                        d1++;
        !           475:                        s++;
        !           476:                } while (isdigit(*s));
        !           477:        }
        !           478:        if(d1 >= MAXEXPON)
        !           479:                return(0);      /* too many digits to convert */
        !           480:        if (*s == '.') {
        !           481:                point++;
        !           482:                s++;
        !           483:        }
        !           484:        if (isdigit(*s)) {
        !           485:                d2++;
        !           486:                do {
        !           487:                        s++;
        !           488:                } while (isdigit(*s));
        !           489:        }
        !           490:        if (!(d1 || point && d2))
        !           491:                return(0);
        !           492:        if (*s == 'e' || *s == 'E') {
        !           493:                s++;
        !           494:                if (*s == '+' || *s == '-')
        !           495:                        s++;
        !           496:                if (!isdigit(*s))
        !           497:                        return(0);
        !           498:                es = s;
        !           499:                do {
        !           500:                        s++;
        !           501:                } while (isdigit(*s));
        !           502:                if (s - es > 2)
        !           503:                        return(0);
        !           504:                else if (s - es == 2 && 10 * (*es-'0') + *(es+1)-'0' >= MAXEXPON)
        !           505:                        return(0);
        !           506:        }
        !           507:        while (*s == ' ' || *s == '\t' || *s == '\n')
        !           508:                s++;
        !           509:        if (*s == '\0')
        !           510:                return(1);
        !           511:        else
        !           512:                return(0);
        !           513: }

unix.superglobalmegacorp.com

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