Annotation of coherent/d/bin/awk/awk4.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * AWK - Common support routines.
        !             3:  * node allocation, etc.
        !             4:  */
        !             5: 
        !             6: #include "awk.h"
        !             7: #include "y.tab.h"
        !             8: 
        !             9: static int     eosflag;                /* for pgetc/pungetc */
        !            10: 
        !            11: /*
        !            12:  * Allocate n bytes of
        !            13:  * storage, checking for
        !            14:  * running out of space.
        !            15:  * This version doesn't call malloc, but
        !            16:  * rather uses sbrk and doles out storage
        !            17:  * itself.  This sames much time for
        !            18:  * searching long alloc lists.  However,
        !            19:  * i/o calls must all be buffered staticly.
        !            20:  * A call with 0 bytes returns the pointer to
        !            21:  * the end which can be saved for a call to xfree.
        !            22:  * The following are 2 pointers maintained by the allocator/xfree.
        !            23:  */
        !            24: static int     *xallrp;                /* Running pointer for xalloc */
        !            25: static int     *xallep;                /* End pointer for xfree */
        !            26: CHAR *
        !            27: xalloc(size)
        !            28: register unsigned size;
        !            29: {
        !            30:        register int *rp;
        !            31: 
        !            32:        if ((rp = (int *)malloc(size)) == NULL)
        !            33:                awkerr("Out of memory");
        !            34:        return ((CHAR *)rp);
        !            35: }
        !            36: 
        !            37: /*
        !            38:  * Create an expression tree node.
        !            39:  * The only required argument is the
        !            40:  * operation code.  The other three
        !            41:  * are operands.
        !            42:  */
        !            43: /* VARARGS 1 */
        !            44: NODE *
        !            45: node(op, o1, o2, o3, o4)
        !            46: int op;
        !            47: NODE *o1, *o2, *o3, *o4;
        !            48: {
        !            49:        register NODE *np;
        !            50: 
        !            51:        np = (NODE *)xalloc(sizeof (NODE));
        !            52:        np->n_op = op;
        !            53:        np->n_flag = 0;
        !            54:        np->n_O1 = o1;
        !            55:        np->n_O2 = o2;
        !            56:        np->n_O3 = o3;
        !            57:        np->n_O4 = o4;
        !            58:        return (np);
        !            59: }
        !            60: 
        !            61: /*
        !            62:  * Produce a node with a character (int)
        !            63:  * int it (mostly for regular expressions).
        !            64:  */
        !            65: NODE *
        !            66: cnode(op, c)
        !            67: int op, c;
        !            68: {
        !            69:        register NODE *np;
        !            70: 
        !            71:        np = (NODE *)xalloc(sizeof (NODE));
        !            72:        np->n_op = op;
        !            73:        np->n_flag = 0;
        !            74:        np->n_o1.n_char = c;
        !            75:        np->n_O2 = np->n_O3 = np->n_O4 = NULL;
        !            76:        return (np);
        !            77: }
        !            78: 
        !            79: /*
        !            80:  * Produce a string node.
        !            81:  * While running, this node
        !            82:  * is considered temporary.
        !            83:  */
        !            84: NODE *
        !            85: snode(s, type)
        !            86: register CHAR *s;
        !            87: int type;
        !            88: {
        !            89:        register NODE *np;
        !            90: 
        !            91:        np = (NODE *)xalloc(sizeof(TERM));
        !            92:        np->t_op = ATERM;
        !            93:        np->t_flag = type;
        !            94:        np->t_un.t_str = s;
        !            95:        if (runflag) {
        !            96:                np->t_next = tempnodes;
        !            97:                tempnodes = np;
        !            98:        }
        !            99:        return (np);
        !           100: }
        !           101: 
        !           102: /*
        !           103:  * Build a node for a (long)
        !           104:  * integer.
        !           105:  */
        !           106: NODE *
        !           107: inode(i)
        !           108: INT i;
        !           109: {
        !           110:        register NODE *np;
        !           111: 
        !           112:        np = (NODE *)xalloc(sizeof(NODE));
        !           113:        np->t_op = ATERM;
        !           114:        np->t_flag = T_NUM|T_INT;
        !           115:        np->t_un.t_int = i;
        !           116:        if (runflag) {
        !           117:                np->t_next = tempnodes;
        !           118:                tempnodes = np;
        !           119:        }
        !           120:        return (np);
        !           121: }
        !           122: 
        !           123: /*
        !           124:  * Build a node for a (double)
        !           125:  * floating point number.
        !           126:  */
        !           127: NODE *
        !           128: fnode(f)
        !           129: FLOAT f;
        !           130: {
        !           131:        register NODE *np;
        !           132: 
        !           133:        np = (NODE *)xalloc(sizeof(NODE));
        !           134:        np->t_op = ATERM;
        !           135:        np->t_flag = T_NUM;
        !           136:        np->t_un.t_float = f;
        !           137:        if (runflag) {
        !           138:                np->t_next = tempnodes;
        !           139:                tempnodes = np;
        !           140:        }
        !           141:        return (np);
        !           142: }
        !           143: 
        !           144: /*
        !           145:  * Free a terminal node.  This
        !           146:  * looks at the flags to see if
        !           147:  * it is a string, and frees it if
        !           148:  * it is also an allocated string.
        !           149:  */
        !           150: freenode(np)
        !           151: register NODE *np;
        !           152: {
        !           153:        if ((np->t_flag&(T_NUM|T_ALLOC)) == T_ALLOC)
        !           154:                free(np->t_STRING);
        !           155:        free(np);
        !           156: }
        !           157: 
        !           158: /*
        !           159:  * Checks to see if a node is numeric.
        !           160:  * Here it must be not in string form
        !           161:  * but in number form.  This is
        !           162:  * used mostly for comparisons.
        !           163:  */
        !           164: isnumeric(np)
        !           165: register NODE *np;
        !           166: {
        !           167:        if (np->t_flag & T_NUM)
        !           168:                return (1);
        !           169:        return (0);
        !           170: }
        !           171: 
        !           172: /*
        !           173:  * Return 1 if a number is of the floating
        !           174:  * type.  This will check strings as well
        !           175:  * as numbers.
        !           176:  */
        !           177: isfloat(np)
        !           178: register NODE *np;
        !           179: {
        !           180:        register CHAR *cp;
        !           181:        register int isfloat = 0, sawDigit = 0;
        !           182: 
        !           183:        if (np->t_flag & T_NUM)
        !           184:                return (!(np->t_flag & T_INT));
        !           185: 
        !           186:        for (cp = np->t_STRING;;cp++) {
        !           187:                switch (*cp) {
        !           188:                case 0:
        !           189:                        return (isfloat);
        !           190:                case 'e':
        !           191:                case 'E':
        !           192:                        if (!sawDigit)
        !           193:                                return (0);
        !           194:                case '.':
        !           195:                        sawDigit = isfloat = 1;
        !           196:                        break;
        !           197:                case ' ':
        !           198:                case '\t':
        !           199:                        if (sawDigit)
        !           200:                                return (0);
        !           201:                        break;
        !           202:                default:
        !           203:                        if (isdigit(*cp) || '-' == *cp) {
        !           204:                                sawDigit = 1;
        !           205:                                break;
        !           206:                        }
        !           207:                        return (0);
        !           208:                }
        !           209:        }
        !           210: }
        !           211: 
        !           212: /*
        !           213:  * Fetch a character from
        !           214:  * the program, either on
        !           215:  * the command line or in a file.
        !           216:  */
        !           217: pgetc()
        !           218: {
        !           219:        register int c;
        !           220: 
        !           221:        if (parg != NULL) {
        !           222:                if (eosflag)
        !           223:                        return (EOF);
        !           224:                else if ((c = *parg++) == '\0') {
        !           225:                        eosflag = 1;
        !           226:                        return ('\n');
        !           227:                }
        !           228:        } else {
        !           229:                while ((c = getc(pfp)) == '\\') {
        !           230:                        if ((c = getc(pfp)) != '\n') {
        !           231:                                ungetc(c, pfp);
        !           232:                                return ('\\');
        !           233:                        }
        !           234:                        /* bypass \ newline */
        !           235:                        if (lineno == 0)
        !           236:                                lineno++;
        !           237:                        lineno++;
        !           238:                }
        !           239:        }
        !           240:        if (c == '\n') {
        !           241:                if (lineno == 0)
        !           242:                        lineno++;
        !           243:                lineno++;
        !           244:        }
        !           245:        return (c);
        !           246: }
        !           247: 
        !           248: /*
        !           249:  * Set up a new string for the
        !           250:  * lexical analyser to read.
        !           251:  */
        !           252: pgetinit(s)
        !           253: CHAR *s;
        !           254: {
        !           255:        parg = s;
        !           256:        eosflag = 0;
        !           257:        lineno = 0;
        !           258: }
        !           259: 
        !           260: /*
        !           261:  * Return a character to the
        !           262:  * program input.
        !           263:  */
        !           264: pungetc(c)
        !           265: int c;
        !           266: {
        !           267:        if (parg != NULL) {
        !           268:                if (eosflag)
        !           269:                        c = '\0';
        !           270:                *--parg = c;
        !           271:                eosflag = 0;
        !           272:        } else
        !           273:                ungetc(c, pfp);
        !           274:        if (c == '\n')
        !           275:                        --lineno;
        !           276: }
        !           277: 
        !           278: /*
        !           279:  * Error routines and usage
        !           280:  * messages.
        !           281:  */
        !           282: usage()
        !           283: {
        !           284:        fprintf(stderr,
        !           285:           "Usage: awk [-y] [-Fc] [-f prog] [parameters] [prog] [file ...]\n");
        !           286:        exit(1);
        !           287: }
        !           288: 
        !           289: /* VARARGS */
        !           290: awkerr(x)
        !           291: {
        !           292:        fprintf(stderr, "awk: ");
        !           293:        if (FILENAME[0] != '\0')
        !           294:                fprintf(stderr, "%s: ", FILENAME);
        !           295:        if (lineno != 0)
        !           296:                fprintf(stderr, "%d: ", lineno);
        !           297:        fprintf(stderr, "%r", &x);
        !           298:        putc('\n', stderr);
        !           299:        exit(1);
        !           300: }
        !           301: 
        !           302: /* VARARGS */
        !           303: awkwarn(x)
        !           304: {
        !           305:        fprintf(stderr, "awk: ");
        !           306:        if (FILENAME[0] != '\0')
        !           307:                fprintf(stderr, "%s: ", FILENAME);
        !           308:        if (lineno != 0)
        !           309:                fprintf(stderr, "%d: ", lineno);
        !           310:        fprintf(stderr, "Warning: %r", &x);
        !           311:        putc('\n', stderr);
        !           312: }
        !           313: 
        !           314: /* VARARGS */
        !           315: yyerror(x)
        !           316: {
        !           317:        awkerr(x);
        !           318: }

unix.superglobalmegacorp.com

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