gawk-diffs
[Top][All Lists]
Advanced

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

[gawk-diffs] [SCM] gawk branch, extgawk, updated. 37cd3566b9b74c43d5f11f


From: Arnold Robbins
Subject: [gawk-diffs] [SCM] gawk branch, extgawk, updated. 37cd3566b9b74c43d5f11f1cba8dec147a25e474
Date: Sun, 24 Jun 2012 18:08:09 +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, extgawk has been updated
       via  37cd3566b9b74c43d5f11f1cba8dec147a25e474 (commit)
      from  115d332143b1a9d23bbf57088a577e778dcf31f8 (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=37cd3566b9b74c43d5f11f1cba8dec147a25e474

commit 37cd3566b9b74c43d5f11f1cba8dec147a25e474
Author: Arnold D. Robbins <address@hidden>
Date:   Sun Jun 24 21:07:22 2012 +0300

    Get rwarray extension working with new API.

diff --git a/ChangeLog b/ChangeLog
index dbfc8ef..9f6cad4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2012-06-24         Arnold D. Robbins     <address@hidden>
+
+       * ext.c (load_ext): Don't retun a value from a void function.
+       * gawkapi.c (api_set_array_element): Set up vname and parent_array.
+
 2012-06-21         Arnold D. Robbins     <address@hidden>
 
        More API and cleanup:
diff --git a/ext.c b/ext.c
index 911754b..0b87def 100644
--- a/ext.c
+++ b/ext.c
@@ -69,9 +69,9 @@ load_ext(const char *lib_name)
        if (install_func(& api_impl, NULL /* ext_id */) == 0) {
                warning(_("load_ext: library `%s' initialization routine `%s' 
failed\n"),
                                lib_name, INIT_FUNC);
-               return make_number(-1);
+               return;
        }
-       return make_number(0);
+       return;
 }
 
 
diff --git a/extension/ChangeLog b/extension/ChangeLog
index b482d6f..9d4305c 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,9 @@
+2012-06-24         Arnold D. Robbins     <address@hidden>
+
+       * Makefile.am: Enable rwarray extension.
+       * rwarray.c: Redone to use new API.
+       * rwarray.awk: Revamped for new version.
+
 2012-06-21         Arnold D. Robbins     <address@hidden>
 
        * testext.c (test_array_elem): Add a subarray.
diff --git a/extension/Makefile.am b/extension/Makefile.am
index bdb1bd1..767c2ab 100644
--- a/extension/Makefile.am
+++ b/extension/Makefile.am
@@ -1,7 +1,7 @@
 #
 # extension/Makefile.am --- automake input file for gawk
 #
-# Copyright (C) 1995-2006 the Free Software Foundation, Inc.
+# Copyright (C) 1995-2006, 2012 the Free Software Foundation, Inc.
 #
 # This file is part of GAWK, the GNU implementation of the
 # AWK Programming Language.
@@ -36,6 +36,7 @@ pkgextension_LTLIBRARIES =    \
        fork.la         \
        ordchr.la       \
        readfile.la     \
+       rwarray.la      \
        testext.la      \
        time.la
 
@@ -49,12 +50,12 @@ ordchr_la_SOURCES     = ordchr.c
 ordchr_la_LDFLAGS     = $(MY_MODULE_FLAGS)
 readfile_la_SOURCES   = readfile.c
 readfile_la_LDFLAGS   = $(MY_MODULE_FLAGS)
+rwarray_la_SOURCES    = rwarray.c
+rwarray_la_LDFLAGS    = $(MY_MODULE_FLAGS)
 time_la_SOURCES       = time.c
 time_la_LDFLAGS       = $(MY_MODULE_FLAGS)
-testext_la_SOURCES       = testext.c
-testext_la_LDFLAGS       = $(MY_MODULE_FLAGS)
-#rwarray_la_SOURCES    = rwarray.c
-#rwarray_la_LDFLAGS    = $(MY_MODULE_FLAGS)
+testext_la_SOURCES    = testext.c
+testext_la_LDFLAGS    = $(MY_MODULE_FLAGS)
 
 EXTRA_DIST = \
        ChangeLog \
diff --git a/extension/Makefile.in b/extension/Makefile.in
index 202989a..5666c9d 100644
--- a/extension/Makefile.in
+++ b/extension/Makefile.in
@@ -18,7 +18,7 @@
 #
 # extension/Makefile.am --- automake input file for gawk
 #
-# Copyright (C) 1995-2006 the Free Software Foundation, Inc.
+# Copyright (C) 1995-2006, 2012 the Free Software Foundation, Inc.
 #
 # This file is part of GAWK, the GNU implementation of the
 # AWK Programming Language.
@@ -154,6 +154,12 @@ readfile_la_OBJECTS = $(am_readfile_la_OBJECTS)
 readfile_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(readfile_la_LDFLAGS) $(LDFLAGS) -o $@
+rwarray_la_LIBADD =
+am_rwarray_la_OBJECTS = rwarray.lo
+rwarray_la_OBJECTS = $(am_rwarray_la_OBJECTS)
+rwarray_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(rwarray_la_LDFLAGS) $(LDFLAGS) -o $@
 testext_la_LIBADD =
 am_testext_la_OBJECTS = testext.lo
 testext_la_OBJECTS = $(am_testext_la_OBJECTS)
@@ -181,10 +187,10 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) 
$(LIBTOOLFLAGS) \
        $(LDFLAGS) -o $@
 SOURCES = $(filefuncs_la_SOURCES) $(fork_la_SOURCES) \
        $(ordchr_la_SOURCES) $(readfile_la_SOURCES) \
