diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | awk.h | 3 | ||||
-rw-r--r-- | ext.c | 2 | ||||
-rw-r--r-- | extension/ChangeLog | 5 | ||||
-rw-r--r-- | extension/testext.c | 47 | ||||
-rw-r--r-- | gawkapi.c | 15 | ||||
-rw-r--r-- | gawkapi.h | 12 | ||||
-rw-r--r-- | test/ChangeLog | 4 | ||||
-rw-r--r-- | test/testext.ok | 8 |
9 files changed, 79 insertions, 28 deletions
@@ -1,11 +1,22 @@ 2012-06-19 Arnold D. Robbins <arnold@skeeve.com> + Remove code duplication in gawkapi.c from msg.c: + * awk.h (err): Add `isfatal' first parameter. * awkgram.y (err): Adjust all calls. * msg.c (err): Adjust all calls. Move fatal code to here ... (r_fatal): From here. * gawkapi.c: Remove code duplication and adjust calls to `err'. + Handle deleting elements of flattened array: + + * awk.h (get_argument): Remove declaration. + * ext.c (get_argument): Make static. + * gawkapi.h (awk_flat_array_t): Make opaque fields const. Add + more descriptive comments. + * gawkapi.c (release_flattened_array): Delete elements flagged + for deletion. Free the flattened array also. + 2012-06-18 Arnold D. Robbins <arnold@skeeve.com> * gawkapi.h (get_array_element): Restore `wanted' paramater. @@ -1506,7 +1506,6 @@ 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) @@ -1605,7 +1604,7 @@ extern int mpg_strtoui(mpz_ptr, char *, size_t, char **, int); /* msg.c */ extern void gawk_exit(int status); extern void final_exit(int status) ATTRIBUTE_NORETURN; -extern void err(bool isfatal, const char *s, const char *emsg, va_list argp) ATTRIBUTE_PRINTF(2, 0); +extern void err(bool isfatal, const char *s, const char *emsg, va_list argp) ATTRIBUTE_PRINTF(3, 0); extern void msg (const char *mesg, ...) ATTRIBUTE_PRINTF_1; extern void error (const char *mesg, ...) ATTRIBUTE_PRINTF_1; extern void warning (const char *mesg, ...) ATTRIBUTE_PRINTF_1; @@ -152,7 +152,7 @@ make_builtin(const awk_ext_func_t *funcinfo) /* get_argument --- get the i'th argument of a dynamically linked function */ -NODE * +static NODE * get_argument(int i) { NODE *t; diff --git a/extension/ChangeLog b/extension/ChangeLog index 54bf3f8a..8d8cf2bb 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,8 @@ +2012-06-19 Arnold D. Robbins <arnold@skeeve.com> + + * testext.c (dump_array_and_delete): Renamed from dump_array. + Get second parameter which is index to delete. Update awk test. + 2012-06-18 Arnold D. Robbins <arnold@skeeve.com> * filefuncs.c (do_chdir): Change element use to match change types. diff --git a/extension/testext.c b/extension/testext.c index f5e16ba1..0a7594aa 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -84,25 +84,29 @@ valrep2str(const awk_value_t *value) BEGIN { n = split("blacky rusty sophie raincloud lucky", pets) printf "pets has %d elements\n", length(pets) - ret = dump_array("pets") - printf "dump_array(pets) returned %d\n", ret + ret = dump_array_and_delete("pets", "3") + printf "dump_array_and_delete(pets) returned %d\n", ret + if ("3" in pets) + printf("dump_array_and_delete() did NOT remove index \"3\"!\n") + else + printf("dump_array_and_delete() did remove index \"3\"!\n") print "" } */ static awk_value_t * -dump_array(int nargs, awk_value_t *result) +dump_array_and_delete(int nargs, awk_value_t *result) { - awk_value_t value, value2; + awk_value_t value, value2, value3; awk_flat_array_t *flat_array; size_t count; - int i; char *name; + int i; assert(result != NULL); make_number(0.0, result); - if (nargs != 1) { - printf("dump_array: nargs not right (%d should be 1)\n", nargs); + if (nargs != 2) { + printf("dump_array_and_delete: nargs not right (%d should be 2)\n", nargs); goto out; } @@ -110,45 +114,56 @@ dump_array(int nargs, awk_value_t *result) if (get_argument(0, AWK_STRING, & value)) { name = value.str_value.str; if (sym_lookup(name, AWK_ARRAY, & value2)) - printf("dump_array: sym_lookup of %s passed\n", name); + printf("dump_array_and_delete: sym_lookup of %s passed\n", name); else { - printf("dump_array: sym_lookup of %s failed\n", name); + printf("dump_array_and_delete: sym_lookup of %s failed\n", name); goto out; } } else { - printf("dump_array: get_argument(0) failed\n"); + printf("dump_array_and_delete: get_argument(0) failed\n"); goto out; } if (! get_element_count(value2.array_cookie, & count)) { - printf("dump_array: get_element_count failed\n"); + printf("dump_array_and_delete: get_element_count failed\n"); goto out; } - printf("dump_array: incoming size is %lu\n", (unsigned long) count); + printf("dump_array_and_delete: incoming size is %lu\n", (unsigned long) count); if (! flatten_array(value2.array_cookie, & flat_array)) { - printf("dump_array: could not flatten array\n"); + printf("dump_array_and_delete: could not flatten array\n"); goto out; } if (flat_array->count != count) { - printf("dump_array: flat_array->count (%lu) != count (%lu)\n", + printf("dump_array_and_delete: flat_array->count (%lu) != count (%lu)\n", (unsigned long) flat_array->count, (unsigned long) count); goto out; } + if (! get_argument(1, AWK_STRING, & value3)) { + printf("dump_array_and_delete: get_argument(1) failed\n"); + goto out; + } + for (i = 0; i < flat_array->count; i++) { printf("\t%s[\"%.*s\"] = %s\n", name, (int) flat_array->elements[i].index.str_value.len, flat_array->elements[i].index.str_value.str, valrep2str(& flat_array->elements[i].value)); + + if (strcmp(value3.str_value.str, flat_array->elements[i].index.str_value.str) == 0) { + flat_array->elements[i].flags |= AWK_ELEMENT_DELETE; + printf("dump_array_and_delete: marking element \"%s\" for deletion\n", + flat_array->elements[i].index.str_value.str); + } } if (! release_flattened_array(value2.array_cookie, flat_array)) { - printf("dump_array: could not release flattened array\n"); + printf("dump_array_and_delete: could not release flattened array\n"); goto out; } @@ -504,7 +519,7 @@ static void at_exit2(void *data, int exit_status) } static awk_ext_func_t func_table[] = { - { "dump_array", dump_array, 1 }, + { "dump_array_and_delete", dump_array_and_delete, 2 }, { "var_test", var_test, 1 }, { "test_errno", test_errno, 0 }, { "test_array_size", test_array_size, 1 }, @@ -637,15 +637,24 @@ api_release_flattened_array(awk_ext_id_t id, list = (NODE **) data->opaque2; - /* FIXME: Delete items flagged for delete. */ + /* 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 = 0; i < 2 * array->table_size; i += 2) { unref(list[i]); + } efree(list); + efree(data); - return true; /* for now */ + return true; } gawk_api_t api_impl = { @@ -131,7 +131,8 @@ typedef struct { } awk_value_t; /* - * A "flattened" array element. Gawk produces an array of these. + * A "flattened" array element. Gawk produces an array of these + * inside the awk_flattened_array_t. * ALL memory pointed to belongs to gawk. Individual elements may * be marked for deletion. New elements must be added individually, * one at a time, using the separate API for that purpose. @@ -149,15 +150,20 @@ typedef struct awk_element { awk_value_t value; } awk_element_t; +/* This is used to keep the extension from modifying certain fields. */ #ifdef GAWK #define awk_const #else #define awk_const const #endif +/* + * A "flattened" array. See the description above for how + * to use the elements contained herein. + */ typedef struct awk_flat_array { - void *opaque1; /* private data for use by gawk */ - void *opaque2; /* private data for use by gawk */ + awk_const void *opaque1; /* private data for use by gawk */ + awk_const void *opaque2; /* private data for use by gawk */ awk_const size_t count; /* how many elements */ awk_element_t elements[1]; /* will be extended */ } awk_flat_array_t; diff --git a/test/ChangeLog b/test/ChangeLog index f8fc382e..44af6057 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,7 @@ +2012-06-19 Arnold D. Robbins <arnold@skeeve.com> + + * testext.ok: Update contents. + 2012-06-18 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am (testext): New test. diff --git a/test/testext.ok b/test/testext.ok index 83711a7b..2f54668a 100644 --- a/test/testext.ok +++ b/test/testext.ok @@ -1,12 +1,14 @@ pets has 5 elements -dump_array: sym_lookup of pets passed -dump_array: incoming size is 5 +dump_array_and_delete: sym_lookup of pets passed +dump_array_and_delete: incoming size is 5 pets["1"] = "blacky" pets["2"] = "rusty" pets["3"] = "sophie" +dump_array_and_delete: marking element "3" for deletion pets["4"] = "raincloud" pets["5"] = "lucky" -dump_array(pets) returned 1 +dump_array_and_delete(pets) returned 1 +dump_array_and_delete() did remove index "3"! var_test: sym_lookup of ARGC passed - did not get a value var_test: sym_update("testvar") succeeded |