awk: make builtin definitions more understandable, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
640212ae0e
commit
786ca197ad
@ -331,8 +331,7 @@ if ((n) & TC_NUMBER ) debug_printf_parse(" NUMBER" ); \
|
||||
#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
|
||||
* (for builtins it has different meaning)
|
||||
*/
|
||||
#undef P
|
||||
#undef PRIMASK
|
||||
@ -430,8 +429,6 @@ static const char tokenlist[] ALIGN1 =
|
||||
/* compiler adds trailing "\0" */
|
||||
;
|
||||
|
||||
#define OC_B OC_BUILTIN
|
||||
|
||||
static const uint32_t tokeninfo[] ALIGN4 = {
|
||||
0,
|
||||
0,
|
||||
@ -464,20 +461,43 @@ static const uint32_t tokeninfo[] ALIGN4 = {
|
||||
OC_RETURN|Vx, OC_EXIT|Nx,
|
||||
ST_WHILE,
|
||||
0, /* else */
|
||||
OC_B|B_an|P(0x83), OC_B|B_co|P(0x41), OC_B|B_ls|P(0x83), OC_B|B_or|P(0x83),
|
||||
OC_B|B_rs|P(0x83), OC_B|B_xo|P(0x83),
|
||||
OC_FBLTIN|Sx|F_cl, OC_FBLTIN|Sx|F_sy, OC_FBLTIN|Sx|F_ff, OC_B|B_a2|P(0x83),
|
||||
OC_FBLTIN|Nx|F_co, OC_FBLTIN|Nx|F_ex, OC_FBLTIN|Nx|F_in, OC_FBLTIN|Nx|F_lg,
|
||||
OC_FBLTIN|F_rn, OC_FBLTIN|Nx|F_si, OC_FBLTIN|Nx|F_sq, OC_FBLTIN|Nx|F_sr,
|
||||
OC_B|B_ge|P(0xd6), OC_B|B_gs|P(0xb6), OC_B|B_ix|P(0x9b), /* OC_FBLTIN|Sx|F_le, was here */
|
||||
OC_B|B_ma|P(0x89), OC_B|B_sp|P(0x8b), OC_SPRINTF, OC_B|B_su|P(0xb6),
|
||||
OC_B|B_ss|P(0x8f), OC_FBLTIN|F_ti, OC_B|B_ti|P(0x0b), OC_B|B_mt|P(0x0b),
|
||||
OC_B|B_lo|P(0x49), OC_B|B_up|P(0x49),
|
||||
OC_FBLTIN|Sx|F_le, /* TC_LENGTH */
|
||||
OC_GETLINE|SV|P(0),
|
||||
0, 0,
|
||||
0,
|
||||
0 /* TC_END */
|
||||
// OC_B's are builtins with enforced minimum number of arguments (two upper bits).
|
||||
// Highest byte bit pattern: nn s3s2s1 v3v2v1
|
||||
// nn - min. number of args, sN - resolve Nth arg to string, vN - resolve to var
|
||||
// OC_FBLTIN's are builtins with one optional argument,
|
||||
// TODO: enforce exactly one arg for: system, close, cos, sin, exp, int, log, sqrt
|
||||
// zero args for: rand systime
|
||||
// Do have one optional arg: fflush, srand, length
|
||||
#define OC_B OC_BUILTIN
|
||||
#define A1 P(0x40) /*one arg*/
|
||||
#define A2 P(0x80) /*two args*/
|
||||
#define A3 P(0xc0) /*three args*/
|
||||
#define __v P(1)
|
||||
#define _vv P(3)
|
||||
#define __s__v P(9)
|
||||
#define __s_vv P(0x0b)
|
||||
#define __svvv P(0x0f)
|
||||
#define _ss_vv P(0x1b)
|
||||
#define _s_vv_ P(0x16)
|
||||
#define ss_vv_ P(0x36)
|
||||
OC_B|B_an|_vv|A2, OC_B|B_co|__v|A1, OC_B|B_ls|_vv|A2, OC_B|B_or|_vv|A2, // and compl lshift or
|
||||
OC_B|B_rs|_vv|A2, OC_B|B_xo|_vv|A2, // rshift xor
|
||||
OC_FBLTIN|Sx|F_cl, OC_FBLTIN|Sx|F_sy, OC_FBLTIN|Sx|F_ff, OC_B|B_a2|_vv|A2, // close system fflush atan2
|
||||
OC_FBLTIN|Nx|F_co, OC_FBLTIN|Nx|F_ex, OC_FBLTIN|Nx|F_in, OC_FBLTIN|Nx|F_lg, // cos exp int log
|
||||
OC_FBLTIN|F_rn, OC_FBLTIN|Nx|F_si, OC_FBLTIN|Nx|F_sq, OC_FBLTIN|Nx|F_sr, // rand sin sqrt srand
|
||||
OC_B|B_ge|_s_vv_|A3, OC_B|B_gs|ss_vv_|A2, OC_B|B_ix|_ss_vv|A2, // gensub gsub index /*length was here*/
|
||||
OC_B|B_ma|__s__v|A2, OC_B|B_sp|__s_vv|A2, OC_SPRINTF, OC_B|B_su|ss_vv_|A2, // match split sprintf sub
|
||||
OC_B|B_ss|__svvv|A2, OC_FBLTIN|F_ti, OC_B|B_ti|__s_vv, OC_B|B_mt|__s_vv, // substr systime strftime mktime
|
||||
OC_B|B_lo|__s__v|A1, OC_B|B_up|__s__v|A1, // tolower toupper
|
||||
OC_FBLTIN|Sx|F_le, // length
|
||||
OC_GETLINE|SV, // getline
|
||||
0, 0, // func function
|
||||
0, // BEGIN
|
||||
0 // END
|
||||
#undef A1
|
||||
#undef A2
|
||||
#undef A3
|
||||
#undef OC_B
|
||||
};
|
||||
|
||||
/* internal variable names and their initial values */
|
||||
@ -1630,6 +1650,7 @@ static void chain_group(void)
|
||||
debug_printf_parse("%s: OC_BREAK\n", __func__);
|
||||
n = chain_node(OC_EXEC);
|
||||
n->a.n = break_ptr;
|
||||
//TODO: if break_ptr is NULL, syntax error (not in the loop)?
|
||||
chain_expr(t_info);
|
||||
break;
|
||||
|
||||
@ -1637,6 +1658,7 @@ static void chain_group(void)
|
||||
debug_printf_parse("%s: OC_CONTINUE\n", __func__);
|
||||
n = chain_node(OC_EXEC);
|
||||
n->a.n = continue_ptr;
|
||||
//TODO: if continue_ptr is NULL, syntax error (not in the loop)?
|
||||
chain_expr(t_info);
|
||||
break;
|
||||
|
||||
@ -1799,8 +1821,8 @@ static regex_t *as_regex(node *op, regex_t *preg)
|
||||
return icase ? op->r.ire : op->l.re;
|
||||
}
|
||||
|
||||
#define TMPVAR (&G.as_regex__tmpvar)
|
||||
//tmpvar = nvalloc(1);
|
||||
#define TMPVAR (&G.as_regex__tmpvar)
|
||||
// We use a single "static" tmpvar (instead of on-stack or malloced one)
|
||||
// to decrease memory consumption in deeply-recursive awk programs.
|
||||
// The rule to work safely is to never call evaluate() while our static
|
||||
@ -2720,8 +2742,6 @@ static var *evaluate(node *op, var *res)
|
||||
#define sreg (G.evaluate__sreg)
|
||||
|
||||
var *tmpvars;
|
||||
#define TMPVAR0 (tmpvars)
|
||||
#define TMPVAR1 (tmpvars + 1)
|
||||
|
||||
if (!op)
|
||||
return setvar_s(res, NULL);
|
||||
@ -2729,6 +2749,8 @@ static var *evaluate(node *op, var *res)
|
||||
debug_printf_eval("entered %s()\n", __func__);
|
||||
|
||||
tmpvars = nvalloc(2);
|
||||
#define TMPVAR0 (tmpvars)
|
||||
#define TMPVAR1 (tmpvars + 1)
|
||||
|
||||
while (op) {
|
||||
struct {
|
||||
@ -3166,7 +3188,7 @@ static var *evaluate(node *op, var *res)
|
||||
rstream *rsm;
|
||||
int err = 0;
|
||||
rsm = (rstream *)hash_search(fdhash, L.s);
|
||||
debug_printf_eval("OC_FBLTIN F_cl rsm:%p\n", rsm);
|
||||
debug_printf_eval("OC_FBLTIN close: op1:%p s:'%s' rsm:%p\n", op1, L.s, rsm);
|
||||
if (rsm) {
|
||||
debug_printf_eval("OC_FBLTIN F_cl "
|
||||
"rsm->is_pipe:%d, ->F:%p\n",
|
||||
@ -3177,6 +3199,11 @@ static var *evaluate(node *op, var *res)
|
||||
*/
|
||||
if (rsm->F)
|
||||
err = rsm->is_pipe ? pclose(rsm->F) : fclose(rsm->F);
|
||||
//TODO: fix this case:
|
||||
// $ awk 'BEGIN { print close(""); print ERRNO }'
|
||||
// -1
|
||||
// close of redirection that was never opened
|
||||
// (we print 0, 0)
|
||||
free(rsm->buffer);
|
||||
hash_remove(fdhash, L.s);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user