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. 3a8c139d1a28651bf2


From: John Haque
Subject: [gawk-diffs] [SCM] gawk branch, array-iface, updated. 3a8c139d1a28651bf222b05cb0895bf5066bb9f9
Date: Wed, 02 May 2012 13:28:21 +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  3a8c139d1a28651bf222b05cb0895bf5066bb9f9 (commit)
      from  50c2afd6433f1c4407b04d2f75e536da7c94fe74 (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=3a8c139d1a28651bf222b05cb0895bf5066bb9f9

commit 3a8c139d1a28651bf222b05cb0895bf5066bb9f9
Author: john haque <address@hidden>
Date:   Wed May 2 08:05:43 2012 -0500

    Fix memory corruption in copying an array, add another array extension.

diff --git a/ChangeLog b/ChangeLog
index 9b46a92..5784af3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2012-05-02         John Haque      <address@hidden>
+
+       * str_array.c (str_copy): Initialize next pointer in the linked list
+       to avoid memory corruption.
+       * int_array.c (int_copy): Ditto.
+
 2012-04-21         John Haque      <address@hidden>
 
        Shutdown routine for a dynamic extension.
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 75dc66a..6fdd40e 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,8 @@
+2011-05-02         John Haque     <address@hidden>
+
+       * bindarr.c, dbarray.awk, testdbarray.awk: New files.
+       * steps: Updated.
+
 2011-04-24         John Haque     <address@hidden>
 
        * spec_array.c, spec_array.h, sparr.c, testsparr.awk: New files.
diff --git a/extension/bindarr.c b/extension/bindarr.c
new file mode 100644
index 0000000..f500b74
--- /dev/null
+++ b/extension/bindarr.c
@@ -0,0 +1,339 @@
+/*
+ * bindarr.c - routines for binding (attaching) user-defined functions
+ *             to array and array elements.
+ */
+
+/* 
+ * Copyright (C) 1986, 1988, 1989, 1991-2011 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"
+
+/*
+ * Binding an array is basically the binding of functions to the internal
+ * triggers for reading and writing that array or an element of that array.
+ * This allows the user to define the set of behaviors for gawk arrays
+ * using gawk functions. With arrays you can assign and read values of
+ * specific elements, provide list of indices and values, and tell if a
+ * certain index exists or not. A variable can be "tied" by including
+ * code which overrides any or all of the standard behaviors of awk arrays.
+ *
+ * See dbarray.awk and testdbarray.awk to learn how to bind an array
+ * to an external database for persistent storage.
+ */
+
+int plugin_is_GPL_compatible;
+
+static NODE **bind_array_lookup(NODE *, NODE *);
+static NODE **bind_array_exists(NODE *, NODE *);
+static NODE **bind_array_clear(NODE *, NODE *);
+static NODE **bind_array_remove(NODE *, NODE *);
+static NODE **bind_array_list(NODE *, NODE *);
+static NODE **bind_array_store(NODE *, NODE *);
+static NODE **bind_array_length(NODE *, NODE *);
+
+static afunc_t bind_array_func[] = {
+       (afunc_t) 0,
+       (afunc_t) 0,
+       bind_array_length,
+       bind_array_lookup,
+       bind_array_exists,
+       bind_array_clear,
+       bind_array_remove,
+       bind_array_list,
+       null_afunc,     /* copy */
+       null_afunc,     /* dump */
+       bind_array_store,
+};
+
+enum { INIT, FINI, COUNT, EXISTS, LOOKUP,
+       STORE, DELETE, CLEAR, FETCHALL };
+
+static const char *const bfn[] = {
+       "init", "fini", "count", "exists", "lookup",
+       "store", "delete", "clear", "fetchall",
+};
+
+typedef struct {
+       NODE *func[sizeof(bfn)/sizeof(char *)];
+       NODE *arg0;
+} array_t;
+
+static NODE *call_func(NODE *func, NODE **arg, int arg_count);
+static long array_func_call(NODE *, NODE *, int);
+
+
+/* bind_array_length -- find the number of elements in the array */
+
+static NODE **
+bind_array_length(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
+{
+       static NODE *length_node;
+
+       symbol->table_size = array_func_call(symbol, NULL, COUNT);
+       length_node = symbol;
+       return & length_node;
+}
+
+/* bind_array_lookup --- find element in the array; return a pointer to value. 
*/
+
+static NODE **
+bind_array_lookup(NODE *symbol, NODE *subs)
+{
+       NODE *xn = symbol->xarray;
+       (void) array_func_call(symbol, subs, LOOKUP);
+       return xn->alookup(xn, subs);
+}
+
+/*
+ * bind_array_exists --- test whether the array element symbol[subs] exists or 
not,
+ *     return pointer to value if it does.
+ */
+
+static NODE **
+bind_array_exists(NODE *symbol, NODE *subs)
+{
+       NODE *xn = symbol->xarray;
+       (void) array_func_call(symbol, subs, EXISTS);
+       return xn->aexists(xn, subs);
+}
+
+/* bind_array_clear --- flush all the values in symbol[] */
+
+static NODE **
+bind_array_clear(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
+{
+       NODE *xn = symbol->xarray;
+       (void) array_func_call(symbol, NULL, CLEAR);
+       return xn->aclear(xn, NULL);
+}
+
+/* bind_array_remove --- if subs is already in the table, remove it. */
+
+static NODE **
+bind_array_remove(NODE *symbol, NODE *subs)
+{
+       NODE *xn = symbol->xarray;
+       (void) array_func_call(symbol, subs, DELETE);
+       return xn->aremove(xn, subs);
+}
+
+/* bind_array_store --- update the value for the SUBS */
+
+static NODE **
+bind_array_store(NODE *symbol, NODE *subs)
+{
+       (void) array_func_call(symbol, subs, STORE);
+       return NULL;
+}
+
+/* bind_array_list --- return a list of array items */
+
+static NODE**
+bind_array_list(NODE *symbol, NODE *akind)
+{
+       NODE *xn = symbol->xarray;
+       (void) array_func_call(symbol, NULL, FETCHALL);
+       return xn->alist(xn, akind);
+}
+
+
+/* array_func_call --- call user-defined array routine */
+
+static long
+array_func_call(NODE *symbol, NODE *arg1, int fi)
+{
+       NODE *argp[3];
+       NODE *retval;
+       long ret;
+       int i = 0;
+       array_t *aq;
+
+       aq = symbol->a_opaque;
+       if (! aq)       /* an array routine invoked from the same or another 
routine */
+               fatal(_("bind_array: cannot access bound array, operation not 
allowed"));
+       symbol->a_opaque = NULL;        /* avoid infinite recursion */
+
+       argp[i++] = symbol->xarray;
+       argp[i++] = aq->arg0;
+       if (arg1 != NULL)
+               argp[i++] = arg1;
+
+       retval = call_func(aq->func[fi], argp, i);
+       symbol->a_opaque = aq;
+       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"));
+       return ret;
+}
+
+/* do_bind_array --- bind an array to user-defined functions */
+
+static NODE *
+do_bind_array(int nargs)
+{
+       NODE *symbol, *xn, *t, *td;
+       int i;
+       array_t *aq;
+       char *aname;
+
+       symbol = get_array_argument(0, FALSE);
+       assoc_clear(symbol);
+
+       emalloc(aq, array_t *, sizeof(array_t), "do_bind_array");
+       memset(aq, '\0', sizeof(array_t));
+
+       t = get_array_argument(1, FALSE);
+
+       for (i = 0; i < sizeof(bfn)/sizeof(char *); i++) {
+               NODE *subs, *val, *f;
+
+               subs = make_string(bfn[i], strlen(bfn[i]));
+               val = in_array(t, subs);
+               unref(subs);
+               if (val == NULL) {
+                       if (i != INIT && i != FINI)
+                               fatal(_("bind_array: array element `%s[\"%s\"]' 
not defined"),
+                                               t->vname, bfn[i]);
+                       continue;
+               }
+
+               force_string(val);
+               f = lookup(val->stptr);
+               if (f == NULL || f->type != Node_func)
+                       fatal(_("bind_array: function `%s' is not defined"), 
val->stptr);
+               aq->func[i] = f;
+       }
+
+       /* copy the array -- this is passed as the second argument to the 
functions */
+       emalloc(aname, char *, strlen(t->vname) + 2, "do_bind_array");
+       aname[0] = '~';         /* any illegal character */
+       strcpy(& aname[1], symbol->vname);
+       td = make_array();
+       td->vname = aname;
+       assoc_copy(t, td);
+       aq->arg0 = td;
+
+       /* internal array for the actual storage */
+       xn = make_array();
+       xn->vname = symbol->vname;      /* shallow copy */
+       xn->flags |= XARRAY;
+       symbol->a_opaque = aq;
+       symbol->array_funcs = bind_array_func;
+       symbol->xarray = xn;
+
+       if (aq->func[INIT] != NULL)
+               (void) array_func_call(symbol, NULL, INIT);
+
+       return make_number(0);
+}
+
+/* do_unbind_array --- unbind an array */
+
+static NODE *
+do_unbind_array(int nargs)
+{
+       NODE *symbol, *xn, *td;
+       array_t *aq;
+
+       symbol = get_array_argument(0, FALSE);
+       if (symbol->array_funcs != bind_array_func)
+               fatal(_("unbind_array: `%s' is not a bound array"), 
array_vname(symbol));
+
+       aq = symbol->a_opaque;
+       if (aq->func[FINI] != NULL)
+               (void) array_func_call(symbol, NULL, FINI);
+
+       td = aq->arg0;
+       assoc_clear(td);
+       efree(td->vname);
+       freenode(td);
+       efree(aq);
+
+       /* promote xarray to symbol */
+       xn = symbol->xarray;
+       xn->flags &= ~XARRAY;
+       xn->parent_array = symbol->parent_array;
+       *symbol = *xn;
+       freenode(xn);
+
+       return make_number(0);  
+}
+
+
+/* call_func --- call a user-defined gawk function */
+
+static NODE *
+call_func(NODE *func, NODE **arg, int arg_count)
+{
+       NODE *ret;
+       INSTRUCTION *code;
+       extern int currule;
+       int i, save_rule = 0;
+
+       if (arg_count > func->param_cnt)
+               fatal(_("function `%s' called with too many parameters"), 
func->vname);
+
+       /* make function call instructions */
+       code = bcalloc(Op_func_call, 2, 0);
+       code->func_body = func;
+       code->func_name = NULL;         /* not needed, func_body already 
assigned */
+       (code + 1)->expr_count = arg_count;
+       code->nexti = bcalloc(Op_stop, 1, 0);
+
+       save_rule = currule;    /* save current rule */
+       currule = 0;
+
+       /* push arguments onto stack */
+       for (i = 0; i < arg_count; i++) {
+               if (arg[i]->type == Node_val)
+                       UPREF(arg[i]);
+               PUSH(arg[i]);
+       }
+
+       /* execute the function */
+       (void) interpret(code);
+
+       ret = POP_SCALAR();     /* the return value of the function */
+
+       /* restore current rule */
+       currule = save_rule;
+
+       /* free code */
+       bcfree(code->nexti);
+       bcfree(code);
+
+       return ret;
+}
+
+
+/* dlload --- load this library */
+
+NODE *
+dlload(NODE *obj, void *dl)
+{
+       make_builtin("bind_array", do_bind_array, 2);
+       make_builtin("unbind_array", do_unbind_array, 1);
+       return make_number((AWKNUM) 0);
+}
diff --git a/extension/dbarray.awk b/extension/dbarray.awk
new file mode 100644
index 0000000..e0a3c09
--- /dev/null
+++ b/extension/dbarray.awk
@@ -0,0 +1,222 @@
+# dbarray.awk -- persistent array with sqlite database backend
+
+# @load "bindarr"
+
+BEGIN {
+       extension("bindarr")
+}
+
+function _db_count(symbol, sq,
+               sth, ret, count)
+{
+       sth = sq["sqlc"]
+       printf "SELECT count(col1) FROM %s;\n", sq["table"] |& sth
+       close(sth, "to")
+       ret = (sth |& getline count)
+       if (close(sth) != 0 || ret <= 0)
+               return -1
+       return count
+}
+
+function _db_exists(symbol, sq, subs,
+               sth, ret, row, qsubs)
+{
+       if (! (subs in symbol)) {
+               sth = sq["sqlc"]
+
+               # double up single quotes
+               qsubs = gensub(/'/, "''", "g", subs)
+
+               printf "SELECT col2 FROM %s WHERE col1='%s';\n", sq["table"], 
qsubs |& sth
+               close(sth, "to")
+               ret = (sth |& getline row)
+               if (close(sth) != 0 || ret < 0)
+                       return -1
+               if (ret == 0)   # non-existent row
+                       return 0
+               if (row == sq["null"])
+                       symbol[subs]    # install null string as value
+               else
+                       symbol[subs] = row
+       }
+       return 0
+}
+
+function _db_lookup(symbol, sq, subs,
+               sth, ret, row, qsubs)
+{
+       if (! (subs in symbol)) {
+               sth = sq["sqlc"]
+
+               # double up single quotes
+               qsubs = gensub(/'/, "''", "g", subs)
+
+               printf "SELECT col2 FROM %s WHERE col1='%s';\n", sq["table"], 
qsubs |& sth
+               close(sth, "to")
+               ret = (sth |& getline row)
+               if (close(sth) != 0 || ret < 0)
+                       return -1
+
+               if (ret > 0) {
+                       if (row == sq["null"])
+                               symbol[subs]    # install null string as value
+                       else
+                               symbol[subs] = row
+               } else {
+                       # Not there, install it with NULL as value
+                       printf "INSERT INTO %s (col1) VALUES('%s');\n", 
sq["table"], qsubs |& sth
+                       close(sth, "to")
+                       ret = (sth |& getline)
+                       if (close(sth) != 0 || ret < 0)
+                               return -1
+               }
+       }
+       return 0
+}
+
+function _db_clear(symbol, sq,
+               sth, ret)
+{
+       sth = sq["sqlc"]
+       printf "DELETE FROM %s;\n", sq["table"] |& sth
+       close(sth, "to")
+       ret = (sth |& getline)
+       if (close(sth) != 0 || ret < 0)
+               return -1
+       return 0
+}
+
+function _db_delete(symbol, sq, subs,
+               sth, ret, qsubs)
+{
+       sth = sq["sqlc"]
+       qsubs = gensub(/'/, "''", "g", subs)
+       printf "DELETE FROM %s WHERE col1='%s';\n", sq["table"], qsubs |& sth
+       close(sth, "to")
+       ret = (sth |& getline)
+       if (close(sth) != 0 || ret < 0)
+               return -1
+       return 0
+}
+
+function _db_store(symbol, sq, subs,
+               sth, ret, qsubs, qval)
+{
+       sth = sq["sqlc"]
+
+       qval = gensub(/'/, "''", "g", symbol[subs])
+       qsubs = gensub(/'/, "''", "g", subs)
+       printf "UPDATE %s SET col2='%s' WHERE col1='%s';\n", \
+                       sq["table"], qval, qsubs |& sth
+       close(sth, "to")
+       ret = (sth |& getline)
+       if (close(sth) != 0 || ret < 0)
+               return -1
+       return 0
+}
+
+function _db_fetchall(symbol, sq,
+               sth, ret, save_RS, save_FS)
+{
+       sth = sq["sqlc2"]
+
+       if (! sq["loaded"]) {
+               printf "SELECT col1, col2 FROM %s;\n", sq["table"] |& sth
+               close(sth, "to")
+               save_RS = RS
+               save_FS = FS
+               RS = "\n\n"
+               FS = "\n"
+               while ((ret = (sth |& getline)) > 0) {
+                       sub(/^ *col1 = /, "", $1)
+                       sub(/^ *col2 = /, "", $2)
+                       if ($2 == sq["null"])
+                               symbol[$1]      # install null string as value
+                       else
+                               symbol[$1] = $2
+               }
+               RS = save_RS
+               FS = save_FS
+               if (ret < 0 || close(sth) != 0)
+                       return -1
+               sq["loaded"] = 1
+       }
+}
+
+
+function _db_init(symbol, sq,
+               sth, table, ret)
+{
+       sth = sq["sqlc"]
+       table = sq["table"]
+
+       # check if table exists
+       printf ".tables %s\n", table |& sth
+       close(sth, "to")
+       ret = (sth |& getline)
+       if (close(sth) != 0 || ret < 0)
+               return -1
+       if (ret > 0 && $0 == table) {
+               # verify schema
+               printf ".schema %s\n", table |& sth
+               close(sth, "to")
+               ret = (sth |& getline)
+               if (close(sth) != 0 || ret <= 0)
+                       return -1
+               if ($0 !~ /\(col1 TEXT PRIMARY KEY, col2 TEXT\)/) {
+                       printf "table %s: Invalid column name or type(s)\n", 
table > "/dev/stderr"
+                       return -1
+               }
+       } else {
+               # table does not exist, create it.
+               printf "CREATE TABLE %s (col1 TEXT PRIMARY KEY, col2 TEXT);\n", 
table |& sth
+               close(sth, "to")
+               ret = (sth |& getline)
+               if (close(sth) != 0 || ret < 0)
+                       return -1
+       }
+       return 0
+}
+
+#function _db_fini(tie, a, subs) {}
+
+function db_bind(arr, database, table,         sq)
+{
+       if (! database) {
+               print "db_bind: must specify a database name" > "/dev/stderr"
+               exit(1)
+       }
+
+       if (! table) {
+               print "db_bind: must specify a table name" > "/dev/stderr"
+               exit(1)
+       }
+
+       # string used by the sqlite3 client to represent NULL
+       sq["null"] = "(null)"
+
+       sq["sqlc"] = sprintf("sqlite3 -nullvalue '%s' %s", sq["null"], database)
+       # sqlite command used in _db_fetchall 
+       sq["sqlc2"] = sprintf("sqlite3 -line -nullvalue '%s' %s", sq["null"], 
database)
+
+       sq["table"] = table
+
+       # register our array routines
+       sq["init"] = "_db_init"
+       sq["count"] = "_db_count"
+       sq["exists"] = "_db_exists"
+       sq["lookup"] = "_db_lookup"
+       sq["delete"] = "_db_delete"
+       sq["store"] = "_db_store"
+       sq["clear"] = "_db_clear"
+       sq["fetchall"] = "_db_fetchall"
+
+#      sq["fini"] = "_db_fini";
+
+       bind_array(arr, sq)
+}
+
+function db_unbind(arr)
+{
+       unbind_array(arr)
+}
diff --git a/extension/steps b/extension/steps
index 0cd0042..1abab9d 100755
--- a/extension/steps
+++ b/extension/steps
@@ -15,6 +15,7 @@ gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. 
testarg.c
 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
 ld -o dl.so -shared dl.o
 ld -o filefuncs.so -shared filefuncs.o
 ld -o fork.so -shared fork.o
@@ -24,3 +25,4 @@ ld -o readfile.so -shared readfile.o
 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
diff --git a/extension/testdbarray.awk b/extension/testdbarray.awk
new file mode 100644
index 0000000..fd7fd59
--- /dev/null
+++ b/extension/testdbarray.awk
@@ -0,0 +1,21 @@
address@hidden "dbarray.awk"
+
+# $ ../gawk -f testdbarray.awk
+# $ ../gawk -f testdbarray.awk
+# ...
+# $ ../gawk -vINIT=1 -f testdbarray.awk
+
+
+BEGIN {
+       # bind array 'A' to the table 'table_A' in sqlite3 database 'testdb'
+       db_bind(A, "testdb", "table_A")
+
+       if (INIT)       # detele table and start over
+               delete A
+
+       lenA = length(A)
+       A[++lenA] = strftime()
+       PROCINFO["sorted_in"] = "@ind_num_asc"
+       for (item in A)
+               print item, ":", A[item]
+}
diff --git a/int_array.c b/int_array.c
index 7b8b261..1f19b14 100644
--- a/int_array.c
+++ b/int_array.c
@@ -425,6 +425,7 @@ int_copy(NODE *symbol, NODE *newsymb)
                        }
 
                        *pnew = newchain;
+                       newchain->ainext = NULL;
                        pnew = & newchain->ainext;
                }
        }       
diff --git a/po/da.gmo b/po/da.gmo
index df6ac1b..0f945fd 100644
Binary files a/po/da.gmo and b/po/da.gmo differ
diff --git a/po/da.po b/po/da.po
index b988b63..3c9d02d 100644
--- a/po/da.po
+++ b/po/da.po
@@ -14,10 +14,10 @@ msgstr ""
 "PO-Revision-Date: 2012-02-06 10:37+0100\n"
 "Last-Translator: Keld Simonsen <address@hidden>\n"
 "Language-Team: Danish <address@hidden>\n"
-"Language: da\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: da\n"
 "X-Generator: Lokalize 1.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
@@ -1032,8 +1032,8 @@ msgstr "atalt: extension: kan ikke 
 msgid ""
 "extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
 msgstr ""
-"fatalt: extension: bibliotek '%s': definer ikke "
-"'plugin_is_GPL_compatible' (%s)\n"
+"fatalt: extension: bibliotek '%s': definer ikke 'plugin_is_GPL_compatible' (%"
+"s)\n"
 
 #: ext.c:91
 #, fuzzy, c-format
diff --git a/po/de.gmo b/po/de.gmo
index 2a17fa9..f5dbae9 100644
Binary files a/po/de.gmo and b/po/de.gmo differ
diff --git a/po/de.po b/po/de.po
index 20dcb88..05ac454 100644
--- a/po/de.po
+++ b/po/de.po
@@ -12,10 +12,10 @@ msgstr ""
 "PO-Revision-Date: 2012-01-30 16:21+0100\n"
 "Last-Translator: Philipp Thomas <address@hidden>\n"
 "Language-Team: German <address@hidden>\n"
-"Language: de\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
 
 #: array.c:267
 #, c-format
@@ -129,8 +129,8 @@ msgstr "»%s« ist eine eingebaute Funktion und kann nicht 
umdefiniert werden"
 #: awkgram.y:389
 msgid "regexp constant `//' looks like a C++ comment, but is not"
 msgstr ""
-"Die Regulärer-Ausdruck-Konstante »//« sieht wie ein C-Kommentar aus, ist "
-"aber keiner"
+"Die Regulärer-Ausdruck-Konstante »//« sieht wie ein C-Kommentar aus, ist 
aber "
+"keiner"
 
 #: awkgram.y:393
 #, c-format
@@ -467,8 +467,8 @@ msgstr "Funktion »%s«: Funktionsnamen können nicht als 
Parameternamen benutze
 #, c-format
 msgid "function `%s': can't use special variable `%s' as a function parameter"
 msgstr ""
-"Funktion »%s«: die spezielle Variable »%s« kann nicht als Parameter "
-"verwendet werden"
+"Funktion »%s«: die spezielle Variable »%s« kann nicht als Parameter 
verwendet "
+"werden"
 
 #: awkgram.y:4055
 #, c-format
@@ -538,8 +538,7 @@ msgstr ""
 #, c-format
 msgid "fflush: cannot flush: file `%s' opened for reading, not writing"
 msgstr ""
-"fflush: Leeren der Puffer nicht möglich, Datei »%s« ist nur zum Lesen "
-"geöffnet"
+"fflush: Leeren der Puffer nicht möglich, Datei »%s« ist nur zum Lesen 
geöffnet"
 
 #: builtin.c:217
 #, c-format
@@ -1283,8 +1282,7 @@ msgstr "%s: Die Option »-W %s« erfordert ein Argument\n"
 #: io.c:315
 #, c-format
 msgid "command line argument `%s' is a directory: skipped"
-msgstr ""
-"das Kommandozeilen-Argument »%s« ist ein Verzeichnis: wird übersprungen"
+msgstr "das Kommandozeilen-Argument »%s« ist ein Verzeichnis: wird 
übersprungen"
 
 #: io.c:318 io.c:421
 #, c-format
@@ -1383,8 +1381,8 @@ msgstr "»close« für eine Umlenkung, die nie geöffnet 
wurde"
 #, c-format
 msgid "close: redirection `%s' not opened with `|&', second argument ignored"
 msgstr ""
-"close: Umlenkung »%s« wurde nicht mit »[&« geöffnet, das zweite Argument 
"
-"wird ignoriert"
+"close: Umlenkung »%s« wurde nicht mit »[&« geöffnet, das zweite Argument 
wird "
+"ignoriert"
 
 #: io.c:1105
 #, c-format
@@ -2036,14 +2034,12 @@ msgstr "redir2str: unbekannter Umlenkungstyp %d"
 #: re.c:573
 #, c-format
 msgid "range of the form `[%c-%c]' is locale dependent"
-msgstr ""
-"Ein Bereich in der Form »[%c-%c]« ist abhängig von der gesetzten Locale"
+msgstr "Ein Bereich in der Form »[%c-%c]« ist abhängig von der gesetzten 
Locale"
 
 #: re.c:600
 #, c-format
 msgid "regexp component `%.*s' should probably be `[%.*s]'"
-msgstr ""
-"Regulärer-Ausdruck-Komponente »%.*s« sollte wahrscheinlich »[%.*s]« sein"
+msgstr "Regulärer-Ausdruck-Komponente »%.*s« sollte wahrscheinlich 
»[%.*s]« sein"
 
 #: regcomp.c:131
 msgid "Success"
diff --git a/po/es.gmo b/po/es.gmo
index 29c36a3..61ae2c6 100644
Binary files a/po/es.gmo and b/po/es.gmo differ
diff --git a/po/es.po b/po/es.po
index 2c1ab61..e504e6c 100644
--- a/po/es.po
+++ b/po/es.po
@@ -11,10 +11,10 @@ msgstr ""
 "PO-Revision-Date: 2012-01-30 07:42-0600\n"
 "Last-Translator: Cristian Othón Martínez Vera <address@hidden>\n"
 "Language-Team: Spanish <address@hidden>\n"
-"Language: es\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: es\n"
 
 #: array.c:267
 #, c-format
@@ -1053,15 +1053,15 @@ msgstr "fatal: extension: no se puede abrir `%s' (%s)\n"
 msgid ""
 "extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"
 msgstr ""
-"fatal: extension: la biblioteca `%s': no define "
-"`plugin_is_GPL_compatible' (%s)\n"
+"fatal: extension: la biblioteca `%s': no define `plugin_is_GPL_compatible' (%"
+"s)\n"
 
 #: ext.c:91
 #, fuzzy, c-format
 msgid "extension: library `%s': cannot call function `%s' (%s)\n"
 msgstr ""
-"fatal: extension: la biblioteca `%s': no puede llamar a la función `"
-"%s' (%s)\n"
+"fatal: extension: la biblioteca `%s': no puede llamar a la función `%s' (%"
+"s)\n"
 
 #: ext.c:119
 msgid "extension: missing function name"
@@ -1494,8 +1494,8 @@ msgstr "falló al cerrar la entrada estándar en el hijo 
(%s)"
 #, c-format
 msgid "moving slave pty to stdin in child failed (dup: %s)"
 msgstr ""
-"falló el movimiento del pty esclavo a la entrada estándar en el hijo (dup: "
-"%s)"
+"falló el movimiento del pty esclavo a la entrada estándar en el hijo (dup: 
%"
+"s)"
 
 #: io.c:1795 io.c:1816
 #, c-format
diff --git a/po/fi.gmo b/po/fi.gmo
index a556e9b..a7fd6b8 100644
Binary files a/po/fi.gmo and b/po/fi.gmo differ
diff --git a/po/fi.po b/po/fi.po
index 46a1042..b9bee74 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -11,10 +11,10 @@ msgstr ""
 "PO-Revision-Date: 2012-03-13 18:00+0200\n"
 "Last-Translator: Jorma Karvonen <address@hidden>\n"
 "Language-Team: Finnish <address@hidden>\n"
-"Language: fi\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: fi\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #: array.c:267
diff --git a/str_array.c b/str_array.c
index c6b33c6..a38562c 100644
--- a/str_array.c
+++ b/str_array.c
@@ -332,6 +332,7 @@ str_copy(NODE *symbol, NODE *newsymb)
                        newchain->ahcode = chain->ahcode;
 
                        *pnew = newchain;
+                       newchain->ahnext = NULL;
                        pnew = & newchain->ahnext;
                }
        }       

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

Summary of changes:
 ChangeLog                 |    6 +
 extension/ChangeLog       |    5 +
 extension/bindarr.c       |  339 +++++++++++++++++++++++++++++++++++++++++++++
 extension/dbarray.awk     |  222 +++++++++++++++++++++++++++++
 extension/steps           |    2 +
 extension/testdbarray.awk |   21 +++
 int_array.c               |    1 +
 po/da.gmo                 |  Bin 46123 -> 46123 bytes
 po/da.po                  |    6 +-
 po/de.gmo                 |  Bin 49358 -> 49358 bytes
 po/de.po                  |   26 ++--
 po/es.gmo                 |  Bin 48746 -> 48746 bytes
 po/es.po                  |   14 +-
 po/fi.gmo                 |  Bin 48930 -> 48930 bytes
 po/fi.po                  |    2 +-
 str_array.c               |    1 +
 16 files changed, 619 insertions(+), 26 deletions(-)
 create mode 100644 extension/bindarr.c
 create mode 100644 extension/dbarray.awk
 create mode 100644 extension/testdbarray.awk


hooks/post-receive
-- 
gawk



reply via email to

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