gawk: Creating Arrays
1
1 16.4.11.4 How To Create and Populate Arrays
1 ...........................................
1
1 Besides working with arrays created by 'awk' code, you can create arrays
1 and populate them as you see fit, and then 'awk' code can access them
1 and manipulate them.
1
1 There are two important points about creating arrays from extension
1 code:
1
1 * You must install a new array into 'gawk''s symbol table immediately
1 upon creating it. Once you have done so, you can then populate the
1 array.
1
1 Similarly, if installing a new array as a subarray of an existing
1 array, you must add the new array to its parent before adding any
1 elements to it.
1
1 Thus, the correct way to build an array is to work "top down."
1 Create the array, and immediately install it in 'gawk''s symbol
1 table using 'sym_update()', or install it as an element in a
1 previously existing array using 'set_array_element()'. We show
1 example code shortly.
1
1 * Due to 'gawk' internals, after using 'sym_update()' to install an
1 array into 'gawk', you have to retrieve the array cookie from the
1 value passed in to 'sym_update()' before doing anything else with
1 it, like so:
1
1 awk_value_t val;
1 awk_array_t new_array;
1
1 new_array = create_array();
1 val.val_type = AWK_ARRAY;
1 val.array_cookie = new_array;
1
1 /* install array in the symbol table */
1 sym_update("array", & val);
1
1 new_array = val.array_cookie; /* YOU MUST DO THIS */
1
1 If installing an array as a subarray, you must also retrieve the
1 value of the array cookie after the call to 'set_element()'.
1
1 The following C code is a simple test extension to create an array
1 with two regular elements and with a subarray. The leading '#include'
11 directives and boilerplate variable declarations (⇒Extension API
Boilerplate) are omitted for brevity. The first step is to create a
1 new array and then install it in the symbol table:
1
1 /* create_new_array --- create a named array */
1
1 static void
1 create_new_array()
1 {
1 awk_array_t a_cookie;
1 awk_array_t subarray;
1 awk_value_t index, value;
1
1 a_cookie = create_array();
1 value.val_type = AWK_ARRAY;
1 value.array_cookie = a_cookie;
1
1 if (! sym_update("new_array", & value))
1 printf("create_new_array: sym_update(\"new_array\") failed!\n");
1 a_cookie = value.array_cookie;
1
1 Note how 'a_cookie' is reset from the 'array_cookie' field in the
1 'value' structure.
1
1 The second step is to install two regular values into 'new_array':
1
1 (void) make_const_string("hello", 5, & index);
1 (void) make_const_string("world", 5, & value);
1 if (! set_array_element(a_cookie, & index, & value)) {
1 printf("fill_in_array: set_array_element failed\n");
1 return;
1 }
1
1 (void) make_const_string("answer", 6, & index);
1 (void) make_number(42.0, & value);
1 if (! set_array_element(a_cookie, & index, & value)) {
1 printf("fill_in_array: set_array_element failed\n");
1 return;
1 }
1
1 The third step is to create the subarray and install it:
1
1 (void) make_const_string("subarray", 8, & index);
1 subarray = create_array();
1 value.val_type = AWK_ARRAY;
1 value.array_cookie = subarray;
1 if (! set_array_element(a_cookie, & index, & value)) {
1 printf("fill_in_array: set_array_element failed\n");
1 return;
1 }
1 subarray = value.array_cookie;
1
1 The final step is to populate the subarray with its own element:
1
1 (void) make_const_string("foo", 3, & index);
1 (void) make_const_string("bar", 3, & value);
1 if (! set_array_element(subarray, & index, & value)) {
1 printf("fill_in_array: set_array_element failed\n");
1 return;
1 }
1 }
1
1 Here is a sample script that loads the extension and then dumps the
1 array:
1
1 @load "subarray"
1
1 function dumparray(name, array, i)
1 {
1 for (i in array)
1 if (isarray(array[i]))
1 dumparray(name "[\"" i "\"]", array[i])
1 else
1 printf("%s[\"%s\"] = %s\n", name, i, array[i])
1 }
1
1 BEGIN {
1 dumparray("new_array", new_array);
1 }
1
1 Here is the result of running the script:
1
1 $ AWKLIBPATH=$PWD gawk -f subarray.awk
1 -| new_array["subarray"]["foo"] = bar
1 -| new_array["hello"] = world
1 -| new_array["answer"] = 42
1
1 (⇒Finding Extensions for more information on the 'AWKLIBPATH'
1 environment variable.)
1