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. 6d1724214a95330b63a6a5


From: Arnold Robbins
Subject: [gawk-diffs] [SCM] gawk branch, extgawk, updated. 6d1724214a95330b63a6a557f89fb9b40b4a521f
Date: Wed, 11 Jul 2012 18:27:47 +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  6d1724214a95330b63a6a557f89fb9b40b4a521f (commit)
      from  e33b672ff4ab1b7469355a79eaf4c4740f412e45 (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=6d1724214a95330b63a6a557f89fb9b40b4a521f

commit 6d1724214a95330b63a6a557f89fb9b40b4a521f
Author: Arnold D. Robbins <address@hidden>
Date:   Wed Jul 11 21:26:37 2012 +0300

    API clean up and require strings to be malloced.

diff --git a/ChangeLog b/ChangeLog
index 759daaa..2429bd8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2012-07-11         Arnold D. Robbins     <address@hidden>
+
+       Lots of API work.
+
+       * gawkapi.h: Function pointer members renamed api_XXXX and
+       macros adjusted. More documentation.
+       (awk_valtype_t): New AWK_SCALAR enum for scalar cookies.
+       (awk_scalar_t): New type.
+       (awk_value_t): New member scalar_cookie.
+       (api_sym_update_scalar): New API function.
+       (erealloc): New macro.
+       (make_const_string): New macro, renamed from dup_string.
+       (make_malloced_string): New macro, renamed from make_string.
+       (make_null_string): New inline function.
+
+       * gawkapi.c (awk_value_to_node): Assume that string values came
+       from malloc.
+       (node_to_awk_value): Handle AWK_SCALAR.
+       (api_sym_update): Ditto.
+       (api_sym_update_scalar): New routine.
+       (api_get_array_element): Return false if the element doesn't exist.
+       Always unref the subscript.
+       (remove_element): New helper routine.
+       (api_del_array_element): Use it.
+       (api_release_flattened_array): Ditto.
+       (api_impl): Add the new routine.
+
 2012-07-11         Andrew J. Schorr     <address@hidden>
 
        * gawkapi.c (api_sym_update): Allow val_type to be AWK_UNDEFINED
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 7e61fc5..be31561 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,14 @@
+2012-07-11         Arnold D. Robbins     <address@hidden>
+
+       * filefuncs.c (array_set, do_stat): Use make_const_string.
+       * fork.c (array_set_numeric): Ditto.
+       * ordchr.c (do_chr): Ditto.
+       * readfile.c (do_readfile): Use make_null_string, make_malloced_string.
+       * rwarray.c (read_elem): Ditto.
+       * testext.c (valrep2str): Add case for AWK_SCALAR.
+       (test_array_elem): Duplicate strings coming from gawk before passing
+       them back in.
+
 2012-07-09         Arnold D. Robbins     <address@hidden>
 
        * filefuncs.c (do_readfile): Return "" and set ERRNO on error
diff --git a/extension/filefuncs.c b/extension/filefuncs.c
index 32a3cee..74af8b1 100644
--- a/extension/filefuncs.c
+++ b/extension/filefuncs.c
@@ -214,7 +214,7 @@ array_set(awk_array_t array, const char *sub, awk_value_t 
*value)
        awk_value_t index;
 
        set_array_element(array,
-                       make_string(sub, strlen(sub), & index),
+                       make_const_string(sub, strlen(sub), & index),
                        value);
 
 }
@@ -292,7 +292,7 @@ do_stat(int nargs, awk_value_t *result)
        }
 
        /* fill in the array */
-       array_set(array, "name", make_string(name, file_param.str_value.len, 
&tmp));
+       array_set(array, "name", make_const_string(name, 
file_param.str_value.len, &tmp));
        array_set_numeric(array, "dev", sbuf.st_dev);
        array_set_numeric(array, "ino", sbuf.st_ino);
        array_set_numeric(array, "mode", sbuf.st_mode);
@@ -317,7 +317,7 @@ do_stat(int nargs, awk_value_t *result)
 #endif /* HAVE_ST_BLKSIZE */
 
        pmode = format_mode(sbuf.st_mode);
