gawk-diffs
[Top][All Lists]
Advanced

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

[gawk-diffs] [SCM] gawk branch, array-iface, updated. dbabe5a569ad82a9fa


From: John Haque
Subject: [gawk-diffs] [SCM] gawk branch, array-iface, updated. dbabe5a569ad82a9faeb2f121e387ec6399f9dcb
Date: Thu, 03 May 2012 21:58:46 +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, array-iface has been updated
       via  dbabe5a569ad82a9faeb2f121e387ec6399f9dcb (commit)
      from  3a8c139d1a28651bf222b05cb0895bf5066bb9f9 (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=dbabe5a569ad82a9faeb2f121e387ec6399f9dcb

commit dbabe5a569ad82a9faeb2f121e387ec6399f9dcb
Author: john haque <address@hidden>
Date:   Thu May 3 16:36:25 2012 -0500

    Add extension example to read/write files with fixed-length records.

diff --git a/extension/ChangeLog b/extension/ChangeLog
index 6fdd40e..678e270 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,8 @@
+2011-05-03         John Haque     <address@hidden>
+
+       * fileop.c, record.awk, testrecord.sh: New files.
+       * steps: Updated.
+
 2011-05-02         John Haque     <address@hidden>
 
        * bindarr.c, dbarray.awk, testdbarray.awk: New files.
diff --git a/extension/bindarr.c b/extension/bindarr.c
index f500b74..9f8e090 100644
--- a/extension/bindarr.c
+++ b/extension/bindarr.c
@@ -64,7 +64,8 @@ static afunc_t bind_array_func[] = {
 };
 
 enum { INIT, FINI, COUNT, EXISTS, LOOKUP,
-       STORE, DELETE, CLEAR, FETCHALL };
+       STORE, DELETE, CLEAR, FETCHALL
+};
 
 static const char *const bfn[] = {
        "init", "fini", "count", "exists", "lookup",
@@ -121,8 +122,9 @@ static NODE **
 bind_array_clear(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
 {
        NODE *xn = symbol->xarray;
+       (void) xn->aclear(xn, NULL);
        (void) array_func_call(symbol, NULL, CLEAR);
-       return xn->aclear(xn, NULL);
+       return NULL;
 }
 
 /* bind_array_remove --- if subs is already in the table, remove it. */
@@ -131,8 +133,9 @@ static NODE **
 bind_array_remove(NODE *symbol, NODE *subs)
 {
        NODE *xn = symbol->xarray;
+       (void) xn->aremove(xn, subs);
        (void) array_func_call(symbol, subs, DELETE);
-       return xn->aremove(xn, subs);
+       return NULL;
 }
 
 /* bind_array_store --- update the value for the SUBS */
@@ -181,10 +184,12 @@ array_func_call(NODE *symbol, NODE *arg1, int fi)
        force_number(retval);
        ret = get_number_si(retval);
        unref(retval);
-       if (ret < 0)
-               fatal(ERRNO_node->var_value->stlen > 0 ?
-                       _("%s"), ERRNO_node->var_value->stptr : 
-                       _("unknown reason"));
+       if (ret < 0) {
+               if (ERRNO_node->var_value->stlen > 0)
+                       fatal(_("%s"), ERRNO_node->var_value->stptr);
+               else
+                       fatal(_("unknown reason"));
+       }
        return ret;
 }
 
@@ -199,6 +204,9 @@ do_bind_array(int nargs)
        char *aname;
 
        symbol = get_array_argument(0, FALSE);
+       if (symbol->array_funcs == bind_array_func)
+               fatal(_("bind_array: array `%s' already bound"), 
array_vname(symbol));
+
        assoc_clear(symbol);
 
        emalloc(aq, array_t *, sizeof(array_t), "do_bind_array");
diff --git a/extension/fileop.c b/extension/fileop.c
new file mode 100644
index 0000000..947c683
--- /dev/null
+++ b/extension/fileop.c
@@ -0,0 +1,394 @@
+/*
+ * fileop.c -- Builtin functions for binary I/O and other interfaces to
+ *     the filesystem.
+ */
+
+/*
+ * Copyright (C) 2012 the Free Software Foundation, Inc.
+ * 
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ * 
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA
+ */
+
+#include "awk.h"
+
+int plugin_is_GPL_compatible;
+
+typedef struct file_struct {
+       struct file_struct *next;
+       FILE *fp;
+       int flags;
+       char path[1];
+} file_t;
+
+static file_t *files;
+static file_t *file_open(const char *builtin_name, int nargs, int do_open);
+static int mode2flags(const char *mode);
+
+/* do_fread --- read from file */
+
+static NODE *
+do_fread(int nargs)
+{
+       NODE *arg;
+       size_t rlen, count;
+       file_t *f;
+       char *rbuf;
+
+       f = file_open("fread", nargs, TRUE);
+
+       arg = get_scalar_argument(2, FALSE);
+       force_number(arg);
+       rlen = get_number_ui(arg);
+
+       emalloc(rbuf, char *, rlen + 2, "do_fread");
+       if ((count = fread(rbuf, 1, rlen, f->fp)) < rlen) {
+               if (! feof(f->fp))
+                       update_ERRNO();
+       }
+       return make_str_node(rbuf, count, ALREADY_MALLOCED);
+}
+
+/* do_fwrite --- write to file */
+
+static NODE *
+do_fwrite(int nargs)
+{
+       NODE *arg;
+       file_t *f;
+       size_t count = 0;
+
+       f = file_open("fwrite", nargs, TRUE);
+
+       arg = get_scalar_argument(2, FALSE);
+       force_string(arg);
+       if (arg->stlen > 0) {
+               count = fwrite(arg->stptr, 1, arg->stlen, f->fp);
+               if (count < arg->stlen)
+                       update_ERRNO();
+       }
+       return make_number(count);
+}
+
+/* do_fseek --- set the file position indicator */
+
+static NODE *
+do_fseek(int nargs)
+{
+       NODE *arg;
+       long offset;
+       file_t *f;
+       int whence = 0, ret = 0;
+
+       f = file_open("fseek", nargs, TRUE);
+
+       arg = get_scalar_argument(2, FALSE);
+       force_number(arg);
+       offset = get_number_si(arg);
+
+       arg = get_scalar_argument(3, FALSE);
+       force_string(arg);
+       if (strcasecmp(arg->stptr, "SEEK_SET") == 0)
+               whence = SEEK_SET;
+       else if (strcasecmp(arg->stptr, "SEEK_CUR") == 0)
+               whence = SEEK_CUR;
+       else if (strcasecmp(arg->stptr, "SEEK_END") == 0)
+               whence = SEEK_END;
+       else
+               fatal(_("fseek: `%.*s' is not a valid 4th argument"),
+                       (int) arg->stlen, arg->stptr);
+
+       if (fseek(f->fp, offset, whence) < 0) {
+               update_ERRNO();
+               ret = -1;
+       }
+       return make_number(ret);
+}
+
+/* do_ftruncate --- truncate the file to a specified length */
+
+static NODE *
+do_ftruncate(int nargs)
+{
+       NODE *arg;
+       file_t *f;
+       off_t len;
+       int ret = 0;
+
+       f = file_open("ftruncate", nargs, TRUE);
+       arg = get_scalar_argument(2, FALSE);
+       force_number(arg);
+       len = (off_t) get_number_si(arg);
+       if (ftruncate(fileno(f->fp), len) < 0) {
+               update_ERRNO();
+               ret = -1;
+       }
+       return make_number(ret);
+}
+
+/* do_unlink --- delete the name from the filesystem */
+
+static NODE *
+do_unlink(int nargs)
+{
+       NODE *file;
+       int ret = 0;
+
+       file = get_scalar_argument(0, FALSE);
+       force_string(file);
+       if (file->stlen == 0)
+               fatal(_("unlink: filename has empty string value"));
+       if (unlink(file->stptr) < 0) {
+               update_ERRNO();
+               ret = -1;
+       }
+       return make_number(ret);
+}
+
+/* do_flush --- flush buffered data to file */
+
+static NODE *
+do_flush(int nargs)
+{
+       file_t *f;
+       int status = -1;
+
+       f = file_open("flush", nargs, FALSE);
+       if (f != NULL) {
+               status = fflush(f->fp);
+               if (status != 0)
+                       update_ERRNO();
+       }
+       return make_number(status);
+}
+
+/* do_fclose --- close an open file */
+
+static NODE *
+do_fclose(int nargs)
+{
+       file_t *f;
+       int status = -1;
+
+       f = file_open("fclose", nargs, FALSE);
+       if (f != NULL) {
+               status = fclose(f->fp);
+               if (status != 0)
+                       update_ERRNO();
+               assert(files == f);
+               files = f->next;
+               efree(f);
+       }
+       return make_number(status);
+}
+
+/* do_filesize --- return the size of the file */
+
+static NODE *
+do_filesize(int nargs)
+{
+       NODE *file;
+       struct stat sbuf;
+       AWKNUM d = -1.0;
+
+       file = get_scalar_argument(0, FALSE);
+       force_string(file);
+       if (file->stlen == 0)
+               fatal(_("filesize: filename has empty string value"));
+
+       if (stat(file->stptr, & sbuf) < 0) {
+               update_ERRNO();
+               goto ferror;
+       }
+       if ((sbuf.st_mode & S_IFMT) != S_IFREG) {
+               errno = EINVAL;
+               update_ERRNO();
+               goto ferror;
+       }
+       d = sbuf.st_size;
+
+ferror:
+       return make_number(d);
+}
+
+/* do_file_exists --- check if path exists in the filesystem */
+
+static NODE *
+do_file_exists(int nargs)
+{
+       NODE *file;
+       struct stat sbuf;
+       int ret = 1;
+
+       file = get_scalar_argument(0, FALSE);
+       force_string(file);
+       if (file->stlen == 0)
+               fatal(_("file_exists: filename has empty string value"));
+
+       if (stat(file->stptr, & sbuf) < 0) {
+               if (errno != ENOENT)
+                       update_ERRNO();
+               ret = 0;
+       }
+       return make_number(ret);
+}
+
+
+/* file_open --- open a file or find an already opened file */
+
+static file_t *
+file_open(const char *builtin_name, int nargs, int do_open)
+{
+       NODE *file, *mode;
+       file_t *f, *prev;
+       FILE *fp;
+       int flags;
+       char *path;
+
+       if (nargs < 2)
+               cant_happen();
+
+       file = get_scalar_argument(0, FALSE);
+       force_string(file);
+       mode = get_scalar_argument(1, TRUE);
+       force_string(mode);
+
+       if (file->stlen == 0)
+               fatal(_("%s: filename has empty string value"), builtin_name);
+       if (mode->stlen == 0)
+               fatal(_("%s: mode has empty string value"), builtin_name);
+
+       flags = mode2flags(mode->stptr);
+       if (flags < 0)
+               fatal(_("%s: invalid mode `%.*s'"), builtin_name,
+                       (int) mode->stlen, mode->stptr);
+
+       path = file->stptr;
+       for (prev = NULL, f = files; f != NULL; prev = f, f = f->next) {
+               if (strcmp(f->path, path) == 0 && f->flags == flags) {
+                       /* Move to the head of the list */
+                       if (prev != NULL) {
+                               prev->next = f->next;
+                               f->next = files;
+                               files = f;
+                       }
+                       return f;
+               }
+       }
+
+       if (! do_open) {
+               if (do_lint)
+                       lintwarn(_("%s: `%.*s' is not an open file"),
+                               builtin_name, (int) file->stlen, file->stptr);
+               return NULL;
+       }
+
+       fp = fopen(path, mode->stptr);
+       if (fp == NULL)
+               fatal(_("%s: cannot open file `%.*s'"),
+                       builtin_name, (int) file->stlen, file->stptr);
+
+       os_close_on_exec(fileno(fp), path, "", "");
+
+       emalloc(f, file_t *, sizeof(file_t) + file->stlen + 1, "file_open");
+       memcpy(f->path, path, file->stlen + 1);
+       f->fp = fp;
+       f->flags = flags;
+       f->next = files;
+       files = f;
+       return f;
+}
+
+
+/*
+ * mode2flags --- convert a string mode to an integer flag;
+ *     modified from str2mode in io.c.
+ */
+
+static int
+mode2flags(const char *mode)
+{
+       int ret = -1;
+       const char *second;
+
+       if (mode == NULL || mode[0] == '\0')
+               return -1;
+
+       second = & mode[1];
+
+       if (*second == 'b')
+               second++;
+
+       switch(mode[0]) {
+       case 'r':
+               ret = O_RDONLY;
+               if (*second == '+' || *second == 'w')
+                       ret = O_RDWR;
+               break;
+
+       case 'w':
+               ret = O_WRONLY|O_CREAT|O_TRUNC;
+               if (*second == '+' || *second == 'r')
+                       ret = O_RDWR|O_CREAT|O_TRUNC;
+               break;
+
+       case 'a':
+               ret = O_WRONLY|O_APPEND|O_CREAT;
+               if (*second == '+')
+                       ret = O_RDWR|O_APPEND|O_CREAT;
+               break;
+
+       default:
+               ret = -1;
+       }
+       if (ret != -1 && strchr(mode, 'b') != NULL)
+               ret |= O_BINARY;
+       return ret;
+}
+
+
+/* dlload --- load new builtins in this library */
+
+NODE *
+dlload(NODE *tree, void *dl)
+{
+       make_builtin("fseek", do_fseek, 4);
+       make_builtin("fread", do_fread, 3);
+       make_builtin("fwrite", do_fwrite, 3);
+       make_builtin("flush", do_flush, 2);
+       make_builtin("filesize", do_filesize, 1);
+       make_builtin("file_exists", do_file_exists, 1);
+       make_builtin("fclose", do_fclose, 2);
+       make_builtin("ftruncate", do_ftruncate, 3);
+       make_builtin("unlink", do_unlink, 1);
+       return make_number((AWKNUM) 0);
+}
+
+
+/* dlunload --- routine called when exiting */ 
+
+void
+dlunload()
+{
+       file_t *f;
+       for (f = files; f != NULL; f = f->next) {
+               if (f->fp != NULL) {
+                       fclose(f->fp);
+                       f->fp = NULL;
+               }
+       }
+}
diff --git a/extension/record.awk b/extension/record.awk
new file mode 100644
index 0000000..18a3ce4
--- /dev/null
+++ b/extension/record.awk
@@ -0,0 +1,252 @@
+# record.awk -- represent fixed-length records in a file as an array.
+# Each element in the array corresponds to a record in the file.
+# The records are numbered starting from 1, and each record read in
+# from the file is cached. If opened using mode "r+",
+# changes to the array are reflected in the file immediately i.e.
+# writing to an element writes the data into the file.
+#
+# Usage:
+#      record(r, path [, reclen [, mode]])
+#              r      -- array to bind
+#              path   -- filename
+#              reclen -- length of each record 
+#              mode   -- "r" for reading (default), "r+" for reading and 
writing
+#
+#      With reclen <= 0, entire file is treated as one record #1.
+#
+#              record(r, "data.in", 80, "r+")
+#              r[10] = r[1]
+#              for (i = 1; i in r; i++)
+#                      print r[i]      
+#              delete r[1]
+#
+# See Also: testrecord.sh
+#
+#
+# TODO:
+#      * implement deferred writing
+#      * limit memory usage for read cache
+#      * use fixed size buffer when deleting a record
+#
+
+BEGIN {
+       extension("fileop.so")
+       extension("bindarr.so")
+}
+
+# _record_count --- return the number of records in file
+
+function _record_count(symbol, rd)
+{
+       if (! ("rectot" in rd))
+               rd["rectot"] = ("reclen" in rd) ?
+                               int(filesize(rd["path"]) / rd["reclen"]) : 1
+       return rd["rectot"]
+}
+
+# _record_exists --- check if record exists
+
+function _record_exists(symbol, rd, recnum,
+               path, mode, reclen, rectot)
+{
+       path = rd["path"]
+       reclen = ("reclen" in rd) ? rd["reclen"] : filesize(path)
+       mode = rd["mode"]
+       rectot = _record_count(symbol, rd)
+
+       recnum = int(recnum)
+       if (recnum <= 0 || recnum > rectot)
+               return 0
+
+       if (! (recnum in symbol)) {
+               fseek(path, mode, (recnum - 1) * reclen, "SEEK_SET")
+               symbol[recnum] = fread(path, mode, reclen)
+       }
+       return 0
+}
+
+# _record_lookup --- lookup a record
+
+function _record_lookup(symbol, rd, recnum,
+               path, mode, reclen, rectot)
+{
+       path = rd["path"]
+       reclen = ("reclen" in rd) ? rd["reclen"] : filesize(path)
+       mode = rd["mode"]
+       rectot = _record_count(symbol, rd)
+
+       recnum = int(recnum)
+       if (recnum <= 0 || recnum > rectot) {
+               ERRNO = sprintf("record: %s: reference to non-existent record 
#%d", path, recnum)
+               return -1
+       }
+
+       if (! (recnum in symbol)) {
+               fseek(path, mode, (recnum - 1) * reclen, "SEEK_SET")
+               symbol[recnum] = fread(path, mode, reclen)
+       }
+       return 0
+}
+
+# _record_clear --- remove all records
+
+function _record_clear(symbol, rd,
+               path, mode)
+{
+       path = rd["path"]
+       mode = rd["mode"]
+       if (mode == "r") {
+               ERRNO = sprintf("record: cannot delete record from file `%s' 
opened only for reading", path)
+               return -1
+       }
+       ftruncate(path, mode, 0)
+       delete rd["reclen"]
+       return 0
+}
+
+# _record_delete --- delete a record from the file
+
+function _record_delete(symbol, rd, recnum,
+               path, mode, reclen, rectot)
+{
+       path = rd["path"]
+       reclen = ("reclen" in rd) ? rd["reclen"] : filesize(path)
+       mode = rd["mode"]
+
+       if (mode == "r") {
+               ERRNO = sprintf("record: cannot delete record from file `%s' 
opened only for reading", path)
+               return -1
+       }
+
+       recnum = int(recnum)
+       if (! ("reclen" in rd)) {
+               # entire file is record #1
+               ftruncate(path, mode, 0)
+               delete rd["reclen"]
+               return 0
+       }
+
+       sz = filesize(path)
+       rectot = int(sz / reclen)
+
+       recstart = (recnum - 1) * reclen
+       off = sz - (recstart + reclen)
+
+       fseek(path, mode, -off, "SEEK_END")
+       tmp = fread(path, mode, off)
+       fseek(path, mode, recstart, "SEEK_SET")
+       if (fwrite(path, mode, tmp) != length(tmp))
+               return -1
+       flush(path, mode)
+       ftruncate(path, mode, sz - reclen)
+
+       rd["rectot"] = rectot - 1
+       for (i = recnum + 1; i <= rectot; i++) {
+               if (i in symbol) {
+                       symbol[i - 1] = symbol[i]
+                       delete symbol[i]
+               }
+       }
+       return 0
+}
+
+# _record_store --- write a record to file
+
+function _record_store(symbol, rd, recnum,
+               path, mode, reclen, val)
+{
+       path = rd["path"]
+       reclen = ("reclen" in rd) ? rd["reclen"] : filesize(path)
+       mode = rd["mode"]
+
+       if (mode == "r") {
+               ERRNO = sprintf("record: cannot write to file `%s' opened only 
for reading", path)
+               return -1
+       }
+
+       recnum = int(recnum)
+       val = symbol[recnum]
+       if (! ("reclen" in rd)) {
+               # the entire file is record #1
+               if (reclen != 0)
+                       ftruncate(path, mode, 0)
+       } else if (length(val) != reclen) {
+               ERRNO = sprintf("record: %s: invalid length for record #%d", 
path, recnum)
+               return -1
+       }
+
+       fseek(path, mode, (recnum - 1) * reclen, "SEEK_SET")
+       if (fwrite(path, mode, val) != length(val))
+               return -1
+       flush(path, mode)
+       return 0
+}
+
+# _record_fetchall --- retrieve all the records
+
+function _record_fetchall(symbol, rd,
+               path, mode, reclen, rectot, recnum)
+{
+       path = rd["path"]
+       reclen = ("reclen" in rd) ? rd["reclen"] : filesize(path)
+       mode = rd["mode"]
+       rectot = _record_count(symbol, rd)
+
+       if (rd["loaded"])
+               return 0
+       for (recnum = 1; recnum <= rectot; recnum++) {
+               if (! (recnum in symbol)) {
+                       fseek(path, mode, (recnum - 1) * reclen, "SEEK_SET")
+                       symbol[recnum] = fread(path, mode, reclen)
+               }
+       }
+       rd["loaded"] = 1
+       return 0
+}
+
+# _record_init --- initialization routine
+
+function _record_init(symbol, rd)
+{
+       if (! file_exists(rd["path"])) {
+               ERRNO = sprintf("record: cannot open file `%s' for reading", 
rd["path"])
+               return -1
+       }
+       return 0
+}
+
+# _record_fini --- cleanup routine
+
+function _record_fini(symbol, rd)
+{
+       fclose(rd["path"], rd["mode"])
+}
+
+# record --- bind an array to a file with fixed-length records
+
+function record(array, path, reclen, mode,     rd)
+{
+       if (path == "") {
+               print "fatal: record: empty string value for filename" > 
"/dev/stderr"
+               exit(1)
+       }
+
+       # register our array routines
+       rd["init"] = "_record_init"
+       rd["fini"] = "_record_fini"
+       rd["count"] = "_record_count"
+       rd["exists"] = "_record_exists"
+       rd["lookup"] = "_record_lookup"
+       rd["delete"] = "_record_delete"
+       rd["store"] = "_record_store"
+       rd["clear"] = "_record_clear"
+       rd["fetchall"] = "_record_fetchall"
+
+       rd["path"] = path
+       if (reclen > 0)
+               rd["reclen"] = reclen
+       rd["mode"] = mode == "r+" ? "r+" : "r"
+
+       delete array
+       bind_array(array, rd)
+}
diff --git a/extension/spec_array.c b/extension/spec_array.c
index b271300..78b2401 100644
--- a/extension/spec_array.c
+++ b/extension/spec_array.c
@@ -130,13 +130,43 @@ deferred_array_##F(NODE *symbol, NODE *subs)              
\
 
 DEF_ARR(exists)
 DEF_ARR(lookup)
-DEF_ARR(clear)
-DEF_ARR(remove)
 DEF_ARR(list)
 DEF_ARR(copy)
 
 #undef DEF_ARR
 
+/* deferred_array_remove --- remove the index from the array */
+
+static NODE **
+deferred_array_remove(NODE *symbol, NODE *subs)
+{
+       array_t *av = (array_t *) symbol->xarray;
+       
+       (void) SUPER(aremove)(symbol, subs);
+       if (av) {
+               symbol->xarray = NULL;
+               (*av->load_func)(symbol, av->data);
+               symbol->xarray = (NODE *) av;
+       }
+       return NULL;
+}
+
+/* deferred_array_clear --- flush all the values in symbol[] */
+
+static NODE **
+deferred_array_clear(NODE *symbol, NODE *subs)
+{
+       array_t *av = (array_t *) symbol->xarray;
+       
+       (void) SUPER(aclear)(symbol, subs);
+       if (av) {
+               symbol->xarray = NULL;
+               (*av->load_func)(symbol, av->data);
+               symbol->xarray = (NODE *) av;
+       }
+       return NULL;
+}
+
 
 /*
  * dyn_array --- array with triggers for reading and writing
@@ -272,12 +302,13 @@ dyn_array_remove(NODE *symbol, NODE *subs)
 {
        array_t *av = (array_t *) symbol->xarray;
 
+       (void) SUPER(aremove)(symbol, subs);
        if (av && av->store_func) {
                symbol->xarray = NULL;
                (*av->store_func)(symbol, subs, NULL, av->data);
                symbol->xarray = (NODE *) av;
        }
-       return SUPER(aremove)(symbol, subs);
+       return NULL;
 }
 
 /* dyn_array_clear --- flush all the values in symbol[] */
@@ -287,12 +318,13 @@ dyn_array_clear(NODE *symbol, NODE *subs)
 {
        array_t *av = (array_t *) symbol->xarray;
 
+       (void) SUPER(aclear)(symbol, subs);
        if (av && av->store_func) {
                symbol->xarray = NULL;
                (*av->store_func)(symbol, NULL, NULL, av->data);
                symbol->xarray = (NODE *) av;
        }
-       return SUPER(aclear)(symbol, subs);
+       return NULL;
 }
 
 /* dyn_array_list --- return a list of items in symbol[] */
diff --git a/extension/steps b/extension/steps
index 1abab9d..9e0cc00 100755
--- a/extension/steps
+++ b/extension/steps
@@ -16,6 +16,7 @@ gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. 
rwarray.c
 gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. spec_array.c
 gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. sparr.c
 gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. bindarr.c
+gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. fileop.c
 ld -o dl.so -shared dl.o
 ld -o filefuncs.so -shared filefuncs.o
 ld -o fork.so -shared fork.o
@@ -26,3 +27,4 @@ ld -o testarg.so -shared testarg.o
 ld -o rwarray.so -shared rwarray.o
 ld -o sparr.so -shared sparr.o spec_array.o
 ld -o bindarr.so -shared bindarr.o
+ld -o fileop.so -shared fileop.o
diff --git a/extension/testrecord.sh b/extension/testrecord.sh
new file mode 100755
index 0000000..61d1ba7
--- /dev/null
+++ b/extension/testrecord.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+AWK=../gawk
+$AWK 'BEGIN { OFS = ORS = ""; for (j = 1; j <= 4; j++) for (i = 1; i <= 16; 
i++) print j}' > _rec.in
+for i in 1 2 3 4 5
+do
+$AWK -f record.awk -vinfile='_rec.in' -e 'BEGIN {
+reclen = 16
+record(r, infile, reclen, "r+")
+FIELDWIDTHS="8 4 4"
+for (i = 1; i in r; i++) {
+       $0 = r[i]
+       print $1
+}
+delete r[1]
+unbind_array(r)
+print "--" }'
+done
+rm -f _rec.in

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

Summary of changes:
 extension/ChangeLog     |    5 +
 extension/bindarr.c     |   22 ++-
 extension/fileop.c      |  394 +++++++++++++++++++++++++++++++++++++++++++++++
 extension/record.awk    |  252 ++++++++++++++++++++++++++++++
 extension/spec_array.c  |   40 +++++-
 extension/steps         |    2 +
 extension/testrecord.sh |   19 +++
 7 files changed, 723 insertions(+), 11 deletions(-)
 create mode 100644 extension/fileop.c
 create mode 100644 extension/record.awk
 create mode 100755 extension/testrecord.sh


hooks/post-receive
-- 
gawk



reply via email to

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