-       $(testext_la_SOURCES) $(time_la_SOURCES)
+       $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES)
 DIST_SOURCES = $(filefuncs_la_SOURCES) $(fork_la_SOURCES) \
        $(ordchr_la_SOURCES) $(readfile_la_SOURCES) \
-       $(testext_la_SOURCES) $(time_la_SOURCES)
+       $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -337,6 +343,7 @@ pkgextension_LTLIBRARIES = \
        fork.la         \
        ordchr.la       \
        readfile.la     \
+       rwarray.la      \
        testext.la      \
        time.la
 
@@ -349,12 +356,12 @@ ordchr_la_SOURCES = ordchr.c
 ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS)
 readfile_la_SOURCES = readfile.c
 readfile_la_LDFLAGS = $(MY_MODULE_FLAGS)
+rwarray_la_SOURCES = rwarray.c
+rwarray_la_LDFLAGS = $(MY_MODULE_FLAGS)
 time_la_SOURCES = time.c
 time_la_LDFLAGS = $(MY_MODULE_FLAGS)
 testext_la_SOURCES = testext.c
 testext_la_LDFLAGS = $(MY_MODULE_FLAGS)
-#rwarray_la_SOURCES    = rwarray.c
-#rwarray_la_LDFLAGS    = $(MY_MODULE_FLAGS)
 EXTRA_DIST = \
        ChangeLog \
        ChangeLog.0 \
