Annotation of researchv10dc/cmd/prefer/prefawk/tran.c, revision 1.1.1.1

1.1       root        1: #define        DEBUG
                      2: #include <stdio.h>
                      3: #include <ctype.h>
                      4: #include "awk.h"
                      5: #include "y.tab.h"
                      6: 
                      7: #define        FULLTAB 2       /* rehash when table gets this x full */
                      8: #define        GROWTAB 4       /* grow table by this factor */
                      9: 
                     10: Array  *symtab;        /* main symbol table */
                     11: 
                     12: uchar  **FS;           /* initial field sep */
                     13: uchar  **RS;           /* initial record sep */
                     14: uchar  **OFS;          /* output field sep */
                     15: uchar  **ORS;          /* output record sep */
                     16: uchar  **OFMT;         /* output format for numbers*/
                     17: Awkfloat *NF;          /* number of fields in current record */
                     18: Awkfloat *NR;          /* number of current record */
                     19: Awkfloat *FNR;         /* number of current record in current file */
                     20: uchar  **FILENAME;     /* current filename argument */
                     21: Awkfloat *ARGC;                /* number of arguments from command line */
                     22: uchar  **SUBSEP;       /* subscript separator for a[i,j,k]; default \034 */
                     23: Awkfloat *RSTART;      /* start of re matched with ~; origin 1 (!) */
                     24: Awkfloat *RLENGTH;     /* length of same */
                     25: 
                     26: Cell   *recloc;        /* location of record */
                     27: Cell   *nrloc;         /* NR */
                     28: Cell   *nfloc;         /* NF */
                     29: Cell   *fnrloc;        /* FNR */
                     30: Array  *ARGVtab;       /* symbol table containing ARGV[...] */
                     31: Cell   *rstartloc;     /* RSTART */
                     32: Cell   *rlengthloc;    /* RLENGTH */
                     33: Cell   *symtabloc;     /* SYMTAB */
                     34: 
                     35: Cell   *nullloc;
                     36: Node   *nullnode;      /* zero&null, converted into a node for comparisons */
                     37: 
                     38: syminit()
                     39: {
                     40:        extern Node *valtonode();
                     41:        extern Cell fldtab[];
                     42: 
                     43:        symtab = makesymtab(NSYMTAB);
                     44:        setsymtab("0", "0", 0.0, NUM|STR|CON, symtab);
                     45:        /* this is used for if(x)... tests: */
                     46:        nullloc = setsymtab("$zero&null", "", 0.0, NUM|STR|CON, symtab);
                     47:        nullnode = valtonode(nullloc, CCON);
                     48:        /* recloc = setsymtab("$0", record, 0.0, REC|STR|DONTFREE, symtab); */
                     49:        recloc = &fldtab[0];
                     50:        FS = &setsymtab("FS", " ", 0.0, STR, symtab)->sval;
                     51:        RS = &setsymtab("RS", "\n", 0.0, STR, symtab)->sval;
                     52:        OFS = &setsymtab("OFS", " ", 0.0, STR, symtab)->sval;
                     53:        ORS = &setsymtab("ORS", "\n", 0.0, STR, symtab)->sval;
                     54:        OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR, symtab)->sval;
                     55:        FILENAME = &setsymtab("FILENAME", "", 0.0, STR, symtab)->sval;
                     56:        nfloc = setsymtab("NF", "", 0.0, NUM, symtab);
                     57:        NF = &nfloc->fval;
                     58:        nrloc = setsymtab("NR", "", 0.0, NUM, symtab);
                     59:        NR = &nrloc->fval;
                     60:        fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab);
                     61:        FNR = &fnrloc->fval;
                     62:        SUBSEP = &setsymtab("SUBSEP", "\034", 0.0, STR, symtab)->sval;
                     63:        rstartloc = setsymtab("RSTART", "", 0.0, NUM, symtab);
                     64:        RSTART = &rstartloc->fval;
                     65:        rlengthloc = setsymtab("RLENGTH", "", 0.0, NUM, symtab);
                     66:        RLENGTH = &rlengthloc->fval;
                     67:        symtabloc = setsymtab("SYMTAB", "", 0.0, ARR, symtab);
                     68:        symtabloc->sval = (uchar *) symtab;
                     69: }
                     70: 
                     71: arginit(ac, av)
                     72:        int ac;
                     73:        uchar *av[];
                     74: {
                     75:        Cell *cp;
                     76:        Array *makesymtab();
                     77:        int i;
                     78:        uchar temp[5];
                     79: 
                     80:        ARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval;
                     81:        cp = setsymtab("ARGV", "", 0.0, ARR, symtab);
                     82:        ARGVtab = makesymtab(NSYMTAB);  /* could be (int) ARGC as well */
                     83:        cp->sval = (uchar *) ARGVtab;
                     84:        for (i = 0; i < ac; i++) {
                     85:                sprintf(temp, "%d", i);
                     86:                if (isnumber(*av))
                     87:                        setsymtab(temp, *av, atof(*av), STR|NUM, ARGVtab);
                     88:                else
                     89:                        setsymtab(temp, *av, 0.0, STR, ARGVtab);
                     90:                av++;
                     91:        }
                     92: }
                     93: 
                     94: Array *makesymtab(n)
                     95:        int n;
                     96: {
                     97:        Array *ap;
                     98:        Cell **tp;
                     99: 
                    100:        ap = (Array *) Malloc(sizeof(Array));
                    101:        tp = (Cell **) Calloc(n, sizeof(Cell *));
                    102:        if (ap == NULL || tp == NULL)
                    103:                error(FATAL, "out of space in makesymtab");
                    104:        ap->nelem = 0;
                    105:        ap->size = n;
                    106:        ap->tab = tp;
                    107:        return(ap);
                    108: }
                    109: 
                    110: freesymtab(ap) /* free symbol table */
                    111:        Cell *ap;
                    112: {
                    113:        Cell *cp;
                    114:        Array *tp;
                    115:        int i;
                    116: 
                    117:        if (!isarr(ap))
                    118:                return;
                    119:        tp = (Array *) ap->sval;
                    120:        if (tp == NULL)
                    121:                return;
                    122:        for (i = 0; i < tp->size; i++) {
                    123:                for (cp = tp->tab[i]; cp != NULL; cp = cp->cnext) {
                    124:                        xfree(cp->nval);
                    125:                        xfree(cp->sval);
                    126:                        Free(cp);
                    127:                }
                    128:        }
                    129:        Free(tp->tab);
                    130:        Free(tp);
                    131: }
                    132: 
                    133: freeelem(ap, s)                /* free elem s from ap (i.e., ap["s"] */
                    134:        Cell *ap;
                    135:        uchar *s;
                    136: {
                    137:        Array *tp;
                    138:        Cell *p, *prev = NULL;
                    139:        int h;
                    140:        
                    141:        tp = (Array *) ap->sval;
                    142:        h = hash(s, tp->size);
                    143:        for (p = tp->tab[h]; p != NULL; prev = p, p = p->cnext)
                    144:                if (strcmp(s, p->nval) == 0) {
                    145:                        if (prev == NULL)       /* 1st one */
                    146:                                tp->tab[h] = p->cnext;
                    147:                        else                    /* middle somewhere */
                    148:                                prev->cnext = p->cnext;
                    149:                        if (freeable(p))
                    150:                                xfree(p->sval);
                    151:                        Free(p->nval);
                    152:                        Free(p);
                    153:                        tp->nelem--;
                    154:                        return;
                    155:                }
                    156: }
                    157: 
                    158: Cell *setsymtab(n, s, f, t, tp)
                    159:        uchar *n, *s;
                    160:        Awkfloat f;
                    161:        unsigned t;
                    162:        Array *tp;
                    163: {
                    164:        register h;
                    165:        register Cell *p;
                    166:        Cell *lookup();
                    167: 
                    168:        if (n != NULL && (p = lookup(n, tp)) != NULL) {
                    169:                dprintf("setsymtab found %o: n=%s", p, p->nval, NULL);
                    170:                dprintf(" s=\"%s\" f=%g t=%o\n", p->sval, p->fval, p->tval);
                    171:                return(p);
                    172:        }
                    173:        p = (Cell *) Malloc(sizeof(Cell));
                    174:        if (p == NULL)
                    175:                error(FATAL, "symbol table overflow at %s", n);
                    176:        p->nval = tostring(n);
                    177:        p->sval = s ? tostring(s) : tostring("");
                    178:        p->fval = f;
                    179:        p->tval = t;
                    180:        tp->nelem++;
                    181:        if (tp->nelem > FULLTAB * tp->size)
                    182:                rehash(tp);
                    183:        h = hash(n, tp->size);
                    184:        p->cnext = tp->tab[h];
                    185:        tp->tab[h] = p;
                    186:        dprintf("setsymtab set %o: n=%s", p, p->nval, NULL);
                    187:        dprintf(" s=\"%s\" f=%g t=%o\n", p->sval, p->fval, p->tval);
                    188:        return(p);
                    189: }
                    190: 
                    191: hash(s, n)     /* form hash value for string s */
                    192:        register uchar *s;
                    193:        int n;
                    194: {
                    195:        register unsigned hashval;
                    196: 
                    197:        for (hashval = 0; *s != '\0'; s++)
                    198:                hashval = (*s + 31 * hashval);
                    199:        return hashval % n;
                    200: }
                    201: 
                    202: rehash(tp)     /* rehash items in small table into big one */
                    203:        Array *tp;
                    204: {
                    205:        int i, nh, nsz;
                    206:        Cell *cp, *op, **np;
                    207: 
                    208:        nsz = GROWTAB * tp->size;
                    209:        np = (Cell **) Calloc(nsz, sizeof(Cell *));
                    210:        if (np == NULL)
                    211:                error(FATAL, "out of space in rehash");
                    212:        for (i = 0; i < tp->size; i++) {
                    213:                for (cp = tp->tab[i]; cp; cp = op) {
                    214:                        op = cp->cnext;
                    215:                        nh = hash(cp->nval, nsz);
                    216:                        cp->cnext = np[nh];
                    217:                        np[nh] = cp;
                    218:                }
                    219:        }
                    220:        free(tp->tab);
                    221:        tp->tab = np;
                    222:        tp->size = nsz;
                    223: }
                    224: 
                    225: Cell *lookup(s, tp)    /* look for s in tp */
                    226:        register uchar *s;
                    227:        Array *tp;
                    228: {
                    229:        register Cell *p, *prev = NULL;
                    230:        int h;
                    231: 
                    232:        h = hash(s, tp->size);
                    233:        for (p = tp->tab[h]; p != NULL; prev = p, p = p->cnext)
                    234:                if (strcmp(s, p->nval) == 0)
                    235:                        return(p);      /* found it */
                    236:        return(NULL);                   /* not found */
                    237: }
                    238: 
                    239: Awkfloat setfval(vp, f)
                    240:        register Cell *vp;
                    241:        Awkfloat f;
                    242: {
                    243:        extern Cell fldtab[];
                    244: 
                    245:        if ((vp->tval & (NUM | STR)) == 0) 
                    246:                funnyvar(vp, "assign to");
                    247:        if (vp->tval & FLD) {
                    248:                donerec = 0;    /* mark $0 invalid */
                    249:                if (vp-fldtab > *NF)
                    250:                        newfld(vp-fldtab);
                    251:                dprintf("setting field %d to %g\n", vp-fldtab, f);
                    252:        } else if (vp->tval & REC) {
                    253:                donefld = 0;    /* mark $1... invalid */
                    254:                donerec = 1;
                    255:        }
                    256:        vp->tval &= ~STR;       /* mark string invalid */
                    257:        vp->tval |= NUM;        /* mark number ok */
                    258:        dprintf("setfval %o: %s = %g, t=%o\n", vp, vp->nval, f, vp->tval);
                    259:        return vp->fval = f;
                    260: }
                    261: 
                    262: funnyvar(vp, rw)
                    263:        Cell *vp;
                    264:        char *rw;
                    265: {
                    266:        if (vp->tval & ARR)
                    267:                error(FATAL, "can't %s %s; it's an array name.", rw, vp->nval);
                    268:        if (vp->tval & FCN)
                    269:                error(FATAL, "can't %s %s; it's a function.", rw, vp->nval);
                    270:        error(FATAL, "funny variable %o: n=%s s=\"%s\" f=%g t=%o",
                    271:                vp, vp->nval, vp->sval, vp->fval, vp->tval);
                    272: }
                    273: 
                    274: uchar *setsval(vp, s)
                    275: register Cell *vp;
                    276: uchar *s;
                    277: {
                    278:        if ((vp->tval & (NUM | STR)) == 0)
                    279:                funnyvar(vp, "assign to");
                    280:        if (vp->tval & FLD) {
                    281:                donerec = 0;    /* mark $0 invalid */
                    282:                if (vp-fldtab > *NF)
                    283:                        newfld(vp-fldtab);
                    284:                dprintf("setting field %d to %s\n", vp-fldtab, s);
                    285:        } else if (vp->tval & REC) {
                    286:                donefld = 0;    /* mark $1... invalid */
                    287:                donerec = 1;
                    288:        }
                    289:        vp->tval &= ~NUM;
                    290:        vp->tval |= STR;
                    291:        if (!(vp->tval&DONTFREE))
                    292:                xfree(vp->sval);
                    293:        vp->tval &= ~DONTFREE;
                    294:        dprintf("setsval %o: %s = \"%s\", t=%o\n", vp, vp->nval, s, vp->tval);
                    295:        return(vp->sval = tostring(s));
                    296: }
                    297: 
                    298: Awkfloat r_getfval(vp)
                    299: register Cell *vp;
                    300: {
                    301:        /* if (vp->tval & ARR)
                    302:                error(FATAL, "illegal reference to array %s", vp->nval);
                    303:                return 0.0; */
                    304:        if ((vp->tval & (NUM | STR)) == 0)
                    305:                funnyvar(vp, "read value of");
                    306:        if ((vp->tval & FLD) && donefld == 0)
                    307:                fldbld();
                    308:        else if ((vp->tval & REC) && donerec == 0)
                    309:                recbld();
                    310:        if (!isnum(vp)) {       /* not a number */
                    311:                vp->fval = atof(vp->sval);      /* best guess */
                    312:                if (isnumber(vp->sval) && !(vp->tval&CON))
                    313:                        vp->tval |= NUM;        /* make NUM only sparingly */
                    314:        }
                    315:        dprintf("getfval %o: %s = %g, t=%o\n", vp, vp->nval, vp->fval, vp->tval);
                    316:        return(vp->fval);
                    317: }
                    318: 
                    319: uchar *r_getsval(vp)
                    320: register Cell *vp;
                    321: {
                    322:        uchar s[100];
                    323: 
                    324:        /* if (vp->tval & ARR)
                    325:                error(FATAL, "illegal reference to array %s", vp->nval);
                    326:                return ""; */
                    327:        if ((vp->tval & (NUM | STR)) == 0)
                    328:                funnyvar(vp, "read value of");
                    329:        if ((vp->tval & FLD) && donefld == 0)
                    330:                fldbld();
                    331:        else if ((vp->tval & REC) && donerec == 0)
                    332:                recbld();
                    333:        if ((vp->tval & STR) == 0) {
                    334:                if (!(vp->tval&DONTFREE))
                    335:                        xfree(vp->sval);
                    336:                if ((long)vp->fval == vp->fval)
                    337:                        sprintf(s, "%.20g", vp->fval);
                    338:                else
                    339:                        sprintf(s, *OFMT, vp->fval);
                    340:                vp->sval = tostring(s);
                    341:                vp->tval &= ~DONTFREE;
                    342:                vp->tval |= STR;
                    343:        }
                    344:        dprintf("getsval %o: %s = \"%s\", t=%o\n", vp, vp->nval, vp->sval, vp->tval);
                    345:        return(vp->sval);
                    346: }
                    347: 
                    348: uchar *tostring(s)
                    349: register uchar *s;
                    350: {
                    351:        register uchar *p;
                    352: 
                    353:        p = Malloc(strlen(s)+1);
                    354:        if (p == NULL)
                    355:                error(FATAL, "out of space in tostring on %s", s);
                    356:        strcpy(p, s);
                    357:        return(p);
                    358: }
                    359: 
                    360: uchar *qstring(s, delim)       /* collect string up to delim */
                    361:        uchar *s;
                    362:        int delim;
                    363: {
                    364:        uchar *q;
                    365:        int c, n;
                    366: 
                    367:        for (q = cbuf; (c = *s) != delim; s++) {
                    368:                if (q >= cbuf + CBUFLEN - 1)
                    369:                        yyerror("string %.10s... too long", cbuf);
                    370:                else if (c == '\n')
                    371:                        yyerror("newline in string %.10s...", cbuf);
                    372:                else if (c != '\\')
                    373:                        *q++ = c;
                    374:                else    /* \something */        
                    375:                        switch (c = *++s) {
                    376:                        case '\\':      *q++ = '\\'; break;
                    377:                        case 'n':       *q++ = '\n'; break;
                    378:                        case 't':       *q++ = '\t'; break;
                    379:                        case 'b':       *q++ = '\b'; break;
                    380:                        case 'f':       *q++ = '\f'; break;
                    381:                        case 'r':       *q++ = '\r'; break;
                    382:                        default:
                    383:                                if (!isdigit(c)) {
                    384:                                        *q++ = c;
                    385:                                        break;
                    386:                                }
                    387:                                n = c - '0';
                    388:                                if (isdigit(s[1])) {
                    389:                                        n = 8 * n + *++s - '0';
                    390:                                        if (isdigit(s[1]))
                    391:                                                n = 8 * n + *++s - '0';
                    392:                                }
                    393:                                *q++ = n;
                    394:                                break;
                    395:                        }
                    396:        }
                    397:        *q = '\0';
                    398:        return cbuf;
                    399: }
                    400: 
                    401: #ifdef MYALLOC
                    402: 
                    403: long   stamp;
                    404: 
                    405: uchar *Malloc(n)
                    406:        int n;
                    407: {
                    408:        uchar *p;
                    409: 
                    410:        p = (uchar *) malloc(n);
                    411:        fprintf(stderr, "%6d a %d %d\n", ++stamp, p, n);
                    412:        return p;
                    413: }
                    414: 
                    415: uchar *Calloc(n, sz)
                    416:        int n, sz;
                    417: {
                    418:        uchar *p;
                    419: 
                    420:        p = (uchar *) calloc(n, sz);
                    421:        fprintf(stderr, "%6d a %d %d (%d %d)\n", ++stamp, p, n*sz, n, sz);
                    422:        return p;
                    423: }
                    424: 
                    425: Free(p)
                    426:        uchar *p;
                    427: {
                    428:        fprintf(stderr, "%6d f %d\n", ++stamp, p);
                    429:        free(p);
                    430: }
                    431: 
                    432: #endif

unix.superglobalmegacorp.com

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