diff options
Diffstat (limited to 'editors/awk.c')
-rw-r--r-- | editors/awk.c | 491 |
1 files changed, 251 insertions, 240 deletions
diff --git a/editors/awk.c b/editors/awk.c index 76ebe0fb9..d0a8846b9 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -71,19 +71,19 @@ typedef struct rstream_s { typedef struct hash_item_s { union { - struct var_s v; /* variable/array hash */ - struct rstream_s rs; /* redirect streams hash */ - struct func_s f; /* functions hash */ + struct var_s v; /* variable/array hash */ + struct rstream_s rs; /* redirect streams hash */ + struct func_s f; /* functions hash */ } data; - struct hash_item_s *next; /* next in chain */ - char name[1]; /* really it's longer */ + struct hash_item_s *next; /* next in chain */ + char name[1]; /* really it's longer */ } hash_item; typedef struct xhash_s { - unsigned nel; /* num of elements */ - unsigned csize; /* current hash size */ - unsigned nprime; /* next hash size in PRIMES[] */ - unsigned glen; /* summary length of item names */ + unsigned nel; /* num of elements */ + unsigned csize; /* current hash size */ + unsigned nprime; /* next hash size in PRIMES[] */ + unsigned glen; /* summary length of item names */ struct hash_item_s **items; } xhash; @@ -156,42 +156,42 @@ typedef struct tsplitter_s { #define TC_STRING (1 << 28) #define TC_NUMBER (1 << 29) -#define TC_UOPPRE (TC_UOPPRE1 | TC_UOPPRE2) +#define TC_UOPPRE (TC_UOPPRE1 | TC_UOPPRE2) /* combined token classes */ -#define TC_BINOP (TC_BINOPX | TC_COMMA | TC_PIPE | TC_IN) -#define TC_UNARYOP (TC_UOPPRE | TC_UOPPOST) -#define TC_OPERAND (TC_VARIABLE | TC_ARRAY | TC_FUNCTION | \ - TC_BUILTIN | TC_GETLINE | TC_SEQSTART | TC_STRING | TC_NUMBER) +#define TC_BINOP (TC_BINOPX | TC_COMMA | TC_PIPE | TC_IN) +#define TC_UNARYOP (TC_UOPPRE | TC_UOPPOST) +#define TC_OPERAND (TC_VARIABLE | TC_ARRAY | TC_FUNCTION \ + | TC_BUILTIN | TC_GETLINE | TC_SEQSTART | TC_STRING | TC_NUMBER) -#define TC_STATEMNT (TC_STATX | TC_WHILE) -#define TC_OPTERM (TC_SEMICOL | TC_NEWLINE) +#define TC_STATEMNT (TC_STATX | TC_WHILE) +#define TC_OPTERM (TC_SEMICOL | TC_NEWLINE) /* word tokens, cannot mean something else if not expected */ -#define TC_WORD (TC_IN | TC_STATEMNT | TC_ELSE | TC_BUILTIN | \ - TC_GETLINE | TC_FUNCDECL | TC_BEGIN | TC_END) +#define TC_WORD (TC_IN | TC_STATEMNT | TC_ELSE | TC_BUILTIN \ + | TC_GETLINE | TC_FUNCDECL | TC_BEGIN | TC_END) /* discard newlines after these */ -#define TC_NOTERM (TC_COMMA | TC_GRPSTART | TC_GRPTERM | \ - TC_BINOP | TC_OPTERM) +#define TC_NOTERM (TC_COMMA | TC_GRPSTART | TC_GRPTERM \ + | TC_BINOP | TC_OPTERM) /* what can expression begin with */ -#define TC_OPSEQ (TC_OPERAND | TC_UOPPRE | TC_REGEXP) +#define TC_OPSEQ (TC_OPERAND | TC_UOPPRE | TC_REGEXP) /* what can group begin with */ -#define TC_GRPSEQ (TC_OPSEQ | TC_OPTERM | TC_STATEMNT | TC_GRPSTART) +#define TC_GRPSEQ (TC_OPSEQ | TC_OPTERM | TC_STATEMNT | TC_GRPSTART) /* if previous token class is CONCAT1 and next is CONCAT2, concatenation */ /* operator is inserted between them */ -#define TC_CONCAT1 (TC_VARIABLE | TC_ARRTERM | TC_SEQTERM | \ - TC_STRING | TC_NUMBER | TC_UOPPOST) -#define TC_CONCAT2 (TC_OPERAND | TC_UOPPRE) +#define TC_CONCAT1 (TC_VARIABLE | TC_ARRTERM | TC_SEQTERM \ + | TC_STRING | TC_NUMBER | TC_UOPPOST) +#define TC_CONCAT2 (TC_OPERAND | TC_UOPPRE) -#define OF_RES1 0x010000 -#define OF_RES2 0x020000 -#define OF_STR1 0x040000 -#define OF_STR2 0x080000 -#define OF_NUM1 0x100000 -#define OF_CHECKED 0x200000 +#define OF_RES1 0x010000 +#define OF_RES2 0x020000 +#define OF_STR1 0x040000 +#define OF_STR2 0x080000 +#define OF_NUM1 0x100000 +#define OF_CHECKED 0x200000 /* combined operator flags */ #define xx 0 @@ -205,16 +205,16 @@ typedef struct tsplitter_s { #define SV (OF_RES1 | OF_STR1 | OF_RES2) #define SS (OF_RES1 | OF_STR1 | OF_RES2 | OF_STR2) -#define OPCLSMASK 0xFF00 -#define OPNMASK 0x007F +#define OPCLSMASK 0xFF00 +#define OPNMASK 0x007F /* operator priority is a highest byte (even: r->l, odd: l->r grouping) * For builtins it has different meaning: n n s3 s2 s1 v3 v2 v1, * n - min. number of args, vN - resolve Nth arg to var, sN - resolve to string */ -#define P(x) (x << 24) -#define PRIMASK 0x7F000000 -#define PRIMASK2 0x7E000000 +#define P(x) (x << 24) +#define PRIMASK 0x7F000000 +#define PRIMASK2 0x7E000000 /* Operation classes */ @@ -222,44 +222,44 @@ typedef struct tsplitter_s { #define RECUR_FROM_THIS 0x1000 enum { - OC_DELETE=0x0100, OC_EXEC=0x0200, OC_NEWSOURCE=0x0300, - OC_PRINT=0x0400, OC_PRINTF=0x0500, OC_WALKINIT=0x0600, - - OC_BR=0x0700, OC_BREAK=0x0800, OC_CONTINUE=0x0900, - OC_EXIT=0x0a00, OC_NEXT=0x0b00, OC_NEXTFILE=0x0c00, - OC_TEST=0x0d00, OC_WALKNEXT=0x0e00, - - OC_BINARY=0x1000, OC_BUILTIN=0x1100, OC_COLON=0x1200, - OC_COMMA=0x1300, OC_COMPARE=0x1400, OC_CONCAT=0x1500, - OC_FBLTIN=0x1600, OC_FIELD=0x1700, OC_FNARG=0x1800, - OC_FUNC=0x1900, OC_GETLINE=0x1a00, OC_IN=0x1b00, - OC_LAND=0x1c00, OC_LOR=0x1d00, OC_MATCH=0x1e00, - OC_MOVE=0x1f00, OC_PGETLINE=0x2000, OC_REGEXP=0x2100, - OC_REPLACE=0x2200, OC_RETURN=0x2300, OC_SPRINTF=0x2400, - OC_TERNARY=0x2500, OC_UNARY=0x2600, OC_VAR=0x2700, - OC_DONE=0x2800, - - ST_IF=0x3000, ST_DO=0x3100, ST_FOR=0x3200, - ST_WHILE=0x3300 + OC_DELETE = 0x0100, OC_EXEC = 0x0200, OC_NEWSOURCE = 0x0300, + OC_PRINT = 0x0400, OC_PRINTF = 0x0500, OC_WALKINIT = 0x0600, + + OC_BR = 0x0700, OC_BREAK = 0x0800, OC_CONTINUE = 0x0900, + OC_EXIT = 0x0a00, OC_NEXT = 0x0b00, OC_NEXTFILE = 0x0c00, + OC_TEST = 0x0d00, OC_WALKNEXT = 0x0e00, + + OC_BINARY = 0x1000, OC_BUILTIN = 0x1100, OC_COLON = 0x1200, + OC_COMMA = 0x1300, OC_COMPARE = 0x1400, OC_CONCAT = 0x1500, + OC_FBLTIN = 0x1600, OC_FIELD = 0x1700, OC_FNARG = 0x1800, + OC_FUNC = 0x1900, OC_GETLINE = 0x1a00, OC_IN = 0x1b00, + OC_LAND = 0x1c00, OC_LOR = 0x1d00, OC_MATCH = 0x1e00, + OC_MOVE = 0x1f00, OC_PGETLINE = 0x2000, OC_REGEXP = 0x2100, + OC_REPLACE = 0x2200, OC_RETURN = 0x2300, OC_SPRINTF = 0x2400, + OC_TERNARY = 0x2500, OC_UNARY = 0x2600, OC_VAR = 0x2700, + OC_DONE = 0x2800, + + ST_IF = 0x3000, ST_DO = 0x3100, ST_FOR = 0x3200, + ST_WHILE = 0x3300 }; /* simple builtins */ enum { - F_in=0, F_rn, F_co, F_ex, F_lg, F_si, F_sq, F_sr, + F_in, F_rn, F_co, F_ex, F_lg, F_si, F_sq, F_sr, F_ti, F_le, F_sy, F_ff, F_cl }; /* builtins */ enum { - B_a2=0, B_ix, B_ma, B_sp, B_ss, B_ti, B_lo, B_up, + B_a2, B_ix, B_ma, B_sp, B_ss, B_ti, B_lo, B_up, B_ge, B_gs, B_su, B_an, B_co, B_ls, B_or, B_rs, B_xo, }; /* tokens and their corresponding info values */ -#define NTC "\377" /* switch to next token class (tc<<1) */ -#define NTCC '\377' +#define NTC "\377" /* switch to next token class (tc<<1) */ +#define NTCC '\377' #define OC_B OC_BUILTIN @@ -365,12 +365,12 @@ static const uint32_t tokeninfo[] = { /* internal variable names and their initial values */ /* asterisk marks SPECIAL vars; $ is just no-named Field0 */ enum { - CONVFMT=0, OFMT, FS, OFS, + CONVFMT, OFMT, FS, OFS, ORS, RS, RT, FILENAME, SUBSEP, ARGIND, ARGC, ARGV, ERRNO, FNR, NR, NF, IGNORECASE, - ENVIRON, F0, _intvarcount_ + ENVIRON, F0, NUM_INTERNAL_VARS }; static const char vNames[] = @@ -390,11 +390,11 @@ static const char vValues[] = /* hash size may grow to these values */ #define FIRST_PRIME 61; static const unsigned PRIMES[] = { 251, 1021, 4093, 16381, 65521 }; -enum { NPRIMES = sizeof(PRIMES) / sizeof(unsigned) }; +enum { NPRIMES = sizeof(PRIMES) / sizeof(PRIMES[0]) }; /* globals */ -static var * V[_intvarcount_]; +static var *intvar[NUM_INTERNAL_VARS]; static chain beginseq, mainseq, endseq, *seq; static int nextrec, nextfile; static node *break_ptr, *continue_ptr; @@ -421,6 +421,7 @@ static struct { int rollback; } ttt; /* It had even better name: 't'. Whoever knows what is it, please rename! */ +/* (actually it looks like unrelated stuff lumped together...) */ /* function prototypes */ static void handle_special(var *); @@ -508,7 +509,7 @@ static void hash_rebuild(xhash *hash) newsize = PRIMES[hash->nprime++]; newitems = xzalloc(newsize * sizeof(hash_item *)); - for (i=0; i<hash->csize; i++) { + for (i = 0; i < hash->csize; i++) { hi = hash->items[i]; while (hi) { thi = hi; @@ -548,16 +549,16 @@ static void *hash_find(xhash *hash, const char *name) return &(hi->data); } -#define findvar(hash, name) ((var*) hash_find((hash) , (name))) -#define newvar(name) ((var*) hash_find(vhash , (name))) -#define newfile(name) ((rstream*)hash_find(fdhash ,(name))) -#define newfunc(name) ((func*) hash_find(fnhash , (name))) +#define findvar(hash, name) ((var*) hash_find((hash), (name))) +#define newvar(name) ((var*) hash_find(vhash, (name))) +#define newfile(name) ((rstream*)hash_find(fdhash, (name))) +#define newfunc(name) ((func*) hash_find(fnhash, (name))) static void hash_remove(xhash *hash, const char *name) { hash_item *hi, **phi; - phi = &(hash->items[ hashidx(name) % hash->csize ]); + phi = &(hash->items[hashidx(name) % hash->csize]); while (*phi) { hi = *phi; if (strcmp(hi->name, name) == 0) { @@ -671,7 +672,6 @@ static var *setvar_p(var *v, char *value) clrvar(v); v->string = value; handle_special(v); - return v; } @@ -692,8 +692,8 @@ static var *setvar_u(var *v, const char *value) /* set array element to user string */ static void setari_u(var *a, int idx, const char *s) { + char sidx[sizeof(int)*3 + 1]; var *v; - static char sidx[12]; sprintf(sidx, "%d", idx); v = findvar(iamarray(a), sidx); @@ -714,7 +714,7 @@ static const char *getvar_s(var *v) { /* if v is numeric and has no cached string, convert it to string */ if ((v->type & (VF_NUMBER | VF_CACHED)) == VF_NUMBER) { - fmt_num(buf, MAXVARFMT, getvar_s(V[CONVFMT]), v->number, TRUE); + fmt_num(buf, MAXVARFMT, getvar_s(intvar[CONVFMT]), v->number, TRUE); v->string = xstrdup(buf); v->type |= VF_CACHED; } @@ -819,8 +819,8 @@ static void nvfree(var *v) if (v < cb->nv || v >= cb->pos) runtime_error(EMSG_INTERNAL_ERROR); - for (p=v; p<cb->pos; p++) { - if ((p->type & (VF_ARRAY|VF_CHILD)) == VF_ARRAY) { + for (p = v; p < cb->pos; p++) { + if ((p->type & (VF_ARRAY | VF_CHILD)) == VF_ARRAY) { clear_array(iamarray(p)); free(p->x.array->items); free(p->x.array); @@ -868,7 +868,8 @@ static uint32_t next_token(uint32_t expected) skip_spaces(&p); lineno = ttt.lineno; if (*p == '#') - while (*p != '\n' && *p != '\0') p++; + while (*p != '\n' && *p != '\0') + p++; if (*p == '\n') ttt.lineno++; @@ -894,11 +895,14 @@ static uint32_t next_token(uint32_t expected) while (*p != '/') { if (*p == '\0' || *p == '\n') syntax_error(EMSG_UNEXP_EOS); - if ((*s++ = *p++) == '\\') { + *s++ = *p++; + if (*s++ == '\\') { pp = p; *(s-1) = bb_process_escape_sequence((const char **)&p); - if (*pp == '\\') *s++ = '\\'; - if (p == pp) *s++ = *p++; + if (*pp == '\\') + *s++ = '\\'; + if (p == pp) + *s++ = *p++; } } p++; @@ -927,9 +931,10 @@ static uint32_t next_token(uint32_t expected) * matches and it's not a longer word, * then this is what we are looking for */ - if ((tc & (expected | TC_WORD | TC_NEWLINE)) && - *tl == *p && strncmp(p, tl, l) == 0 && - !((tc & TC_WORD) && isalnum_(*(p + l)))) { + if ((tc & (expected | TC_WORD | TC_NEWLINE)) + && *tl == *p && strncmp(p, tl, l) == 0 + && !((tc & TC_WORD) && isalnum_(p[l])) + ) { ttt.info = *ti; p += l; break; @@ -952,7 +957,8 @@ static uint32_t next_token(uint32_t expected) *(p-1) = '\0'; tc = TC_VARIABLE; /* also consume whitespace between functionname and bracket */ - if (!(expected & TC_VARIABLE)) skip_spaces(&p); + if (!(expected & TC_VARIABLE)) + skip_spaces(&p); if (*p == '(') { tc = TC_FUNCTION; } else { @@ -970,7 +976,7 @@ static uint32_t next_token(uint32_t expected) goto readnext; /* insert concatenation operator when needed */ - if ((ltclass&TC_CONCAT1) && (tc&TC_CONCAT2) && (expected&TC_BINOP)) { + if ((ltclass & TC_CONCAT1) && (tc & TC_CONCAT2) && (expected & TC_BINOP)) { concat_inserted = TRUE; save_tclass = tc; save_info = ttt.info; @@ -983,9 +989,9 @@ static uint32_t next_token(uint32_t expected) ltclass = ttt.tclass; /* Are we ready for this? */ - if (! (ltclass & expected)) + if (!(ltclass & expected)) syntax_error((ltclass & (TC_NEWLINE | TC_EOF)) ? - EMSG_UNEXP_EOS : EMSG_UNEXP_TOKEN); + EMSG_UNEXP_EOS : EMSG_UNEXP_TOKEN); return ltclass; } @@ -1011,7 +1017,7 @@ static node *mk_re_node(const char *s, node *n, regex_t *re) n->l.re = re; n->r.ire = re + 1; xregcomp(re, s, REG_EXTENDED); - xregcomp(re+1, s, REG_EXTENDED | REG_ICASE); + xregcomp(re + 1, s, REG_EXTENDED | REG_ICASE); return n; } @@ -1037,9 +1043,9 @@ static node *parse_expr(uint32_t iexp) xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP | iexp; while (!((tc = next_token(xtc)) & iexp)) { - if (glptr && (ttt.info == (OC_COMPARE|VV|P(39)|2))) { + if (glptr && (ttt.info == (OC_COMPARE | VV | P(39) | 2))) { /* input redirection (<) attached to glptr node */ - cn = glptr->l.n = new_node(OC_CONCAT|SS|P(37)); + cn = glptr->l.n = new_node(OC_CONCAT | SS | P(37)); cn->a.n = glptr; xtc = TC_OPERAND | TC_UOPPRE; glptr = NULL; @@ -1048,8 +1054,8 @@ static node *parse_expr(uint32_t iexp) /* for binary and postfix-unary operators, jump back over * previous operators with higher priority */ vn = cn; - while ( ((ttt.info & PRIMASK) > (vn->a.n->info & PRIMASK2)) || - ((ttt.info == vn->info) && ((ttt.info & OPCLSMASK) == OC_COLON)) ) + while ( ((ttt.info & PRIMASK) > (vn->a.n->info & PRIMASK2)) + || ((ttt.info == vn->info) && ((ttt.info & OPCLSMASK) == OC_COLON)) ) vn = vn->a.n; if ((ttt.info & OPCLSMASK) == OC_TERNARY) ttt.info += P(6); @@ -1086,7 +1092,8 @@ static node *parse_expr(uint32_t iexp) case TC_VARIABLE: case TC_ARRAY: cn->info = OC_VAR; - if ((v = hash_search(ahash, ttt.string)) != NULL) { + v = hash_search(ahash, ttt.string); + if (v != NULL) { cn->info = OC_FNARG; cn->l.i = v->x.aidx; } else { @@ -1213,83 +1220,83 @@ static void chain_group(void) chain_expr(OC_EXEC | Vx); } else { /* TC_STATEMNT */ switch (ttt.info & OPCLSMASK) { - case ST_IF: - n = chain_node(OC_BR | Vx); - n->l.n = condition(); + case ST_IF: + n = chain_node(OC_BR | Vx); + n->l.n = condition(); + chain_group(); + n2 = chain_node(OC_EXEC); + n->r.n = seq->last; + if (next_token(TC_GRPSEQ | TC_GRPTERM | TC_ELSE) == TC_ELSE) { chain_group(); - n2 = chain_node(OC_EXEC); - n->r.n = seq->last; - if (next_token(TC_GRPSEQ | TC_GRPTERM | TC_ELSE)==TC_ELSE) { - chain_group(); - n2->a.n = seq->last; - } else { - rollback_token(); - } - break; + n2->a.n = seq->last; + } else { + rollback_token(); + } + break; - case ST_WHILE: - n2 = condition(); - n = chain_loop(NULL); - n->l.n = n2; - break; + case ST_WHILE: + n2 = condition(); + n = chain_loop(NULL); + n->l.n = n2; + break; - case ST_DO: - n2 = chain_node(OC_EXEC); - n = chain_loop(NULL); - n2->a.n = n->a.n; - next_token(TC_WHILE); - n->l.n = condition(); - break; + case ST_DO: + n2 = chain_node(OC_EXEC); + n = chain_loop(NULL); + n2->a.n = n->a.n; + next_token(TC_WHILE); + n->l.n = condition(); + break; - case ST_FOR: - next_token(TC_SEQSTART); - n2 = parse_expr(TC_SEMICOL | TC_SEQTERM); - if (ttt.tclass & TC_SEQTERM) { /* for-in */ - if ((n2->info & OPCLSMASK) != OC_IN) - syntax_error(EMSG_UNEXP_TOKEN); - n = chain_node(OC_WALKINIT | VV); - n->l.n = n2->l.n; - n->r.n = n2->r.n; - n = chain_loop(NULL); - n->info = OC_WALKNEXT | Vx; - n->l.n = n2->l.n; - } else { /* for (;;) */ - n = chain_node(OC_EXEC | Vx); - n->l.n = n2; - n2 = parse_expr(TC_SEMICOL); - n3 = parse_expr(TC_SEQTERM); - n = chain_loop(n3); - n->l.n = n2; - if (! n2) - n->info = OC_EXEC; - } - break; + case ST_FOR: + next_token(TC_SEQSTART); + n2 = parse_expr(TC_SEMICOL | TC_SEQTERM); + if (ttt.tclass & TC_SEQTERM) { /* for-in */ + if ((n2->info & OPCLSMASK) != OC_IN) + syntax_error(EMSG_UNEXP_TOKEN); + n = chain_node(OC_WALKINIT | VV); + n->l.n = n2->l.n; + n->r.n = n2->r.n; + n = chain_loop(NULL); + n->info = OC_WALKNEXT | Vx; + n->l.n = n2->l.n; + } else { /* for (;;) */ + n = chain_node(OC_EXEC | Vx); + n->l.n = n2; + n2 = parse_expr(TC_SEMICOL); + n3 = parse_expr(TC_SEQTERM); + n = chain_loop(n3); + n->l.n = n2; + if (! n2) + n->info = OC_EXEC; + } + break; - case OC_PRINT: - case OC_PRINTF: - n = chain_node(ttt.info); - n->l.n = parse_expr(TC_OPTERM | TC_OUTRDR | TC_GRPTERM); - if (ttt.tclass & TC_OUTRDR) { - n->info |= ttt.info; - n->r.n = parse_expr(TC_OPTERM | TC_GRPTERM); - } - if (ttt.tclass & TC_GRPTERM) - rollback_token(); - break; + case OC_PRINT: + case OC_PRINTF: + n = chain_node(ttt.info); + n->l.n = parse_expr(TC_OPTERM | TC_OUTRDR | TC_GRPTERM); + if (ttt.tclass & TC_OUTRDR) { + n->info |= ttt.info; + n->r.n = parse_expr(TC_OPTERM | TC_GRPTERM); + } + if (ttt.tclass & TC_GRPTERM) + rollback_token(); + break; - case OC_BREAK: - n = chain_node(OC_EXEC); - n->a.n = break_ptr; - break; + case OC_BREAK: + n = chain_node(OC_EXEC); + n->a.n = break_ptr; + break; - case OC_CONTINUE: - n = chain_node(OC_EXEC); - n->a.n = continue_ptr; - break; + case OC_CONTINUE: + n = chain_node(OC_EXEC); + n->a.n = continue_ptr; + break; - /* delete, next, nextfile, return, exit */ - default: - chain_expr(ttt.info); + /* delete, next, nextfile, return, exit */ + default: + chain_expr(ttt.info); } } } @@ -1304,7 +1311,7 @@ static void parse_program(char *p) pos = p; ttt.lineno = 1; while ((tclass = next_token(TC_EOF | TC_OPSEQ | TC_GRPSTART | - TC_OPTERM | TC_BEGIN | TC_END | TC_FUNCDECL)) != TC_EOF) { + TC_OPTERM | TC_BEGIN | TC_END | TC_FUNCDECL)) != TC_EOF) { if (tclass & TC_OPTERM) continue; @@ -1389,13 +1396,12 @@ static regex_t *as_regex(node *op, regex_t *preg) if ((op->info & OPCLSMASK) == OC_REGEXP) { return icase ? op->r.ire : op->l.re; - } else { - v = nvalloc(1); - s = getvar_s(evaluate(op, v)); - xregcomp(preg, s, icase ? REG_EXTENDED | REG_ICASE : REG_EXTENDED); - nvfree(v); - return preg; } + v = nvalloc(1); + s = getvar_s(evaluate(op, v)); + xregcomp(preg, s, icase ? REG_EXTENDED | REG_ICASE : REG_EXTENDED); + nvfree(v); + return preg; } /* gradually increasing buffer */ @@ -1442,7 +1448,8 @@ static int awk_split(const char *s, node *spl, char **slist) c[0] = c[1] = (char)spl->info; c[2] = c[3] = '\0'; - if (*getvar_s(V[RS]) == '\0') c[2] = '\n'; + if (*getvar_s(intvar[RS]) == '\0') + c[2] = '\n'; if ((spl->info & OPCLSMASK) == OC_REGEXP) { /* regex split */ while (*s) { @@ -1451,7 +1458,10 @@ static int awk_split(const char *s, node *spl, char **slist) && pmatch[0].rm_so <= l ) { l = pmatch[0].rm_so; - if (pmatch[0].rm_eo == 0) { l++; pmatch[0].rm_eo++; } + if (pmatch[0].rm_eo == 0) { + l++; + pmatch[0].rm_eo++; + } } else { pmatch[0].rm_eo = l; if (s[l]) pmatch[0].rm_eo++; @@ -1495,6 +1505,7 @@ static int awk_split(const char *s, node *spl, char **slist) static void split_f0(void) { static char *fstrings = NULL; + int i, n; char *s; @@ -1504,7 +1515,7 @@ static void split_f0(void) is_f0_split = TRUE; free(fstrings); fsrealloc(0); - n = awk_split(getvar_s(V[F0]), &fsplitter.n, &fstrings); + n = awk_split(getvar_s(intvar[F0]), &fsplitter.n, &fstrings); fsrealloc(n); s = fstrings; for (i = 0; i < n; i++) { @@ -1513,9 +1524,9 @@ static void split_f0(void) } /* set NF manually to avoid side effects */ - clrvar(V[NF]); - V[NF]->type = VF_NUMBER | VF_SPECIAL; - V[NF]->number = nfields; + clrvar(intvar[NF]); + intvar[NF]->type = VF_NUMBER | VF_SPECIAL; + intvar[NF]->number = nfields; } /* perform additional actions when some internal variables changed */ @@ -1529,16 +1540,16 @@ static void handle_special(var *v) if (!(v->type & VF_SPECIAL)) return; - if (v == V[NF]) { + if (v == intvar[NF]) { n = (int)getvar_i(v); fsrealloc(n); /* recalculate $0 */ - sep = getvar_s(V[OFS]); + sep = getvar_s(intvar[OFS]); sl = strlen(sep); b = NULL; len = 0; - for (i=0; i<n; i++) { + for (i = 0; i < n; i++) { s = getvar_s(&Fields[i]); l = strlen(s); if (b) { @@ -1551,24 +1562,24 @@ static void handle_special(var *v) } if (b) b[len] = '\0'; - setvar_p(V[F0], b); + setvar_p(intvar[F0], b); is_f0_split = TRUE; - } else if (v == V[F0]) { + } else if (v == intvar[F0]) { is_f0_split = FALSE; - } else if (v == V[FS]) { + } else if (v == intvar[FS]) { mk_splitter(getvar_s(v), &fsplitter); - } else if (v == V[RS]) { + } else if (v == intvar[RS]) { mk_splitter(getvar_s(v), &rsplitter); - } else if (v == V[IGNORECASE]) { + } else if (v == intvar[IGNORECASE]) { icase = istrue(v); } else { /* $n */ - n = getvar_i(V[NF]); - setvar_i(V[NF], n > v-Fields ? n : v-Fields+1); + n = getvar_i(intvar[NF]); + setvar_i(intvar[NF], n > v-Fields ? n : v-Fields+1); /* right here v is invalid. Just to note... */ } } @@ -1599,8 +1610,8 @@ static void hashwalk_init(var *v, xhash *array) v->type |= VF_WALK; w = v->x.walker = xzalloc(2 + 2*sizeof(char *) + array->glen); - *w = *(w+1) = (char *)(w + 2); - for (i=0; i<array->csize; i++) { + w[0] = w[1] = (char *)(w + 2); + for (i = 0; i < array->csize; i++) { hi = array->items[i]; while (hi) { strcpy(*w, hi->name); @@ -1615,7 +1626,7 @@ static int hashwalk_next(var *v) char **w; w = v->x.walker; - if (*(w+1) == *w) + if (w[1] == w[0]) return FALSE; setvar_s(v, nextword(w+1)); @@ -1658,7 +1669,7 @@ static int awk_getline(rstream *rsm, var *v) if (p > 0) { if ((rsplitter.n.info & OPCLSMASK) == OC_REGEXP) { if (regexec(icase ? rsplitter.n.r.ire : rsplitter.n.l.re, - b, 1, pmatch, 0) == 0) { + b, 1, pmatch, 0) == 0) { so = pmatch[0].rm_so; eo = pmatch[0].rm_eo; if (b[eo] != '\0') @@ -1698,7 +1709,7 @@ static int awk_getline(rstream *rsm, var *v) if (p < pp) { p = 0; r = 0; - setvar_i(V[ERRNO], errno); + setvar_i(intvar[ERRNO], errno); } b[p] = '\0'; @@ -1712,7 +1723,7 @@ static int awk_getline(rstream *rsm, var *v) v->type |= VF_USER; b[so] = c; c = b[eo]; b[eo] = '\0'; - setvar_s(V[RT], b+so); + setvar_s(intvar[RT], b+so); b[eo] = c; } @@ -1782,12 +1793,10 @@ static char *awk_printf(node *n) if (c == 'c' || !c) { i += sprintf(b+i, s, is_numeric(arg) ? (char)getvar_i(arg) : *getvar_s(arg)); - } else if (c == 's') { s1 = getvar_s(arg); qrealloc(&b, incr+i+strlen(s1), &bsize); i += sprintf(b+i, s, s1); - } else { i += fmt_num(b+i, incr, s, getvar_i(arg), FALSE); } @@ -1820,13 +1829,13 @@ static int awk_sub(node *rn, const char *repl, int nm, var *src, var *dest, int regex_t sreg, *re; re = as_regex(rn, &sreg); - if (! src) src = V[F0]; - if (! dest) dest = V[F0]; + if (! src) src = intvar[F0]; + if (! dest) dest = intvar[F0]; i = di = 0; sp = getvar_s(src); rl = strlen(repl); - while (regexec(re, sp, 10, pmatch, sp==getvar_s(src) ? 0:REG_NOTBOL) == 0) { + while (regexec(re, sp, 10, pmatch, sp==getvar_s(src) ? 0 : REG_NOTBOL) == 0) { so = pmatch[0].rm_so; eo = pmatch[0].rm_eo; @@ -1882,7 +1891,7 @@ static var *exec_builtin(node *op, var *res) int (*to_xxx)(int); var *tv; node *an[4]; - var *av[4]; + var *av[4]; const char *as[4]; regmatch_t pmatch[2]; regex_t sreg, *re; @@ -1899,7 +1908,7 @@ static var *exec_builtin(node *op, var *res) op = op->l.n; av[2] = av[3] = NULL; - for (i=0 ; i<4 && op ; i++) { + for (i = 0; i < 4 && op; i++) { an[i] = nextarg(&op); if (isr & 0x09000000) av[i] = evaluate(an[i], &tv[i]); if (isr & 0x08000000) as[i] = getvar_s(av[i]); @@ -1940,9 +1949,10 @@ static var *exec_builtin(node *op, var *res) case B_ss: l = strlen(as[0]); i = getvar_i(av[1]) - 1; - if (i>l) i=l; if (i<0) i=0; + if (i > l) i = l; + if (i < 0) i = 0; n = (nargs > 2) ? getvar_i(av[2]) : l-i; - if (n<0) n=0; + if (n < 0) n = 0; s = xmalloc(n+1); strncpy(s, as[0]+i, n); s[n] = '\0'; @@ -2168,22 +2178,22 @@ static var *evaluate(node *op, var *res) if ((opinfo & OPCLSMASK) == OC_PRINT) { if (! op1) { - fputs(getvar_s(V[F0]), X.F); + fputs(getvar_s(intvar[F0]), X.F); } else { while (op1) { L.v = evaluate(nextarg(&op1), v1); if (L.v->type & VF_NUMBER) { - fmt_num(buf, MAXVARFMT, getvar_s(V[OFMT]), + fmt_num(buf, MAXVARFMT, getvar_s(intvar[OFMT]), getvar_i(L.v), TRUE); fputs(buf, X.F); } else { fputs(getvar_s(L.v), X.F); } - if (op1) fputs(getvar_s(V[OFS]), X.F); + if (op1) fputs(getvar_s(intvar[OFS]), X.F); } } - fputs(getvar_s(V[ORS]), X.F); + fputs(getvar_s(intvar[ORS]), X.F); } else { /* OC_PRINTF */ L.s = awk_printf(op1); @@ -2235,7 +2245,7 @@ static var *evaluate(node *op, var *res) case XC( OC_VAR ): L.v = op->l.v; - if (L.v == V[NF]) + if (L.v == intvar[NF]) split_f0(); goto v_cont; @@ -2251,7 +2261,7 @@ static var *evaluate(node *op, var *res) case XC( OC_REGEXP ): op1 = op; - L.s = getvar_s(V[F0]); + L.s = getvar_s(intvar[F0]); goto re_cont; case XC( OC_MATCH ): @@ -2280,7 +2290,7 @@ static var *evaluate(node *op, var *res) break; case XC( OC_FUNC ): - if (! op->r.f->body.first) + if (!op->r.f->body.first) runtime_error(EMSG_UNDEF_FUNC); X.v = R.v = nvalloc(op->r.f->nargs+1); @@ -2308,7 +2318,7 @@ static var *evaluate(node *op, var *res) case XC( OC_PGETLINE ): if (op1) { X.rsm = newfile(L.s); - if (! X.rsm->F) { + if (!X.rsm->F) { if ((opinfo & OPCLSMASK) == OC_PGETLINE) { X.rsm->F = popen(L.s, "r"); X.rsm->is_pipe = TRUE; @@ -2317,24 +2327,24 @@ static var *evaluate(node *op, var *res) } } } else { - if (! iF) iF = next_input_file(); + if (!iF) iF = next_input_file(); X.rsm = iF; } - if (! X.rsm->F) { - setvar_i(V[ERRNO], errno); + if (!X.rsm->F) { + setvar_i(intvar[ERRNO], errno); setvar_i(res, -1); break; } - if (! op->r.n) - R.v = V[F0]; + if (!op->r.n) + R.v = intvar[F0]; L.i = awk_getline(X.rsm, R.v); if (L.i > 0) { - if (! op1) { - incvar(V[FNR]); - incvar(V[NR]); + if (!op1) { + incvar(intvar[FNR]); + incvar(intvar[NR]); } } setvar_i(res, L.i); @@ -2391,8 +2401,8 @@ static var *evaluate(node *op, var *res) break; case F_le: - if (! op1) - L.s = getvar_s(V[F0]); + if (!op1) + L.s = getvar_s(intvar[F0]); R.d = strlen(L.s); break; @@ -2403,7 +2413,7 @@ static var *evaluate(node *op, var *res) break; case F_ff: - if (! op1) + if (!op1) fflush(stdout); else { if (L.s && *L.s) { @@ -2423,7 +2433,7 @@ static var *evaluate(node *op, var *res) hash_remove(fdhash, L.s); } if (R.i != 0) - setvar_i(V[ERRNO], errno); + setvar_i(intvar[ERRNO], errno); R.d = (double)R.i; break; } @@ -2469,13 +2479,12 @@ static var *evaluate(node *op, var *res) case XC( OC_FIELD ): R.i = (int)getvar_i(R.v); if (R.i == 0) { - res = V[F0]; + res = intvar[F0]; } else { split_f0(); if (R.i > nfields) fsrealloc(R.i); - - res = &Fields[R.i-1]; + res = &Fields[R.i - 1]; } break; @@ -2486,7 +2495,7 @@ static var *evaluate(node *op, var *res) X.s = xmalloc(opn); strcpy(X.s, L.s); if ((opinfo & OPCLSMASK) == OC_COMMA) { - L.s = getvar_s(V[SUBSEP]); + L.s = getvar_s(intvar[SUBSEP]); X.s = xrealloc(X.s, opn + strlen(L.s)); strcat(X.s, L.s); } @@ -2531,7 +2540,7 @@ static var *evaluate(node *op, var *res) L.d -= (int)(L.d / R.d) * R.d; break; } - res = setvar_i(((opinfo&OPCLSMASK) == OC_BINARY) ? res : X.v, L.d); + res = setvar_i(((opinfo & OPCLSMASK) == OC_BINARY) ? res : X.v, L.d); break; case XC( OC_COMPARE ): @@ -2627,30 +2636,31 @@ static int is_assignment(const char *expr) static rstream *next_input_file(void) { static rstream rsm; + static int files_happen = FALSE; + FILE *F = NULL; const char *fname, *ind; - static int files_happen = FALSE; if (rsm.F) fclose(rsm.F); rsm.F = NULL; rsm.pos = rsm.adv = 0; do { - if (getvar_i(V[ARGIND])+1 >= getvar_i(V[ARGC])) { + if (getvar_i(intvar[ARGIND])+1 >= getvar_i(intvar[ARGC])) { if (files_happen) return NULL; fname = "-"; F = stdin; } else { - ind = getvar_s(incvar(V[ARGIND])); - fname = getvar_s(findvar(iamarray(V[ARGV]), ind)); + ind = getvar_s(incvar(intvar[ARGIND])); + fname = getvar_s(findvar(iamarray(intvar[ARGV]), ind)); if (fname && *fname && !is_assignment(fname)) F = afopen(fname, "r"); } } while (!F); files_happen = TRUE; - setvar_s(V[FILENAME], fname); + setvar_s(intvar[FILENAME], fname); rsm.F = F; return &rsm; } @@ -2685,7 +2695,7 @@ int awk_main(int argc, char **argv) /* initialize variables */ for (i = 0; *vnames; i++) { - V[i] = v = newvar(nextword(&vnames)); + intvar[i] = v = newvar(nextword(&vnames)); if (*vvalues != '\377') setvar_s(v, nextword(&vvalues)); else @@ -2697,8 +2707,8 @@ int awk_main(int argc, char **argv) } } - handle_special(V[FS]); - handle_special(V[RS]); + handle_special(intvar[FS]); + handle_special(intvar[RS]); newfile("/dev/stdin")->F = stdin; newfile("/dev/stdout")->F = stdout; @@ -2710,7 +2720,7 @@ int awk_main(int argc, char **argv) char *s1 = strchr(s, '='); if (s1) { *s1++ = '\0'; - setvar_u(findvar(iamarray(V[ENVIRON]), s), s1); + setvar_u(findvar(iamarray(intvar[ENVIRON]), s), s1); } free(s); } @@ -2718,7 +2728,8 @@ int awk_main(int argc, char **argv) opt = getopt32(argc, argv, "F:v:f:W:", &opt_F, &opt_v, &programname, &opt_W); argv += optind; argc -= optind; - if (opt & 0x1) setvar_s(V[FS], opt_F); // -F + if (opt & 0x1) + setvar_s(intvar[FS], opt_F); // -F while (opt_v) { /* -v */ if (!is_assignment(llist_pop(&opt_v))) bb_show_usage(); @@ -2753,11 +2764,11 @@ int awk_main(int argc, char **argv) bb_error_msg("warning: unrecognized option '-W %s' ignored", opt_W); /* fill in ARGV array */ - setvar_i(V[ARGC], argc + 1); - setari_u(V[ARGV], 0, "awk"); + setvar_i(intvar[ARGC], argc + 1); + setari_u(intvar[ARGV], 0, "awk"); i = 0; while (*argv) - setari_u(V[ARGV], ++i, *argv++); + setari_u(intvar[ARGV], ++i, *argv++); evaluate(beginseq.first, &tv); if (!mainseq.first && !endseq.first) @@ -2769,12 +2780,12 @@ int awk_main(int argc, char **argv) /* passing through input files */ while (iF) { nextfile = FALSE; - setvar_i(V[FNR], 0); + setvar_i(intvar[FNR], 0); - while ((i = awk_getline(iF, V[F0])) > 0) { + while ((i = awk_getline(iF, intvar[F0])) > 0) { nextrec = FALSE; - incvar(V[NR]); - incvar(V[FNR]); + incvar(intvar[NR]); + incvar(intvar[FNR]); evaluate(mainseq.first, &tv); if (nextfile) |