|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 4802 (0x12c2) Types: TextFile Notes: UNIX file Names: »awk4.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─⟦this⟧ »cmd/awk/awk4.c«
/* * AWK - Common support routines. * node allocation, etc. */ #include "awk.h" #include "y.tab.h" static int eosflag; /* for pgetc/pungetc */ /* * Allocate n bytes of * storage, checking for * running out of space. * This version doesn't call malloc, but * rather uses sbrk and doles out storage * itself. This sames much time for * searching long alloc lists. However, * i/o calls must all be buffered staticly. * A call with 0 bytes returns the pointer to * the end which can be saved for a call to xfree. * The following are 2 pointers maintained by the allocator/xfree. */ static int *xallrp; /* Running pointer for xalloc */ static int *xallep; /* End pointer for xfree */ char * xalloc(size) register unsigned size; { register int *rp; if ((rp = (int *)malloc(size)) == NULL) awkerr("Out of memory"); return ((char *)rp); } /* * Create an expression tree node. * The only required argument is the * operation code. The other three * are operands. */ /* VARARGS 1 */ NODE * node(op, o1, o2, o3, o4) int op; NODE *o1, *o2, *o3, *o4; { register NODE *np; np = (NODE *)xalloc(sizeof (NODE)); np->n_op = op; np->n_flag = 0; np->n_O1 = o1; np->n_O2 = o2; np->n_O3 = o3; np->n_O4 = o4; return (np); } /* * Produce a node with a character (int) * int it (mostly for regular expressions). */ NODE * cnode(op, c) int op, c; { register NODE *np; np = (NODE *)xalloc(sizeof (NODE)); np->n_op = op; np->n_flag = 0; np->n_o1.n_char = c; np->n_O2 = np->n_O3 = np->n_O4 = NULL; return (np); } /* * Produce a string node. * While running, this node * is considered temporary. */ NODE * snode(s, type) register char *s; int type; { register NODE *np; np = (NODE *)xalloc(sizeof(TERM)); np->t_op = ATERM; np->t_flag = type; np->t_un.t_str = s; if (runflag) { np->t_next = tempnodes; tempnodes = np; } return (np); } /* * Build a node for a (long) * integer. */ NODE * inode(i) INT i; { register NODE *np; np = (NODE *)xalloc(sizeof(NODE)); np->t_op = ATERM; np->t_flag = T_NUM|T_INT; np->t_un.t_int = i; if (runflag) { np->t_next = tempnodes; tempnodes = np; } return (np); } /* * Build a node for a (double) * floating point number. */ NODE * fnode(f) FLOAT f; { register NODE *np; np = (NODE *)xalloc(sizeof(NODE)); np->t_op = ATERM; np->t_flag = T_NUM; np->t_un.t_float = f; if (runflag) { np->t_next = tempnodes; tempnodes = np; } return (np); } /* * Free a terminal node. This * looks at the flags to see if * it is a string, and frees it if * it is also an allocated string. */ freenode(np) register NODE *np; { if ((np->t_flag&(T_NUM|T_ALLOC)) == T_ALLOC) free(np->t_STRING); free(np); } /* * Checks to see if a node is numeric. * Here it must be not in string form * but in number form. This is * used mostly for comparisons. */ isnumeric(np) register NODE *np; { if (np->t_flag & T_NUM) return (1); return (0); } /* * Return 1 if a number is of the floating * type. This will check strings as well * as numbers. */ isfloat(np) register NODE *np; { register char *cp; register int isfloat = 0; if (np->t_flag & T_NUM) if (np->t_flag & T_INT) return (0); else return (1); for (cp = np->t_STRING; *cp != '\0'; cp++) { if ((*cp=='e' || *cp=='E') && cp!=np->t_STRING) isfloat++; else if (*cp == '.') isfloat++; else if (!isdigit(*cp) && *cp!='-') return (0); } return (isfloat); } /* * Fetch a character from * the program, either on * the command line or in a file. */ pgetc() { register int c; if (parg != NULL) { if (eosflag) return (EOF); else if ((c = *parg++) == '\0') { eosflag = 1; return ('\n'); } } else c = getc(pfp); if (c == '\n') { if (lineno == 0) lineno++; lineno++; } return (c); } /* * Set up a new string for the * lexical analyser to read. */ pgetinit(s) char *s; { parg = s; eosflag = 0; lineno = 0; } /* * Return a character to the * program input. */ pungetc(c) int c; { if (parg != NULL) { if (eosflag) c = '\0'; *--parg = c; eosflag = 0; } else ungetc(c, pfp); if (c == '\n') --lineno; } /* * Error routines and usage * messages. */ usage() { fprintf(stderr, "Usage: awk [-y] [-Fc] [-f prog] [parameters] [prog] [file ...]\n"); exit(1); } /* VARARGS */ awkerr(x) { fprintf(stderr, "awk: "); if (FILENAME[0] != '\0') fprintf(stderr, "%s: ", FILENAME); if (lineno != 0) fprintf(stderr, "%d: ", lineno); fprintf(stderr, "%r", &x); putc('\n', stderr); exit(1); } /* VARARGS */ awkwarn(x) { fprintf(stderr, "awk: "); if (FILENAME[0] != '\0') fprintf(stderr, "%s: ", FILENAME); if (lineno != 0) fprintf(stderr, "%d: ", lineno); fprintf(stderr, "Warning: %r", &x); putc('\n', stderr); } /* VARARGS */ yyerror(x) { awkerr(x); }