aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--awk.h1
-rw-r--r--ext.c2
-rw-r--r--extension/ChangeLog6
-rw-r--r--extension/testext.c70
-rw-r--r--gawkapi.c81
-rw-r--r--gawkapi.h11
-rw-r--r--test/ChangeLog4
-rw-r--r--test/testext.ok8
9 files changed, 179 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 8ae6d3f1..beb8f36e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,17 @@
2012-06-20 Arnold D. Robbins <arnold@skeeve.com>
- * awgram.y (stopme): Restore long lost debugging function.
- * awgram.y (stopme): Add declaration.
+ Restore lost debugging function:
+
+ * awkgram.y (stopme): Restore long lost debugging function.
+ * awk.h (stopme): Add declaration.
+
+ API work:
+
+ * ext.c (get_argument): Make extern.
+ * awk.h (get_argument): Declare it.
+ * gawkapi.c (api_set_argument): Call it. Finish off the logic.
+ (api_get_argument): Refine logic to use get_argument.
+ * gawkapi.h (set_argument): New API.
2012-06-19 Arnold D. Robbins <arnold@skeeve.com>
diff --git a/awk.h b/awk.h
index 77aa1117..4bfaef47 100644
--- a/awk.h
+++ b/awk.h
@@ -1507,6 +1507,7 @@ NODE *do_ext(int nargs);
NODE *load_ext(const char *lib_name, const char *init_func);
#ifdef DYNAMIC
awk_bool_t make_builtin(const awk_ext_func_t *);
+NODE *get_argument(int);
NODE *get_actual_argument(int, bool, bool);
#define get_scalar_argument(i, opt) get_actual_argument((i), (opt), false)
#define get_array_argument(i, opt) get_actual_argument((i), (opt), true)
diff --git a/ext.c b/ext.c
index 4945c7cb..d0755ccd 100644
--- a/ext.c
+++ b/ext.c
@@ -152,7 +152,7 @@ make_builtin(const awk_ext_func_t *funcinfo)
/* get_argument --- get the i'th argument of a dynamically linked function */
-static NODE *
+NODE *
get_argument(int i)
{
NODE *t;
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 8d8cf2bb..a134e00c 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,9 @@
+2012-06-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.c (fill_in_array): New function.
+ (create_new_array): Most code moved into fill_in_array.
+ (test_array_param): New function.
+
2012-06-19 Arnold D. Robbins <arnold@skeeve.com>
* testext.c (dump_array_and_delete): Renamed from dump_array.
diff --git a/extension/testext.c b/extension/testext.c
index 0a7594aa..963a5638 100644
--- a/extension/testext.c
+++ b/extension/testext.c
@@ -42,6 +42,8 @@ static awk_ext_id_t *ext_id;
int plugin_is_GPL_compatible;
+static void fill_in_array(awk_value_t *value);
+
/* valrep2str --- turn a value into a string */
static const char *
@@ -386,6 +388,54 @@ out:
/*
BEGIN {
+ ret = test_array_param(a_new_array)
+ printf "test_array_param() returned %d\n", ret
+ printf "isarray(a_new_array) = %d\n", isarray(a_new_array)
+ if (isarray(a_new_array))
+ for (i in a_new_array)
+ printf("a_new_array[\"%s\"] = %s\n",
+ i, a_new_array[i])
+
+ a_scalar = 42
+ ret = test_array_param(a_scalar)
+ printf "test_array_param() returned %d\n", ret
+ printf "isarray(a_scalar) = %d\n", isarray(a_scalar)
+ print ""
+}
+*/
+
+static awk_value_t *
+test_array_param(int nargs, awk_value_t *result)
+{
+ awk_value_t new_array;
+ awk_value_t arg0;
+
+ make_number(0.0, result);
+
+ if (! get_argument(0, AWK_UNDEFINED, & arg0)) {
+ printf("test_array_param: could not get argument\n");
+ goto out;
+ }
+
+ if (arg0.val_type != AWK_UNDEFINED) {
+ printf("test_array_param: argument is not undefined (%d)\n",
+ arg0.val_type);
+ goto out;
+ }
+
+ fill_in_array(& new_array);
+ if (! set_argument(0, new_array.array_cookie)) {
+ printf("test_array_param: could not change type of argument\n");
+ goto out;
+ }
+
+ make_number(1.0, result);
+out:
+ return result; /* for now */
+}
+
+/*
+BEGIN {
printf "Initial value of LINT is %d\n", LINT
ret = print_do_lint();
printf "print_do_lint() returned %d\n", ret
@@ -448,12 +498,11 @@ out:
}
static void
-create_new_array()
+fill_in_array(awk_value_t *value)
{
awk_element_t element;
awk_array_t a_cookie;
awk_value_t index;
- awk_value_t value;
a_cookie = create_array();
@@ -461,7 +510,7 @@ create_new_array()
element.index = index;
(void) make_string("world", 5, & element.value);
if (! set_array_element(a_cookie, & element)) {
- printf("create_new_array:%d: set_array_element failed\n", __LINE__);
+ printf("fill_in_array:%d: set_array_element failed\n", __LINE__);
return;
}
@@ -469,13 +518,21 @@ create_new_array()
element.index = index;
(void) make_number(42.0, & element.value);
if (! set_array_element(a_cookie, & element)) {
- printf("create_new_array:%d: set_array_element failed\n", __LINE__);
+ printf("fill_in_array:%d: set_array_element failed\n", __LINE__);
return;
}
- value.val_type = AWK_ARRAY;
- value.array_cookie = a_cookie;
+ value->val_type = AWK_ARRAY;
+ value->array_cookie = a_cookie;
+
+}
+
+static void
+create_new_array()
+{
+ awk_value_t value;
+ fill_in_array(& value);
if (! sym_update("new_array", & value))
printf("create_new_array: sym_update(\"new_array\") failed!\n");
}
@@ -524,6 +581,7 @@ static awk_ext_func_t func_table[] = {
{ "test_errno", test_errno, 0 },
{ "test_array_size", test_array_size, 1 },
{ "test_array_elem", test_array_elem, 2 },
+ { "test_array_param", test_array_param, 1 },
{ "test_array_flatten", test_array_flatten, 1 },
{ "print_do_lint", print_do_lint, 0 },
};
diff --git a/gawkapi.c b/gawkapi.c
index 5eb16881..ad7e68fd 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -44,17 +44,83 @@ api_get_argument(awk_ext_id_t id, size_t count,
(void) id;
- arg = (wanted == AWK_ARRAY
- ? get_array_argument(count, false)
- : get_scalar_argument(count, false) );
-
- if (arg == NULL) {
- memset(result, 0, sizeof(*result));
- result->val_type = AWK_UNDEFINED;
+ /* set up default result */
+ memset(result, 0, sizeof(*result));
+ result->val_type = AWK_UNDEFINED;
+
+ /*
+ * Song and dance here. get_array_argument() and get_scalar_argument()
+ * will force a change in type of a parameter that is Node_var_new.
+ *
+ * Start by looking at the unadulterated argument as it was passed.
+ */
+ arg = get_argument(count);
+ if (arg == NULL)
return false;
+
+ /* if type is undefined */
+ if (arg->type == Node_var_new) {
+ if (wanted == AWK_UNDEFINED)
+ return true;
+ else if (wanted == AWK_ARRAY) {
+ goto array;
+ } else {
+ goto scalar;
+ }
}
+
+ /* at this point, we have real type */
+ if (arg->type == Node_var_array || arg->type == Node_array_ref) {
+ if (wanted != AWK_ARRAY && wanted != AWK_UNDEFINED)
+ return false;
+ goto array;
+ } else
+ goto scalar;
+
+array:
+ /* get the array here */
+ arg = get_array_argument(count, false);
+ if (arg == NULL)
+ return false;
return node_to_awk_value(arg, result, wanted);
+
+scalar:
+ /* at this point we have a real type that is not an array */
+ arg = get_scalar_argument(count, false);
+ if (arg == NULL)
+ return false;
+
+ return node_to_awk_value(arg, result, wanted);
+}
+
+static awk_bool_t
+api_set_argument(awk_ext_id_t id,
+ size_t count,
+ awk_array_t new_array)
+{
+ NODE *arg;
+ NODE *array = (NODE *) new_array;
+ awk_valtype_t valtype;
+
+ (void) id;
+
+ if (array == NULL || array->type != Node_var_array)
+ return false;
+
+ if ( (arg = get_argument(count)) == NULL
+ || arg->type != Node_var_new)
+ return false;
+
+ arg = get_array_argument(count, false);
+ if (arg == NULL)
+ return false;
+
+ array->vname = arg->vname;
+ *arg = *array;
+ freenode(array);
+
+ return true;
}
/* awk_value_to_node --- convert a value into a NODE */
@@ -663,6 +729,7 @@ gawk_api_t api_impl = {
{ 0 }, /* do_flags */
api_get_argument,
+ api_set_argument,
api_fatal,
api_warning,
diff --git a/gawkapi.h b/gawkapi.h
index 7973d7a8..3325c454 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -242,9 +242,14 @@ typedef struct gawk_api {
awk_value_t *result);
/*
- * FIXME: Missing update_argument to convert an undefined
- * argument into an array or scalar.
+ * Convert a paramter that was undefined into an array
+ * (provide call-by-reference for arrays). Returns false
+ * if count is too big, or if the argument's type is
+ * not undefined.
*/
+ awk_bool_t (*set_argument)(awk_ext_id_t id,
+ size_t count,
+ awk_array_t array);
/* Functions to print messages */
void (*api_fatal)(awk_ext_id_t id, const char *format, ...);
@@ -373,6 +378,8 @@ typedef struct gawk_api {
#define get_argument(count, wanted, result) \
(api->get_argument(ext_id, count, wanted, result))
+#define set_argument(count, new_array) \
+ (api->set_argument(ext_id, count, new_array))
#define fatal api->api_fatal
#define warning api->api_warning
diff --git a/test/ChangeLog b/test/ChangeLog
index 44af6057..71edf199 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,7 @@
+2012-06-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testext.ok: Update contents.
+
2012-06-19 Arnold D. Robbins <arnold@skeeve.com>
* testext.ok: Update contents.
diff --git a/test/testext.ok b/test/testext.ok
index 2f54668a..08e272d0 100644
--- a/test/testext.ok
+++ b/test/testext.ok
@@ -25,6 +25,14 @@ test_array_elem() returned 1, test_array2[3] = 42
test_array_elem did remove element "5"
test_array_elem added element "7" --> seven
+test_array_param() returned 1
+isarray(a_new_array) = 1
+a_new_array["hello"] = world
+a_new_array["answer"] = 42
+test_array_param: argument is not undefined (1)
+test_array_param() returned 0
+isarray(a_scalar) = 0
+
Initial value of LINT is 0
print_do_lint: lint = 0
print_do_lint() returned 1