aboutsummaryrefslogtreecommitdiffstats
path: root/gawkapi.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2012-06-18 23:00:58 +0300
committerArnold D. Robbins <arnold@skeeve.com>2012-06-18 23:00:58 +0300
commit1e3ac8a49caeeb991d8163042a576a66db51c74b (patch)
tree81fe5ffd621c6cba3f98d2997f2f930a3f66343d /gawkapi.c
parentb0f08ac2443e239b0ed9cc4421758f0ed3f7a94f (diff)
downloadegawk-1e3ac8a49caeeb991d8163042a576a66db51c74b.tar.gz
egawk-1e3ac8a49caeeb991d8163042a576a66db51c74b.tar.bz2
egawk-1e3ac8a49caeeb991d8163042a576a66db51c74b.zip
Get most of array flattening done.
Diffstat (limited to 'gawkapi.c')
-rw-r--r--gawkapi.c80
1 files changed, 72 insertions, 8 deletions
diff --git a/gawkapi.c b/gawkapi.c
index b616fbfc..b1fba48a 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -478,10 +478,11 @@ api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie,
if ( array == NULL
|| array->type != Node_var_array
|| element == NULL
- || element->index.str == NULL)
+ || element->index.str_value.str == NULL)
return false;
- tmp = make_string(element->index.str, element->index.len);
+ tmp = make_string(element->index.str_value.str,
+ element->index.str_value.len);
aptr = assoc_lookup(array, tmp);
unref(tmp);
unref(*aptr);
@@ -570,14 +571,56 @@ api_clear_array(awk_ext_id_t id, awk_array_t a_cookie)
return true;
}
-/* Flatten out an array so that it can be looped over easily. */
+/* api_flatten_array --- flatten out an array so that it can be looped over easily. */
+
static awk_bool_t
api_flatten_array(awk_ext_id_t id,
awk_array_t a_cookie,
- size_t *count,
- awk_element_t **data)
+ awk_flat_array_t **data)
{
- return true; /* for now */
+ NODE **list;
+ size_t i, j;
+ NODE *array = (NODE *) a_cookie;
+ size_t alloc_size;
+
+ if ( array == NULL
+ || array->type != Node_var_array
+ || array->table_size == 0
+ || data == NULL)
+ return false;
+
+ alloc_size = sizeof(awk_flat_array_t) +
+ (array->table_size - 1) * sizeof(awk_element_t);
+
+ emalloc(*data, awk_flat_array_t *, alloc_size,
+ "api_flatten_array");
+ memset(*data, 0, alloc_size);
+
+ list = assoc_list(array, "@unsorted", ASORTI);
+
+ (*data)->opaque1 = array;
+ (*data)->opaque2 = list;
+ (*data)->count = array->table_size;
+
+ for (i = j = 0; i < 2 * array->table_size; i += 2, j++) {
+ NODE *index, *value;
+
+ index = force_string(list[i]);
+ value = list[i + 1]; /* number or string or subarray */
+
+ /* convert index and value to ext types */
+ if (! node_to_awk_value(index,
+ & (*data)->elements[j].index, AWK_UNDEFINED)) {
+ fatal(_("api_flatten_array: could not convert index %d\n"),
+ (int) i);
+ }
+ if (! node_to_awk_value(value,
+ & (*data)->elements[j].value, AWK_UNDEFINED)) {
+ fatal(_("api_flatten_array: could not convert value %d\n"),
+ (int) i);
+ }
+ }
+ return true;
}
/*
@@ -587,9 +630,30 @@ api_flatten_array(awk_ext_id_t id,
static awk_bool_t
api_release_flattened_array(awk_ext_id_t id,
awk_array_t a_cookie,
- size_t count,
- awk_element_t *data)
+ awk_flat_array_t *data)
{
+ NODE *array = a_cookie;
+ NODE **list;
+ size_t i;
+
+ if ( array == NULL
+ || array->type != Node_var_array
+ || data == NULL
+ || array != (NODE *) data->opaque1
+ || data->count != array->table_size
+ || data->opaque2 == NULL)
+ return false;
+
+ list = (NODE **) data->opaque2;
+
+ /* FIXME: Delete items flagged for delete. */
+
+ /* free index nodes */
+ for (i = 0; i < 2 * array->table_size; i += 2)
+ unref(list[i]);
+
+ efree(list);
+
return true; /* for now */
}