Previous: Extension API Variables, Up: Extension API Description


16.4.12 Boilerplate Code

As mentioned earlier (see Extension Mechanism Outline), the function definitions as presented are really macros. To use these macros, your extension must provide a small amount of boilerplate code (variables and functions) towards the top of your source file, using pre-defined names as described below. The boilerplate needed is also provided in comments in the gawkapi.h header file:

     /* Boiler plate code: */
     int plugin_is_GPL_compatible;
     
     static gawk_api_t *const api;
     static awk_ext_id_t ext_id;
     static const char *ext_version = NULL; /* or ... = "some string" */
     
     static awk_ext_func_t func_table[] = {
         { "name", do_name, 1 },
         /* ... */
     };
     
     /* EITHER: */
     
     static awk_bool_t (*init_func)(void) = NULL;
     
     /* OR: */
     
     static awk_bool_t
     init_my_module(void)
     {
         ...
     }
     
     static awk_bool_t (*init_func)(void) = init_my_module;
     
     dl_load_func(func_table, some_name, "name_space_in_quotes")

These variables and functions are as follows:

int plugin_is_GPL_compatible;
This asserts that the extension is compatible with the GNU GPL (see Copying). If your extension does not have this, gawk will not load it (see Plugin License).
static gawk_api_t *const api;
This global static variable should be set to point to the gawk_api_t pointer that gawk passes to your dl_load() function. This variable is used by all of the macros.
static awk_ext_id_t ext_id;
This global static variable should be set to the awk_ext_id_t value that gawk passes to your dl_load() function. This variable is used by all of the macros.
static const char *ext_version = NULL; /* or ... = "some string" */
This global static variable should be set either to NULL, or to point to a string giving the name and version of your extension.
static awk_ext_func_t func_table[] = { ... };
This is an array of one or more awk_ext_func_t structures as described earlier (see Extension Functions). It can then be looped over for multiple calls to add_ext_func().
static awk_bool_t (*init_func)(void) = NULL;
OR
static awk_bool_t init_my_module(void) { ... }
static awk_bool_t (*init_func)(void) = init_my_module;
If you need to do some initialization work, you should define a function that does it (creates variables, opens files, etc.) and then define the init_func pointer to point to your function. The function should return awk_false upon failure, or awk_true if everything goes well.

If you don't need to do any initialization, define the pointer and initialize it to NULL.

dl_load_func(func_table, some_name, "name_space_in_quotes")
This macro expands to a dl_load() function that performs all the necessary initializations.

The point of the all the variables and arrays is to let the dl_load() function (from the dl_load_func() macro) do all the standard work. It does the following:

  1. Check the API versions. If the extension major version does not match gawk's, or if the extension minor version is greater than gawk's, it prints a fatal error message and exits.
  2. Load the functions defined in func_table. If any of them fails to load, it prints a warning message but continues on.
  3. If the init_func pointer is not NULL, call the function it points to. If it returns awk_false, print a warning message.
  4. If ext_version is not NULL, register the version string with gawk.