aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--awk.h3
-rw-r--r--ext.c2
-rw-r--r--extension/ChangeLog5
-rw-r--r--extension/testext.c47
-rw-r--r--gawkapi.c15
-rw-r--r--gawkapi.h12
-rw-r--r--test/ChangeLog4
-rw-r--r--test/testext.ok8
9 files changed, 79 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index 820e1cbb..0b6f7b49 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/awk.h b/awk.h
index 4f120d37..eb512f21 100644
--- a/awk.h
+++ b/awk.h
@@ -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;
diff --git a/ext.c b/ext.c
index d0755ccd..4945c7cb 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 */
-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 },
diff --git a/gawkapi.c b/gawkapi.c
index 92403dce..5eb16881 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -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 = {
diff --git a/gawkapi.h b/gawkapi.h
index 8102f70e..7973d7a8 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -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