gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gawk-diffs] [SCM] gawk branch, select, updated. gawk-4.1.0-1068-gf38a8f


From: Andrew J. Schorr
Subject: [gawk-diffs] [SCM] gawk branch, select, updated. gawk-4.1.0-1068-gf38a8f8
Date: Wed, 07 Jan 2015 01:17:57 +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, select has been updated
       via  f38a8f801496ea91cef7a8507e2919f6586d0694 (commit)
      from  9121c3059288f36e004108e02ed4d826b84604e7 (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=f38a8f801496ea91cef7a8507e2919f6586d0694

commit f38a8f801496ea91cef7a8507e2919f6586d0694
Author: Andrew J. Schorr <address@hidden>
Date:   Tue Jan 6 20:17:35 2015 -0500

    Fix bug in API deferred variable creation and add a test case.

diff --git a/ChangeLog b/ChangeLog
index 098031a..71268d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2015-01-06         Andrew J. Schorr     <address@hidden>
 
+       * awk.h (variable_create): Now takes a 3rd argument to tell caller
+       whether this is a deferred variable.
+       * awkgram.y (variable_create): Return indicator of whether this is
+       a deferred variable in a newly added 3rd arg.
+       (variable): Pass 3rd arg to variable_create.
+       * gawkapi.c (api_sym_update): If we triggered the creation of a deferred
+       variable, we must merge the extension's array elements into the deffered
+       array, not the other way around.  The ENVIRON array has special funcs
+       to call setenv and unsetenv.
+
+2015-01-06         Andrew J. Schorr     <address@hidden>
+
        * awk.h (variable_create): Declare new function.
        * awkgram.y (variable_create): New function to create a variable
        taking the deferred variable list into consideration.
diff --git a/awk.h b/awk.h
index 5ecc13f..f624a87 100644
--- a/awk.h
+++ b/awk.h
@@ -1318,7 +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 *variable_create(char *name, NODETYPE type);
+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 2257ee3..249fdcd 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -7054,16 +7054,18 @@ is_deferred_variable(const char *name)
 
 /* variable_create --- create a new variable */
 NODE *
-variable_create(char *name, NODETYPE type)
+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);
 }
 
@@ -7073,6 +7075,7 @@ 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 )
@@ -7084,7 +7087,7 @@ variable(int location, char *name, NODETYPE type)
                return r;
        }
        /* not found */
-       return variable_create(name, type);
+       return variable_create(name, type, & is_deferred);
 }
 
 /* process_deferred --- if the program uses SYMTAB, load deferred variables */
diff --git a/awkgram.y b/awkgram.y
index 6575e0f..461bd6b 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -4716,16 +4716,18 @@ is_deferred_variable(const char *name)
 
 /* variable_create --- create a new variable */
 NODE *
-variable_create(char *name, NODETYPE type)
+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);
 }
 
@@ -4735,6 +4737,7 @@ 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 )
@@ -4746,7 +4749,7 @@ variable(int location, char *name, NODETYPE type)
                return r;
        }
        /* not found */
-       return variable_create(name, type);
+       return variable_create(name, type, & is_deferred);
 }
 
 /* process_deferred --- if the program uses SYMTAB, load deferred variables */
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 617cc03..c8f7704 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,10 @@
+2015-01-06         Andrew J. Schorr     <address@hidden>
+
+       * testext.c (test_deferred): New function to help with testing
+       of deferred variable instantiation.
+       (do_get_file): Remove unused variable array.
+       (func_table): Add test_deferred.
+
 2015-01-05         Andrew J. Schorr     <address@hidden>
 
        * testext.c (test_get_file): Fix error message.
diff --git a/extension/testext.c b/extension/testext.c
index c931ed3..7c61bb0 100644
--- a/extension/testext.c
+++ b/extension/testext.c
@@ -374,6 +374,75 @@ out:
        return result;
 }
 
