void freenode(obj *p) /* free space occupied by object p */ { obj *q, *q1; if (p->o_type == BLOCK) { /* I think there's */ freesymtab(p->o_val[N_VAL+1].s); /* a bug here, for */ q = p->o_val[N_VAL].o; /* nested blocks. */ p->o_prev->o_next = q->o_next; q->o_next->o_prev = p->o_prev; q->o_next = (obj *)NULL; for (q = p->o_next; q != NULL; ) { if (q->o_type == BLOCK) freesymtab(q->o_val[N_VAL+1].s); q1 = q; q = q->o_next; free(q1); } } else { p->o_prev->o_next = p->o_next; p->o_next->o_prev = p->o_prev; } free (p); if (!objbuf) redo_gbox = 1; /* page boundaries are now suspect */ }
Cell *adelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ { Cell *x, *y; Node *np; char buf[RECSIZE], *s; x = execute(a[0]); /* Cell* for symbol table */ if (!isarr(x)) return true; if (a[1] == 0) { /* delete the elements, not the table */ freesymtab(x); x->tval &= ~STR; x->tval |= ARR; x->sval = (char *) makesymtab(NSYMTAB); } else { buf[0] = 0; for (np = a[1]; np; np = np->nnext) { y = execute(np); /* subscript */ s = getsval(y); strcat(buf, s); if (np->nnext) strcat(buf, *SUBSEP); tempfree(y); } freeelem(x, buf); } tempfree(x); return true; }
Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ { Cell *x, *y; Node *np; char *s; int nsub = strlen(*SUBSEP); x = execute(a[0]); /* Cell* for symbol table */ if (!isarr(x)) return True; if (a[1] == 0) { /* delete the elements, not the table */ freesymtab(x); x->tval &= ~STR; x->tval |= ARR; x->sval = (char *) makesymtab(NSYMTAB); } else { int bufsz = recsize; char *buf; if ((buf = (char *) malloc(bufsz)) == NULL) FATAL("out of memory in adelete"); buf[0] = 0; for (np = a[1]; np; np = np->nnext) { y = execute(np); /* subscript */ s = getsval(y); if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "awkdelete")) FATAL("out of memory deleting %s[%s...]", x->nval, buf); strcat(buf, s); if (np->nnext) strcat(buf, *SUBSEP); tempfree(y); } freeelem(x, buf); free(buf); } tempfree(x); return True; }
int main(int argc, char *argv[]) { Symtab *symtab; Symbol *sym; setpname(argv[0]); if (argc > 1) fprintf(stderr, "%s: unused arguments\n", getpname()); if ((symtab = makesymtab(0)) == NULL) die(1, "failed to allocate symbol table:"); if ((sym = storesym(symtab, "foo")) == NULL) die(1, "failed to insert lexem \"foo\":"); sym->symtype = S_IDENT; if ((sym = storesym(symtab, "bar")) == NULL) die(1, "failed to insert lexem \"bar\":"); sym->symtype = S_IDENT; if ((sym = storesym(symtab, "baz")) == NULL) die(1, "failed to insert lexem \"baz\":"); sym->symtype = S_IDENT; if ((sym = findsym(symtab, "foo")) == NULL) die(1, "couldn't find lexem \"foo\":"); if (sym->symtype != S_IDENT) die(1, "symtype of \"foo\" is not S_IDENT"); sym->symtype = S_INTCONST; if ((sym = findsym(symtab, "bar")) == NULL) die(1, "couldn't find lexem \"bar\":"); if (sym->symtype != S_IDENT) die(1, "%s: symtype of \"bar\" is not S_IDENT"); sym->symtype = S_INTCONST; if ((sym = findsym(symtab, "baz")) == NULL) die(1, "couldn't find lexem \"baz\":"); if (sym->symtype != S_IDENT) die(1, "symtype of \"baz\" is not S_IDENT"); sym->symtype = S_INTCONST; if ((sym = findsym(symtab, "foo")) == NULL) die(1, "couldn't find lexem \"foo\":"); if (sym->symtype != S_INTCONST) die(1, "symtype of \"foo\" is not S_INTCONST"); if ((sym = findsym(symtab, "bar")) == NULL) die(1, "couldn't find lexem \"bar\":"); if (sym->symtype != S_INTCONST) die(1, "symtype of \"bar\" is not S_INTCONST"); if ((sym = findsym(symtab, "baz")) == NULL) die(1, "couldn't find lexem \"baz\":"); if (sym->symtype != S_INTCONST) die(1, "symtype of \"baz\" is not S_INTCONST"); freesymtab(symtab); return 0; }
Cell *call(Node **a, int n) /* function call. very kludgy and fragile */ { static Cell newcopycell = { OCELL, CCOPY, 0, (char *) "", 0.0, NUM|STR|DONTFREE }; int i, ncall, ndef; Node *x; Cell *args[NARGS], *oargs[NARGS], *y, *z, *fcn; char *s; fcn = execute(a[0]); /* the function itself */ s = fcn->nval; if (!isfunc(fcn)) ERROR "calling undefined function %s", s FATAL; if (frame == NULL) { fp = frame = (struct Frame *) calloc(nframe += 100, sizeof(struct Frame)); if (frame == NULL) ERROR "out of space for stack frames calling %s", s FATAL; } for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */ ncall++; ndef = (int) fcn->fval; /* args in defn */ dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, fp-frame) ); if (ncall > ndef) ERROR "function %s called with %d args, uses only %d", s, ncall, ndef WARNING; if (ncall + ndef > NARGS) ERROR "function %s has %d arguments, limit %d", s, ncall+ndef, NARGS FATAL; for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { /* get call args */ dprintf( ("evaluate args[%d], fp=%d:\n", i, fp-frame) ); y = execute(x); oargs[i] = y; dprintf( ("args[%d]: %s %f <%s>, t=%o\n", i, y->nval, y->fval, isarr(y) ? "(array)" : (char*) y->sval, y->tval) ); if (isfunc(y)) ERROR "can't use function %s as argument in %s", y->nval, s FATAL; if (isarr(y)) args[i] = y; /* arrays by ref */ else args[i] = copycell(y); tempfree(y); } for ( ; i < ndef; i++) { /* add null args for ones not provided */ args[i] = gettemp(); *args[i] = newcopycell; } fp++; /* now ok to up frame */ if (fp >= frame + nframe) { int dfp = fp - frame; /* old index */ frame = (struct Frame *) realloc((char *) frame, (nframe += 100) * sizeof(struct Frame)); if (frame == NULL) ERROR "out of space for stack frames in %s", s FATAL; fp = frame + dfp; } fp->fcncell = fcn; fp->args = args; fp->nargs = ndef; /* number defined with (excess are locals) */ fp->retval = gettemp(); dprintf( ("start exec of %s, fp=%d\n", s, fp-frame) ); y = execute((Node *)(fcn->sval)); /* execute body */ dprintf( ("finished exec of %s, fp=%d\n", s, fp-frame) ); for (i = 0; i < ndef; i++) { Cell *t = fp->args[i]; if (isarr(t)) { if (t->csub == CCOPY) { if (i >= ncall) { freesymtab(t); t->csub = CTEMP; } else { oargs[i]->tval = t->tval; oargs[i]->tval &= ~(STR|NUM|DONTFREE); oargs[i]->sval = t->sval; tempfree(t); } } } else if (t != y) { /* kludge to prevent freeing twice */ t->csub = CTEMP; tempfree(t); } } tempfree(fcn); if (isexit(y) || isnext(y) || isnextfile(y)) return y; tempfree(y); /* this can free twice! */ z = fp->retval; /* return value */ dprintf( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) ); fp--; return(z); }
Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ { Cell *x = 0, *y, *ap; char *s; int sep; char *t, temp, num[10], *fs = 0; int n, tempstat; y = execute(a[0]); /* source string */ s = getsval(y); if (a[2] == 0) /* fs string */ fs = *FS; else if ((int) a[3] == STRING) { /* split(str,arr,"string") */ x = execute(a[2]); fs = getsval(x); } else if ((int) a[3] == REGEXPR) fs = (char*) "(regexpr)"; /* split(str,arr,/regexpr/) */ else ERROR "illegal type of split()" FATAL; sep = *fs; ap = execute(a[1]); /* array name */ freesymtab(ap); dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, ap->nval, fs) ); ap->tval &= ~STR; ap->tval |= ARR; ap->sval = (char *) makesymtab(NSYMTAB); n = 0; if ((*s != '\0' && strlen(fs) > 1) || (int) a[3] == REGEXPR) { /* reg expr */ fa *pfa; if ((int) a[3] == REGEXPR) { /* it's ready already */ pfa = (fa *) a[2]; } else { pfa = makedfa(fs, 1); } if (nematch(pfa,s)) { tempstat = pfa->initstat; pfa->initstat = 2; do { n++; sprintf((char *)num, "%d", n); temp = *patbeg; *patbeg = '\0'; if (isnumber(s)) setsymtab(num, s, atof((char *)s), STR|NUM, (Array *) ap->sval); else setsymtab(num, s, 0.0, STR, (Array *) ap->sval); *patbeg = temp; s = patbeg + patlen; if (*(patbeg+patlen-1) == 0 || *s == 0) { n++; sprintf((char *)num, "%d", n); setsymtab(num, "", 0.0, STR, (Array *) ap->sval); pfa->initstat = tempstat; goto spdone; } } while (nematch(pfa,s)); } n++; sprintf((char *)num, "%d", n); if (isnumber(s)) setsymtab(num, s, atof((char *)s), STR|NUM, (Array *) ap->sval); else setsymtab(num, s, 0.0, STR, (Array *) ap->sval); spdone: pfa = NULL; } else if (sep == ' ') { for (n = 0; ; ) { while (*s == ' ' || *s == '\t' || *s == '\n') s++; if (*s == 0) break; n++; t = s; do s++; while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); temp = *s; *s = '\0'; sprintf((char *)num, "%d", n); if (isnumber(t)) setsymtab(num, t, atof((char *)t), STR|NUM, (Array *) ap->sval); else setsymtab(num, t, 0.0, STR, (Array *) ap->sval); *s = temp; if (*s != 0) s++; } } else if (sep == 0) { /* new: split(s, a, "") => 1 char/elem */ for (n = 0; *s != 0; s++) { char buf[2]; n++; sprintf((char *)num, "%d", n); buf[0] = *s; buf[1] = 0; if (isdigit(buf[0])) setsymtab(num, buf, atof(buf), STR|NUM, (Array *) ap->sval); else setsymtab(num, buf, 0.0, STR, (Array *) ap->sval); } } else if (*s != 0) { for (;;) { n++; t = s; while (*s != sep && *s != '\n' && *s != '\0') s++; temp = *s; *s = '\0'; sprintf((char *)num, "%d", n); if (isnumber(t)) setsymtab(num, t, atof((char *)t), STR|NUM, (Array *) ap->sval); else setsymtab(num, t, 0.0, STR, (Array *) ap->sval); *s = temp; if (*s++ == 0) break; } } tempfree(ap); tempfree(y); if (a[2] != 0 && (int) a[3] == STRING) tempfree(x); x = gettemp(); x->tval = NUM; x->fval = n; return(x); }
Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ { Cell *x = 0, *y, *ap; char *s, *origs; int sep; char *t, temp, num[50], *fs = 0; int n, tempstat, arg3type; y = execute(a[0]); /* source string */ origs = s = strdup(getsval(y)); arg3type = ptoi(a[3]); if (a[2] == 0) /* fs string */ fs = *FS; else if (arg3type == STRING) { /* split(str,arr,"string") */ x = execute(a[2]); fs = getsval(x); } else if (arg3type == REGEXPR) fs = "(regexpr)"; /* split(str,arr,/regexpr/) */ else FATAL("illegal type of split"); sep = *fs; ap = execute(a[1]); /* array name */ freesymtab(ap); dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs) ); ap->tval &= ~STR; ap->tval |= ARR; ap->sval = (char *) makesymtab(NSYMTAB); n = 0; if (arg3type == REGEXPR && strlen((char*)((fa*)a[2])->restr) == 0) { /* split(s, a, //); have to arrange that it looks like empty sep */ arg3type = 0; fs = ""; sep = 0; } if (*s != '\0' && (strlen(fs) > 1 || arg3type == REGEXPR)) { /* reg expr */ fa *pfa; if (arg3type == REGEXPR) { /* it's ready already */ pfa = (fa *) a[2]; } else { pfa = makedfa(fs, 1); } if (nematch(pfa,s)) { tempstat = pfa->initstat; pfa->initstat = 2; do { n++; sprintf(num, "%d", n); temp = *patbeg; *patbeg = '\0'; if (is_number(s)) setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); else setsymtab(num, s, 0.0, STR, (Array *) ap->sval); *patbeg = temp; s = patbeg + patlen; if (*(patbeg+patlen-1) == 0 || *s == 0) { n++; sprintf(num, "%d", n); setsymtab(num, "", 0.0, STR, (Array *) ap->sval); pfa->initstat = tempstat; goto spdone; } } while (nematch(pfa,s)); pfa->initstat = tempstat; /* bwk: has to be here to reset */ /* cf gsub and refldbld */ } n++; sprintf(num, "%d", n); if (is_number(s)) setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); else setsymtab(num, s, 0.0, STR, (Array *) ap->sval); spdone: pfa = NULL; } else if (sep == ' ') { for (n = 0; ; ) { while (*s == ' ' || *s == '\t' || *s == '\n') s++; if (*s == 0) break; n++; t = s; do s++; while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); temp = *s; *s = '\0'; sprintf(num, "%d", n); if (is_number(t)) setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); else setsymtab(num, t, 0.0, STR, (Array *) ap->sval); *s = temp; if (*s != 0) s++; } } else if (sep == 0) { /* new: split(s, a, "") => 1 char/elem */ for (n = 0; *s != 0; s++) { char buf[2]; n++; sprintf(num, "%d", n); buf[0] = *s; buf[1] = 0; if (isdigit((uschar)buf[0])) setsymtab(num, buf, atof(buf), STR|NUM, (Array *) ap->sval); else setsymtab(num, buf, 0.0, STR, (Array *) ap->sval); } } else if (*s != 0) { for (;;) { n++; t = s; while (*s != sep && *s != '\n' && *s != '\0') s++; temp = *s; *s = '\0'; sprintf(num, "%d", n); if (is_number(t)) setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); else setsymtab(num, t, 0.0, STR, (Array *) ap->sval); *s = temp; if (*s++ == 0) break; } } tempfree(ap); tempfree(y); free(origs); if (a[2] != 0 && arg3type == STRING) { tempfree(x); } x = gettemp(); x->tval = NUM; x->fval = n; return(x); }