gawk: Extension Functions

1 
1 16.4.5.1 Registering An Extension Function
1 ..........................................
1 
1 Extension functions are described by the following record:
1 
1      typedef struct awk_ext_func {
1          const char *name;
1          awk_value_t *(*const function)(int num_actual_args,
1                                         awk_value_t *result,
1                                         struct awk_ext_func *finfo);
1          const size_t max_expected_args;
1          const size_t min_required_args;
1          awk_bool_t suppress_lint;
1          void *data;        /* opaque pointer to any extra state */
1      } awk_ext_func_t;
1 
1    The fields are:
1 
1 'const char *name;'
1      The name of the new function.  'awk'-level code calls the function
1      by this name.  This is a regular C string.
1 
1      Function names must obey the rules for 'awk' identifiers.  That is,
1      they must begin with either an English letter or an underscore,
1      which may be followed by any number of letters, digits, and
1      underscores.  Letter case in function names is significant.
1 
1 'awk_value_t *(*const function)(int num_actual_args,'
1 '                              awk_value_t *result,'
1 '                              struct awk_ext_func *finfo);'
1      This is a pointer to the C function that provides the extension's
1      functionality.  The function must fill in '*result' with either a
1      number, a string, or a regexp.  'gawk' takes ownership of any
1      string memory.  As mentioned earlier, string memory _must_ come
1      from one of 'gawk_malloc()', 'gawk_calloc()', or 'gawk_realloc()'.
1 
1      The 'num_actual_args' argument tells the C function how many actual
1      parameters were passed from the calling 'awk' code.
1 
1      The 'finfo' parameter is a pointer to the 'awk_ext_func_t' for this
1      function.  The called function may access data within it as
1      desired, or not.
1 
1      The function must return the value of 'result'.  This is for the
1      convenience of the calling code inside 'gawk'.
1 
1 'const size_t max_expected_args;'
1      This is the maximum number of arguments the function expects to
1      receive.  If called with more arguments than this, and if lint
1      checking has been enabled, then 'gawk' prints a warning message.
1      For more information, see the entry for 'suppress_lint', later in
1      this list.
1 
1 'const size_t min_required_args;'
1      This is the minimum number of arguments the function expects to
1      receive.  If called with fewer arguments, 'gawk' prints a fatal
1      error message and exits.
1 
1 'awk_bool_t suppress_lint;'
1      This flag tells 'gawk' not to print a lint message if lint checking
1      has been enabled and if more arguments were supplied in the call
1      than expected.  An extension function can tell if 'gawk' already
1      printed at least one such message by checking if 'num_actual_args >
1      finfo->max_expected_args'.  If so, and the function does not want
1      more lint messages to be printed, it should set
1      'finfo->suppress_lint' to 'awk_true'.
1 
1 'void *data;'
1      This is an opaque pointer to any data that an extension function
1      may wish to have available when called.  Passing the
1      'awk_ext_func_t' structure to the extension function, and having
1      this pointer available in it enable writing a single C or C++
1      function that implements multiple 'awk'-level extension functions.
1 
1    Once you have a record representing your extension function, you
1 register it with 'gawk' using this API function:
1 
1 'awk_bool_t add_ext_func(const char *name_space, awk_ext_func_t *func);'
1      This function returns true upon success, false otherwise.  The
1      'name_space' parameter is currently not used; you should pass in an
1      empty string ('""').  The 'func' pointer is the address of a
1      'struct' representing your function, as just described.
1 
1      'gawk' does not modify what 'func' points to, but the extension
1      function itself receives this pointer and can modify what it points
1      to, thus it is purposely not declared to be 'const'.
1 
1    The combination of 'min_required_args', 'max_expected_args', and
1 'suppress_lint' may be confusing.  Here is how you should set things up.
1 
1 Any number of arguments is valid
1      Set 'min_required_args' and 'max_expected_args' to zero and set
1      'suppress_lint' to 'awk_true'.
1 
1 A minimum number of arguments is required, no limit on maximum number of arguments
1      Set 'min_required_args' to the minimum required.  Set
1      'max_expected_args' to zero and set 'suppress_lint' to 'awk_true'.
1 
1 A minimum number of arguments is required, a maximum number is expected
1      Set 'min_required_args' to the minimum required.  Set
1      'max_expected_args' to the maximum expected.  Set 'suppress_lint'
1      to 'awk_false'.
1 
1 A minimum number of arguments is required, and no more than a maximum is allowed
1      Set 'min_required_args' to the minimum required.  Set
1      'max_expected_args' to the maximum expected.  Set 'suppress_lint'
1      to 'awk_false'.  In your extension function, check that
1      'num_actual_args' does not exceed 'f->max_expected_args'.  If it
1      does, issue a fatal error message.
1