syminit() { setsymtab("0", tostring("0"), 0.0, NUM|STR|CON|FLD, symtab); recloc = setsymtab("$record", record, 0.0, STR|FLD, symtab); dprintf("recloc %o lookup %o\n", recloc, lookup("$record", symtab), NULL); FS = &setsymtab("FS", tostring(" "), 0.0, STR|FLD, symtab)->sval; RS = &setsymtab("RS", tostring("\n"), 0.0, STR|FLD, symtab)->sval; OFS = &setsymtab("OFS", tostring(" "), 0.0, STR|FLD, symtab)->sval; ORS = &setsymtab("ORS", tostring("\n"), 0.0, STR|FLD, symtab)->sval; OFMT = &setsymtab("OFMT", tostring("%.6g"), 0.0, STR|FLD, symtab)->sval; FILENAME = &setsymtab("FILENAME", NULL, 0.0, STR|FLD, symtab)->sval; nfloc = setsymtab("NF", NULL, 0.0, NUM, symtab); NF = &nfloc->fval; nrloc = setsymtab("NR", NULL, 0.0, NUM, symtab); NR = &nrloc->fval; }
Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ { Cell *x, *y, *z; char *s; Node *np; char buf[RECSIZE]; x = execute(a[0]); /* Cell* for symbol table */ buf[0] = 0; for (np = a[1]; np; np = np->nnext) { y = execute(np); /* subscript */ s = getsval(y); strcat(buf, s); /* BUG: unchecked! */ if (np->nnext) strcat(buf, *SUBSEP); tempfree(y); } if (!isarr(x)) { dprintf( ("making %s into an array\n", x->nval) ); if (freeable(x)) xfree(x->sval); x->tval &= ~(STR|NUM|DONTFREE); x->tval |= ARR; x->sval = (char *) makesymtab(NSYMTAB); } z = setsymtab(buf, "", 0.0, STR|NUM, (Array *) x->sval); z->ctype = OCELL; z->csub = CVAR; tempfree(x); return(z); }
void envinit(uchar **envp) { Cell *cp; uchar *p; cp = setsymtab("ENVIRON", "", 0.0, ARR, symtab); ENVtab = makesymtab(NSYMTAB); cp->sval = (uchar *) ENVtab; for ( ; *envp; envp++) { if ((p = (uchar *) strchr((char *) *envp, '=')) == NULL) /* index() on bsd */ continue; *p++ = 0; /* split into two strings at = */ if (isnumber(p)) setsymtab(*envp, p, atof(p), STR|NUM, ENVtab); else setsymtab(*envp, p, 0.0, STR, ENVtab); p[-1] = '='; /* restore in case env is passed down to a shell */ } }
void arginit(int ac, char **av) /* set up ARGV and ARGC */ { Cell *cp; int i; char temp[50]; ARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval; cp = setsymtab("ARGV", "", 0.0, ARR, symtab); ARGVtab = makesymtab(NSYMTAB); /* could be (int) ARGC as well */ cp->sval = (char *) ARGVtab; for (i = 0; i < ac; i++) { sprintf(temp, "%d", i); if (is_number(*av)) setsymtab(temp, *av, atof(*av), STR|NUM, ARGVtab); else setsymtab(temp, *av, 0.0, STR, ARGVtab); av++; } }
int word(char *w) { Keyword *kp; int c, n; n = binsearch(w, keywords, sizeof(keywords)/sizeof(keywords[0])); /* BUG: this ought to be inside the if; in theory could fault (daniel barrett) */ kp = keywords + n; if (n != -1) { /* found in table */ yylval.i = kp->sub; switch (kp->type) { /* special handling */ case BLTIN: if (kp->sub == FSYSTEM && safe) SYNTAX( "system is unsafe" ); RET(kp->type); case FUNC: if (infunc) SYNTAX( "illegal nested function" ); RET(kp->type); case RETURN: if (!infunc) SYNTAX( "return not in function" ); RET(kp->type); case VARNF: yylval.cp = setsymtab("NF", "", 0.0, NUM, symtab); RET(VARNF); default: RET(kp->type); } } c = peek(); /* look for '(' */ if (c != '(' && infunc && (n=isarg(w)) >= 0) { yylval.i = n; RET(ARG); } else { yylval.cp = setsymtab(w, "", 0.0, STR|NUM|DONTFREE, symtab); if (c == '(') { RET(CALL); } else { RET(VAR); } } }
int word(char *w) { Keyword *kp; int c, n; n = binsearch(w, keywords, sizeof(keywords)/sizeof(keywords[0])); kp = keywords + n; if (n != -1) { /* found in table */ yylval.i = kp->sub; switch (kp->type) { /* special handling */ case FSYSTEM: if (safe) ERROR "system is unsafe" SYNTAX; RET(kp->type); case FUNC: if (infunc) ERROR "illegal nested function" SYNTAX; RET(kp->type); case RETURN: if (!infunc) ERROR "return not in function" SYNTAX; RET(kp->type); case VARNF: yylval.cp = setsymtab("NF", "", 0.0, NUM, symtab); RET(VARNF); default: RET(kp->type); } } c = peek(); /* look for '(' */ if (c != '(' && infunc && (n=isarg(w)) >= 0) { yylval.i = n; RET(ARG); } else { yylval.cp = setsymtab(w, "", 0.0, STR|NUM|DONTFREE, symtab); if (c == '(') { RET(CALL); } else { RET(VAR); } } }
char *getargv(int n) /* get ARGV[n] */ { Cell *x; char *s, temp[50]; extern Array *ARGVtab; sprintf(temp, "%d", n); x = setsymtab(temp, "", 0.0, STR, ARGVtab); s = getsval(x); dprintf( ("getargv(%d) returns |%s|\n", n, s) ); return s; }
void envinit(char **envp) /* set up ENVIRON variable */ { Cell *cp; char *p; cp = setsymtab("ENVIRON", "", 0.0, ARR, symtab); ENVtab = makesymtab(NSYMTAB); cp->sval = (char *) ENVtab; for ( ; *envp; envp++) { if ((p = strchr(*envp, '=')) == NULL) continue; if( p == *envp ) /* no left hand side name in env string */ continue; *p++ = 0; /* split into two strings at = */ if (is_number(p)) setsymtab(*envp, p, atof(p), STR|NUM, ENVtab); else setsymtab(*envp, p, 0.0, STR, ENVtab); p[-1] = '='; /* restore in case env is passed down to a shell */ } }
unsigned char *getargv(int n) /* get ARGV[n] */ { Cell *x; unsigned char *s, temp[25]; extern Array *ARGVtab; snprintf((char *)temp, sizeof temp, "%d", n); x = setsymtab(temp, "", 0.0, STR, ARGVtab); s = getsval(x); dprintf( ("getargv(%d) returns |%s|\n", n, s) ); return s; }
void setclvar(char *s) /* set var=value from s */ { char *p; cell *q; for (p=s; *p != '='; p++) ; *p++ = 0; q = setsymtab(s, tostring(p), 0.0, STR, symtab); setsval(q, p); dprintf("command line set %s to |%s|\n", s, p); }
char *getargv(int n) /* get ARGV[n] */ { Cell *x; char *s, temp[50]; extern Array *ARGVtab; snprintf(temp, sizeof(temp), "%d", n); if (lookup(temp, ARGVtab) == NULL) return NULL; x = setsymtab(temp, "", 0.0, STR, ARGVtab); s = getsval(x); dprintf( ("getargv(%d) returns |%s|\n", n, s) ); return s; }
void setclvar(unsigned char *s) /* set var=value from s */ { unsigned char *p; Cell *q; for (p=s; *p != '='; p++) ; *p++ = 0; p = qstring(p, '\0'); q = setsymtab(s, p, 0.0, STR, symtab); setsval(q, p); (void)is2number(0, q); dprintf( ("command line set %s to |%s|\n", s, p) ); }
Cell *catstr(Cell *a, Cell *b) /* concatenate a and b */ { Cell *c; char *p; char *sa = getsval(a); char *sb = getsval(b); size_t l = strlen(sa) + strlen(sb) + 1; p = malloc(l); if (p == NULL) FATAL("out of space concatenating %s and %s", sa, sb); snprintf(p, l, "%s%s", sa, sb); c = setsymtab(p, p, 0.0, CON|STR|DONTFREE, symtab); free(p); return c; }
void arginit(int ac, uchar *av[]) { Cell *cp; int i; uchar temp[5]; for (i = 1; i < ac; i++) /* first make FILENAME first real argument */ if (!isclvar(av[i])) { setsval(lookup("FILENAME", symtab), av[i]); break; } ARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval; cp = setsymtab("ARGV", "", 0.0, ARR, symtab); ARGVtab = makesymtab(NSYMTAB); /* could be (int) ARGC as well */ cp->sval = (uchar *) ARGVtab; for (i = 0; i < ac; i++) { sprintf((char *)temp, "%d", i); if (isnumber(*av)) setsymtab(temp, *av, atof(*av), STR|NUM, ARGVtab); else setsymtab(temp, *av, 0.0, STR, ARGVtab); av++; } }
void setclvar(char *s) /* set var=value from s */ { char *p; Cell *q; for (p=s; *p != '='; p++) ; *p++ = 0; p = qstring(p, '\0'); q = setsymtab(s, p, 0.0, STR, symtab); setsval(q, p); if (is_number(q->sval)) { q->fval = atof(q->sval); q->tval |= NUM; } dprintf( ("command line set %s to |%s|\n", s, p) ); }
Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ { Cell *x, *y, *z; char *s; Node *np; char *buf; int bufsz = recsize; int nsub = strlen(*SUBSEP); if ((buf = (char *) malloc(bufsz)) == NULL) FATAL("out of memory in array"); x = execute(a[0]); /* Cell* for symbol table */ 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, "array")) FATAL("out of memory for %s[%s...]", x->nval, buf); strcat(buf, s); if (np->nnext) strcat(buf, *SUBSEP); tempfree(y); } if (!isarr(x)) { dprintf( ("making %s into an array\n", NN(x->nval)) ); if (freeable(x)) xfree(x->sval); x->tval &= ~(STR|NUM|DONTFREE); x->tval |= ARR; x->sval = (char *) makesymtab(NSYMTAB); } z = setsymtab(buf, "", 0.0, STR|NUM, (Array *) x->sval); z->ctype = OCELL; z->csub = CVAR; tempfree(x); free(buf); return(z); }
void syminit(void) /* initialize symbol table with builtin vars */ { literal0 = setsymtab("0", "0", 0.0, NUM|STR|CON|DONTFREE, symtab); /* this is used for if(x)... tests: */ nullloc = setsymtab("$zero&null", "", 0.0, NUM|STR|CON|DONTFREE, symtab); nullnode = celltonode(nullloc, CCON); fsloc = setsymtab("FS", " ", 0.0, STR|DONTFREE, symtab); FS = &fsloc->sval; RS = &setsymtab("RS", "\n", 0.0, STR|DONTFREE, symtab)->sval; OFS = &setsymtab("OFS", " ", 0.0, STR|DONTFREE, symtab)->sval; ORS = &setsymtab("ORS", "\n", 0.0, STR|DONTFREE, symtab)->sval; OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval; CONVFMT = &setsymtab("CONVFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval; FILENAME = &setsymtab("FILENAME", "", 0.0, STR|DONTFREE, symtab)->sval; nfloc = setsymtab("NF", "", 0.0, NUM, symtab); NF = &nfloc->fval; nrloc = setsymtab("NR", "", 0.0, NUM, symtab); NR = &nrloc->fval; fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab); FNR = &fnrloc->fval; SUBSEP = &setsymtab("SUBSEP", "\034", 0.0, STR|DONTFREE, symtab)->sval; rstartloc = setsymtab("RSTART", "", 0.0, NUM, symtab); RSTART = &rstartloc->fval; rlengthloc = setsymtab("RLENGTH", "", 0.0, NUM, symtab); RLENGTH = &rlengthloc->fval; symtabloc = setsymtab("SYMTAB", "", 0.0, ARR, symtab); symtabloc->sval = (char *) symtab; }
void syminit(void) { static wchar_t L_0[] = L"0"; static wchar_t L_zeronull[] = L"$zero&null"; static wchar_t L_record[] = L"$record"; static wchar_t L_FS[] = L"FS"; static wchar_t L_OFS[] = L"OFS"; static wchar_t L_ORS[] = L"ORS"; static wchar_t L_RS[] = L"RS"; static wchar_t L_OFMT[] = L"OFMT"; static wchar_t L_space[] = L" "; static wchar_t L_newline[] = L"\n"; static wchar_t L_dot6g[] = L"%.6g"; static wchar_t L_FILENAME[] = L"FILENAME"; static wchar_t L_NF[] = L"NF"; static wchar_t L_NR[] = L"NR"; setsymtab(L_0, tostring(L_0), 0.0, NUM|STR|CON|FLD, symtab); /* this one is used for if (x)... tests: */ setsymtab(L_zeronull, tostring(L_NULL), 0.0, NUM|STR|CON|FLD, symtab); recloc = setsymtab(L_record, record, 0.0, STR|FLD, symtab); dprintf("recloc %o lookup %o\n", recloc, lookup(L_record, symtab, 0), NULL); FS = &setsymtab(L_FS, tostring(L_space), 0.0, STR|FLD, symtab)->sval; RS = &setsymtab(L_RS, tostring(L_newline), 0.0, STR|FLD, symtab)->sval; OFS = &setsymtab(L_OFS, tostring(L_space), 0.0, STR|FLD, symtab)->sval; ORS = &setsymtab(L_ORS, tostring(L_newline), 0.0, STR|FLD, symtab)->sval; OFMT = &setsymtab(L_OFMT, tostring(L_dot6g), 0.0, STR|FLD, symtab)->sval; FILENAME = &setsymtab(L_FILENAME, NULL, 0.0, STR|FLD, symtab)->sval; nfloc = setsymtab(L_NF, NULL, 0.0, NUM, symtab); NF = &nfloc->fval; nrloc = setsymtab(L_NR, NULL, 0.0, NUM, symtab); NR = &nrloc->fval; }
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); }
void syminit(void) { setsymtab("0", tostring("0"), 0.0, NUM|STR|CON|FLD, symtab); /* this one is used for if(x)... tests: */ setsymtab("$zero&null", tostring(""), 0.0, NUM|STR|CON|FLD, symtab); recloc = setsymtab("$record", record, 0.0, STR|FLD, symtab); dprintf("recloc %lo lookup %lo\n", (long)recloc, (long)lookup("$record", symtab, 0)); FS = &setsymtab("FS", tostring(" "), 0.0, STR|FLD, symtab)->sval; RS = &setsymtab("RS", tostring("\n"), 0.0, STR|FLD, symtab)->sval; OFS = &setsymtab("OFS", tostring(" "), 0.0, STR|FLD, symtab)->sval; ORS = &setsymtab("ORS", tostring("\n"), 0.0, STR|FLD, symtab)->sval; OFMT = &setsymtab("OFMT", tostring("%.6g"), 0.0, STR|FLD, symtab)->sval; FILENAME = &setsymtab("FILENAME", EMPTY, 0.0, STR|FLD, symtab)->sval; nfloc = setsymtab("NF", EMPTY, 0.0, NUM, symtab); NF = &nfloc->fval; nrloc = setsymtab("NR", EMPTY, 0.0, NUM, symtab); NR = &nrloc->fval; }
int string(void) { int c, n; char *s, *bp; static char *buf = 0; static int bufsz = 500; if (buf == 0 && (buf = (char *) malloc(bufsz)) == NULL) FATAL("out of space for strings"); for (bp = buf; (c = input()) != '"'; ) { if (!adjbuf(&buf, &bufsz, bp-buf+2, 500, &bp, 0)) FATAL("out of space for string %.10s...", buf); switch (c) { case '\n': case '\r': case 0: SYNTAX( "non-terminated string %.10s...", buf ); lineno++; if (c == 0) /* hopeless */ FATAL( "giving up" ); break; case '\\': c = input(); switch (c) { case '"': *bp++ = '"'; break; case 'n': *bp++ = '\n'; break; case 't': *bp++ = '\t'; break; case 'f': *bp++ = '\f'; break; case 'r': *bp++ = '\r'; break; case 'b': *bp++ = '\b'; break; case 'v': *bp++ = '\v'; break; case 'a': *bp++ = '\007'; break; case '\\': *bp++ = '\\'; break; case '0': case '1': case '2': /* octal: \d \dd \ddd */ case '3': case '4': case '5': case '6': case '7': n = c - '0'; if ((c = peek()) >= '0' && c < '8') { n = 8 * n + input() - '0'; if ((c = peek()) >= '0' && c < '8') n = 8 * n + input() - '0'; } *bp++ = n; break; case 'x': /* hex \x0-9a-fA-F + */ { char xbuf[100], *px; for (px = xbuf; (c = input()) != 0 && px-xbuf < 100-2; ) { if (isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) *px++ = c; else break; } *px = 0; unput(c); sscanf(xbuf, "%x", &n); *bp++ = n; break; } default: *bp++ = c; break; } break; default: *bp++ = c; break; } } *bp = 0; s = tostring(buf); *bp++ = ' '; *bp++ = 0; yylval.cp = setsymtab(buf, s, 0.0, CON|STR|DONTFREE, symtab); RET(STRING); }
int yylex(void) { int c; static char *buf = 0; static int bufsize = 500; if (buf == 0 && (buf = (char *) malloc(bufsize)) == NULL) FATAL( "out of space in yylex" ); if (sc) { sc = 0; RET('}'); } if (reg) { reg = 0; return regexpr(); } /* printf("top\n"); */ for (;;) { c = gettok(&buf, &bufsize); /* printf("gettok [%s]\n", buf); */ if (c == 0) return 0; if (isalpha(c) || c == '_') return word(buf); if (isdigit(c)) { yylval.cp = setsymtab(buf, tostring(buf), atof(buf), CON|NUM, symtab); /* should this also have STR set? */ RET(NUMBER); } yylval.i = c; switch (c) { case '\n': /* {EOL} */ RET(NL); case '\r': /* assume \n is coming */ case ' ': /* {WS}+ */ case '\t': break; case '#': /* #.* strip comments */ while ((c = input()) != '\n' && c != 0) ; unput(c); break; case ';': RET(';'); case '\\': if (peek() == '\n') { input(); } else if (peek() == '\r') { input(); input(); /* \n */ lineno++; } else { RET(c); } break; case '&': if (peek() == '&') { input(); RET(AND); } else RET('&'); case '|': if (peek() == '|') { input(); RET(BOR); } else RET('|'); case '!': if (peek() == '=') { input(); yylval.i = NE; RET(NE); } else if (peek() == '~') { input(); yylval.i = NOTMATCH; RET(MATCHOP); } else RET(NOT); case '~': yylval.i = MATCH; RET(MATCHOP); case '<': if (peek() == '=') { input(); yylval.i = LE; RET(LE); } else { yylval.i = LT; RET(LT); } case '=': if (peek() == '=') { input(); yylval.i = EQ; RET(EQ); } else { yylval.i = ASSIGN; RET(ASGNOP); } case '>': if (peek() == '=') { input(); yylval.i = GE; RET(GE); } else if (peek() == '>') { input(); yylval.i = APPEND; RET(APPEND); } else { yylval.i = GT; RET(GT); } case '+': if (peek() == '+') { input(); yylval.i = INCR; RET(INCR); } else if (peek() == '=') { input(); yylval.i = ADDEQ; RET(ASGNOP); } else RET('+'); case '-': if (peek() == '-') { input(); yylval.i = DECR; RET(DECR); } else if (peek() == '=') { input(); yylval.i = SUBEQ; RET(ASGNOP); } else RET('-'); case '*': if (peek() == '=') { /* *= */ input(); yylval.i = MULTEQ; RET(ASGNOP); } else if (peek() == '*') { /* ** or **= */ input(); /* eat 2nd * */ if (peek() == '=') { input(); yylval.i = POWEQ; RET(ASGNOP); } else { RET(POWER); } } else RET('*'); case '/': RET('/'); case '%': if (peek() == '=') { input(); yylval.i = MODEQ; RET(ASGNOP); } else RET('%'); case '^': if (peek() == '=') { input(); yylval.i = POWEQ; RET(ASGNOP); } else RET(POWER); case '$': /* BUG: awkward, if not wrong */ c = gettok(&buf, &bufsize); if (isalpha(c)) { if (strcmp(buf, "NF") == 0) { /* very special */ unputstr("(NF)"); RET(INDIRECT); } c = peek(); if (c == '(' || c == '[' || (infunc && isarg(buf) >= 0)) { unputstr(buf); RET(INDIRECT); } yylval.cp = setsymtab(buf, "", 0.0, STR|NUM, symtab); RET(IVAR); } else if (c == 0) { /* */ SYNTAX( "unexpected end of input after $" ); RET(';'); } else { unputstr(buf); RET(INDIRECT); } case '}': if (--bracecnt < 0) SYNTAX( "extra }" ); sc = 1; RET(';'); case ']': if (--brackcnt < 0) SYNTAX( "extra ]" ); RET(']'); case ')': if (--parencnt < 0) SYNTAX( "extra )" ); RET(')'); case '{': bracecnt++; RET('{'); case '[': brackcnt++; RET('['); case '(': parencnt++; RET('('); case '"': return string(); /* BUG: should be like tran.c ? */ default: RET(c); } } }
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); }
syminit() { extern Node *valtonode(); extern Cell fldtab[]; symtab = makesymtab(NSYMTAB); setsymtab("0", "0", 0.0, NUM|STR|CON, symtab); /* this is used for if(x)... tests: */ nullloc = setsymtab("$zero&null", "", 0.0, NUM|STR|CON, symtab); nullnode = valtonode(nullloc, CCON); /* recloc = setsymtab("$0", record, 0.0, REC|STR|DONTFREE, symtab); */ recloc = &fldtab[0]; FS = &setsymtab("FS", " ", 0.0, STR, symtab)->sval; RS = &setsymtab("RS", "\n", 0.0, STR, symtab)->sval; OFS = &setsymtab("OFS", " ", 0.0, STR, symtab)->sval; ORS = &setsymtab("ORS", "\n", 0.0, STR, symtab)->sval; OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR, symtab)->sval; FILENAME = &setsymtab("FILENAME", "", 0.0, STR, symtab)->sval; nfloc = setsymtab("NF", "", 0.0, NUM, symtab); NF = &nfloc->fval; nrloc = setsymtab("NR", "", 0.0, NUM, symtab); NR = &nrloc->fval; fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab); FNR = &fnrloc->fval; SUBSEP = &setsymtab("SUBSEP", "\034", 0.0, STR, symtab)->sval; rstartloc = setsymtab("RSTART", "", 0.0, NUM, symtab); RSTART = &rstartloc->fval; rlengthloc = setsymtab("RLENGTH", "", 0.0, NUM, symtab); RLENGTH = &rlengthloc->fval; symtabloc = setsymtab("SYMTAB", "", 0.0, ARR, symtab); symtabloc->sval = (uchar *) symtab; }