summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2015-01-08 09:41:19 -0500
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2015-01-08 09:41:19 -0500
commitf8fecb69346cbcd774a73a49322aeb8ddea73e44 (patch)
treed364c944782ef4092e3599f49b20e5738660b324
parent41483acb1969b24e336b11aaf3bfdc1dbdfe33a8 (diff)
downloadgawk-f8fecb69346cbcd774a73a49322aeb8ddea73e44.tar.gz
When an extension calls sym_lookup on a deferred variable, it should always succeed.
-rw-r--r--ChangeLog9
-rw-r--r--awk.h1
-rw-r--r--awkgram.c9
-rw-r--r--awkgram.y9
-rw-r--r--extension/ChangeLog6
-rw-r--r--extension/testext.c18
-rw-r--r--gawkapi.c14
-rw-r--r--test/ChangeLog4
-rw-r--r--test/testext.ok2
9 files changed, 59 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 0498088d..931972d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2015-01-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+ * awk.h (deferred_create): Declare new function.
+ * awkgram.y (deferred_create): New function.
+ * gawkapi.c (lookup_deferred): New helper function to call lookup and
+ then deferred_create if lookup fails.
+ (api_sym_lookup, api_sym_update): Call lookup_deferred instead of
+ lookup.
+
+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.
diff --git a/awk.h b/awk.h
index bb63f65a..eddcb18f 100644
--- a/awk.h
+++ b/awk.h
@@ -1318,6 +1318,7 @@ 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 *deferred_create(const char *name);
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 adb31d9c..bc79df58 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -7052,6 +7052,15 @@ is_deferred_variable(const char *name)
return false;
}
+NODE *
+deferred_create(const char *name)
+{
+ struct deferred_variable *dv;
+ for (dv = deferred_variables; dv != NULL; dv = dv->next)
+ if (strcmp(name, dv->name) == 0)
+ return (*dv->load_func)();
+ return NULL;
+}
/* variable --- make sure NAME is in the symbol table */
diff --git a/awkgram.y b/awkgram.y
index 52284af4..1399262d 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -4714,6 +4714,15 @@ is_deferred_variable(const char *name)
return false;
}
+NODE *
+deferred_create(const char *name)
+{
+ struct deferred_variable *dv;
+ for (dv = deferred_variables; dv != NULL; dv = dv->next)
+ if (strcmp(name, dv->name) == 0)
+ return (*dv->load_func)();
+ return NULL;
+}
/* variable --- make sure NAME is in the symbol table */
diff --git a/extension/ChangeLog b/extension/ChangeLog
index c8f77042..15153213 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,9 @@
+2015-01-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * testext.c (var_test): Lookup of PROCINFO should always succeed.
+ (test_deferred): PROCINFO should always be present, so call lookup
+ to grab it.
+
2015-01-06 Andrew J. Schorr <aschorr@telemetry-investments.com>
* testext.c (test_deferred): New function to help with testing
diff --git a/extension/testext.c b/extension/testext.c
index 7c61bb0d..42ec0915 100644
--- a/extension/testext.c
+++ b/extension/testext.c
@@ -303,11 +303,11 @@ var_test(int nargs, awk_value_t *result)
goto out;
}
- /* look up PROCINFO - should fail */
+ /* look up PROCINFO - should succeed */
if (sym_lookup("PROCINFO", AWK_ARRAY, & value))
- printf("var_test: sym_lookup of PROCINFO failed - got a value!\n");
+ printf("var_test: sym_lookup of PROCINFO passed - got a value!\n");
else
- printf("var_test: sym_lookup of PROCINFO passed - did not get a value\n");
+ printf("var_test: sym_lookup of PROCINFO failed - did not get a value\n");
/* look up a reserved variable - should pass */
if (sym_lookup("ARGC", AWK_NUMBER, & value))
@@ -399,8 +399,11 @@ test_deferred(int nargs, awk_value_t *result)
printf("test_deferred: nargs not right (%d should be 0)\n", nargs);
goto out;
}
- arr.val_type = AWK_ARRAY;
- arr.array_cookie = create_array();
+
+ if (! sym_lookup("PROCINFO", AWK_ARRAY, & arr)) {
+ printf("test_deferred: %d: sym_lookup failed\n", __LINE__);
+ goto out;
+ }
for (i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) {
make_const_string(seed[i].name, strlen(seed[i].name), & index);
@@ -411,11 +414,6 @@ test_deferred(int nargs, awk_value_t *result)
}
}
- if (! sym_update("PROCINFO", & arr)) {
- printf("test_deferred: %d: sym_update failed\n", __LINE__);
- goto out;
- }
-
/* test that it still contains the values we loaded */
for (i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) {
make_const_string(seed[i].name, strlen(seed[i].name), & index);
diff --git a/gawkapi.c b/gawkapi.c
index f8d04986..0213936a 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -486,6 +486,16 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted)
return ret;
}
+static NODE *
+lookup_deferred(const char *name)
+{
+ NODE *node;
+
+ if ((node = lookup(name)) != NULL)
+ return node;
+ return deferred_create(name);
+}
+
/*
* Symbol table access:
* - No access to special variables (NF, etc.)
@@ -516,7 +526,7 @@ api_sym_lookup(awk_ext_id_t id,
if ( name == NULL
|| *name == '\0'
|| result == NULL
- || (node = lookup(name)) == NULL)
+ || (node = lookup_deferred(name)) == NULL)
return awk_false;
if (is_off_limits_var(name)) /* a built-in variable */
@@ -574,7 +584,7 @@ api_sym_update(awk_ext_id_t id,
return awk_false;
}
- node = lookup(name);
+ node = lookup_deferred(name);
if (node == NULL) {
/* new value to be installed */
diff --git a/test/ChangeLog b/test/ChangeLog
index 7522f7aa..06b4c8bc 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,7 @@
+2015-01-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * testext.ok: PROCINFO lookup should succeed.
+
2015-01-06 Andrew J. Schorr <aschorr@telemetry-investments.com>
* Makefile.am (EXTRA_DIST): Add defvar.awk and defvar.ok.
diff --git a/test/testext.ok b/test/testext.ok
index 5a78c159..9dae010f 100644
--- a/test/testext.ok
+++ b/test/testext.ok
@@ -15,7 +15,7 @@ try_modify_environ: set_array_element of ENVIRON failed
try_modify_environ: marking element "testext" for deletion
try_del_environ() could not delete element - pass
try_del_environ() could not add an element - pass
-var_test: sym_lookup of PROCINFO passed - did not get a value
+var_test: sym_lookup of PROCINFO passed - got a value!
var_test: sym_lookup of ARGC passed - got a value!
var_test: sym_update of ARGC failed - correctly
var_test: sym_update("testvar") succeeded