diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | awk.h | 1 | ||||
-rw-r--r-- | ext.c | 2 | ||||
-rw-r--r-- | extension/ChangeLog | 6 | ||||
-rw-r--r-- | extension/testext.c | 70 | ||||
-rw-r--r-- | gawkapi.c | 81 | ||||
-rw-r--r-- | gawkapi.h | 11 | ||||
-rw-r--r-- | test/ChangeLog | 4 | ||||
-rw-r--r-- | test/testext.ok | 8 |
9 files changed, 179 insertions, 18 deletions
@@ -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> @@ -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) @@ -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 }, }; @@ -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, @@ -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 |