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