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