@@ -456,6 +463,8 @@ ordchr.la: $(ordchr_la_OBJECTS) $(ordchr_la_DEPENDENCIES) 
$(EXTRA_ordchr_la_DEPE
        $(ordchr_la_LINK) -rpath $(pkgextensiondir) $(ordchr_la_OBJECTS) 
$(ordchr_la_LIBADD) $(LIBS)
 readfile.la: $(readfile_la_OBJECTS) $(readfile_la_DEPENDENCIES) 
$(EXTRA_readfile_la_DEPENDENCIES) 
        $(readfile_la_LINK) -rpath $(pkgextensiondir) $(readfile_la_OBJECTS) 
$(readfile_la_LIBADD) $(LIBS)
+rwarray.la: $(rwarray_la_OBJECTS) $(rwarray_la_DEPENDENCIES) 
$(EXTRA_rwarray_la_DEPENDENCIES) 
+       $(rwarray_la_LINK) -rpath $(pkgextensiondir) $(rwarray_la_OBJECTS) 
$(rwarray_la_LIBADD) $(LIBS)
 testext.la: $(testext_la_OBJECTS) $(testext_la_DEPENDENCIES) 
$(EXTRA_testext_la_DEPENDENCIES) 
        $(testext_la_LINK) -rpath $(pkgextensiondir) $(testext_la_OBJECTS) 
$(testext_la_LIBADD) $(LIBS)
 time.la: $(time_la_OBJECTS) $(time_la_DEPENDENCIES) 
$(EXTRA_time_la_DEPENDENCIES) 
@@ -471,6 +480,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 
diff --git a/extension/rwarray.awk b/extension/rwarray.awk
index 1057b39..b34a42a 100644
--- a/extension/rwarray.awk
+++ b/extension/rwarray.awk
@@ -1,19 +1,24 @@
-BEGIN {
-       extension("./rwarray.so","dlload")
address@hidden "rwarray"
 
+BEGIN {
        while ((getline word < "/usr/share/dict/words") > 0)
                dict[word] = word word
 
-       for (i in dict)
-               printf("dict[%s] = %s\n", i, dict[i]) > "orig.out"
+       n = asorti(dict, dictindices)
+       for (i = 1; i <= n; i++)
+               printf("dict[%s] = %s\n", dictindices[i], dict[dictindices[i]]) 
> "orig.out"
        close("orig.out");
 
-       writea("orig.bin", dict)
+       ret = writea("orig.bin", dict)
+       printf "writea() returned %d, expecting 1\n", ret
 
-       reada("orig.bin", dict)
+ 
+       ret = reada("orig.bin", dict)
+       printf "reada() returned %d, expecting 1\n", ret
 
-       for (i in dict)
-               printf("dict[%s] = %s\n", i, dict[i]) > "new.out"
+       n = asorti(dict, dictindices)
+       for (i = 1; i <= n; i++)
+               printf("dict[%s] = %s\n", dictindices[i], dict[dictindices[i]]) 
> "new.out"
        close("new.out");
 
        ret = system("cmp orig.out new.out")
@@ -23,6 +28,6 @@ BEGIN {
        else
                print "old and new are not equal - BAD"
 
-       if (ret == 0 && !("keepit" in ENVIRON))
-               system("rm orig.bin orig.out new.out")
+       if (ret == 0 && !("KEEPIT" in ENVIRON))
+               system("rm -f orig.bin orig.out new.out")
 }
diff --git a/extension/rwarray.c b/extension/rwarray.c
index fed040f..e4ddde3 100644
--- a/extension/rwarray.c
+++ b/extension/rwarray.c
@@ -3,10 +3,11 @@
  *
  * Arnold Robbins
  * May 2009
+ * Redone June 2012
  */
 
 /*
- * Copyright (C) 2009, 2010, 2011 the Free Software Foundation, Inc.
+ * Copyright (C) 2009, 2010, 2011, 2012 the Free Software Foundation, Inc.
  * 
  * This file is part of GAWK, the GNU implementation of the
  * AWK Programming Language.
@@ -26,76 +27,98 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA
  */
 
-#include "awk.h"
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
 #include <arpa/inet.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <fcntl.h>
 
+#include "gawkapi.h"
 
 #define MAGIC "awkrulz\n"
-#define MAJOR 1
+#define MAJOR 3
 #define MINOR 0
 
+static const gawk_api_t *api;  /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+
 int plugin_is_GPL_compatible;
 
-static int write_array(int fd, NODE *array);
-static int write_elem(int fd, int index, NODE *item);
-static int write_chain(int fd, int index, NODE *item);
-static int write_value(int fd, NODE *val);
+static awk_bool_t write_array(int fd, awk_array_t array);
+static awk_bool_t write_elem(int fd, awk_element_t *element);
+static awk_bool_t write_value(int fd, awk_value_t *val);
 
-static int read_array(int fd, NODE *array);
-static NODE *read_elem(int fd, int *index, NODE *array);
-static NODE *read_value(int fd);
+static awk_bool_t read_array(int fd, awk_array_t array);
+static awk_bool_t read_elem(int fd, awk_element_t *element);
+static awk_bool_t read_value(int fd, awk_value_t *value);
 
 /*
  * Format of array info:
  *
- * MAGIC       8 bytes
+ * MAGIC               8 bytes
  * Major version       4 bytes - network order
  * Minor version       4 bytes - network order
  * Element count       4 bytes - network order
- * Array size          4 bytes - network order
  * Elements
  * 
  * For each element:
- * Bucket number:      4 bytes - network order
- * Hash of index val:  4 bytes - network order
  * Length of index val:        4 bytes - network order
  * Index val as characters (N bytes)
- * Value type          1 byte (0 = string, 1 = number, 2 = array)
+ * Value type          4 bytes (0 = string, 1 = number, 2 = array)
  * IF string:
  *     Length of value 4 bytes
  *     Value as characters (N bytes)
- * ELSE
+ * ELSE IF number:
  *     8 bytes as native double
+ * ELSE
+ *     Element count
+ *     Elements
+ * END IF
  */
 
 /* do_writea --- write an array */
 
-static NODE *
-do_writea(int nargs)
+static awk_value_t *
+do_writea(int nargs, awk_value_t *result)
 {
-       NODE *file, *array;
-       int ret;
-       int fd;
+       awk_value_t filename, array;
+       int fd = -1;
        uint32_t major = MAJOR;
        uint32_t minor = MINOR;
 
+       assert(result != NULL);
+       make_number(0.0, result);
+
        if (do_lint && nargs > 2)
-               lintwarn("writea: called with too many arguments");
+               lintwarn(ext_id, "writea: called with too many arguments");
+
+       if (nargs < 2)
+               goto out;
 
        /* directory is first arg, array to dump is second */
-       file = get_scalar_argument(0, false);
-       array = get_array_argument(1, false);
+       if (! get_argument(0, AWK_STRING, & filename)) {
+               fprintf(stderr, "do_writea: argument 0 is not a string\n");
+               errno = EINVAL;
+               goto done1;
+       }
 
-       /* open the file, if error, set ERRNO and return */
-       (void) force_string(file);
-       fd = creat(file->stptr, 0600);
-       if (fd < 0) {
+       if (! get_argument(1, AWK_ARRAY, & array)) {
+               fprintf(stderr, "do_writea: argument 1 is not an array\n");
+               errno = EINVAL;
                goto done1;
        }
 
+       /* open the file, if error, set ERRNO and return */
+       fd = creat(filename.str_value.str, 0600);
+       if (fd < 0)
+               goto done1;
+
        if (write(fd, MAGIC, strlen(MAGIC)) != strlen(MAGIC))
                goto done1;
 
@@ -107,356 +130,336 @@ do_writea(int nargs)
        if (write(fd, & minor, sizeof(minor)) != sizeof(minor))
                goto done1;
 
-       ret = write_array(fd, array);
-       if (ret != 0)
-               goto done1;
-       ret = 0;
-       goto done0;
+       if (write_array(fd, array.array_cookie)) {
+               make_number(1.0, result);
+               goto done0;
+       }
 
 done1:
-       ret = -1;
        update_ERRNO_int(errno);
-       unlink(file->stptr);
+       unlink(filename.str_value.str);
 
 done0:
        close(fd);
-
-       /* Set the return value */
-       return make_number((AWKNUM) ret);
+out:
+       return result;
 }
 
 
 /* write_array --- write out an array or a sub-array */
 
-static int
-write_array(int fd, NODE *array)
+static awk_bool_t
+write_array(int fd, awk_array_t array)
 {
-       int ret;
+       uint32_t i;
        uint32_t count;
-       uint32_t array_sz;
-       int i;
-
-       count = htonl(array->table_size);
-       if (write(fd, & count, sizeof(count)) != sizeof(count))
-               return -1;
+       awk_flat_array_t *flat_array;
 
-       array_sz = htonl(array->array_size);
-       if (write(fd, & array_sz, sizeof(array_sz)) != sizeof(array_sz))
-               return -1;
-
-       for (i = 0; i < array->array_size; i++) {
-               ret = write_chain(fd, i, array->var_array[i]);
-               if (ret != 0)
-                       return ret;
+       if (! flatten_array(array, & flat_array)) {
+               printf("write_array: could not flatten array\n");
+               return 0;
        }
-       return 0;
-}
 
+       count = htonl(flat_array->count);
+       if (write(fd, & count, sizeof(count)) != sizeof(count))
+               return 0;
 
-/* write_chain --- write out a whole hash chain */
-
-/*
- * Write elements in the chain in reverse order so that
- * when we read the elements back in we can just push them
- * onto the front and thus recreate the array as it was.
- */
-
-static int
-write_chain(int fd, int index, NODE *bucket)
-{
-       int ret;
+       for (i = 0; i < flat_array->count; i++) {
+               if (! write_elem(fd, & flat_array->elements[i]))
+                       return 0;
+       }
 
-       if (bucket == NULL)
+       if (! release_flattened_array(array, flat_array)) {
+               printf("write_array: could not release flattened array\n");
                return 0;
+       }
 
-       ret = write_chain(fd, index, bucket->ahnext);
-       if (ret != 0)
-               return ret;
-
-       return write_elem(fd, index, bucket);
+       return 1;
 }
 
 /* write_elem --- write out a single element */
 
-static int
-write_elem(int fd, int index, NODE *item)
+static awk_bool_t
+write_elem(int fd, awk_element_t *element)
 {
-       uint32_t hashval, indexval_len;
-
-       index = htonl(index);
-       if (write(fd, & index, sizeof(index)) != sizeof(index))
-               return -1;
+       uint32_t indexval_len;
+       ssize_t write_count;
 
-       hashval = htonl(item->ahcode);
-       if (write(fd, & hashval, sizeof(hashval)) != sizeof(hashval))
-               return -1;
-
-       indexval_len = htonl(item->ahname_len);
+       indexval_len = htonl(element->index.str_value.len);
        if (write(fd, & indexval_len, sizeof(indexval_len)) != 
sizeof(indexval_len))
-               return -1;
+               return 0;
 
-       if (write(fd, item->ahname_str, item->ahname_len) != item->ahname_len)
-               return -1;
+       if (element->index.str_value.len > 0) {
+               write_count = write(fd, element->index.str_value.str,
+                               element->index.str_value.len);
+               if (write_count != (ssize_t) element->index.str_value.len)
+                       return 0;
+       }
 
-       return write_value(fd, item->ahvalue);
+       return write_value(fd, & element->value);
 }
 
 /* write_value --- write a number or a string or a array */
 
 static int
-write_value(int fd, NODE *val)
+write_value(int fd, awk_value_t *val)
 {
-       int code, len;
+       uint32_t code, len;
 
-       if (val->type == Node_var_array) {
+       if (val->val_type == AWK_ARRAY) {
                code = htonl(2);
                if (write(fd, & code, sizeof(code)) != sizeof(code))
-                       return -1;
-               return write_array(fd, val);
+                       return 0;
+               return write_array(fd, val->array_cookie);
        }
 
-       if ((val->flags & NUMBER) != 0) {
+       if (val->val_type == AWK_NUMBER) {
                code = htonl(1);
                if (write(fd, & code, sizeof(code)) != sizeof(code))
-                       return -1;
+                       return 0;
 
-               if (write(fd, & val->numbr, sizeof(val->numbr)) != 
sizeof(val->numbr))
-                       return -1;
+               if (write(fd, & val->num_value, sizeof(val->num_value)) != 
sizeof(val->num_value))
+                       return 0;
        } else {
                code = 0;
                if (write(fd, & code, sizeof(code)) != sizeof(code))
-                       return -1;
+                       return 0;
 
-               len = htonl(val->stlen);
+               len = htonl(val->str_value.len);
                if (write(fd, & len, sizeof(len)) != sizeof(len))
-                       return -1;
+                       return 0;
 
-               if (write(fd, val->stptr, val->stlen) != val->stlen)
-                       return -1;
+               if (write(fd, val->str_value.str, val->str_value.len)
+                               != (ssize_t) val->str_value.len)
+                       return 0;
        }
 
-       return 0;
+       return 1;
 }
 
 /* do_reada --- read an array */
 
-static NODE *
-do_reada(int nargs)
+static awk_value_t *
+do_reada(int nargs, awk_value_t *result)
 {
-       NODE *file, *array;
-       int ret;
-       int fd;
+       awk_value_t filename, array;
+       int fd = -1;
        uint32_t major;
        uint32_t minor;
        char magic_buf[30];
 
+       assert(result != NULL);
+       make_number(0.0, result);
+
        if (do_lint && nargs > 2)
-               lintwarn("reada: called with too many arguments");
+               lintwarn(ext_id, "reada: called with too many arguments");
 
-       /* directory is first arg, array to dump is second */
-       file = get_scalar_argument(0, false);
-       array = get_array_argument(1, false);
+       if (nargs < 2)
+               goto out;
 
-       (void) force_string(file);
-       fd = open(file->stptr, O_RDONLY);
-       if (fd < 0) {
+       /* directory is first arg, array to read is second */
+       if (! get_argument(0, AWK_STRING, & filename)) {
+               fprintf(stderr, "do_reada: argument 0 is not a string\n");
+               errno = EINVAL;
                goto done1;
        }
 
+       if (! get_argument(1, AWK_ARRAY, & array)) {
+               fprintf(stderr, "do_reada: argument 1 is not an array\n");
+               errno = EINVAL;
+               goto done1;
+       }
+
+       fd = open(filename.str_value.str, O_RDONLY);
+       if (fd < 0)
+               goto done1;
+
        memset(magic_buf, '\0', sizeof(magic_buf));
        if (read(fd, magic_buf, strlen(MAGIC)) != strlen(MAGIC)) {
+               errno = EBADF;
                goto done1;
        }
 
        if (strcmp(magic_buf, MAGIC) != 0) {
+               errno = EBADF;
                goto done1;
        }
 
        if (read(fd, & major, sizeof(major)) != sizeof(major)) {
+               errno = EBADF;
                goto done1;
        }
        major = ntohl(major);
 
        if (major != MAJOR) {
+               errno = EBADF;
                goto done1;
        }
 
        if (read(fd, & minor, sizeof(minor)) != sizeof(minor)) {
+               /* read() sets errno */
                goto done1;
        }
+
        minor = ntohl(minor);
        if (minor != MINOR) {
+               errno = EBADF;
                goto done1;
        }
 
-       assoc_clear(array, NULL);
+       if (! clear_array(array.array_cookie)) {
+               errno = ENOMEM;
+               printf("do_reada: clear_array failed\n");
+               goto done1;
+       }
 
-       ret = read_array(fd, array);
-       if (ret == 0)
+       if (read_array(fd, array.array_cookie)) {
+               make_number(1.0, result);
                goto done0;
+       }
 
 done1:
-       ret = -1;
        update_ERRNO_int(errno);
-
 done0:
        close(fd);
-
-       /* Set the return value */
-       return make_number((AWKNUM) ret);
+out:
+       return result;
 }
 
 
 /* read_array --- read in an array or sub-array */
 
-static int
-read_array(int fd, NODE *array)
+static awk_bool_t
+read_array(int fd, awk_array_t array)
 {
-       int i;
+       uint32_t i;
        uint32_t count;
-       uint32_t array_sz;
-       int index;
-       NODE *new_elem;
+       awk_element_t new_elem;
 
        if (read(fd, & count, sizeof(count)) != sizeof(count)) {
-               return -1;
-       }
-       array->table_size = ntohl(count);
-
-       if (read(fd, & array_sz, sizeof(array_sz)) != sizeof(array_sz)) {
-               return -1;
+               return 0;
        }
-       array->array_size = ntohl(array_sz);
-
-       /* malloc var_array */
-       array->var_array = (NODE **) malloc(array->array_size * sizeof(NODE *));
-       memset(array->var_array, '\0', array->array_size * sizeof(NODE *));
-
-       for (i = 0; i < array->table_size; i++) {
-               if ((new_elem = read_elem(fd, & index, array)) != NULL) {
-                       new_elem->ahnext = array->var_array[index];
-                       array->var_array[index] = new_elem;
+       count = ntohl(count);
+
+       for (i = 0; i < count; i++) {
+               if (read_elem(fd, & new_elem)) {
+                       /* add to array */
+                       if (! set_array_element(array, & new_elem)) {
+                               printf("read_array: set_array_element 
failed\n");
+                               return 0;
+                       }
                } else
                        break;
        }
-       if (i != array->table_size)
-               return -1; 
-       return 0;
-}
 
+       if (i != count)
+               return 0;
+
+       return 1;
+}
 
 /* read_elem --- read in a single element */
 
-static NODE *
-read_elem(int fd, int *the_index, NODE *array)
+static awk_bool_t
+read_elem(int fd, awk_element_t *element)
 {
-       uint32_t hashval, indexval_len, index;
-       NODE *item;
-       NODE *val;
-       int ret;
+       uint32_t index_len;
+       static char *buffer;
+       static uint32_t buflen;
+       ssize_t ret;
 
-       *the_index = 0;
-
-       if ((ret = read(fd, & index, sizeof(index))) != sizeof(index)) {
-               return NULL;
+       if ((ret = read(fd, & index_len, sizeof(index_len))) != 
sizeof(index_len)) {
+               return 0;
        }
-       *the_index = index = ntohl(index);
+       index_len = ntohl(index_len);
 
-       getnode(item);
-       memset(item, 0, sizeof(*item));
-       item->type = Node_ahash;
-       item->flags = MALLOC;
+       memset(element, 0, sizeof(*element));
 
-       if (read(fd, & hashval, sizeof(hashval)) != sizeof(hashval)) {
-               return NULL;
-       }
+       if (index_len > 0) {
+               if (buffer == NULL) {
+                       // allocate buffer
+                       emalloc(buffer, char *, index_len, "read_elem");
+                       buflen = index_len;
+               } else if (buflen < index_len) {
+                       // reallocate buffer
+                       char *cp = realloc(buffer, index_len);
 
-       item->ahcode = ntohl(hashval);
+                       if (cp == NULL)
+                               return 0;
 
-       if (read(fd, & indexval_len, sizeof(indexval_len)) != 
sizeof(indexval_len)) {
-               return NULL;
-       }
-       item->ahname_len = ntohl(indexval_len);
+                       buffer = cp;
+                       buflen = index_len;
+               }
 
-       item->ahname_str = malloc(item->ahname_len + 2);
-       if (read(fd, item->ahname_str, item->ahname_len) != item->ahname_len) {
-               return NULL;
+               if (read(fd, buffer, index_len) != (ssize_t) index_len) {
+                       return 0;
+               }
+               make_string(buffer, index_len, & element->index);
+       } else {
+               make_string("", 0, & element->index);
        }
-       item->ahname_str[item->ahname_len] = '\0';
-       item->ahname_ref = 1;
 
-       item->ahvalue = val = read_value(fd);
-       if (val == NULL) {
-               return NULL;
-       }
-       if (val->type == Node_var_array) {
-               char *aname;
-               size_t aname_len;
-
-               /* construct the sub-array name */
-               aname_len = strlen(array->vname) + item->ahname_len + 4;
-               emalloc(aname, char *, aname_len + 2, "read_elem");
-               sprintf(aname, "%s[\"%.*s\"]", array->vname, (int) 
item->ahname_len, item->ahname_str);
-               val->vname = aname;
-       }
+       if (! read_value(fd, & element->value))
+               return 0;
 
-       return item;
+       return 1;
 }
 
 /* read_value --- read a number or a string */
 
-static NODE *
-read_value(int fd)
+static awk_bool_t
+read_value(int fd, awk_value_t *value)
 {
-       NODE *val;
-       int code, len;
+       uint32_t code, len;
 
-       getnode(val);
-       memset(val, 0, sizeof(*val));
-       val->type = Node_val;
+       if (read(fd, & code, sizeof(code)) != sizeof(code))
+               return 0;
 
-       if (read(fd, & code, sizeof(code)) != sizeof(code)) {
-               return NULL;
-       }
        code = ntohl(code);
 
        if (code == 2) {
-               val->type = Node_var_array;
-               if (read_array(fd, val) != 0)
-                       return NULL; 
+               awk_array_t array = create_array();
+
+               if (read_array(fd, array) != 0)
+                       return 0; 
+
+               /* hook into value */
+               value->val_type = AWK_ARRAY;
+               value->array_cookie = array;
        } else if (code == 1) {
-               if (read(fd, & val->numbr, sizeof(val->numbr)) != 
sizeof(val->numbr)) {
-                       return NULL;
-               }
+               double d;
+
+               if (read(fd, & d, sizeof(d)) != sizeof(d))
+                       return 0;
 
-               val->flags = NUMBER|NUMCUR|MALLOC;
+               /* hook into value */
+               value->val_type = AWK_NUMBER;
+               value->num_value = d;
        } else {
                if (read(fd, & len, sizeof(len)) != sizeof(len)) {
-                       return NULL;
+                       return 0;
                }
-               val->stlen = ntohl(len);
-               val->stptr = malloc(val->stlen + 2);
-               memset(val->stptr, '\0', val->stlen + 2);
-
-               if (read(fd, val->stptr, val->stlen) != val->stlen) {
-                       return NULL;
+               len = ntohl(len);
+               value->val_type = AWK_STRING;
+               value->str_value.len = len;
+               value->str_value.str = malloc(len + 2);
+               memset(value->str_value.str, '\0', len + 2);
+
+               if (read(fd, value->str_value.str, len) != len) {
+                       free(value->str_value.str);
+                       return 0;
                }
-
-               val->flags = STRING|STRCUR|MALLOC;
        }
 
-       return val;
+       return 1;
 }
 
-/* dlload --- load new builtins in this library */
+static awk_ext_func_t func_table[] = {
+       { "writea", do_writea, 2 },
+       { "reada", do_reada, 2 },
+};
 
-NODE *
-dlload(tree, dl)
-NODE *tree;
-void *dl;
-{
-       make_builtin("writea", do_writea, 2);
-       make_builtin("reada", do_reada, 2);
 
-       return make_number((AWKNUM) 0);
-}
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, rwarray, "")
diff --git a/gawkapi.c b/gawkapi.c
index 139d77b..f87c775 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -528,6 +528,7 @@ api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie,
 {
        NODE *array = (NODE *)a_cookie;
        NODE *tmp;
+       NODE *elem;
        NODE **aptr;
 
        /* don't check for index len zero, null str is ok as index */
@@ -542,9 +543,13 @@ api_set_array_element(awk_ext_id_t id, awk_array_t 
a_cookie,
        aptr = assoc_lookup(array, tmp);
        unref(tmp);
        unref(*aptr);
-       *aptr = awk_value_to_node(& element->value);
-       if ((*aptr)->type == Node_var_array)
-               (*aptr)->parent_array = array;
+       elem = *aptr = awk_value_to_node(& element->value);
+       if (elem->type == Node_var_array) {
+               elem->parent_array = array;
+               elem->vname = estrdup(element->index.str_value.str,
+                                       element->index.str_value.len);
+               make_aname(elem);
+       }
 
        return true;
 }

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

Summary of changes:
 ChangeLog             |    5 +
 ext.c                 |    4 +-
 extension/ChangeLog   |    6 +
 extension/Makefile.am |   11 +-
 extension/Makefile.in |   20 ++-
 extension/rwarray.awk |   25 ++-
 extension/rwarray.c   |  469 +++++++++++++++++++++++++------------------------
 gawkapi.c             |   11 +-
 8 files changed, 293 insertions(+), 258 deletions(-)


hooks/post-receive
-- 
gawk



reply via email to

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