[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gawk-diffs] [SCM] gawk branch, gawk_performance, created. dae23ec258049
From: |
John Haque |
Subject: |
[gawk-diffs] [SCM] gawk branch, gawk_performance, created. dae23ec25804903a6c2b7094a2ebd5541e92bb88 |
Date: |
Sat, 20 Aug 2011 13:39:00 +0000 |
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".
The branch, gawk_performance has been created
at dae23ec25804903a6c2b7094a2ebd5541e92bb88 (commit)
- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=dae23ec25804903a6c2b7094a2ebd5541e92bb88
commit dae23ec25804903a6c2b7094a2ebd5541e92bb88
Author: john haque <address@hidden>
Date: Sat Aug 20 08:28:02 2011 -0500
Speed/memory performance improvements.
diff --git a/Makefile.am b/Makefile.am
index 855a5e7..1502694 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -84,6 +84,7 @@ base_sources = \
awk.h \
awkgram.y \
builtin.c \
+ cint_array.c \
custom.h \
dfa.c \
dfa.h \
@@ -97,6 +98,7 @@ base_sources = \
getopt1.c \
getopt_int.h \
gettext.h \
+ int_array.c \
io.c \
mbsupport.h \
main.c \
@@ -109,6 +111,8 @@ base_sources = \
regex.c \
regex.h \
replace.c \
+ str_array.c \
+ symbol.c \
version.c \
xalloc.h
diff --git a/Makefile.in b/Makefile.in
index 2801c61..56f0002 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -88,11 +88,13 @@ CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am__objects_1 = array.$(OBJEXT) awkgram.$(OBJEXT) builtin.$(OBJEXT) \
- dfa.$(OBJEXT) ext.$(OBJEXT) field.$(OBJEXT) \
- floatcomp.$(OBJEXT) gawkmisc.$(OBJEXT) getopt.$(OBJEXT) \
- getopt1.$(OBJEXT) io.$(OBJEXT) main.$(OBJEXT) msg.$(OBJEXT) \
- node.$(OBJEXT) random.$(OBJEXT) re.$(OBJEXT) regex.$(OBJEXT) \
- replace.$(OBJEXT) version.$(OBJEXT)
+ cint_array.$(OBJEXT) dfa.$(OBJEXT) ext.$(OBJEXT) \
+ field.$(OBJEXT) floatcomp.$(OBJEXT) gawkmisc.$(OBJEXT) \
+ getopt.$(OBJEXT) getopt1.$(OBJEXT) int_array.$(OBJEXT) \
+ io.$(OBJEXT) main.$(OBJEXT) msg.$(OBJEXT) node.$(OBJEXT) \
+ random.$(OBJEXT) re.$(OBJEXT) regex.$(OBJEXT) \
+ replace.$(OBJEXT) str_array.$(OBJEXT) symbol.$(OBJEXT) \
+ version.$(OBJEXT)
am_dgawk_OBJECTS = $(am__objects_1) eval_d.$(OBJEXT) profile.$(OBJEXT) \
command.$(OBJEXT) debug.$(OBJEXT)
dgawk_OBJECTS = $(am_dgawk_OBJECTS)
@@ -359,6 +361,7 @@ base_sources = \
awk.h \
awkgram.y \
builtin.c \
+ cint_array.c \
custom.h \
dfa.c \
dfa.h \
@@ -372,6 +375,7 @@ base_sources = \
getopt1.c \
getopt_int.h \
gettext.h \
+ int_array.c \
io.c \
mbsupport.h \
main.c \
@@ -384,6 +388,8 @@ base_sources = \
regex.c \
regex.h \
replace.c \
+ str_array.c \
+ symbol.c \
version.c \
xalloc.h
@@ -516,6 +522,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@@ -528,6 +535,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@@ -538,6 +546,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
.c.o:
diff --git a/array.c b/array.c
index 84b9a91..9b12e97 100644
--- a/array.c
+++ b/array.c
@@ -1,5 +1,5 @@
/*
- * array.c - routines for associative arrays.
+ * array.c - routines for awk arrays.
*/
/*
@@ -25,69 +25,190 @@
#include "awk.h"
-/*
- * Tree walks (``for (iggy in foo)'') and array deletions use expensive
- * linear searching. So what we do is start out with small arrays and
- * grow them as needed, so that our arrays are hopefully small enough,
- * most of the time, that they're pretty full and we're not looking at
- * wasted space.
- *
- * The decision is made to grow the array if the average chain length is
- * ``too big''. This is defined as the total number of entries in the table
- * divided by the size of the array being greater than some constant.
- *
- * We make the constant a variable, so that it can be tweaked
- * via environment variable.
- */
-
-static size_t AVG_CHAIN_MAX = 2; /* Modern machines are bigger, reduce
this from 10. */
+extern FILE *output_fp;
+extern NODE **fmt_list; /* declared in eval.c */
+extern array_ptr str_array_func[];
+extern array_ptr cint_array_func[];
+extern array_ptr int_array_func[];
static size_t SUBSEPlen;
static char *SUBSEP;
+static char indent_char[] = " ";
-static NODE *assoc_find(NODE *symbol, NODE *subs, unsigned long hash1, NODE
**last);
-static void grow_table(NODE *symbol);
+static NODE **e_lookup(NODE *symbol, NODE *subs);
+static array_ptr empty_array_func[NUM_AFUNCS] = {
+ (array_ptr) 0,
+ (array_ptr) 0,
+ e_lookup,
+};
-static unsigned long gst_hash_string(const char *str, size_t len, unsigned
long hsize, size_t *code);
-static unsigned long scramble(unsigned long x);
-static unsigned long awk_hash(const char *s, size_t len, unsigned long hsize,
size_t *code);
+#define MAX_ATYPE 10
-unsigned long (*hash)(const char *s, size_t len, unsigned long hsize, size_t
*code) = awk_hash;
+static array_ptr *atypes[MAX_ATYPE];
+static int num_atypes = 0;
-/* qsort comparison function */
-static int sort_up_index_string(const void *, const void *);
-static int sort_down_index_string(const void *, const void *);
-static int sort_up_index_number(const void *, const void *);
-static int sort_down_index_number(const void *, const void *);
-static int sort_up_value_string(const void *, const void *);
-static int sort_down_value_string(const void *, const void *);
-static int sort_up_value_number(const void *, const void *);
-static int sort_down_value_number(const void *, const void *);
-static int sort_up_value_type(const void *, const void *);
-static int sort_down_value_type(const void *, const void *);
+/*
+ * index 0 : initialization.
+ * index 1 : check if index is compatible.
+ * index 8 : array dump, memory and other statistics (do_adump).
+ * Also used by debugger 'examine' command.
+ */
+
+
+int
+register_array_func(array_ptr *afunc)
+{
+ if (afunc && num_atypes < MAX_ATYPE) {
+ if (afunc != str_array_func && ! afunc[1])
+ return FALSE;
+ atypes[num_atypes++] = afunc;
+ if (afunc[0]) /* execute init routine if any */
+ (void) (*afunc[0])(NULL, NULL);
+ return TRUE;
+ }
+ return FALSE;
+}
-/* array_init --- check relevant environment variables */
+/* array_init --- register all builtin array types */
void
array_init()
{
- const char *val;
- char *endptr;
- size_t newval;
-
- if ((val = getenv("AVG_CHAIN_MAX")) != NULL && isdigit((unsigned char)
*val)) {
- newval = strtoul(val, & endptr, 10);
- if (endptr != val && newval > 0)
- AVG_CHAIN_MAX = newval;
+ (void) register_array_func(str_array_func); /* the default */
+ (void) register_array_func(int_array_func);
+ (void) register_array_func(cint_array_func);
+}
+
+/* make_array --- create an array node */
+
+NODE *
+make_array()
+{
+ NODE *array;
+ getnode(array);
+ memset(array, '\0', sizeof(NODE));
+ array->type = Node_var_array;
+ array->array_funcs = empty_array_func;
+ /* vname, flags, and parent_array not set here */
+
+ return array;
+}
+
+
+/* init_array --- initialize an array node */
+
+void
+init_array(NODE *symbol)
+{
+ symbol->type = Node_var_array;
+ symbol->array_funcs = empty_array_func;
+ symbol->buckets = NULL;
+ symbol->table_size = symbol->array_size = 0;
+ symbol->array_capacity = 0;
+
+ assert(symbol->xarray == NULL);
+ /* symbol->xarray = NULL; */
+
+ /* flags, vname, parent_array not (re)initialized */
+}
+
+
+/* e_lookup: assign type to an empty array. */
+
+static NODE **
+e_lookup(NODE *symbol, NODE *subs)
+{
+ int i;
+ array_ptr *afunc = NULL;
+
+ assert(array_empty(symbol) == TRUE);
+
+ /* Check which array type wants to accept this sub; traverse
+ * array type list in reverse order.
+ */
+ for (i = num_atypes - 1; i >= 1; i--) {
+ afunc = atypes[i];
+ if (afunc[1](symbol, subs) != NULL)
+ break;
+ }
+ if (i == 0 || afunc == NULL)
+ afunc = atypes[0]; /* default is str_array_func */
+ symbol->array_funcs = afunc;
+
+ /* We have the right type of array; install the subscript */
+ return symbol->alookup(symbol, subs);
+}
+
+
+/* assoc_clear --- flush all the values in symbol[] */
+
+void
+assoc_clear(NODE *symbol)
+{
+ if (! array_empty(symbol))
+ (void) symbol->aclear(symbol, NULL);
+}
+
+
+/* r_in_array --- test whether the array element symbol[subs] exists or not,
+ * return pointer to value if it does.
+ */
+
+NODE *
+r_in_array(NODE *symbol, NODE *subs)
+{
+ NODE **ret;
+
+ if (array_empty(symbol))
+ return NULL;
+ ret = symbol->aexists(symbol, subs);
+ return (ret ? *ret : NULL);
+}
+
+
+/* assoc_remove --- remove an index from symbol[] */
+
+int
+assoc_remove(NODE *symbol, NODE *subs)
+{
+ if (array_empty(symbol))
+ return FALSE;
+ return (symbol->aremove(symbol, subs) != NULL);
+}
+
+
+/* assoc_copy --- duplicate input array "symbol" */
+
+NODE *
+assoc_copy(NODE *symbol, NODE *newsymb)
+{
+ assert(newsymb->vname != NULL);
+
+ assoc_clear(newsymb);
+ if (! array_empty(symbol)) {
+ (void) symbol->acopy(symbol, newsymb);
+ newsymb->array_funcs = symbol->array_funcs;
+ newsymb->flags = symbol->flags;
}
+ return newsymb;
+}
- if ((val = getenv("AWK_HASH")) != NULL && strcmp(val, "gst") == 0)
- hash = gst_hash_string;
+
+/* assoc_dump --- dump array */
+
+void
+assoc_dump(NODE *symbol, NODE *ndump)
+{
+ if (array_empty(symbol))
+ fprintf(output_fp, "array `%s' is empty\n",
array_vname(symbol));
+ else if (symbol->adump)
+ (void) symbol->adump(symbol, ndump);
}
+
/* make_aname --- construct a 'vname' for a (sub)array */
-static char *
+const char *
make_aname(const NODE *symbol)
{
static char *aname = NULL;
@@ -115,10 +236,11 @@ make_aname(const NODE *symbol)
erealloc(aname, char *, (max_alen + 1) * sizeof(char
*), "make_aname");
}
memcpy(aname, symbol->vname, alen + 1);
- }
+ }
return aname;
-#undef SLEN
}
+#undef SLEN
+
/*
* array_vname --- print the name of the array
@@ -128,7 +250,7 @@ make_aname(const NODE *symbol)
* to save it, they have to make a copy.
*/
-char *
+const char *
array_vname(const NODE *symbol)
{
static char *message = NULL;
@@ -164,7 +286,6 @@ array_vname(const NODE *symbol)
else
aname = make_aname(symbol);
len += strlen(aname);
-
/*
* Each node contributes by strlen(from) minus the length
* of "%s" in the translation (which is at least 2)
@@ -218,7 +339,7 @@ get_array(NODE *symbol, int canfatal)
NODE *save_symbol = symbol;
int isparam = FALSE;
- if (symbol->type == Node_param_list && (symbol->flags & FUNC) == 0) {
+ if (symbol->type == Node_param_list) {
save_symbol = symbol = GET_PARAM(symbol->param_cnt);
isparam = TRUE;
if (symbol->type == Node_array_ref)
@@ -227,35 +348,24 @@ get_array(NODE *symbol, int canfatal)
switch (symbol->type) {
case Node_var_new:
- symbol->type = Node_var_array;
- symbol->var_array = NULL;
+ init_array(symbol);
symbol->parent_array = NULL; /* main array has no parent */
/* fall through */
case Node_var_array:
break;
case Node_array_ref:
- case Node_param_list:
- if ((symbol->flags & FUNC) == 0)
- cant_happen();
- /* else
- fall through */
-
default:
- /* notably Node_var but catches also e.g. FS[1] = "x" */
+ /* notably Node_var but catches also e.g. a[1] = "x"; a[1][1] =
"y" */
if (canfatal) {
if (symbol->type == Node_val)
fatal(_("attempt to use a scalar value as
array"));
-
- if ((symbol->flags & FUNC) != 0)
- fatal(_("attempt to use function `%s' as an
array"),
-
save_symbol->vname);
- else if (isparam)
+ if (isparam)
fatal(_("attempt to use scalar parameter `%s'
as an array"),
-
save_symbol->vname);
+ save_symbol->vname);
else
fatal(_("attempt to use scalar `%s' as an
array"),
-
save_symbol->vname);
+ save_symbol->vname);
} else
break;
}
@@ -269,16 +379,18 @@ get_array(NODE *symbol, int canfatal)
void
set_SUBSEP()
{
- SUBSEP = force_string(SUBSEP_node->var_value)->stptr;
+ SUBSEP_node->var_value = force_string(SUBSEP_node->var_value);
+ SUBSEP = SUBSEP_node->var_value->stptr;
SUBSEPlen = SUBSEP_node->var_value->stlen;
-}
+}
+
/* concat_exp --- concatenate expression list into a single string */
NODE *
concat_exp(int nargs, int do_subsep)
{
- /* do_subsep is false for Node-concat */
+ /* do_subsep is FALSE for Op_concat */
NODE *r;
char *str;
char *s;
@@ -295,13 +407,14 @@ concat_exp(int nargs, int do_subsep)
len = 0;
for (i = 1; i <= nargs; i++) {
- r = POP();
+ r = TOP();
if (r->type == Node_var_array) {
while (--i > 0)
DEREF(args_array[i]); /* avoid memory leak */
fatal(_("attempt to use array `%s' in a scalar
context"), array_vname(r));
- }
- args_array[i] = force_string(r);
+ }
+ r = POP_STRING();
+ args_array[i] = r;
len += r->stlen;
}
len += (nargs - 1) * subseplen;
@@ -325,247 +438,7 @@ concat_exp(int nargs, int do_subsep)
DEREF(r);
}
- return make_str_node(str, len, ALREADY_MALLOCED);
-}
-
-
-/* assoc_clear --- flush all the values in symbol[] */
-
-void
-assoc_clear(NODE *symbol)
-{
- long i;
- NODE *bucket, *next;
-
- if (symbol->var_array == NULL)
- return;
-
- for (i = 0; i < symbol->array_size; i++) {
- for (bucket = symbol->var_array[i]; bucket != NULL; bucket =
next) {
- next = bucket->ahnext;
- if (bucket->ahvalue->type == Node_var_array) {
- NODE *r = bucket->ahvalue;
- assoc_clear(r); /* recursively clear
all sub-arrays */
- efree(r->vname);
- freenode(r);
- } else
- unref(bucket->ahvalue);
-
- unref(bucket); /* unref() will free the ahname_str */
- }
- symbol->var_array[i] = NULL;
- }
- efree(symbol->var_array);
- symbol->var_array = NULL;
- symbol->array_size = symbol->table_size = 0;
- symbol->flags &= ~ARRAYMAXED;
-}
-
-/* awk_hash --- calculate the hash function of the string in subs */
-
-static unsigned long
-awk_hash(const char *s, size_t len, unsigned long hsize, size_t *code)
-{
- unsigned long h = 0;
- unsigned long htmp;
-
- /*
- * Ozan Yigit's original sdbm hash, copied from Margo Seltzers
- * db package.
- *
- * This is INCREDIBLY ugly, but fast. We break the string up into
- * 8 byte units. On the first time through the loop we get the
- * "leftover bytes" (strlen % 8). On every other iteration, we
- * perform 8 HASHC's so we handle all 8 bytes. Essentially, this
- * saves us 7 cmp & branch instructions. If this routine is
- * heavily used enough, it's worth the ugly coding.
- */
-
- /*
- * Even more speed:
- * #define HASHC h = *s++ + 65599 * h
- * Because 65599 = pow(2, 6) + pow(2, 16) - 1 we multiply by shifts
- *
- * 4/2011: Force the results to 32 bits, to get the same
- * result on both 32- and 64-bit systems. This may be a
- * bad idea.
- */
-#define HASHC htmp = (h << 6); \
- h = *s++ + htmp + (htmp << 10) - h ; \
- htmp &= 0xFFFFFFFF; \
- h &= 0xFFFFFFFF
-
- h = 0;
-
- /* "Duff's Device" */
- if (len > 0) {
- size_t loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1)) {
- case 0:
- do { /* All fall throughs */
- HASHC;
- case 7: HASHC;
- case 6: HASHC;
- case 5: HASHC;
- case 4: HASHC;
- case 3: HASHC;
- case 2: HASHC;
- case 1: HASHC;
- } while (--loop);
- }
- }
-
- if (code != NULL)
- *code = h;
-
- if (h >= hsize)
- h %= hsize;
- return h;
-}
-
-/* assoc_find --- locate symbol[subs] */
-
-static NODE * /* NULL if not found */
-assoc_find(NODE *symbol, NODE *subs, unsigned long hash1, NODE **last)
-{
- NODE *bucket, *prev;
- const char *s1_str;
- size_t s1_len;
- NODE *s2;
-
- for (prev = NULL, bucket = symbol->var_array[hash1]; bucket != NULL;
- prev = bucket, bucket = bucket->ahnext) {
- /*
- * This used to use cmp_nodes() here. That's wrong.
- * Array indices are strings; compare as such, always!
- */
- s1_str = bucket->ahname_str;
- s1_len = bucket->ahname_len;
- s2 = subs;
-
- if (s1_len == s2->stlen) {
- if (s1_len == 0 /* "" is a valid index */
- || memcmp(s1_str, s2->stptr, s1_len) == 0)
- break;
- }
- }
- if (last != NULL)
- *last = prev;
- return bucket;
-}
-
-/* in_array --- test whether the array element symbol[subs] exists or not,
- * return pointer to value if it does.
- */
-
-NODE *
-in_array(NODE *symbol, NODE *subs)
-{
- unsigned long hash1;
- NODE *ret;
-
- assert(symbol->type == Node_var_array);
-
- if (symbol->var_array == NULL)
- return NULL;
-
- hash1 = hash(subs->stptr, subs->stlen, (unsigned long)
symbol->array_size, NULL);
- ret = assoc_find(symbol, subs, hash1, NULL);
- return (ret ? ret->ahvalue : NULL);
-}
-
-/*
- * assoc_lookup:
- * Find SYMBOL[SUBS] in the assoc array. Install it with value "" if it
- * isn't there. Returns a pointer ala get_lhs to where its value is stored.
- *
- * SYMBOL is the address of the node (or other pointer) being dereferenced.
- * SUBS is a number or string used as the subscript.
- */
-
-NODE **
-assoc_lookup(NODE *symbol, NODE *subs, int reference)
-{
- unsigned long hash1;
- NODE *bucket;
- size_t code;
-
- assert(symbol->type == Node_var_array);
-
- (void) force_string(subs);
-
- if (symbol->var_array == NULL) {
- symbol->array_size = symbol->table_size = 0; /* sanity */
- symbol->flags &= ~ARRAYMAXED;
- grow_table(symbol);
- hash1 = hash(subs->stptr, subs->stlen,
- (unsigned long) symbol->array_size, & code);
- } else {
- hash1 = hash(subs->stptr, subs->stlen,
- (unsigned long) symbol->array_size, & code);
- bucket = assoc_find(symbol, subs, hash1, NULL);
- if (bucket != NULL)
- return &(bucket->ahvalue);
- }
-
- if (do_lint && reference) {
- lintwarn(_("reference to uninitialized element `%s[\"%.*s\"]'"),
- array_vname(symbol), (int)subs->stlen, subs->stptr);
- }
-
- /* It's not there, install it. */
- if (do_lint && subs->stlen == 0)
- lintwarn(_("subscript of array `%s' is null string"),
- array_vname(symbol));
-
- /* first see if we would need to grow the array, before installing */
- symbol->table_size++;
- if ((symbol->flags & ARRAYMAXED) == 0
- && (symbol->table_size / symbol->array_size) > AVG_CHAIN_MAX) {
- grow_table(symbol);
- /* have to recompute hash value for new size */
- hash1 = code % (unsigned long) symbol->array_size;
- }
-
- getnode(bucket);
- bucket->type = Node_ahash;
-
- /*
- * Freeze this string value --- it must never
- * change, no matter what happens to the value
- * that created it or to CONVFMT, etc.
- *
- * One day: Use an atom table to track array indices,
- * and avoid the extra memory overhead.
- */
- bucket->flags |= MALLOC;
- bucket->ahname_ref = 1;
-
- emalloc(bucket->ahname_str, char *, subs->stlen + 2, "assoc_lookup");
- bucket->ahname_len = subs->stlen;
- memcpy(bucket->ahname_str, subs->stptr, subs->stlen);
- bucket->ahname_str[bucket->ahname_len] = '\0';
- bucket->ahvalue = Nnull_string;
-
- bucket->ahnext = symbol->var_array[hash1];
- bucket->ahcode = code;
-
- /*
- * Set the numeric value for the index if it's available. Useful
- * for numeric sorting by index. Do this only if the numeric
- * value is available, instead of all the time, since doing it
- * all the time is a big performance hit for something that may
- * never be used.
- */
- if ((subs->flags & NUMCUR) != 0) {
- bucket->ahname_num = subs->numbr;
- bucket->flags |= NUMIND;
- }
-
- /* hook it into the symbol table */
- symbol->var_array[hash1] = bucket;
- return &(bucket->ahvalue);
+ return make_str_node(str, len);
}
@@ -602,7 +475,7 @@ adjust_fcall_stack(NODE *symbol, int nsubs)
func = frame_ptr->func_node;
if (func == NULL) /* in main */
return;
- pcount = func->lnode->param_cnt;
+ pcount = func->param_cnt;
sp = frame_ptr->stack;
for (; pcount > 0; pcount--) {
@@ -627,12 +500,10 @@ adjust_fcall_stack(NODE *symbol, int nsubs)
* function f(c, d) { delete c; ..}
* BEGIN { a[0][0] = 1; f(a[0], a[0]); ...}
*/
- char *save;
-local_array:
- save = r->vname;
- memset(r, '\0', sizeof(NODE));
- r->vname = save;
- r->type = Node_var_array;
+
+ init_array(r);
+ r->parent_array = NULL;
+ r->flags = 0;
continue;
}
@@ -648,8 +519,10 @@ local_array:
* BEGIN { a[0][0][0][0] = 1; f(a[0],
a[0][0][0]); .. }
*
*/
-
- goto local_array;
+ init_array(r);
+ r->parent_array = NULL;
+ r->flags = 0;
+ break;
}
}
}
@@ -660,18 +533,17 @@ local_array:
/*
* `symbol' is array
- * `nsubs' is number of subscripts
+ * `nsubs' is no of subscripts
*/
void
do_delete(NODE *symbol, int nsubs)
{
- unsigned long hash1 = 0;
- NODE *subs, *bucket, *last, *r;
+ NODE *val, *subs;
int i;
assert(symbol->type == Node_var_array);
- subs = bucket = last = r = NULL; /* silence the compiler */
+ subs = val = NULL; /* silence the compiler */
/*
* The force_string() call is needed to make sure that
@@ -683,16 +555,17 @@ do_delete(NODE *symbol, int nsubs)
* Without it, the code does not fail.
*/
-#define free_subs(n) \
-do { \
+#define free_subs(n) do { \
NODE *s = PEEK(n - 1); \
if (s->type == Node_val) { \
- (void) force_string(s); /* may have side effects ? */ \
+ (void) force_string(s); /* may have side effects. */ \
DEREF(s); \
} \
} while (--n > 0)
- if (nsubs == 0) { /* delete array */
+ if (nsubs == 0) {
+ /* delete array */
+
adjust_fcall_stack(symbol, 0); /* fix function call stack; See
above. */
assoc_clear(symbol);
return;
@@ -706,66 +579,46 @@ do {
\
free_subs(i);
fatal(_("attempt to use array `%s' in a scalar
context"), array_vname(subs));
}
- (void) force_string(subs);
- last = NULL; /* shut up gcc -Wall */
- hash1 = 0; /* ditto */
- bucket = NULL; /* array may be empty */
-
- if (symbol->var_array != NULL) {
- hash1 = hash(subs->stptr, subs->stlen,
- (unsigned long) symbol->array_size,
NULL);
- bucket = assoc_find(symbol, subs, hash1, &last);
- }
-
- if (bucket == NULL) {
- if (do_lint)
+ val = in_array(symbol, subs);
+ if (val == NULL) {
+ if (do_lint) {
+ subs = force_string(subs);
lintwarn(_("delete: index `%s' not in array
`%s'"),
subs->stptr, array_vname(symbol));
+ }
/* avoid memory leak, free all subs */
free_subs(i);
return;
}
if (i > 1) {
- if (bucket->ahvalue->type != Node_var_array) {
+ if (val->type != Node_var_array) {
/* e.g.: a[1] = 1; delete a[1][1] */
+
free_subs(i);
+ subs = force_string(subs);
fatal(_("attempt to use scalar `%s[\"%.*s\"]'
as an array"),
array_vname(symbol),
- (int) bucket->ahname_len,
- bucket->ahname_str);
+ (int) subs->stlen,
+ subs->stptr);
}
- symbol = bucket->ahvalue;
+ symbol = val;
+ DEREF(subs);
}
- DEREF(subs);
}
- r = bucket->ahvalue;
- if (r->type == Node_var_array) {
- adjust_fcall_stack(r, nsubs); /* fix function call stack; See
above. */
- assoc_clear(r);
+ if (val->type == Node_var_array) {
+ adjust_fcall_stack(val, nsubs); /* fix function call stack;
See above. */
+ assoc_clear(val);
/* cleared a sub-array, free Node_var_array */
- efree(r->vname);
- freenode(r);
+ efree(val->vname);
+ freenode(val);
} else
- unref(r);
+ unref(val);
- if (last != NULL)
- last->ahnext = bucket->ahnext;
- else
- symbol->var_array[hash1] = bucket->ahnext;
-
- unref(bucket); /* unref() will free the ahname_str */
- symbol->table_size--;
- if (symbol->table_size <= 0) {
- symbol->table_size = symbol->array_size = 0;
- symbol->flags &= ~ARRAYMAXED;
- if (symbol->var_array != NULL) {
- efree(symbol->var_array);
- symbol->var_array = NULL;
- }
- }
+ (void) assoc_remove(symbol, subs);
+ DEREF(subs);
#undef free_subs
}
@@ -782,272 +635,159 @@ do {
\
void
do_delete_loop(NODE *symbol, NODE **lhs)
{
- long i;
-
- assert(symbol->type == Node_var_array);
+ NODE **list;
+ NODE fl;
- if (symbol->var_array == NULL)
+ if (array_empty(symbol))
return;
- /* get first index value */
- for (i = 0; i < symbol->array_size; i++) {
- if (symbol->var_array[i] != NULL) {
- unref(*lhs);
- *lhs = make_string(symbol->var_array[i]->ahname_str,
- symbol->var_array[i]->ahname_len);
- break;
- }
- }
+ fl.flags = AINDEX|ADELETE; /* need a single index */
+ list = symbol->alist(symbol, & fl);
+ assert(list != NULL);
+
+ unref(*lhs);
+ *lhs = list[0];
+ efree(list);
/* blast the array in one shot */
- adjust_fcall_stack(symbol, 0);
+ adjust_fcall_stack(symbol, 0);
assoc_clear(symbol);
}
-/* grow_table --- grow a hash table */
+
+/* value_info --- print scalar node info */
+
+int PREC_NUM = -1;
+int PREC_STR = -1;
static void
-grow_table(NODE *symbol)
+value_info(NODE *n)
{
- NODE **old, **new, *chain, *next;
- int i, j;
- unsigned long hash1;
- unsigned long oldsize, newsize, k;
- /*
- * This is an array of primes. We grow the table by an order of
- * magnitude each time (not just doubling) so that growing is a
- * rare operation. We expect, on average, that it won't happen
- * more than twice. When things are very large (> 8K), we just
- * double more or less, instead of just jumping from 8K to 64K.
- */
- static const long sizes[] = {
- 13, 127, 1021, 8191, 16381, 32749, 65497, 131101, 262147,
- 524309, 1048583, 2097169, 4194319, 8388617, 16777259, 33554467,
- 67108879, 134217757, 268435459, 536870923, 1073741827
- };
-
- /* find next biggest hash size */
- newsize = oldsize = symbol->array_size;
- for (i = 0, j = sizeof(sizes)/sizeof(sizes[0]); i < j; i++) {
- if (oldsize < sizes[i]) {
- newsize = sizes[i];
- break;
- }
- }
-
- if (newsize == oldsize) { /* table already at max (!) */
- symbol->flags |= ARRAYMAXED;
+ if (n == Nnull_string || n == Null_field) {
+ fprintf(output_fp, "<(null)>");
return;
}
- /* allocate new table */
- emalloc(new, NODE **, newsize * sizeof(NODE *), "grow_table");
- memset(new, '\0', newsize * sizeof(NODE *));
+ if ((n->flags & (STRING|STRCUR)) != 0) {
+ fprintf(output_fp, "<");
+ fprintf(output_fp, "\"%.*s\"", PREC_STR, n->stptr);
+ if ((n->flags & (NUMBER|NUMCUR)) != 0)
+ fprintf(output_fp, ":%.*g", PREC_NUM, n->numbr);
+ fprintf(output_fp, ">");
+ } else
+ fprintf(output_fp, "<%.*g>", PREC_NUM, n->numbr);
- /* brand new hash table, set things up and return */
- if (symbol->var_array == NULL) {
- symbol->table_size = 0;
- goto done;
- }
+ fprintf(output_fp, ":%s", flags2str(n->flags));
- /* old hash table there, move stuff to new, free old */
- old = symbol->var_array;
- for (k = 0; k < oldsize; k++) {
- if (old[k] == NULL)
- continue;
-
- for (chain = old[k]; chain != NULL; chain = next) {
- next = chain->ahnext;
- hash1 = chain->ahcode % newsize;
+ if ((n->flags & FIELD) == 0)
+ fprintf(output_fp, ":%ld", n->valref);
+ else
+ fprintf(output_fp, ":");
- /* remove from old list, add to new */
- chain->ahnext = new[hash1];
- new[hash1] = chain;
- }
+ if ((n->flags & (STRING|STRCUR)) == STRCUR) {
+ fprintf(output_fp, "][");
+ fprintf(output_fp, "stfmt=%d, ", n->stfmt);
+ fprintf(output_fp, "CONVFMT=\"%s\"", n->stfmt <= -1 ? "%ld"
+ : fmt_list[n->stfmt]->stptr);
}
- efree(old);
-
-done:
- /*
- * note that symbol->table_size does not change if an old array,
- * and is explicitly set to 0 if a new one.
- */
- symbol->var_array = new;
- symbol->array_size = newsize;
}
-/* pr_node --- print simple node info */
-static void
-pr_node(NODE *n)
+#ifdef ARRAYDEBUG
+
+NODE *
+do_aoption(int nargs)
{
- if ((n->flags & NUMBER) != 0)
- printf("%s %g p: %p", flags2str(n->flags), n->numbr, n);
- else
- printf("%s %.*s p: %p", flags2str(n->flags),
- (int) n->stlen, n->stptr, n);
+ int ret = -1;
+ NODE *opt, *val;
+ int i;
+ array_ptr *afunc;
+
+ val = POP_SCALAR();
+ opt = POP_SCALAR();
+ for (i = 0; i < num_atypes; i++) {
+ afunc = atypes[i];
+ if (afunc[NUM_AFUNCS] && (*afunc[NUM_AFUNCS])(opt, val) !=
NULL) {
+ ret = 0;
+ break;
+ }
+ }
+ DEREF(opt);
+ DEREF(val);
+ return make_number((AWKNUM) ret);
}
+#endif
-static void
+void
indent(int indent_level)
{
- int k;
- for (k = 0; k < indent_level; k++)
- putchar('\t');
+ int i;
+ for (i = 0; i < indent_level; i++)
+ fprintf(output_fp, "%s", indent_char);
}
-/* assoc_dump --- dump the contents of an array */
+/* assoc_info --- print index, value info */
-NODE *
-assoc_dump(NODE *symbol, int indent_level)
+void
+assoc_info(NODE *subs, NODE *val, NODE *ndump, const char *aname)
{
- long i;
- NODE *bucket;
+ int indent_level = ndump->alevel;
+ indent_level++;
indent(indent_level);
- if (symbol->var_array == NULL) {
- printf(_("%s: empty (null)\n"), symbol->vname);
- return make_number((AWKNUM) 0);
- }
-
- if (symbol->table_size == 0) {
- printf(_("%s: empty (zero)\n"), symbol->vname);
- return make_number((AWKNUM) 0);
- }
+ fprintf(output_fp, "I: [%s:", aname);
+ if ((subs->flags & INTIND) != 0)
+ fprintf(output_fp, "<%ld>", (long) subs->numbr);
+ else
+ value_info(subs);
+ fprintf(output_fp, "]\n");
- printf(_("%s: table_size = %d, array_size = %d\n"), symbol->vname,
- (int) symbol->table_size, (int) symbol->array_size);
-
- for (i = 0; i < symbol->array_size; i++) {
- for (bucket = symbol->var_array[i]; bucket != NULL;
- bucket = bucket->ahnext) {
- indent(indent_level);
- printf("%s: I: [len %d <%.*s> p: %p] V: [",
- symbol->vname,
- (int) bucket->ahname_len,
- (int) bucket->ahname_len,
- bucket->ahname_str,
- bucket->ahname_str);
- if (bucket->ahvalue->type == Node_var_array) {
- printf("\n");
- assoc_dump(bucket->ahvalue, indent_level + 1);
- indent(indent_level);
- } else
- pr_node(bucket->ahvalue);
- printf("]\n");
- }
+ indent(indent_level);
+ if (val->type == Node_val) {
+ fprintf(output_fp, "V: [scalar: ");
+ value_info(val);
+ } else {
+ fprintf(output_fp, "V: [");
+ ndump->alevel++;
+ ndump->adepth--;
+ assoc_dump(val, ndump);
+ ndump->adepth++;
+ ndump->alevel--;
+ indent(indent_level);
}
-
- return make_number((AWKNUM) 0);
+ fprintf(output_fp, "]\n");
}
+
/* do_adump --- dump an array: interface to assoc_dump */
NODE *
do_adump(int nargs)
{
- NODE *r, *a;
+ NODE *symbol, *tmp;
+ static NODE ndump;
+ long depth = 0;
- a = POP();
- if (a->type == Node_param_list) {
- printf(_("%s: is parameter\n"), a->vname);
- a = GET_PARAM(a->param_cnt);
- }
- if (a->type == Node_array_ref) {
- printf(_("%s: array_ref to %s\n"), a->vname,
- a->orig_array->vname);
- a = a->orig_array;
- }
- if (a->type != Node_var_array)
- fatal(_("adump: argument not an array"));
- r = assoc_dump(a, 0);
- return r;
-}
-
-/*
- * The following functions implement the builtin
- * asort function. Initial work by Alan J. Broder,
- * address@hidden
- */
-
-/* dup_table --- recursively duplicate input array "symbol" */
+ /* depth < 0, no index and value info.
+ * = 0, main array index and value info; does not descend into
sub-arrays.
+ * > 0, descends into 'depth' sub-arrays, and prints index and
value info.
+ */
-static NODE *
-dup_table(NODE *symbol, NODE *newsymb)
-{
- NODE **old, **new, *chain, *bucket;
- long i;
- unsigned long cursize;
-
- /* find the current hash size */
- cursize = symbol->array_size;
-
- new = NULL;
-
- /* input is a brand new hash table, so there's nothing to copy */
- if (symbol->var_array == NULL)
- newsymb->table_size = 0;
- else {
- /* old hash table there, dupnode stuff into a new table */
-
- /* allocate new table */
- emalloc(new, NODE **, cursize * sizeof(NODE *), "dup_table");
- memset(new, '\0', cursize * sizeof(NODE *));
-
- /* do the copying/dupnode'ing */
- old = symbol->var_array;
- for (i = 0; i < cursize; i++) {
- if (old[i] != NULL) {
- for (chain = old[i]; chain != NULL;
- chain = chain->ahnext) {
- /* get a node for the linked list */
- getnode(bucket);
- bucket->type = Node_ahash;
- bucket->flags |= MALLOC;
- bucket->ahname_ref = 1;
- bucket->ahcode = chain->ahcode;
- if ((chain->flags & NUMIND) != 0) {
- bucket->ahname_num =
chain->ahname_num;
- bucket->flags |= NUMIND;
- }
-
- /*
- * copy the corresponding name and
- * value from the original input list
- */
- emalloc(bucket->ahname_str, char *,
chain->ahname_len + 2, "dup_table");
- bucket->ahname_len = chain->ahname_len;
-
- memcpy(bucket->ahname_str,
chain->ahname_str, chain->ahname_len);
- bucket->ahname_str[bucket->ahname_len]
= '\0';
-
- if (chain->ahvalue->type ==
Node_var_array) {
- NODE *r;
- getnode(r);
- r->type = Node_var_array;
- r->vname =
estrdup(chain->ahname_str, chain->ahname_len);
- r->parent_array = newsymb;
- bucket->ahvalue =
dup_table(chain->ahvalue, r);
- } else
- bucket->ahvalue =
dupnode(chain->ahvalue);
-
- /*
- * put the node on the corresponding
- * linked list in the new table
- */
- bucket->ahnext = new[i];
- new[i] = bucket;
- }
- }
- }
- newsymb->table_size = symbol->table_size;
+ if (nargs == 2) {
+ tmp = POP_SCALAR();
+ depth = (long) force_number(tmp);
+ DEREF(tmp);
}
-
- newsymb->var_array = new;
- newsymb->array_size = cursize;
- newsymb->flags = symbol->flags; /* ARRAYMAXED */
- return newsymb;
+ symbol = POP_PARAM();
+ if (symbol->type != Node_var_array)
+ fatal(_("adump: first argument not an array"));
+
+ ndump.type = Node_dump_array;
+ ndump.adepth = depth;
+ ndump.alevel = 0;
+ assoc_dump(symbol, & ndump);
+ return make_number((AWKNUM) 0);
}
@@ -1059,15 +799,13 @@ asort_actual(int nargs, SORT_CTXT ctxt)
NODE *array, *dest = NULL, *result;
NODE *r, *subs, *s;
NODE **list, **ptr;
-#define TSIZE 100 /* an arbitrary amount */
- static char buf[TSIZE+2];
unsigned long num_elems, i;
const char *sort_str;
if (nargs == 3) /* 3rd optional arg */
s = POP_STRING();
else
- s = Nnull_string; /* "" => default sorting */
+ s = dupnode(Nnull_string); /* "" => default sorting */
s = force_string(s);
sort_str = s->stptr;
@@ -1078,7 +816,6 @@ asort_actual(int nargs, SORT_CTXT ctxt)
sort_str = "@ind_str_asc";
}
-
if (nargs >= 2) { /* 2nd optional arg */
dest = POP_PARAM();
if (dest->type != Node_var_array) {
@@ -1107,15 +844,16 @@ asort_actual(int nargs, SORT_CTXT ctxt)
fatal(ctxt == ASORT ?
_("asort: cannot use a subarray of
second arg for first arg") :
_("asorti: cannot use a subarray of
second arg for first arg"));
- }
+ }
}
- num_elems = array->table_size;
- if (num_elems == 0 || array->var_array == NULL) { /* source array
is empty */
+ if (array_empty(array)) {
+ /* source array is empty */
if (dest != NULL && dest != array)
assoc_clear(dest);
return make_number((AWKNUM) 0);
}
+ num_elems = array->table_size;
/* sorting happens inside assoc_list */
list = assoc_list(array, sort_str, ctxt);
@@ -1132,70 +870,52 @@ asort_actual(int nargs, SORT_CTXT ctxt)
result = dest;
} else {
/* use 'result' as a temporary destination array */
- getnode(result);
- memset(result, '\0', sizeof(NODE));
- result->type = Node_var_array;
+ result = make_array();
result->vname = array->vname;
result->parent_array = array->parent_array;
}
- subs = make_str_node(buf, TSIZE, ALREADY_MALLOCED); /* fake it */
- subs->flags &= ~MALLOC; /* safety */
- for (i = 1, ptr = list; i <= num_elems; i++) {
- sprintf(buf, "%lu", i);
- subs->stlen = strlen(buf);
- /* make number valid in case this array gets sorted later */
- subs->numbr = i;
- subs->flags |= NUMCUR;
- r = *ptr++;
- if (ctxt == ASORTI) {
- /*
- * We want the indices of the source array as values
- * of the 'result' array.
- */
- *assoc_lookup(result, subs, FALSE) =
- make_string(r->ahname_str,
r->ahname_len);
- } else {
- NODE *val;
-
- /* We want the values of the source array. */
-
- val = r->ahvalue;
- if (result != dest) {
- /* optimization for dest = NULL or dest = array
*/
-
- if (val->type == Node_var_array) {
- /* update subarray index in parent
array */
- efree(val->vname);
- val->vname = estrdup(subs->stptr,
subs->stlen);
- }
- *assoc_lookup(result, subs, FALSE) = val;
- r->ahvalue = Nnull_string;
- } else {
- if (val->type == Node_val)
- *assoc_lookup(result, subs, FALSE) =
dupnode(val);
- else {
- NODE *arr;
-
- /*
- * There isn't any reference counting
for
- * subarrays, so recursively copy
subarrays
- * using dup_table().
- */
- getnode(arr);
- arr->type = Node_var_array;
- arr->var_array = NULL;
- arr->vname = estrdup(subs->stptr,
subs->stlen);
- arr->parent_array = array; /* actual
parent, not the temporary one. */
- *assoc_lookup(result, subs, FALSE) =
dup_table(val, arr);
- }
+ subs = make_number((AWKNUM) 0.0);
+
+ if (ctxt == ASORTI) {
+ /* We want the indices of the source array. */
+
+ for (i = 1, ptr = list; i <= num_elems; i++, ptr += 2) {
+ subs->numbr = (AWKNUM) i;
+ r = *ptr;
+ *assoc_lookup(result, subs) = r;
+ }
+ } else {
+ /* We want the values of the source array. */
+
+ for (i = 1, ptr = list; i <= num_elems; i++) {
+ subs->numbr = (AWKNUM) i;
+
+ /* free index node */
+ r = *ptr++;
+ unref(r);
+
+ /* value node */
+ r = *ptr++;
+
+ /* FIXME: asort(a) optimization */
+
+ if (r->type == Node_val)
+ *assoc_lookup(result, subs) = dupnode(r);
+ else {
+ NODE *arr;
+ arr = make_array();
+ subs = force_string(subs);
+ arr->vname = subs->stptr;
+ subs->stptr = NULL;
+ subs->flags &= ~STRCUR;
+ arr->parent_array = array; /* actual parent,
not the temporary one. */
+ *assoc_lookup(result, subs) = assoc_copy(r,
arr);
}
}
+ }
- unref(r);
- }
-
- freenode(subs); /* stptr(buf) not malloc-ed */
+ unref(subs);
efree(list);
if (result != dest) {
@@ -1209,7 +929,6 @@ asort_actual(int nargs, SORT_CTXT ctxt)
return make_number((AWKNUM) num_elems);
}
-#undef TSIZE
/* do_asort --- sort array by value */
@@ -1227,6 +946,7 @@ do_asorti(int nargs)
return asort_actual(nargs, ASORTI);
}
+
/*
* cmp_string --- compare two strings; logic similar to cmp_nodes() in eval.c
* except the extra case-sensitive comparison when the case-insensitive
@@ -1241,18 +961,10 @@ cmp_string(const NODE *n1, const NODE *n2)
int ret;
size_t lmin;
- assert(n1->type == n2->type);
- if (n1->type == Node_ahash) {
- s1 = n1->ahname_str;
- len1 = n1->ahname_len;
- s2 = n2->ahname_str;
- len2 = n2->ahname_len;
- } else {
- s1 = n1->stptr;
- len1 = n1->stlen;
- s2 = n2->stptr;
- len2 = n2->stlen;
- }
+ s1 = n1->stptr;
+ len1 = n1->stlen;
+ s2 = n2->stptr;
+ len2 = n2->stlen;
if (len1 == 0)
return len2 == 0 ? 0 : -1;
@@ -1303,7 +1015,7 @@ sort_up_index_string(const void *p1, const void *p2)
}
-/* sort_down_index_string --- descending index strings */
+/* sort_down_index_str --- qsort comparison function; descending index
strings. */
static int
sort_down_index_string(const void *p1, const void *p2)
@@ -1326,24 +1038,23 @@ sort_down_index_string(const void *p1, const void *p2)
static int
sort_up_index_number(const void *p1, const void *p2)
{
- const NODE *n1, *n2;
+ const NODE *t1, *t2;
int ret;
- n1 = *((const NODE *const *) p1);
- n2 = *((const NODE *const *) p2);
+ t1 = *((const NODE *const *) p1);
+ t2 = *((const NODE *const *) p2);
- if (n1->ahname_num < n2->ahname_num)
+ if (t1->numbr < t2->numbr)
ret = -1;
else
- ret = (n1->ahname_num > n2->ahname_num);
+ ret = (t1->numbr > t2->numbr);
/* break a tie with the index string itself */
if (ret == 0)
- return cmp_string(n1, n2);
+ return cmp_string(t1, t2);
return ret;
}
-
/* sort_down_index_number --- qsort comparison function; descending index
numbers */
static int
@@ -1359,29 +1070,23 @@ static int
sort_up_value_string(const void *p1, const void *p2)
{
const NODE *t1, *t2;
- NODE *n1, *n2;
-
- /* we're passed a pair of index (array subscript) nodes */
- t1 = *(const NODE *const *) p1;
- t2 = *(const NODE *const *) p2;
- /* and we want to compare the element values they refer to */
- n1 = t1->ahvalue;
- n2 = t2->ahvalue;
+ t1 = *((const NODE *const *) p1 + 1);
+ t2 = *((const NODE *const *) p2 + 1);
- if (n1->type == Node_var_array) {
- /* return 0 if n2 is a sub-array too, else return 1 */
- return (n2->type != Node_var_array);
+ if (t1->type == Node_var_array) {
+ /* return 0 if t2 is a sub-array too, else return 1 */
+ return (t2->type != Node_var_array);
}
- if (n2->type == Node_var_array)
- return -1; /* n1 (scalar) < n2 (sub-array) */
+ if (t2->type == Node_var_array)
+ return -1; /* t1 (scalar) < t2 (sub-array) */
- /* n1 and n2 both have string values; See sort_force_value_string(). */
- return cmp_string(n1, n2);
+ /* t1 and t2 both have string values */
+ return cmp_string(t1, t2);
}
-/* sort_down_value_string --- descending value string */
+/* sort_down_value_string --- qsort comparison function; descending value
string */
static int
sort_down_value_string(const void *p1, const void *p2)
@@ -1389,50 +1094,46 @@ sort_down_value_string(const void *p1, const void *p2)
return -sort_up_value_string(p1, p2);
}
+
/* sort_up_value_number --- qsort comparison function; ascending value number
*/
static int
sort_up_value_number(const void *p1, const void *p2)
{
- const NODE *t1, *t2;
- NODE *n1, *n2;
+ NODE *t1, *t2;
int ret;
- /* we're passed a pair of index (array subscript) nodes */
- t1 = *(const NODE *const *) p1;
- t2 = *(const NODE *const *) p2;
-
- /* and we want to compare the element values they refer to */
- n1 = t1->ahvalue;
- n2 = t2->ahvalue;
+ t1 = *((NODE *const *) p1 + 1);
+ t2 = *((NODE *const *) p2 + 1);
- if (n1->type == Node_var_array) {
- /* return 0 if n2 is a sub-array too, else return 1 */
- return (n2->type != Node_var_array);
+ if (t1->type == Node_var_array) {
+ /* return 0 if t2 is a sub-array too, else return 1 */
+ return (t2->type != Node_var_array);
}
- if (n2->type == Node_var_array)
- return -1; /* n1 (scalar) < n2 (sub-array) */
+ if (t2->type == Node_var_array)
+ return -1; /* t1 (scalar) < t2 (sub-array) */
- /* n1 and n2 both Node_val, and force_number'ed */
- if (n1->numbr < n2->numbr)
+ /* t1 and t2 both Node_val, and force_number'ed */
+ if (t1->numbr < t2->numbr)
ret = -1;
else
- ret = (n1->numbr > n2->numbr);
+ ret = (t1->numbr > t2->numbr);
if (ret == 0) {
/*
* Use string value to guarantee same sort order on all
* versions of qsort().
*/
- n1 = force_string(n1);
- n2 = force_string(n2);
- ret = cmp_string(n1, n2);
+ t1 = force_string(t1);
+ t2 = force_string(t2);
+ ret = cmp_string(t1, t2);
}
return ret;
}
-/* sort_down_value_number --- descending value number */
+
+/* sort_down_value_number --- qsort comparison function; descending value
number */
static int
sort_down_value_number(const void *p1, const void *p2)
@@ -1440,21 +1141,17 @@ sort_down_value_number(const void *p1, const void *p2)
return -sort_up_value_number(p1, p2);
}
+
/* sort_up_value_type --- qsort comparison function; ascending value type */
static int
sort_up_value_type(const void *p1, const void *p2)
{
- const NODE *t1, *t2;
NODE *n1, *n2;
- /* we're passed a pair of index (array subscript) nodes */
- t1 = *(const NODE *const *) p1;
- t2 = *(const NODE *const *) p2;
-
- /* and we want to compare the element values they refer to */
- n1 = t1->ahvalue;
- n2 = t2->ahvalue;
+ /* we want to compare the element values */
+ n1 = *((NODE *const *) p1 + 1);
+ n2 = *((NODE *const *) p2 + 1);
/* 1. Arrays vs. scalar, scalar is less than array */
if (n1->type == Node_var_array) {
@@ -1472,6 +1169,12 @@ sort_up_value_type(const void *p1, const void *p2)
if ((n2->flags & MAYBE_NUM) != 0)
(void) force_number(n2);
+ /* 2.5. Resolve INTIND, so that is STRING, and not NUMBER */
+ if ((n1->flags & INTIND) != 0)
+ (void) force_string(n1);
+ if ((n2->flags & INTIND) != 0)
+ (void) force_string(n2);
+
if ((n1->flags & NUMBER) != 0 && (n2->flags & NUMBER) != 0) {
if (n1->numbr < n2->numbr)
return -1;
@@ -1492,7 +1195,7 @@ sort_up_value_type(const void *p1, const void *p2)
return cmp_string(n1, n2);
}
-/* sort_down_value_type --- descending value type */
+/* sort_down_value_type --- qsort comparison function; descending value type */
static int
sort_down_value_type(const void *p1, const void *p2)
@@ -1505,27 +1208,26 @@ sort_down_value_type(const void *p1, const void *p2)
static int
sort_user_func(const void *p1, const void *p2)
{
- const NODE *t1, *t2;
NODE *idx1, *idx2, *val1, *val2;
AWKNUM ret;
INSTRUCTION *code;
extern int exiting;
- t1 = *((const NODE *const *) p1);
- t2 = *((const NODE *const *) p2);
-
- idx1 = make_string(t1->ahname_str, t1->ahname_len);
- idx2 = make_string(t2->ahname_str, t2->ahname_len);
- val1 = t1->ahvalue;
- val2 = t2->ahvalue;
+ idx1 = *((NODE *const *) p1);
+ idx2 = *((NODE *const *) p2);
+ val1 = *((NODE *const *) p1 + 1);
+ val2 = *((NODE *const *) p2 + 1);
code = TOP()->code_ptr; /* comparison function call instructions */
/* setup 4 arguments to comp_func() */
+ UPREF(idx1);
PUSH(idx1);
if (val1->type == Node_val)
UPREF(val1);
PUSH(val1);
+
+ UPREF(idx2);
PUSH(idx2);
if (val2->type == Node_val)
UPREF(val2);
@@ -1543,113 +1245,73 @@ sort_user_func(const void *p1, const void *p2)
return (ret < 0.0) ? -1 : (ret > 0.0);
}
-/* sort_force_index_number -- pre-process list items for sorting indices as
numbers */
-
-static void
-sort_force_index_number(NODE **list, size_t num_elems)
-{
- size_t i;
- NODE *r;
- static NODE temp_node;
-
- for (i = 0; i < num_elems; i++) {
- r = list[i];
-
- if ((r->flags & NUMIND) != 0) /* once in a lifetime is plenty
*/
- continue;
- temp_node.type = Node_val;
- temp_node.stptr = r->ahname_str;
- temp_node.stlen = r->ahname_len;
- temp_node.flags = 0; /* only interested in the return value
of r_force_number */
- r->ahname_num = r_force_number(& temp_node);
- r->flags |= NUMIND;
- }
-}
-
-/* sort_force_value_number -- pre-process list items for sorting values as
numbers */
-
-static void
-sort_force_value_number(NODE **list, size_t num_elems)
-{
- size_t i;
- NODE *r, *val;
-
- for (i = 0; i < num_elems; i++) {
- r = list[i];
- val = r->ahvalue;
- if (val->type == Node_val)
- (void) force_number(val);
- }
-}
-
-/* sort_force_value_string -- pre-process list items for sorting values as
strings */
-
-static void
-sort_force_value_string(NODE **list, size_t num_elems)
-{
- size_t i;
- NODE *r, *val;
-
- for (i = 0; i < num_elems; i++) {
- r = list[i];
- val = r->ahvalue;
- if (val->type == Node_val)
- r->ahvalue = force_string(val);
- }
-}
/* assoc_list -- construct, and optionally sort, a list of array elements */
NODE **
-assoc_list(NODE *array, const char *sort_str, SORT_CTXT sort_ctxt)
+assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT sort_ctxt)
{
- typedef void (*qsort_prefunc)(NODE **, size_t);
typedef int (*qsort_compfunc)(const void *, const void *);
static const struct qsort_funcs {
const char *name;
qsort_compfunc comp_func;
- qsort_prefunc pre_func; /* pre-processing of list items
*/
+ enum assoc_list_flags flags;
} sort_funcs[] = {
- { "@ind_str_asc", sort_up_index_string, 0 },
- { "@ind_num_asc", sort_up_index_number,
sort_force_index_number },
- { "@val_str_asc", sort_up_value_string,
sort_force_value_string },
- { "@val_num_asc", sort_up_value_number,
sort_force_value_number },
- { "@ind_str_desc", sort_down_index_string, 0 },
- { "@ind_num_desc", sort_down_index_number,
sort_force_index_number },
- { "@val_str_desc", sort_down_value_string,
sort_force_value_string },
- { "@val_num_desc", sort_down_value_number,
sort_force_value_number },
- { "@val_type_asc", sort_up_value_type, 0 },
- { "@val_type_desc", sort_down_value_type, 0 },
- { "@unsorted", 0, 0 },
- };
+{ "@ind_str_asc", sort_up_index_string, AINDEX|AISTR|AASC },
+{ "@ind_num_asc", sort_up_index_number, AINDEX|AINUM|AASC },
+{ "@val_str_asc", sort_up_value_string, AVALUE|AVSTR|AASC },
+{ "@val_num_asc", sort_up_value_number, AVALUE|AVNUM|AASC },
+{ "@ind_str_desc", sort_down_index_string, AINDEX|AISTR|ADESC },
+{ "@ind_num_desc", sort_down_index_number, AINDEX|AINUM|ADESC },
+{ "@val_str_desc", sort_down_value_string, AVALUE|AVSTR|ADESC },
+{ "@val_num_desc", sort_down_value_number, AVALUE|AVNUM|ADESC },
+{ "@val_type_asc", sort_up_value_type, AVALUE|AASC },
+{ "@val_type_desc", sort_down_value_type, AVALUE|ADESC },
+{ "@unsorted", 0, AINDEX },
+};
+
+ /* N.B.: AASC and ADESC are hints to the specific array types.
+ * See cint_list() in cint_array.c.
+ */
+
NODE **list;
- NODE *r;
- size_t num_elems, i, j;
+ NODE fl;
+ unsigned long num_elems, j;
+ int elem_size, qi;
qsort_compfunc cmp_func = 0;
- qsort_prefunc pre_func = 0;
INSTRUCTION *code = NULL;
- int qi;
extern int currule;
- num_elems = array->table_size;
+ num_elems = symbol->table_size;
assert(num_elems > 0);
+ elem_size = 1;
+ fl.flags = 0;
+
for (qi = 0, j = sizeof(sort_funcs)/sizeof(sort_funcs[0]); qi < j;
qi++) {
if (strcmp(sort_funcs[qi].name, sort_str) == 0)
break;
}
- if (qi >= 0 && qi < j) {
+ if (qi < j) {
cmp_func = sort_funcs[qi].comp_func;
- pre_func = sort_funcs[qi].pre_func;
+ fl.flags = sort_funcs[qi].flags;
+
+ if (symbol->array_funcs != cint_array_func)
+ fl.flags &= ~(AASC|ADESC);
- } else { /* unrecognized */
+ if (sort_ctxt != SORTED_IN || (fl.flags & AVALUE) != 0) {
+ /* need index and value pair in the list */
+
+ fl.flags |= (AINDEX|AVALUE);
+ elem_size = 2;
+ }
+
+ } else { /* unrecognized */
NODE *f;
const char *sp;
- assert(sort_str != NULL);
-
for (sp = sort_str; *sp != '\0'
&& ! isspace((unsigned char) *sp); sp++)
continue;
@@ -1663,7 +1325,10 @@ assoc_list(NODE *array, const char *sort_str, SORT_CTXT
sort_ctxt)
fatal(_("sort comparison function `%s' is not
defined"), sort_str);
cmp_func = sort_user_func;
- /* pre_func is still NULL */
+
+ /* need index and value pair in the list */
+ fl.flags |= (AVALUE|AINDEX);
+ elem_size = 2;
/* make function call instructions */
code = bcalloc(Op_func_call, 2, 0);
@@ -1683,23 +1348,12 @@ assoc_list(NODE *array, const char *sort_str, SORT_CTXT
sort_ctxt)
PUSH_CODE(code);
}
- /* allocate space for array; the extra space is used in for(i in a)
opcode (eval.c) */
- emalloc(list, NODE **, (num_elems + 1) * sizeof(NODE *), "assoc_list");
-
- /* populate it */
- for (i = j = 0; i < array->array_size; i++)
- for (r = array->var_array[i]; r != NULL; r = r->ahnext)
- list[j++] = dupnode(r);
- list[num_elems] = NULL;
+ list = symbol->alist(symbol, & fl);
- if (! cmp_func) /* unsorted */
- return list;
+ if (! cmp_func || (fl.flags & (AASC|ADESC)) != 0)
+ return list; /* unsorted or list already sorted */
- /* special pre-processing of list items */
- if (pre_func)
- pre_func(list, num_elems);
-
- qsort(list, num_elems, sizeof(NODE *), cmp_func); /* shazzam! */
+ qsort(list, num_elems, elem_size * sizeof(NODE *), cmp_func); /*
shazzam! */
if (cmp_func == sort_user_func) {
code = POP_CODE();
@@ -1708,72 +1362,17 @@ assoc_list(NODE *array, const char *sort_str, SORT_CTXT
sort_ctxt)
bcfree(code); /* Op_func_call */
}
- return list;
-}
-
-
-/*
-From address@hidden Mon Oct 28 16:05:26 2002
-Date: Mon, 28 Oct 2002 13:33:03 +0100
-From: Paolo Bonzini <address@hidden>
-To: address@hidden
-Subject: Hash function
-Message-ID: <address@hidden>
-
-Here is the hash function I'm using in GNU Smalltalk. The scrambling is
-needed if you use powers of two as the table sizes. If you use primes it
-is not needed.
-
-To use double-hashing with power-of-two size, you should use the
-_gst_hash_string(str, len) as the primary hash and
-scramble(_gst_hash_string (str, len)) | 1 as the secondary hash.
-
-Paolo
-
-*/
-/*
- * ADR: Slightly modified to work w/in the context of gawk.
- */
-
-static unsigned long
-gst_hash_string(const char *str, size_t len, unsigned long hsize, size_t *code)
-{
- unsigned long hashVal = 1497032417; /* arbitrary value */
- unsigned long ret;
-
- while (len--) {
- hashVal += *str++;
- hashVal += (hashVal << 10);
- hashVal ^= (hashVal >> 6);
- }
-
- ret = scramble(hashVal);
-
- if (code != NULL)
- *code = ret;
-
- if (ret >= hsize)
- ret %= hsize;
-
- return ret;
-}
+ if (sort_ctxt == SORTED_IN
+ && (fl.flags & (AINDEX|AVALUE)) == (AINDEX|AVALUE)
+ ) {
+ /* relocate all index nodes to the first half of the list. */
+ for (j = 1; j < num_elems; j++)
+ list[j] = list[2 * j];
-static unsigned long
-scramble(unsigned long x)
-{
- if (sizeof(long) == 4) {
- int y = ~x;
+ /* give back extra memory */
- x += (y << 10) | (y >> 22);
- x += (x << 6) | (x >> 26);
- x -= (x << 16) | (x >> 16);
- } else {
- x ^= (~x) >> 31;
- x += (x << 21) | (x >> 11);
- x += (x << 5) | (x >> 27);
- x += (x << 27) | (x >> 5);
- x += (x << 31);
+ erealloc(list, NODE **, num_elems * sizeof(NODE *),
"assoc_list");
}
- return x;
+ return list;
}
diff --git a/awk.h b/awk.h
index 25abf41..dcf3e9a 100644
--- a/awk.h
+++ b/awk.h
@@ -253,10 +253,9 @@ extern double gawk_strtod();
#define FALSE 0
#endif
-#define LINT_INVALID 1 /* only warn about invalid */
-#define LINT_ALL 2 /* warn about all things */
+#define INT32_BIT 32
-enum defrule {BEGIN = 1, Rule, END, BEGINFILE, ENDFILE,
+enum defrule { BEGIN = 1, Rule, END, BEGINFILE, ENDFILE,
MAXRULE /* sentinel, not legal */ };
extern const char *const ruletab[];
@@ -275,10 +274,13 @@ typedef enum nodevals {
Node_var_new, /* newly created variable, may become an array
*/
Node_param_list, /* lnode is a variable, rnode is more list */
Node_func, /* lnode is param. list, rnode is body */
+ Node_ext_func, /* extension function, code_ptr is builtin code
*/
Node_hashnode, /* an identifier in the symbol table */
- Node_ahash, /* an array element */
Node_array_ref, /* array passed by ref as parameter */
+ Node_array_tree, /* Hashed array tree (HAT) */
+ Node_array_leaf, /* Linear 1-D array */
+ Node_dump_array, /* array info */
/* program execution -- stack item types */
Node_arrayfor,
@@ -288,9 +290,44 @@ typedef enum nodevals {
Node_final /* sentry value, not legal */
} NODETYPE;
+struct exp_node;
+
+typedef union bucket_item {
+ struct {
+ union bucket_item *next;
+ char *str;
+ size_t len;
+ size_t code;
+ struct exp_node *name;
+ struct exp_node *val;
+ } hs;
+ struct {
+ union bucket_item *next;
+ long li[2];
+ struct exp_node *val[2];
+ size_t cnt;
+ } hi;
+} BUCKET;
+
+/* string hash table */
+#define ahnext hs.next
+#define ahname hs.name /* a string index node */
+#define ahname_str hs.str /* shallow copy; = ahname->stptr */
+#define ahname_len hs.len /* = ahname->stlen */
+#define ahvalue hs.val
+#define ahcode hs.code
+
+/* integer hash table */
+#define ainext hi.next
+#define ainum hi.li /* integer indices */
+#define aivalue hi.val
+#define aicount hi.cnt
struct exp_instruction;
+typedef int (*Func_print)(FILE *, const char *, ...);
+typedef struct exp_node **(*array_ptr)(struct exp_node *, struct exp_node *);
+
/*
* NOTE - this struct is a rather kludgey -- it is packed to minimize
* space usage, at the expense of cleanliness. Alter at own risk.
@@ -301,11 +338,13 @@ typedef struct exp_node {
union {
struct exp_node *lptr;
long ll;
+ array_ptr *lp;
} l;
union {
struct exp_node *rptr;
Regexp *preg;
struct exp_node **av;
+ BUCKET **bv;
void (*uptr)(void);
struct exp_instruction *iptr;
} r;
@@ -316,16 +355,19 @@ typedef struct exp_node {
char **param_list;
} x;
char *name;
+ size_t reserved;
struct exp_node *rn;
+ unsigned long cnt;
unsigned long reflags;
# define CASE 1
# define CONSTANT 2
# define FS_DFLT 4
} nodep;
+
struct {
AWKNUM fltnum; /* this is here for optimal packing of
- * the structure on many machines
- */
+ * the structure on many machines
+ */
char *sp;
size_t slen;
long sref;
@@ -335,96 +377,120 @@ typedef struct exp_node {
size_t wslen;
#endif
} val;
- struct {
- AWKNUM num;
- struct exp_node *next;
- char *name;
- size_t length;
- struct exp_node *value;
- long ref;
- size_t code;
- } hash;
-#define hnext sub.hash.next
-#define hname sub.hash.name
-#define hlength sub.hash.length
-#define hvalue sub.hash.value
-
-#define ahnext sub.hash.next
-#define ahname_str sub.hash.name
-#define ahname_len sub.hash.length
-#define ahname_num sub.hash.num
-#define ahvalue sub.hash.value
-#define ahname_ref sub.hash.ref
-#define ahcode sub.hash.code
} sub;
NODETYPE type;
- unsigned short flags;
-# define MALLOC 1 /* can be free'd */
-# define PERM 2 /* can't be free'd */
-# define STRING 4 /* assigned as string */
-# define STRCUR 8 /* string value is current */
-# define NUMCUR 16 /* numeric value is current */
-# define NUMBER 32 /* assigned as number */
-# define MAYBE_NUM 64 /* user input: if NUMERIC then
- * a NUMBER */
-# define ARRAYMAXED 128 /* array is at max size */
-# define FUNC 256 /* this parameter is really a
- * function name; see awkgram.y */
-# define FIELD 512 /* this is a field */
-# define INTLSTR 1024 /* use localized version */
-# define NUMIND 2048 /* numeric val of index is current */
-# define WSTRCUR 4096 /* wide str value is current */
+ unsigned int flags;
+
+/* any type */
+# define MALLOC 0x0001 /* can be free'd */
+
+/* type = Node_val */
+# define STRING 0x0002 /* assigned as string */
+# define STRCUR 0x0004 /* string value is current */
+# define NUMCUR 0x0008 /* numeric value is current */
+# define NUMBER 0x0010 /* assigned as number */
+# define MAYBE_NUM 0x0020 /* user input: if NUMERIC then
+ * a NUMBER */
+# define FIELD 0x0040 /* this is a field */
+# define INTLSTR 0x0080 /* use localized version */
+# define NUMINT 0x0100 /* numeric value is an integer */
+# define INTIND 0x0200 /* integral value is array index;
+ * lazy conversion to string.
+ */
+# define WSTRCUR 0x0400 /* wide str value is current */
+
+/* type = Node_var_array */
+# define ARRAYMAXED 0x0800 /* array is at max size */
+# define HALFHAT 0x1000 /* half-capacity Hashed
Array Tree;
+ * See cint_array.c */
+# define XARRAY 0x2000 /* FIXME: Nuke */
} NODE;
-
#define vname sub.nodep.name
#define lnode sub.nodep.l.lptr
#define nextp sub.nodep.l.lptr
#define rnode sub.nodep.r.rptr
-#define param_cnt sub.nodep.l.ll
-#define param vname
+/* Node_hashnode, Node_param_list */
+#define hnext sub.nodep.r.rptr
+#define hname vname
+#define hlength sub.nodep.reserved
+#define hcode sub.nodep.cnt
+#define hvalue sub.nodep.x.extra
+
+/* Node_param_list, Node_func */
+#define param_cnt sub.nodep.l.ll
+/* Node_param_list */
+#define param vname
-#define parmlist sub.nodep.x.param_list
+/* Node_func */
+#define fparms sub.nodep.rn
#define code_ptr sub.nodep.r.iptr
+/* Node_regex, Node_dynregex */
#define re_reg sub.nodep.r.preg
#define re_flags sub.nodep.reflags
#define re_text lnode
#define re_exp sub.nodep.x.extra
#define re_cnt flags
+/* Node_val */
#define stptr sub.val.sp
#define stlen sub.val.slen
#define valref sub.val.sref
#define stfmt sub.val.idx
-
#define wstptr sub.val.wsp
#define wstlen sub.val.wslen
-
#define numbr sub.val.fltnum
+/* Node_arrayfor */
+#define for_list sub.nodep.r.av
+#define for_list_size sub.nodep.reflags
+#define cur_idx sub.nodep.l.ll
+#define for_array sub.nodep.rn
+
/* Node_frame: */
#define stack sub.nodep.r.av
#define func_node sub.nodep.x.extra
#define reti sub.nodep.reflags
/* Node_var: */
-#define var_value lnode
+#define var_value lnode
#define var_update sub.nodep.r.uptr
-#define var_assign sub.nodep.x.aptr
+#define var_assign sub.nodep.x.aptr
/* Node_var_array: */
-#define var_array sub.nodep.r.av
-#define array_size sub.nodep.l.ll
-#define table_size sub.nodep.x.xl
-#define parent_array sub.nodep.rn
+#define buckets sub.nodep.r.bv
+#define nodes sub.nodep.r.av
+#define array_funcs sub.nodep.l.lp
+#define array_base sub.nodep.l.ll
+#define table_size sub.nodep.reflags
+#define array_size sub.nodep.cnt
+#define array_capacity sub.nodep.reserved
+#define xarray sub.nodep.rn
+#define parent_array sub.nodep.x.extra
+
+/* array_funcs[0] is the array initialization function and
+ * array_funcs[1] is the index type checking function
+ */
+#define alookup array_funcs[2]
+#define aexists array_funcs[3]
+#define aclear array_funcs[4]
+#define aremove array_funcs[5]
+#define alist array_funcs[6]
+#define acopy array_funcs[7]
+#define adump array_funcs[8]
+#define NUM_AFUNCS 9 /* # of entries in array_funcs */
/* Node_array_ref: */
#define orig_array lnode
#define prev_array rnode
+/* Node_array_print */
+#define adepth sub.nodep.l.ll
+#define alevel sub.nodep.x.xl
+
/* --------------------------------lint warning
types----------------------------*/
typedef enum lintvals {
LINT_illegal,
@@ -521,6 +587,7 @@ typedef enum opcodeval {
Op_K_nextfile,
Op_builtin,
+ Op_ext_builtin,
Op_in_array, /* boolean test of membership in array */
/* function call instruction */
@@ -553,7 +620,6 @@ typedef enum opcodeval {
Op_after_beginfile,
Op_after_endfile,
- Op_ext_func,
Op_func,
Op_exec_count,
@@ -638,6 +704,8 @@ typedef struct exp_instruction {
/* Op_token */
#define lextok d.name
+#define param_count x.xl
+
/* Op_rule */
#define in_rule x.xl
@@ -646,11 +714,11 @@ typedef struct exp_instruction {
/* Op_K_case, Op_K_default */
#define case_stmt x.xi
#define case_exp d.di
-#define stmt_start case_exp
-#define stmt_end case_stmt
-#define match_exp x.xl
+#define stmt_start case_exp
+#define stmt_end case_stmt
+#define match_exp x.xl
-#define target_stmt x.xi
+#define target_stmt x.xi
/* Op_K_switch */
#define switch_end x.xi
@@ -707,9 +775,9 @@ typedef struct exp_instruction {
#define field_assign x.aptr
/* Op_concat */
-#define concat_flag d.dl
-#define CSUBSEP 1
-#define CSVAR 2
+#define concat_flag d.dl
+#define CSUBSEP 1
+#define CSVAR 2
/* Op_breakpoint */
#define break_pt x.bpt
@@ -739,6 +807,10 @@ typedef struct exp_instruction {
#define condpair_left d.di
#define condpair_right x.xi
+/* Op_store_var */
+#define initval x.xn
+
+
typedef struct iobuf {
const char *name; /* filename */
int fd; /* file descriptor */
@@ -831,7 +903,7 @@ typedef struct context {
SRCFILE srcfiles;
int sourceline;
char *source;
- void (*install_func)(char *);
+ void (*install_func)(NODE *);
struct context *prev;
} AWK_CONTEXT;
@@ -841,6 +913,20 @@ struct flagtab {
const char *name;
};
+
+typedef struct block_item {
+ size_t size;
+ struct block_item *freep;
+} BLOCK;
+
+enum block_id {
+ BLOCK_INVALID = 0, /* not legal */
+ BLOCK_NODE,
+ BLOCK_BUCKET,
+ BLOCK_MAX /* count */
+};
+
+
#ifndef LONG_MAX
#define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1))))
#endif
@@ -881,21 +967,53 @@ extern int sourceline;
extern char *source;
#if __GNUC__ < 2
-extern NODE *_t; /* used as temporary in tree_eval */
+extern NODE *_t; /* used as temporary in macros */
#endif
-extern NODE *_r; /* used as temporary in stack macros */
+extern NODE *_r; /* used as temporary in macros */
-extern NODE *nextfree;
+extern BLOCK nextfree[];
extern int field0_valid;
-extern int do_traditional;
-extern int do_posix;
-extern int do_intervals;
-extern int do_intl;
-extern int do_non_decimal_data;
-extern int do_profiling;
-extern int do_dump_vars;
-extern int do_tidy_mem;
-extern int do_sandbox;
+
+extern int do_flags;
+
+/* only warn about invalid */
+#define DO_LINT_INVALID 0x0001
+/* warn about all things */
+#define DO_LINT_ALL 0x0002
+/* warn about stuff not in V7 awk */
+#define DO_LINT_OLD 0x0004
+/* no gnu extensions, add traditional weirdnesses */
+#define DO_TRADITIONAL 0x0008
+/* turn off gnu and unix extensions */
+#define DO_POSIX 0x0010
+/* dump locale-izable strings to stdout */
+#define DO_INTL 0x0020
+/* allow octal/hex C style DATA. Use with caution! */
+#define DO_NON_DEC_DATA 0x0040
+/* allow {...,...} in regexps, see resetup() */
+#define DO_INTERVALS 0x0080
+/* profile and pretty print the program */
+#define DO_PROFILING 0x0100
+/* dump all global variables at end */
+#define DO_DUMP_VARS 0x0200
+/* release vars when done */
+#define DO_TIDY_MEM 0x0400
+/* sandbox mode - disable 'system' function & redirections */
+#define DO_SANDBOX 0x0800
+
+
+#define do_traditional (do_flags & DO_TRADITIONAL)
+#define do_posix (do_flags & DO_POSIX)
+#define do_intl (do_flags & DO_INTL)
+#define do_non_decimal_data (do_flags & DO_NON_DEC_DATA)
+#define do_intervals (do_flags & DO_INTERVALS)
+#define do_profiling (do_flags & DO_PROFILING)
+#define do_dump_vars (do_flags & DO_DUMP_VARS)
+#define do_tidy_mem (do_flags & DO_TIDY_MEM)
+#define do_sandbox (do_flags & DO_SANDBOX)
+#define do_annotate (do_flags & DO_ANNOTATE)
+
+
extern int do_optimize;
extern int use_lc_numeric;
extern int exit_val;
@@ -904,8 +1022,8 @@ extern int exit_val;
#define do_lint 0
#define do_lint_old 0
#else
-extern int do_lint;
-extern int do_lint_old;
+#define do_lint (do_flags & (DO_LINT_INVALID|DO_LINT_ALL))
+#define do_lint_old (do_flags & DO_LINT_OLD)
#endif
#ifdef MBS_SUPPORT
extern int gawk_mb_cur_max;
@@ -942,7 +1060,7 @@ extern enum exe_mode which_gawk; /* (defined in eval.c)
*/
typedef union stack_item {
NODE *rptr; /* variable etc. */
- NODE **lptr; /* address of a variable etc. */
+ NODE **lptr; /* address of a variable etc. */
} STACK_ITEM;
extern STACK_ITEM *stack_ptr;
@@ -950,84 +1068,75 @@ extern NODE *frame_ptr;
extern STACK_ITEM *stack_bottom;
extern STACK_ITEM *stack_top;
-#define decr_sp() (stack_ptr--)
+#define decr_sp() (stack_ptr--)
#define incr_sp() ((stack_ptr < stack_top) ? ++stack_ptr :
grow_stack())
-#define stack_adj(n) (stack_ptr += (n))
-#define stack_empty() (stack_ptr < stack_bottom)
-
-#define POP() decr_sp()->rptr
-#define POP_ADDRESS() decr_sp()->lptr
-#define PEEK(n) (stack_ptr - (n))->rptr
-#define TOP() stack_ptr->rptr /* same as
PEEK(0) */
-#define TOP_ADDRESS() stack_ptr->lptr
-#define PUSH(r) (void) (incr_sp()->rptr = (r))
-#define PUSH_ADDRESS(l) (void) (incr_sp()->lptr = (l))
-#define REPLACE(r) (void) (stack_ptr->rptr = (r))
-#define REPLACE_ADDRESS(l) (void) (stack_ptr->lptr = (l))
-
+#define stack_adj(n) (stack_ptr += (n))
+#define stack_empty() (stack_ptr < stack_bottom)
+
+#define POP() decr_sp()->rptr
+#define POP_ADDRESS() decr_sp()->lptr
+#define PEEK(n) (stack_ptr - (n))->rptr
+#define TOP() stack_ptr->rptr /* same as PEEK(0) */
+#define TOP_ADDRESS() stack_ptr->lptr
+#define PUSH(r) (void) (incr_sp()->rptr = (r))
+#define PUSH_ADDRESS(l) (void) (incr_sp()->lptr = (l))
+#define REPLACE(r) (void) (stack_ptr->rptr = (r))
+#define REPLACE_ADDRESS(l) (void) (stack_ptr->lptr = (l))
/* function param */
-#define GET_PARAM(n) frame_ptr->stack[n]
+#define GET_PARAM(n) frame_ptr->stack[n]
/*
- * UPREF and DEREF --- simplified versions of dupnode and unref
- * UPREF does not handle FIELD node. Most appropriate use is
- * for elements on the runtime stack. When in doubt, use dupnode.
- */
+ * UPREF --- simplified versions of dupnode, does not handle FIELD node.
+ * Most appropriate use is for elements on the runtime stack.
+ * When in doubt, use dupnode.
+ */
-#define DEREF(r) ( _r = (r), (!(_r->flags & PERM) && (--_r->valref ==
0)) ? unref(_r) : (void)0 )
+#define UPREF(r) (void) ((r)->valref++)
+
+#define DEREF(r) ( _r = (r), (--_r->valref == 0) ? r_unref(_r) :
(void)0 )
#if __GNUC__ >= 2
-#define UPREF(r) ({ NODE *_t = (r); !(_t->flags & PERM) &&
_t->valref++;})
#define POP_ARRAY() ({ NODE *_t = POP(); \
- _t->type == Node_var_array ? \
- _t : get_array(_t, TRUE); })
+ _t->type == Node_var_array ? _t : get_array(_t, TRUE); })
#define POP_PARAM() ({ NODE *_t = POP(); \
- _t->type == Node_var_array ? \
- _t : get_array(_t, FALSE); })
+ _t->type == Node_var_array ? _t : get_array(_t, FALSE); })
-#define POP_NUMBER(x) ({ NODE *_t = POP_SCALAR(); \
- x = force_number(_t); DEREF(_t); })
-#define TOP_NUMBER(x) ({ NODE *_t = TOP_SCALAR(); \
- x = force_number(_t); DEREF(_t); })
+#define POP_NUMBER(x) ({ NODE *_t = POP_SCALAR(); x = force_number(_t);
DEREF(_t); })
+#define TOP_NUMBER(x) ({ NODE *_t = TOP_SCALAR(); x = force_number(_t);
DEREF(_t); })
-#define POP_SCALAR() ({ NODE *_t = POP(); _t->type !=
Node_var_array ? _t \
- : (fatal(_("attempt to use array `%s' in a scalar
context"), array_vname(_t)), _t);})
-#define TOP_SCALAR() ({ NODE *_t = TOP(); _t->type !=
Node_var_array ? _t \
- : (fatal(_("attempt to use array `%s' in a scalar
context"), array_vname(_t)), _t);})
+#define POP_SCALAR() ({ NODE *_t = POP(); _t->type != Node_var_array ? _t \
+ : (fatal(_("attempt to use array `%s' in a scalar context"),
array_vname(_t)), _t);})
+#define TOP_SCALAR() ({ NODE *_t = TOP(); _t->type != Node_var_array ? _t \
+ : (fatal(_("attempt to use array `%s' in a scalar context"),
array_vname(_t)), _t);})
-#else /* not __GNUC__ */
+#define POP_STRING() force_string(POP_SCALAR())
+#define TOP_STRING() force_string(TOP_SCALAR())
-#define UPREF(r) (_t = (r), !(_t->flags & PERM) && _t->valref++)
+#else /* not __GNUC__ */
#define POP_ARRAY() (_t = POP(), \
- _t->type == Node_var_array ? \
- _t : get_array(_t, TRUE))
+ _t->type == Node_var_array ? _t : get_array(_t, TRUE))
#define POP_PARAM() (_t = POP(), \
- _t->type == Node_var_array ? \
- _t : get_array(_t, FALSE))
+ _t->type == Node_var_array ? _t : get_array(_t, FALSE))
-#define POP_NUMBER(x) (_t = POP_SCALAR(), \
- x = force_number(_t), DEREF(_t))
-#define TOP_NUMBER(x) (_t = TOP_SCALAR(), \
- x = force_number(_t), DEREF(_t))
+#define POP_NUMBER(x) (_t = POP_SCALAR(), x = force_number(_t), DEREF(_t))
+#define TOP_NUMBER(x) (_t = TOP_SCALAR(), x = force_number(_t), DEREF(_t))
#define POP_SCALAR() (_t = POP(), _t->type != Node_var_array ? _t \
- : (fatal(_("attempt to use array `%s' in a scalar
context"), array_vname(_t)), _t))
+ : (fatal(_("attempt to use array `%s' in a scalar context"),
array_vname(_t)), _t))
#define TOP_SCALAR() (_t = TOP(), _t->type != Node_var_array ? _t \
- : (fatal(_("attempt to use array `%s' in a scalar
context"), array_vname(_t)), _t))
-
-#endif /* __GNUC__ */
+ : (fatal(_("attempt to use array `%s' in a scalar context"),
array_vname(_t)), _t))
+#define POP_STRING() (_r = POP_SCALAR(), m_force_string(_r))
+#define TOP_STRING() (_r = TOP_SCALAR(), m_force_string(_r))
-#define POP_STRING() force_string(POP_SCALAR())
-#define TOP_STRING() force_string(TOP_SCALAR())
+#endif /* __GNUC__ */
/* ------------------------- Pseudo-functions ------------------------- */
-
#define is_identchar(c) (isalnum(c) || (c) == '_')
#define var_uninitialized(n) ((n)->var_value == Nnull_string)
@@ -1035,24 +1144,20 @@ extern STACK_ITEM *stack_top;
#define get_lhs(n, r) (n)->type == Node_var && ! var_uninitialized(n) ? \
&((n)->var_value) : r_get_lhs((n), (r))
-#ifdef MPROF
-#define getnode(n) emalloc((n), NODE *, sizeof(NODE), "getnode"), \
- (n)->flags = 0
-#define freenode(n) efree(n)
-#else /* not MPROF */
-#define getnode(n) (void) (nextfree ? \
- (n = nextfree, nextfree = nextfree->nextp) \
- : (n = more_nodes()))
-#define freenode(n) ((n)->flags = 0, (n)->nextp = nextfree,
nextfree = (n))
-#endif /* not MPROF */
+#define getblock(p, id, ty) (void) ((p = (ty) nextfree[id].freep) ? \
+ (ty) (nextfree[id].freep = ((BLOCK *) p)->freep) \
+ : (p = (ty) more_blocks(id)))
+#define freeblock(p, id) (void) (((BLOCK *) p)->freep =
nextfree[id].freep, \
+ nextfree[id].freep = (BLOCK *) p)
-#define make_number(x) mk_number((x), (unsigned int)(MALLOC|NUMCUR|NUMBER))
+#define getnode(n) getblock(n, BLOCK_NODE, NODE *)
+#define freenode(n) freeblock(n, BLOCK_NODE)
-#define make_string(s, l) r_make_str_node((s), (size_t)
(l), 0)
-#define make_str_node(s, l, f) r_make_str_node((s), (size_t) (l), (f))
+#define getbucket(b) getblock(b, BLOCK_BUCKET, BUCKET *)
+#define freebucket(b) freeblock(b, BLOCK_BUCKET)
-#define SCAN 1
-#define ALREADY_MALLOCED 2
+#define make_string(s, l) r_make_str_node((s), (size_t) (l),
FALSE)
+#define make_str_node(s, l) r_make_str_node((s), (size_t) (l), TRUE)
#define cant_happen() r_fatal("internal error line %d, file: %s", \
__LINE__, __FILE__)
@@ -1069,19 +1174,34 @@ extern STACK_ITEM *stack_top;
#ifdef GAWKDEBUG
#define force_number r_force_number
-#define force_string r_force_string
+#define dupnode r_dupnode
+#define unref r_unref
+#define m_force_string r_force_string
+extern NODE *r_force_string(NODE *s);
#else /* not GAWKDEBUG */
+
+#define unref(r) ( _r = (r), (_r == NULL || --_r->valref > 0) ? \
+ (void)0 : r_unref(_r) )
+
+#define m_force_string(_ts) (((_ts->flags & STRCUR) && \
+ (_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ? \
+ _ts : format_val(CONVFMT, CONVFMTidx, _ts))
+
#if __GNUC__ >= 2
-#define force_number(n) __extension__ ({NODE *_tn = (n);\
- (_tn->flags & NUMCUR) ? _tn->numbr :
r_force_number(_tn);})
+#define dupnode(n) __extension__ ({ NODE *_tn = (n); \
+ (_tn->flags & MALLOC) ? (_tn->valref++, _tn) : r_dupnode(_tn); })
+
+#define force_number(n) __extension__ ({ NODE *_tn = (n);\
+ (_tn->flags & NUMCUR) ? _tn->numbr : r_force_number(_tn); })
+
+#define force_string(s) __extension__ ({ NODE *_ts = (s);
m_force_string(_ts); })
-#define force_string(s) __extension__ ({NODE *_ts = (s);\
- ((_ts->flags & STRCUR) && \
- (_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ?\
- _ts : format_val(CONVFMT, CONVFMTidx, _ts);})
#else /* not __GNUC__ */
+#define dupnode(n) (_t = (n), \
+ (_t->flags & MALLOC) ? (_t->valref++, _t) : r_dupnode(_t))
+
#define force_number r_force_number
-#define force_string r_force_string
+#define force_string(s) (_t = (s), m_force_string(_t))
#endif /* __GNUC__ */
#endif /* GAWKDEBUG */
@@ -1102,57 +1222,66 @@ if (val++) \
if (--val) \
memcpy((char *) tag, (const char *) (stack), sizeof(jmp_buf))
-/* ------------- Function prototypes or defs (as appropriate) ------------- */
-typedef int (*Func_print)(FILE *, const char *, ...);
+#define array_empty(a) ((a)->table_size == 0)
+#define assoc_lookup(a, s) (a)->alookup(a, s)
+
+#if __GNUC__ >= 2
+#define in_array(a, s) ({ NODE **_l; array_empty(a) ? NULL \
+ : (_l = (a)->aexists(a, s), _l ? *_l : NULL); })
+#else /* not __GNUC__ */
+#define in_array(a, s) r_in_array(a, s)
+#endif /* __GNUC__ */
+
+/* ------------- Function prototypes or defs (as appropriate) ------------- */
/* array.c */
typedef enum sort_context { SORTED_IN = 1, ASORT, ASORTI } SORT_CTXT;
-extern NODE **assoc_list(NODE *array, const char *sort_str, SORT_CTXT
sort_ctxt);
+enum assoc_list_flags {
+AINDEX = 0x01, /* list of indices */
+AVALUE = 0x02, /* list of values */
+AINUM = 0x04, /* numeric index */
+AISTR = 0x08, /* string index */
+AVNUM = 0x10, /* numeric scalar value */
+AVSTR = 0x20, /* string scalar value */
+AASC = 0x40, /* ascending order */
+ADESC = 0x80, /* descending order */
+ADELETE = 0x100, /* need a single index; for use in do_delete_loop */
+};
+
+extern NODE *make_array(void);
+extern void init_array(NODE *symbol);
extern NODE *get_array(NODE *symbol, int canfatal);
-extern char *array_vname(const NODE *symbol);
+extern const char *make_aname(const NODE *symbol);
+extern const char *array_vname(const NODE *symbol);
extern void array_init(void);
extern void set_SUBSEP(void);
extern NODE *concat_exp(int nargs, int do_subsep);
-extern void ahash_unref(NODE *tmp);
extern void assoc_clear(NODE *symbol);
-extern NODE *in_array(NODE *symbol, NODE *subs);
-extern NODE **assoc_lookup(NODE *symbol, NODE *subs, int reference);
+extern NODE *r_in_array(NODE *symbol, NODE *subs);
+extern int assoc_remove(NODE *symbol, NODE *subs);
+extern NODE *assoc_copy(NODE *symbol, NODE *newsymb);
+extern void assoc_dump(NODE *symbol, NODE *p);
+extern NODE **assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT
sort_ctxt);
+extern void assoc_info(NODE *subs, NODE *val, NODE *p, const char *aname);
extern void do_delete(NODE *symbol, int nsubs);
extern void do_delete_loop(NODE *symbol, NODE **lhs);
-extern NODE *assoc_dump(NODE *symbol, int indent_level);
extern NODE *do_adump(int nargs);
+extern NODE *do_aoption(int nargs);
extern NODE *do_asort(int nargs);
extern NODE *do_asorti(int nargs);
extern unsigned long (*hash)(const char *s, size_t len, unsigned long hsize,
size_t *code);
/* awkgram.c */
-extern NODE *mk_symbol(NODETYPE type, NODE *value);
-extern NODE *install_symbol(char *name, NODE *value);
-extern NODE *remove_symbol(char *name);
-extern NODE *lookup(const char *name);
-extern NODE *variable(char *name, NODETYPE type);
+extern NODE *variable(int location, char *name, NODETYPE type);
extern int parse_program(INSTRUCTION **pcode);
extern void dump_funcs(void);
extern void dump_vars(const char *fname);
-extern void release_all_vars(void);
extern const char *getfname(NODE *(*)(int));
-extern NODE *stopme(int nargs);
extern void shadow_funcs(void);
extern int check_special(const char *name);
-extern int foreach_func(int (*)(INSTRUCTION *, void *), int, void *);
-extern INSTRUCTION *bcalloc(OPCODE op, int size, int srcline);
-extern void bcfree(INSTRUCTION *);
extern SRCFILE *add_srcfile(int stype, char *src, SRCFILE *curr, int
*already_included, int *errcode);
extern void register_deferred_variable(const char *name, NODE
*(*load_func)(void));
extern int files_are_same(char *path, SRCFILE *src);
extern void valinfo(NODE *n, Func_print print_func, FILE *fp);
-extern void print_vars(Func_print print_func, FILE *fp);
-extern AWK_CONTEXT *new_context(void);
-extern void push_context(AWK_CONTEXT *ctxt);
-extern void pop_context();
-extern int in_main_context();
-extern void free_context(AWK_CONTEXT *ctxt, int );
-extern void append_symbol(char *name);
-
/* builtin.c */
extern double double_to_int(double d);
extern NODE *do_exp(int nargs);
@@ -1204,7 +1333,7 @@ extern int strncasecmpmbs(const unsigned char *,
extern void PUSH_CODE(INSTRUCTION *cp);
extern INSTRUCTION *POP_CODE(void);
extern int interpret(INSTRUCTION *);
-extern int cmp_nodes(NODE *, NODE *);
+extern int cmp_nodes(NODE *p1, NODE *p2);
extern void set_IGNORECASE(void);
extern void set_OFS(void);
extern void set_ORS(void);
@@ -1236,7 +1365,6 @@ extern void dump_fcall_stack(FILE *fp);
NODE *do_ext(int nargs);
#ifdef DYNAMIC
void make_builtin(const char *, NODE *(*)(int), int);
-size_t get_curfunc_arg_count(void);
NODE *get_argument(int);
NODE *get_actual_argument(int, int, int);
#define get_scalar_argument(i, opt) get_actual_argument((i), (opt), FALSE)
@@ -1300,6 +1428,7 @@ extern int arg_assign(char *arg, int initing);
extern int is_std_var(const char *var);
extern char *estrdup(const char *str, size_t len);
extern void update_global_values();
+extern long getenv_long(const char *name);
/* msg.c */
extern void gawk_exit(int status);
extern void err(const char *s, const char *emsg, va_list argp)
ATTRIBUTE_PRINTF(2, 0);
@@ -1327,13 +1456,14 @@ extern void pp_string_fp(Func_print print_func, FILE
*fp, const char *str,
/* node.c */
extern AWKNUM r_force_number(NODE *n);
extern NODE *format_val(const char *format, int index, NODE *s);
-extern NODE *r_force_string(NODE *s);
-extern NODE *dupnode(NODE *n);
-extern NODE *mk_number(AWKNUM x, unsigned int flags);
-extern NODE *r_make_str_node(const char *s, unsigned long len, int scan);
-extern NODE *more_nodes(void);
-extern void unref(NODE *tmp);
+extern NODE *r_dupnode(NODE *n);
+extern NODE *make_number(AWKNUM x);
+extern NODE *r_make_str_node(const char *s, size_t len, int already_malloced);
+extern void *more_blocks(int id);
+extern void r_unref(NODE *tmp);
extern int parse_escape(const char **string_ptr);
+extern size_t scan_escape(char *s, size_t len);
+
#ifdef MBS_SUPPORT
extern NODE *str2wstr(NODE *n, size_t **ptr);
extern NODE *wstr2str(NODE *n);
@@ -1363,6 +1493,29 @@ extern int reisstring(const char *text, size_t len,
Regexp *re, const char *buf)
extern int remaybelong(const char *text, size_t len);
extern int isnondecimal(const char *str, int use_locale);
+/* symbol.c */
+extern NODE *install_symbol(char *name, NODETYPE type);
+extern NODE *remove_symbol(NODE *r);
+extern void destroy_symbol(NODE *r);
+extern void release_symbols(NODE *symlist, int keep_globals);
+extern void append_symbol(NODE *r);
+extern NODE *lookup(const char *name);
+extern NODE *make_params(char **pnames, int pcount);
+extern void install_params(NODE *func);
+extern void remove_params(NODE *func);
+extern void release_all_vars(void);
+extern int foreach_func(NODE **table, int (*)(INSTRUCTION *, void *), void *);
+extern INSTRUCTION *bcalloc(OPCODE op, int size, int srcline);
+extern void bcfree(INSTRUCTION *);
+extern AWK_CONTEXT *new_context(void);
+extern void push_context(AWK_CONTEXT *ctxt);
+extern void pop_context();
+extern int in_main_context();
+extern void free_context(AWK_CONTEXT *ctxt, int );
+extern NODE **variable_list();
+extern NODE **function_list(int sort);
+extern void print_vars(NODE **table, Func_print print_func, FILE *fp);
+
/* floatcomp.c */
#ifdef VMS /* VMS linker weirdness? */
#define Ceil gawk_ceil
diff --git a/awkgram.c b/awkgram.c
index 4edec57..efc0739 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -86,19 +86,15 @@ static char *get_src_buf(void);
static int yylex(void);
int yyparse(void);
static INSTRUCTION *snode(INSTRUCTION *subn, INSTRUCTION *op);
-static int func_install(INSTRUCTION *fp, INSTRUCTION *def);
-static void pop_params(NODE *params);
-static NODE *make_param(char *pname);
+static char **check_params(char *fname, int pcount, INSTRUCTION *list);
+static int install_function(char *fname, INSTRUCTION *fi, INSTRUCTION *plist);
static NODE *mk_rexp(INSTRUCTION *exp);
-static void append_param(char *pname);
-static int dup_parms(INSTRUCTION *fp, NODE *func);
static void param_sanity(INSTRUCTION *arglist);
static int parms_shadow(INSTRUCTION *pc, int *shadow);
static int isnoeffect(OPCODE type);
static INSTRUCTION *make_assignable(INSTRUCTION *ip);
static void dumpintlstr(const char *str, size_t len);
static void dumpintlstr2(const char *str1, size_t len1, const char *str2,
size_t len2);
-static int isarray(NODE *n);
static int include_source(INSTRUCTION *file);
static void next_sourcefile(void);
static char *tokexpand(void);
@@ -107,6 +103,7 @@ static char *tokexpand(void);
static INSTRUCTION *mk_program(void);
static INSTRUCTION *append_rule(INSTRUCTION *pattern, INSTRUCTION *action);
+static INSTRUCTION *mk_function(INSTRUCTION *fi, INSTRUCTION *def);
static INSTRUCTION *mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp,
INSTRUCTION *true_branch,
INSTRUCTION *elsep, INSTRUCTION *false_branch);
static INSTRUCTION *mk_expression_list(INSTRUCTION *list, INSTRUCTION *s1);
@@ -125,13 +122,10 @@ static void add_lint(INSTRUCTION *list, LINTTYPE
linttype);
enum defref { FUNC_DEFINE, FUNC_USE };
static void func_use(const char *name, enum defref how);
static void check_funcs(void);
-static void free_bcpool(INSTRUCTION *pl);
static ssize_t read_one_line(int fd, void *buffer, size_t count);
static int one_line_close(int fd);
-static void (*install_func)(char *) = NULL;
-
static int want_source = FALSE;
static int want_regexp; /* lexical scanning kludge */
static int can_return; /* parsing kludge */
@@ -169,22 +163,11 @@ static int continue_allowed; /* kludge for continue
*/
#define END_SRC -2000
#define YYDEBUG_LEXER_TEXT (lexeme)
-static int param_counter;
-static NODE *func_params; /* list of parameters for the current function
*/
static char *tokstart = NULL;
static char *tok = NULL;
static char *tokend;
static int errcount = 0;
-static NODE *symbol_list;
-extern void destroy_symbol(char *name);
-
-static long func_count; /* total number of functions */
-
-#define HASHSIZE 1021 /* this constant only used here */
-NODE *variables[HASHSIZE];
-static int var_count; /* total number of global variables */
-
extern char *source;
extern int sourceline;
extern SRCFILE *srcfiles;
@@ -206,22 +189,12 @@ static inline INSTRUCTION *list_prepend(INSTRUCTION *l,
INSTRUCTION *x);
static inline INSTRUCTION *list_merge(INSTRUCTION *l1, INSTRUCTION *l2);
extern double fmod(double x, double y);
-/*
- * This string cannot occur as a real awk identifier.
- * Use it as a special token to make function parsing
- * uniform, but if it's seen, don't install the function.
- * e.g.
- * function split(x) { return x }
- * function x(a) { return a }
- * should only produce one error message, and not core dump.
- */
-static char builtin_func[] = "@builtin";
#define YYSTYPE INSTRUCTION *
/* Line 268 of yacc.c */
-#line 225 "awkgram.c"
+#line 198 "awkgram.c"
/* Enabling traces. */
#ifndef YYDEBUG
@@ -367,7 +340,7 @@ typedef int YYSTYPE;
/* Line 343 of yacc.c */
-#line 371 "awkgram.c"
+#line 344 "awkgram.c"
#ifdef short
# undef short
@@ -583,16 +556,16 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 1157
+#define YYLAST 1150
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 74
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 65
+#define YYNNTS 64
/* YYNRULES -- Number of rules. */
-#define YYNRULES 185
+#define YYNRULES 184
/* YYNRULES -- Number of states. */
-#define YYNSTATES 330
+#define YYNSTATES 329
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
@@ -644,110 +617,110 @@ static const yytype_uint16 yyprhs[] =
{
0, 0, 3, 4, 7, 10, 13, 16, 19, 22,
25, 30, 32, 35, 37, 38, 40, 45, 47, 49,
- 51, 53, 59, 61, 63, 65, 68, 70, 72, 73,
- 81, 82, 86, 88, 90, 91, 94, 97, 99, 102,
- 105, 109, 111, 121, 128, 137, 146, 159, 171, 173,
- 176, 179, 182, 185, 189, 190, 195, 198, 199, 204,
- 205, 210, 215, 217, 218, 220, 221, 224, 227, 233,
- 238, 240, 243, 246, 248, 250, 252, 254, 256, 260,
- 261, 262, 266, 273, 283, 285, 288, 289, 291, 292,
- 295, 296, 298, 300, 304, 306, 309, 313, 314, 316,
- 317, 319, 321, 325, 327, 330, 334, 338, 342, 346,
- 350, 354, 358, 362, 368, 370, 372, 374, 377, 379,
- 381, 383, 385, 387, 389, 392, 394, 398, 402, 406,
- 410, 414, 418, 422, 425, 428, 434, 439, 443, 447,
- 451, 455, 459, 463, 465, 468, 472, 477, 482, 484,
- 486, 488, 491, 494, 496, 498, 501, 504, 506, 509,
- 514, 515, 517, 518, 521, 523, 526, 528, 532, 534,
- 537, 540, 542, 545, 547, 551, 553, 555, 556, 559,
- 562, 564, 565, 567, 569, 571
+ 51, 53, 59, 61, 63, 65, 68, 70, 72, 79,
+ 80, 84, 86, 88, 89, 92, 95, 97, 100, 103,
+ 107, 109, 119, 126, 135, 144, 157, 169, 171, 174,
+ 177, 180, 183, 187, 188, 193, 196, 197, 202, 203,
+ 208, 213, 215, 216, 218, 219, 222, 225, 231, 236,
+ 238, 241, 244, 246, 248, 250, 252, 254, 258, 259,
+ 260, 264, 271, 281, 283, 286, 287, 289, 290, 293,
+ 294, 296, 298, 302, 304, 307, 311, 312, 314, 315,
+ 317, 319, 323, 325, 328, 332, 336, 340, 344, 348,
+ 352, 356, 360, 366, 368, 370, 372, 375, 377, 379,
+ 381, 383, 385, 387, 390, 392, 396, 400, 404, 408,
+ 412, 416, 420, 423, 426, 432, 437, 441, 445, 449,
+ 453, 457, 461, 463, 466, 470, 475, 480, 482, 484,
+ 486, 489, 492, 494, 496, 499, 502, 504, 507, 512,
+ 513, 515, 516, 519, 521, 524, 526, 530, 532, 535,
+ 538, 540, 543, 545, 549, 551, 553, 554, 557, 560,
+ 562, 563, 565, 567, 569
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int16 yyrhs[] =
{
- 75, 0, -1, -1, 75, 76, -1, 75, 104, -1,
+ 75, 0, -1, -1, 75, 76, -1, 75, 103, -1,
75, 47, -1, 75, 1, -1, 78, 79, -1, 78,
- 88, -1, 82, 79, -1, 68, 48, 77, 88, -1,
- 6, -1, 6, 1, -1, 1, -1, -1, 112, -1,
- 112, 54, 105, 112, -1, 17, -1, 18, -1, 36,
- -1, 37, -1, 132, 87, 133, 135, 105, -1, 4,
+ 87, -1, 82, 79, -1, 68, 48, 77, 87, -1,
+ 6, -1, 6, 1, -1, 1, -1, -1, 111, -1,
+ 111, 54, 104, 111, -1, 17, -1, 18, -1, 36,
+ -1, 37, -1, 131, 86, 132, 134, 104, -1, 4,
-1, 3, -1, 81, -1, 68, 49, -1, 45, -1,
- 46, -1, -1, 35, 83, 80, 66, 107, 134, 105,
- -1, -1, 86, 85, 5, -1, 60, -1, 51, -1,
- -1, 87, 89, -1, 87, 1, -1, 104, -1, 136,
- 105, -1, 136, 105, -1, 132, 87, 133, -1, 103,
- -1, 23, 66, 112, 134, 105, 132, 96, 105, 133,
- -1, 26, 66, 112, 134, 105, 89, -1, 27, 105,
- 89, 26, 66, 112, 134, 105, -1, 28, 66, 4,
- 40, 129, 134, 105, 89, -1, 28, 66, 95, 136,
- 105, 112, 136, 105, 95, 134, 105, 89, -1, 28,
- 66, 95, 136, 105, 136, 105, 95, 134, 105, 89,
- -1, 90, -1, 29, 88, -1, 30, 88, -1, 33,
- 88, -1, 39, 88, -1, 34, 109, 88, -1, -1,
- 21, 91, 109, 88, -1, 92, 88, -1, -1, 99,
- 93, 100, 101, -1, -1, 22, 4, 94, 123, -1,
- 22, 66, 4, 67, -1, 112, -1, -1, 92, -1,
- -1, 96, 97, -1, 96, 1, -1, 24, 98, 137,
- 105, 87, -1, 25, 137, 105, 87, -1, 7, -1,
- 58, 7, -1, 57, 7, -1, 8, -1, 84, -1,
- 31, -1, 32, -1, 110, -1, 66, 111, 134, -1,
- -1, -1, 10, 102, 116, -1, 19, 66, 112, 134,
- 105, 89, -1, 19, 66, 112, 134, 105, 89, 20,
- 105, 89, -1, 50, -1, 104, 50, -1, -1, 104,
- -1, -1, 55, 117, -1, -1, 108, -1, 4, -1,
- 108, 138, 4, -1, 1, -1, 108, 1, -1, 108,
- 138, 1, -1, -1, 112, -1, -1, 111, -1, 112,
- -1, 111, 138, 112, -1, 1, -1, 111, 1, -1,
- 111, 1, 112, -1, 111, 138, 1, -1, 130, 113,
- 112, -1, 112, 41, 112, -1, 112, 42, 112, -1,
- 112, 14, 112, -1, 112, 40, 129, -1, 112, 115,
- 112, -1, 112, 52, 112, 53, 112, -1, 116, -1,
- 13, -1, 12, -1, 51, 13, -1, 9, -1, 55,
- -1, 114, -1, 56, -1, 117, -1, 118, -1, 116,
- 117, -1, 119, -1, 117, 64, 117, -1, 117, 59,
- 117, -1, 117, 60, 117, -1, 117, 61, 117, -1,
- 117, 57, 117, -1, 117, 58, 117, -1, 38, 122,
- 106, -1, 130, 43, -1, 130, 44, -1, 66, 111,
- 134, 40, 129, -1, 116, 11, 38, 122, -1, 118,
- 64, 117, -1, 118, 59, 117, -1, 118, 60, 117,
- -1, 118, 61, 117, -1, 118, 57, 117, -1, 118,
- 58, 117, -1, 84, -1, 62, 117, -1, 66, 112,
- 134, -1, 45, 66, 110, 134, -1, 46, 66, 110,
- 134, -1, 46, -1, 120, -1, 130, -1, 43, 130,
- -1, 44, 130, -1, 7, -1, 8, -1, 58, 117,
- -1, 57, 117, -1, 121, -1, 68, 121, -1, 3,
- 66, 110, 134, -1, -1, 130, -1, -1, 124, 16,
- -1, 125, -1, 124, 125, -1, 126, -1, 69, 111,
- 70, -1, 126, -1, 127, 126, -1, 127, 16, -1,
- 4, -1, 4, 128, -1, 129, -1, 65, 119, 131,
- -1, 43, -1, 44, -1, -1, 71, 105, -1, 72,
- 105, -1, 67, -1, -1, 136, -1, 73, -1, 53,
- -1, 54, 105, -1
+ 46, -1, 35, 80, 66, 106, 133, 104, -1, -1,
+ 85, 84, 5, -1, 60, -1, 51, -1, -1, 86,
+ 88, -1, 86, 1, -1, 103, -1, 135, 104, -1,
+ 135, 104, -1, 131, 86, 132, -1, 102, -1, 23,
+ 66, 111, 133, 104, 131, 95, 104, 132, -1, 26,
+ 66, 111, 133, 104, 88, -1, 27, 104, 88, 26,
+ 66, 111, 133, 104, -1, 28, 66, 4, 40, 128,
+ 133, 104, 88, -1, 28, 66, 94, 135, 104, 111,
+ 135, 104, 94, 133, 104, 88, -1, 28, 66, 94,
+ 135, 104, 135, 104, 94, 133, 104, 88, -1, 89,
+ -1, 29, 87, -1, 30, 87, -1, 33, 87, -1,
+ 39, 87, -1, 34, 108, 87, -1, -1, 21, 90,
+ 108, 87, -1, 91, 87, -1, -1, 98, 92, 99,
+ 100, -1, -1, 22, 4, 93, 122, -1, 22, 66,
+ 4, 67, -1, 111, -1, -1, 91, -1, -1, 95,
+ 96, -1, 95, 1, -1, 24, 97, 136, 104, 86,
+ -1, 25, 136, 104, 86, -1, 7, -1, 58, 7,
+ -1, 57, 7, -1, 8, -1, 83, -1, 31, -1,
+ 32, -1, 109, -1, 66, 110, 133, -1, -1, -1,
+ 10, 101, 115, -1, 19, 66, 111, 133, 104, 88,
+ -1, 19, 66, 111, 133, 104, 88, 20, 104, 88,
+ -1, 50, -1, 103, 50, -1, -1, 103, -1, -1,
+ 55, 116, -1, -1, 107, -1, 4, -1, 107, 137,
+ 4, -1, 1, -1, 107, 1, -1, 107, 137, 1,
+ -1, -1, 111, -1, -1, 110, -1, 111, -1, 110,
+ 137, 111, -1, 1, -1, 110, 1, -1, 110, 1,
+ 111, -1, 110, 137, 1, -1, 129, 112, 111, -1,
+ 111, 41, 111, -1, 111, 42, 111, -1, 111, 14,
+ 111, -1, 111, 40, 128, -1, 111, 114, 111, -1,
+ 111, 52, 111, 53, 111, -1, 115, -1, 13, -1,
+ 12, -1, 51, 13, -1, 9, -1, 55, -1, 113,
+ -1, 56, -1, 116, -1, 117, -1, 115, 116, -1,
+ 118, -1, 116, 64, 116, -1, 116, 59, 116, -1,
+ 116, 60, 116, -1, 116, 61, 116, -1, 116, 57,
+ 116, -1, 116, 58, 116, -1, 38, 121, 105, -1,
+ 129, 43, -1, 129, 44, -1, 66, 110, 133, 40,
+ 128, -1, 115, 11, 38, 121, -1, 117, 64, 116,
+ -1, 117, 59, 116, -1, 117, 60, 116, -1, 117,
+ 61, 116, -1, 117, 57, 116, -1, 117, 58, 116,
+ -1, 83, -1, 62, 116, -1, 66, 111, 133, -1,
+ 45, 66, 109, 133, -1, 46, 66, 109, 133, -1,
+ 46, -1, 119, -1, 129, -1, 43, 129, -1, 44,
+ 129, -1, 7, -1, 8, -1, 58, 116, -1, 57,
+ 116, -1, 120, -1, 68, 120, -1, 3, 66, 109,
+ 133, -1, -1, 129, -1, -1, 123, 16, -1, 124,
+ -1, 123, 124, -1, 125, -1, 69, 110, 70, -1,
+ 125, -1, 126, 125, -1, 126, 16, -1, 4, -1,
+ 4, 127, -1, 128, -1, 65, 118, 130, -1, 43,
+ -1, 44, -1, -1, 71, 104, -1, 72, 104, -1,
+ 67, -1, -1, 135, -1, 73, -1, 53, -1, 54,
+ 104, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 218, 218, 220, 225, 226, 230, 242, 246, 257,
- 265, 273, 281, 283, 289, 290, 292, 318, 329, 340,
- 346, 355, 365, 367, 369, 380, 385, 386, 391, 390,
- 420, 419, 452, 454, 459, 460, 473, 478, 479, 483,
- 485, 487, 494, 584, 626, 668, 783, 790, 797, 807,
- 816, 825, 834, 849, 865, 864, 876, 888, 888, 984,
- 984, 1009, 1032, 1038, 1039, 1045, 1046, 1053, 1058, 1070,
- 1084, 1086, 1092, 1097, 1099, 1107, 1109, 1118, 1119, 1127,
- 1132, 1132, 1143, 1147, 1155, 1156, 1159, 1161, 1166, 1167,
- 1174, 1176, 1180, 1186, 1193, 1195, 1197, 1204, 1205, 1211,
- 1212, 1217, 1219, 1224, 1226, 1228, 1230, 1236, 1243, 1245,
- 1247, 1263, 1273, 1280, 1282, 1287, 1289, 1291, 1299, 1301,
- 1306, 1308, 1313, 1315, 1317, 1370, 1372, 1374, 1376, 1378,
- 1380, 1382, 1384, 1407, 1412, 1417, 1442, 1448, 1450, 1452,
- 1454, 1456, 1458, 1463, 1467, 1498, 1500, 1506, 1512, 1525,
- 1526, 1527, 1532, 1537, 1541, 1545, 1557, 1570, 1575, 1611,
- 1629, 1630, 1636, 1637, 1642, 1644, 1651, 1668, 1685, 1687,
- 1694, 1699, 1707, 1721, 1734, 1743, 1747, 1751, 1755, 1759,
- 1763, 1766, 1768, 1772, 1776, 1780
+ 0, 191, 191, 193, 198, 199, 203, 215, 219, 230,
+ 236, 244, 252, 254, 260, 261, 263, 289, 300, 311,
+ 317, 326, 336, 338, 340, 346, 351, 352, 356, 375,
+ 374, 408, 410, 415, 416, 429, 434, 435, 439, 441,
+ 443, 450, 540, 582, 624, 739, 746, 753, 763, 772,
+ 781, 790, 805, 821, 820, 832, 844, 844, 938, 938,
+ 963, 986, 992, 993, 999, 1000, 1007, 1012, 1024, 1038,
+ 1040, 1046, 1051, 1053, 1061, 1063, 1072, 1073, 1081, 1086,
+ 1086, 1097, 1101, 1109, 1110, 1113, 1115, 1120, 1121, 1130,
+ 1131, 1136, 1141, 1147, 1149, 1151, 1158, 1159, 1165, 1166,
+ 1171, 1173, 1178, 1180, 1182, 1184, 1190, 1197, 1199, 1201,
+ 1217, 1227, 1234, 1236, 1241, 1243, 1245, 1253, 1255, 1260,
+ 1262, 1267, 1269, 1271, 1321, 1323, 1325, 1327, 1329, 1331,
+ 1333, 1335, 1358, 1363, 1368, 1393, 1399, 1401, 1403, 1405,
+ 1407, 1409, 1414, 1418, 1449, 1451, 1457, 1463, 1476, 1477,
+ 1478, 1483, 1488, 1492, 1496, 1509, 1522, 1527, 1563, 1581,
+ 1582, 1588, 1589, 1594, 1596, 1603, 1620, 1637, 1639, 1646,
+ 1651, 1659, 1669, 1682, 1691, 1695, 1699, 1703, 1707, 1711,
+ 1714, 1716, 1720, 1724, 1728
};
#endif
@@ -769,10 +742,10 @@ static const char *const yytname[] =
"'+'", "'-'", "'*'", "'/'", "'%'", "'!'", "UNARY", "'^'", "'$'", "'('",
"')'", "'@'", "'['", "']'", "'{'", "'}'", "';'", "$accept", "program",
"rule", "source", "pattern", "action", "func_name", "lex_builtin",
- "function_prologue", "address@hidden", "regexp", "address@hidden",
"a_slash", "statements",
- "statement_term", "statement", "non_compound_stmt", "address@hidden",
"simple_stmt",
- "address@hidden", "address@hidden", "opt_simple_stmt", "case_statements",
"case_statement",
- "case_value", "print", "print_expression_list", "output_redir",
"address@hidden",
+ "function_prologue", "regexp", "address@hidden", "a_slash", "statements",
+ "statement_term", "statement", "non_compound_stmt", "address@hidden",
"simple_stmt",
+ "address@hidden", "address@hidden", "opt_simple_stmt", "case_statements",
"case_statement",
+ "case_value", "print", "print_expression_list", "output_redir",
"address@hidden",
"if_statement", "nls", "opt_nls", "input_redir", "opt_param_list",
"param_list", "opt_exp", "opt_expression_list", "expression_list", "exp",
"assign_operator", "relop_or_less", "a_relop", "common_exp", "simp_exp",
@@ -805,23 +778,23 @@ static const yytype_uint8 yyr1[] =
{
0, 74, 75, 75, 75, 75, 75, 76, 76, 76,
76, 77, 77, 77, 78, 78, 78, 78, 78, 78,
- 78, 79, 80, 80, 80, 80, 81, 81, 83, 82,
- 85, 84, 86, 86, 87, 87, 87, 88, 88, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 90,
- 90, 90, 90, 90, 91, 90, 90, 93, 92, 94,
- 92, 92, 92, 95, 95, 96, 96, 96, 97, 97,
- 98, 98, 98, 98, 98, 99, 99, 100, 100, 101,
- 102, 101, 103, 103, 104, 104, 105, 105, 106, 106,
- 107, 107, 108, 108, 108, 108, 108, 109, 109, 110,
- 110, 111, 111, 111, 111, 111, 111, 112, 112, 112,
- 112, 112, 112, 112, 112, 113, 113, 113, 114, 114,
- 115, 115, 116, 116, 116, 117, 117, 117, 117, 117,
- 117, 117, 117, 117, 117, 117, 118, 118, 118, 118,
- 118, 118, 118, 119, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 119, 120, 120, 121,
- 122, 122, 123, 123, 124, 124, 125, 126, 127, 127,
- 128, 129, 129, 130, 130, 131, 131, 131, 132, 133,
- 134, 135, 135, 136, 137, 138
+ 78, 79, 80, 80, 80, 80, 81, 81, 82, 84,
+ 83, 85, 85, 86, 86, 86, 87, 87, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 89, 89,
+ 89, 89, 89, 90, 89, 89, 92, 91, 93, 91,
+ 91, 91, 94, 94, 95, 95, 95, 96, 96, 97,
+ 97, 97, 97, 97, 98, 98, 99, 99, 100, 101,
+ 100, 102, 102, 103, 103, 104, 104, 105, 105, 106,
+ 106, 107, 107, 107, 107, 107, 108, 108, 109, 109,
+ 110, 110, 110, 110, 110, 110, 111, 111, 111, 111,
+ 111, 111, 111, 111, 112, 112, 112, 113, 113, 114,
+ 114, 115, 115, 115, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 117, 117, 117, 117, 117,
+ 117, 117, 118, 118, 118, 118, 118, 118, 118, 118,
+ 118, 118, 118, 118, 118, 118, 119, 119, 120, 121,
+ 121, 122, 122, 123, 123, 124, 125, 126, 126, 127,
+ 128, 128, 129, 129, 130, 130, 130, 131, 132, 133,
+ 134, 134, 135, 136, 137
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
@@ -829,23 +802,23 @@ static const yytype_uint8 yyr2[] =
{
0, 2, 0, 2, 2, 2, 2, 2, 2, 2,
4, 1, 2, 1, 0, 1, 4, 1, 1, 1,
- 1, 5, 1, 1, 1, 2, 1, 1, 0, 7,
- 0, 3, 1, 1, 0, 2, 2, 1, 2, 2,
- 3, 1, 9, 6, 8, 8, 12, 11, 1, 2,
- 2, 2, 2, 3, 0, 4, 2, 0, 4, 0,
- 4, 4, 1, 0, 1, 0, 2, 2, 5, 4,
- 1, 2, 2, 1, 1, 1, 1, 1, 3, 0,
- 0, 3, 6, 9, 1, 2, 0, 1, 0, 2,
- 0, 1, 1, 3, 1, 2, 3, 0, 1, 0,
- 1, 1, 3, 1, 2, 3, 3, 3, 3, 3,
- 3, 3, 3, 5, 1, 1, 1, 2, 1, 1,
- 1, 1, 1, 1, 2, 1, 3, 3, 3, 3,
- 3, 3, 3, 2, 2, 5, 4, 3, 3, 3,
- 3, 3, 3, 1, 2, 3, 4, 4, 1, 1,
- 1, 2, 2, 1, 1, 2, 2, 1, 2, 4,
- 0, 1, 0, 2, 1, 2, 1, 3, 1, 2,
- 2, 1, 2, 1, 3, 1, 1, 0, 2, 2,
- 1, 0, 1, 1, 1, 2
+ 1, 5, 1, 1, 1, 2, 1, 1, 6, 0,
+ 3, 1, 1, 0, 2, 2, 1, 2, 2, 3,
+ 1, 9, 6, 8, 8, 12, 11, 1, 2, 2,
+ 2, 2, 3, 0, 4, 2, 0, 4, 0, 4,
+ 4, 1, 0, 1, 0, 2, 2, 5, 4, 1,
+ 2, 2, 1, 1, 1, 1, 1, 3, 0, 0,
+ 3, 6, 9, 1, 2, 0, 1, 0, 2, 0,
+ 1, 1, 3, 1, 2, 3, 0, 1, 0, 1,
+ 1, 3, 1, 2, 3, 3, 3, 3, 3, 3,
+ 3, 3, 5, 1, 1, 1, 2, 1, 1, 1,
+ 1, 1, 1, 2, 1, 3, 3, 3, 3, 3,
+ 3, 3, 2, 2, 5, 4, 3, 3, 3, 3,
+ 3, 3, 1, 2, 3, 4, 4, 1, 1, 1,
+ 2, 2, 1, 1, 2, 2, 1, 2, 4, 0,
+ 1, 0, 2, 1, 2, 1, 3, 1, 2, 2,
+ 1, 2, 1, 3, 1, 1, 0, 2, 2, 1,
+ 0, 1, 1, 1, 2
};
/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
@@ -853,353 +826,353 @@ static const yytype_uint8 yyr2[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 2, 0, 1, 6, 0, 171, 153, 154, 17, 18,
- 28, 19, 20, 160, 0, 0, 0, 148, 5, 84,
- 33, 0, 0, 32, 0, 0, 0, 0, 3, 0,
- 0, 143, 30, 4, 15, 114, 122, 123, 125, 149,
- 157, 173, 150, 0, 0, 168, 0, 172, 0, 88,
- 161, 151, 152, 0, 0, 0, 156, 150, 155, 144,
- 0, 177, 150, 103, 0, 101, 0, 158, 86, 183,
- 7, 8, 37, 34, 86, 9, 0, 85, 118, 0,
- 0, 0, 0, 0, 86, 119, 121, 120, 0, 0,
- 124, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 116, 115, 133, 134, 0, 0, 0,
- 0, 101, 0, 170, 169, 23, 22, 26, 27, 0,
- 0, 24, 0, 132, 0, 0, 0, 175, 176, 174,
- 104, 86, 180, 0, 0, 145, 13, 0, 0, 87,
- 178, 0, 38, 31, 110, 111, 108, 109, 0, 0,
- 112, 160, 130, 131, 127, 128, 129, 126, 141, 142,
- 138, 139, 140, 137, 117, 107, 159, 167, 25, 0,
- 89, 146, 147, 105, 185, 0, 106, 102, 12, 10,
- 36, 0, 54, 0, 0, 0, 86, 0, 0, 0,
- 75, 76, 0, 97, 0, 86, 35, 48, 0, 57,
- 41, 62, 34, 181, 86, 0, 16, 136, 94, 92,
- 0, 0, 135, 0, 97, 59, 0, 0, 0, 0,
- 63, 49, 50, 51, 0, 98, 52, 179, 56, 0,
- 0, 86, 182, 39, 113, 86, 95, 0, 0, 0,
- 162, 0, 0, 0, 0, 171, 64, 0, 53, 0,
- 79, 77, 40, 21, 29, 96, 93, 86, 55, 60,
- 0, 164, 166, 61, 86, 86, 0, 0, 86, 0,
- 80, 58, 0, 163, 165, 0, 0, 0, 0, 0,
- 78, 0, 82, 65, 43, 0, 86, 0, 86, 81,
- 86, 0, 86, 0, 86, 63, 0, 67, 0, 0,
- 66, 0, 44, 45, 63, 0, 83, 70, 73, 0,
- 0, 74, 0, 184, 86, 42, 0, 86, 72, 71,
- 86, 34, 86, 0, 34, 0, 0, 47, 0, 46
+ 2, 0, 1, 6, 0, 170, 152, 153, 17, 18,
+ 0, 19, 20, 159, 0, 0, 0, 147, 5, 83,
+ 32, 0, 0, 31, 0, 0, 0, 0, 3, 0,
+ 0, 142, 29, 4, 15, 113, 121, 122, 124, 148,
+ 156, 172, 149, 0, 0, 167, 0, 171, 23, 22,
+ 26, 27, 0, 0, 24, 87, 160, 150, 151, 0,
+ 0, 0, 155, 149, 154, 143, 0, 176, 149, 102,
+ 0, 100, 0, 157, 85, 182, 7, 8, 36, 33,
+ 85, 9, 0, 84, 117, 0, 0, 0, 0, 0,
+ 85, 118, 120, 119, 0, 0, 123, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 115,
+ 114, 132, 133, 0, 0, 0, 0, 100, 0, 169,
+ 168, 25, 0, 0, 131, 0, 0, 0, 174, 175,
+ 173, 103, 85, 179, 0, 0, 144, 13, 0, 0,
+ 86, 177, 0, 37, 30, 109, 110, 107, 108, 0,
+ 0, 111, 159, 129, 130, 126, 127, 128, 125, 140,
+ 141, 137, 138, 139, 136, 116, 106, 158, 166, 93,
+ 91, 0, 0, 88, 145, 146, 104, 184, 0, 105,
+ 101, 12, 10, 35, 0, 53, 0, 0, 0, 85,
+ 0, 0, 0, 74, 75, 0, 96, 0, 85, 34,
+ 47, 0, 56, 40, 61, 33, 180, 85, 0, 16,
+ 135, 85, 94, 0, 134, 0, 96, 58, 0, 0,
+ 0, 0, 62, 48, 49, 50, 0, 97, 51, 178,
+ 55, 0, 0, 85, 181, 38, 112, 28, 95, 92,
+ 0, 0, 161, 0, 0, 0, 0, 170, 63, 0,
+ 52, 0, 78, 76, 39, 21, 85, 54, 59, 0,
+ 163, 165, 60, 85, 85, 0, 0, 85, 0, 79,
+ 57, 0, 162, 164, 0, 0, 0, 0, 0, 77,
+ 0, 81, 64, 42, 0, 85, 0, 85, 80, 85,
+ 0, 85, 0, 85, 62, 0, 66, 0, 0, 65,
+ 0, 43, 44, 62, 0, 82, 69, 72, 0, 0,
+ 73, 0, 183, 85, 41, 0, 85, 71, 70, 85,
+ 33, 85, 0, 33, 0, 0, 46, 0, 45
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int16 yydefgoto[] =
{
- -1, 1, 28, 138, 29, 70, 120, 121, 30, 48,
- 31, 76, 32, 141, 71, 196, 197, 214, 198, 229,
- 240, 247, 291, 300, 312, 199, 250, 271, 281, 200,
- 139, 140, 123, 210, 211, 224, 109, 110, 201, 108,
- 87, 88, 35, 36, 37, 38, 39, 40, 49, 259,
- 260, 261, 45, 46, 47, 41, 42, 129, 202, 203,
- 135, 231, 204, 314, 134
+ -1, 1, 28, 139, 29, 76, 53, 54, 30, 31,
+ 82, 32, 142, 77, 199, 200, 216, 201, 231, 242,
+ 249, 290, 299, 311, 202, 252, 270, 280, 203, 140,
+ 141, 124, 171, 172, 226, 115, 116, 204, 114, 93,
+ 94, 35, 36, 37, 38, 39, 40, 55, 258, 259,
+ 260, 45, 46, 47, 41, 42, 130, 205, 206, 136,
+ 233, 207, 313, 135
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -269
+#define YYPACT_NINF -264
static const yytype_int16 yypact[] =
{
- -269, 335, -269, -269, -31, -24, -269, -269, -269, -269,
- -269, -269, -269, 12, 12, 12, -19, -12, -269, -269,
- -269, 978, 978, -269, 978, 1023, 804, 21, -269, 115,
- -21, -269, -269, 8, 1062, 952, -20, 330, -269, -269,
- -269, -269, 246, 736, 804, -269, 2, -269, 205, 15,
- -269, -269, -269, 736, 736, 70, 52, 80, 52, 52,
- 978, 147, -269, -269, 50, 308, 174, -269, 64, -269,
- -269, -269, 8, -269, 64, -269, 129, -269, -269, 978,
- 143, 978, 978, 978, 64, -269, -269, -269, 978, 112,
- -20, 978, 978, 978, 978, 978, 978, 978, 978, 978,
- 978, 978, 978, -269, -269, -269, -269, 141, 978, 90,
- 152, 1101, 48, -269, -269, -269, -269, -269, -269, 111,
- 105, -269, 978, -269, 90, 90, 308, -269, -269, -269,
- 978, 64, -269, 134, 830, -269, -269, 13, -16, 8,
- -269, 552, -269, -269, 53, -269, 142, 300, 1081, 978,
- 103, 12, 185, 185, 52, 52, 52, 52, 185, 185,
- 52, 52, 52, 52, -269, 1101, -269, -269, -269, 63,
- -20, -269, -269, 1101, -269, 143, -269, 1101, -269, -269,
- -269, 121, -269, 6, 130, 137, 64, 139, -16, -16,
- -269, -269, -16, 978, -16, 64, -269, -269, -16, -269,
- -269, 1101, -269, 127, 64, 978, 1101, -269, -269, -269,
- 90, 118, -269, 978, 978, -269, 180, 978, 978, 665,
- 875, -269, -269, -269, -16, 1101, -269, -269, -269, 598,
- 552, 64, -269, -269, 1101, 64, -269, 28, 308, -16,
- -24, 140, 308, 308, 189, -14, -269, 127, -269, 804,
- 201, -269, -269, -269, -269, -269, -269, 64, -269, -269,
- 14, -269, -269, -269, 64, 64, 158, 143, 64, 50,
- -269, -269, 665, -269, -269, -21, 665, 978, 90, 710,
- 134, 978, 198, -269, -269, 308, 64, 1056, 64, 952,
- 64, 60, 64, 665, 64, 907, 665, -269, 119, 177,
- -269, 155, -269, -269, 907, 90, -269, -269, -269, 224,
- 228, -269, 177, -269, 64, -269, 90, 64, -269, -269,
- 64, -269, 64, 665, -269, 406, 665, -269, 479, -269
+ -264, 367, -264, -264, -31, -42, -264, -264, -264, -264,
+ 165, -264, -264, 46, 46, 46, -29, -27, -264, -264,
+ -264, 1010, 1010, -264, 1010, 1055, 836, 27, -264, -35,
+ -7, -264, -264, 17, 1088, 984, 288, 362, -264, -264,
+ -264, -264, 146, 768, 836, -264, 1, -264, -264, -264,
+ -264, -264, 60, -18, -264, 11, -264, -264, -264, 768,
+ 768, 74, 52, 9, 52, 52, 1010, 13, -264, -264,
+ 53, 341, 28, -264, 79, -264, -264, -264, 17, -264,
+ 79, -264, 119, -264, -264, 1010, 148, 1010, 1010, 1010,
+ 79, -264, -264, -264, 1010, 122, 288, 1010, 1010, 1010,
+ 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, -264,
+ -264, -264, -264, 151, 1010, 94, 81, 1094, 40, -264,
+ -264, -264, 45, 1010, -264, 94, 94, 341, -264, -264,
+ -264, 1010, 79, -264, 125, 862, -264, -264, 82, -22,
+ 17, -264, 584, -264, -264, 62, -264, 212, 267, 301,
+ 1010, 118, 46, 127, 127, 52, 52, 52, 52, 127,
+ 127, 52, 52, 52, 52, -264, 1094, -264, -264, -264,
+ -264, 94, 61, 288, -264, -264, 1094, -264, 148, -264,
+ 1094, -264, -264, -264, 105, -264, 10, 109, 112, 79,
+ 113, -22, -22, -264, -264, -22, 1010, -22, 79, -264,
+ -264, -22, -264, -264, 1094, -264, 107, 79, 1010, 1094,
+ -264, 79, -264, 43, -264, 1010, 1010, -264, 180, 1010,
+ 1010, 697, 907, -264, -264, -264, -22, 1094, -264, -264,
+ -264, 630, 584, 79, -264, -264, 1094, -264, -264, -264,
+ 341, -22, -42, 126, 341, 341, 166, -14, -264, 107,
+ -264, 836, 190, -264, -264, -264, 79, -264, -264, 16,
+ -264, -264, -264, 79, 79, 136, 148, 79, 53, -264,
+ -264, 697, -264, -264, -7, 697, 1010, 94, 742, 125,
+ 1010, 186, -264, -264, 341, 79, 278, 79, 984, 79,
+ 132, 79, 697, 79, 939, 697, -264, 240, 155, -264,
+ 137, -264, -264, 939, 94, -264, -264, -264, 205, 206,
+ -264, 155, -264, 79, -264, 94, 79, -264, -264, 79,
+ -264, 79, 697, -264, 438, 697, -264, 511, -264
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int16 yypgoto[] =
{
- -269, -269, -269, -269, -269, 208, -269, -269, -269, -269,
- -58, -269, -269, -193, 72, -171, -269, -269, -189, -269,
- -269, -268, -269, -269, -269, -269, -269, -269, -269, -269,
- 45, 37, -269, -269, -269, 38, -48, -23, -1, -269,
- -269, -269, -26, 44, -269, 217, -269, 1, 102, -269,
- -269, -3, -39, -269, -269, -72, -2, -269, -28, -213,
- -49, -269, -25, -47, 66
+ -264, -264, -264, -264, -264, 187, -264, -264, -264, -74,
+ -264, -264, -197, 98, -203, -264, -264, -213, -264, -264,
+ -263, -264, -264, -264, -264, -264, -264, -264, -264, 44,
+ 73, -264, -264, -264, 18, -54, -23, -1, -264, -264,
+ -264, -55, 39, -264, 202, -264, 124, 77, -264, -264,
+ -19, -39, -264, -264, -70, -2, -264, -28, -222, -46,
+ -264, -25, -79, 70
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -101
+#define YYTABLE_NINF -100
static const yytype_int16 yytable[] =
{
- 34, 73, 73, 64, 74, 124, 125, 114, 145, 230,
- 215, 50, 51, 52, 178, 133, 5, 252, 113, 57,
- 57, 112, 57, 62, 4, 65, 267, 305, 67, 255,
- 273, 246, 256, 57, 19, 43, 316, 91, 92, 93,
- 94, 95, 111, 111, 96, 44, 33, 53, 244, 130,
- 68, 130, 111, 111, 54, 44, 67, 69, 77, 126,
- 166, 297, 78, -11, 208, 56, 58, 209, 59, 66,
- 122, 44, 216, 4, 72, 171, 172, 25, 144, 90,
- 146, 147, 148, 44, 298, 299, -11, 150, 315, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 282, 131, 212, 131, 284, 246, 165, 85, 86,
- 19, 142, -101, 74, 19, 246, 96, 132, 167, 236,
- 57, 149, 303, 105, 106, 306, 307, 308, 325, 173,
- -90, 328, -86, 177, 143, 152, 153, 154, 155, 156,
- 157, 158, 159, 160, 161, 162, 163, 5, 206, 50,
- 151, 78, 327, 130, 164, 329, 79, 132, -101, -101,
- 168, 235, -100, 74, 74, 19, 170, 74, 174, 74,
- 20, 169, 131, 74, 175, 136, 309, 310, 232, 23,
- 137, 251, 80, 72, 241, -91, 68, 213, 69, 257,
- 127, 128, 225, 264, 265, 278, 217, 85, 86, 74,
- 69, 262, -100, 218, 234, 220, 131, 263, 115, 116,
- 179, 270, 238, 225, 74, 266, 242, 243, 290, -100,
- 280, 262, 268, 219, 277, -100, 269, 195, 111, 286,
- 313, 318, 227, 72, 72, 319, 292, 72, 75, 72,
- 311, 233, 61, 72, 93, 94, 95, 283, 65, 96,
- 117, 118, 239, 207, 288, 289, 317, 274, 103, 104,
- 221, 222, 294, 0, 223, 320, 226, 322, 253, 72,
- 228, 0, 254, 119, 0, 0, 285, 237, 287, 57,
- 0, 0, 0, 0, 72, 0, 0, 57, 0, 105,
- 106, 0, 0, 0, 272, 0, 248, 107, 0, 0,
- 0, 275, 276, 0, 0, 279, 0, 0, 0, 78,
- 0, 258, 0, 0, 79, 0, 0, 78, 0, 0,
- 0, 0, 79, 293, 0, 295, 0, 296, 301, 302,
- 0, 304, 0, 90, 0, 2, 3, 0, 4, 5,
- 80, 81, 6, 7, 0, 0, 0, 0, 80, 81,
- 82, 321, 8, 9, 323, 85, 86, 324, 0, 326,
- 83, 0, 0, 85, 86, 0, 0, 0, 0, 0,
- 10, 11, 12, 13, 0, 132, 0, 0, 14, 15,
- 16, 17, 18, 0, 0, 19, 20, 97, 98, 99,
- 100, 101, 21, 22, 102, 23, 0, 24, 0, 0,
- 25, 26, 0, 27, 0, 0, -14, 180, -14, 4,
- 5, 0, 0, 6, 7, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 181, 0, 182, 183, 184,
- -69, -69, 185, 186, 187, 188, 189, 190, 191, 192,
- 193, 0, 0, 0, 13, 194, 0, 0, 0, 14,
- 15, 16, 17, 0, 0, 0, -69, 20, 0, 0,
- 0, 0, 0, 21, 22, 0, 23, 0, 24, 0,
- 0, 25, 26, 0, 55, 0, 0, 68, -69, 69,
- 180, 0, 4, 5, 0, 0, 6, 7, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 181, 0,
- 182, 183, 184, -68, -68, 185, 186, 187, 188, 189,
- 190, 191, 192, 193, 0, 0, 0, 13, 194, 0,
- 0, 0, 14, 15, 16, 17, 0, 0, 0, -68,
- 20, 0, 0, 0, 0, 0, 21, 22, 0, 23,
- 0, 24, 0, 0, 25, 26, 0, 55, 0, 0,
- 68, -68, 69, 180, 0, 4, 5, 0, 0, 6,
- 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 181, 0, 182, 183, 184, 0, 0, 185, 186,
- 187, 188, 189, 190, 191, 192, 193, 0, 0, 0,
- 13, 194, 0, 0, 0, 14, 15, 16, 17, 63,
- 0, 4, 5, 20, 0, 6, 7, 0, -99, 21,
- 22, 0, 23, 0, 24, 0, 0, 25, 26, 0,
- 55, 0, 0, 68, 195, 69, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 13, 0, 0, 0,
- 0, 14, 15, 16, 17, 0, 0, 0, -99, 20,
+ 34, 79, 79, 70, 80, 125, 126, 120, 232, 248,
+ 254, 56, 57, 58, 217, 19, 146, 119, 246, 63,
+ 63, 118, 63, 68, 134, 71, 266, 44, 19, 137,
+ 4, 304, 272, 63, 138, 43, 74, 59, 75, 60,
+ 315, 131, 117, 117, 238, 33, 169, 239, 122, 170,
+ 5, 75, 111, 112, 131, 44, 128, 129, 117, 117,
+ 62, 64, 212, 65, 74, 127, 123, 83, 281, 167,
+ 44, 84, 283, 78, 96, 72, 218, 4, 314, 174,
+ 175, 248, 131, 181, 145, 44, 147, 148, 149, 302,
+ 248, -99, 305, 151, 132, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 132, 214, 121,
+ 168, 25, -89, 166, 80, 132, 102, 91, 92, 326,
+ 133, 63, 328, 324, 144, 211, 327, -100, -90, 19,
+ 176, -99, -11, 296, 180, 132, 153, 154, 155, 156,
+ 157, 158, 159, 160, 161, 162, 163, 164, -99, 209,
+ 56, 73, 5, 143, -99, -11, 297, 298, 109, 110,
+ 152, 133, 173, 150, 165, 178, 80, 80, 48, 49,
+ 80, 215, 80, -100, -100, 219, 80, 253, 220, 222,
+ 75, 234, 19, 78, 243, 73, 99, 100, 101, 111,
+ 112, 102, 265, 262, 256, 227, 277, 113, 263, 264,
+ 269, 80, 276, 261, -85, 177, 289, 236, 312, 198,
+ 50, 51, 317, 318, 240, 227, 80, 81, 244, 245,
+ 261, 84, 279, 310, 267, 288, 85, 67, 268, 210,
+ 117, 285, 319, 52, 241, 78, 78, 182, 291, 78,
+ 273, 78, 213, 0, 0, 78, 282, 306, 307, 0,
+ 71, 0, 86, 287, 0, 0, 0, 0, 316, 0,
+ 0, 293, 221, 0, 0, 0, 0, 91, 92, 321,
+ 78, 229, 0, 0, 0, 284, 84, 286, 63, 0,
+ 235, 85, 0, 0, 237, 78, 63, 84, 0, 223,
+ 224, 20, 85, 225, 0, 228, 0, 308, 309, 230,
+ 23, 0, 0, 0, 0, 0, 255, 86, 87, 0,
+ 84, 0, 0, 0, 0, 85, 0, 0, 86, 87,
+ 88, 0, 91, 92, 250, 0, 0, 96, 0, 271,
+ 89, 0, 0, 91, 92, 0, 274, 275, 0, 257,
+ 278, 86, 87, 88, 0, 97, 98, 99, 100, 101,
+ 84, 75, 102, 89, 208, 85, 91, 92, 292, 0,
+ 294, 0, 295, 300, 301, 0, 303, 2, 3, 0,
+ 4, 5, 0, 0, 6, 7, 0, 0, 0, 0,
+ 0, 86, 87, 88, 8, 9, 320, 0, 0, 322,
+ 0, 0, 323, 89, 325, 0, 91, 92, 0, 0,
+ 0, 0, 10, 11, 12, 13, 0, 0, 133, 0,
+ 14, 15, 16, 17, 18, 0, 0, 19, 20, 103,
+ 104, 105, 106, 107, 21, 22, 108, 23, 0, 24,
+ 0, 0, 25, 26, 0, 27, 0, 0, -14, 183,
+ -14, 4, 5, 0, 0, 6, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 184, 0, 185,
+ 186, 187, -68, -68, 188, 189, 190, 191, 192, 193,
+ 194, 195, 196, 0, 0, 0, 13, 197, 0, 0,
+ 0, 14, 15, 16, 17, 0, 0, 0, -68, 20,
0, 0, 0, 0, 0, 21, 22, 0, 23, 0,
- 24, 0, 0, 25, 249, -99, 55, 0, 4, 5,
- 0, -99, 6, 7, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 181, 0, 182, 183, 184, 0,
- 0, 185, 186, 187, 188, 189, 190, 191, 192, 193,
- 0, 0, 0, 13, 194, 0, 0, 0, 14, 15,
- 16, 17, 0, 4, 5, 0, 20, 6, 7, 0,
- 0, 0, 21, 22, 0, 23, 0, 24, 0, 0,
- 25, 26, 0, 55, 0, 0, 68, 63, 69, 4,
- 5, 0, 0, 6, 7, 0, 0, 0, 13, 0,
- 0, 0, 0, 14, 15, 16, 17, 0, 0, 0,
- 0, 20, 0, 0, 0, 0, 0, 21, 22, 0,
- 23, 0, 24, 0, 13, 25, 26, 0, 55, 14,
- 15, 16, 17, 69, 0, 0, 0, 20, 0, 0,
- 0, 0, 0, 21, 22, 0, 23, 0, 24, 0,
- 0, 25, 26, -99, 55, 63, 0, 4, 5, 0,
+ 24, 0, 0, 25, 26, 0, 61, 0, 0, 74,
+ -68, 75, 183, 0, 4, 5, 0, 0, 6, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 184, 0, 185, 186, 187, -67, -67, 188, 189, 190,
+ 191, 192, 193, 194, 195, 196, 0, 0, 0, 13,
+ 197, 0, 0, 0, 14, 15, 16, 17, 0, 0,
+ 0, -67, 20, 0, 0, 0, 0, 0, 21, 22,
+ 0, 23, 0, 24, 0, 0, 25, 26, 0, 61,
+ 0, 0, 74, -67, 75, 183, 0, 4, 5, 0,
0, 6, 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 184, 0, 185, 186, 187, 0, 0,
+ 188, 189, 190, 191, 192, 193, 194, 195, 196, 0,
+ 0, 0, 13, 197, 0, 0, 0, 14, 15, 16,
+ 17, 69, 0, 4, 5, 20, 0, 6, 7, 0,
+ -98, 21, 22, 0, 23, 0, 24, 0, 0, 25,
+ 26, 0, 61, 0, 0, 74, 198, 75, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 13, 0,
+ 0, 0, 0, 14, 15, 16, 17, 0, 0, 0,
+ -98, 20, 0, 0, 0, 0, 0, 21, 22, 0,
+ 23, 0, 24, 0, 0, 25, 251, -98, 61, 0,
+ 4, 5, 0, -98, 6, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 184, 0, 185, 186,
+ 187, 0, 0, 188, 189, 190, 191, 192, 193, 194,
+ 195, 196, 0, 0, 0, 13, 197, 0, 0, 0,
+ 14, 15, 16, 17, 0, 4, 5, 0, 20, 6,
+ 7, 0, 0, 0, 21, 22, 0, 23, 0, 24,
+ 0, 0, 25, 26, 0, 61, 0, 0, 74, 69,
+ 75, 4, 5, 0, 0, 6, 7, 0, 0, 0,
+ 13, 0, 0, 0, 0, 14, 15, 16, 17, 0,
+ 0, 0, 0, 20, 0, 0, 0, 0, 0, 21,
+ 22, 0, 23, 0, 24, 0, 13, 25, 26, 0,
+ 61, 14, 15, 16, 17, 75, 0, 0, 0, 20,
+ 0, 0, 0, 0, 0, 21, 22, 0, 23, 0,
+ 24, 0, 0, 25, 26, -98, 61, 69, 0, 4,
+ 5, 0, 0, 6, 7, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 176, 0, 4, 5, 0, 0, 6, 7, 0,
+ 0, 0, 0, 179, 0, 4, 5, 0, 0, 6,
+ 7, 0, 0, 0, 13, 0, 0, 0, 0, 14,
+ 15, 16, 17, 0, 0, 0, 0, 20, 0, 0,
+ 0, 0, 0, 21, 22, 0, 23, 0, 24, 0,
+ 13, 25, 26, 0, 61, 14, 15, 16, 17, 0,
+ 4, 247, 0, 20, 6, 7, 0, 0, 0, 21,
+ 22, 0, 23, 0, 24, 0, 0, 25, 26, 186,
+ 61, 0, 0, 0, 0, 0, 0, 0, 193, 194,
+ 0, 0, 4, 5, 0, 13, 6, 7, 0, 0,
+ 14, 15, 16, 17, 0, 0, 0, 0, 20, 0,
+ 0, 186, 0, 0, 21, 22, 0, 23, 0, 24,
+ 193, 194, 25, 26, 0, 61, 0, 13, 0, 0,
+ 0, 0, 14, 15, 16, 17, 0, 4, 5, 0,
+ 20, 6, 7, 0, 0, 95, 21, 22, 0, 23,
+ 0, 24, 0, 0, 25, 26, 0, 61, 0, 0,
+ 0, 0, 0, 4, 5, 0, 0, 6, 7, 0,
0, 0, 13, 0, 0, 0, 0, 14, 15, 16,
17, 0, 0, 0, 0, 20, 0, 0, 0, 0,
0, 21, 22, 0, 23, 0, 24, 0, 13, 25,
- 26, 0, 55, 14, 15, 16, 17, 0, 4, 245,
+ 26, 0, 61, 14, 15, 16, 17, 0, 4, 5,
0, 20, 6, 7, 0, 0, 0, 21, 22, 0,
- 23, 0, 24, 0, 0, 25, 26, 183, 55, 0,
- 0, 0, 0, 0, 0, 0, 190, 191, 0, 0,
- 4, 5, 0, 13, 6, 7, 0, 0, 14, 15,
- 16, 17, 0, 0, 0, 0, 20, 0, 0, 183,
- 0, 0, 21, 22, 0, 23, 0, 24, 190, 191,
- 25, 26, 0, 55, 0, 13, 0, 0, 0, 0,
- 14, 15, 16, 17, 0, 4, 5, 0, 20, 6,
- 7, 0, 0, 89, 21, 22, 0, 23, 0, 24,
- 0, 0, 25, 26, 0, 55, 0, 0, 0, 0,
- 0, 4, 5, 0, 0, 6, 7, 0, 0, 0,
- 13, 0, 0, 0, 0, 14, 15, 16, 17, 0,
- 0, 0, 0, 20, 0, 0, 0, 0, 0, 21,
- 22, 0, 23, 0, 24, 0, 13, 25, 26, 0,
- 55, 14, 15, 16, 17, 0, 4, 5, 0, 20,
- 6, 7, 0, 0, 0, 21, 22, 0, 23, 0,
- 24, 0, 0, 25, 26, 0, 55, 0, 0, 0,
+ 23, 0, 24, 0, 0, 25, 26, 0, 61, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 78, 14, 15, 16, 17,
- 79, 78, 0, 0, 20, 0, 79, 0, 0, 0,
- 21, 22, 0, 23, 0, 24, 0, 0, 25, 60,
- 78, 55, 0, 0, 0, 79, 80, 81, 82, 0,
- 0, 0, 80, 81, 82, 0, 0, 0, 83, 0,
- 78, 85, 86, 0, 83, 79, 84, 85, 86, 0,
- 0, 80, 81, 82, 0, 0, 0, 0, 0, 69,
- 0, 0, 0, 83, 205, 0, 85, 86, 0, 0,
- 0, 80, 81, 82, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 83, 0, 0, 85, 86
+ 0, 0, 0, 0, 0, 0, 0, 84, 14, 15,
+ 16, 17, 85, 84, 0, 0, 20, 0, 85, 0,
+ 0, 0, 21, 22, 0, 23, 0, 24, 0, 0,
+ 25, 66, 0, 61, 0, 0, 0, 0, 86, 87,
+ 88, 0, 0, 0, 86, 87, 88, 0, 0, 0,
+ 89, 0, 90, 91, 92, 0, 89, 0, 0, 91,
+ 92
};
#define yypact_value_is_default(yystate) \
- ((yystate) == (-269))
+ ((yystate) == (-264))
#define yytable_value_is_error(yytable_value) \
- ((yytable_value) == (-101))
+ ((yytable_value) == (-100))
static const yytype_int16 yycheck[] =
{
- 1, 29, 30, 26, 29, 53, 54, 46, 80, 202,
- 4, 13, 14, 15, 1, 64, 4, 230, 16, 21,
- 22, 44, 24, 25, 3, 26, 40, 295, 27, 1,
- 16, 220, 4, 35, 50, 66, 304, 57, 58, 59,
- 60, 61, 43, 44, 64, 69, 1, 66, 219, 1,
- 71, 1, 53, 54, 66, 69, 55, 73, 50, 60,
- 109, 1, 9, 50, 1, 21, 22, 4, 24, 48,
- 55, 69, 66, 3, 29, 124, 125, 65, 79, 35,
- 81, 82, 83, 69, 24, 25, 73, 88, 301, 91,
- 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
- 102, 272, 54, 175, 54, 276, 295, 108, 55, 56,
- 50, 74, 9, 138, 50, 304, 64, 67, 70, 1,
- 122, 84, 293, 43, 44, 296, 7, 8, 321, 130,
- 67, 324, 72, 134, 5, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 4, 149, 151,
- 38, 9, 323, 1, 13, 326, 14, 67, 55, 56,
- 49, 210, 10, 188, 189, 50, 122, 192, 131, 194,
- 51, 66, 54, 198, 40, 1, 57, 58, 203, 60,
- 6, 229, 40, 138, 4, 67, 71, 66, 73, 238,
- 43, 44, 193, 242, 243, 267, 66, 55, 56, 224,
- 73, 240, 50, 66, 205, 66, 54, 67, 3, 4,
- 138, 10, 213, 214, 239, 26, 217, 218, 20, 67,
- 269, 260, 247, 186, 66, 73, 249, 72, 229, 278,
- 53, 7, 195, 188, 189, 7, 285, 192, 30, 194,
- 298, 204, 25, 198, 59, 60, 61, 275, 249, 64,
- 45, 46, 214, 151, 279, 281, 305, 260, 12, 13,
- 188, 189, 287, -1, 192, 312, 194, 316, 231, 224,
- 198, -1, 235, 68, -1, -1, 277, 211, 279, 281,
- -1, -1, -1, -1, 239, -1, -1, 289, -1, 43,
- 44, -1, -1, -1, 257, -1, 224, 51, -1, -1,
- -1, 264, 265, -1, -1, 268, -1, -1, -1, 9,
- -1, 239, -1, -1, 14, -1, -1, 9, -1, -1,
- -1, -1, 14, 286, -1, 288, -1, 290, 291, 292,
- -1, 294, -1, 289, -1, 0, 1, -1, 3, 4,
- 40, 41, 7, 8, -1, -1, -1, -1, 40, 41,
- 42, 314, 17, 18, 317, 55, 56, 320, -1, 322,
- 52, -1, -1, 55, 56, -1, -1, -1, -1, -1,
- 35, 36, 37, 38, -1, 67, -1, -1, 43, 44,
- 45, 46, 47, -1, -1, 50, 51, 57, 58, 59,
- 60, 61, 57, 58, 64, 60, -1, 62, -1, -1,
- 65, 66, -1, 68, -1, -1, 71, 1, 73, 3,
- 4, -1, -1, 7, 8, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 19, -1, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, -1, -1, -1, 38, 39, -1, -1, -1, 43,
- 44, 45, 46, -1, -1, -1, 50, 51, -1, -1,
- -1, -1, -1, 57, 58, -1, 60, -1, 62, -1,
- -1, 65, 66, -1, 68, -1, -1, 71, 72, 73,
- 1, -1, 3, 4, -1, -1, 7, 8, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 19, -1,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, -1, -1, -1, 38, 39, -1,
- -1, -1, 43, 44, 45, 46, -1, -1, -1, 50,
- 51, -1, -1, -1, -1, -1, 57, 58, -1, 60,
- -1, 62, -1, -1, 65, 66, -1, 68, -1, -1,
- 71, 72, 73, 1, -1, 3, 4, -1, -1, 7,
- 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 19, -1, 21, 22, 23, -1, -1, 26, 27,
- 28, 29, 30, 31, 32, 33, 34, -1, -1, -1,
- 38, 39, -1, -1, -1, 43, 44, 45, 46, 1,
- -1, 3, 4, 51, -1, 7, 8, -1, 10, 57,
- 58, -1, 60, -1, 62, -1, -1, 65, 66, -1,
- 68, -1, -1, 71, 72, 73, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 38, -1, -1, -1,
+ 1, 29, 30, 26, 29, 59, 60, 46, 205, 222,
+ 232, 13, 14, 15, 4, 50, 86, 16, 221, 21,
+ 22, 44, 24, 25, 70, 26, 40, 69, 50, 1,
+ 3, 294, 16, 35, 6, 66, 71, 66, 73, 66,
+ 303, 1, 43, 44, 1, 1, 1, 4, 66, 4,
+ 4, 73, 43, 44, 1, 69, 43, 44, 59, 60,
+ 21, 22, 1, 24, 71, 66, 55, 50, 271, 115,
+ 69, 9, 275, 29, 35, 48, 66, 3, 300, 125,
+ 126, 294, 1, 1, 85, 69, 87, 88, 89, 292,
+ 303, 10, 295, 94, 54, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 54, 178, 49,
+ 70, 65, 67, 114, 139, 54, 64, 55, 56, 322,
+ 67, 123, 325, 320, 5, 171, 323, 9, 67, 50,
+ 131, 50, 50, 1, 135, 54, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 67, 150,
+ 152, 27, 4, 80, 73, 73, 24, 25, 12, 13,
+ 38, 67, 123, 90, 13, 40, 191, 192, 3, 4,
+ 195, 66, 197, 55, 56, 66, 201, 231, 66, 66,
+ 73, 206, 50, 139, 4, 61, 59, 60, 61, 43,
+ 44, 64, 26, 67, 240, 196, 266, 51, 244, 245,
+ 10, 226, 66, 242, 72, 132, 20, 208, 53, 72,
+ 45, 46, 7, 7, 215, 216, 241, 30, 219, 220,
+ 259, 9, 268, 297, 249, 280, 14, 25, 251, 152,
+ 231, 277, 311, 68, 216, 191, 192, 139, 284, 195,
+ 259, 197, 172, -1, -1, 201, 274, 7, 8, -1,
+ 251, -1, 40, 278, -1, -1, -1, -1, 304, -1,
+ -1, 286, 189, -1, -1, -1, -1, 55, 56, 315,
+ 226, 198, -1, -1, -1, 276, 9, 278, 280, -1,
+ 207, 14, -1, -1, 211, 241, 288, 9, -1, 191,
+ 192, 51, 14, 195, -1, 197, -1, 57, 58, 201,
+ 60, -1, -1, -1, -1, -1, 233, 40, 41, -1,
+ 9, -1, -1, -1, -1, 14, -1, -1, 40, 41,
+ 42, -1, 55, 56, 226, -1, -1, 288, -1, 256,
+ 52, -1, -1, 55, 56, -1, 263, 264, -1, 241,
+ 267, 40, 41, 42, -1, 57, 58, 59, 60, 61,
+ 9, 73, 64, 52, 53, 14, 55, 56, 285, -1,
+ 287, -1, 289, 290, 291, -1, 293, 0, 1, -1,
+ 3, 4, -1, -1, 7, 8, -1, -1, -1, -1,
+ -1, 40, 41, 42, 17, 18, 313, -1, -1, 316,
+ -1, -1, 319, 52, 321, -1, 55, 56, -1, -1,
+ -1, -1, 35, 36, 37, 38, -1, -1, 67, -1,
+ 43, 44, 45, 46, 47, -1, -1, 50, 51, 57,
+ 58, 59, 60, 61, 57, 58, 64, 60, -1, 62,
+ -1, -1, 65, 66, -1, 68, -1, -1, 71, 1,
+ 73, 3, 4, -1, -1, 7, 8, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 19, -1, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, -1, -1, -1, 38, 39, -1, -1,
-1, 43, 44, 45, 46, -1, -1, -1, 50, 51,
-1, -1, -1, -1, -1, 57, 58, -1, 60, -1,
- 62, -1, -1, 65, 66, 67, 68, -1, 3, 4,
- -1, 73, 7, 8, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 19, -1, 21, 22, 23, -1,
- -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- -1, -1, -1, 38, 39, -1, -1, -1, 43, 44,
- 45, 46, -1, 3, 4, -1, 51, 7, 8, -1,
- -1, -1, 57, 58, -1, 60, -1, 62, -1, -1,
- 65, 66, -1, 68, -1, -1, 71, 1, 73, 3,
- 4, -1, -1, 7, 8, -1, -1, -1, 38, -1,
- -1, -1, -1, 43, 44, 45, 46, -1, -1, -1,
- -1, 51, -1, -1, -1, -1, -1, 57, 58, -1,
- 60, -1, 62, -1, 38, 65, 66, -1, 68, 43,
- 44, 45, 46, 73, -1, -1, -1, 51, -1, -1,
- -1, -1, -1, 57, 58, -1, 60, -1, 62, -1,
- -1, 65, 66, 67, 68, 1, -1, 3, 4, -1,
+ 62, -1, -1, 65, 66, -1, 68, -1, -1, 71,
+ 72, 73, 1, -1, 3, 4, -1, -1, 7, 8,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 19, -1, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, -1, -1, -1, 38,
+ 39, -1, -1, -1, 43, 44, 45, 46, -1, -1,
+ -1, 50, 51, -1, -1, -1, -1, -1, 57, 58,
+ -1, 60, -1, 62, -1, -1, 65, 66, -1, 68,
+ -1, -1, 71, 72, 73, 1, -1, 3, 4, -1,
-1, 7, 8, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 19, -1, 21, 22, 23, -1, -1,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, -1,
+ -1, -1, 38, 39, -1, -1, -1, 43, 44, 45,
+ 46, 1, -1, 3, 4, 51, -1, 7, 8, -1,
+ 10, 57, 58, -1, 60, -1, 62, -1, -1, 65,
+ 66, -1, 68, -1, -1, 71, 72, 73, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 38, -1,
+ -1, -1, -1, 43, 44, 45, 46, -1, -1, -1,
+ 50, 51, -1, -1, -1, -1, -1, 57, 58, -1,
+ 60, -1, 62, -1, -1, 65, 66, 67, 68, -1,
+ 3, 4, -1, 73, 7, 8, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 19, -1, 21, 22,
+ 23, -1, -1, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, -1, -1, -1, 38, 39, -1, -1, -1,
+ 43, 44, 45, 46, -1, 3, 4, -1, 51, 7,
+ 8, -1, -1, -1, 57, 58, -1, 60, -1, 62,
+ -1, -1, 65, 66, -1, 68, -1, -1, 71, 1,
+ 73, 3, 4, -1, -1, 7, 8, -1, -1, -1,
+ 38, -1, -1, -1, -1, 43, 44, 45, 46, -1,
+ -1, -1, -1, 51, -1, -1, -1, -1, -1, 57,
+ 58, -1, 60, -1, 62, -1, 38, 65, 66, -1,
+ 68, 43, 44, 45, 46, 73, -1, -1, -1, 51,
+ -1, -1, -1, -1, -1, 57, 58, -1, 60, -1,
+ 62, -1, -1, 65, 66, 67, 68, 1, -1, 3,
+ 4, -1, -1, 7, 8, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 1, -1, 3, 4, -1, -1, 7, 8, -1,
+ -1, -1, -1, 1, -1, 3, 4, -1, -1, 7,
+ 8, -1, -1, -1, 38, -1, -1, -1, -1, 43,
+ 44, 45, 46, -1, -1, -1, -1, 51, -1, -1,
+ -1, -1, -1, 57, 58, -1, 60, -1, 62, -1,
+ 38, 65, 66, -1, 68, 43, 44, 45, 46, -1,
+ 3, 4, -1, 51, 7, 8, -1, -1, -1, 57,
+ 58, -1, 60, -1, 62, -1, -1, 65, 66, 22,
+ 68, -1, -1, -1, -1, -1, -1, -1, 31, 32,
+ -1, -1, 3, 4, -1, 38, 7, 8, -1, -1,
+ 43, 44, 45, 46, -1, -1, -1, -1, 51, -1,
+ -1, 22, -1, -1, 57, 58, -1, 60, -1, 62,
+ 31, 32, 65, 66, -1, 68, -1, 38, -1, -1,
+ -1, -1, 43, 44, 45, 46, -1, 3, 4, -1,
+ 51, 7, 8, -1, -1, 11, 57, 58, -1, 60,
+ -1, 62, -1, -1, 65, 66, -1, 68, -1, -1,
+ -1, -1, -1, 3, 4, -1, -1, 7, 8, -1,
-1, -1, 38, -1, -1, -1, -1, 43, 44, 45,
46, -1, -1, -1, -1, 51, -1, -1, -1, -1,
-1, 57, 58, -1, 60, -1, 62, -1, 38, 65,
66, -1, 68, 43, 44, 45, 46, -1, 3, 4,
-1, 51, 7, 8, -1, -1, -1, 57, 58, -1,
- 60, -1, 62, -1, -1, 65, 66, 22, 68, -1,
- -1, -1, -1, -1, -1, -1, 31, 32, -1, -1,
- 3, 4, -1, 38, 7, 8, -1, -1, 43, 44,
- 45, 46, -1, -1, -1, -1, 51, -1, -1, 22,
- -1, -1, 57, 58, -1, 60, -1, 62, 31, 32,
- 65, 66, -1, 68, -1, 38, -1, -1, -1, -1,
- 43, 44, 45, 46, -1, 3, 4, -1, 51, 7,
- 8, -1, -1, 11, 57, 58, -1, 60, -1, 62,
- -1, -1, 65, 66, -1, 68, -1, -1, -1, -1,
- -1, 3, 4, -1, -1, 7, 8, -1, -1, -1,
- 38, -1, -1, -1, -1, 43, 44, 45, 46, -1,
- -1, -1, -1, 51, -1, -1, -1, -1, -1, 57,
- 58, -1, 60, -1, 62, -1, 38, 65, 66, -1,
- 68, 43, 44, 45, 46, -1, 3, 4, -1, 51,
- 7, 8, -1, -1, -1, 57, 58, -1, 60, -1,
- 62, -1, -1, 65, 66, -1, 68, -1, -1, -1,
+ 60, -1, 62, -1, -1, 65, 66, -1, 68, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 9, 43, 44, 45, 46,
- 14, 9, -1, -1, 51, -1, 14, -1, -1, -1,
- 57, 58, -1, 60, -1, 62, -1, -1, 65, 66,
- 9, 68, -1, -1, -1, 14, 40, 41, 42, -1,
- -1, -1, 40, 41, 42, -1, -1, -1, 52, -1,
- 9, 55, 56, -1, 52, 14, 54, 55, 56, -1,
- -1, 40, 41, 42, -1, -1, -1, -1, -1, 73,
- -1, -1, -1, 52, 53, -1, 55, 56, -1, -1,
- -1, 40, 41, 42, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 52, -1, -1, 55, 56
+ -1, -1, -1, -1, -1, -1, -1, 9, 43, 44,
+ 45, 46, 14, 9, -1, -1, 51, -1, 14, -1,
+ -1, -1, 57, 58, -1, 60, -1, 62, -1, -1,
+ 65, 66, -1, 68, -1, -1, -1, -1, 40, 41,
+ 42, -1, -1, -1, 40, 41, 42, -1, -1, -1,
+ 52, -1, 54, 55, 56, -1, 52, -1, -1, 55,
+ 56
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -1209,36 +1182,36 @@ static const yytype_uint8 yystos[] =
0, 75, 0, 1, 3, 4, 7, 8, 17, 18,
35, 36, 37, 38, 43, 44, 45, 46, 47, 50,
51, 57, 58, 60, 62, 65, 66, 68, 76, 78,
- 82, 84, 86, 104, 112, 116, 117, 118, 119, 120,
- 121, 129, 130, 66, 69, 126, 127, 128, 83, 122,
- 130, 130, 130, 66, 66, 68, 117, 130, 117, 117,
- 66, 119, 130, 1, 111, 112, 48, 121, 71, 73,
- 79, 88, 104, 132, 136, 79, 85, 50, 9, 14,
- 40, 41, 42, 52, 54, 55, 56, 114, 115, 11,
- 117, 57, 58, 59, 60, 61, 64, 57, 58, 59,
- 60, 61, 64, 12, 13, 43, 44, 51, 113, 110,
- 111, 112, 111, 16, 126, 3, 4, 45, 46, 68,
- 80, 81, 55, 106, 110, 110, 112, 43, 44, 131,
- 1, 54, 67, 134, 138, 134, 1, 6, 77, 104,
- 105, 87, 105, 5, 112, 129, 112, 112, 112, 105,
- 112, 38, 117, 117, 117, 117, 117, 117, 117, 117,
- 117, 117, 117, 117, 13, 112, 134, 70, 49, 66,
- 117, 134, 134, 112, 105, 40, 1, 112, 1, 88,
- 1, 19, 21, 22, 23, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, 39, 72, 89, 90, 92, 99,
- 103, 112, 132, 133, 136, 53, 112, 122, 1, 4,
- 107, 108, 129, 66, 91, 4, 66, 66, 66, 105,
- 66, 88, 88, 88, 109, 112, 88, 105, 88, 93,
- 87, 135, 136, 105, 112, 134, 1, 138, 112, 109,
- 94, 4, 112, 112, 89, 4, 92, 95, 88, 66,
- 100, 110, 133, 105, 105, 1, 4, 134, 88, 123,
- 124, 125, 126, 67, 134, 134, 26, 40, 136, 111,
- 10, 101, 105, 16, 125, 105, 105, 66, 129, 105,
- 134, 102, 89, 132, 89, 112, 134, 112, 136, 116,
- 20, 96, 134, 105, 136, 105, 105, 1, 24, 25,
- 97, 105, 105, 89, 105, 95, 89, 7, 8, 57,
- 58, 84, 98, 53, 137, 133, 95, 134, 7, 7,
- 137, 105, 134, 105, 105, 87, 105, 89, 87, 89
+ 82, 83, 85, 103, 111, 115, 116, 117, 118, 119,
+ 120, 128, 129, 66, 69, 125, 126, 127, 3, 4,
+ 45, 46, 68, 80, 81, 121, 129, 129, 129, 66,
+ 66, 68, 116, 129, 116, 116, 66, 118, 129, 1,
+ 110, 111, 48, 120, 71, 73, 79, 87, 103, 131,
+ 135, 79, 84, 50, 9, 14, 40, 41, 42, 52,
+ 54, 55, 56, 113, 114, 11, 116, 57, 58, 59,
+ 60, 61, 64, 57, 58, 59, 60, 61, 64, 12,
+ 13, 43, 44, 51, 112, 109, 110, 111, 110, 16,
+ 125, 49, 66, 55, 105, 109, 109, 111, 43, 44,
+ 130, 1, 54, 67, 133, 137, 133, 1, 6, 77,
+ 103, 104, 86, 104, 5, 111, 128, 111, 111, 111,
+ 104, 111, 38, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 13, 111, 133, 70, 1,
+ 4, 106, 107, 116, 133, 133, 111, 104, 40, 1,
+ 111, 1, 87, 1, 19, 21, 22, 23, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 39, 72, 88,
+ 89, 91, 98, 102, 111, 131, 132, 135, 53, 111,
+ 121, 133, 1, 137, 128, 66, 90, 4, 66, 66,
+ 66, 104, 66, 87, 87, 87, 108, 111, 87, 104,
+ 87, 92, 86, 134, 135, 104, 111, 104, 1, 4,
+ 111, 108, 93, 4, 111, 111, 88, 4, 91, 94,
+ 87, 66, 99, 109, 132, 104, 133, 87, 122, 123,
+ 124, 125, 67, 133, 133, 26, 40, 135, 110, 10,
+ 100, 104, 16, 124, 104, 104, 66, 128, 104, 133,
+ 101, 88, 131, 88, 111, 133, 111, 135, 115, 20,
+ 95, 133, 104, 135, 104, 104, 1, 24, 25, 96,
+ 104, 104, 88, 104, 94, 88, 7, 8, 57, 58,
+ 83, 97, 53, 136, 132, 94, 133, 7, 7, 136,
+ 104, 133, 104, 104, 86, 104, 88, 86, 88
};
#define yyerrok (yyerrstatus = 0)
@@ -2065,8 +2038,8 @@ yyreduce:
{
case 3:
-/* Line 1806 of yacc.c */
-#line 221 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 194 "awkgram.y"
{
rule = 0;
yyerrok;
@@ -2075,8 +2048,8 @@ yyreduce:
case 5:
-/* Line 1806 of yacc.c */
-#line 227 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 200 "awkgram.y"
{
next_sourcefile();
}
@@ -2084,8 +2057,8 @@ yyreduce:
case 6:
-/* Line 1806 of yacc.c */
-#line 231 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 204 "awkgram.y"
{
rule = 0;
/*
@@ -2098,8 +2071,8 @@ yyreduce:
case 7:
-/* Line 1806 of yacc.c */
-#line 243 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 216 "awkgram.y"
{
(void) append_rule((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
}
@@ -2107,8 +2080,8 @@ yyreduce:
case 8:
-/* Line 1806 of yacc.c */
-#line 247 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 220 "awkgram.y"
{
if (rule != Rule) {
msg(_("%s blocks must have an action part"),
ruletab[rule]);
@@ -2123,21 +2096,19 @@ yyreduce:
case 9:
-/* Line 1806 of yacc.c */
-#line 258 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 231 "awkgram.y"
{
can_return = FALSE;
- if ((yyvsp[(1) - (2)]) && func_install((yyvsp[(1) - (2)]),
(yyvsp[(2) - (2)])) < 0)
- YYABORT;
- func_params = NULL;
+ (void) mk_function((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
yyerrok;
}
break;
case 10:
-/* Line 1806 of yacc.c */
-#line 266 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 237 "awkgram.y"
{
want_source = FALSE;
yyerrok;
@@ -2146,8 +2117,8 @@ yyreduce:
case 11:
-/* Line 1806 of yacc.c */
-#line 274 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 245 "awkgram.y"
{
if (include_source((yyvsp[(1) - (1)])) < 0)
YYABORT;
@@ -2159,36 +2130,36 @@ yyreduce:
case 12:
-/* Line 1806 of yacc.c */
-#line 282 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 253 "awkgram.y"
{ (yyval) = NULL; }
break;
case 13:
-/* Line 1806 of yacc.c */
-#line 284 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 255 "awkgram.y"
{ (yyval) = NULL; }
break;
case 14:
-/* Line 1806 of yacc.c */
-#line 289 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 260 "awkgram.y"
{ (yyval) = NULL; rule = Rule; }
break;
case 15:
-/* Line 1806 of yacc.c */
-#line 291 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 262 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); rule = Rule; }
break;
case 16:
-/* Line 1806 of yacc.c */
-#line 293 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 264 "awkgram.y"
{
INSTRUCTION *tp;
@@ -2218,8 +2189,8 @@ yyreduce:
case 17:
-/* Line 1806 of yacc.c */
-#line 319 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 290 "awkgram.y"
{
static int begin_seen = 0;
if (do_lint_old && ++begin_seen == 2)
@@ -2234,8 +2205,8 @@ yyreduce:
case 18:
-/* Line 1806 of yacc.c */
-#line 330 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 301 "awkgram.y"
{
static int end_seen = 0;
if (do_lint_old && ++end_seen == 2)
@@ -2250,8 +2221,8 @@ yyreduce:
case 19:
-/* Line 1806 of yacc.c */
-#line 341 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 312 "awkgram.y"
{
(yyvsp[(1) - (1)])->in_rule = rule = BEGINFILE;
(yyvsp[(1) - (1)])->source_file = source;
@@ -2261,8 +2232,8 @@ yyreduce:
case 20:
-/* Line 1806 of yacc.c */
-#line 347 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 318 "awkgram.y"
{
(yyvsp[(1) - (1)])->in_rule = rule = ENDFILE;
(yyvsp[(1) - (1)])->source_file = source;
@@ -2272,8 +2243,8 @@ yyreduce:
case 21:
-/* Line 1806 of yacc.c */
-#line 356 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 327 "awkgram.y"
{
if ((yyvsp[(2) - (5)]) == NULL)
(yyval) = list_create(instruction(Op_no_op));
@@ -2284,90 +2255,70 @@ yyreduce:
case 22:
-/* Line 1806 of yacc.c */
-#line 366 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 337 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 23:
-/* Line 1806 of yacc.c */
-#line 368 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 339 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 24:
-/* Line 1806 of yacc.c */
-#line 370 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 341 "awkgram.y"
{
yyerror(_("`%s' is a built-in function, it cannot be
redefined"),
- tokstart);
- (yyvsp[(1) - (1)])->opcode = Op_symbol; /* Op_symbol instead of
Op_token so that
- * free_bc_internal does not try to
free it
- */
- (yyvsp[(1) - (1)])->lextok = builtin_func;
- (yyval) = (yyvsp[(1) - (1)]);
- /* yyerrok; */
+ tokstart);
+ YYABORT;
}
break;
case 25:
-/* Line 1806 of yacc.c */
-#line 381 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 347 "awkgram.y"
{ (yyval) = (yyvsp[(2) - (2)]); }
break;
case 28:
-/* Line 1806 of yacc.c */
-#line 391 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 357 "awkgram.y"
{
- param_counter = 0;
- func_params = NULL;
+ (yyvsp[(1) - (6)])->source_file = source;
+ if (install_function((yyvsp[(2) - (6)])->lextok, (yyvsp[(1) -
(6)]), (yyvsp[(4) - (6)])) < 0)
+ YYABORT;
+ (yyvsp[(2) - (6)])->lextok = NULL;
+ bcfree((yyvsp[(2) - (6)]));
+ /* $4 already free'd in install_function */
+ (yyval) = (yyvsp[(1) - (6)]);
+ can_return = TRUE;
}
break;
case 29:
-/* Line 1806 of yacc.c */
-#line 396 "awkgram.y"
- {
- NODE *t;
-
- (yyvsp[(1) - (7)])->source_file = source;
- t = make_param((yyvsp[(3) - (7)])->lextok);
- (yyvsp[(3) - (7)])->lextok = NULL;
- bcfree((yyvsp[(3) - (7)]));
- t->flags |= FUNC;
- t->rnode = func_params;
- func_params = t;
- (yyval) = (yyvsp[(1) - (7)]);
- can_return = TRUE;
- /* check for duplicate parameter names */
- if (dup_parms((yyvsp[(1) - (7)]), t))
- errcount++;
- }
- break;
-
- case 30:
-
-/* Line 1806 of yacc.c */
-#line 420 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 375 "awkgram.y"
{ ++want_regexp; }
break;
- case 31:
+ case 30:
-/* Line 1806 of yacc.c */
-#line 422 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 377 "awkgram.y"
{
NODE *n, *exp;
char *re;
size_t len;
re = (yyvsp[(3) - (3)])->lextok;
+ (yyvsp[(3) - (3)])->lextok = NULL;
len = strlen(re);
if (do_lint) {
if (len == 0)
@@ -2379,7 +2330,7 @@ yyreduce:
_("regexp constant `/%s/' looks like a
C comment, but is not"), re);
}
- exp = make_str_node(re, len, ALREADY_MALLOCED);
+ exp = make_str_node(re, len);
n = make_regnode(Node_regex, exp);
if (n == NULL) {
unref(exp);
@@ -2391,24 +2342,24 @@ yyreduce:
}
break;
- case 32:
+ case 31:
-/* Line 1806 of yacc.c */
-#line 453 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 409 "awkgram.y"
{ bcfree((yyvsp[(1) - (1)])); }
break;
- case 34:
+ case 33:
-/* Line 1806 of yacc.c */
-#line 459 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 415 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 35:
+ case 34:
-/* Line 1806 of yacc.c */
-#line 461 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 417 "awkgram.y"
{
if ((yyvsp[(2) - (2)]) == NULL)
(yyval) = (yyvsp[(1) - (2)]);
@@ -2423,31 +2374,31 @@ yyreduce:
}
break;
- case 36:
+ case 35:
-/* Line 1806 of yacc.c */
-#line 474 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 430 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 39:
+ case 38:
-/* Line 1806 of yacc.c */
-#line 484 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 440 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 40:
+ case 39:
-/* Line 1806 of yacc.c */
-#line 486 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 442 "awkgram.y"
{ (yyval) = (yyvsp[(2) - (3)]); }
break;
- case 41:
+ case 40:
-/* Line 1806 of yacc.c */
-#line 488 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 444 "awkgram.y"
{
if (do_profiling)
(yyval) = list_prepend((yyvsp[(1) - (1)]),
instruction(Op_exec_count));
@@ -2456,10 +2407,10 @@ yyreduce:
}
break;
- case 42:
+ case 41:
-/* Line 1806 of yacc.c */
-#line 495 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 451 "awkgram.y"
{
INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt;
INSTRUCTION *ip, *nextc, *tbreak;
@@ -2551,10 +2502,10 @@ yyreduce:
}
break;
- case 43:
+ case 42:
-/* Line 1806 of yacc.c */
-#line 585 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 541 "awkgram.y"
{
/*
* -----------------
@@ -2598,10 +2549,10 @@ yyreduce:
}
break;
- case 44:
+ case 43:
-/* Line 1806 of yacc.c */
-#line 627 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 583 "awkgram.y"
{
/*
* -----------------
@@ -2645,10 +2596,10 @@ yyreduce:
}
break;
- case 45:
+ case 44:
-/* Line 1806 of yacc.c */
-#line 669 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 625 "awkgram.y"
{
INSTRUCTION *ip;
char *var_name = (yyvsp[(3) - (8)])->lextok;
@@ -2715,7 +2666,7 @@ regular_loop:
tbreak = instruction(Op_arrayfor_final);
(yyvsp[(4) - (8)])->opcode = Op_arrayfor_incr;
- (yyvsp[(4) - (8)])->array_var = variable(var_name,
Node_var);
+ (yyvsp[(4) - (8)])->array_var = variable((yyvsp[(3) -
(8)])->source_line, var_name, Node_var);
(yyvsp[(4) - (8)])->target_jmp = tbreak;
tcont = (yyvsp[(4) - (8)]);
(yyvsp[(3) - (8)])->opcode = Op_arrayfor_init;
@@ -2765,10 +2716,10 @@ regular_loop:
}
break;
- case 46:
+ case 45:
-/* Line 1806 of yacc.c */
-#line 784 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 740 "awkgram.y"
{
(yyval) = mk_for_loop((yyvsp[(1) - (12)]), (yyvsp[(3) - (12)]),
(yyvsp[(6) - (12)]), (yyvsp[(9) - (12)]), (yyvsp[(12) - (12)]));
@@ -2777,10 +2728,10 @@ regular_loop:
}
break;
- case 47:
+ case 46:
-/* Line 1806 of yacc.c */
-#line 791 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 747 "awkgram.y"
{
(yyval) = mk_for_loop((yyvsp[(1) - (11)]), (yyvsp[(3) - (11)]),
(INSTRUCTION *) NULL, (yyvsp[(8) - (11)]), (yyvsp[(11) - (11)]));
@@ -2789,10 +2740,10 @@ regular_loop:
}
break;
- case 48:
+ case 47:
-/* Line 1806 of yacc.c */
-#line 798 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 754 "awkgram.y"
{
if (do_profiling)
(yyval) = list_prepend((yyvsp[(1) - (1)]),
instruction(Op_exec_count));
@@ -2801,10 +2752,10 @@ regular_loop:
}
break;
- case 49:
+ case 48:
-/* Line 1806 of yacc.c */
-#line 808 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 764 "awkgram.y"
{
if (! break_allowed)
error_ln((yyvsp[(1) - (2)])->source_line,
@@ -2815,10 +2766,10 @@ regular_loop:
}
break;
- case 50:
+ case 49:
-/* Line 1806 of yacc.c */
-#line 817 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 773 "awkgram.y"
{
if (! continue_allowed)
error_ln((yyvsp[(1) - (2)])->source_line,
@@ -2829,10 +2780,10 @@ regular_loop:
}
break;
- case 51:
+ case 50:
-/* Line 1806 of yacc.c */
-#line 826 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 782 "awkgram.y"
{
/* if inside function (rule = 0), resolve context at run-time */
if (rule && rule != Rule)
@@ -2843,10 +2794,10 @@ regular_loop:
}
break;
- case 52:
+ case 51:
-/* Line 1806 of yacc.c */
-#line 835 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 791 "awkgram.y"
{
if (do_traditional)
error_ln((yyvsp[(1) - (2)])->source_line,
@@ -2863,10 +2814,10 @@ regular_loop:
}
break;
- case 53:
+ case 52:
-/* Line 1806 of yacc.c */
-#line 850 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 806 "awkgram.y"
{
/* Initialize the two possible jump targets, the actual target
* is resolved at run-time.
@@ -2877,47 +2828,47 @@ regular_loop:
if ((yyvsp[(2) - (3)]) == NULL) {
(yyval) = list_create((yyvsp[(1) - (3)]));
(void) list_prepend((yyval), instruction(Op_push_i));
- (yyval)->nexti->memory = Nnull_string;
+ (yyval)->nexti->memory = dupnode(Nnull_string);
} else
(yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) -
(3)]));
}
break;
- case 54:
+ case 53:
-/* Line 1806 of yacc.c */
-#line 865 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 821 "awkgram.y"
{
if (! can_return)
yyerror(_("`return' used outside function context"));
}
break;
- case 55:
+ case 54:
-/* Line 1806 of yacc.c */
-#line 868 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 824 "awkgram.y"
{
if ((yyvsp[(3) - (4)]) == NULL) {
(yyval) = list_create((yyvsp[(1) - (4)]));
(void) list_prepend((yyval), instruction(Op_push_i));
- (yyval)->nexti->memory = Nnull_string;
+ (yyval)->nexti->memory = dupnode(Nnull_string);
} else
(yyval) = list_append((yyvsp[(3) - (4)]), (yyvsp[(1) -
(4)]));
}
break;
- case 57:
+ case 56:
-/* Line 1806 of yacc.c */
-#line 888 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 844 "awkgram.y"
{ in_print = TRUE; in_parens = 0; }
break;
- case 58:
+ case 57:
-/* Line 1806 of yacc.c */
-#line 889 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 845 "awkgram.y"
{
/*
* Optimization: plain `print' has no expression list, so $3 is
null.
@@ -2926,13 +2877,13 @@ regular_loop:
*/
if ((yyvsp[(1) - (4)])->opcode == Op_K_print &&
- ((yyvsp[(3) - (4)]) == NULL
- || ((yyvsp[(3) - (4)])->lasti->opcode
== Op_field_spec
- && (yyvsp[(3) -
(4)])->nexti->nexti->nexti == (yyvsp[(3) - (4)])->lasti
- && (yyvsp[(3) -
(4)])->nexti->nexti->opcode == Op_push_i
- && (yyvsp[(3) -
(4)])->nexti->nexti->memory->type == Node_val
- && (yyvsp[(3) -
(4)])->nexti->nexti->memory->numbr == 0.0)
- )
+ ((yyvsp[(3) - (4)]) == NULL
+ || ((yyvsp[(3) - (4)])->lasti->opcode ==
Op_field_spec
+ && (yyvsp[(3) -
(4)])->nexti->nexti->nexti == (yyvsp[(3) - (4)])->lasti
+ && (yyvsp[(3) -
(4)])->nexti->nexti->opcode == Op_push_i
+ && (yyvsp[(3) -
(4)])->nexti->nexti->memory->type == Node_val
+ && (yyvsp[(3) -
(4)])->nexti->nexti->memory->numbr == 0.0)
+ )
) {
static short warned = FALSE;
/* -----------------
@@ -2946,8 +2897,6 @@ regular_loop:
if ((yyvsp[(3) - (4)]) != NULL) {
bcfree((yyvsp[(3) - (4)])->lasti);
/* Op_field_spec */
- (yyvsp[(3) - (4)])->nexti->nexti->memory->flags
&= ~PERM;
- (yyvsp[(3) - (4)])->nexti->nexti->memory->flags
|= MALLOC;
unref((yyvsp[(3) -
(4)])->nexti->nexti->memory); /* Node_val */
bcfree((yyvsp[(3) - (4)])->nexti->nexti);
/* Op_push_i */
bcfree((yyvsp[(3) - (4)])->nexti);
/* Op_list */
@@ -3014,22 +2963,22 @@ regular_loop:
}
break;
- case 59:
+ case 58:
-/* Line 1806 of yacc.c */
-#line 984 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 938 "awkgram.y"
{ sub_counter = 0; }
break;
- case 60:
+ case 59:
-/* Line 1806 of yacc.c */
-#line 985 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 939 "awkgram.y"
{
char *arr = (yyvsp[(2) - (4)])->lextok;
(yyvsp[(2) - (4)])->opcode = Op_push_array;
- (yyvsp[(2) - (4)])->memory = variable(arr, Node_var_new);
+ (yyvsp[(2) - (4)])->memory = variable((yyvsp[(2) -
(4)])->source_line, arr, Node_var_new);
if ((yyvsp[(4) - (4)]) == NULL) {
static short warned = FALSE;
@@ -3051,10 +3000,10 @@ regular_loop:
}
break;
- case 61:
+ case 60:
-/* Line 1806 of yacc.c */
-#line 1014 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 968 "awkgram.y"
{
static short warned = FALSE;
char *arr = (yyvsp[(3) - (4)])->lextok;
@@ -3068,45 +3017,45 @@ regular_loop:
error_ln((yyvsp[(1) - (4)])->source_line,
_("`delete array' is a gawk extension"));
}
- (yyvsp[(3) - (4)])->memory = variable(arr, Node_var_new);
+ (yyvsp[(3) - (4)])->memory = variable((yyvsp[(3) -
(4)])->source_line, arr, Node_var_new);
(yyvsp[(3) - (4)])->opcode = Op_push_array;
(yyvsp[(1) - (4)])->expr_count = 0;
(yyval) = list_append(list_create((yyvsp[(3) - (4)])),
(yyvsp[(1) - (4)]));
}
break;
- case 62:
+ case 61:
-/* Line 1806 of yacc.c */
-#line 1033 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 987 "awkgram.y"
{ (yyval) = optimize_assignment((yyvsp[(1) - (1)])); }
break;
- case 63:
+ case 62:
-/* Line 1806 of yacc.c */
-#line 1038 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 992 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 64:
+ case 63:
-/* Line 1806 of yacc.c */
-#line 1040 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 994 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 65:
+ case 64:
-/* Line 1806 of yacc.c */
-#line 1045 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 999 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 66:
+ case 65:
-/* Line 1806 of yacc.c */
-#line 1047 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1001 "awkgram.y"
{
if ((yyvsp[(1) - (2)]) == NULL)
(yyval) = list_create((yyvsp[(2) - (2)]));
@@ -3115,17 +3064,17 @@ regular_loop:
}
break;
- case 67:
+ case 66:
-/* Line 1806 of yacc.c */
-#line 1054 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1008 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 68:
+ case 67:
-/* Line 1806 of yacc.c */
-#line 1059 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1013 "awkgram.y"
{
INSTRUCTION *casestmt = (yyvsp[(5) - (5)]);
if ((yyvsp[(5) - (5)]) == NULL)
@@ -3139,10 +3088,10 @@ regular_loop:
}
break;
- case 69:
+ case 68:
-/* Line 1806 of yacc.c */
-#line 1071 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1025 "awkgram.y"
{
INSTRUCTION *casestmt = (yyvsp[(4) - (4)]);
if ((yyvsp[(4) - (4)]) == NULL)
@@ -3155,17 +3104,17 @@ regular_loop:
}
break;
- case 70:
+ case 69:
-/* Line 1806 of yacc.c */
-#line 1085 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1039 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 71:
+ case 70:
-/* Line 1806 of yacc.c */
-#line 1087 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1041 "awkgram.y"
{
(yyvsp[(2) - (2)])->memory->numbr = -(force_number((yyvsp[(2) -
(2)])->memory));
bcfree((yyvsp[(1) - (2)]));
@@ -3173,60 +3122,60 @@ regular_loop:
}
break;
- case 72:
+ case 71:
-/* Line 1806 of yacc.c */
-#line 1093 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1047 "awkgram.y"
{
bcfree((yyvsp[(1) - (2)]));
(yyval) = (yyvsp[(2) - (2)]);
}
break;
- case 73:
+ case 72:
-/* Line 1806 of yacc.c */
-#line 1098 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1052 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 74:
+ case 73:
-/* Line 1806 of yacc.c */
-#line 1100 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1054 "awkgram.y"
{
(yyvsp[(1) - (1)])->opcode = Op_push_re;
(yyval) = (yyvsp[(1) - (1)]);
}
break;
- case 75:
+ case 74:
-/* Line 1806 of yacc.c */
-#line 1108 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1062 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 76:
+ case 75:
-/* Line 1806 of yacc.c */
-#line 1110 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1064 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 78:
+ case 77:
-/* Line 1806 of yacc.c */
-#line 1120 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1074 "awkgram.y"
{
(yyval) = (yyvsp[(2) - (3)]);
}
break;
- case 79:
+ case 78:
-/* Line 1806 of yacc.c */
-#line 1127 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1081 "awkgram.y"
{
in_print = FALSE;
in_parens = 0;
@@ -3234,17 +3183,17 @@ regular_loop:
}
break;
- case 80:
+ case 79:
-/* Line 1806 of yacc.c */
-#line 1132 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1086 "awkgram.y"
{ in_print = FALSE; in_parens = 0; }
break;
- case 81:
+ case 80:
-/* Line 1806 of yacc.c */
-#line 1133 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1087 "awkgram.y"
{
if ((yyvsp[(1) - (3)])->redir_type == redirect_twoway
&& (yyvsp[(3) - (3)])->lasti->opcode ==
Op_K_getline_redir
@@ -3254,162 +3203,174 @@ regular_loop:
}
break;
- case 82:
+ case 81:
-/* Line 1806 of yacc.c */
-#line 1144 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1098 "awkgram.y"
{
(yyval) = mk_condition((yyvsp[(3) - (6)]), (yyvsp[(1) - (6)]),
(yyvsp[(6) - (6)]), NULL, NULL);
}
break;
- case 83:
+ case 82:
-/* Line 1806 of yacc.c */
-#line 1149 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1103 "awkgram.y"
{
(yyval) = mk_condition((yyvsp[(3) - (9)]), (yyvsp[(1) - (9)]),
(yyvsp[(6) - (9)]), (yyvsp[(7) - (9)]), (yyvsp[(9) - (9)]));
}
break;
- case 88:
+ case 87:
-/* Line 1806 of yacc.c */
-#line 1166 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1120 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 89:
+ case 88:
-/* Line 1806 of yacc.c */
-#line 1168 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1122 "awkgram.y"
{
bcfree((yyvsp[(1) - (2)]));
(yyval) = (yyvsp[(2) - (2)]);
}
break;
- case 92:
+ case 89:
-/* Line 1806 of yacc.c */
-#line 1181 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1130 "awkgram.y"
+ { (yyval) = NULL; }
+ break;
+
+ case 90:
+
+/* Line 1821 of yacc.c */
+#line 1132 "awkgram.y"
+ { (yyval) = (yyvsp[(1) - (1)]) ; }
+ break;
+
+ case 91:
+
+/* Line 1821 of yacc.c */
+#line 1137 "awkgram.y"
{
- append_param((yyvsp[(1) - (1)])->lextok);
- (yyvsp[(1) - (1)])->lextok = NULL;
- bcfree((yyvsp[(1) - (1)]));
+ (yyvsp[(1) - (1)])->param_count = 0;
+ (yyval) = list_create((yyvsp[(1) - (1)]));
}
break;
- case 93:
+ case 92:
-/* Line 1806 of yacc.c */
-#line 1187 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1142 "awkgram.y"
{
- append_param((yyvsp[(3) - (3)])->lextok);
- (yyvsp[(3) - (3)])->lextok = NULL;
- bcfree((yyvsp[(3) - (3)]));
+ (yyvsp[(3) - (3)])->param_count = (yyvsp[(1) -
(3)])->lasti->param_count + 1;
+ (yyval) = list_append((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]));
yyerrok;
}
break;
- case 94:
+ case 93:
-/* Line 1806 of yacc.c */
-#line 1194 "awkgram.y"
- { /* func_params = NULL; */ }
+/* Line 1821 of yacc.c */
+#line 1148 "awkgram.y"
+ { (yyval) = NULL; }
break;
- case 95:
+ case 94:
-/* Line 1806 of yacc.c */
-#line 1196 "awkgram.y"
- { /* func_params = NULL; */ }
+/* Line 1821 of yacc.c */
+#line 1150 "awkgram.y"
+ { (yyval) = (yyvsp[(1) - (2)]); }
break;
- case 96:
+ case 95:
-/* Line 1806 of yacc.c */
-#line 1198 "awkgram.y"
- { /* func_params = NULL; */ }
+/* Line 1821 of yacc.c */
+#line 1152 "awkgram.y"
+ { (yyval) = (yyvsp[(1) - (3)]); }
break;
- case 97:
+ case 96:
-/* Line 1806 of yacc.c */
-#line 1204 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1158 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 98:
+ case 97:
-/* Line 1806 of yacc.c */
-#line 1206 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1160 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 99:
+ case 98:
-/* Line 1806 of yacc.c */
-#line 1211 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1165 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 100:
+ case 99:
-/* Line 1806 of yacc.c */
-#line 1213 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1167 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 101:
+ case 100:
-/* Line 1806 of yacc.c */
-#line 1218 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1172 "awkgram.y"
{ (yyval) = mk_expression_list(NULL, (yyvsp[(1) - (1)])); }
break;
- case 102:
+ case 101:
-/* Line 1806 of yacc.c */
-#line 1220 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1174 "awkgram.y"
{
(yyval) = mk_expression_list((yyvsp[(1) - (3)]), (yyvsp[(3) -
(3)]));
yyerrok;
}
break;
- case 103:
+ case 102:
-/* Line 1806 of yacc.c */
-#line 1225 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1179 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 104:
+ case 103:
-/* Line 1806 of yacc.c */
-#line 1227 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1181 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 105:
+ case 104:
-/* Line 1806 of yacc.c */
-#line 1229 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1183 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 106:
+ case 105:
-/* Line 1806 of yacc.c */
-#line 1231 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1185 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 107:
+ case 106:
-/* Line 1806 of yacc.c */
-#line 1237 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1191 "awkgram.y"
{
if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode ==
Op_match_rec)
lintwarn_ln((yyvsp[(2) - (3)])->source_line,
@@ -3418,24 +3379,24 @@ regular_loop:
}
break;
- case 108:
+ case 107:
-/* Line 1806 of yacc.c */
-#line 1244 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1198 "awkgram.y"
{ (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2)
- (3)])); }
break;
- case 109:
+ case 108:
-/* Line 1806 of yacc.c */
-#line 1246 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1200 "awkgram.y"
{ (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2)
- (3)])); }
break;
- case 110:
+ case 109:
-/* Line 1806 of yacc.c */
-#line 1248 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1202 "awkgram.y"
{
if ((yyvsp[(1) - (3)])->lasti->opcode == Op_match_rec)
warning_ln((yyvsp[(2) - (3)])->source_line,
@@ -3453,13 +3414,13 @@ regular_loop:
}
break;
- case 111:
+ case 110:
-/* Line 1806 of yacc.c */
-#line 1264 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1218 "awkgram.y"
{
if (do_lint_old)
- warning_ln((yyvsp[(2) - (3)])->source_line,
+ warning_ln((yyvsp[(2) - (3)])->source_line,
_("old awk does not support the keyword `in'
except after `for'"));
(yyvsp[(3) - (3)])->nexti->opcode = Op_push_array;
(yyvsp[(2) - (3)])->opcode = Op_in_array;
@@ -3468,10 +3429,10 @@ regular_loop:
}
break;
- case 112:
+ case 111:
-/* Line 1806 of yacc.c */
-#line 1274 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1228 "awkgram.y"
{
if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode ==
Op_match_rec)
lintwarn_ln((yyvsp[(2) - (3)])->source_line,
@@ -3480,90 +3441,90 @@ regular_loop:
}
break;
- case 113:
+ case 112:
-/* Line 1806 of yacc.c */
-#line 1281 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1235 "awkgram.y"
{ (yyval) = mk_condition((yyvsp[(1) - (5)]), (yyvsp[(2) - (5)]),
(yyvsp[(3) - (5)]), (yyvsp[(4) - (5)]), (yyvsp[(5) - (5)])); }
break;
- case 114:
+ case 113:
-/* Line 1806 of yacc.c */
-#line 1283 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1237 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 115:
+ case 114:
-/* Line 1806 of yacc.c */
-#line 1288 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1242 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 116:
+ case 115:
-/* Line 1806 of yacc.c */
-#line 1290 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1244 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 117:
+ case 116:
-/* Line 1806 of yacc.c */
-#line 1292 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1246 "awkgram.y"
{
(yyvsp[(2) - (2)])->opcode = Op_assign_quotient;
(yyval) = (yyvsp[(2) - (2)]);
}
break;
+ case 117:
+
+/* Line 1821 of yacc.c */
+#line 1254 "awkgram.y"
+ { (yyval) = (yyvsp[(1) - (1)]); }
+ break;
+
case 118:
-/* Line 1806 of yacc.c */
-#line 1300 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1256 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 119:
-/* Line 1806 of yacc.c */
-#line 1302 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1261 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 120:
-/* Line 1806 of yacc.c */
-#line 1307 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1263 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 121:
-/* Line 1806 of yacc.c */
-#line 1309 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1268 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 122:
-/* Line 1806 of yacc.c */
-#line 1314 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1270 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 123:
-/* Line 1806 of yacc.c */
-#line 1316 "awkgram.y"
- { (yyval) = (yyvsp[(1) - (1)]); }
- break;
-
- case 124:
-
-/* Line 1806 of yacc.c */
-#line 1318 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1272 "awkgram.y"
{
int count = 2;
int is_simple_var = FALSE;
@@ -3575,32 +3536,29 @@ regular_loop:
(yyvsp[(1) - (2)])->lasti->opcode = Op_no_op;
} else {
is_simple_var = ((yyvsp[(1) - (2)])->nexti->opcode ==
Op_push
- && (yyvsp[(1) - (2)])->lasti ==
(yyvsp[(1) - (2)])->nexti); /* first exp. is a simple
- *
variable?; kludge for use
- *
in Op_assign_concat.
- */
+ && (yyvsp[(1) - (2)])->lasti ==
(yyvsp[(1) - (2)])->nexti); /* first exp. is a simple
+ *
variable?; kludge for use
+ * in
Op_assign_concat.
+ */
}
if (do_optimize > 1
- && (yyvsp[(1) - (2)])->nexti == (yyvsp[(1) -
(2)])->lasti && (yyvsp[(1) - (2)])->nexti->opcode == Op_push_i
- && (yyvsp[(2) - (2)])->nexti == (yyvsp[(2) -
(2)])->lasti && (yyvsp[(2) - (2)])->nexti->opcode == Op_push_i
+ && (yyvsp[(1) - (2)])->nexti == (yyvsp[(1) -
(2)])->lasti && (yyvsp[(1) - (2)])->nexti->opcode == Op_push_i
+ && (yyvsp[(2) - (2)])->nexti == (yyvsp[(2) -
(2)])->lasti && (yyvsp[(2) - (2)])->nexti->opcode == Op_push_i
) {
NODE *n1 = (yyvsp[(1) - (2)])->nexti->memory;
NODE *n2 = (yyvsp[(2) - (2)])->nexti->memory;
size_t nlen;
- (void) force_string(n1);
- (void) force_string(n2);
+ n1 = force_string(n1);
+ n2 = force_string(n2);
nlen = n1->stlen + n2->stlen;
erealloc(n1->stptr, char *, nlen + 2, "constant fold");
memcpy(n1->stptr + n1->stlen, n2->stptr, n2->stlen);
n1->stlen = nlen;
n1->stptr[nlen] = '\0';
- n1->flags &= ~(NUMCUR|NUMBER);
+ n1->flags &= ~(NUMCUR|NUMBER|NUMINT);
n1->flags |= (STRING|STRCUR);
-
- n2->flags &= ~PERM;
- n2->flags |= MALLOC;
unref(n2);
bcfree((yyvsp[(2) - (2)])->nexti);
bcfree((yyvsp[(2) - (2)]));
@@ -3615,52 +3573,52 @@ regular_loop:
}
break;
+ case 125:
+
+/* Line 1821 of yacc.c */
+#line 1324 "awkgram.y"
+ { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
+ break;
+
case 126:
-/* Line 1806 of yacc.c */
-#line 1373 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1326 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 127:
-/* Line 1806 of yacc.c */
-#line 1375 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1328 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 128:
-/* Line 1806 of yacc.c */
-#line 1377 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1330 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 129:
-/* Line 1806 of yacc.c */
-#line 1379 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1332 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 130:
-/* Line 1806 of yacc.c */
-#line 1381 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1334 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 131:
-/* Line 1806 of yacc.c */
-#line 1383 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
- break;
-
- case 132:
-
-/* Line 1806 of yacc.c */
-#line 1385 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1336 "awkgram.y"
{
/*
* In BEGINFILE/ENDFILE, allow `getline var < file'
@@ -3685,30 +3643,30 @@ regular_loop:
}
break;
- case 133:
+ case 132:
-/* Line 1806 of yacc.c */
-#line 1408 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1359 "awkgram.y"
{
(yyvsp[(2) - (2)])->opcode = Op_postincrement;
(yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) -
(2)]));
}
break;
- case 134:
+ case 133:
-/* Line 1806 of yacc.c */
-#line 1413 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1364 "awkgram.y"
{
(yyvsp[(2) - (2)])->opcode = Op_postdecrement;
(yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) -
(2)]));
}
break;
- case 135:
+ case 134:
-/* Line 1806 of yacc.c */
-#line 1418 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1369 "awkgram.y"
{
if (do_lint_old) {
warning_ln((yyvsp[(4) - (5)])->source_line,
@@ -3730,81 +3688,81 @@ regular_loop:
}
break;
- case 136:
+ case 135:
-/* Line 1806 of yacc.c */
-#line 1443 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1394 "awkgram.y"
{
(yyval) = mk_getline((yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]),
(yyvsp[(1) - (4)]), (yyvsp[(2) - (4)])->redir_type);
bcfree((yyvsp[(2) - (4)]));
}
break;
+ case 136:
+
+/* Line 1821 of yacc.c */
+#line 1400 "awkgram.y"
+ { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
+ break;
+
case 137:
-/* Line 1806 of yacc.c */
-#line 1449 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1402 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 138:
-/* Line 1806 of yacc.c */
-#line 1451 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1404 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 139:
-/* Line 1806 of yacc.c */
-#line 1453 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1406 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 140:
-/* Line 1806 of yacc.c */
-#line 1455 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1408 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 141:
-/* Line 1806 of yacc.c */
-#line 1457 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1410 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 142:
-/* Line 1806 of yacc.c */
-#line 1459 "awkgram.y"
- { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
- break;
-
- case 143:
-
-/* Line 1806 of yacc.c */
-#line 1464 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1415 "awkgram.y"
{
(yyval) = list_create((yyvsp[(1) - (1)]));
}
break;
- case 144:
+ case 143:
-/* Line 1806 of yacc.c */
-#line 1468 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1419 "awkgram.y"
{
if ((yyvsp[(2) - (2)])->opcode == Op_match_rec) {
(yyvsp[(2) - (2)])->opcode = Op_nomatch;
(yyvsp[(1) - (2)])->opcode = Op_push_i;
- (yyvsp[(1) - (2)])->memory = mk_number(0.0,
(PERM|NUMCUR|NUMBER));
+ (yyvsp[(1) - (2)])->memory = make_number(0.0);
(yyval) =
list_append(list_append(list_create((yyvsp[(1) - (2)])),
-
instruction(Op_field_spec)), (yyvsp[(2) - (2)]));
+ instruction(Op_field_spec)),
(yyvsp[(2) - (2)]));
} else {
if (do_optimize > 1 && (yyvsp[(2) - (2)])->nexti ==
(yyvsp[(2) - (2)])->lasti
- && (yyvsp[(2) -
(2)])->nexti->opcode == Op_push_i
+ && (yyvsp[(2) - (2)])->nexti->opcode ==
Op_push_i
) {
NODE *n = (yyvsp[(2) - (2)])->nexti->memory;
if ((n->flags & (STRCUR|STRING)) != 0) {
@@ -3827,17 +3785,17 @@ regular_loop:
}
break;
- case 145:
+ case 144:
-/* Line 1806 of yacc.c */
-#line 1499 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1450 "awkgram.y"
{ (yyval) = (yyvsp[(2) - (3)]); }
break;
- case 146:
+ case 145:
-/* Line 1806 of yacc.c */
-#line 1501 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1452 "awkgram.y"
{
(yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
if ((yyval) == NULL)
@@ -3845,10 +3803,10 @@ regular_loop:
}
break;
- case 147:
+ case 146:
-/* Line 1806 of yacc.c */
-#line 1507 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1458 "awkgram.y"
{
(yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
if ((yyval) == NULL)
@@ -3856,10 +3814,10 @@ regular_loop:
}
break;
- case 148:
+ case 147:
-/* Line 1806 of yacc.c */
-#line 1513 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1464 "awkgram.y"
{
static short warned1 = FALSE;
@@ -3874,51 +3832,52 @@ regular_loop:
}
break;
- case 151:
+ case 150:
-/* Line 1806 of yacc.c */
-#line 1528 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1479 "awkgram.y"
{
(yyvsp[(1) - (2)])->opcode = Op_preincrement;
(yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) -
(2)]));
}
break;
- case 152:
+ case 151:
-/* Line 1806 of yacc.c */
-#line 1533 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1484 "awkgram.y"
{
(yyvsp[(1) - (2)])->opcode = Op_predecrement;
(yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) -
(2)]));
}
break;
- case 153:
+ case 152:
-/* Line 1806 of yacc.c */
-#line 1538 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1489 "awkgram.y"
{
(yyval) = list_create((yyvsp[(1) - (1)]));
}
break;
- case 154:
+ case 153:
-/* Line 1806 of yacc.c */
-#line 1542 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1493 "awkgram.y"
{
(yyval) = list_create((yyvsp[(1) - (1)]));
}
break;
- case 155:
+ case 154:
-/* Line 1806 of yacc.c */
-#line 1546 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1497 "awkgram.y"
{
if ((yyvsp[(2) - (2)])->lasti->opcode == Op_push_i
- && ((yyvsp[(2) - (2)])->lasti->memory->flags &
(STRCUR|STRING)) == 0) {
+ && ((yyvsp[(2) - (2)])->lasti->memory->flags &
(STRCUR|STRING)) == 0
+ ) {
(yyvsp[(2) - (2)])->lasti->memory->numbr =
-(force_number((yyvsp[(2) - (2)])->lasti->memory));
(yyval) = (yyvsp[(2) - (2)]);
bcfree((yyvsp[(1) - (2)]));
@@ -3929,35 +3888,35 @@ regular_loop:
}
break;
- case 156:
+ case 155:
-/* Line 1806 of yacc.c */
-#line 1558 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1510 "awkgram.y"
{
/*
* was: $$ = $2
* POSIX semantics: force a conversion to numeric type
*/
(yyvsp[(1) - (2)])->opcode = Op_plus_i;
- (yyvsp[(1) - (2)])->memory = mk_number((AWKNUM) 0.0,
(PERM|NUMCUR|NUMBER));
+ (yyvsp[(1) - (2)])->memory = make_number(0.0);
(yyval) = list_append((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
}
break;
- case 157:
+ case 156:
-/* Line 1806 of yacc.c */
-#line 1571 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1523 "awkgram.y"
{
func_use((yyvsp[(1) - (1)])->lasti->func_name, FUNC_USE);
(yyval) = (yyvsp[(1) - (1)]);
}
break;
- case 158:
+ case 157:
-/* Line 1806 of yacc.c */
-#line 1576 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1528 "awkgram.y"
{
/* indirect function call */
INSTRUCTION *f, *t;
@@ -3978,7 +3937,7 @@ regular_loop:
name = estrdup(f->func_name, strlen(f->func_name));
if (is_std_var(name))
yyerror(_("can not use special variable `%s' for
indirect function call"), name);
- indirect_var = variable(name, Node_var_new);
+ indirect_var = variable(f->source_line, name, Node_var_new);
t = instruction(Op_push);
t->memory = indirect_var;
@@ -3992,10 +3951,10 @@ regular_loop:
}
break;
- case 159:
+ case 158:
-/* Line 1806 of yacc.c */
-#line 1612 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1564 "awkgram.y"
{
param_sanity((yyvsp[(3) - (4)]));
(yyvsp[(1) - (4)])->opcode = Op_func_call;
@@ -4011,54 +3970,54 @@ regular_loop:
}
break;
- case 160:
+ case 159:
-/* Line 1806 of yacc.c */
-#line 1629 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1581 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 161:
+ case 160:
-/* Line 1806 of yacc.c */
-#line 1631 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1583 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 162:
+ case 161:
-/* Line 1806 of yacc.c */
-#line 1636 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1588 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 163:
+ case 162:
-/* Line 1806 of yacc.c */
-#line 1638 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1590 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (2)]); }
break;
- case 164:
+ case 163:
-/* Line 1806 of yacc.c */
-#line 1643 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1595 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 165:
+ case 164:
-/* Line 1806 of yacc.c */
-#line 1645 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1597 "awkgram.y"
{
(yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
}
break;
- case 166:
+ case 165:
-/* Line 1806 of yacc.c */
-#line 1652 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1604 "awkgram.y"
{
INSTRUCTION *ip = (yyvsp[(1) - (1)])->lasti;
int count = ip->sub_count; /* # of SUBSEP-seperated
expressions */
@@ -4074,10 +4033,10 @@ regular_loop:
}
break;
- case 167:
+ case 166:
-/* Line 1806 of yacc.c */
-#line 1669 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1621 "awkgram.y"
{
INSTRUCTION *t = (yyvsp[(2) - (3)]);
if ((yyvsp[(2) - (3)]) == NULL) {
@@ -4085,7 +4044,7 @@ regular_loop:
_("invalid subscript expression"));
/* install Null string as subscript. */
t = list_create(instruction(Op_push_i));
- t->nexti->memory = Nnull_string;
+ t->nexti->memory = dupnode(Nnull_string);
(yyvsp[(3) - (3)])->sub_count = 1;
} else
(yyvsp[(3) - (3)])->sub_count = count_expressions(&t,
FALSE);
@@ -4093,67 +4052,63 @@ regular_loop:
}
break;
- case 168:
+ case 167:
-/* Line 1806 of yacc.c */
-#line 1686 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1638 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
- case 169:
+ case 168:
-/* Line 1806 of yacc.c */
-#line 1688 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1640 "awkgram.y"
{
(yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
}
break;
- case 170:
+ case 169:
-/* Line 1806 of yacc.c */
-#line 1695 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1647 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (2)]); }
break;
- case 171:
+ case 170:
-/* Line 1806 of yacc.c */
-#line 1700 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1652 "awkgram.y"
{
char *var_name = (yyvsp[(1) - (1)])->lextok;
(yyvsp[(1) - (1)])->opcode = Op_push;
- (yyvsp[(1) - (1)])->memory = variable(var_name, Node_var_new);
+ (yyvsp[(1) - (1)])->memory = variable((yyvsp[(1) -
(1)])->source_line, var_name, Node_var_new);
(yyval) = list_create((yyvsp[(1) - (1)]));
}
break;
- case 172:
+ case 171:
-/* Line 1806 of yacc.c */
-#line 1708 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1660 "awkgram.y"
{
- NODE *n;
-
char *arr = (yyvsp[(1) - (2)])->lextok;
- if ((n = lookup(arr)) != NULL && ! isarray(n))
- yyerror(_("use of non-array as array"));
- (yyvsp[(1) - (2)])->memory = variable(arr, Node_var_new);
+ (yyvsp[(1) - (2)])->memory = variable((yyvsp[(1) -
(2)])->source_line, arr, Node_var_new);
(yyvsp[(1) - (2)])->opcode = Op_push_array;
(yyval) = list_prepend((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
}
break;
- case 173:
+ case 172:
-/* Line 1806 of yacc.c */
-#line 1722 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1670 "awkgram.y"
{
INSTRUCTION *ip = (yyvsp[(1) - (1)])->nexti;
if (ip->opcode == Op_push
- && ip->memory->type == Node_var
- && ip->memory->var_update
+ && ip->memory->type == Node_var
+ && ip->memory->var_update
) {
(yyval) = list_prepend((yyvsp[(1) - (1)]),
instruction(Op_var_update));
(yyval)->nexti->memory = ip->memory;
@@ -4163,81 +4118,81 @@ regular_loop:
}
break;
- case 174:
+ case 173:
-/* Line 1806 of yacc.c */
-#line 1735 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1683 "awkgram.y"
{
(yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)]));
if ((yyvsp[(3) - (3)]) != NULL)
- mk_assignment((yyvsp[(2) - (3)]), NULL, (yyvsp[(3) - (3)]));
+ mk_assignment((yyvsp[(2) - (3)]), NULL, (yyvsp[(3) -
(3)]));
}
break;
- case 175:
+ case 174:
-/* Line 1806 of yacc.c */
-#line 1744 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1692 "awkgram.y"
{
(yyvsp[(1) - (1)])->opcode = Op_postincrement;
}
break;
- case 176:
+ case 175:
-/* Line 1806 of yacc.c */
-#line 1748 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1696 "awkgram.y"
{
(yyvsp[(1) - (1)])->opcode = Op_postdecrement;
}
break;
- case 177:
+ case 176:
-/* Line 1806 of yacc.c */
-#line 1751 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1699 "awkgram.y"
{ (yyval) = NULL; }
break;
- case 179:
+ case 178:
-/* Line 1806 of yacc.c */
-#line 1759 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1707 "awkgram.y"
{ yyerrok; }
break;
- case 180:
+ case 179:
-/* Line 1806 of yacc.c */
-#line 1763 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1711 "awkgram.y"
{ yyerrok; }
break;
- case 183:
+ case 182:
-/* Line 1806 of yacc.c */
-#line 1772 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1720 "awkgram.y"
{ yyerrok; }
break;
- case 184:
+ case 183:
-/* Line 1806 of yacc.c */
-#line 1776 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1724 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); yyerrok; }
break;
- case 185:
+ case 184:
-/* Line 1806 of yacc.c */
-#line 1780 "awkgram.y"
+/* Line 1821 of yacc.c */
+#line 1728 "awkgram.y"
{ yyerrok; }
break;
-/* Line 1806 of yacc.c */
-#line 4253 "awkgram.c"
+/* Line 1821 of yacc.c */
+#line 4208 "awkgram.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -4468,7 +4423,7 @@ yyreturn:
/* Line 2067 of yacc.c */
-#line 1782 "awkgram.y"
+#line 1730 "awkgram.y"
struct token {
@@ -4515,9 +4470,12 @@ static const struct token tokentab[] = {
{"END", Op_rule, LEX_END, 0, 0},
{"ENDFILE", Op_rule, LEX_ENDFILE, GAWKX, 0},
#ifdef ARRAYDEBUG
-{"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_adump},
+{"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2),
do_adump},
#endif
{"and", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_and},
+#ifdef ARRAYDEBUG
+{"aoption", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_aoption},
+#endif
{"asort", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3),
do_asort},
{"asorti", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3),
do_asorti},
{"atan2", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2},
@@ -4570,9 +4528,6 @@ static const struct token tokentab[] = {
{"sprintf", Op_builtin, LEX_BUILTIN, 0, do_sprintf},
{"sqrt", Op_builtin, LEX_BUILTIN, A(1), do_sqrt},
{"srand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand},
-#if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */
-{"stopme", Op_builtin, LEX_BUILTIN, GAWKX|A(0), stopme},
-#endif
{"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3),
do_strftime},
{"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum},
{"sub", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3),
do_sub},
@@ -5095,6 +5050,7 @@ next_sourcefile()
*
* assert(lexeof == TRUE);
*/
+
lexeof = FALSE;
eof_warned = FALSE;
sourcefile->srclines = sourceline; /* total no of lines in current
file */
@@ -5483,8 +5439,10 @@ yylex(void)
int mid;
static int did_newline = FALSE;
char *tokkey;
+ size_t toklen;
int inhex = FALSE;
int intlstr = FALSE;
+ AWKNUM d;
#define GET_INSTRUCTION(op) bcalloc(op, 1, sourceline)
@@ -5916,16 +5874,16 @@ retry:
tokadd(c);
}
yylval = GET_INSTRUCTION(Op_token);
+ toklen = tok - tokstart;
if (want_source) {
- yylval->lextok = estrdup(tokstart, tok - tokstart);
+ yylval->lextok = estrdup(tokstart, toklen);
return lasttok = FILENAME;
}
yylval->opcode = Op_push_i;
- yylval->memory = make_str_node(tokstart,
- tok - tokstart, esc_seen ? SCAN
: 0);
- yylval->memory->flags &= ~MALLOC;
- yylval->memory->flags |= PERM;
+ if (esc_seen)
+ toklen = scan_escape(tokstart, toklen);
+ yylval->memory = make_string(tokstart, toklen);
if (intlstr) {
yylval->memory->flags |= INTLSTR;
intlstr = FALSE;
@@ -6067,10 +6025,12 @@ retry:
lintwarn("numeric constant `%.*s'
treated as hexadecimal",
(int) strlen(tokstart)-1,
tokstart);
}
- yylval->memory = mk_number(nondec2awknum(tokstart,
strlen(tokstart)),
-
PERM|NUMCUR|NUMBER);
+ d = nondec2awknum(tokstart, strlen(tokstart));
} else
- yylval->memory = mk_number(atof(tokstart),
PERM|NUMCUR|NUMBER);
+ d = atof(tokstart);
+ yylval->memory = make_number(d);
+ if (d <= INT32_MAX && d >= INT32_MIN && d == (int32_t) d)
+ yylval->memory->flags |= NUMINT;
return lasttok = YNUMBER;
case '&':
@@ -6247,23 +6207,6 @@ out:
#undef NEWLINE_EOF
}
-/* mk_symbol --- allocates a symbol for the symbol table. */
-
-NODE *
-mk_symbol(NODETYPE type, NODE *value)
-{
- NODE *r;
-
- getnode(r);
- r->type = type;
- r->flags = MALLOC;
- r->lnode = value;
- r->rnode = NULL;
- r->parent_array = NULL;
- r->var_assign = (Func_ptr) 0;
- return r;
-}
-
/* snode --- instructions for builtin functions. Checks for arg. count
and supplies defaults where possible. */
@@ -6306,7 +6249,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
list = list_create(r);
(void) list_prepend(list, instruction(Op_field_spec));
(void) list_prepend(list, instruction(Op_push_i));
- list->nexti->memory = mk_number((AWKNUM) 0.0,
(PERM|NUMCUR|NUMBER));
+ list->nexti->memory = make_number(0.0);
return list;
} else {
arg = subn->nexti;
@@ -6348,7 +6291,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
if (nexp == 2) {
INSTRUCTION *expr;
expr = list_create(instruction(Op_push_i));
- expr->nexti->memory = mk_number((AWKNUM) 0.0,
(PERM|NUMCUR|NUMBER));
+ expr->nexti->memory = make_number(0.0);
(void) mk_expression_list(subn,
list_append(expr,
instruction(Op_field_spec)));
}
@@ -6396,7 +6339,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
if (nexp == 3) {
arg = subn->nexti->lasti->nexti->lasti->nexti; /* 3rd
arg list */
ip = instruction(Op_push_i);
- ip->memory = mk_number((AWKNUM) 0.0,
(PERM|NUMCUR|NUMBER));
+ ip->memory = make_number(0.0);
(void) mk_expression_list(subn,
list_append(list_create(ip),
instruction(Op_field_spec)));
@@ -6499,7 +6442,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
if (ip->opcode == Op_push)
ip->opcode = Op_push_array;
}
-#endif
+#endif
if (subn != NULL) {
r->expr_count = count_expressions(&subn, FALSE);
@@ -6510,75 +6453,6 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
return list_create(r);
}
-/* append_param --- append PNAME to the list of parameters
- * for the current function.
- */
-
-static void
-append_param(char *pname)
-{
- static NODE *savetail = NULL;
- NODE *p;
-
- p = make_param(pname);
- if (func_params == NULL) {
- func_params = p;
- savetail = p;
- } else if (savetail != NULL) {
- savetail->rnode = p;
- savetail = p;
- }
-}
-
-/* dup_parms --- return TRUE if there are duplicate parameters */
-
-static int
-dup_parms(INSTRUCTION *fp, NODE *func)
-{
- NODE *np;
- const char *fname, **names;
- int count, i, j, dups;
- NODE *params;
-
- if (func == NULL) /* error earlier */
- return TRUE;
-
- fname = func->param;
- count = func->param_cnt;
- params = func->rnode;
-
- if (count == 0) /* no args, no problem */
- return FALSE;
-
- if (params == NULL) /* error earlier */
- return TRUE;
-
- emalloc(names, const char **, count * sizeof(char *), "dup_parms");
-
- i = 0;
- for (np = params; np != NULL; np = np->rnode) {
- if (np->param == NULL) { /* error earlier, give up, go home */
- efree(names);
- return TRUE;
- }
- names[i++] = np->param;
- }
-
- dups = 0;
- for (i = 1; i < count; i++) {
- for (j = 0; j < i; j++) {
- if (strcmp(names[i], names[j]) == 0) {
- dups++;
- error_ln(fp->source_line,
- _("function `%s': parameter #%d, `%s', duplicates parameter #%d"),
- fname, i + 1, names[j], j+1);
- }
- }
- }
-
- efree(names);
- return (dups > 0 ? TRUE : FALSE);
-}
/* parms_shadow --- check if parameters shadow globals */
@@ -6587,18 +6461,19 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
{
int pcount, i;
int ret = FALSE;
- NODE *func;
+ NODE *func, *fp;
char *fname;
func = pc->func_body;
- fname = func->lnode->param;
-
+ fname = func->vname;
+ fp = func->fparms;
+
#if 0 /* can't happen, already exited if error ? */
if (fname == NULL || func == NULL) /* error earlier */
return FALSE;
#endif
- pcount = func->lnode->param_cnt;
+ pcount = func->param_cnt;
if (pcount == 0) /* no args, no problem */
return 0;
@@ -6610,10 +6485,10 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
* about all shadowed parameters.
*/
for (i = 0; i < pcount; i++) {
- if (lookup(func->parmlist[i]) != NULL) {
+ if (lookup(fp[i].param) != NULL) {
warning(
_("function `%s': parameter `%s' shadows global variable"),
- fname, func->parmlist[i]);
+ fname, fp[i].param);
ret = TRUE;
}
}
@@ -6623,79 +6498,10 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
}
-/*
- * install_symbol:
- * Install a name in the symbol table, even if it is already there.
- * Caller must check against redefinition if that is desired.
- */
-
-
-NODE *
-install_symbol(char *name, NODE *value)
-{
- NODE *hp;
- size_t len;
- int bucket;
-
- if (install_func)
- (*install_func)(name);
-
- var_count++;
- len = strlen(name);
- bucket = hash(name, len, (unsigned long) HASHSIZE, NULL);
- getnode(hp);
- hp->type = Node_hashnode;
- hp->hnext = variables[bucket];
- variables[bucket] = hp;
- hp->hlength = len;
- hp->hvalue = value;
- hp->hname = name;
- hp->hvalue->vname = name;
- return hp->hvalue;
-}
-
-/* lookup --- find the most recent hash node for name installed by
install_symbol */
-
-NODE *
-lookup(const char *name)
-{
- NODE *bucket;
- size_t len;
-
- len = strlen(name);
- for (bucket = variables[hash(name, len, (unsigned long) HASHSIZE,
NULL)];
- bucket != NULL; bucket = bucket->hnext)
- if (bucket->hlength == len && STREQN(bucket->hname, name, len))
- return bucket->hvalue;
- return NULL;
-}
-
-/* sym_comp --- compare two symbol (variable or function) names */
-
-static int
-sym_comp(const void *v1, const void *v2)
-{
- const NODE *const *npp1, *const *npp2;
- const NODE *n1, *n2;
- int minlen;
-
- npp1 = (const NODE *const *) v1;
- npp2 = (const NODE *const *) v2;
- n1 = *npp1;
- n2 = *npp2;
-
- if (n1->hlength > n2->hlength)
- minlen = n1->hlength;
- else
- minlen = n2->hlength;
-
- return strncmp(n1->hname, n2->hname, minlen);
-}
-
/* valinfo --- dump var info */
void
-valinfo(NODE *n, int (*print_func)(FILE *, const char *, ...), FILE *fp)
+valinfo(NODE *n, Func_print print_func, FILE *fp)
{
if (n == Nnull_string)
print_func(fp, "uninitialized scalar\n");
@@ -6713,52 +6519,6 @@ valinfo(NODE *n, int (*print_func)(FILE *, const char *,
...), FILE *fp)
print_func(fp, "?? flags %s\n", flags2str(n->flags));
}
-/* get_varlist --- list of global variables */
-
-NODE **
-get_varlist()
-{
- int i, j;
- NODE **table;
- NODE *p;
-
- emalloc(table, NODE **, (var_count + 1) * sizeof(NODE *),
"get_varlist");
- update_global_values();
- for (i = j = 0; i < HASHSIZE; i++)
- for (p = variables[i]; p != NULL; p = p->hnext)
- table[j++] = p;
- assert(j == var_count);
-
- /* Shazzam! */
- qsort(table, j, sizeof(NODE *), sym_comp);
-
- table[j] = NULL;
- return table;
-}
-
-/* print_vars --- print names and values of global variables */
-
-void
-print_vars(int (*print_func)(FILE *, const char *, ...), FILE *fp)
-{
- int i;
- NODE **table;
- NODE *p;
-
- table = get_varlist();
- for (i = 0; (p = table[i]) != NULL; i++) {
- if (p->hvalue->type == Node_func)
- continue;
- print_func(fp, "%.*s: ", (int) p->hlength, p->hname);
- if (p->hvalue->type == Node_var_array)
- print_func(fp, "array, %ld elements\n",
p->hvalue->table_size);
- else if (p->hvalue->type == Node_var_new)
- print_func(fp, "untyped variable\n");
- else if (p->hvalue->type == Node_var)
- valinfo(p->hvalue->var_value, print_func, fp);
- }
- efree(table);
-}
/* dump_vars --- dump the symbol table */
@@ -6766,6 +6526,7 @@ void
dump_vars(const char *fname)
{
FILE *fp;
+ NODE **vars;
if (fname == NULL)
fp = stderr;
@@ -6775,48 +6536,25 @@ dump_vars(const char *fname)
fp = stderr;
}
- print_vars(fprintf, fp);
+ vars = variable_list();
+ print_vars(vars, fprintf, fp);
+ efree(vars);
if (fp != stderr && fclose(fp) != 0)
warning(_("%s: close failed (%s)"), fname, strerror(errno));
}
-/* release_all_vars --- free all variable memory */
-
-void
-release_all_vars()
-{
- int i;
- NODE *p, *next;
-
- for (i = 0; i < HASHSIZE; i++) {
- for (p = variables[i]; p != NULL; p = next) {
- next = p->hnext;
-
- if (p->hvalue->type == Node_func)
- continue;
- else if (p->hvalue->type == Node_var_array)
- assoc_clear(p->hvalue);
- else if (p->hvalue->type != Node_var_new)
- unref(p->hvalue->var_value);
-
- efree(p->hname);
- freenode(p->hvalue);
- freenode(p);
- }
- }
-}
-
/* dump_funcs --- print all functions */
void
dump_funcs()
{
- if (func_count <= 0)
- return;
-
- (void) foreach_func((int (*)(INSTRUCTION *, void *)) pp_func, TRUE,
(void *) 0);
+ NODE **funcs;
+ funcs = function_list(TRUE);
+ (void) foreach_func(funcs, (int (*)(INSTRUCTION *, void *)) pp_func,
(void *) 0);
+ efree(funcs);
}
+
/* shadow_funcs --- check all functions for parameters that shadow globals */
void
@@ -6824,175 +6562,152 @@ shadow_funcs()
{
static int calls = 0;
int shadow = FALSE;
-
- if (func_count <= 0)
- return;
+ NODE **funcs;
if (calls++ != 0)
fatal(_("shadow_funcs() called twice!"));
- (void) foreach_func((int (*)(INSTRUCTION *, void *)) parms_shadow,
TRUE, &shadow);
+ funcs = function_list(TRUE);
+ (void) foreach_func(funcs, (int (*)(INSTRUCTION *, void *))
parms_shadow, & shadow);
+ efree(funcs);
/* End with fatal if the user requested it. */
if (shadow && lintfunc != warning)
lintwarn(_("there were shadowed variables."));
}
-/*
- * func_install:
- * check if name is already installed; if so, it had better have Null value,
- * in which case def is added as the value. Otherwise, install name with def
- * as value.
- *
- * Extra work, build up and save a list of the parameter names in a table
- * and hang it off params->parmlist. This is used to set the `vname' field
- * of each function parameter during a function call. See eval.c.
+
+/* mk_function --- finalize function definition node; remove parameters
+ * out of the symbol table.
*/
-static int
-func_install(INSTRUCTION *func, INSTRUCTION *def)
+static INSTRUCTION *
+mk_function(INSTRUCTION *fi, INSTRUCTION *def)
{
- NODE *params;
- NODE *r, *n, *thisfunc, *hp;
- char **pnames = NULL;
- char *fname;
- int pcount = 0;
- int i;
-
- params = func_params;
-
- /* check for function foo(foo) { ... }. bleah. */
- for (n = params->rnode; n != NULL; n = n->rnode) {
- if (strcmp(n->param, params->param) == 0) {
- error_ln(func->source_line,
- _("function `%s': can't use function name as
parameter name"), params->param);
- return -1;
- } else if (is_std_var(n->param)) {
- error_ln(func->source_line,
- _("function `%s': can't use special variable
`%s' as a function parameter"),
- params->param, n->param);
- return -1;
- }
- }
-
- thisfunc = NULL; /* turn off warnings */
+ NODE *thisfunc;
- fname = params->param;
- /* symbol table management */
- hp = remove_symbol(params->param); /* remove function name out of
symbol table */
- if (hp != NULL)
- freenode(hp);
- r = lookup(fname);
- if (r != NULL) {
- error_ln(func->source_line,
- _("function name `%s' previously defined"), fname);
- return -1;
- } else if (fname == builtin_func) /* not a valid function name */
- goto remove_params;
+ thisfunc = fi->func_body;
+ assert(thisfunc != NULL);
/* add an implicit return at end;
* also used by 'return' command in debugger
*/
-
+
(void) list_append(def, instruction(Op_push_i));
- def->lasti->memory = Nnull_string;
+ def->lasti->memory = dupnode(Nnull_string);
(void) list_append(def, instruction(Op_K_return));
if (do_profiling)
(void) list_prepend(def, instruction(Op_exec_count));
- /* func->opcode is Op_func */
- (func + 1)->firsti = def->nexti;
- (func + 1)->lasti = def->lasti;
- (func + 2)->first_line = func->source_line;
- (func + 2)->last_line = lastline;
-
- func->nexti = def->nexti;
+ /* fi->opcode = Op_func */
+ (fi + 1)->firsti = def->nexti;
+ (fi + 1)->lasti = def->lasti;
+ (fi + 2)->first_line = fi->source_line;
+ (fi + 2)->last_line = lastline;
+ fi->nexti = def->nexti;
bcfree(def);
- (void) list_append(rule_list, func + 1); /* debugging */
-
- /* install the function */
- thisfunc = mk_symbol(Node_func, params);
- (void) install_symbol(fname, thisfunc);
- thisfunc->code_ptr = func;
- func->func_body = thisfunc;
-
- for (n = params->rnode; n != NULL; n = n->rnode)
- pcount++;
-
- if (pcount != 0) {
- emalloc(pnames, char **, (pcount + 1) * sizeof(char *),
"func_install");
- for (i = 0, n = params->rnode; i < pcount; i++, n = n->rnode)
- pnames[i] = n->param;
- pnames[pcount] = NULL;
- }
- thisfunc->parmlist = pnames;
+ (void) list_append(rule_list, fi + 1); /* debugging */
/* update lint table info */
- func_use(fname, FUNC_DEFINE);
-
- func_count++; /* used in profiler / pretty printer */
+ func_use(thisfunc->vname, FUNC_DEFINE);
-remove_params:
/* remove params from symbol table */
- pop_params(params->rnode);
- return 0;
+ remove_params(thisfunc);
+ return fi;
}
-/* remove_symbol --- remove a variable from the symbol table */
+/*
+ * install_function:
+ * install function name in the symbol table.
+ * Extra work, build up and install a list of the parameter names.
+ */
-NODE *
-remove_symbol(char *name)
+static int
+install_function(char *fname, INSTRUCTION *fi, INSTRUCTION *plist)
{
- NODE *bucket, **save;
- size_t len;
+ NODE *r, *f;
+ int pcount = 0;
- len = strlen(name);
- save = &(variables[hash(name, len, (unsigned long) HASHSIZE, NULL)]);
- for (bucket = *save; bucket != NULL; bucket = bucket->hnext) {
- if (len == bucket->hlength && STREQN(bucket->hname, name, len))
{
- var_count--;
- *save = bucket->hnext;
- return bucket;
- }
- save = &(bucket->hnext);
+ r = lookup(fname);
+ if (r != NULL) {
+ error_ln(fi->source_line, _("function name `%s' previously
defined"), fname);
+ return -1;
}
- return NULL;
+
+ if (plist != NULL)
+ pcount = plist->lasti->param_count + 1;
+ f = install_symbol(fname, Node_func);
+ fi->func_body = f;
+ f->param_cnt = pcount;
+ f->code_ptr = fi;
+ f->fparms = NULL;
+ if (pcount > 0) {
+ char **pnames;
+ pnames = check_params(fname, pcount, plist); /* frees plist
*/
+ f->fparms = make_params(pnames, pcount);
+ efree(pnames);
+ install_params(f);
+ }
+ return 0;
}
-/* pop_params --- remove list of function parameters from symbol table */
-/*
- * pop parameters out of the symbol table. do this in reverse order to
- * avoid reading freed memory if there were duplicated parameters.
+/* check_params --- build a list of function parameter names after
+ * making sure that the names are valid and there are no duplicates.
*/
-static void
-pop_params(NODE *params)
+
+static char **
+check_params(char *fname, int pcount, INSTRUCTION *list)
{
- NODE *hp;
- if (params == NULL)
- return;
- pop_params(params->rnode);
- hp = remove_symbol(params->param);
- if (hp != NULL)
- freenode(hp);
-}
+ INSTRUCTION *p, *np;
+ int i, j;
+ char *name;
+ char **pnames;
-/* make_param --- make NAME into a function parameter */
+ assert(pcount > 0);
-static NODE *
-make_param(char *name)
-{
- NODE *r;
+ emalloc(pnames, char **, pcount * sizeof(char *), "check_params");
- getnode(r);
- r->type = Node_param_list;
- r->rnode = NULL;
- r->param_cnt = param_counter++;
- return (install_symbol(name, r));
+ for (i = 0, p = list->nexti; p != NULL; i++, p = np) {
+ np = p->nexti;
+ name = p->lextok;
+ p->lextok = NULL;
+
+ if (strcmp(name, fname) == 0) {
+ /* check for function foo(foo) { ... }. bleah. */
+ error_ln(p->source_line,
+ _("function `%s': can't use function name as
parameter name"), fname);
+ } else if (is_std_var(name)) {
+ error_ln(p->source_line,
+ _("function `%s': can't use special variable
`%s' as a function parameter"),
+ fname, name);
+ }
+
+ /* check for duplicate parameters */
+ for (j = 0; j < i; j++) {
+ if (strcmp(name, pnames[j]) == 0) {
+ error_ln(p->source_line,
+ _("function `%s': parameter #%d, `%s',
duplicates parameter #%d"),
+ fname, i + 1, name, j + 1);
+ }
+ }
+
+ pnames[i] = name;
+ bcfree(p);
+ }
+ bcfree(list);
+
+ return pnames;
}
+
+#ifdef HASHSIZE
+undef HASHSIZE
+#endif
+#define HASHSIZE 1021
+
static struct fdesc {
char *name;
short used;
@@ -7100,69 +6815,6 @@ param_sanity(INSTRUCTION *arglist)
}
}
-/* foreach_func --- execute given function for each awk function in symbol
table. */
-
-int
-foreach_func(int (*pfunc)(INSTRUCTION *, void *), int sort, void *data)
-{
- int i, j;
- NODE *p;
- int ret = 0;
-
- if (sort) {
- NODE **tab;
-
- /*
- * Walk through symbol table counting functions.
- * Could be more than func_count if there are
- * extension functions.
- */
- for (i = j = 0; i < HASHSIZE; i++) {
- for (p = variables[i]; p != NULL; p = p->hnext) {
- if (p->hvalue->type == Node_func) {
- j++;
- }
- }
- }
-
- if (j == 0)
- return 0;
-
- emalloc(tab, NODE **, j * sizeof(NODE *), "foreach_func");
-
- /* now walk again, copying info */
- for (i = j = 0; i < HASHSIZE; i++) {
- for (p = variables[i]; p != NULL; p = p->hnext) {
- if (p->hvalue->type == Node_func) {
- tab[j] = p;
- j++;
- }
- }
- }
-
- /* Shazzam! */
- qsort(tab, j, sizeof(NODE *), sym_comp);
-
- for (i = 0; i < j; i++) {
- if ((ret = pfunc(tab[i]->hvalue->code_ptr, data)) != 0)
- break;
- }
-
- efree(tab);
- return ret;
- }
-
- /* unsorted */
- for (i = 0; i < HASHSIZE; i++) {
- for (p = variables[i]; p != NULL; p = p->hnext) {
- if (p->hvalue->type == Node_func
- && (ret = pfunc(p->hvalue->code_ptr,
data)) != 0)
- return ret;
- }
- }
- return 0;
-}
-
/* deferred variables --- those that are only defined if needed. */
/*
@@ -7197,17 +6849,14 @@ register_deferred_variable(const char *name, NODE
*(*load_func)(void))
/* variable --- make sure NAME is in the symbol table */
NODE *
-variable(char *name, NODETYPE type)
+variable(int location, char *name, NODETYPE type)
{
NODE *r;
if ((r = lookup(name)) != NULL) {
- if (r->type == Node_func) {
- error(_("function `%s' called with space between name
and `(',\nor used as a variable or an array"),
+ if (r->type == Node_func || r->type == Node_ext_func )
+ error_ln(location, _("function `%s' called with space
between name and `(',\nor used as a variable or an array"),
r->vname);
- errcount++;
- r->type = Node_var_new; /* continue parsing instead of
exiting */
- }
} else {
/* not found */
struct deferred_variable *dv;
@@ -7217,11 +6866,7 @@ variable(char *name, NODETYPE type)
/*
* This is the only case in which we may not free the
string.
*/
- if (type == Node_var)
- r = mk_symbol(type, Nnull_string);
- else
- r = mk_symbol(type, (NODE *) NULL);
- return install_symbol(name, r);
+ return install_symbol(name, type);
}
if (STREQ(name, dv->name)) {
r = (*dv->load_func)();
@@ -7328,9 +6973,6 @@ make_assignable(INSTRUCTION *ip)
{
switch (ip->opcode) {
case Op_push:
- if (ip->memory->type == Node_param_list
- && (ip->memory->flags & FUNC) != 0)
- return NULL;
ip->opcode = Op_push_lhs;
return ip;
case Op_field_spec:
@@ -7345,14 +6987,6 @@ make_assignable(INSTRUCTION *ip)
return NULL;
}
-/* stopme --- for debugging */
-
-NODE *
-stopme(int nargs ATTRIBUTE_UNUSED)
-{
- return (NODE *) 0;
-}
-
/* dumpintlstr --- write out an initial .po file entry for the string */
static void
@@ -7402,27 +7036,6 @@ dumpintlstr2(const char *str1, size_t len1, const char
*str2, size_t len2)
fflush(stdout);
}
-/* isarray --- can this type be subscripted? */
-
-static int
-isarray(NODE *n)
-{
- switch (n->type) {
- case Node_var_new:
- case Node_var_array:
- return TRUE;
- case Node_param_list:
- return (n->flags & FUNC) == 0;
- case Node_array_ref:
- cant_happen();
- break;
- default:
- break; /* keeps gcc -Wall happy */
- }
-
- return FALSE;
-}
-
/* mk_binary --- instructions for binary operators */
static INSTRUCTION *
@@ -7483,11 +7096,7 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION
*op)
}
op->opcode = Op_push_i;
- op->memory = mk_number(res, (PERM|NUMCUR|NUMBER));
- n1->flags &= ~PERM;
- n1->flags |= MALLOC;
- n2->flags &= ~PERM;
- n2->flags |= MALLOC;
+ op->memory = make_number(res);
unref(n1);
unref(n2);
bcfree(ip1);
@@ -7819,9 +7428,7 @@ mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs,
INSTRUCTION *op)
static INSTRUCTION *
optimize_assignment(INSTRUCTION *exp)
{
- INSTRUCTION *i1;
- INSTRUCTION *i2;
- INSTRUCTION *i3;
+ INSTRUCTION *i1, *i2, *i3;
/*
* Optimize assignment statements array[subs] = x; var = x; $n = x;
@@ -7942,13 +7549,26 @@ optimize_assignment(INSTRUCTION *exp)
case Op_push_lhs:
if (i2->nexti == i1
- && i1->opcode == Op_assign
+ && i1->opcode == Op_assign
) {
/* var = .. */
i2->opcode = Op_store_var;
i2->nexti = NULL;
bcfree(i1); /* Op_assign */
exp->lasti = i2; /* update Op_list */
+
+ i3 = exp->nexti;
+ if (i3->opcode == Op_push_i
+ && (i3->memory->flags & INTLSTR) == 0
+ && i3->nexti == i2
+ ) {
+ /* constant initializer */
+ i2->initval = i3->memory;
+ bcfree(i3);
+ exp->nexti = i2;
+ } else
+ i2->initval = NULL;
+
return exp;
}
break;
@@ -8249,320 +7869,6 @@ fix_break_continue(INSTRUCTION *list, INSTRUCTION
*b_target, INSTRUCTION *c_targ
}
}
-
-/* append_symbol --- append symbol to the list of symbols
- * installed in the symbol table.
- */
-
-void
-append_symbol(char *name)
-{
- NODE *hp;
-
- /* N.B.: func_install removes func name and reinstalls it;
- * and we get two entries for it here!. destroy_symbol()
- * will find and destroy the Node_func which is what we want.
- */
-
- getnode(hp);
- hp->hname = name; /* shallow copy */
- hp->hnext = symbol_list->hnext;
- symbol_list->hnext = hp;
-}
-
-/* release_symbol --- free symbol list and optionally remove symbol from
symbol table */
-
-void
-release_symbols(NODE *symlist, int keep_globals)
-{
- NODE *hp, *n;
-
- for (hp = symlist->hnext; hp != NULL; hp = n) {
- if (! keep_globals) {
- /* destroys globals, function, and params
- * if still in symbol table and not removed by
func_install
- * due to syntax error.
- */
- destroy_symbol(hp->hname);
- }
- n = hp->hnext;
- freenode(hp);
- }
- symlist->hnext = NULL;
-}
-
-/* destroy_symbol --- remove a symbol from symbol table
-* and free all associated memory.
-*/
-
-void
-destroy_symbol(char *name)
-{
- NODE *symbol, *hp;
-
- symbol = lookup(name);
- if (symbol == NULL)
- return;
-
- if (symbol->type == Node_func) {
- char **varnames;
- NODE *func, *n;
-
- func = symbol;
- varnames = func->parmlist;
- if (varnames != NULL)
- efree(varnames);
-
- /* function parameters of type Node_param_list */
- for (n = func->lnode->rnode; n != NULL; ) {
- NODE *np;
- np = n->rnode;
- efree(n->param);
- freenode(n);
- n = np;
- }
- freenode(func->lnode);
- func_count--;
-
- } else if (symbol->type == Node_var_array)
- assoc_clear(symbol);
- else if (symbol->type == Node_var)
- unref(symbol->var_value);
-
- /* remove from symbol table */
- hp = remove_symbol(name);
- efree(hp->hname);
- freenode(hp->hvalue);
- freenode(hp);
-}
-
-#define pool_size d.dl
-#define freei x.xi
-static INSTRUCTION *pool_list;
-static AWK_CONTEXT *curr_ctxt = NULL;
-
-/* new_context --- create a new execution context. */
-
-AWK_CONTEXT *
-new_context()
-{
- AWK_CONTEXT *ctxt;
-
- emalloc(ctxt, AWK_CONTEXT *, sizeof(AWK_CONTEXT), "new_context");
- memset(ctxt, 0, sizeof(AWK_CONTEXT));
- ctxt->srcfiles.next = ctxt->srcfiles.prev = &ctxt->srcfiles;
- ctxt->rule_list.opcode = Op_list;
- ctxt->rule_list.lasti = &ctxt->rule_list;
- return ctxt;
-}
-
-/* set_context --- change current execution context. */
-
-static void
-set_context(AWK_CONTEXT *ctxt)
-{
- pool_list = &ctxt->pools;
- symbol_list = &ctxt->symbols;
- srcfiles = &ctxt->srcfiles;
- rule_list = &ctxt->rule_list;
- install_func = ctxt->install_func;
- curr_ctxt = ctxt;
-}
-
-/*
- * push_context:
- *
- * Switch to the given context after saving the current one. The set
- * of active execution contexts forms a stack; the global or main context
- * is at the bottom of the stack.
- */
-
-void
-push_context(AWK_CONTEXT *ctxt)
-{
- ctxt->prev = curr_ctxt;
- /* save current source and sourceline */
- if (curr_ctxt != NULL) {
- curr_ctxt->sourceline = sourceline;
- curr_ctxt->source = source;
- }
- sourceline = 0;
- source = NULL;
- set_context(ctxt);
-}
-
-/* pop_context --- switch to previous execution context. */
-
-void
-pop_context()
-{
- AWK_CONTEXT *ctxt;
-
- assert(curr_ctxt != NULL);
- ctxt = curr_ctxt->prev;
- /* restore source and sourceline */
- sourceline = ctxt->sourceline;
- source = ctxt->source;
- set_context(ctxt);
-}
-
-/* in_main_context --- are we in the main context ? */
-
-int
-in_main_context()
-{
- assert(curr_ctxt != NULL);
- return (curr_ctxt->prev == NULL);
-}
-
-/* free_context --- free context structure and related data. */
-
-void
-free_context(AWK_CONTEXT *ctxt, int keep_globals)
-{
- SRCFILE *s, *sn;
-
- if (ctxt == NULL)
- return;
-
- assert(curr_ctxt != ctxt);
-
- /* free all code including function codes */
- free_bcpool(&ctxt->pools);
- /* free symbols */
- release_symbols(&ctxt->symbols, keep_globals);
- /* free srcfiles */
- for (s = &ctxt->srcfiles; s != &ctxt->srcfiles; s = sn) {
- sn = s->next;
- if (s->stype != SRC_CMDLINE && s->stype != SRC_STDIN)
- efree(s->fullpath);
- efree(s->src);
- efree(s);
- }
- efree(ctxt);
-}
-
-/* free_bc_internal --- free internal memory of an instruction. */
-
-static void
-free_bc_internal(INSTRUCTION *cp)
-{
- NODE *m;
-
- switch(cp->opcode) {
- case Op_func_call:
- if (cp->func_name != NULL
- && cp->func_name != builtin_func
- )
- efree(cp->func_name);
- break;
- case Op_push_re:
- case Op_match_rec:
- case Op_match:
- case Op_nomatch:
- m = cp->memory;
- if (m->re_reg != NULL)
- refree(m->re_reg);
- if (m->re_exp != NULL)
- unref(m->re_exp);
- if (m->re_text != NULL)
- unref(m->re_text);
- freenode(m);
- break;
- case Op_token: /* token lost during error recovery in yyparse */
- if (cp->lextok != NULL)
- efree(cp->lextok);
- break;
- case Op_illegal:
- cant_happen();
- default:
- break;
- }
-}
-
-
-/* INSTR_CHUNK must be > largest code size (3) */
-#define INSTR_CHUNK 127
-
-/* bcfree --- deallocate instruction */
-
-void
-bcfree(INSTRUCTION *cp)
-{
- cp->opcode = 0;
- cp->nexti = pool_list->freei;
- pool_list->freei = cp;
-}
-
-/* bcalloc --- allocate a new instruction */
-
-INSTRUCTION *
-bcalloc(OPCODE op, int size, int srcline)
-{
- INSTRUCTION *cp;
-
- if (size > 1) {
- /* wide instructions Op_rule, Op_func_call .. */
- emalloc(cp, INSTRUCTION *, (size + 1) * sizeof(INSTRUCTION),
"bcalloc");
- cp->pool_size = size;
- cp->nexti = pool_list->nexti;
- pool_list->nexti = cp++;
- } else {
- INSTRUCTION *pool;
-
- pool = pool_list->freei;
- if (pool == NULL) {
- INSTRUCTION *last;
- emalloc(cp, INSTRUCTION *, (INSTR_CHUNK + 1) *
sizeof(INSTRUCTION), "bcalloc");
-
- cp->pool_size = INSTR_CHUNK;
- cp->nexti = pool_list->nexti;
- pool_list->nexti = cp;
- pool = ++cp;
- last = &pool[INSTR_CHUNK - 1];
- for (; cp <= last; cp++) {
- cp->opcode = 0;
- cp->nexti = cp + 1;
- }
- --cp;
- cp->nexti = NULL;
- }
- cp = pool;
- pool_list->freei = cp->nexti;
- }
-
- memset(cp, 0, size * sizeof(INSTRUCTION));
- cp->opcode = op;
- cp->source_line = srcline;
- return cp;
-}
-
-/* free_bcpool --- free list of instruction memory pools */
-
-static void
-free_bcpool(INSTRUCTION *pl)
-{
- INSTRUCTION *pool, *tmp;
-
- for (pool = pl->nexti; pool != NULL; pool = tmp) {
- INSTRUCTION *cp, *last;
- long psiz;
- psiz = pool->pool_size;
- if (psiz == INSTR_CHUNK)
- last = pool + psiz;
- else
- last = pool + 1;
- for (cp = pool + 1; cp <= last ; cp++) {
- if (cp->opcode != 0)
- free_bc_internal(cp);
- }
- tmp = pool->nexti;
- efree(pool);
- }
- memset(pl, 0, sizeof(INSTRUCTION));
-}
-
-
static inline INSTRUCTION *
list_create(INSTRUCTION *x)
{
diff --git a/awkgram.y b/awkgram.y
index 6b28b52..36bf3f9 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -42,19 +42,15 @@ static char *get_src_buf(void);
static int yylex(void);
int yyparse(void);
static INSTRUCTION *snode(INSTRUCTION *subn, INSTRUCTION *op);
-static int func_install(INSTRUCTION *fp, INSTRUCTION *def);
-static void pop_params(NODE *params);
-static NODE *make_param(char *pname);
+static char **check_params(char *fname, int pcount, INSTRUCTION *list);
+static int install_function(char *fname, INSTRUCTION *fi, INSTRUCTION *plist);
static NODE *mk_rexp(INSTRUCTION *exp);
-static void append_param(char *pname);
-static int dup_parms(INSTRUCTION *fp, NODE *func);
static void param_sanity(INSTRUCTION *arglist);
static int parms_shadow(INSTRUCTION *pc, int *shadow);
static int isnoeffect(OPCODE type);
static INSTRUCTION *make_assignable(INSTRUCTION *ip);
static void dumpintlstr(const char *str, size_t len);
static void dumpintlstr2(const char *str1, size_t len1, const char *str2,
size_t len2);
-static int isarray(NODE *n);
static int include_source(INSTRUCTION *file);
static void next_sourcefile(void);
static char *tokexpand(void);
@@ -63,6 +59,7 @@ static char *tokexpand(void);
static INSTRUCTION *mk_program(void);
static INSTRUCTION *append_rule(INSTRUCTION *pattern, INSTRUCTION *action);
+static INSTRUCTION *mk_function(INSTRUCTION *fi, INSTRUCTION *def);
static INSTRUCTION *mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp,
INSTRUCTION *true_branch,
INSTRUCTION *elsep, INSTRUCTION *false_branch);
static INSTRUCTION *mk_expression_list(INSTRUCTION *list, INSTRUCTION *s1);
@@ -81,13 +78,10 @@ static void add_lint(INSTRUCTION *list, LINTTYPE linttype);
enum defref { FUNC_DEFINE, FUNC_USE };
static void func_use(const char *name, enum defref how);
static void check_funcs(void);
-static void free_bcpool(INSTRUCTION *pl);
static ssize_t read_one_line(int fd, void *buffer, size_t count);
static int one_line_close(int fd);
-static void (*install_func)(char *) = NULL;
-
static int want_source = FALSE;
static int want_regexp; /* lexical scanning kludge */
static int can_return; /* parsing kludge */
@@ -125,22 +119,11 @@ static int continue_allowed; /* kludge for continue
*/
#define END_SRC -2000
#define YYDEBUG_LEXER_TEXT (lexeme)
-static int param_counter;
-static NODE *func_params; /* list of parameters for the current function
*/
static char *tokstart = NULL;
static char *tok = NULL;
static char *tokend;
static int errcount = 0;
-static NODE *symbol_list;
-extern void destroy_symbol(char *name);
-
-static long func_count; /* total number of functions */
-
-#define HASHSIZE 1021 /* this constant only used here */
-NODE *variables[HASHSIZE];
-static int var_count; /* total number of global variables */
-
extern char *source;
extern int sourceline;
extern SRCFILE *srcfiles;
@@ -162,16 +145,6 @@ static inline INSTRUCTION *list_prepend(INSTRUCTION *l,
INSTRUCTION *x);
static inline INSTRUCTION *list_merge(INSTRUCTION *l1, INSTRUCTION *l2);
extern double fmod(double x, double y);
-/*
- * This string cannot occur as a real awk identifier.
- * Use it as a special token to make function parsing
- * uniform, but if it's seen, don't install the function.
- * e.g.
- * function split(x) { return x }
- * function x(a) { return a }
- * should only produce one error message, and not core dump.
- */
-static char builtin_func[] = "@builtin";
#define YYSTYPE INSTRUCTION *
%}
@@ -257,9 +230,7 @@ rule
| function_prologue action
{
can_return = FALSE;
- if ($1 && func_install($1, $2) < 0)
- YYABORT;
- func_params = NULL;
+ (void) mk_function($1, $2);
yyerrok;
}
| '@' LEX_INCLUDE source statement_term
@@ -369,13 +340,8 @@ func_name
| lex_builtin
{
yyerror(_("`%s' is a built-in function, it cannot be
redefined"),
- tokstart);
- $1->opcode = Op_symbol; /* Op_symbol instead of Op_token so that
- * free_bc_internal does not try to
free it
- */
- $1->lextok = builtin_func;
- $$ = $1;
- /* yyerrok; */
+ tokstart);
+ YYABORT;
}
| '@' LEX_EVAL
{ $$ = $2; }
@@ -387,28 +353,17 @@ lex_builtin
;
function_prologue
- : LEX_FUNCTION
+ : LEX_FUNCTION func_name '(' opt_param_list r_paren opt_nls
{
- param_counter = 0;
- func_params = NULL;
+ $1->source_file = source;
+ if (install_function($2->lextok, $1, $4) < 0)
+ YYABORT;
+ $2->lextok = NULL;
+ bcfree($2);
+ /* $4 already free'd in install_function */
+ $$ = $1;
+ can_return = TRUE;
}
- func_name '(' opt_param_list r_paren opt_nls
- {
- NODE *t;
-
- $1->source_file = source;
- t = make_param($3->lextok);
- $3->lextok = NULL;
- bcfree($3);
- t->flags |= FUNC;
- t->rnode = func_params;
- func_params = t;
- $$ = $1;
- can_return = TRUE;
- /* check for duplicate parameter names */
- if (dup_parms($1, t))
- errcount++;
- }
;
regexp
@@ -425,6 +380,7 @@ regexp
size_t len;
re = $3->lextok;
+ $3->lextok = NULL;
len = strlen(re);
if (do_lint) {
if (len == 0)
@@ -436,7 +392,7 @@ regexp
_("regexp constant `/%s/' looks like a
C comment, but is not"), re);
}
- exp = make_str_node(re, len, ALREADY_MALLOCED);
+ exp = make_str_node(re, len);
n = make_regnode(Node_regex, exp);
if (n == NULL) {
unref(exp);
@@ -732,7 +688,7 @@ regular_loop:
tbreak = instruction(Op_arrayfor_final);
$4->opcode = Op_arrayfor_incr;
- $4->array_var = variable(var_name, Node_var);
+ $4->array_var = variable($3->source_line, var_name,
Node_var);
$4->target_jmp = tbreak;
tcont = $4;
$3->opcode = Op_arrayfor_init;
@@ -857,7 +813,7 @@ non_compound_stmt
if ($2 == NULL) {
$$ = list_create($1);
(void) list_prepend($$, instruction(Op_push_i));
- $$->nexti->memory = Nnull_string;
+ $$->nexti->memory = dupnode(Nnull_string);
} else
$$ = list_append($2, $1);
}
@@ -869,7 +825,7 @@ non_compound_stmt
if ($3 == NULL) {
$$ = list_create($1);
(void) list_prepend($$, instruction(Op_push_i));
- $$->nexti->memory = Nnull_string;
+ $$->nexti->memory = dupnode(Nnull_string);
} else
$$ = list_append($3, $1);
}
@@ -894,13 +850,13 @@ simple_stmt
*/
if ($1->opcode == Op_K_print &&
- ($3 == NULL
- || ($3->lasti->opcode == Op_field_spec
- && $3->nexti->nexti->nexti ==
$3->lasti
- && $3->nexti->nexti->opcode ==
Op_push_i
- &&
$3->nexti->nexti->memory->type == Node_val
- &&
$3->nexti->nexti->memory->numbr == 0.0)
- )
+ ($3 == NULL
+ || ($3->lasti->opcode == Op_field_spec
+ && $3->nexti->nexti->nexti == $3->lasti
+ && $3->nexti->nexti->opcode == Op_push_i
+ && $3->nexti->nexti->memory->type ==
Node_val
+ && $3->nexti->nexti->memory->numbr ==
0.0)
+ )
) {
static short warned = FALSE;
/* -----------------
@@ -914,8 +870,6 @@ simple_stmt
if ($3 != NULL) {
bcfree($3->lasti);
/* Op_field_spec */
- $3->nexti->nexti->memory->flags &= ~PERM;
- $3->nexti->nexti->memory->flags |= MALLOC;
unref($3->nexti->nexti->memory); /*
Node_val */
bcfree($3->nexti->nexti); /*
Op_push_i */
bcfree($3->nexti);
/* Op_list */
@@ -986,7 +940,7 @@ simple_stmt
char *arr = $2->lextok;
$2->opcode = Op_push_array;
- $2->memory = variable(arr, Node_var_new);
+ $2->memory = variable($2->source_line, arr, Node_var_new);
if ($4 == NULL) {
static short warned = FALSE;
@@ -1024,7 +978,7 @@ simple_stmt
error_ln($1->source_line,
_("`delete array' is a gawk extension"));
}
- $3->memory = variable(arr, Node_var_new);
+ $3->memory = variable($3->source_line, arr, Node_var_new);
$3->opcode = Op_push_array;
$1->expr_count = 0;
$$ = list_append(list_create($3), $1);
@@ -1173,29 +1127,29 @@ input_redir
opt_param_list
: /* empty */
+ { $$ = NULL; }
| param_list
+ { $$ = $1 ; }
;
param_list
: NAME
{
- append_param($1->lextok);
- $1->lextok = NULL;
- bcfree($1);
+ $1->param_count = 0;
+ $$ = list_create($1);
}
| param_list comma NAME
{
- append_param($3->lextok);
- $3->lextok = NULL;
- bcfree($3);
+ $3->param_count = $1->lasti->param_count + 1;
+ $$ = list_append($1, $3);
yyerrok;
}
| error
- { /* func_params = NULL; */ }
+ { $$ = NULL; }
| param_list error
- { /* func_params = NULL; */ }
+ { $$ = $1; }
| param_list comma error
- { /* func_params = NULL; */ }
+ { $$ = $1; }
;
/* optional expression, as in for loop */
@@ -1263,7 +1217,7 @@ exp
| exp LEX_IN simple_variable
{
if (do_lint_old)
- warning_ln($2->source_line,
+ warning_ln($2->source_line,
_("old awk does not support the keyword `in'
except after `for'"));
$3->nexti->opcode = Op_push_array;
$2->opcode = Op_in_array;
@@ -1326,32 +1280,29 @@ common_exp
$1->lasti->opcode = Op_no_op;
} else {
is_simple_var = ($1->nexti->opcode == Op_push
- && $1->lasti == $1->nexti); /*
first exp. is a simple
- *
variable?; kludge for use
- *
in Op_assign_concat.
- */
+ && $1->lasti == $1->nexti); /* first
exp. is a simple
+ *
variable?; kludge for use
+ * in
Op_assign_concat.
+ */
}
if (do_optimize > 1
- && $1->nexti == $1->lasti && $1->nexti->opcode
== Op_push_i
- && $2->nexti == $2->lasti && $2->nexti->opcode
== Op_push_i
+ && $1->nexti == $1->lasti && $1->nexti->opcode ==
Op_push_i
+ && $2->nexti == $2->lasti && $2->nexti->opcode ==
Op_push_i
) {
NODE *n1 = $1->nexti->memory;
NODE *n2 = $2->nexti->memory;
size_t nlen;
- (void) force_string(n1);
- (void) force_string(n2);
+ n1 = force_string(n1);
+ n2 = force_string(n2);
nlen = n1->stlen + n2->stlen;
erealloc(n1->stptr, char *, nlen + 2, "constant fold");
memcpy(n1->stptr + n1->stlen, n2->stptr, n2->stlen);
n1->stlen = nlen;
n1->stptr[nlen] = '\0';
- n1->flags &= ~(NUMCUR|NUMBER);
+ n1->flags &= ~(NUMCUR|NUMBER|NUMINT);
n1->flags |= (STRING|STRCUR);
-
- n2->flags &= ~PERM;
- n2->flags |= MALLOC;
unref(n2);
bcfree($2->nexti);
bcfree($2);
@@ -1469,12 +1420,12 @@ non_post_simp_exp
if ($2->opcode == Op_match_rec) {
$2->opcode = Op_nomatch;
$1->opcode = Op_push_i;
- $1->memory = mk_number(0.0, (PERM|NUMCUR|NUMBER));
+ $1->memory = make_number(0.0);
$$ = list_append(list_append(list_create($1),
-
instruction(Op_field_spec)), $2);
+ instruction(Op_field_spec)),
$2);
} else {
if (do_optimize > 1 && $2->nexti == $2->lasti
- && $2->nexti->opcode ==
Op_push_i
+ && $2->nexti->opcode == Op_push_i
) {
NODE *n = $2->nexti->memory;
if ((n->flags & (STRCUR|STRING)) != 0) {
@@ -1545,7 +1496,8 @@ non_post_simp_exp
| '-' simp_exp %prec UNARY
{
if ($2->lasti->opcode == Op_push_i
- && ($2->lasti->memory->flags & (STRCUR|STRING))
== 0) {
+ && ($2->lasti->memory->flags & (STRCUR|STRING)) == 0
+ ) {
$2->lasti->memory->numbr =
-(force_number($2->lasti->memory));
$$ = $2;
bcfree($1);
@@ -1561,7 +1513,7 @@ non_post_simp_exp
* POSIX semantics: force a conversion to numeric type
*/
$1->opcode = Op_plus_i;
- $1->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER));
+ $1->memory = make_number(0.0);
$$ = list_append($2, $1);
}
;
@@ -1593,7 +1545,7 @@ func_call
name = estrdup(f->func_name, strlen(f->func_name));
if (is_std_var(name))
yyerror(_("can not use special variable `%s' for
indirect function call"), name);
- indirect_var = variable(name, Node_var_new);
+ indirect_var = variable(f->source_line, name, Node_var_new);
t = instruction(Op_push);
t->memory = indirect_var;
@@ -1673,7 +1625,7 @@ bracketed_exp_list
_("invalid subscript expression"));
/* install Null string as subscript. */
t = list_create(instruction(Op_push_i));
- t->nexti->memory = Nnull_string;
+ t->nexti->memory = dupnode(Nnull_string);
$3->sub_count = 1;
} else
$3->sub_count = count_expressions(&t, FALSE);
@@ -1701,17 +1653,13 @@ simple_variable
char *var_name = $1->lextok;
$1->opcode = Op_push;
- $1->memory = variable(var_name, Node_var_new);
+ $1->memory = variable($1->source_line, var_name, Node_var_new);
$$ = list_create($1);
}
| NAME subscript_list
{
- NODE *n;
-
char *arr = $1->lextok;
- if ((n = lookup(arr)) != NULL && ! isarray(n))
- yyerror(_("use of non-array as array"));
- $1->memory = variable(arr, Node_var_new);
+ $1->memory = variable($1->source_line, arr, Node_var_new);
$1->opcode = Op_push_array;
$$ = list_prepend($2, $1);
}
@@ -1722,8 +1670,8 @@ variable
{
INSTRUCTION *ip = $1->nexti;
if (ip->opcode == Op_push
- && ip->memory->type == Node_var
- && ip->memory->var_update
+ && ip->memory->type == Node_var
+ && ip->memory->var_update
) {
$$ = list_prepend($1, instruction(Op_var_update));
$$->nexti->memory = ip->memory;
@@ -1735,7 +1683,7 @@ variable
{
$$ = list_append($2, $1);
if ($3 != NULL)
- mk_assignment($2, NULL, $3);
+ mk_assignment($2, NULL, $3);
}
;
@@ -1825,9 +1773,12 @@ static const struct token tokentab[] = {
{"END", Op_rule, LEX_END, 0, 0},
{"ENDFILE", Op_rule, LEX_ENDFILE, GAWKX, 0},
#ifdef ARRAYDEBUG
-{"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_adump},
+{"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2),
do_adump},
#endif
{"and", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_and},
+#ifdef ARRAYDEBUG
+{"aoption", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_aoption},
+#endif
{"asort", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3),
do_asort},
{"asorti", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3),
do_asorti},
{"atan2", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2},
@@ -1880,9 +1831,6 @@ static const struct token tokentab[] = {
{"sprintf", Op_builtin, LEX_BUILTIN, 0, do_sprintf},
{"sqrt", Op_builtin, LEX_BUILTIN, A(1), do_sqrt},
{"srand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand},
-#if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */
-{"stopme", Op_builtin, LEX_BUILTIN, GAWKX|A(0), stopme},
-#endif
{"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3),
do_strftime},
{"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum},
{"sub", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3),
do_sub},
@@ -2405,6 +2353,7 @@ next_sourcefile()
*
* assert(lexeof == TRUE);
*/
+
lexeof = FALSE;
eof_warned = FALSE;
sourcefile->srclines = sourceline; /* total no of lines in current
file */
@@ -2793,8 +2742,10 @@ yylex(void)
int mid;
static int did_newline = FALSE;
char *tokkey;
+ size_t toklen;
int inhex = FALSE;
int intlstr = FALSE;
+ AWKNUM d;
#define GET_INSTRUCTION(op) bcalloc(op, 1, sourceline)
@@ -3226,16 +3177,16 @@ retry:
tokadd(c);
}
yylval = GET_INSTRUCTION(Op_token);
+ toklen = tok - tokstart;
if (want_source) {
- yylval->lextok = estrdup(tokstart, tok - tokstart);
+ yylval->lextok = estrdup(tokstart, toklen);
return lasttok = FILENAME;
}
yylval->opcode = Op_push_i;
- yylval->memory = make_str_node(tokstart,
- tok - tokstart, esc_seen ? SCAN
: 0);
- yylval->memory->flags &= ~MALLOC;
- yylval->memory->flags |= PERM;
+ if (esc_seen)
+ toklen = scan_escape(tokstart, toklen);
+ yylval->memory = make_string(tokstart, toklen);
if (intlstr) {
yylval->memory->flags |= INTLSTR;
intlstr = FALSE;
@@ -3377,10 +3328,12 @@ retry:
lintwarn("numeric constant `%.*s'
treated as hexadecimal",
(int) strlen(tokstart)-1,
tokstart);
}
- yylval->memory = mk_number(nondec2awknum(tokstart,
strlen(tokstart)),
-
PERM|NUMCUR|NUMBER);
+ d = nondec2awknum(tokstart, strlen(tokstart));
} else
- yylval->memory = mk_number(atof(tokstart),
PERM|NUMCUR|NUMBER);
+ d = atof(tokstart);
+ yylval->memory = make_number(d);
+ if (d <= INT32_MAX && d >= INT32_MIN && d == (int32_t) d)
+ yylval->memory->flags |= NUMINT;
return lasttok = YNUMBER;
case '&':
@@ -3557,23 +3510,6 @@ out:
#undef NEWLINE_EOF
}
-/* mk_symbol --- allocates a symbol for the symbol table. */
-
-NODE *
-mk_symbol(NODETYPE type, NODE *value)
-{
- NODE *r;
-
- getnode(r);
- r->type = type;
- r->flags = MALLOC;
- r->lnode = value;
- r->rnode = NULL;
- r->parent_array = NULL;
- r->var_assign = (Func_ptr) 0;
- return r;
-}
-
/* snode --- instructions for builtin functions. Checks for arg. count
and supplies defaults where possible. */
@@ -3616,7 +3552,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
list = list_create(r);
(void) list_prepend(list, instruction(Op_field_spec));
(void) list_prepend(list, instruction(Op_push_i));
- list->nexti->memory = mk_number((AWKNUM) 0.0,
(PERM|NUMCUR|NUMBER));
+ list->nexti->memory = make_number(0.0);
return list;
} else {
arg = subn->nexti;
@@ -3658,7 +3594,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
if (nexp == 2) {
INSTRUCTION *expr;
expr = list_create(instruction(Op_push_i));
- expr->nexti->memory = mk_number((AWKNUM) 0.0,
(PERM|NUMCUR|NUMBER));
+ expr->nexti->memory = make_number(0.0);
(void) mk_expression_list(subn,
list_append(expr,
instruction(Op_field_spec)));
}
@@ -3706,7 +3642,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
if (nexp == 3) {
arg = subn->nexti->lasti->nexti->lasti->nexti; /* 3rd
arg list */
ip = instruction(Op_push_i);
- ip->memory = mk_number((AWKNUM) 0.0,
(PERM|NUMCUR|NUMBER));
+ ip->memory = make_number(0.0);
(void) mk_expression_list(subn,
list_append(list_create(ip),
instruction(Op_field_spec)));
@@ -3809,7 +3745,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
if (ip->opcode == Op_push)
ip->opcode = Op_push_array;
}
-#endif
+#endif
if (subn != NULL) {
r->expr_count = count_expressions(&subn, FALSE);
@@ -3820,75 +3756,6 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
return list_create(r);
}
-/* append_param --- append PNAME to the list of parameters
- * for the current function.
- */
-
-static void
-append_param(char *pname)
-{
- static NODE *savetail = NULL;
- NODE *p;
-
- p = make_param(pname);
- if (func_params == NULL) {
- func_params = p;
- savetail = p;
- } else if (savetail != NULL) {
- savetail->rnode = p;
- savetail = p;
- }
-}
-
-/* dup_parms --- return TRUE if there are duplicate parameters */
-
-static int
-dup_parms(INSTRUCTION *fp, NODE *func)
-{
- NODE *np;
- const char *fname, **names;
- int count, i, j, dups;
- NODE *params;
-
- if (func == NULL) /* error earlier */
- return TRUE;
-
- fname = func->param;
- count = func->param_cnt;
- params = func->rnode;
-
- if (count == 0) /* no args, no problem */
- return FALSE;
-
- if (params == NULL) /* error earlier */
- return TRUE;
-
- emalloc(names, const char **, count * sizeof(char *), "dup_parms");
-
- i = 0;
- for (np = params; np != NULL; np = np->rnode) {
- if (np->param == NULL) { /* error earlier, give up, go home */
- efree(names);
- return TRUE;
- }
- names[i++] = np->param;
- }
-
- dups = 0;
- for (i = 1; i < count; i++) {
- for (j = 0; j < i; j++) {
- if (strcmp(names[i], names[j]) == 0) {
- dups++;
- error_ln(fp->source_line,
- _("function `%s': parameter #%d, `%s', duplicates parameter #%d"),
- fname, i + 1, names[j], j+1);
- }
- }
- }
-
- efree(names);
- return (dups > 0 ? TRUE : FALSE);
-}
/* parms_shadow --- check if parameters shadow globals */
@@ -3897,18 +3764,19 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
{
int pcount, i;
int ret = FALSE;
- NODE *func;
+ NODE *func, *fp;
char *fname;
func = pc->func_body;
- fname = func->lnode->param;
-
+ fname = func->vname;
+ fp = func->fparms;
+
#if 0 /* can't happen, already exited if error ? */
if (fname == NULL || func == NULL) /* error earlier */
return FALSE;
#endif
- pcount = func->lnode->param_cnt;
+ pcount = func->param_cnt;
if (pcount == 0) /* no args, no problem */
return 0;
@@ -3920,10 +3788,10 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
* about all shadowed parameters.
*/
for (i = 0; i < pcount; i++) {
- if (lookup(func->parmlist[i]) != NULL) {
+ if (lookup(fp[i].param) != NULL) {
warning(
_("function `%s': parameter `%s' shadows global variable"),
- fname, func->parmlist[i]);
+ fname, fp[i].param);
ret = TRUE;
}
}
@@ -3933,79 +3801,10 @@ parms_shadow(INSTRUCTION *pc, int *shadow)
}
-/*
- * install_symbol:
- * Install a name in the symbol table, even if it is already there.
- * Caller must check against redefinition if that is desired.
- */
-
-
-NODE *
-install_symbol(char *name, NODE *value)
-{
- NODE *hp;
- size_t len;
- int bucket;
-
- if (install_func)
- (*install_func)(name);
-
- var_count++;
- len = strlen(name);
- bucket = hash(name, len, (unsigned long) HASHSIZE, NULL);
- getnode(hp);
- hp->type = Node_hashnode;
- hp->hnext = variables[bucket];
- variables[bucket] = hp;
- hp->hlength = len;
- hp->hvalue = value;
- hp->hname = name;
- hp->hvalue->vname = name;
- return hp->hvalue;
-}
-
-/* lookup --- find the most recent hash node for name installed by
install_symbol */
-
-NODE *
-lookup(const char *name)
-{
- NODE *bucket;
- size_t len;
-
- len = strlen(name);
- for (bucket = variables[hash(name, len, (unsigned long) HASHSIZE,
NULL)];
- bucket != NULL; bucket = bucket->hnext)
- if (bucket->hlength == len && STREQN(bucket->hname, name, len))
- return bucket->hvalue;
- return NULL;
-}
-
-/* sym_comp --- compare two symbol (variable or function) names */
-
-static int
-sym_comp(const void *v1, const void *v2)
-{
- const NODE *const *npp1, *const *npp2;
- const NODE *n1, *n2;
- int minlen;
-
- npp1 = (const NODE *const *) v1;
- npp2 = (const NODE *const *) v2;
- n1 = *npp1;
- n2 = *npp2;
-
- if (n1->hlength > n2->hlength)
- minlen = n1->hlength;
- else
- minlen = n2->hlength;
-
- return strncmp(n1->hname, n2->hname, minlen);
-}
-
/* valinfo --- dump var info */
void
-valinfo(NODE *n, int (*print_func)(FILE *, const char *, ...), FILE *fp)
+valinfo(NODE *n, Func_print print_func, FILE *fp)
{
if (n == Nnull_string)
print_func(fp, "uninitialized scalar\n");
@@ -4023,52 +3822,6 @@ valinfo(NODE *n, int (*print_func)(FILE *, const char *,
...), FILE *fp)
print_func(fp, "?? flags %s\n", flags2str(n->flags));
}
-/* get_varlist --- list of global variables */
-
-NODE **
-get_varlist()
-{
- int i, j;
- NODE **table;
- NODE *p;
-
- emalloc(table, NODE **, (var_count + 1) * sizeof(NODE *),
"get_varlist");
- update_global_values();
- for (i = j = 0; i < HASHSIZE; i++)
- for (p = variables[i]; p != NULL; p = p->hnext)
- table[j++] = p;
- assert(j == var_count);
-
- /* Shazzam! */
- qsort(table, j, sizeof(NODE *), sym_comp);
-
- table[j] = NULL;
- return table;
-}
-
-/* print_vars --- print names and values of global variables */
-
-void
-print_vars(int (*print_func)(FILE *, const char *, ...), FILE *fp)
-{
- int i;
- NODE **table;
- NODE *p;
-
- table = get_varlist();
- for (i = 0; (p = table[i]) != NULL; i++) {
- if (p->hvalue->type == Node_func)
- continue;
- print_func(fp, "%.*s: ", (int) p->hlength, p->hname);
- if (p->hvalue->type == Node_var_array)
- print_func(fp, "array, %ld elements\n",
p->hvalue->table_size);
- else if (p->hvalue->type == Node_var_new)
- print_func(fp, "untyped variable\n");
- else if (p->hvalue->type == Node_var)
- valinfo(p->hvalue->var_value, print_func, fp);
- }
- efree(table);
-}
/* dump_vars --- dump the symbol table */
@@ -4076,6 +3829,7 @@ void
dump_vars(const char *fname)
{
FILE *fp;
+ NODE **vars;
if (fname == NULL)
fp = stderr;
@@ -4085,48 +3839,25 @@ dump_vars(const char *fname)
fp = stderr;
}
- print_vars(fprintf, fp);
+ vars = variable_list();
+ print_vars(vars, fprintf, fp);
+ efree(vars);
if (fp != stderr && fclose(fp) != 0)
warning(_("%s: close failed (%s)"), fname, strerror(errno));
}
-/* release_all_vars --- free all variable memory */
-
-void
-release_all_vars()
-{
- int i;
- NODE *p, *next;
-
- for (i = 0; i < HASHSIZE; i++) {
- for (p = variables[i]; p != NULL; p = next) {
- next = p->hnext;
-
- if (p->hvalue->type == Node_func)
- continue;
- else if (p->hvalue->type == Node_var_array)
- assoc_clear(p->hvalue);
- else if (p->hvalue->type != Node_var_new)
- unref(p->hvalue->var_value);
-
- efree(p->hname);
- freenode(p->hvalue);
- freenode(p);
- }
- }
-}
-
/* dump_funcs --- print all functions */
void
dump_funcs()
{
- if (func_count <= 0)
- return;
-
- (void) foreach_func((int (*)(INSTRUCTION *, void *)) pp_func, TRUE,
(void *) 0);
+ NODE **funcs;
+ funcs = function_list(TRUE);
+ (void) foreach_func(funcs, (int (*)(INSTRUCTION *, void *)) pp_func,
(void *) 0);
+ efree(funcs);
}
+
/* shadow_funcs --- check all functions for parameters that shadow globals */
void
@@ -4134,175 +3865,152 @@ shadow_funcs()
{
static int calls = 0;
int shadow = FALSE;
-
- if (func_count <= 0)
- return;
+ NODE **funcs;
if (calls++ != 0)
fatal(_("shadow_funcs() called twice!"));
- (void) foreach_func((int (*)(INSTRUCTION *, void *)) parms_shadow,
TRUE, &shadow);
+ funcs = function_list(TRUE);
+ (void) foreach_func(funcs, (int (*)(INSTRUCTION *, void *))
parms_shadow, & shadow);
+ efree(funcs);
/* End with fatal if the user requested it. */
if (shadow && lintfunc != warning)
lintwarn(_("there were shadowed variables."));
}
-/*
- * func_install:
- * check if name is already installed; if so, it had better have Null value,
- * in which case def is added as the value. Otherwise, install name with def
- * as value.
- *
- * Extra work, build up and save a list of the parameter names in a table
- * and hang it off params->parmlist. This is used to set the `vname' field
- * of each function parameter during a function call. See eval.c.
+
+/* mk_function --- finalize function definition node; remove parameters
+ * out of the symbol table.
*/
-static int
-func_install(INSTRUCTION *func, INSTRUCTION *def)
+static INSTRUCTION *
+mk_function(INSTRUCTION *fi, INSTRUCTION *def)
{
- NODE *params;
- NODE *r, *n, *thisfunc, *hp;
- char **pnames = NULL;
- char *fname;
- int pcount = 0;
- int i;
+ NODE *thisfunc;
- params = func_params;
-
- /* check for function foo(foo) { ... }. bleah. */
- for (n = params->rnode; n != NULL; n = n->rnode) {
- if (strcmp(n->param, params->param) == 0) {
- error_ln(func->source_line,
- _("function `%s': can't use function name as
parameter name"), params->param);
- return -1;
- } else if (is_std_var(n->param)) {
- error_ln(func->source_line,
- _("function `%s': can't use special variable
`%s' as a function parameter"),
- params->param, n->param);
- return -1;
- }
- }
-
- thisfunc = NULL; /* turn off warnings */
-
- fname = params->param;
- /* symbol table management */
- hp = remove_symbol(params->param); /* remove function name out of
symbol table */
- if (hp != NULL)
- freenode(hp);
- r = lookup(fname);
- if (r != NULL) {
- error_ln(func->source_line,
- _("function name `%s' previously defined"), fname);
- return -1;
- } else if (fname == builtin_func) /* not a valid function name */
- goto remove_params;
+ thisfunc = fi->func_body;
+ assert(thisfunc != NULL);
/* add an implicit return at end;
* also used by 'return' command in debugger
*/
-
+
(void) list_append(def, instruction(Op_push_i));
- def->lasti->memory = Nnull_string;
+ def->lasti->memory = dupnode(Nnull_string);
(void) list_append(def, instruction(Op_K_return));
if (do_profiling)
(void) list_prepend(def, instruction(Op_exec_count));
- /* func->opcode is Op_func */
- (func + 1)->firsti = def->nexti;
- (func + 1)->lasti = def->lasti;
- (func + 2)->first_line = func->source_line;
- (func + 2)->last_line = lastline;
-
- func->nexti = def->nexti;
+ /* fi->opcode = Op_func */
+ (fi + 1)->firsti = def->nexti;
+ (fi + 1)->lasti = def->lasti;
+ (fi + 2)->first_line = fi->source_line;
+ (fi + 2)->last_line = lastline;
+ fi->nexti = def->nexti;
bcfree(def);
- (void) list_append(rule_list, func + 1); /* debugging */
-
- /* install the function */
- thisfunc = mk_symbol(Node_func, params);
- (void) install_symbol(fname, thisfunc);
- thisfunc->code_ptr = func;
- func->func_body = thisfunc;
-
- for (n = params->rnode; n != NULL; n = n->rnode)
- pcount++;
-
- if (pcount != 0) {
- emalloc(pnames, char **, (pcount + 1) * sizeof(char *),
"func_install");
- for (i = 0, n = params->rnode; i < pcount; i++, n = n->rnode)
- pnames[i] = n->param;
- pnames[pcount] = NULL;
- }
- thisfunc->parmlist = pnames;
+ (void) list_append(rule_list, fi + 1); /* debugging */
/* update lint table info */
- func_use(fname, FUNC_DEFINE);
-
- func_count++; /* used in profiler / pretty printer */
+ func_use(thisfunc->vname, FUNC_DEFINE);
-remove_params:
/* remove params from symbol table */
- pop_params(params->rnode);
- return 0;
+ remove_params(thisfunc);
+ return fi;
}
-/* remove_symbol --- remove a variable from the symbol table */
+/*
+ * install_function:
+ * install function name in the symbol table.
+ * Extra work, build up and install a list of the parameter names.
+ */
-NODE *
-remove_symbol(char *name)
+static int
+install_function(char *fname, INSTRUCTION *fi, INSTRUCTION *plist)
{
- NODE *bucket, **save;
- size_t len;
+ NODE *r, *f;
+ int pcount = 0;
- len = strlen(name);
- save = &(variables[hash(name, len, (unsigned long) HASHSIZE, NULL)]);
- for (bucket = *save; bucket != NULL; bucket = bucket->hnext) {
- if (len == bucket->hlength && STREQN(bucket->hname, name, len))
{
- var_count--;
- *save = bucket->hnext;
- return bucket;
- }
- save = &(bucket->hnext);
+ r = lookup(fname);
+ if (r != NULL) {
+ error_ln(fi->source_line, _("function name `%s' previously
defined"), fname);
+ return -1;
}
- return NULL;
+
+ if (plist != NULL)
+ pcount = plist->lasti->param_count + 1;
+ f = install_symbol(fname, Node_func);
+ fi->func_body = f;
+ f->param_cnt = pcount;
+ f->code_ptr = fi;
+ f->fparms = NULL;
+ if (pcount > 0) {
+ char **pnames;
+ pnames = check_params(fname, pcount, plist); /* frees plist
*/
+ f->fparms = make_params(pnames, pcount);
+ efree(pnames);
+ install_params(f);
+ }
+ return 0;
}
-/* pop_params --- remove list of function parameters from symbol table */
-/*
- * pop parameters out of the symbol table. do this in reverse order to
- * avoid reading freed memory if there were duplicated parameters.
+/* check_params --- build a list of function parameter names after
+ * making sure that the names are valid and there are no duplicates.
*/
-static void
-pop_params(NODE *params)
+
+static char **
+check_params(char *fname, int pcount, INSTRUCTION *list)
{
- NODE *hp;
- if (params == NULL)
- return;
- pop_params(params->rnode);
- hp = remove_symbol(params->param);
- if (hp != NULL)
- freenode(hp);
-}
+ INSTRUCTION *p, *np;
+ int i, j;
+ char *name;
+ char **pnames;
-/* make_param --- make NAME into a function parameter */
+ assert(pcount > 0);
-static NODE *
-make_param(char *name)
-{
- NODE *r;
+ emalloc(pnames, char **, pcount * sizeof(char *), "check_params");
- getnode(r);
- r->type = Node_param_list;
- r->rnode = NULL;
- r->param_cnt = param_counter++;
- return (install_symbol(name, r));
+ for (i = 0, p = list->nexti; p != NULL; i++, p = np) {
+ np = p->nexti;
+ name = p->lextok;
+ p->lextok = NULL;
+
+ if (strcmp(name, fname) == 0) {
+ /* check for function foo(foo) { ... }. bleah. */
+ error_ln(p->source_line,
+ _("function `%s': can't use function name as
parameter name"), fname);
+ } else if (is_std_var(name)) {
+ error_ln(p->source_line,
+ _("function `%s': can't use special variable
`%s' as a function parameter"),
+ fname, name);
+ }
+
+ /* check for duplicate parameters */
+ for (j = 0; j < i; j++) {
+ if (strcmp(name, pnames[j]) == 0) {
+ error_ln(p->source_line,
+ _("function `%s': parameter #%d, `%s',
duplicates parameter #%d"),
+ fname, i + 1, name, j + 1);
+ }
+ }
+
+ pnames[i] = name;
+ bcfree(p);
+ }
+ bcfree(list);
+
+ return pnames;
}
+
+#ifdef HASHSIZE
+undef HASHSIZE
+#endif
+#define HASHSIZE 1021
+
static struct fdesc {
char *name;
short used;
@@ -4410,69 +4118,6 @@ param_sanity(INSTRUCTION *arglist)
}
}
-/* foreach_func --- execute given function for each awk function in symbol
table. */
-
-int
-foreach_func(int (*pfunc)(INSTRUCTION *, void *), int sort, void *data)
-{
- int i, j;
- NODE *p;
- int ret = 0;
-
- if (sort) {
- NODE **tab;
-
- /*
- * Walk through symbol table counting functions.
- * Could be more than func_count if there are
- * extension functions.
- */
- for (i = j = 0; i < HASHSIZE; i++) {
- for (p = variables[i]; p != NULL; p = p->hnext) {
- if (p->hvalue->type == Node_func) {
- j++;
- }
- }
- }
-
- if (j == 0)
- return 0;
-
- emalloc(tab, NODE **, j * sizeof(NODE *), "foreach_func");
-
- /* now walk again, copying info */
- for (i = j = 0; i < HASHSIZE; i++) {
- for (p = variables[i]; p != NULL; p = p->hnext) {
- if (p->hvalue->type == Node_func) {
- tab[j] = p;
- j++;
- }
- }
- }
-
- /* Shazzam! */
- qsort(tab, j, sizeof(NODE *), sym_comp);
-
- for (i = 0; i < j; i++) {
- if ((ret = pfunc(tab[i]->hvalue->code_ptr, data)) != 0)
- break;
- }
-
- efree(tab);
- return ret;
- }
-
- /* unsorted */
- for (i = 0; i < HASHSIZE; i++) {
- for (p = variables[i]; p != NULL; p = p->hnext) {
- if (p->hvalue->type == Node_func
- && (ret = pfunc(p->hvalue->code_ptr,
data)) != 0)
- return ret;
- }
- }
- return 0;
-}
-
/* deferred variables --- those that are only defined if needed. */
/*
@@ -4507,17 +4152,14 @@ register_deferred_variable(const char *name, NODE
*(*load_func)(void))
/* variable --- make sure NAME is in the symbol table */
NODE *
-variable(char *name, NODETYPE type)
+variable(int location, char *name, NODETYPE type)
{
NODE *r;
if ((r = lookup(name)) != NULL) {
- if (r->type == Node_func) {
- error(_("function `%s' called with space between name
and `(',\nor used as a variable or an array"),
+ if (r->type == Node_func || r->type == Node_ext_func )
+ error_ln(location, _("function `%s' called with space
between name and `(',\nor used as a variable or an array"),
r->vname);
- errcount++;
- r->type = Node_var_new; /* continue parsing instead of
exiting */
- }
} else {
/* not found */
struct deferred_variable *dv;
@@ -4527,11 +4169,7 @@ variable(char *name, NODETYPE type)
/*
* This is the only case in which we may not free the
string.
*/
- if (type == Node_var)
- r = mk_symbol(type, Nnull_string);
- else
- r = mk_symbol(type, (NODE *) NULL);
- return install_symbol(name, r);
+ return install_symbol(name, type);
}
if (STREQ(name, dv->name)) {
r = (*dv->load_func)();
@@ -4638,9 +4276,6 @@ make_assignable(INSTRUCTION *ip)
{
switch (ip->opcode) {
case Op_push:
- if (ip->memory->type == Node_param_list
- && (ip->memory->flags & FUNC) != 0)
- return NULL;
ip->opcode = Op_push_lhs;
return ip;
case Op_field_spec:
@@ -4655,14 +4290,6 @@ make_assignable(INSTRUCTION *ip)
return NULL;
}
-/* stopme --- for debugging */
-
-NODE *
-stopme(int nargs ATTRIBUTE_UNUSED)
-{
- return (NODE *) 0;
-}
-
/* dumpintlstr --- write out an initial .po file entry for the string */
static void
@@ -4712,27 +4339,6 @@ dumpintlstr2(const char *str1, size_t len1, const char
*str2, size_t len2)
fflush(stdout);
}
-/* isarray --- can this type be subscripted? */
-
-static int
-isarray(NODE *n)
-{
- switch (n->type) {
- case Node_var_new:
- case Node_var_array:
- return TRUE;
- case Node_param_list:
- return (n->flags & FUNC) == 0;
- case Node_array_ref:
- cant_happen();
- break;
- default:
- break; /* keeps gcc -Wall happy */
- }
-
- return FALSE;
-}
-
/* mk_binary --- instructions for binary operators */
static INSTRUCTION *
@@ -4793,11 +4399,7 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION
*op)
}
op->opcode = Op_push_i;
- op->memory = mk_number(res, (PERM|NUMCUR|NUMBER));
- n1->flags &= ~PERM;
- n1->flags |= MALLOC;
- n2->flags &= ~PERM;
- n2->flags |= MALLOC;
+ op->memory = make_number(res);
unref(n1);
unref(n2);
bcfree(ip1);
@@ -5129,9 +4731,7 @@ mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs,
INSTRUCTION *op)
static INSTRUCTION *
optimize_assignment(INSTRUCTION *exp)
{
- INSTRUCTION *i1;
- INSTRUCTION *i2;
- INSTRUCTION *i3;
+ INSTRUCTION *i1, *i2, *i3;
/*
* Optimize assignment statements array[subs] = x; var = x; $n = x;
@@ -5252,13 +4852,26 @@ optimize_assignment(INSTRUCTION *exp)
case Op_push_lhs:
if (i2->nexti == i1
- && i1->opcode == Op_assign
+ && i1->opcode == Op_assign
) {
/* var = .. */
i2->opcode = Op_store_var;
i2->nexti = NULL;
bcfree(i1); /* Op_assign */
exp->lasti = i2; /* update Op_list */
+
+ i3 = exp->nexti;
+ if (i3->opcode == Op_push_i
+ && (i3->memory->flags & INTLSTR) == 0
+ && i3->nexti == i2
+ ) {
+ /* constant initializer */
+ i2->initval = i3->memory;
+ bcfree(i3);
+ exp->nexti = i2;
+ } else
+ i2->initval = NULL;
+
return exp;
}
break;
@@ -5559,320 +5172,6 @@ fix_break_continue(INSTRUCTION *list, INSTRUCTION
*b_target, INSTRUCTION *c_targ
}
}
-
-/* append_symbol --- append symbol to the list of symbols
- * installed in the symbol table.
- */
-
-void
-append_symbol(char *name)
-{
- NODE *hp;
-
- /* N.B.: func_install removes func name and reinstalls it;
- * and we get two entries for it here!. destroy_symbol()
- * will find and destroy the Node_func which is what we want.
- */
-
- getnode(hp);
- hp->hname = name; /* shallow copy */
- hp->hnext = symbol_list->hnext;
- symbol_list->hnext = hp;
-}
-
-/* release_symbol --- free symbol list and optionally remove symbol from
symbol table */
-
-void
-release_symbols(NODE *symlist, int keep_globals)
-{
- NODE *hp, *n;
-
- for (hp = symlist->hnext; hp != NULL; hp = n) {
- if (! keep_globals) {
- /* destroys globals, function, and params
- * if still in symbol table and not removed by
func_install
- * due to parse error.
- */
- destroy_symbol(hp->hname);
- }
- n = hp->hnext;
- freenode(hp);
- }
- symlist->hnext = NULL;
-}
-
-/* destroy_symbol --- remove a symbol from symbol table
-* and free all associated memory.
-*/
-
-void
-destroy_symbol(char *name)
-{
- NODE *symbol, *hp;
-
- symbol = lookup(name);
- if (symbol == NULL)
- return;
-
- if (symbol->type == Node_func) {
- char **varnames;
- NODE *func, *n;
-
- func = symbol;
- varnames = func->parmlist;
- if (varnames != NULL)
- efree(varnames);
-
- /* function parameters of type Node_param_list */
- for (n = func->lnode->rnode; n != NULL; ) {
- NODE *np;
- np = n->rnode;
- efree(n->param);
- freenode(n);
- n = np;
- }
- freenode(func->lnode);
- func_count--;
-
- } else if (symbol->type == Node_var_array)
- assoc_clear(symbol);
- else if (symbol->type == Node_var)
- unref(symbol->var_value);
-
- /* remove from symbol table */
- hp = remove_symbol(name);
- efree(hp->hname);
- freenode(hp->hvalue);
- freenode(hp);
-}
-
-#define pool_size d.dl
-#define freei x.xi
-static INSTRUCTION *pool_list;
-static AWK_CONTEXT *curr_ctxt = NULL;
-
-/* new_context --- create a new execution context. */
-
-AWK_CONTEXT *
-new_context()
-{
- AWK_CONTEXT *ctxt;
-
- emalloc(ctxt, AWK_CONTEXT *, sizeof(AWK_CONTEXT), "new_context");
- memset(ctxt, 0, sizeof(AWK_CONTEXT));
- ctxt->srcfiles.next = ctxt->srcfiles.prev = &ctxt->srcfiles;
- ctxt->rule_list.opcode = Op_list;
- ctxt->rule_list.lasti = &ctxt->rule_list;
- return ctxt;
-}
-
-/* set_context --- change current execution context. */
-
-static void
-set_context(AWK_CONTEXT *ctxt)
-{
- pool_list = &ctxt->pools;
- symbol_list = &ctxt->symbols;
- srcfiles = &ctxt->srcfiles;
- rule_list = &ctxt->rule_list;
- install_func = ctxt->install_func;
- curr_ctxt = ctxt;
-}
-
-/*
- * push_context:
- *
- * Switch to the given context after saving the current one. The set
- * of active execution contexts forms a stack; the global or main context
- * is at the bottom of the stack.
- */
-
-void
-push_context(AWK_CONTEXT *ctxt)
-{
- ctxt->prev = curr_ctxt;
- /* save current source and sourceline */
- if (curr_ctxt != NULL) {
- curr_ctxt->sourceline = sourceline;
- curr_ctxt->source = source;
- }
- sourceline = 0;
- source = NULL;
- set_context(ctxt);
-}
-
-/* pop_context --- switch to previous execution context. */
-
-void
-pop_context()
-{
- AWK_CONTEXT *ctxt;
-
- assert(curr_ctxt != NULL);
- ctxt = curr_ctxt->prev;
- /* restore source and sourceline */
- sourceline = ctxt->sourceline;
- source = ctxt->source;
- set_context(ctxt);
-}
-
-/* in_main_context --- are we in the main context ? */
-
-int
-in_main_context()
-{
- assert(curr_ctxt != NULL);
- return (curr_ctxt->prev == NULL);
-}
-
-/* free_context --- free context structure and related data. */
-
-void
-free_context(AWK_CONTEXT *ctxt, int keep_globals)
-{
- SRCFILE *s, *sn;
-
- if (ctxt == NULL)
- return;
-
- assert(curr_ctxt != ctxt);
-
- /* free all code including function codes */
- free_bcpool(&ctxt->pools);
- /* free symbols */
- release_symbols(&ctxt->symbols, keep_globals);
- /* free srcfiles */
- for (s = &ctxt->srcfiles; s != &ctxt->srcfiles; s = sn) {
- sn = s->next;
- if (s->stype != SRC_CMDLINE && s->stype != SRC_STDIN)
- efree(s->fullpath);
- efree(s->src);
- efree(s);
- }
- efree(ctxt);
-}
-
-/* free_bc_internal --- free internal memory of an instruction. */
-
-static void
-free_bc_internal(INSTRUCTION *cp)
-{
- NODE *m;
-
- switch(cp->opcode) {
- case Op_func_call:
- if (cp->func_name != NULL
- && cp->func_name != builtin_func
- )
- efree(cp->func_name);
- break;
- case Op_push_re:
- case Op_match_rec:
- case Op_match:
- case Op_nomatch:
- m = cp->memory;
- if (m->re_reg != NULL)
- refree(m->re_reg);
- if (m->re_exp != NULL)
- unref(m->re_exp);
- if (m->re_text != NULL)
- unref(m->re_text);
- freenode(m);
- break;
- case Op_token: /* token lost during error recovery in yyparse */
- if (cp->lextok != NULL)
- efree(cp->lextok);
- break;
- case Op_illegal:
- cant_happen();
- default:
- break;
- }
-}
-
-
-/* INSTR_CHUNK must be > largest code size (3) */
-#define INSTR_CHUNK 127
-
-/* bcfree --- deallocate instruction */
-
-void
-bcfree(INSTRUCTION *cp)
-{
- cp->opcode = 0;
- cp->nexti = pool_list->freei;
- pool_list->freei = cp;
-}
-
-/* bcalloc --- allocate a new instruction */
-
-INSTRUCTION *
-bcalloc(OPCODE op, int size, int srcline)
-{
- INSTRUCTION *cp;
-
- if (size > 1) {
- /* wide instructions Op_rule, Op_func_call .. */
- emalloc(cp, INSTRUCTION *, (size + 1) * sizeof(INSTRUCTION),
"bcalloc");
- cp->pool_size = size;
- cp->nexti = pool_list->nexti;
- pool_list->nexti = cp++;
- } else {
- INSTRUCTION *pool;
-
- pool = pool_list->freei;
- if (pool == NULL) {
- INSTRUCTION *last;
- emalloc(cp, INSTRUCTION *, (INSTR_CHUNK + 1) *
sizeof(INSTRUCTION), "bcalloc");
-
- cp->pool_size = INSTR_CHUNK;
- cp->nexti = pool_list->nexti;
- pool_list->nexti = cp;
- pool = ++cp;
- last = &pool[INSTR_CHUNK - 1];
- for (; cp <= last; cp++) {
- cp->opcode = 0;
- cp->nexti = cp + 1;
- }
- --cp;
- cp->nexti = NULL;
- }
- cp = pool;
- pool_list->freei = cp->nexti;
- }
-
- memset(cp, 0, size * sizeof(INSTRUCTION));
- cp->opcode = op;
- cp->source_line = srcline;
- return cp;
-}
-
-/* free_bcpool --- free list of instruction memory pools */
-
-static void
-free_bcpool(INSTRUCTION *pl)
-{
- INSTRUCTION *pool, *tmp;
-
- for (pool = pl->nexti; pool != NULL; pool = tmp) {
- INSTRUCTION *cp, *last;
- long psiz;
- psiz = pool->pool_size;
- if (psiz == INSTR_CHUNK)
- last = pool + psiz;
- else
- last = pool + 1;
- for (cp = pool + 1; cp <= last ; cp++) {
- if (cp->opcode != 0)
- free_bc_internal(cp);
- }
- tmp = pool->nexti;
- efree(pool);
- }
- memset(pl, 0, sizeof(INSTRUCTION));
-}
-
-
static inline INSTRUCTION *
list_create(INSTRUCTION *x)
{
diff --git a/builtin.c b/builtin.c
index 724ea6d..6ed7abd 100644
--- a/builtin.c
+++ b/builtin.c
@@ -77,8 +77,10 @@ static NODE *sub_common(int nargs, long how_many, int
backdigs);
#define POP_TWO_SCALARS(s1, s2) \
s2 = POP_SCALAR(); \
s1 = POP(); \
-if ((s1)->type == Node_var_array) \
- DEREF(s2), fatal(_("attempt to use array `%s' in a scalar context"),
array_vname(s1)), 0
+do { if (s1->type == Node_var_array) { \
+DEREF(s2); \
+fatal(_("attempt to use array `%s' in a scalar context"), array_vname(s1)); \
+}} while (FALSE)
/*
@@ -331,8 +333,10 @@ do_index(int nargs)
if ((s2->flags & (STRING|STRCUR)) == 0)
lintwarn(_("index: received non-string second
argument"));
}
- force_string(s1);
- force_string(s2);
+
+ s1 = force_string(s1);
+ s2 = force_string(s2);
+
p1 = s1->stptr;
p2 = s2->stptr;
l1 = s1->stlen;
@@ -499,7 +503,7 @@ do_length(int nargs)
if (do_lint && (tmp->flags & (STRING|STRCUR)) == 0)
lintwarn(_("length: received non-string argument"));
- (void) force_string(tmp);
+ tmp = force_string(tmp);
#ifdef MBS_SUPPORT
if (gawk_mb_cur_max > 1) {
@@ -1345,7 +1349,7 @@ out2:
_("too many arguments supplied for format string"));
}
bchunk(s0, s1 - s0);
- r = make_str_node(obuf, obufout - obuf, ALREADY_MALLOCED);
+ r = make_str_node(obuf, obufout - obuf);
obuf = NULL;
out:
{
@@ -1382,7 +1386,7 @@ printf_common(int nargs)
}
}
- force_string(args_array[0]);
+ args_array[0] = force_string(args_array[0]);
r = format_tree(args_array[0]->stptr, args_array[0]->stlen, args_array,
nargs);
for (i = 0; i < nargs; i++)
DEREF(args_array[i]);
@@ -1495,12 +1499,12 @@ do_substr(int nargs)
if (nargs == 3) {
if (! (d_length >= 1)) {
- if (do_lint == LINT_ALL)
+ if (do_lint == DO_LINT_ALL)
lintwarn(_("substr: length %g is not >= 1"),
d_length);
- else if (do_lint == LINT_INVALID && ! (d_length >= 0))
+ else if (do_lint == DO_LINT_INVALID && ! (d_length >=
0))
lintwarn(_("substr: length %g is not >= 0"),
d_length);
DEREF(t1);
- return Nnull_string;
+ return dupnode(Nnull_string);
}
if (do_lint) {
if (double_to_int(d_length) != d_length)
@@ -1551,10 +1555,10 @@ do_substr(int nargs)
if (t1->stlen == 0) {
/* substr("", 1, 0) produces a warning only if LINT_ALL */
- if (do_lint && (do_lint == LINT_ALL || ((indx | length) != 0)))
+ if (do_lint && (do_lint == DO_LINT_ALL || ((indx | length) !=
0)))
lintwarn(_("substr: source string is zero length"));
DEREF(t1);
- return Nnull_string;
+ return dupnode(Nnull_string);
}
/* get total len of input string, for following checks */
@@ -1571,7 +1575,7 @@ do_substr(int nargs)
lintwarn(_("substr: start index %g is past end of
string"),
d_index);
DEREF(t1);
- return Nnull_string;
+ return dupnode(Nnull_string);
}
if (length > src_len - indx) {
if (do_lint)
@@ -1609,7 +1613,7 @@ do_substr(int nargs)
wp++;
}
*cp = '\0';
- r = make_str_node(substr, cp - substr, ALREADY_MALLOCED);
+ r = make_str_node(substr, cp - substr);
}
#else
r = make_string(t1->stptr + indx, length);
@@ -1668,7 +1672,7 @@ do_strftime(int nargs)
do_gmt = (t3->stlen > 0);
DEREF(t3);
}
-
+
if (nargs >= 2) {
t2 = POP_SCALAR();
if (do_lint && (t2->flags & (NUMCUR|NUMBER)) == 0)
@@ -1680,6 +1684,7 @@ do_strftime(int nargs)
tmp = POP_SCALAR();
if (do_lint && (tmp->flags & (STRING|STRCUR)) == 0)
lintwarn(_("strftime: received non-string first
argument"));
+
t1 = force_string(tmp);
format = t1->stptr;
formatlen = t1->stlen;
@@ -1762,13 +1767,13 @@ do_mktime(int nargs)
& hour, & minute, & second,
& dst);
- if (do_lint /* Ready? Set! Go: */
- && ( (second < 0 || second > 60)
- || (minute < 0 || minute > 60)
- || (hour < 0 || hour > 23)
- || (day < 1 || day > 31)
- || (month < 1 || month > 12) ))
- lintwarn(_("mktime: at least one of the values is out of the default
range"));
+ if (do_lint /* Ready? Set! Go: */
+ && ( (second < 0 || second > 60)
+ || (minute < 0 || minute > 60)
+ || (hour < 0 || hour > 23)
+ || (day < 1 || day > 31)
+ || (month < 1 || month > 12) ))
+ lintwarn(_("mktime: at least one of the values is out
of the default range"));
t1->stptr[t1->stlen] = save;
DEREF(t1);
@@ -1829,11 +1834,9 @@ do_system(int nargs)
return make_number((AWKNUM) ret);
}
-extern NODE **fmt_list; /* declared in eval.c */
-
/* do_print --- print items, separated by OFS, terminated with ORS */
-void
+void
do_print(int nargs, int redirtype)
{
struct redirect *rp = NULL;
@@ -1841,7 +1844,7 @@ do_print(int nargs, int redirtype)
FILE *fp = NULL;
int i;
NODE *redir_exp = NULL;
- NODE *tmp;
+ NODE *tmp = NULL;
assert(nargs <= max_args);
@@ -1862,12 +1865,10 @@ do_print(int nargs, int redirtype)
DEREF(args_array[i]);
fatal(_("attempt to use array `%s' in a scalar
context"), array_vname(tmp));
}
- if (do_lint && tmp->type == Node_var_new)
- lintwarn(_("reference to uninitialized variable `%s'"),
- tmp->vname);
+
if ((tmp->flags & (NUMBER|STRING)) == NUMBER) {
if (OFMTidx == CONVFMTidx)
- (void) force_string(tmp);
+ args_array[i] = force_string(tmp);
else
args_array[i] = format_val(OFMT, OFMTidx, tmp);
}
@@ -2259,7 +2260,7 @@ do_match(int nargs)
it->flags |= MAYBE_NUM; /* user input */
sub = make_number((AWKNUM) (ii));
- lhs = assoc_lookup(dest, sub, FALSE);
+ lhs = assoc_lookup(dest, sub);
unref(*lhs);
*lhs = it;
unref(sub);
@@ -2282,7 +2283,7 @@ do_match(int nargs)
it = make_number((AWKNUM) subpat_start
+ 1);
sub = make_string(buf, slen);
- lhs = assoc_lookup(dest, sub, FALSE);
+ lhs = assoc_lookup(dest, sub);
unref(*lhs);
*lhs = it;
unref(sub);
@@ -2295,7 +2296,7 @@ do_match(int nargs)
it = make_number((AWKNUM) subpat_len);
sub = make_string(buf, slen);
- lhs = assoc_lookup(dest, sub, FALSE);
+ lhs = assoc_lookup(dest, sub);
unref(*lhs);
*lhs = it;
unref(sub);
@@ -2641,7 +2642,7 @@ sub_common(int nargs, long how_many, int backdigs)
if (lhs != NULL) {
if (matches > 0) {
unref(*lhs);
- *lhs = make_str_node(buf, textlen, ALREADY_MALLOCED);
+ *lhs = make_str_node(buf, textlen);
} else
efree(buf);
} else {
diff --git a/cmd.h b/cmd.h
index a0c1788..8f8026a 100644
--- a/cmd.h
+++ b/cmd.h
@@ -28,8 +28,7 @@
#include <readline/history.h>
extern char **command_completion(const char *text, int start, int end);
extern void initialize_pager(FILE *fp); /* debug.c */
-extern NODE **get_varlist(void);
-extern char **get_parmlist(void);
+extern NODE *get_function(void);
#else
#define initialize_pager(x) /* nothing */
#define add_history(x) /* nothing */
diff --git a/command.c b/command.c
index 2b3b349..b705d5e 100644
--- a/command.c
+++ b/command.c
@@ -1,9 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.4.3. */
+/* A Bison parser, made by GNU Bison 2.5. */
-/* Skeleton implementation for Bison's Yacc-like parsers in C
+/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -45,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.4.3"
+#define YYBISON_VERSION "2.5"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -74,7 +73,7 @@
/* Copy the first part of user declarations. */
-/* Line 189 of yacc.c */
+/* Line 268 of yacc.c */
#line 26 "command.y"
#include "awk.h"
@@ -103,7 +102,7 @@ static int num_dim;
static int in_eval = FALSE;
static const char start_EVAL[] = "function @eval(){";
static const char end_EVAL[] = "}";
-static CMDARG *append_statement(CMDARG *alist, char *stmt);
+static CMDARG *append_statement(CMDARG *stmt_list, char *stmt);
static char *next_word(char *p, int len, char **endp);
static NODE *concat_args(CMDARG *a, int count);
@@ -143,8 +142,8 @@ static int find_argument(CMDARG *arg);
#define YYSTYPE CMDARG *
-/* Line 189 of yacc.c */
-#line 148 "command.c"
+/* Line 268 of yacc.c */
+#line 147 "command.c"
/* Enabling traces. */
#ifndef YYDEBUG
@@ -281,8 +280,8 @@ typedef int YYSTYPE;
/* Copy the second part of user declarations. */
-/* Line 264 of yacc.c */
-#line 286 "command.c"
+/* Line 343 of yacc.c */
+#line 285 "command.c"
#ifdef short
# undef short
@@ -384,11 +383,11 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ ||
defined __C99__FUNC__ \
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ ||
defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
# endif
# endif
# endif
@@ -411,24 +410,24 @@ YYID (yyi)
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
-# if (defined __cplusplus && ! defined _STDLIB_H \
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined
__C99__FUNC__ \
+# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ ||
defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined
__C99__FUNC__ \
+# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ ||
defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
@@ -455,23 +454,7 @@ union yyalloc
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
-/* Copy COUNT objects from FROM to TO. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (YYID (0))
-# endif
-# endif
+# define YYCOPY_NEEDED 1
/* Relocate STACK from its old location to the new one. The
local variables YYSIZE and YYSTACKSIZE give the old and new number of
@@ -491,6 +474,26 @@ union yyalloc
#endif
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
@@ -721,8 +724,8 @@ static const yytype_uint8 yyr2[] =
1, 1, 2, 1, 2, 2, 1
};
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
- STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
@@ -801,8 +804,7 @@ static const yytype_int16 yypgoto[] =
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
- number is the opposite. If zero, do what YYDEFACT says.
- If YYTABLE_NINF, syntax error. */
+ number is the opposite. If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -148
static const yytype_int16 yytable[] =
{
@@ -829,6 +831,12 @@ static const yytype_int16 yytable[] =
0, 0, 0, 45
};
+#define yypact_value_is_default(yystate) \
+ ((yystate) == (-151))
+
+#define yytable_value_is_error(yytable_value) \
+ YYID (0)
+
static const yytype_int16 yycheck[] =
{
3, 6, 17, 17, 81, 1, 83, 1, 85, 86,
@@ -914,7 +922,6 @@ do
\
{ \
yychar = (Token); \
yylval = (Value); \
- yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
@@ -956,19 +963,10 @@ while (YYID (0))
#endif
-/* YY_LOCATION_PRINT -- Print the location on the stream.
- This macro was not mandated originally: define only if we know
- we won't break user code: when these are the locations we know. */
+/* This macro is provided for backward compatibility. */
#ifndef YY_LOCATION_PRINT
-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-# define YY_LOCATION_PRINT(File, Loc) \
- fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
-# else
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
#endif
@@ -1156,7 +1154,6 @@ int yydebug;
# define YYMAXDEPTH 10000
#endif
-
#if YYERROR_VERBOSE
@@ -1257,115 +1254,142 @@ yytnamerr (char *yyres, const char *yystr)
}
# endif
-/* Copy into YYRESULT an error message about the unexpected token
- YYCHAR while in state YYSTATE. Return the number of bytes copied,
- including the terminating null byte. If YYRESULT is null, do not
- copy anything; just return the number of bytes that would be
- copied. As a special case, return 0 if an ordinary "syntax error"
- message will do. Return YYSIZE_MAXIMUM if overflow occurs during
- size calculation. */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
- int yyn = yypact[yystate];
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
- if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
- return 0;
- else
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = 0;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - Assume YYFAIL is not used. It's too flawed to consider. See
+ <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+ for details. YYERROR is fine as it does not invoke this
+ function.
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
{
- int yytype = YYTRANSLATE (yychar);
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- int yysize_overflow = 0;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- int yyx;
-
-# if 0
- /* This is so xgettext sees the translatable formats that are
- constructed on the fly. */
- YY_("syntax error, unexpected %s");
- YY_("syntax error, unexpected %s, expecting %s");
- YY_("syntax error, unexpected %s, expecting %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
- char *yyfmt;
- char const *yyf;
- static char const yyunexpected[] = "syntax error, unexpected %s";
- static char const yyexpecting[] = ", expecting %s";
- static char const yyor[] = " or %s";
- char yyformat[sizeof yyunexpected
- + sizeof yyexpecting - 1
- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
- * (sizeof yyor - 1))];
- char const *yyprefix = yyexpecting;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 1;
-
- yyarg[0] = yytname[yytype];
- yyfmt = yystpcpy (yyformat, yyunexpected);
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- yyformat[sizeof yyunexpected - 1] = '\0';
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
- yyfmt = yystpcpy (yyfmt, yyprefix);
- yyprefix = yyor;
- }
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
- yyf = YY_(yyformat);
- yysize1 = yysize + yystrlen (yyf);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or
%s"));
+# undef YYCASE_
+ }
- if (yysize_overflow)
- return YYSIZE_MAXIMUM;
+ yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
- if (yyresult)
- {
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- char *yyp = yyresult;
- int yyi = 0;
- while ((*yyp = *yyf) != '\0')
- {
- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyf += 2;
- }
- else
- {
- yyp++;
- yyf++;
- }
- }
- }
- return yysize;
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
}
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
}
#endif /* YYERROR_VERBOSE */
-
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
@@ -1397,6 +1421,7 @@ yydestruct (yymsg, yytype, yyvaluep)
}
}
+
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
@@ -1423,10 +1448,9 @@ YYSTYPE yylval;
int yynerrs;
-
-/*-------------------------.
-| yyparse or yypush_parse. |
-`-------------------------*/
+/*----------.
+| yyparse. |
+`----------*/
#ifdef YYPARSE_PARAM
#if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus ||
defined _MSC_VER)
@@ -1448,8 +1472,6 @@ yyparse ()
#endif
#endif
{
-
-
int yystate;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
@@ -1604,7 +1626,7 @@ yybackup:
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
- if (yyn == YYPACT_NINF)
+ if (yypact_value_is_default (yyn))
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
@@ -1635,8 +1657,8 @@ yybackup:
yyn = yytable[yyn];
if (yyn <= 0)
{
- if (yyn == 0 || yyn == YYTABLE_NINF)
- goto yyerrlab;
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
@@ -1691,7 +1713,7 @@ yyreduce:
{
case 3:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 109 "command.y"
{
cmd_idx = -1;
@@ -1711,7 +1733,7 @@ yyreduce:
case 5:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 128 "command.y"
{
if (errcount == 0 && cmd_idx >= 0) {
@@ -1766,7 +1788,7 @@ yyreduce:
case 6:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 178 "command.y"
{
yyerrok;
@@ -1775,14 +1797,14 @@ yyreduce:
case 22:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 212 "command.y"
{ want_nodeval = TRUE; }
break;
case 23:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 217 "command.y"
{
if (errcount == 0) {
@@ -1802,7 +1824,7 @@ yyreduce:
case 24:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 235 "command.y"
{
(yyval) = append_statement(arg_list, (char *) start_EVAL);
@@ -1815,14 +1837,14 @@ yyreduce:
case 25:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 242 "command.y"
{ (yyval) = append_statement((yyvsp[(1) - (2)]), lexptr_begin); }
break;
case 26:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 243 "command.y"
{
(yyval) = (yyvsp[(3) - (4)]);
@@ -1831,7 +1853,7 @@ yyreduce:
case 27:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 250 "command.y"
{
arg_list = append_statement((yyvsp[(2) - (3)]), (char *)
end_EVAL);
@@ -1852,7 +1874,7 @@ yyreduce:
case 28:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 266 "command.y"
{
NODE *n;
@@ -1868,7 +1890,7 @@ yyreduce:
case 34:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 285 "command.y"
{
if (cmdtab[cmd_idx].class == D_FRAME
@@ -1879,7 +1901,7 @@ yyreduce:
case 35:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 291 "command.y"
{
int idx = find_argument((yyvsp[(2) - (2)]));
@@ -1896,49 +1918,49 @@ yyreduce:
case 38:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 304 "command.y"
{ want_nodeval = TRUE; }
break;
case 40:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 305 "command.y"
{ want_nodeval = TRUE; }
break;
case 46:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 310 "command.y"
{ want_nodeval = TRUE; }
break;
case 49:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 312 "command.y"
{ want_nodeval = TRUE; }
break;
case 51:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 313 "command.y"
{ want_nodeval = TRUE; }
break;
case 53:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 314 "command.y"
{ want_nodeval = TRUE; }
break;
case 57:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 318 "command.y"
{
if (in_cmd_src((yyvsp[(2) - (2)])->a_string))
@@ -1948,7 +1970,7 @@ yyreduce:
case 58:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 323 "command.y"
{
if (! input_from_tty)
@@ -1958,7 +1980,7 @@ yyreduce:
case 59:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 328 "command.y"
{
int type = 0;
@@ -1989,7 +2011,7 @@ yyreduce:
case 60:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 354 "command.y"
{
if (! in_commands)
@@ -2004,7 +2026,7 @@ yyreduce:
case 61:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 364 "command.y"
{
if (! in_commands)
@@ -2014,7 +2036,7 @@ yyreduce:
case 62:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 369 "command.y"
{
int idx = find_argument((yyvsp[(2) - (2)]));
@@ -2031,14 +2053,14 @@ yyreduce:
case 63:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 380 "command.y"
{ want_nodeval = TRUE; }
break;
case 64:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 381 "command.y"
{
int type;
@@ -2051,7 +2073,7 @@ yyreduce:
case 65:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 389 "command.y"
{
if (in_commands) {
@@ -2067,7 +2089,7 @@ yyreduce:
case 66:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 403 "command.y"
{
if ((yyvsp[(1) - (1)]) != NULL) {
@@ -2082,42 +2104,42 @@ yyreduce:
case 68:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 417 "command.y"
{ (yyval) = NULL; }
break;
case 69:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 422 "command.y"
{ (yyval) = NULL; }
break;
case 74:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 431 "command.y"
{ (yyval) = NULL; }
break;
case 75:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 436 "command.y"
{ (yyval) = NULL; }
break;
case 77:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 439 "command.y"
{ (yyval) = NULL; }
break;
case 78:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 444 "command.y"
{
NODE *n;
@@ -2129,14 +2151,14 @@ yyreduce:
case 79:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 454 "command.y"
{ (yyval) = NULL; }
break;
case 80:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 456 "command.y"
{
if (find_option((yyvsp[(1) - (1)])->a_string) < 0)
@@ -2146,7 +2168,7 @@ yyreduce:
case 81:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 461 "command.y"
{
if (find_option((yyvsp[(1) - (3)])->a_string) < 0)
@@ -2156,7 +2178,7 @@ yyreduce:
case 82:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 469 "command.y"
{
NODE *n;
@@ -2174,56 +2196,56 @@ yyreduce:
case 83:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 485 "command.y"
{ (yyval) = NULL; }
break;
case 88:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 494 "command.y"
{ (yyval) = NULL; }
break;
case 89:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 495 "command.y"
{ want_nodeval = TRUE; }
break;
case 92:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 497 "command.y"
{ want_nodeval = TRUE; }
break;
case 95:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 503 "command.y"
{ (yyval) = NULL; }
break;
case 97:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 509 "command.y"
{ (yyval) = NULL; }
break;
case 99:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 515 "command.y"
{ (yyval) = NULL; }
break;
case 104:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 527 "command.y"
{
int idx = find_argument((yyvsp[(1) - (2)]));
@@ -2240,7 +2262,7 @@ yyreduce:
case 106:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 543 "command.y"
{
(yyvsp[(2) - (2)])->type = D_array; /* dump all items */
@@ -2250,7 +2272,7 @@ yyreduce:
case 107:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 548 "command.y"
{
(yyvsp[(2) - (3)])->type = D_array;
@@ -2260,21 +2282,21 @@ yyreduce:
case 117:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 574 "command.y"
{ (yyval) = NULL; }
break;
case 118:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 576 "command.y"
{ (yyval) = NULL; }
break;
case 119:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 578 "command.y"
{
CMDARG *a;
@@ -2286,7 +2308,7 @@ yyreduce:
case 126:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 594 "command.y"
{
if ((yyvsp[(1) - (3)])->a_int > (yyvsp[(3) - (3)])->a_int)
@@ -2300,28 +2322,28 @@ yyreduce:
case 127:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 606 "command.y"
{ (yyval) = NULL; }
break;
case 134:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 620 "command.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 135:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 622 "command.y"
{ (yyval) = (yyvsp[(1) - (3)]); }
break;
case 137:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 628 "command.y"
{
CMDARG *a;
@@ -2341,21 +2363,21 @@ yyreduce:
case 139:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 647 "command.y"
{ (yyval) = (yyvsp[(1) - (1)]); num_dim = 1; }
break;
case 140:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 649 "command.y"
{ (yyval) = (yyvsp[(1) - (2)]); num_dim++; }
break;
case 142:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 655 "command.y"
{
NODE *n = (yyvsp[(2) - (2)])->a_node;
@@ -2369,7 +2391,7 @@ yyreduce:
case 143:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 664 "command.y"
{
/* a_string is array name, a_count is dimension count */
@@ -2381,14 +2403,14 @@ yyreduce:
case 144:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 674 "command.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 145:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 676 "command.y"
{
NODE *n = (yyvsp[(2) - (2)])->a_node;
@@ -2400,7 +2422,7 @@ yyreduce:
case 146:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 683 "command.y"
{
NODE *n = (yyvsp[(2) - (2)])->a_node;
@@ -2414,35 +2436,35 @@ yyreduce:
case 147:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 695 "command.y"
{ (yyval) = NULL; }
break;
case 148:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 697 "command.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 149:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 702 "command.y"
{ (yyval) = NULL; }
break;
case 150:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 704 "command.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 151:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 709 "command.y"
{
if ((yyvsp[(1) - (1)])->a_int == 0)
@@ -2453,7 +2475,7 @@ yyreduce:
case 152:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 715 "command.y"
{
if ((yyvsp[(2) - (2)])->a_int == 0)
@@ -2464,21 +2486,21 @@ yyreduce:
case 153:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 724 "command.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 154:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 726 "command.y"
{ (yyval) = (yyvsp[(2) - (2)]); }
break;
case 155:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 728 "command.y"
{
(yyvsp[(2) - (2)])->a_int = - (yyvsp[(2) - (2)])->a_int;
@@ -2488,7 +2510,7 @@ yyreduce:
case 156:
-/* Line 1464 of yacc.c */
+/* Line 1821 of yacc.c */
#line 736 "command.y"
{
if (lexptr_begin != NULL) {
@@ -2502,10 +2524,21 @@ yyreduce:
-/* Line 1464 of yacc.c */
-#line 2519 "command.c"
+/* Line 1821 of yacc.c */
+#line 2541 "command.c"
default: break;
}
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
@@ -2533,6 +2566,10 @@ yyreduce:
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
@@ -2540,37 +2577,36 @@ yyerrlab:
#if ! YYERROR_VERBOSE
yyerror (YY_("syntax error"));
#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
{
- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
- {
- YYSIZE_T yyalloc = 2 * yysize;
- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
- yyalloc = YYSTACK_ALLOC_MAXIMUM;
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yyalloc);
- if (yymsg)
- yymsg_alloc = yyalloc;
- else
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- }
- }
-
- if (0 < yysize && yysize <= yymsg_alloc)
- {
- (void) yysyntax_error (yymsg, yystate, yychar);
- yyerror (yymsg);
- }
- else
- {
- yyerror (YY_("syntax error"));
- if (yysize != 0)
- goto yyexhaustedlab;
- }
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
}
+# undef YYSYNTAX_ERROR
#endif
}
@@ -2629,7 +2665,7 @@ yyerrlab1:
for (;;)
{
yyn = yypact[yystate];
- if (yyn != YYPACT_NINF)
+ if (!yypact_value_is_default (yyn))
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -2688,8 +2724,13 @@ yyexhaustedlab:
yyreturn:
if (yychar != YYEMPTY)
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval);
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ }
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
@@ -2714,7 +2755,7 @@ yyreturn:
-/* Line 1684 of yacc.c */
+/* Line 2067 of yacc.c */
#line 746 "command.y"
@@ -2722,7 +2763,7 @@ yyreturn:
/* append_statement --- append 'stmt' to the list of eval awk statements */
static CMDARG *
-append_statement(CMDARG *alist, char *stmt)
+append_statement(CMDARG *stmt_list, char *stmt)
{
CMDARG *a, *arg;
char *s;
@@ -2732,7 +2773,7 @@ append_statement(CMDARG *alist, char *stmt)
if (stmt == start_EVAL) {
len = sizeof(start_EVAL);
- for (a = alist; a != NULL; a = a->next)
+ for (a = stmt_list; a != NULL; a = a->next)
len += strlen(a->a_string) + 1; /* 1 for ',' */
len += EVALSIZE;
@@ -2744,7 +2785,7 @@ append_statement(CMDARG *alist, char *stmt)
slen = sizeof("function @eval(") - 1;
memcpy(s, start_EVAL, slen);
- for (a = alist; a != NULL; a = a->next) {
+ for (a = stmt_list; a != NULL; a = a->next) {
len = strlen(a->a_string);
memcpy(s + slen, a->a_string, len);
slen += len;
@@ -2758,14 +2799,14 @@ append_statement(CMDARG *alist, char *stmt)
}
len = strlen(stmt) + 1; /* 1 for newline */
- s = alist->a_string;
+ s = stmt_list->a_string;
slen = strlen(s);
- ssize = alist->a_count;
+ ssize = stmt_list->a_count;
if (len > ssize - slen) {
ssize = slen + len + EVALSIZE;
erealloc(s, char *, (ssize + 2) * sizeof(char),
"append_statement");
- alist->a_string = s;
- alist->a_count = ssize;
+ stmt_list->a_string = s;
+ stmt_list->a_count = ssize;
}
memcpy(s + slen, stmt, len);
slen += len;
@@ -2775,8 +2816,8 @@ append_statement(CMDARG *alist, char *stmt)
}
if (stmt == end_EVAL)
- erealloc(alist->a_string, char *, slen + 2, "append_statement");
- return alist;
+ erealloc(stmt_list->a_string, char *, slen + 2,
"append_statement");
+ return stmt_list;
#undef EVALSIZE
}
@@ -3136,7 +3177,6 @@ again:
if (c == '"') {
char *str, *p;
- int flags = ALREADY_MALLOCED;
int esc_seen = FALSE;
toklen = lexend - lexptr;
@@ -3165,14 +3205,16 @@ err:
if (! want_nodeval) {
yylval = mk_cmdarg(D_string);
- yylval->a_string = estrdup(str, p - str);
+ yylval->a_string = str;
append_cmdarg(yylval);
return D_STRING;
} else { /* awk string */
+ size_t len;
+ len = p - str;
if (esc_seen)
- flags |= SCAN;
+ len = scan_escape(str, len);
yylval = mk_cmdarg(D_node);
- yylval->a_node = make_str_node(str, p - str, flags);
+ yylval->a_node = make_str_node(str, len);
append_cmdarg(yylval);
return D_NODE;
}
@@ -3322,7 +3364,7 @@ concat_args(CMDARG *arg, int count)
}
str[len] = '\0';
efree(tmp);
- return make_str_node(str, len, ALREADY_MALLOCED);
+ return make_str_node(str, len);
}
/* find_command --- find the index in 'cmdtab' using exact,
@@ -3356,8 +3398,10 @@ find_command(const char *token, size_t toklen)
&& strncmp(name, token, toklen) == 0
)
return i;
- if (*name > *token)
+
+ if (*name > *token || i == (k - 1))
try_exact = FALSE;
+
if (abrv_match < 0) {
abrv = cmdtab[i].abbrvn;
if (abrv[0] == token[0]) {
@@ -3497,6 +3541,7 @@ command_completion(const char *text, int start, int end)
return NULL;
}
}
+
if (this_cmd == D_print || this_cmd == D_printf)
return rl_completion_matches(text, variable_generator);
return NULL;
@@ -3557,7 +3602,7 @@ argument_generator(const char *text, int state)
{
static size_t textlen;
static int idx;
- char *name;
+ const char *name;
if (! state) { /* first time */
textlen = strlen(text);
@@ -3565,12 +3610,12 @@ argument_generator(const char *text, int state)
}
if (this_cmd == D_help) {
- while ((name = (char *) cmdtab[idx++].name) != NULL) {
+ while ((name = cmdtab[idx++].name) != NULL) {
if (strncmp(name, text, textlen) == 0)
return estrdup(name, strlen(name));
}
} else {
- while ((name = (char *) argtab[idx].name) != NULL) {
+ while ((name = argtab[idx].name) != NULL) {
if (this_cmd != argtab[idx++].cmd)
continue;
if (strncmp(name, text, textlen) == 0)
@@ -3587,45 +3632,39 @@ variable_generator(const char *text, int state)
{
static size_t textlen;
static int idx = 0;
- static char **pnames = NULL;
- static NODE **var_table = NULL;
- char *name;
- NODE *hp;
+ static NODE *func = NULL;
+ static NODE **vars = NULL;
+ const char *name;
+ NODE *r;
if (! state) { /* first time */
textlen = strlen(text);
- if (var_table != NULL)
- efree(var_table);
- var_table = get_varlist();
+ if (vars != NULL)
+ efree(vars);
+ vars = variable_list();
idx = 0;
- pnames = get_parmlist(); /* names of function params in
- * current context; the array
- * is NULL terminated in
- * awkgram.y (func_install).
- */
+ func = get_function(); /* function in current context */
}
/* function params */
- while (pnames != NULL) {
- name = pnames[idx];
- if (name == NULL) {
- pnames = NULL; /* don't try to match params again */
+ while (func != NULL) {
+ if (idx >= func->param_cnt) {
+ func = NULL; /* don't try to match params again */
idx = 0;
break;
}
- idx++;
+ name = func->fparms[idx++].param;
if (strncmp(name, text, textlen) == 0)
return estrdup(name, strlen(name));
}
/* globals */
- while ((hp = var_table[idx]) != NULL) {
- idx++;
- if (hp->hvalue->type == Node_func)
- continue;
- if (strncmp(hp->hname, text, textlen) == 0)
- return estrdup(hp->hname, hp->hlength);
+ while ((r = vars[idx++]) != NULL) {
+ name = r->vname;
+ if (strncmp(name, text, textlen) == 0)
+ return estrdup(name, strlen(name));
}
+
return NULL;
}
@@ -3651,4 +3690,3 @@ history_expand_line(char **line)
#endif
-
diff --git a/command.y b/command.y
index bcaa74f..d2a61a0 100644
--- a/command.y
+++ b/command.y
@@ -50,7 +50,7 @@ static int num_dim;
static int in_eval = FALSE;
static const char start_EVAL[] = "function @eval(){";
static const char end_EVAL[] = "}";
-static CMDARG *append_statement(CMDARG *alist, char *stmt);
+static CMDARG *append_statement(CMDARG *stmt_list, char *stmt);
static char *next_word(char *p, int len, char **endp);
static NODE *concat_args(CMDARG *a, int count);
@@ -749,7 +749,7 @@ nls
/* append_statement --- append 'stmt' to the list of eval awk statements */
static CMDARG *
-append_statement(CMDARG *alist, char *stmt)
+append_statement(CMDARG *stmt_list, char *stmt)
{
CMDARG *a, *arg;
char *s;
@@ -759,7 +759,7 @@ append_statement(CMDARG *alist, char *stmt)
if (stmt == start_EVAL) {
len = sizeof(start_EVAL);
- for (a = alist; a != NULL; a = a->next)
+ for (a = stmt_list; a != NULL; a = a->next)
len += strlen(a->a_string) + 1; /* 1 for ',' */
len += EVALSIZE;
@@ -771,7 +771,7 @@ append_statement(CMDARG *alist, char *stmt)
slen = sizeof("function @eval(") - 1;
memcpy(s, start_EVAL, slen);
- for (a = alist; a != NULL; a = a->next) {
+ for (a = stmt_list; a != NULL; a = a->next) {
len = strlen(a->a_string);
memcpy(s + slen, a->a_string, len);
slen += len;
@@ -785,14 +785,14 @@ append_statement(CMDARG *alist, char *stmt)
}
len = strlen(stmt) + 1; /* 1 for newline */
- s = alist->a_string;
+ s = stmt_list->a_string;
slen = strlen(s);
- ssize = alist->a_count;
+ ssize = stmt_list->a_count;
if (len > ssize - slen) {
ssize = slen + len + EVALSIZE;
erealloc(s, char *, (ssize + 2) * sizeof(char),
"append_statement");
- alist->a_string = s;
- alist->a_count = ssize;
+ stmt_list->a_string = s;
+ stmt_list->a_count = ssize;
}
memcpy(s + slen, stmt, len);
slen += len;
@@ -802,8 +802,8 @@ append_statement(CMDARG *alist, char *stmt)
}
if (stmt == end_EVAL)
- erealloc(alist->a_string, char *, slen + 2, "append_statement");
- return alist;
+ erealloc(stmt_list->a_string, char *, slen + 2,
"append_statement");
+ return stmt_list;
#undef EVALSIZE
}
@@ -1163,7 +1163,6 @@ again:
if (c == '"') {
char *str, *p;
- int flags = ALREADY_MALLOCED;
int esc_seen = FALSE;
toklen = lexend - lexptr;
@@ -1192,14 +1191,16 @@ err:
if (! want_nodeval) {
yylval = mk_cmdarg(D_string);
- yylval->a_string = estrdup(str, p - str);
+ yylval->a_string = str;
append_cmdarg(yylval);
return D_STRING;
} else { /* awk string */
+ size_t len;
+ len = p - str;
if (esc_seen)
- flags |= SCAN;
+ len = scan_escape(str, len);
yylval = mk_cmdarg(D_node);
- yylval->a_node = make_str_node(str, p - str, flags);
+ yylval->a_node = make_str_node(str, len);
append_cmdarg(yylval);
return D_NODE;
}
@@ -1349,7 +1350,7 @@ concat_args(CMDARG *arg, int count)
}
str[len] = '\0';
efree(tmp);
- return make_str_node(str, len, ALREADY_MALLOCED);
+ return make_str_node(str, len);
}
/* find_command --- find the index in 'cmdtab' using exact,
@@ -1383,8 +1384,10 @@ find_command(const char *token, size_t toklen)
&& strncmp(name, token, toklen) == 0
)
return i;
- if (*name > *token)
+
+ if (*name > *token || i == (k - 1))
try_exact = FALSE;
+
if (abrv_match < 0) {
abrv = cmdtab[i].abbrvn;
if (abrv[0] == token[0]) {
@@ -1524,6 +1527,7 @@ command_completion(const char *text, int start, int end)
return NULL;
}
}
+
if (this_cmd == D_print || this_cmd == D_printf)
return rl_completion_matches(text, variable_generator);
return NULL;
@@ -1584,7 +1588,7 @@ argument_generator(const char *text, int state)
{
static size_t textlen;
static int idx;
- char *name;
+ const char *name;
if (! state) { /* first time */
textlen = strlen(text);
@@ -1592,12 +1596,12 @@ argument_generator(const char *text, int state)
}
if (this_cmd == D_help) {
- while ((name = (char *) cmdtab[idx++].name) != NULL) {
+ while ((name = cmdtab[idx++].name) != NULL) {
if (strncmp(name, text, textlen) == 0)
return estrdup(name, strlen(name));
}
} else {
- while ((name = (char *) argtab[idx].name) != NULL) {
+ while ((name = argtab[idx].name) != NULL) {
if (this_cmd != argtab[idx++].cmd)
continue;
if (strncmp(name, text, textlen) == 0)
@@ -1614,45 +1618,39 @@ variable_generator(const char *text, int state)
{
static size_t textlen;
static int idx = 0;
- static char **pnames = NULL;
- static NODE **var_table = NULL;
- char *name;
- NODE *hp;
+ static NODE *func = NULL;
+ static NODE **vars = NULL;
+ const char *name;
+ NODE *r;
if (! state) { /* first time */
textlen = strlen(text);
- if (var_table != NULL)
- efree(var_table);
- var_table = get_varlist();
+ if (vars != NULL)
+ efree(vars);
+ vars = variable_list();
idx = 0;
- pnames = get_parmlist(); /* names of function params in
- * current context; the array
- * is NULL terminated in
- * awkgram.y (func_install).
- */
+ func = get_function(); /* function in current context */
}
/* function params */
- while (pnames != NULL) {
- name = pnames[idx];
- if (name == NULL) {
- pnames = NULL; /* don't try to match params again */
+ while (func != NULL) {
+ if (idx >= func->param_cnt) {
+ func = NULL; /* don't try to match params again */
idx = 0;
break;
}
- idx++;
+ name = func->fparms[idx++].param;
if (strncmp(name, text, textlen) == 0)
return estrdup(name, strlen(name));
}
/* globals */
- while ((hp = var_table[idx]) != NULL) {
- idx++;
- if (hp->hvalue->type == Node_func)
- continue;
- if (strncmp(hp->hname, text, textlen) == 0)
- return estrdup(hp->hname, hp->hlength);
+ while ((r = vars[idx++]) != NULL) {
+ name = r->vname;
+ if (strncmp(name, text, textlen) == 0)
+ return estrdup(name, strlen(name));
}
+
return NULL;
}
@@ -1677,4 +1675,3 @@ history_expand_line(char **line)
}
#endif
-
diff --git a/configure b/configure
index 2fc0835..aa4a04b 100755
--- a/configure
+++ b/configure
@@ -748,8 +748,15 @@ LDFLAGS
LIBS
CPPFLAGS
CPP
+CPPFLAGS
YACC
-YFLAGS'
+YFLAGS
+CC
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CPPFLAGS'
# Initialize some variables set by options.
@@ -5488,7 +5495,7 @@ $as_echo_n "checking for special development options... "
>&6; }
if test -f $srcdir/.developing
then
# add other debug flags as appropriate, save GAWKDEBUG for emergencies
- CFLAGS="$CFLAGS -DARRAYDEBUG -DYYDEBUG"
+ CFLAGS="$CFLAGS -DARRAYDEBUG"
if grep dbug $srcdir/.developing
then
CFLAGS="$CFLAGS -DDBUG"
@@ -5498,7 +5505,7 @@ then
# enable debugging using macros also
if test "$GCC" = yes
then
- CFLAGS="$CFLAGS -Wall -fno-builtin -g3 -gdwarf-2"
+ CFLAGS="$CFLAGS -Wall"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
diff --git a/configure.ac b/configure.ac
index d532963..4b266df 100644
--- a/configure.ac
+++ b/configure.ac
@@ -80,7 +80,7 @@ AC_MSG_CHECKING([for special development options])
if test -f $srcdir/.developing
then
# add other debug flags as appropriate, save GAWKDEBUG for emergencies
- CFLAGS="$CFLAGS -DARRAYDEBUG -DYYDEBUG"
+ CFLAGS="$CFLAGS -DARRAYDEBUG"
if grep dbug $srcdir/.developing
then
CFLAGS="$CFLAGS -DDBUG"
@@ -90,7 +90,7 @@ then
# enable debugging using macros also
if test "$GCC" = yes
then
- CFLAGS="$CFLAGS -Wall -fno-builtin -g3 -gdwarf-2"
+ CFLAGS="$CFLAGS -Wall"
fi
AC_MSG_RESULT([yes])
else
diff --git a/debug.c b/debug.c
index 9b9db34..a0ccdbd 100644
--- a/debug.c
+++ b/debug.c
@@ -43,8 +43,6 @@ extern int r_interpret(INSTRUCTION *);
extern int zzparse(void);
#define read_command() (void) zzparse()
-extern int free_instruction(INSTRUCTION *, int *);
-extern void destroy_symbol(char *name);
extern const char *redir2str(int redirtype);
static char *linebuf = NULL; /* used to print a single line of source */
@@ -266,7 +264,7 @@ static void save_options(const char *file);
/* pager */
jmp_buf pager_quit_tag;
-int pager_quit_tag_valid;
+int pager_quit_tag_valid = FALSE;
static int screen_width = INT_MAX; /* no of columns */
static int screen_height = INT_MAX; /* no of rows */
static int pager_lines_printed = 0; /* no of lines printed so far */
@@ -306,8 +304,8 @@ static struct list_item *add_item(struct list_item *list,
int type, NODE *symbol
static void delete_item(struct list_item *d);
static int breakpoint_triggered(BREAKPOINT *b);
static int watchpoint_triggered(struct list_item *w);
-
static void print_instruction(INSTRUCTION *pc, Func_print print_func, FILE
*fp, int in_dump);
+static int print_code(INSTRUCTION *pc, void *x);
static void next_command();
static char *g_readline(const char *prompt);
static int prompt_yes_no(const char *, char , int , FILE *);
@@ -334,9 +332,6 @@ struct command_source
static struct command_source *cmd_src = NULL;
-#define get_param_count(f) (f)->lnode->param_cnt
-#define get_params(f) (f)->parmlist
-
#define CHECK_PROG_RUNNING() \
do { \
@@ -718,6 +713,8 @@ list:
int
do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
{
+ NODE **table;
+
if (arg == NULL || arg->type != D_argument)
return FALSE;
@@ -803,7 +800,6 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
INSTRUCTION *pc;
int arg_count, pcount;
int i, from, to;
- char **pnames;
CHECK_PROG_RUNNING();
f = find_frame(cur_frame);
@@ -814,8 +810,7 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
return FALSE;
}
- pcount = get_param_count(func); /* # of defined params */
- pnames = get_params(func); /* param names */
+ pcount = func->param_cnt; /* # of defined params */
pc = (INSTRUCTION *) f->reti; /* Op_func_call
instruction */
arg_count = (pc + 1)->expr_count; /* # of arguments
supplied */
@@ -835,7 +830,7 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
r = f->stack[i];
if (r->type == Node_array_ref)
r = r->orig_array;
- fprintf(out_fp, "%s = ", pnames[i]);
+ fprintf(out_fp, "%s = ", func->fparms[i].param);
print_symbol(r, TRUE);
}
if (to < from)
@@ -847,25 +842,28 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
break;
case A_VARIABLES:
+ table = variable_list();
initialize_pager(out_fp);
if (setjmp(pager_quit_tag) == 0) {
gprintf(out_fp, _("All defined variables:\n\n"));
- print_vars(gprintf, out_fp);
+ print_vars(table, gprintf, out_fp);
}
+ efree(table);
break;
case A_FUNCTIONS:
+ table = function_list(TRUE);
initialize_pager(out_fp);
if (setjmp(pager_quit_tag) == 0) {
gprintf(out_fp, _("All defined functions:\n\n"));
pf_data.print_func = gprintf;
pf_data.fp = out_fp;
pf_data.defn = TRUE;
- (void) foreach_func((int (*)(INSTRUCTION *, void *))
print_function,
- FALSE, /* sort */
- &pf_data /* data */
- );
+ (void) foreach_func(table,
+ (int (*)(INSTRUCTION *, void *))
print_function,
+ &pf_data);
}
+ efree(table);
break;
case A_DISPLAY:
@@ -976,6 +974,7 @@ find_param(const char *name, long num, char **pname)
{
NODE *r = NULL;
NODE *f;
+ char *fparam;
if (pname)
*pname = NULL;
@@ -985,20 +984,18 @@ find_param(const char *name, long num, char **pname)
f = find_frame(num);
if (f->func_node != NULL) { /* in function */
NODE *func;
- char **pnames;
int i, pcount;
func = f->func_node;
- pnames = get_params(func);
- pcount = get_param_count(func);
-
+ pcount = func->param_cnt;
for (i = 0; i < pcount; i++) {
- if (STREQ(name, pnames[i])) {
+ fparam = func->fparms[i].param;
+ if (STREQ(name, fparam)) {
r = f->stack[i];
if (r->type == Node_array_ref)
r = r->orig_array;
if (pname)
- *pname = pnames[i];
+ *pname = fparam;
break;
}
}
@@ -1058,7 +1055,7 @@ print_field(long field_num)
static int
print_array(volatile NODE *arr, char *arr_name)
{
- NODE *bucket;
+ NODE *subs;
NODE **list;
int i;
size_t num_elems = 0;
@@ -1066,7 +1063,7 @@ print_array(volatile NODE *arr, char *arr_name)
volatile int ret = 0;
volatile jmp_buf pager_quit_tag_stack;
- if (arr->var_array == NULL || arr->table_size == 0) {
+ if (array_empty(arr)) {
gprintf(out_fp, _("array `%s' is empty\n"), arr_name);
return 0;
}
@@ -1079,12 +1076,12 @@ print_array(volatile NODE *arr, char *arr_name)
PUSH_BINDING(pager_quit_tag_stack, pager_quit_tag,
pager_quit_tag_valid);
if (setjmp(pager_quit_tag) == 0) {
for (i = 0; ret == 0 && i < num_elems; i++) {
- bucket = list[i];
- r = bucket->ahvalue;
+ subs = list[i];
+ r = *assoc_lookup((NODE *) arr, subs);
if (r->type == Node_var_array)
ret = print_array(r, r->vname);
else {
- gprintf(out_fp, "%s[\"%s\"] = ", arr_name,
bucket->ahname_str);
+ gprintf(out_fp, "%s[\"%s\"] = ", arr_name,
subs->stptr);
valinfo((NODE *) r, gprintf, out_fp);
}
}
@@ -1214,7 +1211,7 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
switch (r->type) {
case Node_var_new:
r->type = Node_var;
- r->var_value = Nnull_string;
+ r->var_value = dupnode(Nnull_string);
/* fall through */
case Node_var:
lhs = &r->var_value;
@@ -1254,7 +1251,7 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
else {
arg = arg->next;
val = arg->a_node;
- lhs = assoc_lookup(r, subs, FALSE);
+ lhs = assoc_lookup(r, subs);
unref(*lhs);
*lhs = dupnode(val);
fprintf(out_fp, "%s[\"%s\"] = ", name,
subs->stptr);
@@ -1263,12 +1260,10 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
} else {
if (value == NULL) {
NODE *array;
-
- getnode(array);
- array->type = Node_var_array;
- array->var_array = NULL;
+ array = make_array();
array->vname = estrdup(subs->stptr,
subs->stlen);
- *assoc_lookup(r, subs, FALSE) = array;
+ array->parent_array = r;
+ *assoc_lookup(r, subs) = array;
r = array;
} else if (value->type != Node_var_array) {
d_error(_("attempt to use scalar
`%s[\"%s\"]' as array"),
@@ -1305,7 +1300,7 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
break;
}
return FALSE;
-}
+}
/* find_item --- find an item in the watch/display list */
@@ -1377,14 +1372,18 @@ add_item(struct list_item *list, int type, NODE
*symbol, char *pname)
d->fcall_count = fcall_count - cur_frame;
}
- if (type == D_field) { /* field number */
+ if (type == D_field) {
+ /* field number */
d->symbol = symbol;
d->flags |= FIELD_NUM;
- } else if (type == D_subscript) { /* subscript */
+ } else if (type == D_subscript) {
+ /* subscript */
d->symbol = symbol;
d->flags |= SUBSCRIPT;
- } else /* array or variable */
+ } else {
+ /* array or variable */
d->symbol = symbol;
+ }
/* add to list */
d->next = list->next;
@@ -1429,7 +1428,7 @@ do_add_item(struct list_item *list, CMDARG *arg)
for (i = 0; i < count; i++) {
arg = arg->next;
subs[i] = dupnode(arg->a_node);
- (void) force_string(subs[i]);
+ subs[i] = force_string(subs[i]);
}
item->subs = subs;
item->num_subs = count;
@@ -1597,7 +1596,6 @@ condition_triggered(struct condition *cndn)
}
-
static int
find_subscript(struct list_item *item, NODE **ptr)
{
@@ -1616,7 +1614,8 @@ find_subscript(struct list_item *item, NODE **ptr)
else if (i < count - 1)
return -1;
}
- *ptr = r;
+ if (r != NULL)
+ *ptr = r;
return 0;
}
@@ -1646,8 +1645,7 @@ cmp_val(struct list_item *w, NODE *old, NODE *new)
if (new->type == Node_val) /* 7 */
return TRUE;
/* new->type == Node_var_array */ /* 8 */
- if (new->var_array != NULL)
- size = new->table_size;
+ size = new->table_size;
if (w->cur_size == size)
return FALSE;
return TRUE;
@@ -1721,7 +1719,7 @@ watchpoint_triggered(struct list_item *w)
w->flags &= ~CUR_IS_ARRAY;
w->cur_value = dupnode(t2);
} else
- w->cur_size = (t2->var_array != NULL) ? t2->table_size
: 0;
+ w->cur_size = (t2->type == Node_var_array) ?
t2->table_size : 0;
} else if (! t1) { /* 1, 2 */
w->old_value = 0;
/* new != NULL */
@@ -1729,7 +1727,7 @@ watchpoint_triggered(struct list_item *w)
w->cur_value = dupnode(t2);
else {
w->flags |= CUR_IS_ARRAY;
- w->cur_size = (t2->var_array != NULL) ? t2->table_size
: 0;
+ w->cur_size = (t2->type == Node_var_array) ?
t2->table_size : 0;
}
} else /* if (t1->type == Node_val) */ { /* 4, 5, 6 */
w->old_value = w->cur_value;
@@ -1737,7 +1735,7 @@ watchpoint_triggered(struct list_item *w)
w->cur_value = 0;
else if (t2->type == Node_var_array) {
w->flags |= CUR_IS_ARRAY;
- w->cur_size = (t2->var_array != NULL) ? t2->table_size
: 0;
+ w->cur_size = t2->table_size;
} else
w->cur_value = dupnode(t2);
}
@@ -1763,7 +1761,7 @@ initialize_watch_item(struct list_item *w)
w->cur_value = (NODE *) 0;
else if (r->type == Node_var_array) { /* it's a sub-array */
w->flags |= CUR_IS_ARRAY;
- w->cur_size = (r->var_array != NULL) ? r->table_size :
0;
+ w->cur_size = r->table_size;
} else
w->cur_value = dupnode(r);
} else if (IS_FIELD(w)) {
@@ -1780,7 +1778,7 @@ initialize_watch_item(struct list_item *w)
w->cur_value = dupnode(r);
} else if (symbol->type == Node_var_array) {
w->flags |= CUR_IS_ARRAY;
- w->cur_size = (symbol->var_array != NULL) ?
symbol->table_size : 0;
+ w->cur_size = symbol->table_size;
} /* else
can't happen */
}
@@ -1872,19 +1870,17 @@ print_function(INSTRUCTION *pc, void *x)
{
NODE *func;
int i, pcount;
- char **pnames;
struct pf_data *data = (struct pf_data *) x;
int defn = data->defn;
Func_print print_func = data->print_func;
FILE *fp = data->fp;
func = pc->func_body;
- pcount = get_param_count(func);
- pnames = get_params(func);
+ pcount = func->param_cnt;
- print_func(fp, "%s(", func->lnode->param);
+ print_func(fp, "%s(", func->vname);
for (i = 0; i < pcount; i++) {
- print_func(fp, "%s", pnames[i]);
+ print_func(fp, "%s", func->fparms[i].param);
if (i < pcount - 1)
print_func(fp, ", ");
}
@@ -2350,7 +2346,7 @@ func:
rp = func->code_ptr;
if ((b = set_breakpoint_at(rp, rp->source_line, FALSE)) == NULL)
fprintf(out_fp, _("Can't set breakpoint in function
`%s'\n"),
- func->lnode->param);
+ func->vname);
else if (temporary)
b->flags |= BP_TEMP;
lineno = b->bpi->source_line;
@@ -2477,7 +2473,7 @@ func:
}
if (! bp_found)
fprintf(out_fp, _("No breakpoint(s) at entry to
function `%s'\n"),
- func->lnode->param);
+ func->vname);
else
fprintf(out_fp, "\n");
/* fall through */
@@ -2672,19 +2668,17 @@ do_disable_breakpoint(CMDARG *arg, int cmd
ATTRIBUTE_UNUSED)
#ifdef HAVE_LIBREADLINE
-/* get_parmlist --- list of function params in current context */
+/* get_function --- function definition in current context */
-char **
-get_parmlist()
+NODE *
+get_function()
{
NODE *func;
if (! prog_running)
return NULL;
func = find_frame(cur_frame)->func_node;
- if (func == NULL) /* in main */
- return NULL;
- return func->parmlist;
+ return func;
}
/* initialize_readline --- initialize readline */
@@ -2915,9 +2909,9 @@ do_run(CMDARG *arg ATTRIBUTE_UNUSED, int cmd
ATTRIBUTE_UNUSED)
fatal_tag_valid = FALSE;
prog_running = FALSE;
fprintf(out_fp, _("Program exited %s with exit value: %d\n"),
- (! exiting && exit_val != EXIT_SUCCESS)
? "abnormally"
-
: "normally",
- exit_val);
+ (! exiting && exit_val != EXIT_SUCCESS) ? "abnormally"
+ : "normally",
+ exit_val);
need_restart = TRUE;
return FALSE;
}
@@ -3117,7 +3111,6 @@ do_next(CMDARG *arg, int cmd)
static int
check_nexti(INSTRUCTION **pi)
{
-
/* make sure not to step inside function calls */
if (fcall_count < stop.fcall_count) {
@@ -3206,7 +3199,7 @@ check_return(INSTRUCTION **pi)
int
do_return(CMDARG *arg, int cmd)
{
- NODE *func;
+ NODE *func, *n;
CHECK_PROG_RUNNING();
func = find_frame(cur_frame)->func_node;
@@ -3223,12 +3216,11 @@ do_return(CMDARG *arg, int cmd)
stop.check_func = check_return;
- if (arg != NULL && arg->type == D_node) { /* optional return
value */
- NODE *n;
+ if (arg != NULL && arg->type == D_node) /* optional return value */
n = dupnode(arg->a_node);
- PUSH(n);
- } else
- PUSH(Nnull_string);
+ else
+ n = dupnode(Nnull_string);
+ PUSH(n);
return TRUE;
}
@@ -3297,7 +3289,7 @@ do_until(CMDARG *arg, int cmd)
s = source_find(arg->a_string);
arg = arg->next;
if (s == NULL || arg == NULL
- || (arg->type != D_int && arg->type != D_func))
+ || (arg->type != D_int && arg->type != D_func))
return FALSE;
src = s->src;
if (arg->type == D_func)
@@ -3327,7 +3319,7 @@ func:
}
}
fprintf(out_fp, _("Can't find specified location in function
`%s'\n"),
- func->lnode->param);
+ func->vname);
/* fall through */
default:
return FALSE;
@@ -3596,7 +3588,6 @@ pre_execute(INSTRUCTION **pi)
return TRUE;
case Op_func:
- case Op_ext_func:
case Op_var_update:
return TRUE;
@@ -3631,7 +3622,7 @@ pre_execute(INSTRUCTION **pi)
/* print_memory --- print a scalar value */
static void
-print_memory(NODE *m, char **fparms, Func_print print_func, FILE *fp)
+print_memory(NODE *m, NODE *func, Func_print print_func, FILE *fp)
{
switch (m->type) {
case Node_val:
@@ -3658,8 +3649,8 @@ print_memory(NODE *m, char **fparms, Func_print
print_func, FILE *fp)
break;
case Node_param_list:
- assert(fparms != NULL);
- print_func(fp, "%s", fparms[m->param_cnt]);
+ assert(func != NULL);
+ print_func(fp, "%s", func->fparms[m->param_cnt].param);
break;
case Node_var:
@@ -3678,9 +3669,8 @@ print_memory(NODE *m, char **fparms, Func_print
print_func, FILE *fp)
static void
print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int
in_dump)
{
- static char **fparms = NULL;
int pcount = 0;
- NODE *func = NULL;
+ static NODE *func = NULL;
static int noffset = 0;
if (noffset == 0) {
@@ -3691,25 +3681,17 @@ print_instruction(INSTRUCTION *pc, Func_print
print_func, FILE *fp, int in_dump)
if (pc->opcode == Op_func) {
func = pc->func_body;
- fparms = get_params(func);
- pcount = get_param_count(func);
+ pcount = func->param_cnt;
if (in_dump) {
int j;
- print_func(fp, "\n\t# Function: %s (",
func->lnode->param);
+ print_func(fp, "\n\t# Function: %s (", func->vname);
for (j = 0; j < pcount; j++) {
- print_func(fp, "%s", fparms[j]);
+ print_func(fp, "%s", func->fparms[j].param);
if (j < pcount - 1)
print_func(fp, ", ");
}
print_func(fp, ")\n\n");
}
- } else if (pc->opcode == Op_ext_func) {
- func = pc->func_body;
- fparms = get_params(func);
- pcount = get_param_count(func);
- if (in_dump)
- print_func(fp, "\n\t# Extension function: %s (... %d
params ...)\n\n",
- func->lnode->param, pcount);
} else if (pc->opcode == Op_rule) {
if (in_dump)
print_func(fp, "\n\t# %s\n\n", ruletab[pc->in_rule]);
@@ -3725,12 +3707,8 @@ print_instruction(INSTRUCTION *pc, Func_print
print_func, FILE *fp, int in_dump)
pc->source_line, pc, opcode2str(pc->opcode));
if (prog_running && ! in_dump) {
- /* find params in the current frame */
+ /* find Node_func if in function */
func = find_frame(0)->func_node;
- if (func != NULL)
- fparms = get_params(func);
- /* else
- fparms = NULL; */
}
@@ -3748,10 +3726,6 @@ print_instruction(INSTRUCTION *pc, Func_print
print_func, FILE *fp, int in_dump)
pc->target_assign, pc->do_reference ? "TRUE" :
"FALSE");
break;
- case Op_ext_func:
- print_func(fp, "[param_cnt = %d]\n", pcount);
- break;
-
case Op_func:
print_func(fp, "[param_cnt = %d] [source_file = %s]\n", pcount,
pc->source_file ? pc->source_file : "cmd.
line");
@@ -3816,7 +3790,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func,
FILE *fp, int in_dump)
case Op_arrayfor_incr:
print_func(fp, "[array_var = %s] [target_jmp = %p]\n",
pc->array_var->type == Node_param_list ?
- fparms[pc->array_var->param_cnt] :
pc->array_var->vname,
+ func->fparms[pc->array_var->param_cnt].param
: pc->array_var->vname,
pc->target_jmp);
break;
@@ -3831,13 +3805,13 @@ print_instruction(INSTRUCTION *pc, Func_print
print_func, FILE *fp, int in_dump)
break;
case Op_builtin:
- {
- const char *fname = getfname(pc->builtin);
- if (fname == NULL)
- print_func(fp, "(extension func) [arg_count = %ld]\n",
pc->expr_count);
- else
- print_func(fp, "%s [arg_count = %ld]\n", fname,
pc->expr_count);
- }
+ print_func(fp, "%s [arg_count = %ld]\n", getfname(pc->builtin),
+ pc->expr_count);
+ break;
+
+ case Op_ext_builtin:
+ print_func(fp, "%s [arg_count = %ld]\n", (pc + 1)->func_name,
+ pc->expr_count);
break;
case Op_subscript:
@@ -3846,7 +3820,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func,
FILE *fp, int in_dump)
break;
case Op_store_sub:
- print_memory(pc->memory, fparms, print_func, fp);
+ print_memory(pc->memory, func, print_func, fp);
print_func(fp, " [sub_count = %ld]\n", pc->expr_count);
break;
@@ -3889,9 +3863,17 @@ print_instruction(INSTRUCTION *pc, Func_print
print_func, FILE *fp, int in_dump)
print_func(fp, "[exec_count = %ld]\n", pc->exec_count);
break;
- case Op_store_var:
+ case Op_store_var:
+ print_memory(pc->memory, func, print_func, fp);
+ if (pc->initval != NULL) {
+ print_func(fp, " = ");
+ print_memory(pc->initval, func, print_func, fp);
+ }
+ print_func(fp, "\n");
+ break;
+
case Op_push_lhs:
- print_memory(pc->memory, fparms, print_func, fp);
+ print_memory(pc->memory, func, print_func, fp);
print_func(fp, " [do_reference = %s]\n",
pc->do_reference ? "TRUE" : "FALSE");
break;
@@ -3912,7 +3894,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func,
FILE *fp, int in_dump)
case Op_quotient_i:
case Op_mod_i:
case Op_assign_concat:
- print_memory(pc->memory, fparms, print_func, fp);
+ print_memory(pc->memory, func, print_func, fp);
/* fall through */
default:
print_func(fp, "\n");
@@ -3950,7 +3932,8 @@ int
do_dump_instructions(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
{
FILE *fp;
-
+ NODE **funcs;
+
if (arg != NULL && arg->type == D_string) {
/* dump to a file */
if ((fp = fopen(arg->a_string, "w")) == NULL) {
@@ -3962,25 +3945,27 @@ do_dump_instructions(CMDARG *arg, int cmd
ATTRIBUTE_UNUSED)
pf_data.fp = fp;
pf_data.defn = TRUE; /* in_dump = TRUE */
(void) print_code(code_block, &pf_data);
- (void) foreach_func((int (*)(INSTRUCTION *, void *)) print_code,
- FALSE, /* sort */
- &pf_data /* data */
- );
+ funcs = function_list(TRUE);
+ (void) foreach_func(funcs,
+ (int (*)(INSTRUCTION *, void *))
print_code,
+ &pf_data);
+ efree(funcs);
fclose(fp);
return FALSE;
}
+ funcs = function_list(TRUE);
initialize_pager(out_fp);
if (setjmp(pager_quit_tag) == 0) {
pf_data.print_func = gprintf;
pf_data.fp = out_fp;
pf_data.defn = TRUE; /* in_dump = TRUE */
(void) print_code(code_block, &pf_data);
- (void) foreach_func((int (*)(INSTRUCTION *, void *)) print_code,
- FALSE, /* sort */
- &pf_data /* data */
- );
+ (void) foreach_func(funcs,
+ (int (*)(INSTRUCTION *, void *)) print_code,
+ &pf_data);
}
+ efree(funcs);
return FALSE;
}
@@ -4901,7 +4886,7 @@ do_print_f(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
goto done;
for (; cnt > 0; cnt--) {
- NODE *value, *subs;
+ NODE *value, *subs;
a = a->next;
subs = a->a_node;
value = in_array(r, subs);
@@ -4939,7 +4924,7 @@ do_print_f(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
}
}
- force_string(tmp[0]);
+ tmp[0] = force_string(tmp[0]);
PUSH_BINDING(fatal_tag_stack, fatal_tag, fatal_tag_valid);
if (setjmp(fatal_tag) == 0)
@@ -5282,35 +5267,6 @@ close_all()
set_gawk_output(NULL); /* closes output_fp if not stdout */
}
-/* install_params --- install function parameters into the symbol table */
-
-static void
-install_params(NODE *func)
-{
- NODE *np;
-
- if (func == NULL)
- return;
- /* function parameters of type Node_param_list */
- np = func->lnode;
- for (np = np->rnode; np != NULL; np = np->rnode)
- install_symbol(np->param, np);
-}
-
-/* remove_params --- remove function parameters out of the symbol table */
-
-static void
-remove_params(NODE *func)
-{
- NODE *np;
-
- if (func == NULL)
- return;
- np = func->lnode;
- for (np = np->rnode; np != NULL; np = np->rnode)
- remove_symbol(np->param);
-}
-
/* pre_execute_code --- pre_hook for execute_code, called by pre_execute */
static int
@@ -5353,23 +5309,25 @@ execute_code(volatile INSTRUCTION *code)
volatile NODE *r = NULL;
volatile jmp_buf fatal_tag_stack;
STACK_ITEM *ctxt_stack_bottom;
+ int save_flags = do_flags;
/* We use one global stack for all contexts.
* Remember stack bottom for current context; in case of
* a fatal error, unwind stack until stack_ptr is below that 'bottom'.
*/
ctxt_stack_bottom = stack_ptr + 1;
+ do_flags = FALSE;
PUSH_BINDING(fatal_tag_stack, fatal_tag, fatal_tag_valid);
if (setjmp(fatal_tag) == 0) {
(void) r_interpret((INSTRUCTION *) code);
- assert(stack_ptr == ctxt_stack_bottom);
+ /* assert(stack_ptr == ctxt_stack_bottom); */
r = POP_SCALAR();
} else /* fatal error */
unwind_stack(ctxt_stack_bottom);
POP_BINDING(fatal_tag_stack, fatal_tag, fatal_tag_valid);
-
+ do_flags = save_flags;
if (exit_val != EXIT_SUCCESS) { /* must be EXIT_FATAL? */
exit_val = EXIT_SUCCESS;
return NULL;
@@ -5388,9 +5346,9 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
NODE **sp;
INSTRUCTION *eval, *code = NULL;
AWK_CONTEXT *ctxt;
- char **save_parmlist = NULL;
int ecount = 0, pcount = 0;
int ret;
+ int save_flags = do_flags;
if (prog_running) {
this_frame = find_frame(0);
@@ -5402,7 +5360,9 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
ctxt->install_func = append_symbol; /* keep track of newly
installed globals */
push_context(ctxt);
(void) add_srcfile(SRC_CMDLINE, arg->a_string, srcfiles, NULL, NULL);
+ do_flags = FALSE;
ret = parse_program(&code);
+ do_flags = save_flags;
remove_params(this_func);
if (ret != 0) {
pop_context(); /* switch to prev context */
@@ -5424,9 +5384,7 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
} else {
/* execute as a part of the current function */
int i;
- char **varnames;
INSTRUCTION *t;
- NODE *np;
eval = f->code_ptr; /* Op_func */
eval->source_file = cur_srcfile->src;
@@ -5435,9 +5393,8 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
t->opcode = Op_stop;
/* add or append eval locals to the current frame stack */
- ecount = f->lnode->param_cnt; /* eval local count */
- pcount = this_func->lnode->param_cnt;
- save_parmlist = this_func->parmlist;
+ ecount = f->param_cnt; /* eval local count */
+ pcount = this_func->param_cnt;
if (ecount > 0) {
if (pcount == 0)
@@ -5445,26 +5402,22 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
else
erealloc(this_frame->stack, NODE **, (pcount +
ecount) * sizeof(NODE *), "do_eval");
- emalloc(varnames, char **, (pcount + ecount + 1) *
sizeof(char *), "do_eval");
- if (pcount > 0)
- memcpy(varnames, save_parmlist, pcount *
sizeof(char *));
- for (np = f->lnode->rnode, i = 0; np != NULL; np =
np->rnode, i++) {
- varnames[pcount + i] = np->param;
- np->param_cnt += pcount; /* appending
eval locals: fixup param_cnt */
- }
- varnames[pcount + ecount] = NULL;
sp = this_frame->stack + pcount;
for (i = 0; i < ecount; i++) {
+ NODE *np;
+
+ np = f->fparms + i;
+ np->param_cnt += pcount; /* appending
eval locals: fixup param_cnt */
+
getnode(r);
memset(r, 0, sizeof(NODE));
*sp++ = r;
/* local variable */
r->type = Node_var_new;
- r->vname = varnames[pcount + i];
+ r->vname = np->param;
}
- this_func->parmlist = varnames;
- this_func->lnode->param_cnt += ecount;
+ this_func->param_cnt += ecount;
}
}
@@ -5504,9 +5457,7 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
} /* else
restore_frame() will free it */
- efree(this_func->parmlist);
- this_func->parmlist = save_parmlist;
- this_func->lnode->param_cnt -= ecount;
+ this_func->param_cnt -= ecount;
}
/* always destroy symbol "@eval", however destroy all newly installed
@@ -5516,7 +5467,7 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
pop_context(); /* switch to prev context */
free_context(ctxt, (ret_val != NULL)); /* free all instructions and
optionally symbols */
if (ret_val != NULL)
- destroy_symbol("@eval"); /* destroy "@eval" */
+ destroy_symbol(f); /* destroy "@eval" */
return FALSE;
}
@@ -5533,13 +5484,13 @@ an error message:
static int invalid_symbol = 0;
-void
-check_symbol(char *name)
+static void
+check_symbol(NODE *r)
{
invalid_symbol++;
- d_error(_("No symbol `%s' in current context"), name);
+ d_error(_("No symbol `%s' in current context"), r->vname);
/* install anyway, but keep track of it */
- append_symbol(name);
+ append_symbol(r);
}
/* parse_condition --- compile a condition expression */
@@ -5555,6 +5506,7 @@ parse_condition(int type, int num, char *expr)
NODE *this_func = NULL;
INSTRUCTION *it, *stop, *rule;
struct condition *cndn = NULL;
+ int save_flags = do_flags;
if (type == D_break && (b = find_breakpoint(num)) != NULL) {
INSTRUCTION *rp;
@@ -5578,7 +5530,9 @@ parse_condition(int type, int num, char *expr)
ctxt->install_func = check_symbol;
push_context(ctxt);
(void) add_srcfile(SRC_CMDLINE, expr, srcfiles, NULL, NULL);
+ do_flags = FALSE;
ret = parse_program(&code);
+ do_flags = save_flags;
remove_params(this_func);
pop_context();
@@ -5598,8 +5552,8 @@ parse_condition(int type, int num, char *expr)
it = rule->firsti; /* Op_K_print_rec */
assert(it->opcode == Op_K_print_rec);
- it->opcode = Op_push_i;
- it->memory = mk_number((AWKNUM) 1.0, PERM|NUMBER|NUMCUR);
+ it->opcode = Op_push_i;
+ it->memory = make_number(1.0);
it->nexti = bcalloc(Op_jmp, 1, 0);
it->nexti->target_jmp = stop;
it->nexti->nexti = rule->lasti;
@@ -5607,7 +5561,7 @@ parse_condition(int type, int num, char *expr)
it = rule->lasti; /* Op_no_op, target for Op_jmp_false */
assert(it->opcode == Op_no_op);
it->opcode = Op_push_i;
- it->memory = mk_number((AWKNUM) 0.0, PERM|NUMBER|NUMCUR);
+ it->memory = make_number(0.0);
it->nexti = stop;
out:
@@ -5687,7 +5641,7 @@ push_cmd_src(
cs->str = NULL;
cs->next = cmd_src;
cmd_src = cs;
-
+
input_fd = fd;
input_from_tty = istty;
read_a_line = readfunc;
diff --git a/eval.c b/eval.c
index 4132474..8278371 100644
--- a/eval.c
+++ b/eval.c
@@ -262,9 +262,12 @@ static const char *const nodetypes[] = {
"Node_var_new",
"Node_param_list",
"Node_func",
+ "Node_ext_func",
"Node_hashnode",
- "Node_ahash",
"Node_array_ref",
+ "Node_array_tree",
+ "Node_array_leaf",
+ "Node_dump_array",
"Node_arrayfor",
"Node_frame",
"Node_instruction",
@@ -348,6 +351,7 @@ static struct optypetab {
{ "Op_K_getline", "getline" },
{ "Op_K_nextfile", "nextfile" },
{ "Op_builtin", NULL },
+ { "Op_ext_builtin", NULL },
{ "Op_in_array", " in " },
{ "Op_func_call", NULL },
{ "Op_indirect_func_call", NULL },
@@ -375,7 +379,6 @@ static struct optypetab {
{ "Op_field_assign", NULL },
{ "Op_after_beginfile", NULL },
{ "Op_after_endfile", NULL },
- { "Op_ext_func", NULL },
{ "Op_func", NULL },
{ "Op_exec_count", NULL },
{ "Op_breakpoint", NULL },
@@ -445,20 +448,19 @@ flags2str(int flagval)
{
static const struct flagtab values[] = {
{ MALLOC, "MALLOC" },
- { PERM, "PERM" },
{ STRING, "STRING" },
{ STRCUR, "STRCUR" },
{ NUMCUR, "NUMCUR" },
{ NUMBER, "NUMBER" },
{ MAYBE_NUM, "MAYBE_NUM" },
- { ARRAYMAXED, "ARRAYMAXED" },
- { FUNC, "FUNC" },
{ FIELD, "FIELD" },
{ INTLSTR, "INTLSTR" },
- { NUMIND, "NUMIND" },
-#ifdef WSTRCUR
+ { NUMINT, "NUMINT" },
+ { INTIND, "INTIND" },
{ WSTRCUR, "WSTRCUR" },
-#endif
+ { ARRAYMAXED, "ARRAYMAXED" },
+ { HALFHAT, "HALFHAT" },
+ { XARRAY, "XARRAY" },
{ 0, NULL },
};
@@ -483,7 +485,7 @@ genflags2str(int flagval, const struct flagtab *tab)
* the '|' character.
*/
space_needed = (strlen(tab[i].name) + (sp != buffer));
- if (space_left < space_needed)
+ if (space_left <= space_needed)
fatal(_("buffer overflow in genflags2str"));
if (sp != buffer) {
@@ -497,6 +499,7 @@ genflags2str(int flagval, const struct flagtab *tab)
}
}
+ *sp = '\0';
return buffer;
}
@@ -581,7 +584,6 @@ posix_compare(NODE *s1, NODE *s2)
return ret;
}
-
/* cmp_nodes --- compare two nodes, returning negative, 0, positive */
int
@@ -598,6 +600,11 @@ cmp_nodes(NODE *t1, NODE *t2)
(void) force_number(t1);
if (t2->flags & MAYBE_NUM)
(void) force_number(t2);
+ if (t1->flags & INTIND)
+ t1 = force_string(t1);
+ if (t2->flags & INTIND)
+ t2 = force_string(t2);
+
if ((t1->flags & NUMBER) && (t2->flags & NUMBER)) {
if (t1->numbr == t2->numbr)
ret = 0;
@@ -609,8 +616,8 @@ cmp_nodes(NODE *t1, NODE *t2)
return ret;
}
- (void) force_string(t1);
- (void) force_string(t2);
+ t1 = force_string(t1);
+ t2 = force_string(t2);
len1 = t1->stlen;
len2 = t2->stlen;
ldiff = len1 - len2;
@@ -636,7 +643,9 @@ cmp_nodes(NODE *t1, NODE *t2)
ret = casetable[*cp1] - casetable[*cp2];
} else
ret = memcmp(t1->stptr, t2->stptr, l);
- return (ret == 0 ? ldiff : ret);
+
+ ret = ret == 0 ? ldiff : ret;
+ return ret;
}
@@ -728,9 +737,10 @@ set_IGNORECASE()
if (do_traditional)
IGNORECASE = FALSE;
else if ((IGNORECASE_node->var_value->flags & (STRING|STRCUR)) != 0) {
- if ((IGNORECASE_node->var_value->flags & MAYBE_NUM) == 0)
- IGNORECASE =
(force_string(IGNORECASE_node->var_value)->stlen > 0);
- else
+ if ((IGNORECASE_node->var_value->flags & MAYBE_NUM) == 0) {
+ IGNORECASE_node->var_value =
force_string(IGNORECASE_node->var_value);
+ IGNORECASE = (IGNORECASE_node->var_value->stlen > 0);
+ } else
IGNORECASE = (force_number(IGNORECASE_node->var_value)
!= 0.0);
} else if ((IGNORECASE_node->var_value->flags & (NUMCUR|NUMBER)) != 0)
IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
@@ -823,7 +833,8 @@ set_BINMODE()
void
set_OFS()
{
- OFS = force_string(OFS_node->var_value)->stptr;
+ OFS_node->var_value = force_string(OFS_node->var_value);
+ OFS = OFS_node->var_value->stptr;
OFSlen = OFS_node->var_value->stlen;
OFS[OFSlen] = '\0';
}
@@ -833,7 +844,8 @@ set_OFS()
void
set_ORS()
{
- ORS = force_string(ORS_node->var_value)->stptr;
+ ORS_node->var_value = force_string(ORS_node->var_value);
+ ORS = ORS_node->var_value->stptr;
ORSlen = ORS_node->var_value->stlen;
ORS[ORSlen] = '\0';
}
@@ -849,6 +861,7 @@ fmt_ok(NODE *n)
{
NODE *tmp = force_string(n);
const char *p = tmp->stptr;
+
#if ! defined(PRINTF_HAS_F_FORMAT) || PRINTF_HAS_F_FORMAT != 1
static const char float_formats[] = "efgEG";
#else
@@ -890,7 +903,7 @@ fmt_index(NODE *n)
if (fmt_list == NULL)
emalloc(fmt_list, NODE **, fmt_num*sizeof(*fmt_list),
"fmt_index");
- (void) force_string(n);
+ n = force_string(n);
while (ix < fmt_hiwater) {
if (cmp_nodes(fmt_list[ix], n) == 0)
return ix;
@@ -942,41 +955,45 @@ set_LINT()
if ((LINT_node->var_value->flags & MAYBE_NUM) == 0) {
const char *lintval;
size_t lintlen;
+ NODE *tmp;
- do_lint = (force_string(LINT_node->var_value)->stlen >
0);
- lintval = LINT_node->var_value->stptr;
- lintlen = LINT_node->var_value->stlen;
- if (do_lint) {
- do_lint = LINT_ALL;
+ tmp = LINT_node->var_value =
force_string(LINT_node->var_value);
+ lintval = tmp->stptr;
+ lintlen = tmp->stlen;
+ if (lintlen > 0) {
+ do_flags |= DO_LINT_ALL;
if (lintlen == 5 && strncmp(lintval, "fatal",
5) == 0)
lintfunc = r_fatal;
- else if (lintlen == 7 && strncmp(lintval,
"invalid", 7) == 0)
- do_lint = LINT_INVALID;
- else
+ else if (lintlen == 7 && strncmp(lintval,
"invalid", 7) == 0) {
+ do_flags &= ~ DO_LINT_ALL;
+ do_flags |= DO_LINT_INVALID;
+ } else
lintfunc = warning;
- } else
+ } else {
+ do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID);
lintfunc = warning;
+ }
} else {
if (force_number(LINT_node->var_value) != 0.0)
- do_lint = LINT_ALL;
+ do_flags |= DO_LINT_ALL;
else
- do_lint = FALSE;
+ do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID);
lintfunc = warning;
}
} else if ((LINT_node->var_value->flags & (NUMCUR|NUMBER)) != 0) {
if (force_number(LINT_node->var_value) != 0.0)
- do_lint = LINT_ALL;
+ do_flags |= DO_LINT_ALL;
else
- do_lint = FALSE;
+ do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID);
lintfunc = warning;
} else
- do_lint = FALSE; /* shouldn't happen */
+ do_flags &= ~(DO_LINT_ALL|DO_LINT_INVALID); /* shouldn't
happen */
if (! do_lint)
lintfunc = warning;
/* explicitly use warning() here, in case lintfunc == r_fatal */
- if (old_lint != do_lint && old_lint && do_lint == FALSE)
+ if (old_lint != do_lint && old_lint && ! do_lint)
warning(_("turning off `--lint' due to assignment to `LINT'"));
#endif /* ! NO_LINT */
}
@@ -987,9 +1004,11 @@ void
set_TEXTDOMAIN()
{
int len;
+ NODE *tmp;
- TEXTDOMAIN = force_string(TEXTDOMAIN_node->var_value)->stptr;
- len = TEXTDOMAIN_node->var_value->stlen;
+ tmp = TEXTDOMAIN_node->var_value =
force_string(TEXTDOMAIN_node->var_value);
+ TEXTDOMAIN = tmp->stptr;
+ len = tmp->stlen;
TEXTDOMAIN[len] = '\0';
/*
* Note: don't call textdomain(); this value is for
@@ -1057,7 +1076,6 @@ update_FNR()
}
-
NODE *frame_ptr; /* current frame */
STACK_ITEM *stack_ptr = NULL;
STACK_ITEM *stack_bottom;
@@ -1079,17 +1097,10 @@ STACK_ITEM *
grow_stack()
{
if (stack_ptr == NULL) {
- char *val;
-
- if ((val = getenv("GAWK_STACKSIZE")) != NULL) {
- if (isdigit((unsigned char) *val)) {
- unsigned long n = 0;
- for (; *val && isdigit((unsigned char) *val);
val++)
- n = (n * 10) + *val - '0';
- if (n >= 1)
- STACK_SIZE = n;
- }
- }
+ long newval;
+
+ if ((newval = getenv_long("GAWK_STACKSIZE")) > 0)
+ STACK_SIZE = newval;
emalloc(stack_bottom, STACK_ITEM *, STACK_SIZE *
sizeof(STACK_ITEM), "grow_stack");
stack_ptr = stack_bottom - 1;
@@ -1123,9 +1134,6 @@ r_get_lhs(NODE *n, int reference)
int isparam = FALSE;
if (n->type == Node_param_list) {
- if ((n->flags & FUNC) != 0)
- fatal(_("can't use function name `%s' as variable or
array"),
- n->vname);
isparam = TRUE;
n = GET_PARAM(n->param_cnt);
}
@@ -1139,11 +1147,11 @@ r_get_lhs(NODE *n, int reference)
fatal(_("attempt to use array `%s' in a scalar
context"),
array_vname(n));
n->orig_array->type = Node_var;
- n->orig_array->var_value = Nnull_string;
+ n->orig_array->var_value = dupnode(Nnull_string);
/* fall through */
case Node_var_new:
n->type = Node_var;
- n->var_value = Nnull_string;
+ n->var_value = dupnode(Nnull_string);
break;
case Node_var:
@@ -1164,7 +1172,7 @@ r_get_lhs(NODE *n, int reference)
_("reference to uninitialized argument `%s'") :
_("reference to uninitialized variable `%s'")),
n->vname);
- return &n->var_value;
+ return & n->var_value;
}
@@ -1245,15 +1253,13 @@ static void
setup_frame(INSTRUCTION *pc)
{
NODE *r = NULL;
- NODE *m;
- NODE *f;
+ NODE *m, *f, *fp;
NODE **sp = NULL;
- char **varnames;
int pcount, arg_count, i;
f = pc->func_body;
- pcount = f->lnode->param_cnt;
- varnames = f->parmlist;
+ pcount = f->param_cnt;
+ fp = f->fparms;
arg_count = (pc + 1)->expr_count;
/* check for extra args */
@@ -1280,7 +1286,7 @@ setup_frame(INSTRUCTION *pc)
if (i >= arg_count) {
/* local variable */
r->type = Node_var_new;
- r->vname = varnames[i];
+ r->vname = fp[i].param;
continue;
}
@@ -1307,8 +1313,9 @@ setup_frame(INSTRUCTION *pc)
* scalar during evaluation of expression for a
* subsequent param.
*/
+ /* fall through */
r->type = Node_var;
- r->var_value = Nnull_string;
+ r->var_value = dupnode(Nnull_string);
break;
case Node_val:
@@ -1319,7 +1326,7 @@ setup_frame(INSTRUCTION *pc)
default:
cant_happen();
}
- r->vname = varnames[i];
+ r->vname = fp[i].param;
}
stack_adj(-arg_count); /* adjust stack pointer */
@@ -1332,6 +1339,7 @@ setup_frame(INSTRUCTION *pc)
/* save current frame in stack */
PUSH(frame_ptr);
+
/* setup new frame */
getnode(frame_ptr);
frame_ptr->type = Node_frame;
@@ -1355,7 +1363,7 @@ restore_frame(NODE *fp)
INSTRUCTION *ri;
func = frame_ptr->func_node;
- n = func->lnode->param_cnt;
+ n = func->param_cnt;
sp = frame_ptr->stack;
for (; n > 0; n--) {
@@ -1384,11 +1392,14 @@ restore_frame(NODE *fp)
static inline void
free_arrayfor(NODE *r)
{
- if (r->var_array != NULL) {
- size_t num_elems = r->table_size;
- NODE **list = r->var_array;
- while (num_elems > 0)
- unref(list[--num_elems]);
+ if (r->for_list != NULL) {
+ NODE *n;
+ size_t num_elems = r->for_list_size;
+ NODE **list = r->for_list;
+ while (num_elems > 0) {
+ n = list[--num_elems];
+ unref(n);
+ }
efree(list);
}
freenode(r);
@@ -1407,20 +1418,16 @@ unwind_stack(STACK_ITEM *sp_bottom)
case Node_instruction:
freenode(r);
break;
-
case Node_frame:
(void) restore_frame(r);
source = frame_ptr->vname;
break;
-
case Node_arrayfor:
free_arrayfor(r);
break;
-
case Node_val:
DEREF(r);
break;
-
default:
if (in_main_context())
fatal(_("unwind_stack: unexpected type `%s'"),
@@ -1570,12 +1577,10 @@ POP_CODE()
/* N.B.:
* 1) reference counting done for both number and string values.
- * 2) TEMP flag no longer needed (consequence of the above; valref = 0
- * is the replacement).
- * 3) Stack operations:
+ * 2) Stack operations:
* Use REPLACE[_XX] if last stack operation was TOP[_XX],
* PUSH[_XX] if last operation was POP[_XX] instead.
- * 4) UPREF and DREF -- see awk.h
+ * 3) UPREF and DREF -- see awk.h
*/
@@ -1590,11 +1595,8 @@ r_interpret(INSTRUCTION *code)
NODE *f; /* function definition */
NODE **lhs;
AWKNUM x, x1, x2;
- int di, pre = FALSE;
+ int di;
Regexp *rp;
-#if defined(GAWKDEBUG) || defined(ARRAYDEBUG)
- int last_was_stopme = FALSE; /* builtin stopme() called ? */
-#endif
int stdio_problem = FALSE;
if (args_array == NULL)
@@ -1603,7 +1605,7 @@ r_interpret(INSTRUCTION *code)
erealloc(args_array, NODE **, (max_args + 2)*sizeof(NODE *),
"r_interpret");
/* array subscript */
-#define mk_sub(n) (n == 1 ? POP_STRING() : concat_exp(n, TRUE))
+#define mk_sub(n) (n == 1 ? POP_SCALAR() : concat_exp(n, TRUE))
#ifdef DEBUGGING
#define JUMPTO(x) do { post_execute(pc); pc = (x); goto top; }
while(FALSE)
@@ -1636,7 +1638,6 @@ top:
currule = pc->in_rule; /* for sole use in Op_K_next,
Op_K_nextfile, Op_K_getline* */
/* fall through */
case Op_func:
- case Op_ext_func:
source = pc->source_file;
break;
@@ -1670,7 +1671,18 @@ top:
case Op_push_i:
m = pc->memory;
- PUSH((m->flags & INTLSTR) != 0 ? format_val(CONVFMT,
CONVFMTidx, m): m);
+ if (! do_traditional && (m->flags & INTLSTR) != 0) {
+ char *orig, *trans, save;
+
+ save = m->stptr[m->stlen];
+ m->stptr[m->stlen] = '\0';
+ orig = m->stptr;
+ trans = dgettext(TEXTDOMAIN, orig);
+ m->stptr[m->stlen] = save;
+ m = make_string(trans, strlen(trans));
+ } else
+ UPREF(m);
+ PUSH(m);
break;
case Op_push:
@@ -1681,9 +1693,6 @@ top:
save_symbol = m = pc->memory;
if (m->type == Node_param_list) {
- if ((m->flags & FUNC) != 0)
- fatal(_("can't use function name `%s'
as variable or array"),
- m->vname);
isparam = TRUE;
save_symbol = m = GET_PARAM(m->param_cnt);
if (m->type == Node_array_ref)
@@ -1704,13 +1713,14 @@ top:
case Node_var_new:
m->type = Node_var;
- m->var_value = Nnull_string;
+ m->var_value = dupnode(Nnull_string);
if (do_lint)
lintwarn(isparam ?
_("reference to uninitialized
argument `%s'") :
_("reference to uninitialized
variable `%s'"),
save_symbol->vname);
- PUSH(Nnull_string);
+ m = dupnode(Nnull_string);
+ PUSH(m);
break;
case Node_var_array:
@@ -1751,7 +1761,16 @@ top:
case Op_subscript:
t2 = mk_sub(pc->sub_count);
t1 = POP_ARRAY();
- r = *assoc_lookup(t1, t2, TRUE);
+
+ if (do_lint && in_array(t1, t2) == NULL) {
+ t2 = force_string(t2);
+ lintwarn(_("reference to uninitialized element
`%s[\"%.*s\"]'"),
+ array_vname(t1), (int) t2->stlen,
t2->stptr);
+ if (t2->stlen == 0)
+ lintwarn(_("subscript of array `%s' is
null string"), array_vname(t1));
+ }
+
+ r = *assoc_lookup(t1, t2);
DEREF(t2);
if (r->type == Node_val)
UPREF(r);
@@ -1763,15 +1782,17 @@ top:
t1 = POP_ARRAY();
r = in_array(t1, t2);
if (r == NULL) {
- getnode(r);
- r->type = Node_var_array;
- r->var_array = NULL;
- r->vname = estrdup(t2->stptr, t2->stlen);
/* the subscript in parent array */
+ r = make_array();
r->parent_array = t1;
- *assoc_lookup(t1, t2, FALSE) = r;
- } else if (r->type != Node_var_array)
+ *assoc_lookup(t1, t2) = r;
+ t2 = force_string(t2);
+ r->vname = estrdup(t2->stptr, t2->stlen);
/* the subscript in parent array */
+ } else if (r->type != Node_var_array) {
+ t2 = force_string(t2);
fatal(_("attempt to use scalar `%s[\"%.*s\"]'
as an array"),
array_vname(t1), (int)
t2->stlen, t2->stptr);
+ }
+
DEREF(t2);
PUSH(r);
break;
@@ -1779,10 +1800,22 @@ top:
case Op_subscript_lhs:
t2 = mk_sub(pc->sub_count);
t1 = POP_ARRAY();
- lhs = assoc_lookup(t1, t2, pc->do_reference);
- if ((*lhs)->type == Node_var_array)
+ if (do_lint && in_array(t1, t2) == NULL) {
+ t2 = force_string(t2);
+ if (pc->do_reference)
+ lintwarn(_("reference to uninitialized
element `%s[\"%.*s\"]'"),
+ array_vname(t1), (int)
t2->stlen, t2->stptr);
+ if (t2->stlen == 0)
+ lintwarn(_("subscript of array `%s' is
null string"), array_vname(t1));
+ }
+
+ lhs = assoc_lookup(t1, t2);
+ if ((*lhs)->type == Node_var_array) {
+ t2 = force_string(t2);
fatal(_("attempt to use array `%s[\"%.*s\"]' in
a scalar context"),
array_vname(t1), (int)
t2->stlen, t2->stptr);
+ }
+
DEREF(t2);
PUSH_ADDRESS(lhs);
break;
@@ -1792,10 +1825,6 @@ top:
lhs = r_get_field(t1, (Func_ptr *) 0, TRUE);
decr_sp();
DEREF(t1);
- /* This used to look like this:
- PUSH(dupnode(*lhs));
- but was changed to bypass an apparent bug in the
z/OS C compiler.
- Please do not remerge. */
r = dupnode(*lhs); /* can't use UPREF here */
PUSH(r);
break;
@@ -1868,39 +1897,39 @@ top:
break;
case Op_not:
- t1 = TOP_SCALAR();
+ t1 = TOP_SCALAR();
r = make_number((AWKNUM) ! eval_condition(t1));
DEREF(t1);
REPLACE(r);
break;
case Op_equal:
- r = make_number((AWKNUM) (cmp_scalar() == 0));
+ r = make_number((AWKNUM) cmp_scalar() == 0);
REPLACE(r);
break;
case Op_notequal:
- r = make_number((AWKNUM) (cmp_scalar() != 0));
+ r = make_number((AWKNUM) cmp_scalar() != 0);
REPLACE(r);
break;
case Op_less:
- r = make_number((AWKNUM) (cmp_scalar() < 0));
+ r = make_number((AWKNUM) cmp_scalar() < 0);
REPLACE(r);
break;
case Op_greater:
- r = make_number((AWKNUM) (cmp_scalar() > 0));
+ r = make_number((AWKNUM) cmp_scalar() > 0);
REPLACE(r);
break;
case Op_leq:
- r = make_number((AWKNUM) (cmp_scalar() <= 0));
+ r = make_number((AWKNUM) cmp_scalar() <= 0);
REPLACE(r);
break;
case Op_geq:
- r = make_number((AWKNUM) (cmp_scalar() >= 0));
+ r = make_number((AWKNUM) cmp_scalar() >= 0);
REPLACE(r);
break;
@@ -1991,27 +2020,30 @@ mod:
break;
case Op_preincrement:
- pre = TRUE;
- case Op_postincrement:
- x2 = 1.0;
-post:
+ case Op_predecrement:
+ x2 = pc->opcode == Op_preincrement ? 1.0 : -1.0;
lhs = TOP_ADDRESS();
x1 = force_number(*lhs);
+ x = x1 + x2;
+ r = make_number(x);
unref(*lhs);
- r = *lhs = make_number(x1 + x2);
- if (pre)
- UPREF(r);
- else
- r = make_number(x1);
+ *lhs = r;
+ UPREF(r);
REPLACE(r);
- pre = FALSE;
- break;
+ break;
- case Op_predecrement:
- pre = TRUE;
+ case Op_postincrement:
case Op_postdecrement:
- x2 = -1.0;
- goto post;
+ x2 = pc->opcode == Op_postincrement ? 1.0 : -1.0;
+ lhs = TOP_ADDRESS();
+ x1 = force_number(*lhs);
+ x = x1 + x2;
+ t1 = make_number(x);
+ r = make_number(x1);
+ unref(*lhs);
+ *lhs = t1;
+ REPLACE(r);
+ break;
case Op_unary_minus:
TOP_NUMBER(x1);
@@ -2025,10 +2057,12 @@ post:
*/
t1 = get_array(pc->memory, TRUE); /* array */
t2 = mk_sub(pc->expr_count); /* subscript */
- lhs = assoc_lookup(t1, t2, FALSE);
- if ((*lhs)->type == Node_var_array)
+ lhs = assoc_lookup(t1, t2);
+ if ((*lhs)->type == Node_var_array) {
+ t2 = force_string(t2);
fatal(_("attempt to use array `%s[\"%.*s\"]' in
a scalar context"),
array_vname(t1), (int)
t2->stlen, t2->stptr);
+ }
DEREF(t2);
unref(*lhs);
*lhs = POP_SCALAR();
@@ -2041,7 +2075,13 @@ post:
lhs = get_lhs(pc->memory, FALSE);
unref(*lhs);
- *lhs = POP_SCALAR();
+ r = pc->initval;
+ if (r == NULL)
+ *lhs = POP_SCALAR();
+ else {
+ UPREF(r);
+ *lhs = r;
+ }
break;
case Op_store_field:
@@ -2070,12 +2110,19 @@ post:
free_wstr(*lhs);
- if (t1 != t2 && t1->valref == 1 && (t1->flags & PERM)
== 0) {
+ if (t1 != *lhs) {
+ unref(*lhs);
+ *lhs = dupnode(t1);
+ }
+
+ if (t1 != t2 && t1->valref == 1) {
size_t nlen = t1->stlen + t2->stlen;
+
erealloc(t1->stptr, char *, nlen + 2,
"r_interpret");
memcpy(t1->stptr + t1->stlen, t2->stptr,
t2->stlen);
t1->stlen = nlen;
t1->stptr[nlen] = '\0';
+ t1->flags &= ~(NUMCUR|NUMBER|NUMINT);
} else {
size_t nlen = t1->stlen + t2->stlen;
char *p;
@@ -2084,9 +2131,8 @@ post:
memcpy(p, t1->stptr, t1->stlen);
memcpy(p + t1->stlen, t2->stptr, t2->stlen);
unref(*lhs);
- t1 = *lhs = make_str_node(p, nlen,
ALREADY_MALLOCED);
+ t1 = *lhs = make_str_node(p, nlen);
}
- t1->flags &= ~(NUMCUR|NUMBER);
DEREF(t2);
break;
@@ -2129,9 +2175,10 @@ post:
case Op_K_case:
if ((pc + 1)->match_exp) {
/* match a constant regex against switch
expression instead of $0. */
+
m = POP(); /* regex */
t2 = TOP_SCALAR(); /* switch expression */
- (void) force_string(t2);
+ t2 = force_string(t2);
rp = re_update(m);
di = (research(rp, t2->stptr, 0, t2->stlen,
avoid_dfa(m, t2->stptr,
t2->stlen)) >= 0);
@@ -2142,8 +2189,10 @@ post:
DEREF(t1);
}
- if (di) { /* match found */
- decr_sp();
+ if (di) {
+ /* match found */
+
+ t2 = POP_SCALAR();
DEREF(t2);
JUMPTO(pc->target_jmp);
}
@@ -2170,6 +2219,11 @@ post:
break;
case Op_arrayfor_init:
+#define idx_list sub.nodep.r.av
+#define num_idx sub.nodep.reflags
+#define cur_idx sub.nodep.l.ll
+#define for_array sub.nodep.rn
+
{
NODE **list = NULL;
NODE *array, *sort_str;
@@ -2181,7 +2235,7 @@ post:
array = POP_ARRAY();
/* sanity: check if empty */
- if (array->var_array == NULL || array->table_size == 0)
+ if (array_empty(array))
goto arrayfor;
num_elems = array->table_size;
@@ -2204,19 +2258,14 @@ post:
}
list = assoc_list(array, how_to_sort, SORTED_IN);
-
- /*
- * Actual array for use in lint warning
- * in Op_arrayfor_incr
- */
- list[num_elems] = array;
-
+
arrayfor:
getnode(r);
r->type = Node_arrayfor;
- r->var_array = list;
- r->table_size = num_elems; /* # of elements in list
*/
- r->array_size = -1; /* current index */
+ r->for_list = list;
+ r->for_list_size = num_elems; /* # of
elements in list */
+ r->cur_idx = -1; /* current
index */
+ r->for_array = array; /* array */
PUSH(r);
if (num_elems == 0)
@@ -2226,20 +2275,20 @@ arrayfor:
case Op_arrayfor_incr:
r = TOP(); /* Node_arrayfor */
- if (++r->array_size == r->table_size) {
+ if (++r->cur_idx == r->for_list_size) {
NODE *array;
- array = r->var_array[r->table_size]; /*
actual array */
- if (do_lint && array->table_size !=
r->table_size)
+ array = r->for_array; /* actual array */
+ if (do_lint && array->table_size !=
r->for_list_size)
lintwarn(_("for loop: array `%s'
changed size from %ld to %ld during loop execution"),
- array_vname(array), (long)
r->table_size, (long) array->table_size);
+ array_vname(array), (long)
r->for_list_size, (long) array->table_size);
JUMPTO(pc->target_jmp); /* Op_arrayfor_final */
}
- t1 = r->var_array[r->array_size];
+ t1 = r->for_list[r->cur_idx];
lhs = get_lhs(pc->array_var, FALSE);
unref(*lhs);
- *lhs = make_string(t1->ahname_str, t1->ahname_len);
- break;
+ *lhs = dupnode(t1);
+ break;
case Op_arrayfor_final:
r = POP();
@@ -2249,12 +2298,23 @@ arrayfor:
case Op_builtin:
r = pc->builtin(pc->expr_count);
-#if defined(GAWKDEBUG) || defined(ARRAYDEBUG)
- if (! r)
- last_was_stopme = TRUE;
- else
-#endif
- PUSH(r);
+ PUSH(r);
+ break;
+
+ case Op_ext_builtin:
+ {
+ int arg_count = pc->expr_count;
+
+ PUSH_CODE(pc);
+ r = pc->builtin(arg_count);
+ (void) POP_CODE();
+ while (arg_count-- > 0) {
+ t1 = POP();
+ if (t1->type == Node_val)
+ DEREF(t1);
+ }
+ PUSH(r);
+ }
break;
case Op_K_print:
@@ -2329,18 +2389,20 @@ match_re:
arg_count = (pc + 1)->expr_count;
t1 = PEEK(arg_count); /* indirect var */
assert(t1->type == Node_val); /* @a[1](p) not allowed
in grammar */
- (void) force_string(t1);
+ t1 = force_string(t1);
if (t1->stlen > 0) {
/* retrieve function definition node */
f = pc->func_body;
- if (f != NULL && STREQ(f->vname, t1->stptr))
+ if (f != NULL && STREQ(f->vname, t1->stptr)) {
/* indirect var hasn't been reassigned
*/
goto func_call;
+ }
f = lookup(t1->stptr);
}
if (f == NULL || f->type != Node_func)
- fatal(_("function called indirectly through
`%s' does not exist"), pc->func_name);
+ fatal(_("function called indirectly through
`%s' does not exist"),
+ pc->func_name);
pc->func_body = f; /* save for next call */
goto func_call;
@@ -2351,28 +2413,35 @@ match_re:
f = pc->func_body;
if (f == NULL) {
f = lookup(pc->func_name);
- if (f == NULL || f->type != Node_func)
+ if (f == NULL || (f->type != Node_func &&
f->type != Node_ext_func))
fatal(_("function `%s' not defined"),
pc->func_name);
pc->func_body = f; /* save for next call */
}
- /* save current frame along with source */
+ if (f->type == Node_ext_func) {
+ INSTRUCTION *bc;
+ char *fname = pc->func_name;
+ int arg_count = (pc + 1)->expr_count;
+
+ bc = f->code_ptr;
+ assert(bc->opcode == Op_symbol);
+ pc->opcode = Op_ext_builtin; /* self
modifying code */
+ pc->builtin = bc->builtin;
+ pc->expr_count = arg_count; /*
actual argument count */
+ (pc + 1)->func_name = fname; /* name of the
builtin */
+ (pc + 1)->expr_count = bc->expr_count; /*
defined max # of arguments */
+ ni = pc;
+ JUMPTO(ni);
+ }
func_call:
- frame_ptr->vname = source; /* save current
source */
- setup_frame(pc);
-
- ni = f->code_ptr; /* function code */
- if (ni->opcode == Op_ext_func) {
- /* dynamically set source and line numbers for
an extension builtin. */
- ni->source_file = source;
- ni->source_line = sourceline;
- ni->nexti->source_line = sourceline; /*
Op_builtin */
- ni->nexti->nexti->source_line = sourceline;
/* Op_K_return */
- }
+ ni = f->code_ptr; /* function code */
+ /* save current frame along with source */
+ frame_ptr->vname = source;
+ setup_frame(pc);
/* run the function instructions */
- JUMPTO(ni); /* Op_func or Op_ext_func */
+ JUMPTO(ni); /* Op_func */
case Op_K_return:
m = POP_SCALAR(); /* return value */
@@ -2536,15 +2605,8 @@ func_call:
JUMPTO(pc->target_jmp);
case Op_pop:
-#if defined(GAWKDEBUG) || defined(ARRAYDEBUG)
- if (last_was_stopme)
- last_was_stopme = FALSE;
- else
-#endif
- {
- r = POP_SCALAR();
- DEREF(r);
- }
+ r = POP_SCALAR();
+ DEREF(r);
break;
case Op_line_range:
@@ -2573,7 +2635,7 @@ func_call:
}
result = ip->triggered || di;
- ip->triggered ^= di; /* update triggered
flag */
+ ip->triggered ^= di; /* update triggered flag
*/
r = make_number((AWKNUM) result); /* final value
of condition pair */
REPLACE(r);
JUMPTO(pc->target_jmp);
diff --git a/ext.c b/ext.c
index f0290f9..19e0eec 100644
--- a/ext.c
+++ b/ext.c
@@ -50,9 +50,6 @@ do_ext(int nargs)
int flags = RTLD_LAZY;
int fatal_error = FALSE;
int *gpl_compat;
-#if 0
- static short warned = FALSE;
-#endif
#ifdef __GNUC__
AWKNUM junk;
@@ -63,14 +60,6 @@ do_ext(int nargs)
if (do_sandbox)
fatal(_("extensions are not allowed in sandbox mode"));
-#if 0
- /* already done in parser */
- if (do_lint && ! warned) {
- warned = TRUE;
- lintwarn(_("`extension' is a gawk extension"));
- }
-#endif
-
if (do_traditional || do_posix)
error(_("`extension' is a gawk extension"));
@@ -97,7 +86,6 @@ do_ext(int nargs)
goto done;
}
-
func = (NODE *(*)(NODE *, void *)) dlsym(dl, fun->stptr);
if (func == NULL) {
msg(_("fatal: extension: library `%s': cannot call function
`%s' (%s)\n"),
@@ -108,7 +96,7 @@ do_ext(int nargs)
tmp = (*func)(obj, dl);
if (tmp == NULL)
- tmp = Nnull_string;
+ tmp = dupnode(Nnull_string);
done:
DEREF(obj);
DEREF(fun);
@@ -123,14 +111,10 @@ done:
void
make_builtin(const char *name, NODE *(*func)(int), int count)
{
- NODE *p, *symbol, *f;
- INSTRUCTION *b, *r;
+ NODE *symbol, *f;
+ INSTRUCTION *b;
const char *sp;
- char *pname;
- char **vnames = NULL;
- char c, buf[200];
- size_t space_needed;
- int i;
+ char c;
sp = name;
if (sp == NULL || *sp == '\0')
@@ -146,126 +130,79 @@ make_builtin(const char *name, NODE *(*func)(int), int
count)
if (f != NULL) {
if (f->type == Node_func) {
- INSTRUCTION *pc = f->code_ptr;
- if (pc->opcode != Op_ext_func) /* user-defined
function */
- fatal(_("extension: can't redefine function
`%s'"), name);
- else {
- /* multiple extension() calls etc. */
- if (do_lint)
- lintwarn(_("extension: function `%s'
already defined"), name);
- return;
- }
+ /* user-defined function */
+ fatal(_("extension: can't redefine function `%s'"),
name);
+ } else if (f->type == Node_ext_func) {
+ /* multiple extension() calls etc. */
+ if (do_lint)
+ lintwarn(_("extension: function `%s' already
defined"), name);
+ return;
} else
/* variable name etc. */
fatal(_("extension: function name `%s' previously
defined"), name);
} else if (check_special(name) >= 0)
fatal(_("extension: can't use gawk built-in `%s' as function
name"), name);
- /* count parameters, create artificial list of param names */
if (count < 0)
fatal(_("make_builtin: negative argument count for function
`%s'"),
- name);
-
- if (count > 0) {
- sprintf(buf, "p%d", count);
- space_needed = strlen(buf) + 1;
- emalloc(vnames, char **, count * sizeof(char *),
"make_builtin");
- for (i = 0; i < count; i++) {
- emalloc(pname, char *, space_needed, "make_builtin");
- sprintf(pname, "p%d", i);
- vnames[i] = pname;
- }
- }
+ name);
-
- getnode(p);
- p->type = Node_param_list;
- p->flags |= FUNC;
- /* get our own copy for name */
- p->param = estrdup(name, strlen(name));
- p->param_cnt = count;
-
- /* actual source and line numbers set at runtime for these instructions
*/
- b = bcalloc(Op_builtin, 1, __LINE__);
+ b = bcalloc(Op_symbol, 1, 0);
b->builtin = func;
b->expr_count = count;
- b->nexti = bcalloc(Op_K_return, 1, __LINE__);
- r = bcalloc(Op_ext_func, 1, __LINE__);
- r->source_file = __FILE__;
- r->nexti = b;
/* NB: extension sub must return something */
- symbol = mk_symbol(Node_func, p);
- symbol->parmlist = vnames;
- symbol->code_ptr = r;
- r->func_body = symbol;
- (void) install_symbol(p->param, symbol);
-}
-
-
-/* get_curfunc_arg_count --- return number actual parameters */
-
-size_t
-get_curfunc_arg_count()
-{
- size_t argc;
- INSTRUCTION *pc;
-
- pc = (INSTRUCTION *) frame_ptr->reti; /* Op_func_call instruction
*/
- argc = (pc + 1)->expr_count; /* # of arguments supplied */
- return argc;
+ symbol = install_symbol(estrdup(name, strlen(name)),
Node_ext_func);
+ symbol->code_ptr = b;
}
-/* get_argument --- get the n'th argument of a dynamically linked function */
+/* get_argument --- get the i'th argument of a dynamically linked function */
NODE *
get_argument(int i)
{
- int pcount;
- NODE *t, *f;
- int actual_args;
+ NODE *t;
+ int arg_count, pcount;
INSTRUCTION *pc;
- f = frame_ptr->func_node;
- pcount = f->lnode->param_cnt;
+ pc = TOP()->code_ptr; /* Op_ext_builtin instruction */
+ pcount = (pc + 1)->expr_count; /* max # of arguments */
+ arg_count = pc->expr_count; /* # of arguments supplied */
- pc = (INSTRUCTION *) frame_ptr->reti; /* Op_func_call instruction */
- actual_args = (pc + 1)->expr_count; /* # of arguments supplied */
-
- if (i < 0 || i >= pcount || i >= actual_args)
+ if (i < 0 || i >= pcount || i >= arg_count)
return NULL;
-
- t = GET_PARAM(i);
-
+ i++;
+ t = PEEK(i);
if (t->type == Node_array_ref)
- return t->orig_array; /* Node_var_new or Node_var_array */
- if (t->type == Node_var_new || t->type == Node_var_array)
- return t;
- return t->var_value;
+ t = t->orig_array;
+ if (t->type == Node_var) /* See Case Node_var in setup_frame(),
eval.c */
+ return Nnull_string;
+ /* Node_var_new, Node_var_array or Node_val */
+ return t;
}
-/* get_actual_argument --- get a scalar or array, allowed to be optional */
+/* get_actual_argument --- get the i'th scalar or array argument of a
+ dynamically linked function, allowed to be optional.
+*/
NODE *
get_actual_argument(int i, int optional, int want_array)
{
- /* optional : if TRUE and i th argument not present return NULL, else
fatal. */
-
- NODE *t, *f;
- int pcount;
+ NODE *t;
char *fname;
-
+ int pcount;
+ INSTRUCTION *pc;
+
+ pc = TOP()->code_ptr; /* Op_ext_builtin instruction */
+ fname = (pc + 1)->func_name;
+ pcount = (pc + 1)->expr_count;
+
t = get_argument(i);
-
- f = frame_ptr->func_node;
- pcount = f->lnode->param_cnt;
- fname = f->lnode->param;
-
if (t == NULL) {
- if (i >= pcount) /* must be fatal */
+ if (i >= pcount) /* must be fatal */
fatal(_("function `%s' defined to take no more than %d
argument(s)"),
fname, pcount);
if (! optional)
@@ -279,8 +216,8 @@ get_actual_argument(int i, int optional, int want_array)
return get_array(t, FALSE);
else {
t->type = Node_var;
- t->var_value = Nnull_string;
- return Nnull_string;
+ t->var_value = dupnode(Nnull_string);
+ return t->var_value;
}
}
@@ -293,6 +230,7 @@ get_actual_argument(int i, int optional, int want_array)
fatal(_("function `%s': argument #%d: attempt to use
array as a scalar"),
fname, i + 1);
}
+ assert(t->type == Node_var_array || t->type == Node_val);
return t;
}
diff --git a/extension/arrayparm.c b/extension/arrayparm.c
index 8a550ac..b0aee33 100644
--- a/extension/arrayparm.c
+++ b/extension/arrayparm.c
@@ -43,13 +43,13 @@ int plugin_is_GPL_compatible;
*/
static NODE *
-do_mkarray(int args)
+do_mkarray(int nargs)
{
int ret = -1;
NODE *var, *sub, *val;
NODE **elemval;
- if (do_lint && get_curfunc_arg_count() > 3)
+ if (do_lint && nargs > 3)
lintwarn("mkarray: called with too many arguments");
var = get_array_argument(0, FALSE);
@@ -60,9 +60,9 @@ do_mkarray(int args)
printf("sub->type = %s\n", nodetype2str(sub->type));
printf("val->type = %s\n", nodetype2str(val->type));
- assoc_clear(var);
+ assoc_clear(var, NULL);
- elemval = assoc_lookup(var, sub, 0);
+ elemval = assoc_lookup(var, sub);
*elemval = dupnode(val);
ret = 0;
diff --git a/extension/filefuncs.c b/extension/filefuncs.c
index ad7828f..1a0a86e 100644
--- a/extension/filefuncs.c
+++ b/extension/filefuncs.c
@@ -41,7 +41,7 @@ do_chdir(int nargs)
NODE *newdir;
int ret = -1;
- if (do_lint && get_curfunc_arg_count() != 1)
+ if (do_lint && nargs != 1)
lintwarn("chdir: called with incorrect number of arguments");
newdir = get_scalar_argument(0, FALSE);
@@ -169,7 +169,7 @@ do_stat(int nargs)
char *pmode; /* printable mode */
char *type = "unknown";
- if (do_lint && get_curfunc_arg_count() > 2)
+ if (do_lint && nargs > 2)
lintwarn("stat: called with too many arguments");
/* file is first arg, array to hold results is second */
@@ -177,7 +177,7 @@ do_stat(int nargs)
array = get_array_argument(1, FALSE);
/* empty out the array */
- assoc_clear(array);
+ assoc_clear(array, NULL);
/* lstat the file, if error, set ERRNO and return */
(void) force_string(file);
@@ -188,76 +188,76 @@ do_stat(int nargs)
}
/* fill in the array */
- aptr = assoc_lookup(array, tmp = make_string("name", 4), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("name", 4));
*aptr = dupnode(file);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("dev", 3), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("dev", 3));
*aptr = make_number((AWKNUM) sbuf.st_dev);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("ino", 3), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("ino", 3));
*aptr = make_number((AWKNUM) sbuf.st_ino);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("mode", 4), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("mode", 4));
*aptr = make_number((AWKNUM) sbuf.st_mode);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("nlink", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("nlink", 5));
*aptr = make_number((AWKNUM) sbuf.st_nlink);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("uid", 3), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("uid", 3));
*aptr = make_number((AWKNUM) sbuf.st_uid);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("gid", 3), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("gid", 3));
*aptr = make_number((AWKNUM) sbuf.st_gid);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("size", 4), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("size", 4));
*aptr = make_number((AWKNUM) sbuf.st_size);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("blocks", 6), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("blocks", 6));
*aptr = make_number((AWKNUM) sbuf.st_blocks);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("atime", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("atime", 5));
*aptr = make_number((AWKNUM) sbuf.st_atime);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("mtime", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("mtime", 5));
*aptr = make_number((AWKNUM) sbuf.st_mtime);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("ctime", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("ctime", 5));
*aptr = make_number((AWKNUM) sbuf.st_ctime);
unref(tmp);
/* for block and character devices, add rdev, major and minor numbers */
if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode)) {
- aptr = assoc_lookup(array, tmp = make_string("rdev", 4), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("rdev", 4));
*aptr = make_number((AWKNUM) sbuf.st_rdev);
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("major", 5),
FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("major", 5));
*aptr = make_number((AWKNUM) major(sbuf.st_rdev));
unref(tmp);
- aptr = assoc_lookup(array, tmp = make_string("minor", 5),
FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("minor", 5));
*aptr = make_number((AWKNUM) minor(sbuf.st_rdev));
unref(tmp);
}
#ifdef HAVE_ST_BLKSIZE
- aptr = assoc_lookup(array, tmp = make_string("blksize", 7), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("blksize", 7));
*aptr = make_number((AWKNUM) sbuf.st_blksize);
unref(tmp);
#endif /* HAVE_ST_BLKSIZE */
- aptr = assoc_lookup(array, tmp = make_string("pmode", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("pmode", 5));
pmode = format_mode(sbuf.st_mode);
*aptr = make_string(pmode, strlen(pmode));
unref(tmp);
@@ -277,7 +277,7 @@ do_stat(int nargs)
*/
buf[linksize] = '\0';
- aptr = assoc_lookup(array, tmp = make_string("linkval",
7), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("linkval",
7));
*aptr = make_str_node(buf, linksize, ALREADY_MALLOCED);
unref(tmp);
}
@@ -319,7 +319,7 @@ do_stat(int nargs)
#endif
}
- aptr = assoc_lookup(array, tmp = make_string("type", 4), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("type", 4));
*aptr = make_string(type, strlen(type));
unref(tmp);
diff --git a/extension/fork.c b/extension/fork.c
index aff9b56..8835387 100644
--- a/extension/fork.c
+++ b/extension/fork.c
@@ -38,7 +38,7 @@ do_fork(int nargs)
NODE **aptr;
NODE *tmp;
- if (do_lint && get_curfunc_arg_count() > 0)
+ if (do_lint && nargs > 0)
lintwarn("fork: called with too many arguments");
ret = fork();
@@ -48,11 +48,11 @@ do_fork(int nargs)
else if (ret == 0) {
/* update PROCINFO in the child */
- aptr = assoc_lookup(PROCINFO_node, tmp = make_string("pid", 3),
FALSE);
+ aptr = assoc_lookup(PROCINFO_node, tmp = make_string("pid", 3));
(*aptr)->numbr = (AWKNUM) getpid();
unref(tmp);
- aptr = assoc_lookup(PROCINFO_node, tmp = make_string("ppid",
4), FALSE);
+ aptr = assoc_lookup(PROCINFO_node, tmp = make_string("ppid",
4));
(*aptr)->numbr = (AWKNUM) getppid();
unref(tmp);
}
@@ -73,7 +73,7 @@ do_waitpid(int nargs)
pid_t pid;
int options = 0;
- if (do_lint && get_curfunc_arg_count() > 1)
+ if (do_lint && nargs > 1)
lintwarn("waitpid: called with too many arguments");
pidnode = get_scalar_argument(0, FALSE);
diff --git a/extension/ordchr.c b/extension/ordchr.c
index efbc6d5..8926a94 100644
--- a/extension/ordchr.c
+++ b/extension/ordchr.c
@@ -40,7 +40,7 @@ do_ord(int nargs)
NODE *str;
int ret = -1;
- if (do_lint && get_curfunc_arg_count() > 1)
+ if (do_lint && nargs > 1)
lintwarn("ord: called with too many arguments");
str = get_scalar_argument(0, FALSE);
@@ -67,7 +67,7 @@ do_chr(int nargs)
str[0] = str[1] = '\0';
- if (do_lint && get_curfunc_arg_count() > 1)
+ if (do_lint && nargs > 1)
lintwarn("chr: called with too many arguments");
num = get_scalar_argument(0, FALSE);
diff --git a/extension/readfile.c b/extension/readfile.c
index e6ee0f2..c9b1efc 100644
--- a/extension/readfile.c
+++ b/extension/readfile.c
@@ -50,7 +50,7 @@ do_readfile(int nargs)
char *text;
int fd;
- if (do_lint && get_curfunc_arg_count() > 1)
+ if (do_lint && nargs > 1)
lintwarn("readfile: called with too many arguments");
filename = get_scalar_argument(0, FALSE);
diff --git a/extension/rwarray.c b/extension/rwarray.c
index 3c62957..8175c7c 100644
--- a/extension/rwarray.c
+++ b/extension/rwarray.c
@@ -82,7 +82,7 @@ do_writea(int nargs)
uint32_t major = MAJOR;
uint32_t minor = MINOR;
- if (do_lint && get_curfunc_arg_count() > 2)
+ if (do_lint && nargs > 2)
lintwarn("writea: called with too many arguments");
/* directory is first arg, array to dump is second */
@@ -250,7 +250,7 @@ do_reada(int nargs)
uint32_t minor;
char magic_buf[30];
- if (do_lint && get_curfunc_arg_count() > 2)
+ if (do_lint && nargs > 2)
lintwarn("reada: called with too many arguments");
/* directory is first arg, array to dump is second */
@@ -289,7 +289,7 @@ do_reada(int nargs)
goto done1;
}
- assoc_clear(array);
+ assoc_clear(array, NULL);
ret = read_array(fd, array);
if (ret == 0)
diff --git a/extension/testarg.c b/extension/testarg.c
index ba4d56f..4d012db 100644
--- a/extension/testarg.c
+++ b/extension/testarg.c
@@ -5,17 +5,15 @@ int plugin_is_GPL_compatible;
static NODE *
do_check_arg(int nargs)
{
- int ret = 0, argc;
+ int ret = 0;
NODE *arg1, *arg2, *arg3;
- argc = get_curfunc_arg_count();
- printf("arg count: defined = %d, supplied = %d\n",
- nargs, argc);
+ printf("arg count: defined = 3, supplied = %d\n", nargs);
arg1 = get_scalar_argument(0, FALSE);
arg2 = get_array_argument(1, FALSE);
arg3 = get_scalar_argument(2, TRUE); /* optional */
- if (argc > 3) {
+ if (nargs > 3) {
/* try to use an extra arg */
NODE *arg4;
arg4 = get_array_argument(3, TRUE);
diff --git a/field.c b/field.c
index 0b9c100..67973a9 100644
--- a/field.c
+++ b/field.c
@@ -85,13 +85,13 @@ void
init_fields()
{
emalloc(fields_arr, NODE **, sizeof(NODE *), "init_fields");
- fields_arr[0] = Nnull_string;
+ fields_arr[0] = dupnode(Nnull_string);
parse_extent = fields_arr[0]->stptr;
save_FS = dupnode(FS_node->var_value);
getnode(Null_field);
*Null_field = *Nnull_string;
- Null_field->flags |= FIELD;
- Null_field->flags &= ~(NUMCUR|NUMBER|MAYBE_NUM|PERM|MALLOC);
+ Null_field->valref = 1;
+ Null_field->flags = (FIELD|STRCUR|STRING);
field0_valid = TRUE;
}
@@ -185,7 +185,7 @@ rebuild_record()
}
}
}
- tmp = make_str_node(ops, tlen, ALREADY_MALLOCED);
+ tmp = make_str_node(ops, tlen);
/*
* Since we are about to unref fields_arr[0], we want to find
@@ -207,7 +207,7 @@ rebuild_record()
}
} else {
*n = *(fields_arr[i]);
- n->flags &= ~(MALLOC|PERM|STRING);
+ n->flags &= ~(MALLOC|STRING);
}
n->stptr = cops;
@@ -289,7 +289,7 @@ reset_record()
int i;
NODE *n;
- (void) force_string(fields_arr[0]);
+ fields_arr[0] = force_string(fields_arr[0]);
NF = -1;
for (i = 1; i <= parse_high_water; i++) {
@@ -926,7 +926,7 @@ set_element(long num, char *s, long len, NODE *n)
it = make_string(s, len);
it->flags |= MAYBE_NUM;
sub = make_number((AWKNUM) (num));
- lhs = assoc_lookup(n, sub, FALSE);
+ lhs = assoc_lookup(n, sub);
unref(sub);
unref(*lhs);
*lhs = it;
@@ -987,8 +987,8 @@ do_split(int nargs)
/*
* Skip the work if first arg is the null string.
*/
- decr_sp();
- DEREF(src);
+ tmp = POP_SCALAR();
+ DEREF(tmp);
return make_number((AWKNUM) 0);
}
@@ -1026,7 +1026,7 @@ do_split(int nargs)
tmp = make_number((AWKNUM) (*parseit)(UNLIMITED, &s, (int) src->stlen,
fs, rp, set_element, arr, sep_arr,
FALSE));
- decr_sp();
+ src = POP_SCALAR(); /* really pop off stack */
DEREF(src);
return tmp;
}
@@ -1087,7 +1087,7 @@ do_patsplit(int nargs)
set_element, arr, sep_arr, FALSE));
}
- decr_sp(); /* 1st argument not POP-ed */
+ src = POP_SCALAR(); /* really pop off stack */
DEREF(src);
return tmp;
}
@@ -1103,6 +1103,7 @@ set_FIELDWIDTHS()
static int fw_alloc = 4;
static short warned = FALSE;
int fatal_error = FALSE;
+ NODE *tmp;
if (do_lint && ! warned) {
warned = TRUE;
@@ -1119,7 +1120,8 @@ set_FIELDWIDTHS()
(void) get_field(UNLIMITED - 1, 0);
parse_field = fw_parse_field;
- scan = force_string(FIELDWIDTHS_node->var_value)->stptr;
+ tmp = force_string(FIELDWIDTHS_node->var_value);
+ scan = tmp->stptr;
if (FIELDWIDTHS == NULL)
emalloc(FIELDWIDTHS, int *, fw_alloc * sizeof(int),
"set_FIELDWIDTHS");
@@ -1330,7 +1332,7 @@ update_PROCINFO_str(const char *subscript, const char
*str)
if (PROCINFO_node == NULL)
return;
tmp = make_string(subscript, strlen(subscript));
- aptr = assoc_lookup(PROCINFO_node, tmp, FALSE);
+ aptr = assoc_lookup(PROCINFO_node, tmp);
unref(tmp);
unref(*aptr);
*aptr = make_string(str, strlen(str));
@@ -1347,7 +1349,7 @@ update_PROCINFO_num(const char *subscript, AWKNUM val)
if (PROCINFO_node == NULL)
return;
tmp = make_string(subscript, strlen(subscript));
- aptr = assoc_lookup(PROCINFO_node, tmp, FALSE);
+ aptr = assoc_lookup(PROCINFO_node, tmp);
unref(tmp);
unref(*aptr);
*aptr = make_number(val);
diff --git a/io.c b/io.c
index 21301f4..b14be1b 100644
--- a/io.c
+++ b/io.c
@@ -208,7 +208,7 @@ static int inetfile(const char *str, int *length, int
*family);
#endif
static struct redirect *red_head = NULL;
-static NODE *RS;
+static NODE *RS = NULL;
static Regexp *RS_re_yes_case;
static Regexp *RS_re_no_case;
static Regexp *RS_regexp;
@@ -610,7 +610,7 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
if (do_lint && (redir_exp->flags & STRCUR) == 0)
lintwarn(_("expression in `%s' redirection only has numeric
value"),
what);
- redir_exp = force_string(redir_exp);
+ redir_exp= force_string(redir_exp);
str = redir_exp->stptr;
if (str == NULL || *str == '\0')
@@ -2527,7 +2527,7 @@ iop_alloc(int fd, const char *name, IOBUF *iop, int
do_openhooks)
#define set_RT_to_null() \
(void)(! do_traditional && (unref(RT_node->var_value), \
- RT_node->var_value = Nnull_string))
+ RT_node->var_value = dupnode(Nnull_string)))
#define set_RT(str, len) \
(void)(! do_traditional && (unref(RT_node->var_value), \
@@ -3138,8 +3138,7 @@ pty_vs_pipe(const char *command)
#ifdef HAVE_TERMIOS_H
char *full_index;
size_t full_len;
- NODE *val;
- NODE *sub;
+ NODE *val, *sub;
if (PROCINFO_node == NULL)
return FALSE;
diff --git a/main.c b/main.c
index b30924b..f3f1524 100644
--- a/main.c
+++ b/main.c
@@ -129,23 +129,11 @@ static int disallow_var_assigns = FALSE; /* true for
--exec */
static void add_preassign(enum assign_type type, char *val);
-#undef do_lint
-#undef do_lint_old
-
-int do_traditional = FALSE; /* no gnu extensions, add traditional
weirdnesses */
-int do_posix = FALSE; /* turn off gnu and unix extensions */
-int do_lint = FALSE; /* provide warnings about questionable stuff */
-int do_lint_old = FALSE; /* warn about stuff not in V7 awk */
-int do_intl = FALSE; /* dump locale-izable strings to stdout */
-int do_non_decimal_data = FALSE; /* allow octal/hex C style DATA. Use
with caution! */
-int do_nostalgia = FALSE; /* provide a blast from the past */
-int do_intervals = FALSE; /* allow {...,...} in regexps, see resetup() */
-int do_profiling = FALSE; /* profile and pretty print the program */
-int do_dump_vars = FALSE; /* dump all global variables at end */
-int do_tidy_mem = FALSE; /* release vars when done */
-int do_optimize = TRUE; /* apply default optimizations */
-int do_binary = FALSE; /* hands off my data! */
-int do_sandbox = FALSE; /* sandbox mode - disable 'system' function &
redirections */
+int do_flags = FALSE;
+int do_optimize = TRUE; /* apply default
optimizations */
+static int do_nostalgia = FALSE; /* provide a blast from the past */
+static int do_binary = FALSE; /* hands off my data! */
+
int use_lc_numeric = FALSE; /* obey locale for decimal point */
#ifdef MBS_SUPPORT
@@ -174,20 +162,20 @@ void (*lintfunc)(const char *mesg, ...) = warning;
* Note: reserve -l for future use, for xgawk's -l option.
*/
static const struct option optab[] = {
- { "traditional", no_argument, & do_traditional,
1 },
+ { "traditional", no_argument, NULL, 'c' },
{ "lint", optional_argument, NULL, 'L' },
- { "lint-old", no_argument, & do_lint_old, 1 },
- { "optimize", no_argument, & do_optimize, 'O' },
- { "posix", no_argument, & do_posix, 1 },
+ { "lint-old", no_argument, NULL, 't' },
+ { "optimize", no_argument, NULL, 'O' },
+ { "posix", no_argument, NULL, 'P' },
{ "command", required_argument, NULL, 'R' },
{ "nostalgia", no_argument, & do_nostalgia, 1 },
- { "gen-pot", no_argument, & do_intl, 1 },
- { "non-decimal-data", no_argument, & do_non_decimal_data,
1 },
+ { "gen-pot", no_argument, NULL, 'g' },
+ { "non-decimal-data", no_argument, NULL, 'n' },
{ "profile", optional_argument, NULL, 'p' },
{ "copyright", no_argument, NULL, 'C' },
{ "field-separator", required_argument, NULL, 'F' },
{ "file", required_argument, NULL, 'f' },
- { "re-interval", no_argument, & do_intervals, 1 },
+ { "re-interval", no_argument, NULL, 'r' },
{ "source", required_argument, NULL, 'e' },
{ "dump-variables", optional_argument, NULL, 'd' },
{ "assign", required_argument, NULL, 'v' },
@@ -196,17 +184,13 @@ static const struct option optab[] = {
{ "exec", required_argument, NULL, 'E' },
{ "use-lc-numeric", no_argument, & use_lc_numeric, 1 },
{ "characters-as-bytes", no_argument, & do_binary, 'b' },
- { "sandbox", no_argument, & do_sandbox, 1 },
+ { "sandbox", no_argument, NULL, 'S' },
#if defined(YYDEBUG) || defined(GAWKDEBUG)
{ "parsedebug", no_argument, NULL, 'Y' },
#endif
{ NULL, 0, NULL, '\0' }
};
-#ifdef NO_LINT
-#define do_lint 0
-#define do_lint_old 0
-#endif
/* main --- process args, parse program, run it, clean up */
@@ -227,7 +211,8 @@ main(int argc, char **argv)
char *extra_stack;
/* do these checks early */
- do_tidy_mem = (getenv("TIDYMEM") != NULL);
+ if (getenv("TIDYMEM") != NULL)
+ do_flags |= DO_TIDY_MEM;
#ifdef HAVE_MCHECK_H
#ifdef HAVE_MTRACE
@@ -373,7 +358,7 @@ main(int argc, char **argv)
break;
case 'c':
- do_traditional = TRUE;
+ do_flags |= DO_TRADITIONAL;
break;
case 'C':
@@ -381,7 +366,7 @@ main(int argc, char **argv)
break;
case 'd':
- do_dump_vars = TRUE;
+ do_flags |= DO_DUMP_VARS;
if (optarg != NULL && optarg[0] != '\0')
varfile = optarg;
break;
@@ -394,7 +379,7 @@ main(int argc, char **argv)
break;
case 'g':
- do_intl = TRUE;
+ do_flags |= DO_INTL;
break;
case 'h':
@@ -402,19 +387,21 @@ main(int argc, char **argv)
usage(EXIT_SUCCESS, stdout);
break;
-#ifndef NO_LINT
case 'L':
- do_lint = LINT_ALL;
+#ifndef NO_LINT
+ do_flags |= DO_LINT_ALL;
if (optarg != NULL) {
if (strcmp(optarg, "fatal") == 0)
lintfunc = r_fatal;
- else if (strcmp(optarg, "invalid") == 0)
- do_lint = LINT_INVALID;
+ else if (strcmp(optarg, "invalid") == 0) {
+ do_flags &= ~DO_LINT_ALL;
+ do_flags |= DO_LINT_INVALID;
+ }
}
break;
case 't':
- do_lint_old = TRUE;
+ do_flags |= DO_LINT_OLD;
break;
#else
case 'L':
@@ -423,7 +410,7 @@ main(int argc, char **argv)
#endif
case 'n':
- do_non_decimal_data = TRUE;
+ do_flags |= DO_NON_DEC_DATA;
break;
case 'N':
@@ -435,7 +422,7 @@ main(int argc, char **argv)
break;
case 'p':
- do_profiling = TRUE;
+ do_flags |= DO_PROFILING;
if (optarg != NULL)
set_prof_file(optarg);
else
@@ -443,15 +430,15 @@ main(int argc, char **argv)
break;
case 'P':
- do_posix = TRUE;
+ do_flags |= DO_POSIX;
break;
case 'r':
- do_intervals = TRUE;
+ do_flags |= DO_INTERVALS;
break;
case 'S':
- do_sandbox = TRUE;
+ do_flags |= DO_SANDBOX;
break;
case 'V':
@@ -530,7 +517,7 @@ out:
/* check for POSIXLY_CORRECT environment variable */
if (! do_posix && getenv("POSIXLY_CORRECT") != NULL) {
- do_posix = TRUE;
+ do_flags |= DO_POSIX;
if (do_lint)
lintwarn(
_("environment variable `POSIXLY_CORRECT' set: turning on `--posix'"));
@@ -541,7 +528,7 @@ out:
if (do_traditional) /* both on command line */
warning(_("`--posix' overrides `--traditional'"));
else
- do_traditional = TRUE;
+ do_flags |= DO_TRADITIONAL;
/*
* POSIX compliance also implies
* no GNU extensions either.
@@ -549,7 +536,7 @@ out:
}
if (do_traditional && do_non_decimal_data) {
- do_non_decimal_data = FALSE;
+ do_flags &= ~DO_NON_DEC_DATA;
warning(_("`--posix'/`--traditional' overrides
`--non-decimal-data'"));
}
@@ -570,7 +557,7 @@ out:
* Don't bother if the command line already set profiling up.
*/
if (! do_profiling)
- init_profiling(& do_profiling, DEFAULT_PROFILE);
+ init_profiling(& do_flags, DEFAULT_PROFILE);
/* load group set */
init_groupset();
@@ -578,8 +565,7 @@ out:
/* initialize the null string */
Nnull_string = make_string("", 0);
Nnull_string->numbr = 0.0;
- Nnull_string->type = Node_val;
- Nnull_string->flags = (PERM|STRCUR|STRING|NUMCUR|NUMBER);
+ Nnull_string->flags = (MALLOC|STRCUR|STRING|NUMCUR|NUMBER);
/*
* Tell the regex routines how they should work.
@@ -734,8 +720,9 @@ usage(int exitval, FILE *fp)
/* Not factoring out common stuff makes it easier to translate. */
fprintf(fp, _("Usage: %s [POSIX or GNU style options] -f progfile [--]
file ...\n"),
myname);
- fprintf(fp, _("Usage: %s [POSIX or GNU style options] [--] %cprogram%c
file ...\n"),
- myname, quote, quote);
+ if (which_gawk != exe_debugging)
+ fprintf(fp, _("Usage: %s [POSIX or GNU style options] [--]
%cprogram%c file ...\n"),
+ myname, quote, quote);
/* GNU long options info. This is too many options. */
@@ -842,6 +829,7 @@ static void
cmdline_fs(char *str)
{
NODE **tmp;
+ size_t len;
tmp = &FS_node->var_value;
unref(*tmp);
@@ -858,7 +846,9 @@ cmdline_fs(char *str)
if (do_traditional && ! do_posix)
str[0] = '\t';
}
- *tmp = make_str_node(str, strlen(str), SCAN); /* do process escapes */
+
+ len = scan_escape(str, strlen(str)); /* do process escapes */
+ *tmp = make_string(str, len);
set_FS();
}
@@ -871,26 +861,27 @@ init_args(int argc0, int argc, const char *argv0, char
**argv)
NODE **aptr;
NODE *tmp;
- ARGV_node = install_symbol(estrdup("ARGV", 4),
mk_symbol(Node_var_array, (NODE *) NULL));
+ ARGV_node = install_symbol(estrdup("ARGV", 4), Node_var_array);
tmp = make_number(0.0);
- aptr = assoc_lookup(ARGV_node, tmp, FALSE);
+ aptr = assoc_lookup(ARGV_node, tmp);
unref(tmp);
unref(*aptr);
*aptr = make_string(argv0, strlen(argv0));
(*aptr)->flags |= MAYBE_NUM;
for (i = argc0, j = 1; i < argc; i++, j++) {
tmp = make_number((AWKNUM) j);
- aptr = assoc_lookup(ARGV_node, tmp, FALSE);
+ aptr = assoc_lookup(ARGV_node, tmp);
unref(tmp);
unref(*aptr);
*aptr = make_string(argv[i], strlen(argv[i]));
(*aptr)->flags |= MAYBE_NUM;
}
- ARGC_node = install_symbol(estrdup("ARGC", 4),
- mk_symbol(Node_var,
make_number((AWKNUM) j)));
+ ARGC_node = install_symbol(estrdup("ARGC", 4), Node_var);
+ ARGC_node->var_value = make_number((AWKNUM) j);
}
+
/*
* Set all the special variables to their initial values.
* Note that some of the variables that have set_FOO routines should
@@ -953,13 +944,11 @@ init_vars()
for (vp = varinit; vp->name != NULL; vp++) {
if ((vp->flags & NO_INSTALL) != 0)
continue;
- n = mk_symbol(Node_var, vp->strval == NULL
- ? make_number(vp->numval)
- : make_string(vp->strval, strlen(vp->strval)));
+ n = *(vp->spec) = install_symbol(estrdup(vp->name,
strlen(vp->name)), Node_var);
+ n->var_value = vp->strval == NULL ? make_number(vp->numval)
+ :
make_string(vp->strval, strlen(vp->strval));
n->var_assign = (Func_ptr) vp->assign;
n->var_update = (Func_ptr) vp->update;
-
- *(vp->spec) = install_symbol(estrdup(vp->name,
strlen(vp->name)), n);
if (vp->do_assign)
(*(vp->assign))();
}
@@ -983,9 +972,7 @@ load_environ()
int i;
NODE *tmp;
- ENVIRON_node = install_symbol(estrdup("ENVIRON", 7),
- mk_symbol(Node_var_array, (NODE *) NULL));
-
+ ENVIRON_node = install_symbol(estrdup("ENVIRON", 7), Node_var_array);
for (i = 0; environ[i] != NULL; i++) {
static char nullstr[] = "";
@@ -996,7 +983,7 @@ load_environ()
else
val = nullstr;
tmp = make_string(var, strlen(var));
- aptr = assoc_lookup(ENVIRON_node, tmp, FALSE);
+ aptr = assoc_lookup(ENVIRON_node, tmp);
unref(tmp);
unref(*aptr);
*aptr = make_string(val, strlen(val));
@@ -1019,7 +1006,7 @@ load_environ()
val = getenv("AWKPATH");
if (val == NULL)
val = defpath;
- aptr = assoc_lookup(ENVIRON_node, tmp, FALSE);
+ aptr = assoc_lookup(ENVIRON_node, tmp);
unref(*aptr);
*aptr = make_string(val, strlen(val));
}
@@ -1038,8 +1025,7 @@ load_procinfo()
#endif
AWKNUM value;
- PROCINFO_node = install_symbol(estrdup("PROCINFO", 8),
- mk_symbol(Node_var_array, (NODE *) NULL));
+ PROCINFO_node = install_symbol(estrdup("PROCINFO", 8), Node_var_array);
update_PROCINFO_str("version", VERSION);
update_PROCINFO_str("strftime", def_strftime_format);
@@ -1133,6 +1119,7 @@ int
arg_assign(char *arg, int initing)
{
char *cp, *cp2;
+ size_t cplen;
int badvar;
NODE *var;
NODE *it;
@@ -1194,7 +1181,8 @@ arg_assign(char *arg, int initing)
* BWK awk expands escapes inside assignments.
* This makes sense, so we do it too.
*/
- it = make_str_node(cp, strlen(cp), SCAN);
+ cplen = scan_escape(cp, strlen(cp));
+ it = make_string(cp, cplen);
it->flags |= MAYBE_NUM;
#ifdef LC_NUMERIC
/*
@@ -1215,7 +1203,7 @@ arg_assign(char *arg, int initing)
cp2 = estrdup(arg, cp - arg); /* var name */
- var = variable(cp2, Node_var);
+ var = variable(0, cp2, Node_var);
if (var == NULL) /* error */
exit(EXIT_FATAL);
if (var->type == Node_var && var->var_update)
@@ -1439,3 +1427,18 @@ update_global_values()
vp->update();
}
}
+
+/* getenv_long --- read a long value (>= 0) from an environment var. */
+
+long
+getenv_long(const char *name)
+{
+ const char *val;
+ long newval;
+ if ((val = getenv(name)) != NULL && isdigit((unsigned char) *val)) {
+ for (newval = 0; *val && isdigit((unsigned char) *val); val++)
+ newval = (newval * 10) + *val - '0';
+ return newval;
+ }
+ return -1;
+}
diff --git a/node.c b/node.c
index 315d46c..36c6004 100644
--- a/node.c
+++ b/node.c
@@ -29,6 +29,8 @@
static int is_ieee_magic_val(const char *val);
static AWKNUM get_ieee_magic_val(const char *val);
+extern NODE **fmt_list; /* declared in eval.c */
+
/* force_number --- force a value to be numeric */
@@ -104,6 +106,8 @@ r_force_number(NODE *n)
n->numbr = (AWKNUM)(*cp - '0');
n->flags |= newflags;
n->flags |= NUMCUR;
+ if (cp == n->stptr) /* no leading spaces */
+ n->flags |= NUMINT;
}
return n->numbr;
}
@@ -166,18 +170,6 @@ format_val(const char *format, int index, NODE *s)
char buf[BUFSIZ];
char *sp = buf;
double val;
- char *orig, *trans, save;
-
- if (! do_traditional && (s->flags & INTLSTR) != 0) {
- save = s->stptr[s->stlen];
- s->stptr[s->stlen] = '\0';
-
- orig = s->stptr;
- trans = dgettext(TEXTDOMAIN, orig);
-
- s->stptr[s->stlen] = save;
- return make_string(trans, strlen(trans));
- }
/*
* 2/2007: Simplify our lives here. Instead of worrying about
@@ -210,7 +202,6 @@ format_val(const char *format, int index, NODE *s)
NODE *dummy[2], *r;
unsigned short oflags;
- extern NODE **fmt_list; /* declared in eval.c */
/* create dummy node for a sole use of format_tree */
dummy[1] = s;
@@ -234,8 +225,7 @@ format_val(const char *format, int index, NODE *s)
goto no_malloc;
} else {
/*
- * integral value
- * force conversion to long only once
+ * integral value; force conversion to long only once.
*/
long num = (long) val;
@@ -247,19 +237,25 @@ format_val(const char *format, int index, NODE *s)
s->stlen = strlen(sp);
}
s->stfmt = -1;
+ if (s->flags & INTIND) {
+ s->flags &= ~(INTIND|NUMBER);
+ s->flags |= STRING;
+ }
}
if (s->stptr != NULL)
efree(s->stptr);
emalloc(s->stptr, char *, s->stlen + 2, "format_val");
- memcpy(s->stptr, sp, s->stlen+1);
+ memcpy(s->stptr, sp, s->stlen + 1);
no_malloc:
s->flags |= STRCUR;
free_wstr(s);
return s;
}
-/* force_string --- force a value to be a string */
+/* r_force_string --- force a value to be a string */
+
+#ifdef GAWKDEBUG
NODE *
r_force_string(NODE *s)
{
@@ -269,28 +265,23 @@ r_force_string(NODE *s)
return s;
return format_val(CONVFMT, CONVFMTidx, s);
}
+#endif
-/* dupnode --- duplicate a node */
+/* r_dupnode --- duplicate a node */
NODE *
-dupnode(NODE *n)
+r_dupnode(NODE *n)
{
NODE *r;
- if (n->type == Node_ahash) {
- n->ahname_ref++;
- return n;
- }
-
assert(n->type == Node_val);
- if ((n->flags & PERM) != 0)
- return n;
-
+#ifdef GAWKDEBUG
if ((n->flags & MALLOC) != 0) {
n->valref++;
return n;
}
+#endif
getnode(r);
*r = *n;
@@ -308,13 +299,13 @@ dupnode(NODE *n)
#endif /* defined MBS_SUPPORT */
if ((n->flags & STRCUR) != 0) {
- emalloc(r->stptr, char *, n->stlen + 2, "dupnode");
+ emalloc(r->stptr, char *, n->stlen + 2, "r_dupnode");
memcpy(r->stptr, n->stptr, n->stlen);
r->stptr[n->stlen] = '\0';
#if defined MBS_SUPPORT
if ((n->flags & WSTRCUR) != 0) {
r->wstlen = n->wstlen;
- emalloc(r->wstptr, wchar_t *, sizeof(wchar_t) *
(n->wstlen + 2), "dupnode");
+ emalloc(r->wstptr, wchar_t *, sizeof(wchar_t) *
(n->wstlen + 2), "r_dupnode");
memcpy(r->wstptr, n->wstptr, n->wstlen *
sizeof(wchar_t));
r->wstptr[n->wstlen] = L'\0';
r->flags |= WSTRCUR;
@@ -325,156 +316,78 @@ dupnode(NODE *n)
return r;
}
-/* mk_number --- allocate a node with defined number */
+/* make_number --- allocate a node with defined number */
NODE *
-mk_number(AWKNUM x, unsigned int flags)
+make_number(AWKNUM x)
{
NODE *r;
-
getnode(r);
r->type = Node_val;
r->numbr = x;
r->valref = 1;
- r->flags = flags;
+ r->flags = MALLOC|NUMBER|NUMCUR;
r->stptr = NULL;
r->stlen = 0;
- free_wstr(r);
+#ifdef MBS_SUPPORT
+ r->wstptr = NULL;
+ r->wstlen = 0;
+#endif /* defined MBS_SUPPORT */
return r;
}
-/* make_str_node --- make a string node */
+
+/* r_make_str_node --- make a string node */
NODE *
-r_make_str_node(const char *s, unsigned long len, int flags)
+r_make_str_node(const char *s, size_t len, int already_malloced)
{
NODE *r;
getnode(r);
r->type = Node_val;
+ r->flags = (MALLOC|STRING|STRCUR);
+ r->valref = 1;
r->numbr = 0;
- r->flags = (STRING|STRCUR|MALLOC);
-#ifdef MBS_SUPPORT
- r->wstptr = NULL;
- r->wstlen = 0;
-#endif /* defined MBS_SUPPORT */
-
- if (flags & ALREADY_MALLOCED)
+ r->stfmt = -1;
+ r->stlen = len;
+ if (already_malloced)
r->stptr = (char *) s;
else {
- emalloc(r->stptr, char *, len + 2, "make_str_node");
+ emalloc(r->stptr, char *, len + 2, "make_string");
memcpy(r->stptr, s, len);
}
r->stptr[len] = '\0';
- if ((flags & SCAN) != 0) { /* scan for escape sequences */
- const char *pf;
- char *ptm;
- int c;
- const char *end;
#ifdef MBS_SUPPORT
- mbstate_t cur_state;
-
- memset(& cur_state, 0, sizeof(cur_state));
-#endif
-
- end = &(r->stptr[len]);
- for (pf = ptm = r->stptr; pf < end;) {
-#ifdef MBS_SUPPORT
- /*
- * Keep multibyte characters together. This avoids
- * problems if a subsequent byte of a multibyte
- * character happens to be a backslash.
- */
- if (gawk_mb_cur_max > 1) {
- int mblen = mbrlen(pf, end-pf, &cur_state);
-
- if (mblen > 1) {
- int i;
-
- for (i = 0; i < mblen; i++)
- *ptm++ = *pf++;
- continue;
- }
- }
-#endif
- c = *pf++;
- if (c == '\\') {
- c = parse_escape(&pf);
- if (c < 0) {
- if (do_lint)
- lintwarn(_("backslash at end of
string"));
- c = '\\';
- }
- *ptm++ = c;
- } else
- *ptm++ = c;
- }
- len = ptm - r->stptr;
- erealloc(r->stptr, char *, len + 1, "make_str_node");
- r->stptr[len] = '\0';
- r->flags &= ~MALLOC;
- r->flags |= PERM;
- }
- r->stlen = len;
- r->valref = 1;
- r->stfmt = -1;
-
+ r->wstptr = NULL;
+ r->wstlen = 0;
+#endif /* defined MBS_SUPPORT */
return r;
}
-/* more_nodes --- allocate more nodes */
-
-#define NODECHUNK 100
-
-NODE *nextfree = NULL;
-
-NODE *
-more_nodes()
-{
- NODE *np;
-
- /* get more nodes and initialize list */
- emalloc(nextfree, NODE *, NODECHUNK * sizeof(NODE), "more_nodes");
- memset(nextfree, 0, NODECHUNK * sizeof(NODE));
- for (np = nextfree; np <= &nextfree[NODECHUNK - 1]; np++) {
- np->nextp = np + 1;
- }
- --np;
- np->nextp = NULL;
- np = nextfree;
- nextfree = nextfree->nextp;
- return np;
-}
/* unref --- remove reference to a particular node */
void
-unref(NODE *tmp)
+r_unref(NODE *tmp)
{
+#ifdef GAWKDEBUG
if (tmp == NULL)
return;
- if ((tmp->flags & PERM) != 0)
- return;
-
- if (tmp->type == Node_ahash) {
- if (tmp->ahname_ref > 1)
- tmp->ahname_ref--;
- else {
- efree(tmp->ahname_str);
- freenode(tmp);
- }
- return;
- }
-
if ((tmp->flags & MALLOC) != 0) {
if (tmp->valref > 1) {
- tmp->valref--;
+ tmp->valref--;
return;
- }
+ }
if (tmp->flags & STRCUR)
efree(tmp->stptr);
}
+#else
+ if ((tmp->flags & (MALLOC|STRCUR)) == (MALLOC|STRCUR))
+ efree(tmp->stptr);
+#endif
+
free_wstr(tmp);
freenode(tmp);
}
@@ -615,6 +528,61 @@ parse_escape(const char **string_ptr)
}
}
+
+/* scan_escape --- scan for escape sequences */
+
+size_t
+scan_escape(char *s, size_t len)
+{
+ const char *pf;
+ char *ptm;
+ int c;
+ const char *end;
+#ifdef MBS_SUPPORT
+ mbstate_t cur_state;
+
+ memset(& cur_state, 0, sizeof(cur_state));
+#endif
+
+ end = & s[len];
+ for (pf = ptm = s; pf < end;) {
+#ifdef MBS_SUPPORT
+ /*
+ * Keep multibyte characters together. This avoids
+ * problems if a subsequent byte of a multibyte
+ * character happens to be a backslash.
+ */
+ if (gawk_mb_cur_max > 1) {
+ int mblen = mbrlen(pf, end-pf, &cur_state);
+
+ if (mblen > 1) {
+ int i;
+
+ for (i = 0; i < mblen; i++)
+ *ptm++ = *pf++;
+ continue;
+ }
+ }
+#endif
+ c = *pf++;
+ if (c == '\\') {
+ c = parse_escape(&pf);
+ if (c < 0) {
+ if (do_lint)
+ lintwarn(_("backslash at end of
string"));
+ c = '\\';
+ }
+ *ptm++ = c;
+ } else
+ *ptm++ = c;
+ }
+
+ len = ptm - s;
+ s[len] = '\0';
+ return len;
+}
+
+
/* isnondecimal --- return true if number is not a decimal number */
int
@@ -963,3 +931,41 @@ void init_btowc_cache()
}
}
#endif
+
+#define BLOCKCHUNK 100
+
+BLOCK nextfree[BLOCK_MAX] = {
+ { 0, NULL}, /* invalid */
+ { sizeof(NODE), NULL },
+ { sizeof(BUCKET), NULL },
+};
+
+
+/* more_blocks --- get more blocks of memory and add to the free list;
+ size of a block must be >= sizeof(BLOCK)
+ */
+
+void *
+more_blocks(int id)
+{
+ BLOCK *freep, *np, *next;
+ char *p, *endp;
+ size_t size;
+
+ size = nextfree[id].size;
+
+ emalloc(freep, BLOCK *, BLOCKCHUNK * size, "more_blocks");
+ p = (char *) freep;
+ endp = p + BLOCKCHUNK * size;
+
+ for (np = freep; ; np = next) {
+ next = (BLOCK *) (p += size);
+ if (p >= endp) {
+ np->freep = NULL;
+ break;
+ }
+ np->freep = next;
+ }
+ nextfree[id].freep = freep->freep;
+ return freep;
+}
diff --git a/profile.c b/profile.c
index cba8be9..a4a5e9d 100644
--- a/profile.c
+++ b/profile.c
@@ -51,7 +51,7 @@ static RETSIGTYPE just_dump(int signum);
/* pretty printing related functions and variables */
static NODE *pp_stack = NULL;
-static char **fparms; /* function parameter names */
+static NODE *func_params; /* function parameters */
static FILE *prof_fp; /* where to send the profile */
static long indent_level = 0;
@@ -66,7 +66,7 @@ init_profiling(int *flag ATTRIBUTE_UNUSED, const char
*def_file ATTRIBUTE_UNUSED
{
#ifdef PROFILING
if (*flag == FALSE) {
- *flag = TRUE;
+ *flag |= DO_PROFILING;
set_prof_file(def_file);
}
#endif
@@ -257,6 +257,9 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int
in_for_header)
break;
case Op_store_var:
+ if (pc->initval != NULL)
+ pp_push(Op_push_i, pp_node(pc->initval),
CAN_FREE);
+ /* fall through */
case Op_store_sub:
case Op_assign_concat:
case Op_push_lhs:
@@ -267,7 +270,7 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int
in_for_header)
m = pc->memory;
switch (m->type) {
case Node_param_list:
- pp_push(pc->opcode, fparms[m->param_cnt],
DONT_FREE);
+ pp_push(pc->opcode,
func_params[m->param_cnt].param, DONT_FREE);
break;
case Node_var:
@@ -508,9 +511,13 @@ cleanup:
break;
case Op_builtin:
+ case Op_ext_builtin:
{
- static char *ext_func = "extension_function()";
- const char *fname = getfname(pc->builtin);
+ const char *fname;
+ if (pc->opcode == Op_builtin)
+ fname = getfname(pc->builtin);
+ else
+ fname = (pc + 1)->func_name;
if (fname != NULL) {
if (pc->expr_count > 0) {
tmp = pp_list(pc->expr_count, "()", ",
");
@@ -520,10 +527,10 @@ cleanup:
str = pp_concat(fname, "()", "");
pp_push(Op_builtin, str, CAN_FREE);
} else
- pp_push(Op_builtin, ext_func, DONT_FREE);
+ fatal(_("internal error: builtin with null
fname"));
}
break;
-
+
case Op_K_print:
case Op_K_printf:
case Op_K_print_rec:
@@ -742,14 +749,15 @@ cleanup:
case Op_K_arrayfor:
{
- char *array, *item;
+ char *array;
+ const char *item;
ip = pc + 1;
t1 = pp_pop();
array = t1->pp_str;
m = ip->forloop_cond->array_var;
if (m->type == Node_param_list)
- item = fparms[m->param_cnt];
+ item = func_params[m->param_cnt].param;
else
item = m->vname;
indent(ip->forloop_body->exec_count);
@@ -1307,9 +1315,8 @@ int
pp_func(INSTRUCTION *pc, void *data ATTRIBUTE_UNUSED)
{
int j;
- char **pnames;
- NODE *f;
static int first = TRUE;
+ NODE *func;
int pcount;
if (first) {
@@ -1317,15 +1324,14 @@ pp_func(INSTRUCTION *pc, void *data ATTRIBUTE_UNUSED)
fprintf(prof_fp, _("\n\t# Functions, listed alphabetically\n"));
}
- f = pc->func_body;
+ func = pc->func_body;
fprintf(prof_fp, "\n");
indent(pc->nexti->exec_count);
- fprintf(prof_fp, "%s %s(", op2str(Op_K_function), f->lnode->param);
- pnames = f->parmlist;
- fparms = pnames;
- pcount = f->lnode->param_cnt;
+ fprintf(prof_fp, "%s %s(", op2str(Op_K_function), func->vname);
+ pcount = func->param_cnt;
+ func_params = func->fparms;
for (j = 0; j < pcount; j++) {
- fprintf(prof_fp, "%s", pnames[j]);
+ fprintf(prof_fp, "%s", func_params[j].param);
if (j < pcount - 1)
fprintf(prof_fp, ", ");
}
diff --git a/test/Makefile.am b/test/Makefile.am
index 2d7bf34..256d8ae 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -214,6 +214,7 @@ EXTRA_DIST = \
fnarray.awk \
fnarray.ok \
fnarray2.awk \
+ fnarray2.in \
fnarray2.ok \
fnarydel.awk \
fnarydel.ok \
diff --git a/test/Makefile.in b/test/Makefile.in
index 04ea041..0017424 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -399,6 +399,7 @@ EXTRA_DIST = \
fnarray.awk \
fnarray.ok \
fnarray2.awk \
+ fnarray2.in \
fnarray2.ok \
fnarydel.awk \
fnarydel.ok \
@@ -1969,7 +1970,7 @@ fnarray:
fnarray2:
@echo fnarray2
- @AWKPATH=$(srcdir) $(AWK) -f address@hidden >_$@ 2>&1 || echo EXIT
CODE: $$? >>_$@
+ @AWKPATH=$(srcdir) $(AWK) -f address@hidden < $(srcdir)/address@hidden
>_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
fnaryscl:
diff --git a/test/Maketests b/test/Maketests
index 9a16eb7..8c363e2 100644
--- a/test/Maketests
+++ b/test/Maketests
@@ -242,7 +242,7 @@ fnarray:
fnarray2:
@echo fnarray2
- @AWKPATH=$(srcdir) $(AWK) -f address@hidden >_$@ 2>&1 || echo EXIT
CODE: $$? >>_$@
+ @AWKPATH=$(srcdir) $(AWK) -f address@hidden < $(srcdir)/address@hidden
>_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
fnaryscl:
diff --git a/test/delfunc.ok b/test/delfunc.ok
index d12f0bc..29a7450 100644
--- a/test/delfunc.ok
+++ b/test/delfunc.ok
@@ -1,2 +1,3 @@
-gawk: delfunc.awk:4: fatal: attempt to use function `f' as an array
-EXIT CODE: 2
+gawk: delfunc.awk:4: error: function `f' called with space between name and
`(',
+or used as a variable or an array
+EXIT CODE: 1
diff --git a/test/fnamedat.ok b/test/fnamedat.ok
index d32acff..d7b71c4 100644
--- a/test/fnamedat.ok
+++ b/test/fnamedat.ok
@@ -1,2 +1,3 @@
-gawk: fnamedat.awk:1: (FILENAME=- FNR=1) fatal: can't use function name `foo'
as variable or array
-EXIT CODE: 2
+gawk: fnamedat.awk:1: error: function `foo' called with space between name and
`(',
+or used as a variable or an array
+EXIT CODE: 1
diff --git a/test/fnarray.ok b/test/fnarray.ok
index 04260b0..6cab913 100644
--- a/test/fnarray.ok
+++ b/test/fnarray.ok
@@ -1,5 +1,3 @@
-gawk: fnarray.awk:5: Num = foo[c]
-gawk: fnarray.awk:5: ^ use of non-array as array
gawk: fnarray.awk:5: error: function `foo' called with space between name and
`(',
or used as a variable or an array
EXIT CODE: 1
diff --git a/test/fnarray2.ok b/test/fnarray2.ok
index 243e4cc..8281505 100644
--- a/test/fnarray2.ok
+++ b/test/fnarray2.ok
@@ -1,3 +1,3 @@
-gawk: fnarray2.awk:3: r = ++pile[c]
-gawk: fnarray2.awk:3: ^ use of non-array as array
+gawk: fnarray2.awk:3: error: function `pile' called with space between name
and `(',
+or used as a variable or an array
EXIT CODE: 1
diff --git a/test/fnarydel.ok b/test/fnarydel.ok
index 7f3e453..7078c01 100644
--- a/test/fnarydel.ok
+++ b/test/fnarydel.ok
@@ -1,24 +1,24 @@
first loop
+1
+2
+3
4
5
6
7
8
9
+second loop
+third loop
1
2
3
-second loop
-third loop
4
5
6
7
8
9
-1
-2
-3
call func
fourth loop
You should just see: 4 4
diff --git a/test/fnasgnm.ok b/test/fnasgnm.ok
index 0db5c6d..5cacff2 100644
--- a/test/fnasgnm.ok
+++ b/test/fnasgnm.ok
@@ -1,2 +1,3 @@
-gawk: fnasgnm.awk:14: (FILENAME=- FNR=1) fatal: can't use function name
`ShowMe' as variable or array
-EXIT CODE: 2
+gawk: fnasgnm.awk:14: error: function `ShowMe' called with space between name
and `(',
+or used as a variable or an array
+EXIT CODE: 1
diff --git a/test/fnparydl.ok b/test/fnparydl.ok
index 26a5c39..9f79822 100644
--- a/test/fnparydl.ok
+++ b/test/fnparydl.ok
@@ -1,10 +1,10 @@
BEFORE LOOP
+DELETING KEY 1
+DELETING KEY 2
+DELETING KEY 3
DELETING KEY 4
DELETING KEY 5
DELETING KEY 6
DELETING KEY 7
-DELETING KEY 1
-DELETING KEY 2
-DELETING KEY 3
AFTER LOOP
0 elements still in q[]
diff --git a/test/funsmnam.ok b/test/funsmnam.ok
index e4f2174..cce0d27 100644
--- a/test/funsmnam.ok
+++ b/test/funsmnam.ok
@@ -1,2 +1,2 @@
-gawk: funsmnam.awk:1: error: function `foo': can't use function name as
parameter name
+gawk: funsmnam.awk:2: error: function `foo': can't use function name as
parameter name
EXIT CODE: 1
diff --git a/test/gsubasgn.ok b/test/gsubasgn.ok
index 8817c36..8a309c7 100644
--- a/test/gsubasgn.ok
+++ b/test/gsubasgn.ok
@@ -1,5 +1,5 @@
-gawk: gsubasgn.awk:4: function test1 (r) { gsub(r, "x", test1) }
-gawk: gsubasgn.awk:4: ^ gsub third
parameter is not a changeable object
-gawk: gsubasgn.awk:8: function test2 () { gsub(/a/, "x", test2) }
-gawk: gsubasgn.awk:8: ^ gsub third
parameter is not a changeable object
+gawk: gsubasgn.awk:4: error: function `test1' called with space between name
and `(',
+or used as a variable or an array
+gawk: gsubasgn.awk:8: error: function `test2' called with space between name
and `(',
+or used as a variable or an array
EXIT CODE: 1
diff --git a/test/match2.ok b/test/match2.ok
index a4a91e8..ad2e324 100644
--- a/test/match2.ok
+++ b/test/match2.ok
@@ -1,2 +1,3 @@
-gawk: match2.awk:3: fatal: match: third argument is not an array
-EXIT CODE: 2
+gawk: match2.awk:3: error: function `f' called with space between name and `(',
+or used as a variable or an array
+EXIT CODE: 1
-----------------------------------------------------------------------
hooks/post-receive
--
gawk
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gawk-diffs] [SCM] gawk branch, gawk_performance, created. dae23ec25804903a6c2b7094a2ebd5541e92bb88,
John Haque <=