[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gawk-diffs] [SCM] gawk branch, master, updated. fc9109734ddcf57c5f1faae
From: |
Arnold Robbins |
Subject: |
[gawk-diffs] [SCM] gawk branch, master, updated. fc9109734ddcf57c5f1faaedfadc432ec6841aa8 |
Date: |
Thu, 13 Sep 2012 21:17:22 +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, master has been updated
via fc9109734ddcf57c5f1faaedfadc432ec6841aa8 (commit)
from 99290f5ca37cb905f7f1dab9be416b2e2057d243 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=fc9109734ddcf57c5f1faaedfadc432ec6841aa8
commit fc9109734ddcf57c5f1faaedfadc432ec6841aa8
Author: Arnold D. Robbins <address@hidden>
Date: Fri Sep 14 00:16:48 2012 +0300
Allow extensions read-only access to built-in vars.
diff --git a/ChangeLog b/ChangeLog
index 2598c30..d729027 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2012-09-14 Arnold D. Robbins <address@hidden>
+
+ Allow read-only access to built-in variables from extensions.
+
+ * awk.h (NO_EXT_SET): New flag.
+ * gawkapi.c (api_sym_lookup, api_sym_update_real): Set flag if off
+ limits variable instead of failing. Adjust logic.
+ (api_sym_update_scalar, api_set_array_element, api_del_array_element,
+ api_release_flattened_array): Adjust logic.
+ * gawkapi.h: Adjust documentation.
+
2012-09-13 Arnold D. Robbins <address@hidden>
* configure.ac: Determination of DYNAMIC adjusted. Hopefully is
diff --git a/awk.h b/awk.h
index de42529..b0208e5 100644
--- a/awk.h
+++ b/awk.h
@@ -447,6 +447,7 @@ typedef struct exp_node {
# define WSTRCUR 0x0400 /* wide str value is current */
# define MPFN 0x0800 /* arbitrary-precision
floating-point number */
# define MPZN 0x1000 /* arbitrary-precision integer */
+# define NO_EXT_SET 0x2000 /* extension cannot set a value
for this variable */
/* type = Node_var_array */
# define ARRAYMAXED 0x2000 /* array is at max size */
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 1a32961..2552a38 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,9 @@
+2012-09-14 Arnold D. Robbins <address@hidden>
+
+ * testext.c (try_modify_environ): New function and test.
+ (var_test): Modified ARGC test, added additional.
+ (test_scalar_reserved): New function and test.
+
2012-09-13 Dave Pitts <address@hidden>
* gawkfts.c: Add defines and ifdefs for z/OS.
diff --git a/extension/testext.c b/extension/testext.c
index bb62fa0..c11a4c8 100644
--- a/extension/testext.c
+++ b/extension/testext.c
@@ -186,6 +186,101 @@ out:
/*
BEGIN {
+ ENVIRON["testext"]++
+ try_modify_environ()
+ if ("testext" in ENVIRON)
+ print "try_del_environ() could not delete element - pass"
+ else
+ print "try_del_environ() deleted element! - fail"
+ if ("testext2" in ENVIRON)
+ print "try_del_environ() added an element - fail"
+ else
+ print "try_del_environ() could not add an element - pass"
+}
+*/
+
+static awk_value_t *
+try_modify_environ(int nargs, awk_value_t *result)
+{
+ awk_value_t value, index, newvalue;
+ awk_flat_array_t *flat_array;
+ size_t count;
+ int i;
+
+ assert(result != NULL);
+ make_number(0.0, result);
+
+ if (nargs != 0) {
+ printf("try_modify_environ: nargs not right (%d should be
0)\n", nargs);
+ goto out;
+ }
+
+ /* get ENVIRON array */
+ if (sym_lookup("ENVIRON", AWK_ARRAY, & value))
+ printf("try_modify_environ: sym_lookup of ENVIRON passed\n");
+ else {
+ printf("try_modify_environ: sym_lookup of ENVIRON failed\n");
+ goto out;
+ }
+
+ if (! get_element_count(value.array_cookie, & count)) {
+ printf("try_modify_environ: get_element_count failed\n");
+ goto out;
+ }
+
+ printf("try_modify_environ: incoming size is %lu\n", (unsigned long)
count);
+
+ /* setting an array element should fail */
+ (void) make_const_string("testext2", 8, & index);
+ (void) make_const_string("a value", 7, & value);
+ if (set_array_element(value.array_cookie, & index, & newvalue)) {
+ printf("try_modify_environ: set_array_element of ENVIRON
passed\n");
+ } else {
+ printf("try_modify_environ: set_array_element of ENVIRON
failed\n");
+ free(index.str_value.str);
+ free(value.str_value.str);
+ }
+
+ if (! flatten_array(value.array_cookie, & flat_array)) {
+ printf("try_modify_environ: could not flatten array\n");
+ goto out;
+ }
+
+ if (flat_array->count != count) {
+ printf("try_modify_environ: flat_array->count (%lu) != count
(%lu)\n",
+ (unsigned long) flat_array->count,
+ (unsigned long) count);
+ goto out;
+ }
+
+ for (i = 0; i < flat_array->count; i++) {
+ /* don't print */
+ /*
+ printf("\t%s[\"%.*s\"] = %s\n",
+ name,
+ (int) flat_array->elements[i].index.str_value.len,
+ flat_array->elements[i].index.str_value.str,
+ valrep2str(& flat_array->elements[i].value));
+ */
+ if (strcmp("testext",
flat_array->elements[i].index.str_value.str) == 0) {
+ flat_array->elements[i].flags |= AWK_ELEMENT_DELETE;
+ printf("try_modify_environ: marking element \"%s\" for
deletion\n",
+ flat_array->elements[i].index.str_value.str);
+ }
+ }
+
+ if (! release_flattened_array(value.array_cookie, flat_array)) {
+ printf("try_modify_environ: could not release flattened
array\n");
+ goto out;
+ }
+
+ make_number(1.0, result);
+out:
+ return result;
+}
+
+/*
+BEGIN {
testvar = "One Adam Twelve"
ret = var_test("testvar")
printf "var_test() returned %d, test_var = %s\n", ret, testvar
@@ -207,11 +302,18 @@ var_test(int nargs, awk_value_t *result)
goto out;
}
- /* look up a reserved variable - should fail */
+ /* look up a reserved variable - should pass */
if (sym_lookup("ARGC", AWK_NUMBER, & value))
- printf("var_test: sym_lookup of ARGC failed - got a value!\n");
+ printf("var_test: sym_lookup of ARGC passed - got a value!\n");
+ else
+ printf("var_test: sym_lookup of ARGC failed - did not get a
value\n");
+
+ /* now try to set it - should fail */
+ value.num_value++;
+ if (sym_update("ARGC", & value))
+ printf("var_test: sym_update of ARGC passed and should not
have!\n");
else
- printf("var_test: sym_lookup of ARGC passed - did not get a
value\n");
+ printf("var_test: sym_update of ARGC failed - correctly\n");
/* look up variable whose name is passed in, should pass */
if (get_argument(0, AWK_STRING, & value)) {
@@ -535,6 +637,47 @@ test_scalar(int nargs, awk_value_t *result)
}
if (! sym_update_scalar(the_scalar.scalar_cookie, & new_value2)) {
+ printf("test_scalar: could not update new_value2!\n");
+ goto out;
+ }
+
+ make_number(1.0, result);
+
+out:
+ return result;
+}
+
+/*
+BEGIN {
+ test_scalar_reserved()
+}
+*/
+
+/* test_scalar_reserved --- test scalar cookie on special variable */
+
+static awk_value_t *
+test_scalar_reserved(int nargs, awk_value_t *result)
+{
+ awk_value_t new_value;
+ awk_value_t the_scalar;
+
+ make_number(0.0, result);
+
+ /* look up a reserved variable - should pass */
+ if (sym_lookup("ARGC", AWK_SCALAR, & the_scalar)) {
+ printf("test_scalar_reserved: sym_lookup of ARGC passed - got a
value!\n");
+ } else {
+ printf("test_scalar_reserved: sym_lookup of ARGC failed - did
not get a value\n");
+ goto out;
+ }
+
+ /* updating it should fail */
+ make_number(42.0, & new_value);
+ if (! sym_update_scalar(the_scalar.scalar_cookie, & new_value)) {
+ printf("test_scalar_reserved: could not update new_value2 for
ARGC - pass\n");
+ } else {
+ printf("test_scalar_reserved: was able to update new_value2 for
ARGC - fail\n");
+ goto out;
}
make_number(1.0, result);
@@ -628,6 +771,7 @@ static void at_exit2(void *data, int exit_status)
static awk_ext_func_t func_table[] = {
{ "dump_array_and_delete", dump_array_and_delete, 2 },
+ { "try_modify_environ", try_modify_environ, 0 },
{ "var_test", var_test, 1 },
{ "test_errno", test_errno, 0 },
{ "test_array_size", test_array_size, 1 },
@@ -635,6 +779,7 @@ static awk_ext_func_t func_table[] = {
{ "test_array_param", test_array_param, 1 },
{ "print_do_lint", print_do_lint, 0 },
{ "test_scalar", test_scalar, 1 },
+ { "test_scalar_reserved", test_scalar_reserved, 0 },
};
/* init_testext --- additional initialization function */
diff --git a/gawkapi.c b/gawkapi.c
index 5d372bb..dbb8549 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -489,10 +489,12 @@ api_sym_lookup(awk_ext_id_t id,
if ( name == NULL
|| *name == '\0'
|| result == NULL
- || is_off_limits_var(name) /* most built-in vars not allowed */
|| (node = lookup(name)) == NULL)
return false;
+ if (is_off_limits_var(name)) /* a built-in variable */
+ node->flags |= NO_EXT_SET;
+
return node_to_awk_value(node, result, wanted);
}
@@ -527,7 +529,6 @@ sym_update_real(awk_ext_id_t id,
if ( name == NULL
|| *name == '\0'
- || is_off_limits_var(name) /* most built-in vars not allowed */
|| value == NULL)
return false;
@@ -573,6 +574,12 @@ sym_update_real(awk_ext_id_t id,
* If we get here, then it exists already. Any valid type is
* OK except for AWK_ARRAY.
*/
+ if ( (node->flags & NO_EXT_SET) != 0
+ || is_off_limits_var(name)) { /* most built-in vars not
allowed */
+ node->flags |= NO_EXT_SET;
+ return false;
+ }
+
if ( value->val_type != AWK_ARRAY
&& (node->type == Node_var || node->type == Node_var_new)) {
unref(node->var_value);
@@ -618,7 +625,8 @@ api_sym_update_scalar(awk_ext_id_t id,
if (value == NULL
|| node == NULL
- || node->type != Node_var)
+ || node->type != Node_var
+ || (node->flags & NO_EXT_SET) != 0)
return false;
/*
@@ -766,6 +774,7 @@ api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie,
/* don't check for index len zero, null str is ok as index */
if ( array == NULL
|| array->type != Node_var_array
+ || (array->flags & NO_EXT_SET) != 0
|| index == NULL
|| value == NULL
|| ! valid_subscript_type(index->val_type))
@@ -825,6 +834,7 @@ api_del_array_element(awk_ext_id_t id,
array = (NODE *) a_cookie;
if ( array == NULL
|| array->type != Node_var_array
+ || (array->flags & NO_EXT_SET) != 0
|| index == NULL
|| ! valid_subscript_type(index->val_type))
return false;
@@ -957,7 +967,8 @@ api_release_flattened_array(awk_ext_id_t id,
/* free index nodes */
for (i = j = 0, k = 2 * array->table_size; i < k; i += 2, j++) {
/* Delete items flagged for delete. */
- if ((data->elements[j].flags & AWK_ELEMENT_DELETE) != 0) {
+ if ( (data->elements[j].flags & AWK_ELEMENT_DELETE) != 0
+ && (array->flags & NO_EXT_SET) == 0) {
remove_element(array, list[i]);
}
unref(list[i]);
diff --git a/gawkapi.h b/gawkapi.h
index 95effd9..e8b7ebf 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -447,8 +447,8 @@ typedef struct gawk_api {
* or if the wrong type was requested.
* In the latter case, fills in vaule->val_type with the real type,
* as described above.
- * Built-in variables (except PROCINFO) may not be accessed by an
- * extension.
+ * Built-in variables may be accessed by an extension, but, with
+ * the exception of PROCINFO, they may not be modified.
*
* awk_value_t val;
* if (! api->sym_lookup(id, name, wanted, & val))
@@ -495,13 +495,15 @@ typedef struct gawk_api {
* Flow is
* sym_lookup with wanted == AWK_SCALAR
* if returns false
- * sym_update with real initial value
+ * sym_update with real initial value to install it
* sym_lookup again with AWK_SCALAR
* else
* use the scalar cookie
*
* Return will be false if the new value is not one of
* AWK_STRING or AWK_NUMBER.
+ *
+ * Here too, the built-in variables may not be updated.
*/
awk_bool_t (*api_sym_update_scalar)(awk_ext_id_t id,
awk_scalar_t cookie, awk_value_t *value);
@@ -522,6 +524,8 @@ typedef struct gawk_api {
/*
* Change (or create) element in existing array with
* element->index and element->value.
+ *
+ * ARGV and ENVIRON may not be updated.
*/
awk_bool_t (*api_set_array_element)(awk_ext_id_t id, awk_array_t
a_cookie,
const awk_value_t *const index,
diff --git a/test/ChangeLog b/test/ChangeLog
index ff99236..4bab479 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,7 @@
+2012-09-14 Arnold D. Robbins <address@hidden>
+
+ * testext.ok: Updated.
+
2012-09-11 Arnold D. Robbins <address@hidden>
* Makefile.am (shlib-tests): Check if DYNAMIC is enabled and
diff --git a/test/testext.ok b/test/testext.ok
index 132179c..d291f72 100644
--- a/test/testext.ok
+++ b/test/testext.ok
@@ -10,7 +10,14 @@ dump_array_and_delete: marking element "3" for deletion
dump_array_and_delete(pets) returned 1
dump_array_and_delete() did remove index "3"!
-var_test: sym_lookup of ARGC passed - did not get a value
+try_modify_environ: sym_lookup of ENVIRON passed
+try_modify_environ: incoming size is 60
+try_modify_environ: set_array_element of ENVIRON failed
+try_modify_environ: could not flatten array
+try_del_environ() could not delete element - pass
+try_del_environ() could not add an element - pass
+var_test: sym_lookup of ARGC passed - got a value!
+var_test: sym_update of ARGC failed - correctly
var_test: sym_update("testvar") succeeded
var_test() returned 1, test_var = 42
@@ -57,6 +64,8 @@ test_scalar(over) returned 1, the_scalar is over
test_scalar(the) returned 1, the_scalar is the
test_scalar(lazy) returned 1, the_scalar is lazy
test_scalar(dog) returned 1, the_scalar is dog
+test_scalar_reserved: sym_lookup of ARGC passed - got a value!
+test_scalar_reserved: could not update new_value2 for ARGC - pass
answer_num = 42
message_string = hello, world
new_array["hello"] = "world"
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 11 ++++
awk.h | 1 +
extension/ChangeLog | 6 ++
extension/testext.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++-
gawkapi.c | 19 +++++--
gawkapi.h | 10 +++-
test/ChangeLog | 4 ++
test/testext.ok | 11 ++++-
8 files changed, 202 insertions(+), 11 deletions(-)
hooks/post-receive
--
gawk
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gawk-diffs] [SCM] gawk branch, master, updated. fc9109734ddcf57c5f1faaedfadc432ec6841aa8,
Arnold Robbins <=