Annotation of coherent/d/bin/awk/awk2.c, revision 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.