summaryrefslogtreecommitdiffstats
path: root/contrib/awk/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/awk/eval.c')
-rw-r--r--contrib/awk/eval.c147
1 files changed, 95 insertions, 52 deletions
diff --git a/contrib/awk/eval.c b/contrib/awk/eval.c
index 37c5fef..3d5e568 100644
--- a/contrib/awk/eval.c
+++ b/contrib/awk/eval.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1999 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2000 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -68,6 +68,11 @@ static int func_tag_valid = FALSE;
static jmp_buf func_tag;
extern int exiting, exit_val;
+/* This rather ugly macro is for VMS C */
+#ifdef C
+#undef C
+#endif
+#define C(c) ((char)c)
/*
* This table is used by the regexp routines to do case independant
* matching. Basically, every ascii character maps to itself, except
@@ -110,45 +115,47 @@ char casetable[] = {
/* 'x' 'y' 'z' '{' '|' '}' '~' */
'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
#ifndef USE_PURE_ASCII
- '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
- '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
- '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
- '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
- '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
- '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
- '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
- '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
- '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
- '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
- '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\327',
- '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\337',
- '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
- '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
- '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
- '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+ C('\200'), C('\201'), C('\202'), C('\203'), C('\204'), C('\205'), C('\206'), C('\207'),
+ C('\210'), C('\211'), C('\212'), C('\213'), C('\214'), C('\215'), C('\216'), C('\217'),
+ C('\220'), C('\221'), C('\222'), C('\223'), C('\224'), C('\225'), C('\226'), C('\227'),
+ C('\230'), C('\231'), C('\232'), C('\233'), C('\234'), C('\235'), C('\236'), C('\237'),
+ C('\240'), C('\241'), C('\242'), C('\243'), C('\244'), C('\245'), C('\246'), C('\247'),
+ C('\250'), C('\251'), C('\252'), C('\253'), C('\254'), C('\255'), C('\256'), C('\257'),
+ C('\260'), C('\261'), C('\262'), C('\263'), C('\264'), C('\265'), C('\266'), C('\267'),
+ C('\270'), C('\271'), C('\272'), C('\273'), C('\274'), C('\275'), C('\276'), C('\277'),
+ C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
+ C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
+ C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\327'),
+ C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\337'),
+ C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
+ C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
+ C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\367'),
+ C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\377'),
#else
- '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
- '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
- '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
- '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
- '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
- '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
- '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
- '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
- '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
- '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
- '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
- '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
- '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
- '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
- '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
- '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+ C('\200'), C('\201'), C('\202'), C('\203'), C('\204'), C('\205'), C('\206'), C('\207'),
+ C('\210'), C('\211'), C('\212'), C('\213'), C('\214'), C('\215'), C('\216'), C('\217'),
+ C('\220'), C('\221'), C('\222'), C('\223'), C('\224'), C('\225'), C('\226'), C('\227'),
+ C('\230'), C('\231'), C('\232'), C('\233'), C('\234'), C('\235'), C('\236'), C('\237'),
+ C('\240'), C('\241'), C('\242'), C('\243'), C('\244'), C('\245'), C('\246'), C('\247'),
+ C('\250'), C('\251'), C('\252'), C('\253'), C('\254'), C('\255'), C('\256'), C('\257'),
+ C('\260'), C('\261'), C('\262'), C('\263'), C('\264'), C('\265'), C('\266'), C('\267'),
+ C('\270'), C('\271'), C('\272'), C('\273'), C('\274'), C('\275'), C('\276'), C('\277'),
+ C('\300'), C('\301'), C('\302'), C('\303'), C('\304'), C('\305'), C('\306'), C('\307'),
+ C('\310'), C('\311'), C('\312'), C('\313'), C('\314'), C('\315'), C('\316'), C('\317'),
+ C('\320'), C('\321'), C('\322'), C('\323'), C('\324'), C('\325'), C('\326'), C('\327'),
+ C('\330'), C('\331'), C('\332'), C('\333'), C('\334'), C('\335'), C('\336'), C('\337'),
+ C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
+ C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
+ C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\367'),
+ C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\377'),
#endif
};
#else
#include "You lose. You will need a translation table for your character set."
#endif
+#undef C
+
/*
* This table maps node types to strings for debugging.
* KEEP IN SYNC WITH awk.h!!!!
@@ -207,6 +214,7 @@ static char *nodetypes[] = {
"Node_K_do",
"Node_K_return",
"Node_K_delete",
+ "Node_K_delete_loop",
"Node_K_getline",
"Node_K_function",
"Node_K_nextfile",
@@ -227,6 +235,7 @@ static char *nodetypes[] = {
"Node_regex",
"Node_hashnode",
"Node_ahash",
+ "Node_array_ref",
"Node_NF",
"Node_NR",
"Node_FNR",
@@ -482,6 +491,8 @@ register NODE *volatile tree;
t = tree->arrvar;
if (t->type == Node_param_list)
t = stack_ptr[t->param_cnt];
+ if (t->type == Node_array_ref)
+ t = t->orig_array;
stable_tree = tree;
if ((t->flags & SCALAR) != 0)
fatal("attempt to use scalar as array");
@@ -565,6 +576,10 @@ register NODE *volatile tree;
do_delete(tree->lnode, tree->rnode);
break;
+ case Node_K_delete_loop:
+ do_delete_loop(tree->lnode, tree->rnode);
+ break;
+
case Node_K_next:
if (in_begin_rule)
fatal("`next' cannot be called from a BEGIN rule");
@@ -661,12 +676,18 @@ int iscond;
if (tree->type == Node_param_list) {
int paramnum = tree->param_cnt + 1;
+ if ((tree->flags & FUNC) != 0)
+ fatal("can't use function name `%s' as variable or array",
+ tree->vname);
+
tree = stack_ptr[tree->param_cnt];
if (tree == NULL)
return Nnull_string;
sprintf(namebuf, "parameter #%d", paramnum);
tree->vname = namebuf;
- }
+ }
+ if (tree->type == Node_array_ref)
+ tree = tree->orig_array;
switch (tree->type) {
case Node_var:
@@ -986,11 +1007,12 @@ register NODE *tree;
* able to begin and end on a single input record, so this
* isn't an ELSE IF, as noted above.
*/
- if (! tree->triggered)
+ if (! tree->triggered) {
if (! eval_condition(tree->condpair->lnode))
return FALSE;
else
tree->triggered = TRUE;
+ }
/* Else we are triggered */
if (eval_condition(tree->condpair->rnode))
tree->triggered = FALSE;
@@ -1071,16 +1093,17 @@ register NODE *tree;
NODE *tmp;
Func_ptr after_assign = NULL;
- lhs = get_lhs(tree->lnode, &after_assign);
- lval = force_number(*lhs);
-
/*
- * Can't unref *lhs until we know the type; doing so
- * too early breaks x += x sorts of things.
+ * For ++ and --, get the lhs when doing the op and then
+ * return. For += etc, do the rhs first, since it can
+ * rearrange things, and *then* get the lhs.
*/
+
switch(tree->type) {
case Node_preincrement:
case Node_predecrement:
+ lhs = get_lhs(tree->lnode, &after_assign);
+ lval = force_number(*lhs);
unref(*lhs);
*lhs = make_number(lval +
(tree->type == Node_preincrement ? 1.0 : -1.0));
@@ -1091,6 +1114,8 @@ register NODE *tree;
case Node_postincrement:
case Node_postdecrement:
+ lhs = get_lhs(tree->lnode, &after_assign);
+ lval = force_number(*lhs);
unref(*lhs);
*lhs = make_number(lval +
(tree->type == Node_postincrement ? 1.0 : -1.0));
@@ -1102,16 +1127,16 @@ register NODE *tree;
break; /* handled below */
}
+ /*
+ * It's a += kind of thing. Do the rhs, then the lhs.
+ */
+
tmp = tree_eval(tree->rnode);
rval = force_number(tmp);
free_temp(tmp);
- /*
- * Do this again; the lhs and the rhs could both be fields.
- * Accessing the rhs could cause the lhs to have moved around.
- * (Yet another special case. Gack.)
- */
lhs = get_lhs(tree->lnode, &after_assign);
+ lval = force_number(*lhs);
unref(*lhs);
switch(tree->type) {
@@ -1227,7 +1252,7 @@ pop_fcall()
if (arg->type == Node_param_list)
arg = stack_ptr[arg->param_cnt];
n = *sp++;
- if ((arg->type == Node_var || arg->type == Node_var_array)
+ if ((arg->type == Node_var /* || arg->type == Node_var_array */)
&& n->type == Node_var_array) {
/* should we free arg->var_value ? */
arg->var_array = n->var_array;
@@ -1237,7 +1262,7 @@ pop_fcall()
arg->flags = n->flags;
}
/* n->lnode overlays the array size, don't unref it if array */
- if (n->type != Node_var_array)
+ if (n->type != Node_var_array && n->type != Node_array_ref)
unref(n->lnode);
freenode(n);
count--;
@@ -1247,7 +1272,9 @@ pop_fcall()
/* if n is a local array, all the elements should be freed */
if (n->type == Node_var_array)
assoc_clear(n);
- unref(n->lnode);
+ /* n->lnode overlays the array size, don't unref it if array */
+ if (n->type != Node_var_array && n->type != Node_array_ref)
+ unref(n->lnode);
freenode(n);
}
if (f->stack)
@@ -1307,11 +1334,19 @@ char *func_name;
r->type = Node_var;
/* call by reference for arrays; see below also */
- if (arg->type == Node_param_list)
+ if (arg->type == Node_param_list) {
+ /* we must also reassign f here; see below */
+ f = & fcall_list[curfcall];
arg = f->prevstack[arg->param_cnt];
- if (arg->type == Node_var_array)
+ }
+ if (arg->type == Node_var_array) {
+ r->type = Node_array_ref;
+ r->flags &= ~SCALAR;
+ r->orig_array = arg;
+ r->vname = arg->vname;
+ } else if (arg->type == Node_array_ref) {
*r = *arg;
- else {
+ } else {
n = tree_eval(arg);
r->lnode = dupnode(n);
r->rnode = (NODE *) NULL;
@@ -1445,6 +1480,7 @@ Func_ptr *assign;
}
switch (ptr->type) {
+ case Node_array_ref:
case Node_var_array:
fatal("attempt to use array `%s' in a scalar context",
ptr->vname);
@@ -1567,7 +1603,12 @@ Func_ptr *assign;
n = stack_ptr[n->param_cnt];
if ((n->flags & SCALAR) != 0)
fatal("attempt to use scalar parameter %d as an array", i);
- } else if (n->type == Node_func) {
+ }
+ if (n->type == Node_array_ref) {
+ n = n->orig_array;
+ assert(n->type == Node_var_array || n->type == Node_var);
+ }
+ if (n->type == Node_func) {
fatal("attempt to use function `%s' as array",
n->lnode->param);
}
@@ -1581,6 +1622,8 @@ Func_ptr *assign;
case Node_builtin:
fatal("assignment is not allowed to result of builtin function");
default:
+ fprintf(stderr, "type = %s\n", nodetype2str(ptr->type));
+ fflush(stderr);
cant_happen();
}
return aptr;
OpenPOWER on IntegriCloud