gawk: Extension Mechanism Outline
1
1 16.3 How It Works at a High Level
1 =================================
1
1 Communication between 'gawk' and an extension is two-way. First, when
1 an extension is loaded, 'gawk' passes it a pointer to a 'struct' whose
1
1 [image src="api-figure1.png" alt="Loading the extension" text=" API
1 Struct
1 +---+
1 | |
1 +---+
1 +---------------| |
1 | +---+ dl_load(api_p, id);
1 | | | ___________________
1 | +---+ |
1 | +---------| | __________________ |
1 | | +---+ ||
1 | | | | ||
1 | | +---+ ||
1 | | +---| | ||
1 | | | +---+ \\ || /
1 | | | \\ /
1 v v v \\/
1 +-------+-+---+-+---+-+------------------+--------------------+
1 | |x| |x| |x| |OOOOOOOOOOOOOOOOOOOO|
1 | |x| |x| |x| |OOOOOOOOOOOOOOOOOOOO|
1 | |x| |x| |x| |OOOOOOOOOOOOOOOOOOOO|
1 +-------+-+---+-+---+-+------------------+--------------------+
1
1 gawk Main Program Address Space Extension" ]
1
1 Figure 16.1: Loading the extension
1
1 The extension can call functions inside 'gawk' through these function
1 pointers, at runtime, without needing (link-time) access to 'gawk''s
1 symbols. One of these function pointers is to a function for
1
1 [image src="api-figure2.png" alt="Registering a new Function" text=" register_ext_func({ \"chdir\", do_chdir, 1 });
1
1 +--------------------------------------------+
1 | |
1 V |
1 +-------+-+---+-+---+-+------------------+--------------+-+---+
1 | |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
1 | |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
1 | |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
1 +-------+-+---+-+---+-+------------------+--------------+-+---+
1
1 gawk Main Program Address Space Extension" ]
1
1 Figure 16.2: Registering a new function
1
1 In the other direction, the extension registers its new functions
1 with 'gawk' by passing function pointers to the functions that provide
1 the new feature ('do_chdir()', for example). 'gawk' associates the
1 function pointer with a name and can then call it, using a defined
1
1 [image src="api-figure3.png" alt="Calling the new function" text=" BEGIN {
1 chdir(\"/path\") (*fnptr)(1);
1 }
1 +--------------------------------------------+
1 | |
1 | V
1 +-------+-+---+-+---+-+------------------+--------------+-+---+
1 | |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
1 | |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
1 | |x| |x| |x| |OOOOOOOOOOOOOO|X|OOO|
1 +-------+-+---+-+---+-+------------------+--------------+-+---+
1
1 gawk Main Program Address Space Extension" ]
1
1 Figure 16.3: Calling the new function
1
1 The 'do_XXX()' function, in turn, then uses the function pointers in
1 the API 'struct' to do its work, such as updating variables or arrays,
1 printing messages, setting 'ERRNO', and so on.
1
1 Convenience macros make calling through the function pointers look
1 like regular function calls so that extension code is quite readable and
1 understandable.
1
1 Although all of this sounds somewhat complicated, the result is that
1 extension code is quite straightforward to write and to read. You can
11 see this in the sample extension 'filefuncs.c' (⇒Extension
Example) and also in the 'testext.c' code for testing the APIs.
1
1 Some other bits and pieces:
1
1 * The API provides access to 'gawk''s 'do_XXX' values, reflecting
1 command-line options, like 'do_lint', 'do_profiling', and so on
1 (⇒Extension API Variables). These are informational: an
1 extension cannot affect their values inside 'gawk'. In addition,
1 attempting to assign to them produces a compile-time error.
1
1 * The API also provides major and minor version numbers, so that an
1 extension can check if the 'gawk' it is loaded with supports the
1 facilities it was compiled with. (Version mismatches "shouldn't"
11 happen, but we all know how _that_ goes.) ⇒Extension
Versioning for details.
1