summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2015-01-08 09:20:09 -0500
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2015-01-08 09:20:09 -0500
commit41483acb1969b24e336b11aaf3bfdc1dbdfe33a8 (patch)
tree4d79588f62502c52ff47a510a0cf0f409eb77b00
parent55aefdc29dde7eb585b7a553876313ecceec1d68 (diff)
downloadgawk-41483acb1969b24e336b11aaf3bfdc1dbdfe33a8.tar.gz
Revert changes to API deferred variable creation, since this should be done at lookup time.
-rw-r--r--ChangeLog10
-rw-r--r--awk.h1
-rw-r--r--awkgram.c39
-rw-r--r--awkgram.y39
-rw-r--r--gawkapi.c45
5 files changed, 50 insertions, 84 deletions
diff --git a/ChangeLog b/ChangeLog
index 6e549065..0498088d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2015-01-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ Revert changes to API deferred variable creation -- these variables
+ should be created when lookup is called, not when update is called.
+ * awk.h (variable_create): Remove function declaration.
+ * awkgram.y (variable_create): Remove function.
+ (variable): Restore variable_create functionality inline.
+ * gawkapi.c (api_sym_update): Revert to using install_symbol, since the
+ deferred variable check should be done when lookup is called, not here.
+
2015-01-07 Andrew J. Schorr <aschorr@telemetry-investments.com>
* gawkapi.c (api_set_array_element): Remove stray call to
diff --git a/awk.h b/awk.h
index f624a876..bb63f65a 100644
--- a/awk.h
+++ b/awk.h
@@ -1318,7 +1318,6 @@ extern NODE *do_asorti(int nargs);
extern unsigned long (*hash)(const char *s, size_t len, unsigned long hsize, size_t *code);
extern void init_env_array(NODE *env_node);
/* awkgram.c */
-extern NODE *variable_create(char *name, NODETYPE type, bool *is_deferred);
extern NODE *variable(int location, char *name, NODETYPE type);
extern int parse_program(INSTRUCTION **pcode);
extern void track_ext_func(const char *name);
diff --git a/awkgram.c b/awkgram.c
index 249fdcdf..adb31d9c 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -7052,22 +7052,6 @@ is_deferred_variable(const char *name)
return false;
}
-/* variable_create --- create a new variable */
-NODE *
-variable_create(char *name, NODETYPE type, bool *is_deferred)
-{
- struct deferred_variable *dv;
-
- for (dv = deferred_variables; dv != NULL; dv = dv->next) {
- if (strcmp(name, dv->name) == 0) {
- efree(name);
- *is_deferred = true;
- return (*dv->load_func)();
- }
- }
- *is_deferred = false;
- return install_symbol(name, type);
-}
/* variable --- make sure NAME is in the symbol table */
@@ -7075,7 +7059,6 @@ NODE *
variable(int location, char *name, NODETYPE type)
{
NODE *r;
- bool is_deferred;
if ((r = lookup(name)) != NULL) {
if (r->type == Node_func || r->type == Node_ext_func )
@@ -7083,11 +7066,25 @@ variable(int location, char *name, NODETYPE type)
r->vname);
if (r == symbol_table)
symtab_used = true;
- efree(name);
- return r;
+ } else {
+ /* not found */
+ struct deferred_variable *dv;
+
+ for (dv = deferred_variables; true; dv = dv->next) {
+ if (dv == NULL) {
+ /*
+ * This is the only case in which we may not free the string.
+ */
+ return install_symbol(name, type);
+ }
+ if (strcmp(name, dv->name) == 0) {
+ r = (*dv->load_func)();
+ break;
+ }
+ }
}
- /* not found */
- return variable_create(name, type, & is_deferred);
+ efree(name);
+ return r;
}
/* process_deferred --- if the program uses SYMTAB, load deferred variables */
diff --git a/awkgram.y b/awkgram.y
index 461bd6b0..52284af4 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -4714,22 +4714,6 @@ is_deferred_variable(const char *name)
return false;
}
-/* variable_create --- create a new variable */
-NODE *
-variable_create(char *name, NODETYPE type, bool *is_deferred)
-{
- struct deferred_variable *dv;
-
- for (dv = deferred_variables; dv != NULL; dv = dv->next) {
- if (strcmp(name, dv->name) == 0) {
- efree(name);
- *is_deferred = true;
- return (*dv->load_func)();
- }
- }
- *is_deferred = false;
- return install_symbol(name, type);
-}
/* variable --- make sure NAME is in the symbol table */
@@ -4737,7 +4721,6 @@ NODE *
variable(int location, char *name, NODETYPE type)
{
NODE *r;
- bool is_deferred;
if ((r = lookup(name)) != NULL) {
if (r->type == Node_func || r->type == Node_ext_func )
@@ -4745,11 +4728,25 @@ variable(int location, char *name, NODETYPE type)
r->vname);
if (r == symbol_table)
symtab_used = true;
- efree(name);
- return r;
+ } else {
+ /* not found */
+ struct deferred_variable *dv;
+
+ for (dv = deferred_variables; true; dv = dv->next) {
+ if (dv == NULL) {
+ /*
+ * This is the only case in which we may not free the string.
+ */
+ return install_symbol(name, type);
+ }
+ if (strcmp(name, dv->name) == 0) {
+ r = (*dv->load_func)();
+ break;
+ }
+ }
}
- /* not found */
- return variable_create(name, type, & is_deferred);
+ efree(name);
+ return r;
}
/* process_deferred --- if the program uses SYMTAB, load deferred variables */
diff --git a/gawkapi.c b/gawkapi.c
index 749be178..f8d04986 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -579,48 +579,11 @@ api_sym_update(awk_ext_id_t id,
if (node == NULL) {
/* new value to be installed */
if (value->val_type == AWK_ARRAY) {
- bool is_deferred;
-
array_node = awk_value_to_node(value);
- /*
- * use variable_create instead of install_symbol in
- * case this is a deferred variable such as PROCINFO
- * or ENVIRON
- */
- node = variable_create(estrdup((char *) name, strlen(name)), Node_var_array, & is_deferred);
- if (is_deferred) {
- /*
- * merge the user-supplied elements into the
- * already-existing array. Since ENVIRON
- * has special array_funcs, we need to retain
- * the auto-created array!
- */
- unsigned long nel;
- NODE **list;
- NODE akind;
- unsigned long i;
-
- nel = assoc_length(array_node);
- akind.flags = (AINDEX|AVALUE);
- list = array_node->alist(array_node, & akind);
- for (i = 0; i < nel; i++) {
- NODE **aptr;
- NODE *elem;
- aptr = assoc_lookup(node, list[2*i]);
- unref(*aptr);
- elem = *aptr = dupnode(list[2*i+1]);
- if (elem->type == Node_var_array)
- elem->parent_array = node;
- if (node->astore != NULL)
- (*node->astore)(node, list[2*i]);
- unref(list[2*i]); /* alist duped it */
- }
- efree(list);
- assoc_clear(array_node);
- } else {
- array_node->vname = node->vname;
- *node = *array_node;
- }
+ node = install_symbol(estrdup((char *) name, strlen(name)),
+ Node_var_array);
+ array_node->vname = node->vname;
+ *node = *array_node;
freenode(array_node);
value->array_cookie = node; /* pass new cookie back to extension */
} else {