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

1.1       root        1: /*
                      2:  * AWK - part 2
                      3:  * Initialisation, and
                      4:  * other compiler support.
                      5:  * Symbol table maintenance
                      6:  * and lookup.
                      7:  */
                      8: 
                      9: #include "awk.h"
                     10: #include "y.tab.h"
                     11: 
                     12: void   keyenter();
                     13: void   funcenter();
                     14: 
                     15: typedef        struct  FUNC {
                     16:        int     (*f_funcp)();
                     17:        CHAR    *f_name;
                     18:        CHAR    f_minarg;               /* Minimum number of arguments */
                     19:        CHAR    f_maxarg;               /* Maximum # args (-1 = variable) */
                     20: }      FUNC;
                     21: 
                     22: FUNC   functions[] = {
                     23:        f_length, "length", 0, 1,
                     24:        f_sqrt, "sqrt", 1, 1,
                     25:        f_log, "log", 1, 1,
                     26:        f_exp, "exp", 1, 1,
                     27:        f_int, "int", 1, 1,
                     28:        f_substr, "substr", 2, 3,
                     29:        f_index, "index", 2, 2,
                     30:        f_sprintf, "sprintf", 1, -1,
                     31:        f_split, "split", 2, 3,
                     32:        f_abs, "abs", 1, 1,
                     33: };
                     34: 
                     35: typedef        struct  KEYW    {
                     36:        int     k_lval;
                     37:        CHAR    *k_name;
                     38: }      KEYW;
                     39: 
                     40: KEYW   keywords[] = {
                     41:        BEGIN_, "BEGIN",
                     42:        END_, "END",
                     43:        PRINT_, "print",
                     44:        PRINTF_, "printf",
                     45:        IF_, "if",
                     46:        ELSE_, "else",
                     47:        WHILE_, "while",
                     48:        FOR_, "for",
                     49:        IN_, "in",
                     50:        BREAK_, "break",
                     51:        CONTINUE_, "continue",
                     52:        NEXT_, "next",
                     53:        EXIT_, "exit",
                     54: };
                     55: 
                     56: /*
                     57:  * Initialisation --
                     58:  * Turn on buffering for output.
                     59:  * Initialse static constant values,
                     60:  * install keywords,
                     61:  * and install built-in functions.
                     62:  */
                     63: awkinit()
                     64: {
                     65:        setbuf(stdin, inbuf);
                     66:        setbuf(stdout, outbuf);
                     67:        setbuf(stderr, NULL);
                     68:        /*
                     69:         * Initialise keywords into
                     70:         * the symbol table.
                     71:         */
                     72:        {
                     73:                register KEYW *kp;
                     74: 
                     75:                for (kp = keywords; kp < endof(keywords); kp++)
                     76:                        keyenter(kp->k_name, kp->k_lval);
                     77:        }
                     78:        /*
                     79:         * Install functions into symbol
                     80:         * table.
                     81:         */
                     82:        {
                     83:                register FUNC *fp;
                     84: 
                     85:                for (fp = functions; fp < endof(functions); fp++)
                     86:                        funcenter(fp->f_name, fp->f_funcp, fp->f_minarg,
                     87:                            fp->f_maxarg);
                     88:        }
                     89:        xzero.t_INT = 0;
                     90:        xone.t_INT = 1;
                     91:        xone.t_op = xzero.t_op = ATERM;
                     92:        xone.t_flag = xzero.t_flag = T_INT|T_NUM;
                     93:        xfield0.n_op = AFIELD;
                     94:        xfield0.n_O1 = &xzero;
                     95:        /*
                     96:         * Set up the built-in variables.
                     97:         */
                     98:        NRp = install("NR", (INT)0);
                     99:        NFp = install("NF", (INT)0);
                    100:        FILENAMEp = lookup("FILENAME");
                    101:        sassign(FSp = install("FS", (INT)0), " \t");
                    102:        sassign(RSp = install("RS", (INT)0), "\n");
                    103:        sassign(OFSp = install("OFS", (INT)0), " ");
                    104:        sassign(ORSp = install("ORS", (INT)0), "\n");
                    105:        sassign(OFMTp = install("OFMT", (INT)0), "%ld");
                    106: }
                    107: 
                    108: /*
                    109:  * Lookup an identifier - `id' and
                    110:  * if it is not found, initialise it
                    111:  * with the NULL string.
                    112:  * The hash value is the sum of all
                    113:  * the characters in the name +
                    114:  * the length of the name.
                    115:  */
                    116: NODE *
                    117: lookup(id)
                    118: CHAR *id;
                    119: {
                    120:        register CHAR *ip;
                    121:        register TERM *tp;
                    122:        register unsigned hash;
                    123:        register unsigned nb;
                    124: 
                    125:        hash = 0;
                    126:        nb = sizeof (CHAR);
                    127:        for (ip = id; *ip != '\0'; hash++, nb++)
                    128:                hash += *ip++;
                    129:        for (tp = symtab[hash%NHASH]; tp != NULL; tp = tp->t_next)
                    130:                if (hash==tp->t_hval && tp->t_flag&T_VAR
                    131:                    && streq(tp->t_name, id))
                    132:                        return (tp);
                    133:        tp = (TERM *)xalloc(sizeof(NODE) + nb);
                    134:        strcpy(tp->t_name, id);
                    135:        tp->t_STRING = xalloc(sizeof(CHAR));
                    136:        tp->t_STRING[0] = '\0';
                    137:        tp->t_op = ATERM;
                    138:        tp->t_flag = T_VAR|T_ALLOC;
                    139:        tp->t_hval = hash;
                    140:        tp->t_ahval = -1;
                    141:        tp->t_next = symtab[hash %= NHASH];
                    142:        symtab[hash] = tp;
                    143:        return ((NODE *)tp);
                    144: }
                    145: 
                    146: /*
                    147:  * Lookup for an array.
                    148:  * Arguments are `array' and `index'
                    149:  * (both strings).  Hashing  is an
                    150:  * extension of that in lookup().
                    151:  * New array elements are given value the
                    152:  * NULL string.
                    153:  */
                    154: NODE *
                    155: alookup(array, index)
                    156: CHAR *array;
                    157: CHAR *index;
                    158: {
                    159:        register CHAR *ip;
                    160:        register TERM *tp;
                    161:        register unsigned hash;
                    162:        register unsigned nba, nbi;
                    163:        register unsigned hash2;
                    164: 
                    165:        hash = 0;
                    166:        nba = nbi = sizeof (CHAR);
                    167:        for (ip = array; *ip != '\0'; hash++, nba++)
                    168:                hash += *ip++;
                    169:        hash2 = hash;
                    170:        for (ip = index; *ip != '\0'; hash++, nbi++)
                    171:                hash += *ip++;
                    172:        for (tp = symtab[hash % NHASH]; tp != NULL; tp = tp->t_next)
                    173:                if (hash==tp->t_hval && tp->t_flag&T_ARRAY
                    174:                  && streq(tp->t_name, array) && streq(tp->t_name+nba, index))
                    175:                        return (tp);
                    176:        tp = (TERM *)xalloc(sizeof(NODE) + nba + nbi);
                    177:        strcpy(tp->t_name, array);
                    178:        strcpy(tp->t_name+nba, index);
                    179:        tp->t_STRING = xalloc(sizeof(CHAR));
                    180:        tp->t_STRING[0] = '\0';
                    181:        tp->t_op = ATERM;
                    182:        tp->t_flag = T_ARRAY|T_ALLOC;
                    183:        tp->t_hval = hash;
                    184:        tp->t_ahval = hash2;
                    185:        tp->t_next = symtab[hash %= NHASH];
                    186:        symtab[hash] = tp;
                    187:        return ((NODE *)tp);
                    188: }
                    189: 
                    190: /*
                    191:  * Install a built-in integer
                    192:  * name with value `val'.
                    193:  */
                    194: NODE *
                    195: install(id, val)
                    196: CHAR *id;
                    197: INT val;
                    198: {
                    199:        register NODE *np;
                    200: 
                    201:        np = lookup(id);
                    202:        np->t_flag |= T_NUM|T_INT;
                    203:        free(np->t_STRING);
                    204:        np->t_INT = val;
                    205:        return (np);
                    206: }
                    207: 
                    208: /*
                    209:  * Enter a keyword in the symbol table.
                    210:  * `lval' is the lexical value of the keyword
                    211:  * and the TERM type is `AKEYW'.
                    212:  */
                    213: void
                    214: keyenter(word, lval)
                    215: CHAR *word;
                    216: int lval;
                    217: {
                    218:        register CHAR *ip;
                    219:        register unsigned hash;
                    220:        register TERM *tp;
                    221:        register int nb;
                    222: 
                    223:        hash = 0;
                    224:        nb = sizeof (CHAR);
                    225:        for (ip = word; *ip != '\0'; hash++, nb++)
                    226:                hash += *ip++;
                    227:        tp = (TERM *)xalloc(nb + sizeof(TERM));
                    228:        tp->t_hval = hash;
                    229:        tp->t_op = AKEYW;
                    230:        tp->t_flag = T_ALLOC|T_VAR;
                    231:        strcpy(tp->t_name, word);
                    232:        tp->t_INT = lval;
                    233:        tp->t_next = symtab[hash %= NHASH];
                    234:        symtab[hash] = tp;
                    235: }
                    236: 
                    237: /*
                    238:  * Enter a function name into the
                    239:  * symbol table.
                    240:  * `min' and `max' are the minimum and
                    241:  * maximum number of arguments, respectively.
                    242:  */
                    243: void
                    244: funcenter(name, fun, min, max)
                    245: CHAR *name;
                    246: int (*fun)();
                    247: int min, max;
                    248: {
                    249:        register CHAR *np;
                    250:        register unsigned hash;
                    251:        register TERM *tp;
                    252:        register unsigned nb;
                    253: 
                    254:        hash = 0;
                    255:        nb = sizeof (CHAR);
                    256:        for (np = name; *np != '\0'; hash++, nb++)
                    257:                hash += *np++;
                    258:        tp = (TERM *)xalloc(nb + sizeof(TERM));
                    259:        tp->t_hval = hash;
                    260:        tp->t_op = AFUNC;
                    261:        tp->t_flag = T_ALLOC|T_VAR;
                    262:        strcpy(tp->t_name, name);
                    263:        tp->t_FUNC = fun;
                    264:        tp->t_MINARG = min;
                    265:        tp->t_MAXARG = max;
                    266:        tp->t_next = symtab[hash %= NHASH];
                    267:        symtab[hash] = tp;
                    268: }
                    269: 
                    270: /*
                    271:  * Assign a new value to a string.
                    272:  * It produces a static string.
                    273:  */
                    274: sassign(np, s)
                    275: register NODE *np;
                    276: STRING s;
                    277: {
                    278:        if ((np->t_flag & (T_ALLOC|T_NUM)) == T_ALLOC)
                    279:                free(np->t_STRING);
                    280:        np->t_flag &= ~(T_ALLOC|T_NUM);
                    281:        np->t_STRING = s;
                    282: }
                    283: 
                    284: /*
                    285:  * Assign an INT to a node.
                    286:  */
                    287: iassign(np, i)
                    288: register NODE *np;
                    289: INT i;
                    290: {
                    291:        if ((np->t_flag & (T_ALLOC|T_NUM)) == T_ALLOC)
                    292:                free(np->t_STRING);
                    293:        np->t_flag &= ~T_ALLOC;
                    294:        np->t_flag |= T_INT|T_NUM;
                    295:        np->t_INT = i;
                    296: }
                    297: 
                    298: /*
                    299:  * Initialise (or reset) the mapping
                    300:  * table for field extraction.  It is
                    301:  * set to non-zero for every character
                    302:  * that can end a field + '\0'
                    303:  * Note that FSMAP is defined over `wordbuf'
                    304:  * which is only used lexically and by `sprintf'
                    305:  * Therefore this routine must be called if this
                    306:  * buffer is disturbed.
                    307:  */
                    308: fsmapinit(fsp)
                    309: register CHAR *fsp;
                    310: {
                    311:        register CHAR *cp;
                    312: 
                    313:        whitesw = !strcmp(fsp, " \t");
                    314:        for (cp = FSMAP; cp < &FSMAP[NCSET]; )
                    315:                *cp++ = 0;
                    316:        while (*fsp != '\0')
                    317:                FSMAP[*fsp++] = 1;
                    318: }

unix.superglobalmegacorp.com

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