+static awk_value_t *
+test_deferred(int nargs, awk_value_t *result)
+{
+       awk_value_t arr;
+       awk_value_t index, value;
+       const struct nval {
+               const char *name;
+               double val;
+       } seed[] = {
+               { "fubar", 9.0, },
+               { "rumpus", -5.0, },
+       };
+       struct nval sysval[] = {
+               { "uid", getuid(), },
+               { "api_major", GAWK_API_MAJOR_VERSION, },
+       };
+       size_t i;
+
+       assert(result != NULL);
+       make_number(0.0, result);
+
+       if (nargs != 0) {
+               printf("test_deferred: nargs not right (%d should be 0)\n", 
nargs);
+               goto out;
+       }
+       arr.val_type = AWK_ARRAY;
+       arr.array_cookie = create_array();
+
+       for (i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) {
+               make_const_string(seed[i].name, strlen(seed[i].name), & index);
+               make_number(seed[i].val, & value);
+               if (! set_array_element(arr.array_cookie, & index, & value)) {
+                       printf("test_deferred: %d: set_array_element(%s) 
failed\n", __LINE__, seed[i].name);
+                       goto out;
+               }
+       }
+
+       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);
+               make_null_string(& value);
+               if (! get_array_element(arr.array_cookie, &index, AWK_NUMBER, & 
value)) {
+                       printf("test_deferred: %d: get_array_element(%s) 
failed\n", __LINE__, seed[i].name);
+                       goto out;
+               }
+               printf("%s = %g\n", seed[i].name, value.num_value);
+       }
+
+       /* check a few automatically-supplied values */
+       for (i = 0; i < sizeof(sysval)/sizeof(sysval[0]); i++) {
+               make_const_string(sysval[i].name, strlen(sysval[i].name), & 
index);
+               make_null_string(& value);
+               if (! get_array_element(arr.array_cookie, &index, AWK_NUMBER, & 
value)) {
+                       printf("test_deferred: %d: get_array_element(%s) 
failed\n", __LINE__, sysval[i].name);
+                       goto out;
+               }
+               printf("%s matches %d\n", sysval[i].name, (value.num_value == 
sysval[i].val));
+       }
+
+       make_number(1.0, result);
+out:
+       return result;
+}
+
 /*
 BEGIN {
        for (i = 1; i <= 10; i++)
@@ -809,7 +878,6 @@ do_get_file(int nargs, awk_value_t *result)
        awk_value_t filename, filetype, fd, res;
        const awk_input_buf_t *ibuf;
        const awk_output_buf_t *obuf;
-       awk_array_t array;
 
        if (nargs != 4) {
                printf("%s: nargs not right (%d should be 4)\n", "get_file", 
nargs);
@@ -950,6 +1018,7 @@ 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_deferred", test_deferred, 0 },
        { "test_errno", test_errno, 0 },
        { "test_array_size", test_array_size, 1 },
        { "test_array_elem", test_array_elem, 2 },
diff --git a/gawkapi.c b/gawkapi.c
index 5630185..e887902 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -579,7 +579,7 @@ api_sym_update(awk_ext_id_t id,
        if (node == NULL) {
                /* new value to be installed */
                if (value->val_type == AWK_ARRAY) {
-                       unsigned long nel;
+                       bool is_deferred;
 
                        array_node = awk_value_to_node(value);
                        /*
@@ -587,27 +587,35 @@ api_sym_update(awk_ext_id_t id,
                         * case this is a deferred variable such as PROCINFO
                         * or ENVIRON
                         */
-                       node = variable_create(estrdup((char *) name, 
strlen(name)), Node_var_array);
-                       array_node->vname = node->vname;
-                       if ((nel = assoc_length(node)) > 0) {
-                               /* merge the 2 arrays */
+                       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 = node->alist(node, & akind);
+                               list = array_node->alist(array_node, & akind);
                                for (i = 0; i < nel; i++) {
                                        NODE **aptr;
-                                       aptr = assoc_lookup(array_node, 
list[2*i]);
+                                       aptr = assoc_lookup(node, list[2*i]);
                                        unref(*aptr);
                                        unref(list[2*i]); /* alist duped it */
                                        *aptr = dupnode(list[2*i+1]);
                                }
                                efree(list);
-                               assoc_clear(node);
+                               assoc_clear(array_node);
+                       } else {
+                               array_node->vname = node->vname;
+                               *node = *array_node;
                        }
-                       *node = *array_node;
                        freenode(array_node);
                        value->array_cookie = node;     /* pass new cookie back 
to extension */
                } else {
diff --git a/test/ChangeLog b/test/ChangeLog
index 0fa59a6..7522f7a 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,7 +1,14 @@
+2015-01-06         Andrew J. Schorr     <address@hidden>
+
+       * Makefile.am (EXTRA_DIST): Add defvar.awk and defvar.ok.
+       (SHLIB_TESTS): Add defvar.
+       (defvar): New test.
+       * defvar.awk, defvar.ok: New files.
+
 2015-01-05         Andrew J. Schorr     <address@hidden>
 
        * Makefile.am (EXTRA_DIST): Add getfile.awk and getfile.ok.
-       (SHLIB_TESTS): Add gefile.
+       (SHLIB_TESTS): Add getfile.
        (getfile): New test.
        * getfile.awk, getfile.ok: New files.
 
diff --git a/test/Makefile.am b/test/Makefile.am
index c31e882..3d95f4c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -174,6 +174,8 @@ EXTRA_DIST = \
        dbugeval.ok \
        defref.awk \
        defref.ok \
+       defvar.awk \
+       defvar.ok \
        delargv.awk \
        delargv.ok \
        delarpm2.awk \
@@ -1059,7 +1061,7 @@ LOCALE_CHARSET_TESTS = \
        mbprintf1 mbprintf2 mbprintf3 mbprintf4 rebt8b2 rtlenmb sort1 sprintfc
 
 SHLIB_TESTS = \
-       fnmatch filefuncs fork fork2 fts functab4 getfile inplace1 inplace2 
inplace3 \
+       defvar fnmatch filefuncs fork fork2 fts functab4 getfile inplace1 
inplace2 inplace3 \
        ordchr ordchr2 readdir readfile readfile2 revout revtwoway rwarray 
testext time
 
 # List of the tests which should be run with --lint option:
@@ -1900,6 +1902,11 @@ testext::
        @$(AWK) -f ./testext.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
        @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@ testext.awk
 
+defvar:
+       @echo $@
+       @$(AWK) -v TESTEXT_QUIET=1 -ltestext -f $(srcdir)/address@hidden 
$(srcdir)/address@hidden >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+       @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@
+
 getfile:
        @echo $@
        @$(AWK) -v TESTEXT_QUIET=1 -ltestext -f $(srcdir)/address@hidden 
$(srcdir)/address@hidden >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/Makefile.in b/test/Makefile.in
index 1ab2c8a..d2492d3 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -421,6 +421,8 @@ EXTRA_DIST = \
        dbugeval.ok \
        defref.awk \
        defref.ok \
+       defvar.awk \
+       defvar.ok \
        delargv.awk \
        delargv.ok \
        delarpm2.awk \
@@ -1302,7 +1304,7 @@ LOCALE_CHARSET_TESTS = \
        mbprintf1 mbprintf2 mbprintf3 mbprintf4 rebt8b2 rtlenmb sort1 sprintfc
 
 SHLIB_TESTS = \
-       fnmatch filefuncs fork fork2 fts functab4 getfile inplace1 inplace2 
inplace3 \
+       defvar fnmatch filefuncs fork fork2 fts functab4 getfile inplace1 
inplace2 inplace3 \
        ordchr ordchr2 readdir readfile readfile2 revout revtwoway rwarray 
testext time
 
 
@@ -2325,6 +2327,11 @@ testext::
        @$(AWK) -f ./testext.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
        @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@ testext.awk
 
+defvar:
+       @echo $@
+       @$(AWK) -v TESTEXT_QUIET=1 -ltestext -f $(srcdir)/address@hidden 
$(srcdir)/address@hidden >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+       @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@
+
 getfile:
        @echo $@
        @$(AWK) -v TESTEXT_QUIET=1 -ltestext -f $(srcdir)/address@hidden 
$(srcdir)/address@hidden >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/defvar.awk b/test/defvar.awk
new file mode 100644
index 0000000..444b81c
--- /dev/null
+++ b/test/defvar.awk
@@ -0,0 +1,3 @@
+BEGIN {
+       print "test_deferred returns", test_deferred()
+}
diff --git a/test/defvar.ok b/test/defvar.ok
new file mode 100644
index 0000000..4c85427
--- /dev/null
+++ b/test/defvar.ok
@@ -0,0 +1,5 @@
+fubar = 9
+rumpus = -5
+uid matches 1
+api_major matches 1
+test_deferred returns 1

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog           |   12 ++++++++
 awk.h               |    2 +-
 awkgram.c           |    7 +++-
 awkgram.y           |    7 +++-
 extension/ChangeLog |    7 +++++
 extension/testext.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 gawkapi.c           |   26 ++++++++++++------
 test/ChangeLog      |    9 ++++++-
 test/Makefile.am    |    9 ++++++-
 test/Makefile.in    |    9 ++++++-
 test/defvar.awk     |    3 ++
 test/defvar.ok      |    5 +++
 12 files changed, 149 insertions(+), 18 deletions(-)
 create mode 100644 test/defvar.awk
 create mode 100644 test/defvar.ok


hooks/post-receive
-- 
gawk



reply via email to

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