-       array_set(array, "pmode", make_string(pmode, strlen(pmode), & tmp));
+       array_set(array, "pmode", make_const_string(pmode, strlen(pmode), & 
tmp));
 
        /* for symbolic links, add a linkval field */
        if (S_ISLNK(sbuf.st_mode)) {
@@ -326,7 +326,7 @@ do_stat(int nargs, awk_value_t *result)
 
                if ((buf = read_symlink(name, sbuf.st_size,
                                        & linksize)) != NULL)
-                       array_set(array, "linkval", make_string(buf, linksize, 
& tmp));
+                       array_set(array, "linkval", make_malloced_string(buf, 
linksize, & tmp));
                else
                        warning(ext_id, "stat: unable to read symbolic link 
`%s'", name);
        }
@@ -340,7 +340,7 @@ do_stat(int nargs, awk_value_t *result)
                }
        }
 
-       array_set(array, "type", make_string(type, strlen(type), &tmp));
+       array_set(array, "type", make_const_string(type, strlen(type), &tmp));
 
        ret = 1;        /* success */
 
diff --git a/extension/fork.c b/extension/fork.c
index efad17e..8423266 100644
--- a/extension/fork.c
+++ b/extension/fork.c
@@ -53,7 +53,7 @@ array_set_numeric(awk_array_t array, const char *sub, double 
num)
        awk_value_t index, value;
 
        set_array_element(array,
-               make_string(sub, strlen(sub), & index),
+               make_const_string(sub, strlen(sub), & index),
                make_number(num, & value));
 
 }
diff --git a/extension/ordchr.c b/extension/ordchr.c
index 8d7eac8..3ab0f87 100644
--- a/extension/ordchr.c
+++ b/extension/ordchr.c
@@ -103,7 +103,7 @@ do_chr(int nargs, awk_value_t *result)
        }
 
        /* Set the return value */
-       return dup_string(str, 1, result);
+       return make_const_string(str, 1, result);
 }
 
 static awk_ext_func_t func_table[] = {
diff --git a/extension/readfile.c b/extension/readfile.c
index 56bdcbc..1b6772f 100644
--- a/extension/readfile.c
+++ b/extension/readfile.c
@@ -65,7 +65,7 @@ do_readfile(int nargs, awk_value_t *result)
        int fd;
 
        assert(result != NULL);
-       make_string("", 0, result);     /* default return value */
+       make_null_string(result);       /* default return value */
 
        if (do_lint && nargs > 1)
                lintwarn(ext_id, "readfile: called with too many arguments");
@@ -98,7 +98,7 @@ do_readfile(int nargs, awk_value_t *result)
                }
 
                close(fd);
-               make_string(text, sbuf.st_size, result);
+               make_malloced_string(text, sbuf.st_size, result);
                goto done;
        } else if (do_lint)
                lintwarn(ext_id, "readfile: called with no arguments");
diff --git a/extension/rwarray.c b/extension/rwarray.c
index a63fa3d..64c501d 100644
--- a/extension/rwarray.c
+++ b/extension/rwarray.c
@@ -394,9 +394,9 @@ read_elem(int fd, awk_element_t *element)
                if (read(fd, buffer, index_len) != (ssize_t) index_len) {
                        return 0;
                }
-               make_string(buffer, index_len, & element->index);
+               make_const_string(buffer, index_len, & element->index);
        } else {
-               make_string("", 0, & element->index);
+               make_null_string(& element->index);
        }
 
        if (! read_value(fd, & element->value))
diff --git a/extension/testext.c b/extension/testext.c
index e54055c..8dac1c2 100644
--- a/extension/testext.c
+++ b/extension/testext.c
@@ -59,6 +59,9 @@ valrep2str(const awk_value_t *value)
        case AWK_ARRAY:
                strcpy(buf, "<array>");
                break;
+       case AWK_SCALAR:
+               strcpy(buf, "<scalar>");
+               break;
        case AWK_STRING:
                if (value->str_value.len < size)
                        size = value->str_value.len;
@@ -334,7 +337,7 @@ BEGIN {
 static awk_value_t *
 test_array_elem(int nargs, awk_value_t *result)
 {
-       awk_value_t array, index, value;
+       awk_value_t array, index, index2, value;
 
        make_number(0.0, result);       /* default return until full success */
 
@@ -354,7 +357,8 @@ test_array_elem(int nargs, awk_value_t *result)
                printf("test_array_elem: get_argument 1 (index) failed\n");
                goto out;
        }
-       if (! get_array_element(array.array_cookie, & index, AWK_UNDEFINED, & 
value)) {
+       (void) make_const_string(index.str_value.str, index.str_value.len, & 
index2);
+       if (! get_array_element(array.array_cookie, & index2, AWK_UNDEFINED, & 
value)) {
                printf("test_array_elem: get_array_element failed\n");
                goto out;
        }
@@ -365,28 +369,29 @@ test_array_elem(int nargs, awk_value_t *result)
 
        /* change the element - "3" */
        (void) make_number(42.0, & value);
-       if (! set_array_element(array.array_cookie, & index, & value)) {
+       (void) make_const_string(index.str_value.str, index.str_value.len, & 
index2);
+       if (! set_array_element(array.array_cookie, & index2, & value)) {
                printf("test_array_elem: set_array_element failed\n");
                goto out;
        }
 
        /* delete another element - "5" */
-       (void) make_string("5", 1, & index);
+       (void) make_const_string("5", 1, & index);
        if (! del_array_element(array.array_cookie, & index)) {
                printf("test_array_elem: del_array_element failed\n");
                goto out;
        }
 
        /* add a new element - "7" */
-       (void) make_string("7", 1, & index);
-       (void) make_string("seven", 5, & value);
+       (void) make_const_string("7", 1, & index);
+       (void) make_const_string("seven", 5, & value);
        if (! set_array_element(array.array_cookie, & index, & value)) {
                printf("test_array_elem: set_array_element failed\n");
                goto out;
        }
 
        /* add a subarray */
-       (void) make_string("subarray", 8, & index);
+       (void) make_const_string("subarray", 8, & index);
        fill_in_array(& value);
        if (! set_array_element(array.array_cookie, & index, & value)) {
                printf("test_array_elem: set_array_element (subarray) 
failed\n");
@@ -488,14 +493,14 @@ fill_in_array(awk_value_t *new_array)
 
        a_cookie = create_array();
 
-       (void) make_string("hello", 5, & index);
-       (void) make_string("world", 5, & value);
+       (void) make_const_string("hello", 5, & index);
+       (void) make_const_string("world", 5, & value);
        if (! set_array_element(a_cookie, & index, & value)) {
                printf("fill_in_array:%d: set_array_element failed\n", 
__LINE__);
                return;
        }
 
-       (void) make_string("answer", 6, & index);
+       (void) make_const_string("answer", 6, & index);
        (void) make_number(42.0, & value);
        if (! set_array_element(a_cookie, & index, & value)) {
                printf("fill_in_array:%d: set_array_element failed\n", 
__LINE__);
@@ -620,7 +625,8 @@ BEGIN {
        if (! sym_update("answer_num", make_number(42, & value)))
                printf("testext: sym_update(\"answer_num\") failed!\n");
 
-       if (! sym_update("message_string", dup_string(message, strlen(message), 
& value)))
+       if (! sym_update("message_string",
+                       make_const_string(message, strlen(message), & value)))
                printf("testext: sym_update(\"answer_num\") failed!\n");
 
        create_new_array();
diff --git a/gawkapi.c b/gawkapi.c
index 3fa3e3b..c5f8953 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -140,8 +140,8 @@ awk_value_to_node(const awk_value_t *retval)
        } else if (retval->val_type == AWK_NUMBER) {
                ext_ret_val = make_number(retval->num_value);
        } else {
-               ext_ret_val = make_string(retval->str_value.str,
-                               retval->str_value.len);
+               ext_ret_val = make_str_node(retval->str_value.str,
+                               retval->str_value.len, ALREADY_MALLOCED);
        }
 
        return ext_ret_val;
@@ -317,6 +317,14 @@ node_to_awk_value(NODE *node, awk_value_t *val, 
awk_valtype_t wanted)
                break;
 
        case Node_var:
+               /* a scalar value */
+               if (wanted == AWK_SCALAR) {
+                       val->val_type = AWK_SCALAR;
+                       val->scalar_cookie = (void *) node;
+                       ret = true;
+                       break;
+               }
+
                node = node->var_value;
                /* FALL THROUGH */
        case Node_val:
@@ -343,6 +351,16 @@ node_to_awk_value(NODE *node, awk_value_t *val, 
awk_valtype_t wanted)
                        }
                        break;
 
+               case AWK_SCALAR:
+                       if (node->flags & NUMBER) {
+                               val->val_type = AWK_NUMBER;
+                       } else if (node->flags & STRING) {
+                               val->val_type = AWK_STRING;
+                       } else
+                               val->val_type = AWK_UNDEFINED;
+                       ret = false;
+                       break;
+
                case AWK_UNDEFINED:
                        /* return true and actual type for request of undefined 
*/
                        if (node->flags & NUMBER) {
@@ -466,6 +484,9 @@ api_sym_update(awk_ext_id_t id, const char *name, 
awk_value_t *value)
 
        /* if we get here, then it exists already */
        switch (value->val_type) {
+       case AWK_SCALAR:
+               return false;
+
        case AWK_STRING:
        case AWK_NUMBER:
        case AWK_UNDEFINED:
@@ -484,6 +505,33 @@ api_sym_update(awk_ext_id_t id, const char *name, 
awk_value_t *value)
        return true;
 }
 
+/* api_sym_update_scalar --- update a scalar cookie */
+
+static awk_bool_t
+api_sym_update_scalar(awk_ext_id_t id,
+                       awk_scalar_t cookie,
+                       awk_value_t *value)
+{
+       NODE *node = (NODE *) cookie;
+       NODE *new_value;
+
+       if (value == NULL
+           || node == NULL
+           || node->type != Node_var)
+               return false;
+
+       new_value = awk_value_to_node(value);
+       if (new_value->type != Node_val) {
+               unref(new_value);
+               return false;
+       }
+
+       unref(node->var_value);
+       node->var_value = new_value;
+
+       return true;
+}
+
 /* Array management */
 /*
  * Return the value of an element - read only!
@@ -510,10 +558,21 @@ api_get_array_element(awk_ext_id_t id,
                return false;
 
        subscript = awk_value_to_node(index);
+
+       /* if it doesn't exist, return false */
+       if (in_array(array, subscript) == NULL) {
+               unref(subscript);
+               return false;
+       }
+
        aptr = assoc_lookup(array, subscript);
-       unref(subscript);
-       if (aptr == NULL)
+
+       if (aptr == NULL) {     /* can't happen */
+               unref(subscript);
                return false;
+       }
+
+       unref(subscript);
 
        return node_to_awk_value(*aptr, result, wanted);
 }
@@ -556,6 +615,32 @@ api_set_array_element(awk_ext_id_t id, awk_array_t 
a_cookie,
 }
 
 /*
+ * remove_element --- remove an array element 
+ *             common code used by multiple functions
+ */
+
+static void
+remove_element(NODE *array, NODE *subscript)
+{
+       NODE *val;
+
+       val = in_array(array, subscript);
+
+       if (val == NULL)
+               return;
+
+       if (val->type == Node_var_array) {
+               assoc_clear(val);
+               /* cleared a sub-array, free Node_var_array */
+               efree(val->vname);
+               freenode(val);
+       } else
+               unref(val);
+
+       (void) assoc_remove(array, subscript);
+}
+
+/*
  * Remove the element with the given index.
  * Returns success if removed or if element did not exist.
  */
@@ -563,7 +648,7 @@ static awk_bool_t
 api_del_array_element(awk_ext_id_t id,
                awk_array_t a_cookie, const awk_value_t* const index)
 {
-       NODE *array, *sub, *val;
+       NODE *array, *sub;
 
        array = (NODE *) a_cookie;
        if (   array == NULL
@@ -573,20 +658,7 @@ api_del_array_element(awk_ext_id_t id,
                return false;
 
        sub = awk_value_to_node(index);
-       val = in_array(array, sub);
-
-       if (val == NULL)
-               return false;
-
-       if (val->type == Node_var_array) {
-               assoc_clear(val);
-               /* cleared a sub-array, free Node_var_array */
-               efree(val->vname);
-               freenode(val);
-       } else
-               unref(val);
-
-       (void) assoc_remove(array, sub);
+       remove_element(array, sub);
        unref(sub);
 
        return true;
@@ -698,7 +770,7 @@ api_release_flattened_array(awk_ext_id_t id,
 {
        NODE *array = a_cookie;
        NODE **list;
-       size_t i;
+       size_t i, j, k;
 
        if (   array == NULL
            || array->type != Node_var_array
@@ -710,17 +782,12 @@ api_release_flattened_array(awk_ext_id_t id,
 
        list = (NODE **) data->opaque2;
 
-       /* Delete items flagged for delete. */
-       for (i = 0; i < data->count; i++) {
-               if ((data->elements[i].flags & AWK_ELEMENT_DELETE) != 0) {
-                       /* let the other guy do the work */
-                       (void) api_del_array_element(id, a_cookie,
-                                       & data->elements[i].index);
-               }
-       }
-
        /* free index nodes */
-       for (i = 0; i < 2 * array->table_size; i += 2) {
+       for (i = j = 0, k = 2 * array->table_size; i < k; i += 2, j++) {
+               /* Delete items flagged for delete. */
+               if ((data->elements[j].flags & AWK_ELEMENT_DELETE) != 0) {
+                       remove_element(array, list[i]);
+               }
                unref(list[i]);
        }
 
@@ -754,6 +821,7 @@ gawk_api_t api_impl = {
 
        api_sym_lookup,
        api_sym_update,
+       api_sym_update_scalar,
 
        api_get_array_element,
        api_set_array_element,
diff --git a/gawkapi.h b/gawkapi.h
index 5be5ea0..2bef258 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -42,6 +42,26 @@
  * functions. If your compiler doesn't support it, you should either
  * -Dinline='' on your command line, or use the autotools and include a
  * config.h in your extensions.
+ *
+ * Additional important information:
+ *
+ * 1. ALL string values in awk_value_t objects need to come from malloc().
+ * Gawk will handle releasing the storage if necessary.  This is slightly
+ * awkward, in that you can't take an awk_value_t that you got from gawk
+ * and reuse it directly, even for something that is conceptually pass
+ * by value.
+ *
+ * 2. The correct way to create new arrays is to work "bottom up".
+ *
+ *     new_array = create_array();
+ *     // fill in new array with lots of subscripts and values
+ *     val.val_type = AWK_ARRAY;
+ *     val.array_cookie = new_array;
+ *     sym_update("array", &val);      // install array in the symbol table
+ *
+ * After doing so, do NOT make further use of the new_array variable;
+ * instead use sym_lookup to get the array_cookie if you need to do further
+ * manipulation of the array.
  */
 
 /* Allow use in C++ code.  */
@@ -73,7 +93,8 @@ typedef enum {
        AWK_UNDEFINED,
        AWK_NUMBER,
        AWK_STRING,
-       AWK_ARRAY
+       AWK_ARRAY,
+       AWK_SCALAR,     /* opaque access to a variable */
 } awk_valtype_t;
 
 /*
@@ -88,6 +109,9 @@ typedef struct {
 /* Arrays are represented as an opaque type. */
 typedef void *awk_array_t;
 
+/* Scalars can be represented as an opaque type. */
+typedef void *awk_scalar_t;
+
 /*
  * An awk value. The val_type tag indicates what
  * is in the union.
@@ -98,10 +122,12 @@ typedef struct {
                awk_string_t    s;
                double          d;
                awk_array_t     a;
+               awk_array_t     scl;
        } u;
 #define str_value      u.s
 #define num_value      u.d
 #define array_cookie   u.a
+#define scalar_cookie  u.scl
 } awk_value_t;
 
 /*
@@ -200,23 +226,23 @@ typedef struct gawk_api {
 
        Table entry is type returned:
 
-                             +-----------------------------------------+
-                             |               Type Requested:           |
-                             +----------+----------+-------+-----------+
-                             |  String  |  Number  | Array | Undefined |
-       +---------+-----------+----------+----------+-------+-----------+
-       | Type    | String    |  String  | Number if| false |   String  |
-       |         |           |          | it can be|       |           |
-       |         |           |          |converted,|       |           |
-       |         |           |          |   else   |       |           |
-       |         |           |          |   false  |       |           |
-       | of      +-----------+----------+----------+-------+-----------+
-       | Actual  | Number    |  String  |  Number  | false |   Number  |
-       | Value:  +-----------+----------+----------+-------+-----------+
-       |         | Array     |   false  |   false  | Array |   Array   |
-       |         +-----------+----------+----------+-------+-----------+
-       |         | Undefined |   false  |   false  | false | Undefined |
-       +---------+-----------+----------+----------+-------+-----------+
+                             
+---------------------------------------------------+
+                             |                    Type Requested:              
  |
+                             
+----------+----------+-------+---------+-----------+
+                             |  String  |  Number  | Array | Scalar  | 
Undefined |
+       
+---------+-----------+----------+----------+-------+---------+-----------+
+       | Type    | String    |  String  | Number if| false | Scalar  |   
String  |
+       |         |           |          | it can be|       |         |         
  |
+       |         |           |          |converted,|       |         |         
  |
+       |         |           |          |   else   |       |         |         
  |
+       |         |           |          |   false  |       |         |         
  |
+       | of      
+-----------+----------+----------+-------+---------+-----------+
+       | Actual  | Number    |  String  |  Number  | false | Scalar  |  Number 
  |
+       | Value:  
+-----------+----------+----------+-------+---------+-----------+
+       |         | Array     |   false  |   false  | Array | false   |  Array  
  |
+       |         
+-----------+----------+----------+-------+---------+-----------+
+       |         | Undefined |   false  |   false  | false | false   | 
Undefined |
+       
+---------+-----------+----------+----------+-------+---------+-----------+
        */
 
        /*
@@ -225,7 +251,7 @@ typedef struct gawk_api {
         * does not match what is specified in wanted. In that case,
         * result->val_type is as described above.
         */
-       awk_bool_t (*get_argument)(awk_ext_id_t id, size_t count,
+       awk_bool_t (*api_get_argument)(awk_ext_id_t id, size_t count,
                                          awk_valtype_t wanted,
                                          awk_value_t *result);
 
@@ -235,7 +261,7 @@ typedef struct gawk_api {
         * if count is too big, or if the argument's type is
         * not undefined.
         */
-       awk_bool_t (*set_argument)(awk_ext_id_t id,
+       awk_bool_t (*api_set_argument)(awk_ext_id_t id,
                                        size_t count,
                                        awk_array_t array);
 
@@ -245,20 +271,20 @@ typedef struct gawk_api {
        void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...);
 
        /* Register an open hook; for opening files read-only */
-       void (*register_open_hook)(awk_ext_id_t id, void* 
(*open_func)(IOBUF_PUBLIC *));
+       void (*api_register_open_hook)(awk_ext_id_t id, void* 
(*open_func)(IOBUF_PUBLIC *));
 
        /* Functions to update ERRNO */
-       void (*update_ERRNO_int)(awk_ext_id_t id, int errno_val);
-       void (*update_ERRNO_string)(awk_ext_id_t id, const char *string,
+       void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val);
+       void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string,
                        awk_bool_t translate);
-       void (*unset_ERRNO)(awk_ext_id_t id);
+       void (*api_unset_ERRNO)(awk_ext_id_t id);
 
        /* Add a function to the interpreter, returns true upon success */
-       awk_bool_t (*add_ext_func)(awk_ext_id_t id, const awk_ext_func_t *func,
+       awk_bool_t (*api_add_ext_func)(awk_ext_id_t id, const awk_ext_func_t 
*func,
                        const char *namespace);
 
        /* Add an exit call back, returns true upon success */
-       void (*awk_atexit)(awk_ext_id_t id,
+       void (*api_awk_atexit)(awk_ext_id_t id,
                        void (*funcp)(void *data, int exit_status),
                        void *arg0);
 
@@ -285,7 +311,7 @@ typedef struct gawk_api {
         *              // safe to use val
         *      }
         */
-       awk_bool_t (*sym_lookup)(awk_ext_id_t id,
+       awk_bool_t (*api_sym_lookup)(awk_ext_id_t id,
                                const char *name,
                                awk_valtype_t wanted,
                                awk_value_t *result);
@@ -296,16 +322,32 @@ typedef struct gawk_api {
         * In fact, using this to update an array is not allowed, either.
         * Such an attempt returns false.
         */
-       awk_bool_t (*sym_update)(awk_ext_id_t id, const char *name, awk_value_t 
*value);
+       awk_bool_t (*api_sym_update)(awk_ext_id_t id, const char *name, 
awk_value_t *value);
+
+       /*
+        * Work with a scalar cookie.
+        * Flow is
+        *      sym_lookup with wanted == AWK_SCALAR
+        *      if returns false
+        *              sym_update with real initial value
+        *              sym_lookup again with AWK_SCALAR
+        *      else
+        *              use the scalar cookie
+        *
+        * Return will be false if the new value is not one of
+        * AWK_STRING or AWK_NUMBER.
+        */
+       awk_bool_t (*api_sym_update_scalar)(awk_ext_id_t id,
+                               awk_scalar_t cookie, awk_value_t *value);
 
        /* Array management */
        /*
         * Return the value of an element - read only!
         * Use set_array_element() to change it.
-        * Behavior for value and return is same as for get_argument
+        * Behavior for value and return is same as for api_get_argument
         * and sym_lookup.
         */
-       awk_bool_t (*get_array_element)(awk_ext_id_t id,
+       awk_bool_t (*api_get_array_element)(awk_ext_id_t id,
                        awk_array_t a_cookie,
                        const awk_value_t *const index,
                        awk_valtype_t wanted,
@@ -315,7 +357,7 @@ typedef struct gawk_api {
         * Change (or create) element in existing array with
         * element->index and element->value.
         */
-       awk_bool_t (*set_array_element)(awk_ext_id_t id, awk_array_t a_cookie,
+       awk_bool_t (*api_set_array_element)(awk_ext_id_t id, awk_array_t 
a_cookie,
                                        const awk_value_t *const index,
                                        const awk_value_t *const value);
 
@@ -323,24 +365,24 @@ typedef struct gawk_api {
         * Remove the element with the given index.
         * Returns success if removed or if element did not exist.
         */
-       awk_bool_t (*del_array_element)(awk_ext_id_t id,
+       awk_bool_t (*api_del_array_element)(awk_ext_id_t id,
                        awk_array_t a_cookie, const awk_value_t* const index);
 
        /*
         * Retrieve total number of elements in array.
         * Returns false if some kind of error.
         */
-       awk_bool_t (*get_element_count)(awk_ext_id_t id,
+       awk_bool_t (*api_get_element_count)(awk_ext_id_t id,
                        awk_array_t a_cookie, size_t *count);
 
        /* Create a new array cookie to which elements may be added */
-       awk_array_t (*create_array)(awk_ext_id_t id);
+       awk_array_t (*api_create_array)(awk_ext_id_t id);
 
        /* Clear out an array */
-       awk_bool_t (*clear_array)(awk_ext_id_t id, awk_array_t a_cookie);
+       awk_bool_t (*api_clear_array)(awk_ext_id_t id, awk_array_t a_cookie);
 
        /* Flatten out an array so that it can be looped over easily. */
-       awk_bool_t (*flatten_array)(awk_ext_id_t id,
+       awk_bool_t (*api_flatten_array)(awk_ext_id_t id,
                        awk_array_t a_cookie,
                        awk_flat_array_t **data);
 
@@ -349,7 +391,7 @@ typedef struct gawk_api {
         * Count must match what gawk thinks the size is.
         * Otherwise it's a fatal error.
         */
-       awk_bool_t (*release_flattened_array)(awk_ext_id_t id,
+       awk_bool_t (*api_release_flattened_array)(awk_ext_id_t id,
                        awk_array_t a_cookie,
                        awk_flat_array_t *data);
 } gawk_api_t;
@@ -367,52 +409,54 @@ typedef struct gawk_api {
 #define do_mpfr                (api->do_flags[gawk_do_mpfr])
 
 #define get_argument(count, wanted, result) \
-       (api->get_argument(ext_id, count, wanted, result))
+       (api->api_get_argument(ext_id, count, wanted, result))
 #define set_argument(count, new_array) \
-       (api->set_argument(ext_id, count, new_array))
+       (api->api_set_argument(ext_id, count, new_array))
 
 #define fatal          api->api_fatal
 #define warning                api->api_warning
 #define lintwarn       api->api_lintwarn
 
-#define register_open_hook(func)       (api->register_open_hook(ext_id, func))
+#define register_open_hook(func)       (api->api_register_open_hook(ext_id, 
func))
 
-#define update_ERRNO_int(e)    (api->update_ERRNO_int(ext_id, e))
+#define update_ERRNO_int(e)    (api->api_update_ERRNO_int(ext_id, e))
 #define update_ERRNO_string(str, translate) \
-       (api->update_ERRNO_string(ext_id, str, translate))
-#define unset_ERRNO()  (api->unset_ERRNO(ext_id))
+       (api->api_update_ERRNO_string(ext_id, str, translate))
+#define unset_ERRNO()  (api->api_unset_ERRNO(ext_id))
 
-#define add_ext_func(func, ns) (api->add_ext_func(ext_id, func, ns))
-#define awk_atexit(funcp, arg0)        (api->awk_atexit(ext_id, funcp, arg0))
+#define add_ext_func(func, ns) (api->api_add_ext_func(ext_id, func, ns))
+#define awk_atexit(funcp, arg0)        (api->api_awk_atexit(ext_id, funcp, 
arg0))
 
-#define sym_lookup(name, wanted, result)       (api->sym_lookup(ext_id, name, 
wanted, result))
+#define sym_lookup(name, wanted, result)       (api->api_sym_lookup(ext_id, 
name, wanted, result))
 #define sym_update(name, value) \
-       (api->sym_update(ext_id, name, value))
+       (api->api_sym_update(ext_id, name, value))
+#define sym_update_scalar(scalar_cookie, value) \
+       (api->api_sym_update_scalar)(ext_id, scalar_cookie, value)
 
 #define get_array_element(array, index, wanted, result) \
-       (api->get_array_element(ext_id, array, index, wanted, result))
+       (api->api_get_array_element(ext_id, array, index, wanted, result))
 
 #define set_array_element(array, index, value) \
-       (api->set_array_element(ext_id, array, index, value))
+       (api->api_set_array_element(ext_id, array, index, value))
 
 #define set_array_element_by_elem(array, elem) \
-       (set_array_element(array, & (elem)->index, & (elem)->value))
+       (api->api_set_array_element(ext_id, array, & (elem)->index, & 
(elem)->value))
 
 #define del_array_element(array, index) \
-       (api->del_array_element(ext_id, array, index))
+       (api->api_del_array_element(ext_id, array, index))
 
 #define get_element_count(array, count_p) \
-       (api->get_element_count(ext_id, array, count_p))
+       (api->api_get_element_count(ext_id, array, count_p))
 
-#define create_array()         (api->create_array(ext_id))
+#define create_array()         (api->api_create_array(ext_id))
 
-#define clear_array(array)     (api->clear_array(ext_id, array))
+#define clear_array(array)     (api->api_clear_array(ext_id, array))
 
 #define flatten_array(array, data) \
-       (api->flatten_array(ext_id, array, data))
+       (api->api_flatten_array(ext_id, array, data))
 
 #define release_flattened_array(array, data) \
-       (api->release_flattened_array(ext_id, array, data))
+       (api->api_release_flattened_array(ext_id, array, data))
 
 #define emalloc(pointer, type, size, message) \
        do { \
@@ -420,6 +464,12 @@ typedef struct gawk_api {
                        fatal(ext_id, "malloc of %d bytes failed\n", size); \
        } while(0)
 
+#define erealloc(pointer, type, size, message) \
+       do { \
+               if ((pointer = (type) realloc(pointer, size)) == 0) \
+                       fatal(ext_id, "realloc of %d bytes failed\n", size); \
+       } while(0)
+
 /* Constructor functions */
 
 /* r_make_string --- make a string value in result from the passed-in string */
@@ -440,7 +490,7 @@ r_make_string(const gawk_api_t *api,        /* needed for 
emalloc */
        result->str_value.len = length;
 
        if (duplicate) {
-               emalloc(cp, char *, length + 2, "make_string");
+               emalloc(cp, char *, length + 2, "r_make_string");
                memcpy(cp, string, length);
                cp[length] = '\0';
                result->str_value.str = cp;
@@ -451,8 +501,19 @@ r_make_string(const gawk_api_t *api,       /* needed for 
emalloc */
        return result;
 }
 
-#define make_string(str, len, result)  r_make_string(api, ext_id, str, len, 0, 
result)
-#define dup_string(str, len, result)   r_make_string(api, ext_id, str, len, 1, 
result)
+#define make_const_string(str, len, result)    r_make_string(api, ext_id, str, 
len, 1, result)
+#define make_malloced_string(str, len, result) r_make_string(api, ext_id, str, 
len, 0, result)
+
+/* make_null_string --- make a null string value */
+
+static inline awk_value_t *
+make_null_string(awk_value_t *result)
+{
+       memset(result, 0, sizeof(*result));
+       result->val_type = AWK_UNDEFINED;
+
+       return result;
+}
 
 /* make_number --- make a number value in result */
 

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

Summary of changes:
 ChangeLog             |   27 ++++++++
 extension/ChangeLog   |   11 +++
 extension/filefuncs.c |   10 ++--
 extension/fork.c      |    2 +-
 extension/ordchr.c    |    2 +-
 extension/readfile.c  |    4 +-
 extension/rwarray.c   |    4 +-
 extension/testext.c   |   28 +++++---
 gawkapi.c             |  128 +++++++++++++++++++++++++++--------
 gawkapi.h             |  179 +++++++++++++++++++++++++++++++++----------------
 10 files changed, 284 insertions(+), 111 deletions(-)


hooks/post-receive
-- 
gawk



reply via email to

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