gawk: Extension API Boilerplate

1 
1 16.4.14 Boilerplate Code
1 ------------------------
1 
1 As mentioned earlier (⇒Extension Mechanism Outline), the function
1 definitions as presented are really macros.  To use these macros, your
1 extension must provide a small amount of boilerplate code (variables and
1 functions) toward the top of your source file, using predefined names as
1 described here.  The boilerplate needed is also provided in comments in
1 the 'gawkapi.h' header file:
1 
1      /* Boilerplate code: */
1      int plugin_is_GPL_compatible;
1 
1      static gawk_api_t *const api;
1      static awk_ext_id_t ext_id;
1      static const char *ext_version = NULL; /* or ... = "some string" */
1 
1      static awk_ext_func_t func_table[] = {
1          { "name", do_name, 1, 0, awk_false, NULL },
1          /* ... */
1      };
1 
1      /* EITHER: */
1 
1      static awk_bool_t (*init_func)(void) = NULL;
1 
1      /* OR: */
1 
1      static awk_bool_t
1      init_my_extension(void)
1      {
1          ...
1      }
1 
1      static awk_bool_t (*init_func)(void) = init_my_extension;
1 
1      dl_load_func(func_table, some_name, "name_space_in_quotes")
1 
1    These variables and functions are as follows:
1 
1 'int plugin_is_GPL_compatible;'
1      This asserts that the extension is compatible with the GNU GPL
1      (⇒Copying).  If your extension does not have this, 'gawk'
1      will not load it (⇒Plugin License).
1 
1 'static gawk_api_t *const api;'
1      This global 'static' variable should be set to point to the
1      'gawk_api_t' pointer that 'gawk' passes to your 'dl_load()'
1      function.  This variable is used by all of the macros.
1 
1 'static awk_ext_id_t ext_id;'
1      This global static variable should be set to the 'awk_ext_id_t'
1      value that 'gawk' passes to your 'dl_load()' function.  This
1      variable is used by all of the macros.
1 
1 'static const char *ext_version = NULL; /* or ... = "some string" */'
1      This global 'static' variable should be set either to 'NULL', or to
1      point to a string giving the name and version of your extension.
1 
1 'static awk_ext_func_t func_table[] = { ... };'
1      This is an array of one or more 'awk_ext_func_t' structures, as
1      described earlier (⇒Extension Functions).  It can then be
1      looped over for multiple calls to 'add_ext_func()'.
1 
1 'static awk_bool_t (*init_func)(void) = NULL;'
1 '                   OR'
1 'static awk_bool_t init_my_extension(void) { ... }'
1 'static awk_bool_t (*init_func)(void) = init_my_extension;'
1      If you need to do some initialization work, you should define a
1      function that does it (creates variables, opens files, etc.)  and
1      then define the 'init_func' pointer to point to your function.  The
1      function should return 'awk_false' upon failure, or 'awk_true' if
1      everything goes well.
1 
1      If you don't need to do any initialization, define the pointer and
1      initialize it to 'NULL'.
1 
1 'dl_load_func(func_table, some_name, "name_space_in_quotes")'
1      This macro expands to a 'dl_load()' function that performs all the
1      necessary initializations.
1 
1    The point of all the variables and arrays is to let the 'dl_load()'
1 function (from the 'dl_load_func()' macro) do all the standard work.  It
1 does the following:
1 
1   1. Check the API versions.  If the extension major version does not
1      match 'gawk''s, or if the extension minor version is greater than
1      'gawk''s, it prints a fatal error message and exits.
1 
1   2. Check the MPFR and GMP versions.  If there is a mismatch, it prints
1      a fatal error message and exits.
1 
1   3. Load the functions defined in 'func_table'.  If any of them fails
1      to load, it prints a warning message but continues on.
1 
1   4. If the 'init_func' pointer is not 'NULL', call the function it
1      points to.  If it returns 'awk_false', print a warning message.
1 
1   5. If 'ext_version' is not 'NULL', register the version string with
1      'gawk'.
1