gawk-diffs
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]