gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gawk-diffs] [SCM] gawk branch, master, updated. c4206d92d5bb73c1fc55484


From: Arnold Robbins
Subject: [gawk-diffs] [SCM] gawk branch, master, updated. c4206d92d5bb73c1fc55484fbf938d2d59f18679
Date: Wed, 31 Oct 2012 19:37:21 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, master has been updated
       via  c4206d92d5bb73c1fc55484fbf938d2d59f18679 (commit)
       via  50eac5ad4b81cb3aeb699f4c7ffd71c282d09ab6 (commit)
      from  993eaa708f7785e0ab5c1b1e53ddf4abe1d835e4 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=c4206d92d5bb73c1fc55484fbf938d2d59f18679

commit c4206d92d5bb73c1fc55484fbf938d2d59f18679
Author: Arnold D. Robbins <address@hidden>
Date:   Wed Oct 31 21:36:49 2012 +0200

    Forging ahead with API documentation.

diff --git a/ChangeLog b/ChangeLog
index a63223d..e576dec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,8 @@
        * symbol.c (load_symbols): ``No automatic aggregate initialization.''
        Here too. Sigh again.
 
+       * gawkapi.h: Minor documentation edits.
+
 2012-10-28         Arnold D. Robbins     <address@hidden>
 
        * Update to bison 2.6.4. Various files regenerated.
diff --git a/doc/api.texi b/doc/api.texi
index 52d1115..71f5f6e 100644
--- a/doc/api.texi
+++ b/doc/api.texi
@@ -309,19 +309,19 @@ Fake top node.
 @node Extension API
 @chapter Writing Extensions for @command{gawk}
 
-It is possible to add new built-in
-functions to @command{gawk} using dynamically loaded libraries. This
-facility is available on systems (such as GNU/Linux) that support
-the C @code{dlopen()} and @code{dlsym()} functions.
-This @value{CHAPTER} describes how to do so using
-code written in C or C++.  If you don't know anything about C
+It is possible to add new built-in functions to @command{gawk} using
+dynamically loaded libraries. This facility is available on systems (such
+as GNU/Linux) that support the C @code{dlopen()} and @code{dlsym()}
+functions.  This @value{CHAPTER} describes how to create extensions
+using code written in C or C++.  If you don't know anything about C
 programming, you can safely skip this @value{CHAPTER}, although you
-may wish to review the documentation on the extensions that come
-with @command{gawk} (@pxref{Extension Samples}).
+may wish to review the documentation on the extensions that come with
address@hidden (@pxref{Extension Samples}), and the section on the
address@hidden project (@pxref{gawkextlib}).
 
 @quotation NOTE
 When @option{--sandbox} is specified, extensions are disabled
-(@pxref{Options}.
+(@pxref{Options}).
 @end quotation
 
 @menu
@@ -355,7 +355,8 @@ Interface} (API) defined for this purpose by the 
@command{gawk}
 developers.  The rest of this @value{CHAPTER} explains the design
 decisions behind the API, the facilities it provides and how to use
 them, and presents a small sample extension.  In addition, it documents
-the sample extensions included in the @command{gawk} distribution.
+the sample extensions included in the @command{gawk} distribution,
+and describes the @code{gawkextlib} project.
 
 @node Plugin License
 @section Extension Licensing
@@ -363,7 +364,7 @@ the sample extensions included in the @command{gawk} 
distribution.
 Every dynamic extension should define the global symbol
 @code{plugin_is_GPL_compatible} to assert that it has been licensed under
 a GPL-compatible license.  If this symbol does not exist, @command{gawk}
-will emit a fatal error and exit.
+emits a fatal error and exits when it tries to load your extension.
 
 The declared type of the symbol should be @code{int}.  It does not need
 to be in any allocated section, though.  The code merely asserts that
@@ -466,12 +467,12 @@ The ability to create, access and update global variables.
 @item
 Easy access to all the elements of an array at once (``array flattening'')
 in order to loop over all the element in an easy fashion for C code.
address@hidden itemize
 
 @item
 The ability to create arrays (including @command{gawk}'s true
 multi-dimensional arrays).
 @end itemize
address@hidden itemize
 
 Some additional important goals were:
 
@@ -480,7 +481,7 @@ Some additional important goals were:
 The API should use only features in ISO C 90, so that extensions
 can be written using the widest range of C and C++ compilers. The header
 should include the appropriate @samp{#ifdef __cplusplus} and @samp{extern "C"}
-magic so that a C++ compiler could be used.  (If using the C++, the runtime
+magic so that a C++ compiler could be used.  (If using C++, the runtime
 system has to be smart enough to call any constructors and destructors,
 as @command{gawk} is a C program. As of this writing, this has not been
 tested.)
@@ -491,7 +492,7 @@ address@hidden @dfn{symbols} are the variables and functions
 defined inside @command{gawk}.  Access to these symbols by code
 external to @command{gawk} loaded dynamically at runtime is
 problematic on Windows.} by the compile-time or dynamic linker,
-in order to enable creation of extensions that will also work on Windows.
+in order to enable creation of extensions that also work on Windows.
 @end itemize
 
 During development, it became clear that there were other features
@@ -503,7 +504,7 @@ provided:
 Extensions should have the ability to hook into @command{gawk}'s
 I/O redirection mechanism.  In particular, the @command{xgawk}
 developers provided a so-called ``open hook'' to take over reading
-records.  During the development, this was generalized to allow
+records.  During development, this was generalized to allow
 extensions to hook into input processing, output processing, and
 two-way I/O.
 
@@ -548,7 +549,7 @@ by integers are so transparent that they aren't even 
documented!)
 
 With time, the API will undoubtedly evolve; the @command{gawk} developers
 expect this to be driven by user needs. For now, the current API seems
-to provide a minimal yet powerful set of features for extension creation.
+to provide a minimal yet powerful set of features for creating extensions.
 
 @node Extension Mechanism Outline
 @subsection At A High Level How It Works
@@ -558,7 +559,7 @@ glance, a difficult one to meet.
 
 One design, apparently used by Perl and Ruby and maybe others, would
 be to make the mainline @command{gawk} code into a library, with the
address@hidden program a small C @code{main()} function linked against
address@hidden utility a small C @code{main()} function linked against
 the library.
 
 This seemed like the tail wagging the dog, complicating build and
@@ -637,8 +638,8 @@ extension code is quite readable and understandable.
 
 Although all of this sounds medium complicated, the result is that
 extension code is quite clean and straightforward. This can be seen in
-the sample extensions @file{filefuncs.c} and also the @file{testext.c}
-code for testing the APIs.
+the sample extensions @file{filefuncs.c} (@pxref{Extension Example})
+and also the @file{testext.c} code for testing the APIs.
 
 Some other bits and pieces:
 
@@ -657,11 +658,6 @@ extension can check if the @command{gawk} it is loaded 
with supports the
 facilities it was compiled with.  (Version mismatches ``shouldn't''
 happen, but we all know how @emph{that} goes.)
 @xref{Extension Versioning}, for details.
-
address@hidden
-An extension may register a version string with @command{gawk}; this
-allows @command{gawk} to dump extension version information when
-invoked with the @option{--version} option.
 @end itemize
 
 @node Extension Future Growth
@@ -671,7 +667,7 @@ The API provides room for future growth, in two ways.
 
 An ``extension id'' is passed into the extension when its loaded. This
 extension id is then passed back to @command{gawk} with each function
-call.  This allows @command{gawk} to identify the extension calling it,
+call.  This allows @command{gawk} to identify the extension calling into it,
 should it need to know.
 
 A ``name space'' is passed into @command{gawk} when an extension function
@@ -720,20 +716,20 @@ Registrations functions. You may register:
 @item
 extension functions,
 @item
-input parsers,
+exit callbacks,
 @item
-output wrappers,
+a version string,
 @item
-two-way processors,
+input parsers,
 @item
-exit callbacks,
+output wrappers,
 @item
-and a version string.
+and two-way processors.
 @end itemize
 All of these are discussed in detail, later in this @value{CHAPTER}.
 
 @item
-Printing fatal, warning, and lint warning messages.
+Printing fatal, warning, and ``lint'' warning messages.
 
 @item
 Updating @code{ERRNO}, or unsetting it.
@@ -764,7 +760,7 @@ Creating a new array
 @item
 Clearing an array
 @item
-Flattening an array for easy C style looping over an array
+Flattening an array for easy C style looping over all its indices and elements
 @end itemize
 @end itemize
 
@@ -850,13 +846,13 @@ That value must then be passed back to @command{gawk} as 
the first parameter of
 each API function.
 
 @item #define awk_const @dots{}
-This macro expands to @code{const} when compiling an extension,
+This macro expands to @samp{const} when compiling an extension,
 and to nothing when compiling @command{gawk} itself.  This makes
 certain fields in the API data structures unwritable from extension code,
 while allowing @command{gawk} to use them as it needs to.
 
 @item typedef int awk_bool_t;
-A simple boolean type. As of this moment, the API does not define special
+A simple boolean type. At the moment, the API does not define special
 ``true'' and ``false'' values, although perhaps it should.
 
 @item typedef struct @{
@@ -889,7 +885,7 @@ It is used in the following @code{struct}.
 @itemx @ @ @ @ @ @ @ @ double@ @ @ @ @ @ @ @ @ @ @ @ @ d;
 @itemx @ @ @ @ @ @ @ @ awk_array_t@ @ @ @ @ @ @ @ a;
 @itemx @ @ @ @ @ @ @ @ awk_scalar_t@ @ @ @ @ @ @ scl;
address@hidden @ @ @ @ @ @ @ @ awk_value_cookie_t vc;
address@hidden @ @ @ @ @ @ @ @ awk_value_cookie_t@ vc;
 @itemx @ @ @ @ @} u;
 @itemx @} awk_value_t;
 An address@hidden value.''  
@@ -906,11 +902,14 @@ readable.
 
 @item typedef void *awk_scalar_t;
 Scalars can be represented as an opaque type. These values are obtained from
address@hidden and then passed back into it. This is discussed below.
address@hidden and then passed back into it. This is discussed in a general 
fashion below,
+and in more detail in @ref{Symbol table by cookie}.
 
 @item typedef void *awk_value_cookie_t;
 A ``value cookie'' is an opaque type representing a cached value.
-This is also discussed below.
+This is also discussed in a general fashion below,
+and in more detail in @ref{Cached values}.
+
 @end table
 
 Scalar values in @command{awk} are either numbers or strings. The
@@ -926,7 +925,7 @@ Identifiers (i.e., the names of global variables) can be 
associated
 with either scalar values or with arrays.  In addition, @command{gawk}
 provides true arrays of arrays, where any given array element can
 itself be an array.  Discussion of arrays is delayed until
address@hidden Manipulation}
address@hidden Manipulation}.
 
 The various macros listed earlier make it easier to use the elements
 of the @code{union} as if they were fields in a @code{struct}; this
@@ -949,9 +948,9 @@ can obtain a @dfn{scalar address@hidden
 @uref{http://catb.org/jargon/html/C/cookie.html, the ``cookie'' entry in the 
Jargon file} for a
 definition of @dfn{cookie}, and 
@uref{http://catb.org/jargon/html/M/magic-cookie.html,
 the ``magic cookie'' entry in the Jargon file} for a nice example. See
-also the entry in the @ref{Glossary}.}
+also the entry for ``Cookie'' in the @ref{Glossary}.}
 object for that variable, and then use
-the cookie for getting the variable's value for changing the variable's
+the cookie for getting the variable's value or for changing the variable's
 value.
 This is the @code{awk_scalar_t} type and @code{scalar_cookie} macro.
 Given a scalar cookie, @command{gawk} can directly retrieve or
@@ -970,7 +969,7 @@ process as well as the time needed to create the value.
 
 All of the functions that return values from @command{gawk}
 work in the same way. You pass in an @code{awk_valtype_t} value
-to indicate what kind of value you want.  If the actual value
+to indicate what kind of value you expect.  If the actual value
 matches what you requested, the function returns true and fills
 in the @code{awk_value_t} result.
 Otherwise, the function returns false, and the @code{val_type}
@@ -1039,20 +1038,21 @@ the way that extension code would use them.
 This function creates a string value in the @code{awk_value_t} variable
 pointed to by @code{result}. It expects @code{string} to be a C string constant
 (or other string data), and automatically creates a @emph{copy} of the data
-for storage in @code{result}.
+for storage in @code{result}. It returns @code{result}.
 
 @item static inline awk_value_t *
 @itemx make_malloced_string(const char *string, size_t length, awk_value_t 
*result)
 This function creates a string value in the @code{awk_value_t} variable
 pointed to by @code{result}. It expects @code{string} to be a @samp{char *}
 value pointing to data previously obtained from @code{malloc()}. The idea here
-is that the data will be passed directly to @command{gawk}, which will assume
-responsibility for it.
+is that the data is passed directly to @command{gawk}, which assumes
+responsibility for it. It returns @code{result}.
 
 @item static inline awk_value_t *
 @itemx make_null_string(awk_value_t *result)
 This specialized function creates a null string (the ``undefined'' value)
 in the @code{awk_value_t} variable pointed to by @code{result}.
+It returns @code{result}.
 
 @item static inline awk_value_t *
 @itemx make_number(double num, awk_value_t *result)
@@ -1098,22 +1098,24 @@ make_malloced_string(message, strlen(message), & 
result);
 @end example
 
 @item erealloc(pointer, type, size, message)
+This is like @code{emalloc()}, but it calls @code{realloc()},
+instead of @code{malloc()}.
 The arguments are the same as for the @code{emalloc()} macro.
 @end table
 
 @node Registration Functions
 @subsection Registration Functions
 
-This @value{SECTION} describes the API functions which let you
-register parts of your extension with @command{gawk}.
+This @value{SECTION} describes the API functions for
+registering parts of your extension with @command{gawk}.
 
 @menu
 * Extension Functions::         Registering extension functions.
+* Exit Callback Functions::     Registering an exit callback.
+* Extension Version String::    Registering a version string.
 * Input Parsers::               Registering an input parser.
 * Output Wrappers::             Registering an output wrapper.
 * Two-way processors::          Registering a two-way processor.
-* Exit Callback Functions::     Registering an exit callback.
-* Extension Version String::    Registering a version string.
 @end menu
 
 @node Extension Functions
@@ -1134,13 +1136,14 @@ The fields are:
 @table @code
 @item const char *name;
 The name of the new function.
address@hidden level code will call the function by this name.
address@hidden level code calls the function by this name.
+This is a regular C string.
 
 @item awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
 This is a pointer to the C function that provides the desired
 functionality.
 The function must fill in the result with either a number
-or a string. @command{awk takes ownership of any string memory}.
+or a string. @command{awk} takes ownership of any string memory.
 As mentioned earlier, string memory @strong{must} come from @code{malloc()}.
 
 The function must return the value of @code{result}.
@@ -1161,16 +1164,64 @@ it with @command{gawk} using this API function:
 This function returns true upon success, false otherwise.
 The @code{namespace} parameter is currently not used; you should pass in an
 empty string (@code{""}).  The @code{func} pointer is the address of a
address@hidden describing your function, as just described.
address@hidden representing your function, as just described.
 @end table
 
address@hidden Exit Callback Functions
address@hidden Registering An Exit Callback Function
+
+An @dfn{exit callback} function is a function that
address@hidden calls before it exits.
+Such functions are useful if you have general ``clean up'' tasks
+that should be performed in your extension (such as closing data
+base connections or other resource deallocations).
+You can register such
+a function with @command{gawk} using the following function.
+
address@hidden @code
address@hidden void awk_atexit(void (*funcp)(void *data, int exit_status),
address@hidden @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ void *arg0);
+The parameters are:
address@hidden nested table
address@hidden @code
address@hidden funcp
+A pointer to the function to be called before @command{gawk} exits. The 
@code{data}
+parameter will be the original value of @code{arg0}.
+The @code{exit_status} parameter is
+the exit status value that @command{gawk} will pass to the @code{exit()} 
system call.
+
address@hidden arg0
+A pointer to private data which @command{gawk} saves in order to pass to
+the function pointed to by @code{funcp}.
address@hidden table
address@hidden table
+
+Exit callback functions are called in Last-In-First-Out (LIFO) order---that 
is, in
+the reverse order in which they are registered with @command{gawk}.
+
address@hidden Extension Version String
address@hidden Registering An Extension Version String
+
+You can register a version string which indicates the name and
+version of your extension, with @command{gawk}, as follows:
+
address@hidden @code
address@hidden void register_ext_version(const char *version);
+Register the string pointed to by @code{version} with @command{gawk}.
address@hidden does @emph{not} copy the @code{version} string, so
+it should not be changed.
address@hidden table
+
address@hidden prints all registered extension version strings when it
+is invoked with the @option{--version} option.
+
 @node Input Parsers
 @subsubsection Customized Input Parsers
 
 By default, @command{gawk} reads text files as its input. It uses the value
 of @code{RS} to find the end of the record, and then uses @code{FS}
-(or @code{FIELDWIDTHS}) to split it into fields.  Additionally, it sets
-the value of @code{RT} (@pxref{Built-in Variables}).
+(or @code{FIELDWIDTHS}) to split it into fields (@pxref{Reading Files}).
+Additionally, it sets the value of @code{RT} (@pxref{Built-in Variables}).
 
 If you want, you can provide your own, custom, input parser.  An input
 parser's job is to return a record to the @command{gawk} record processing
@@ -1185,8 +1236,8 @@ To provide an input parser, you must first provide two 
functions
 This function examines the information available in @code{iobuf}
 (which we discuss shortly).  Based on the information there, it
 decides if the input parser should be used for this file.
-If so, it should return true (non-zero). Otherwise, it should
-return false (zero).
+If so, it should return true. Otherwise, it should return false.
+It should not change any state (variable values, etc.) within @command{gawk}.
 
 @item awk_bool_t @var{XXX}_take_control_of(awk_input_buf_t *iobuf)
 When @command{gawk} decides to hand control of the file over to the
@@ -1210,6 +1261,23 @@ typedef struct input_parser @{
 @} awk_input_parser_t;
 @end example
 
+The fields are:
+
address@hidden @code
address@hidden const char *name;
+The name of the input parser. This is a regular C string.
+
address@hidden awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf);
+A pointer to your @address@hidden()} function.
+
address@hidden awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf);
+A pointer to your @address@hidden()} function.
+
address@hidden awk_const struct input_parser *awk_const next;
+This pointer is used by @command{gawk}.
+The extension cannot modify it.
address@hidden table
+
 The steps are as follows:
 
 @enumerate
@@ -1231,9 +1299,9 @@ typedef struct awk_input @{
     int fd;                 /* file descriptor */
 #define INVALID_HANDLE (-1)
     void *opaque;           /* private data for input parsers */
-    int (*get_record)(char **out, struct awk_input *, int *errcode,
-            char **rt_start, size_t *rt_len);
-    void (*close_func)(struct awk_input *);
+    int (*get_record)(char **out, struct awk_input *iobuf,
+                      int *errcode, char **rt_start, size_t *rt_len);
+    void (*close_func)(struct awk_input *iobuf);
     struct stat sbuf;       /* stat buf */
 @} awk_input_buf_t;
 @end example
@@ -1249,12 +1317,12 @@ The name of the file.
 
 @item int fd;
 A file descriptor for the file.  If @command{gawk} was able to
-open the file, then it will @emph{not} be equal to 
+open the file, then @code{fd} will @emph{not} be equal to 
 @code{INVALID_HANDLE}. Otherwise, it will.
 
 @item struct stat sbuf;
 If file descriptor is valid, then @command{gawk} will have filled
-in this structure with a call to the @code{fstat()} system call.
+in this structure via a call to the @code{fstat()} system call.
 @end table
 
 The @address@hidden()} function should examine these
@@ -1266,7 +1334,7 @@ file, whether or not the file descriptor is valid, the 
information
 in the @code{struct stat}, or any combination of the above.
 
 Once @address@hidden()} has returned true, and
address@hidden has decided to use your input parser, it will call
address@hidden has decided to use your input parser, it calls
 @address@hidden()}.  That function then fills in at
 least the @code{get_record} field of the @code{awk_input_buf_t}.  It must
 also ensure that @code{fd} is not set to @code{INVALID_HANDLE}.  All of
@@ -1279,24 +1347,28 @@ This is used to hold any state information needed by 
the input parser
 for this file.  It is ``opaque'' to @command{gawk}.  The input parser
 is not required to use this pointer.
 
address@hidden int (*get_record)(char **out, struct awk_input *, int *errcode,
address@hidden                   char **rt_start, size_t *rt_len);
-This is a function pointer that should be set to point to the
-function that creates the input records.
-Said function is the core of the input parser.  Its behavior is
-described below.
address@hidden int@ (*get_record)(char@ **out,
address@hidden @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ struct@ awk_input *iobuf,
address@hidden @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ int *errcode,
address@hidden @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ char **rt_start,
address@hidden @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ size_t *rt_len);
+This function pointer should point to a function that creates the input
+records.  Said function is the core of the input parser.  Its behavior
+is described below.
+
address@hidden void (*close_func)(struct awk_input *iobuf);
+This function pointer should point to a function that does
+the ``tear down.'' It should release any resources allocated by
address@hidden@var{XXX}_take_control_of()}.  It may also close the file. If it
+does so, it shold set the @code{fd} field to @code{INVALID_HANDLE}.
 
address@hidden void (*close_func)(struct awk_input *);
-This is a function pointer that should be set to point to the
-function that does the ``tear down.'' It should release any resources
-allocated by @address@hidden()}.  It may also close
-the file. If it does so, it shold set the @code{fd} field to
address@hidden
+If @code{fd} is still not @code{INVALID_HANDLE} after the call to this
+function, @command{gawk} calls the regular @code{close()} system call.
 
 Having a ``tear down'' function is optional. If your input parser does
-not need it, do not set this field.  In that case, @command{gawk}
-will close the regular @code{close()} system call on the
-file descriptor, so it should be valid.
+not need it, do not set this field.  Then, @command{gawk} calls the
+regular @code{close()} system call on the file descriptor, so it should
+be valid.
 @end table
 
 The @address@hidden()} function does the work of creating
@@ -1305,7 +1377,7 @@ input records.  The parameters are as follows:
 @table @code
 @item char **out
 This is a pointer to a @code{char *} variable which is set to point
-to the record.  @command{gawk} will make its own copy of the data, so
+to the record.  @command{gawk} makes its own copy of the data, so
 the extension must manage this storage.
 
 @item struct awk_input *iobuf
@@ -1337,13 +1409,13 @@ to zero, so there is no need to set it unless an error 
occurs.
 
 If an error does occur, the function should return @code{EOF} and set
 @code{*errcode} to a non-zero value.  In that case, if @code{*errcode}
-does not equal @minus{}1, @command{gawk|} will automatically update
+does not equal @minus{}1, @command{gawk} automatically updates
 the @code{ERRNO} variable based on the value of @code{*errcode} (e.g.,
 setting @samp{*errcode = errno} should do the right thing).
 
address@hidden ships with a sample extension (@pxref{Extension Sample
-Readdir}) that reads directories, returning records for each entry in
-the directory.  You may wish to use that code as a guide for writing
address@hidden ships with a sample extension that reads directories,
+returning records for each entry in the directory (@pxref{Extension
+Sample Readdir}).  You may wish to use that code as a guide for writing
 your own input parser.
 
 When writing an input parser, you should think about (and document)
@@ -1352,9 +1424,9 @@ it to always be called, and take effect as appropriate 
(as the
 @code{readdir} extension does).  Or you may want it to take effect
 based upon the value of an @code{awk} variable, as the XML extension
 from the @code{gawkextlib} project does (@pxref{gawkextlib}).
-In the latter case, code in a @code{BEGINFILE} section 
(@pxref{BEGINFILE/ENDFILE}).
+In the latter case, code in a @code{BEGINFILE} section
 can look at @code{FILENAME} and @code{ERRNO} to decide whether or
-not to activate an input parser.
+not to activate an input parser (@pxref{BEGINFILE/ENDFILE}).
 
 You register your input parser with the following function:
 
@@ -1368,8 +1440,8 @@ Register the input parser pointed to by 
@code{input_parser} with
 @subsubsection Customized Output Wrappers
 
 An @dfn{output wrapper} is the mirror image of an input parser.
-It allows an extension to take over the output to a file (opened
-with the @samp{>} or @samp{>>} operators, @pxref{Redirection}).
+It allows an extension to take over the output to a file opened
+with the @samp{>} or @samp{>>} operators (@pxref{Redirection}).
 
 The output wrapper is very similar to the input parser structure:
 
@@ -1432,7 +1504,7 @@ The data members are as follows:
 The name of the output file.
 
 @item const char *mode;
-The mode string (as would be used in the second argument to @code{fopen()}
+The mode string (as would be used in the second argument to @code{fopen()})
 with which the file was opened.
 
 @item FILE *fp;
@@ -1440,7 +1512,7 @@ The @code{FILE} pointer from @code{<stdio.h>}. 
@command{gawk} opens the file
 before attempting to find an output wrapper.
 
 @item awk_bool_t redirected;
-The field should be set to true in the @address@hidden()} function.
+This field must be set to true by the @address@hidden()} function.
 
 @item void *opaque;
 This pointer is opaque to @command{gawk}. The extension should use it to store
@@ -1481,7 +1553,7 @@ Register the output wrapper pointed to by 
@code{output_wrapper} with
 
 A @dfn{two-way processor} combines an input parser and an output wrapper for
 two-way I/O with the @samp{|&} operator (@pxref{Redirection}).  It makes 
identical
-use of the @code{awk_input_parser_t} and @code{awk_output_buf_t} structures,
+use of the @code{awk_input_parser_t} and @code{awk_output_buf_t} structures
 as described earlier.
 
 A two-way processor is represented by the following structure:
@@ -1490,7 +1562,9 @@ A two-way processor is represented by the following 
structure:
 typedef struct two_way_processor @{
     const char *name;   /* name of the two-way processor */
     awk_bool_t (*can_take_two_way)(const char *name);
-    awk_bool_t (*take_control_of)(const char *name, awk_input_buf_t *inbuf, 
awk_output_buf_t *outbuf);
+    awk_bool_t (*take_control_of)(const char *name,
+                                  awk_input_buf_t *inbuf,
+                                  awk_output_buf_t *outbuf);
     awk_const struct two_way_processor *awk_const next;  /* for use by gawk */
 @} awk_two_way_processor_t;
 @end example
@@ -1502,9 +1576,13 @@ The fields are as follows:
 The name of the two-way processor.
 
 @item awk_bool_t (*can_take_two_way)(const char *name);
-This function returns true if it wants to take over the two-way I/O for this 
filename.
+This function returns true if it wants to take over two-way I/O for this 
filename.
+It should not change any state (variable
+values, etc.) within @command{gawk}.
 
address@hidden awk_bool_t (*take_control_of)(const char *name, awk_input_buf_t 
*inbuf, awk_output_buf_t *outbuf);
address@hidden awk_bool_t (*take_control_of)(const char *name,
address@hidden @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 
awk_input_buf_t *inbuf,
address@hidden @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 
awk_output_buf_t *outbuf);
 This function should fill in the @code{awk_input_buf_t} and
 @code{awk_outut_buf_t} structures pointed to by @code{inbuf} and
 @code{outbuf}, respectively.  These structures were described earlier.
@@ -1525,52 +1603,6 @@ Register the two-way processor pointed to by 
@code{two_way_processor} with
 @command{gawk}.
 @end table
 
address@hidden Exit Callback Functions
address@hidden Registering An Exit Callback Function
-
-An @dfn{exit callback} function is a function that
address@hidden calls before it exits.
-Such functions are useful if you have general ``clean up'' tasks
-that should be performed in your extension (such as closing data
-base connections or other resource deallocations).
-You can register such
-a function with @command{gawk} using the following function.
-
address@hidden @code
address@hidden void awk_atexit(void (*funcp)(void *data, int exit_status),
address@hidden @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ void *arg0);
-The parameters are:
address@hidden nested table
address@hidden @code
address@hidden funcp
-Points to the function to be called before @command{gawk} exits. The 
@code{data}
-parameter will be the original value of @code{arg0}.
-The @code{exit_status} parameter is
-the exit status value that @command{gawk} will pass to the @code{exit()} 
system call.
-
address@hidden arg0
-A pointer to private data which @command{gawk} saves in order to pass to
-the function pointed to by @code{funcp}.
address@hidden table
address@hidden table
-
-Exit callback functions are called in Last-In-First-Out (LIFO) order---that 
is, in
-the reverse order in which they are registered with @command{gawk}.
-
address@hidden Extension Version String
address@hidden Registering An Extension Version String
-
-You can register a version string which indicates the name and
-version of your extension, with @command{gawk}, as follows:
-
address@hidden @code
address@hidden void register_ext_version(const char *version);
-Register the string pointed to by @code{version} with @command{gawk}.
address@hidden table
-
address@hidden prints all registered extension version strings when it
-is invoked with the @option{--version} option.
-
 @node Printing Messages
 @subsection Printing Messages
 
@@ -1591,7 +1623,7 @@ Print a warning message.
 @item void lintwarn(awk_ext_id_t id, const char *format, ...);
 Print a ``lint warning.''  Normally this is the same as printing a
 warning message, but if @command{gawk} was invoked with @samp{--lint=fatal},
-then they become fatal error messages.
+then lint warnings become fatal error messages.
 @end table
 
 All of these functions are otherwise like the C @code{printf()}
@@ -1602,18 +1634,18 @@ with literal characters and formatting codes intermixed.
 @subsection Updating @code{ERRNO}
 
 The following functions allow you to update the @code{ERRNO}
-variable.
+variable:
 
 @table @code
 @item void update_ERRNO_int(int errno_val);
 Set @code{ERRNO} to the string equivalent of the error code
 in @code{errno_val}. The value should be one of the defined
-error codes in @code{<errno.h>}, and @command{gawk} will turn it
+error codes in @code{<errno.h>}, and @command{gawk} turns it
 into a (possibly translated) string using the C @code{strerror()} function.
 
 @item void update_ERRNO_string(const char *string);
 Set @code{ERRNO} directly to the string value of @code{ERRNO}.
address@hidden will make a copy of the value of @code{string}.
address@hidden makes a copy of the value of @code{string}.
 
 @item void unset_ERRNO();
 Unset @code{ERRNO}.
@@ -1674,7 +1706,7 @@ In the latter case, @code{result->val_type} indicates the 
actual type.
 
 @item awk_bool_t sym_update(const char *name, awk_value_t *value);
 Update the variable named by the string @code{name}, which is a regular
-C string.  The variable will be added to @command{gawk}'s symbol table
+C string.  The variable is added to @command{gawk}'s symbol table
 if it is not there.  Return true if everything worked, false otherwise.
 
 Changing types (scalar to array or vice versa) of an existing variable
@@ -1715,7 +1747,7 @@ Return false if the value cannot be retrieved.
 
 @item awk_bool_t sym_update_scalar(awk_scalar_t cookie, awk_value_t *value);
 Update the value associated with a scalar cookie.
-Return will be false if the new value is not one of
+Return false if the new value is not one of
 @code{AWK_STRING} or @code{AWK_NUMBER}.
 Here too, the built-in variables may not be updated.
 @end table
@@ -1886,7 +1918,7 @@ Using value cookies in this way saves considerable 
storage, since all of
 
 You might be wondering, ``Is this sharing problematic?
 What happens if @command{awk} code assigns a new value to @code{VAR1},
-will all the others be changed too?''
+are all the others be changed too?''
 
 That's a great question. The answer is that no, it's not a problem.
 @command{gawk} is smart enough to avoid such problems.
@@ -1962,7 +1994,7 @@ that traverses the list.
 @itemx @ @ @ @ awk_element_t elements[1];@ @ /* will be extended */
 @itemx @} awk_flat_array_t;
 This is a flattened array. When an extension gets one of these
-from @command{gawk}, the @code{elements} array will be of actual
+from @command{gawk}, the @code{elements} array is of actual
 size @code{count}.
 The @code{opaque1} and @code{opaque2} pointers are for use by @command{gawk};
 therefore they are marked @code{awk_const} so that the extension cannot
@@ -1987,7 +2019,7 @@ Return false if there is an error.
 For the array represented by @code{a_cookie}, return in @code{*result}
 the value of the element whose index is @code{index}.
 The value for @code{index} can be numeric, in which case @command{gawk}
-will convert it to a string. Using non-integral values is possible, but
+converts it to a string. Using non-integral values is possible, but
 requires that you understand how such values are converted to strings
 (@pxref{Conversion}); thus using integral values is safest.
 @code{wanted} specifies the type of value you wish to retrieve.
@@ -1996,7 +2028,7 @@ Return false if @code{wanted} does not match the actual 
type or if
 
 As with @emph{all} strings passed into @code{gawk} from an extension,
 the string value of @code{index} must come from @code{malloc()}, and
address@hidden will release the storage.
address@hidden releases the storage.
 
 @item awk_bool_t set_array_element(awk_array_t a_cookie,
 @itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ const@ 
awk_value_t *const index,
@@ -2201,7 +2233,7 @@ have this flag bit set.
 The sixth step is to release the flattened array. This tells
 @command{gawk} that the extension is no longer using the array,
 and that it should delete any elements marked for deletion.
address@hidden will also free any storage that was allocated,
address@hidden also frees any storage that was allocated,
 so you should not use the pointer (@code{flat_array} in this
 code) once you have called @code{release_flattened_array()}:
 
@@ -2228,12 +2260,12 @@ Here is the output from running this part of the test:
 pets has 5 elements
 dump_array_and_delete: sym_lookup of pets passed
 dump_array_and_delete: incoming size is 5
-       pets["1"] = "blacky"
-       pets["2"] = "rusty"
-       pets["3"] = "sophie"
+        pets["1"] = "blacky"
+        pets["2"] = "rusty"
+        pets["3"] = "sophie"
 dump_array_and_delete: marking element "3" for deletion
-       pets["4"] = "raincloud"
-       pets["5"] = "lucky"
+        pets["4"] = "raincloud"
+        pets["5"] = "lucky"
 dump_array_and_delete(pets) returned 1
 dump_array_and_delete() did remove index "3"!
 @end example
@@ -2437,7 +2469,7 @@ $ @kbd{AWKLIBPATH=$PWD ./gawk -f foo.awk}
 @end example
 
 @node Extension API Variables
address@hidden Variables
address@hidden API Variables
 
 The API provides two sets of variables.  The first provides information
 about the version of the API (both with which the extension was compiled,
@@ -2512,23 +2544,23 @@ whether the corresponding command-line options were 
enabled when
 
 @table @code
 @item do_lint
-This variable will be true if the @option{--lint} option was passed
+This variable is true if the @option{--lint} option was passed
 (@pxref{Options}).
 
 @item do_traditional
-This variable will be true if the @option{--traditional} option was passed.
+This variable is true if the @option{--traditional} option was passed.
 
 @item do_profile
-This variable will be true if the @option{--profile} option was passed.
+This variable is true if the @option{--profile} option was passed.
 
 @item do_sandbox
-This variable will be true if the @option{--sandbox} option was passed.
+This variable is true if the @option{--sandbox} option was passed.
 
 @item do_debug
-This variable will be true if the @option{--debug} option was passed.
+This variable is true if the @option{--debug} option was passed.
 
 @item do_mpfr
-This variable will be true if the @option{--bignum} option was passed.
+This variable is true if the @option{--bignum} option was passed.
 @end table
 
 The value of @code{do_lint} can change if @command{awk} code
@@ -3195,7 +3227,7 @@ implement system calls such as @code{chown()}, 
@code{chmod()},
 and @code{umask()}.
 
 @node Using Internal File Ops
address@hidden Integrating the Extensions
address@hidden Integrating The Extensions
 
 @cindex @command{gawk}, address@hidden adding code to
 Now that the code is written, it must be possible to add it at
@@ -3277,7 +3309,7 @@ $ @kbd{AWKLIBPATH=$PWD gawk -f testff.awk}
 @end example
 
 @node Extension Samples
address@hidden The Sample Extensions in the @command{gawk} Distribution
address@hidden The Sample Extensions In The @command{gawk} Distribution
 
 This @value{SECTION} provides brief overviews of the sample extensions
 that come in the @command{gawk} distribution. Some of them are intended
@@ -3587,7 +3619,7 @@ if (fnmatch("*.a", "foo.c", flags) == FNM_NOMATCH)
 @end example
 
 @node Extension Sample Fork
address@hidden Interface to @code{fork()}, @code{wait()} and @code{waitpid()}
address@hidden Interface To @code{fork()}, @code{wait()} and @code{waitpid()}
 
 The @code{fork} extension adds three functions, as follows.
 
@@ -3713,7 +3745,7 @@ On GNU/Linux systems, there are filesystems that don't 
support the
 @code{d_type} entry (see the @i{readdir}(3) manual page), and so the file
 type is always @code{u}.  Therefore, using @samp{readdir_do_ftype("stat")}
 is advisable even on GNU/Linux systems.  In this case, the @code{readdir}
-extension will fall back to using @code{lstat()} when it encounters an
+extension falls back to using @code{lstat()} when it encounters an
 unknown file type.
 @end quotation
 
@@ -3790,7 +3822,7 @@ Here too, the return value is 1 on success and 0 on 
failure.
 The array created by @code{reada()} is identical to that written by
 @code{writea()} in the sense that the contents are the same. However,
 due to implementation issues, the array traversal order of the recreated
-array will likely be different from that of the original array.  As array
+array is likely to be different from that of the original array.  As array
 traversal order in @command{awk} is by default undefined, this is not
 (technically) a problem.  If you need to guarantee a particular traversal
 order, use the array sorting features in @command{gawk} to do so.
@@ -3967,6 +3999,7 @@ make && make check                    @ii{Build and check 
that all is OK}
 * String Functions::            String-Manipulation Functions.
 * Glossary::                    Glossary.
 * Copying::                     GNU General Public License.
+* Reading Files::               Reading Input Files.
 @end menu
 
 @node Reference to Elements
@@ -4008,4 +4041,7 @@ make && make check                    @ii{Build and check 
that all is OK}
 @node Copying
 @section GNU General Public License
 
address@hidden Reading Files
address@hidden Reading Input Files
+
 @bye
diff --git a/gawkapi.h b/gawkapi.h
index 4466ef3..45f86a0 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -141,7 +141,7 @@ typedef struct awk_input {
         * Gawk itself will close the fd unless close_func first sets it to
         * INVALID_HANDLE.
         */
-       void (*close_func)(struct awk_input *);
+       void (*close_func)(struct awk_input *iobuf);
 
        /* put last, for alignment. bleah */
        struct stat sbuf;       /* stat buf */

http://git.sv.gnu.org/cgit/gawk.git/commit/?id=50eac5ad4b81cb3aeb699f4c7ffd71c282d09ab6

commit 50eac5ad4b81cb3aeb699f4c7ffd71c282d09ab6
Author: Arnold D. Robbins <address@hidden>
Date:   Wed Oct 31 20:31:39 2012 +0200

    Create figures for API doc.

diff --git a/doc/ChangeLog b/doc/ChangeLog
index 9e85bae..f3a89e9 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,10 @@
+2012-10-31         Arnold D. Robbins     <address@hidden>
+
+       * api-figure1.eps, api-figure1.fig, api-figure1.pdf,
+       api-figure2.eps, api-figure2.fig, api-figure2.pdf,
+       api-figure3.eps, api-figure3.fig, api-figure3.pdf: New files.
+       * Makefile.am (EXTRA_DIST): Add the above.
+
 2012-10-28         Arnold D. Robbins     <address@hidden>
 
        * gawk.texi (Glossary): Document cookie, some cleanup of
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 0e4c85a..27d2647 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -30,6 +30,9 @@ man_MANS = gawk.1 igawk.1
 
 EXTRA_DIST = ChangeLog ChangeLog.0 README.card ad.block setter.outline \
        awkcard.in awkforai.txt texinfo.tex cardfonts \
+       api-figure1.eps api-figure1.fig api-figure1.pdf \
+       api-figure2.eps api-figure2.fig api-figure2.pdf \
+       api-figure3.eps api-figure3.fig api-figure3.pdf \
        general-program.eps general-program.fig general-program.pdf \
        process-flow.eps process-flow.fig process-flow.pdf \
        macros colors no.colors $(man_MANS) \
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 6ec65cc..bc3b730 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -274,6 +274,9 @@ info_TEXINFOS = gawk.texi gawkinet.texi
 man_MANS = gawk.1 igawk.1
 EXTRA_DIST = ChangeLog ChangeLog.0 README.card ad.block setter.outline \
        awkcard.in awkforai.txt texinfo.tex cardfonts \
+       api-figure1.eps api-figure1.fig api-figure1.pdf \
+       api-figure2.eps api-figure2.fig api-figure2.pdf \
+       api-figure3.eps api-figure3.fig api-figure3.pdf \
        general-program.eps general-program.fig general-program.pdf \
        process-flow.eps process-flow.fig process-flow.pdf \
        macros colors no.colors $(man_MANS) \
diff --git a/doc/api-figure1.eps b/doc/api-figure1.eps
new file mode 100644
index 0000000..7af094c
--- /dev/null
+++ b/doc/api-figure1.eps
@@ -0,0 +1,536 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Title: api-figure1.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5d
+%%CreationDate: Wed Oct 31 20:16:08 2012
+%%BoundingBox: 0 0 399 227
+%Magnification: 1.0000
+%%EndComments
+%%BeginProlog
+/MyAppDict 100 dict dup begin def
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+
+% This junk string is used by the show operators
+/PATsstr 1 string def
+/PATawidthshow {       % cx cy cchar rx ry string
+  % Loop over each character in the string
+  {  % cx cy cchar rx ry char
+    % Show the character
+    dup                                % cx cy cchar rx ry char char
+    PATsstr dup 0 4 -1 roll put        % cx cy cchar rx ry char (char)
+    false charpath             % cx cy cchar rx ry char
+    /clip load PATdraw
+    % Move past the character (charpath modified the
+    % current point)
+    currentpoint                       % cx cy cchar rx ry char x y
+    newpath
+    moveto                     % cx cy cchar rx ry char
+    % Reposition by cx,cy if the character in the string is cchar
+    3 index eq {                       % cx cy cchar rx ry
+      4 index 4 index rmoveto
+    } if
+    % Reposition all characters by rx ry
+    2 copy rmoveto             % cx cy cchar rx ry
+  } forall
+  pop pop pop pop pop          % -
+  currentpoint
+  newpath
+  moveto
+} bind def
+/PATcg {
+  7 dict dup begin
+    /lw currentlinewidth def
+    /lc currentlinecap def
+    /lj currentlinejoin def
+    /ml currentmiterlimit def
+    /ds [ currentdash ] def
+    /cc [ currentrgbcolor ] def
+    /cm matrix currentmatrix def
+  end
+} bind def
+% PATdraw - calculates the boundaries of the object and
+% fills it with the current pattern
+/PATdraw {                     % proc
+  save exch
+    PATpcalc                   % proc nw nh px py
+    5 -1 roll exec             % nw nh px py
+    newpath
+    PATfill                    % -
+  restore
+} bind def
+% PATfill - performs the tiling for the shape
+/PATfill { % nw nh px py PATfill -
+  PATDict /CurrentPattern get dup begin
+    setfont
+    % Set the coordinate system to Pattern Space
+    PatternGState PATsg
+    % Set the color for uncolored pattezns
+    PaintType 2 eq { PATDict /PColor get PATsc } if
+    % Create the string for showing
+    3 index string             % nw nh px py str
+    % Loop for each of the pattern sources
+    0 1 Multi 1 sub {          % nw nh px py str source
+       % Move to the starting location
+       3 index 3 index         % nw nh px py str source px py
+       moveto                  % nw nh px py str source
+       % For multiple sources, set the appropriate color
+       Multi 1 ne { dup PC exch get PATsc } if
+       % Set the appropriate string for the source
+       0 1 7 index 1 sub { 2 index exch 2 index put } for pop
+       % Loop over the number of vertical cells
+       3 index                 % nw nh px py str nh
+       {                       % nw nh px py str
+         currentpoint          % nw nh px py str cx cy
+         2 index oldshow       % nw nh px py str cx cy
+         YStep add moveto      % nw nh px py str
+       } repeat                % nw nh px py str
+    } for
+    5 { pop } repeat
+  end
+} bind def
+
+% PATkshow - kshow with the current pattezn
+/PATkshow {                    % proc string
+  exch bind                    % string proc
+  1 index 0 get                        % string proc char
+  % Loop over all but the last character in the string
+  0 1 4 index length 2 sub {
+                               % string proc char idx
+    % Find the n+1th character in the string
+    3 index exch 1 add get     % string proc char char+1
+    exch 2 copy                        % strinq proc char+1 char char+1 char
+    % Now show the nth character
+    PATsstr dup 0 4 -1 roll put        % string proc chr+1 chr chr+1 (chr)
+    false charpath             % string proc char+1 char char+1
+    /clip load PATdraw
+    % Move past the character (charpath modified the current point)
+    currentpoint newpath moveto
+    % Execute the user proc (should consume char and char+1)
+    mark 3 1 roll              % string proc char+1 mark char char+1
+    4 index exec               % string proc char+1 mark...
+    cleartomark                        % string proc char+1
+  } for
+  % Now display the last character
+  PATsstr dup 0 4 -1 roll put  % string proc (char+1)
+  false charpath               % string proc
+  /clip load PATdraw
+  neewath
+  pop pop                      % -
+} bind def
+% PATmp - the makepattern equivalent
+/PATmp {                       % patdict patmtx PATmp patinstance
+  exch dup length 7 add                % We will add 6 new entries plus 1 FID
+  dict copy                    % Create a new dictionary
+  begin
+    % Matrix to install when painting the pattern
+    TilingType PATtcalc
+    /PatternGState PATcg def
+    PatternGState /cm 3 -1 roll put
+    % Check for multi pattern sources (Level 1 fast color patterns)
+    currentdict /Multi known not { /Multi 1 def } if
+    % Font dictionary definitions
+    /FontType 3 def
+    % Create a dummy encoding vector
+    /Encoding 256 array def
+    3 string 0 1 255 {
+      Encoding exch dup 3 index cvs cvn put } for pop
+    /FontMatrix matrix def
+    /FontBBox BBox def
+    /BuildChar {
+       mark 3 1 roll           % mark dict char
+       exch begin
+       Multi 1 ne {PaintData exch get}{pop} ifelse  % mark [paintdata]
+         PaintType 2 eq Multi 1 ne or
+         { XStep 0 FontBBox aload pop setcachedevice }
+         { XStep 0 setcharwidth } ifelse
+         currentdict           % mark [paintdata] dict
+         /PaintProc load       % mark [paintdata] dict paintproc
+       end
+       gsave
+         false PATredef exec true PATredef
+       grestore
+       cleartomark             % -
+    } bind def
+    currentdict
+  end                          % newdict
+  /foo exch                    % /foo newlict
+  definefont                   % newfont
+} bind def
+% PATpcalc - calculates the starting point and width/height
+% of the tile fill for the shape
+/PATpcalc {    % - PATpcalc nw nh px py
+  PATDict /CurrentPattern get begin
+    gsave
+       % Set up the coordinate system to Pattern Space
+       % and lock down pattern
+       PatternGState /cm get setmatrix
+       BBox aload pop pop pop translate
+       % Determine the bounding box of the shape
+       pathbbox                        % llx lly urx ury
+    grestore
+    % Determine (nw, nh) the # of cells to paint width and height
+    PatHeight div ceiling              % llx lly urx qh
+    4 1 roll                           % qh llx lly urx
+    PatWidth div ceiling               % qh llx lly qw
+    4 1 roll                           % qw qh llx lly
+    PatHeight div floor                        % qw qh llx ph
+    4 1 roll                           % ph qw qh llx
+    PatWidth div floor                 % ph qw qh pw
+    4 1 roll                           % pw ph qw qh
+    2 index sub cvi abs                        % pw ph qs qh-ph
+    exch 3 index sub cvi abs exch      % pw ph nw=qw-pw nh=qh-ph
+    % Determine the starting point of the pattern fill
+    %(px, py)
+    4 2 roll                           % nw nh pw ph
+    PatHeight mul                      % nw nh pw py
+    exch                               % nw nh py pw
+    PatWidth mul exch                  % nw nh px py
+  end
+} bind def
+
+% Save the original routines so that we can use them later on
+/oldfill       /fill load def
+/oldeofill     /eofill load def
+/oldstroke     /stroke load def
+/oldshow       /show load def
+/oldashow      /ashow load def
+/oldwidthshow  /widthshow load def
+/oldawidthshow /awidthshow load def
+/oldkshow      /kshow load def
+
+% These defs are necessary so that subsequent procs don't bind in
+% the originals
+/fill     { oldfill } bind def
+/eofill           { oldeofill } bind def
+/stroke           { oldstroke } bind def
+/show     { oldshow } bind def
+/ashow    { oldashow } bind def
+/widthshow { oldwidthshow } bind def
+/awidthshow { oldawidthshow } bind def
+/kshow            { oldkshow } bind def
+/PATredef {
+  MyAppDict begin
+    {
+    /fill { /clip load PATdraw newpath } bind def
+    /eofill { /eoclip load PATdraw newpath } bind def
+    /stroke { PATstroke } bind def
+    /show { 0 0 null 0 0 6 -1 roll PATawidthshow } bind def
+    /ashow { 0 0 null 6 3 roll PATawidthshow }
+    bind def
+    /widthshow { 0 0 3 -1 roll PATawidthshow }
+    bind def
+    /awidthshow { PATawidthshow } bind def
+    /kshow { PATkshow } bind def
+  } {
+    /fill   { oldfill } bind def
+    /eofill { oldeofill } bind def
+    /stroke { oldstroke } bind def
+    /show   { oldshow } bind def
+    /ashow  { oldashow } bind def
+    /widthshow { oldwidthshow } bind def
+    /awidthshow { oldawidthshow } bind def
+    /kshow  { oldkshow } bind def
+    } ifelse
+  end
+} bind def
+false PATredef
+% Conditionally define setcmykcolor if not available
+/setcmykcolor where { pop } {
+  /setcmykcolor {
+    1 sub 4 1 roll
+    3 {
+       3 index add neg dup 0 lt { pop 0 } if 3 1 roll
+    } repeat
+    setrgbcolor - pop
+  } bind def
+} ifelse
+/PATsc {               % colorarray
+  aload length         % c1 ... cn length
+    dup 1 eq { pop setgray } { 3 eq { setrgbcolor } { setcmykcolor
+  } ifelse } ifelse
+} bind def
+/PATsg {               % dict
+  begin
+    lw setlinewidth
+    lc setlinecap
+    lj setlinejoin
+    ml setmiterlimit
+    ds aload pop setdash
+    cc aload pop setrgbcolor
+    cm setmatrix
+  end
+} bind def
+
+/PATDict 3 dict def
+/PATsp {
+  true PATredef
+  PATDict begin
+    /CurrentPattern exch def
+    % If it's an uncolored pattern, save the color
+    CurrentPattern /PaintType get 2 eq {
+      /PColor exch def
+    } if
+    /CColor [ currentrgbcolor ] def
+  end
+} bind def
+% PATstroke - stroke with the current pattern
+/PATstroke {
+  countdictstack
+  save
+  mark
+  {
+    currentpoint strokepath moveto
+    PATpcalc                           % proc nw nh px py
+    clip newpath PATfill
+    } stopped {
+       (*** PATstroke Warning: Path is too complex, stroking
+         with gray) =
+    cleartomark
+    restore
+    countdictstack exch sub dup 0 gt
+       { { end } repeat } { pop } ifelse
+    gsave 0.5 setgray oldstroke grestore
+  } { pop restore pop } ifelse
+  newpath
+} bind def
+/PATtcalc {            % modmtx tilingtype PATtcalc tilematrix
+  % Note: tiling types 2 and 3 are not supported
+  gsave
+    exch concat                                        % tilingtype
+    matrix currentmatrix exch                  % cmtx tilingtype
+    % Tiling type 1 and 3: constant spacing
+    2 ne {
+       % Distort the pattern so that it occupies
+       % an integral number of device pixels
+       dup 4 get exch dup 5 get exch           % tx ty cmtx
+       XStep 0 dtransform
+       round exch round exch                   % tx ty cmtx dx.x dx.y
+       XStep div exch XStep div exch           % tx ty cmtx a b
+       0 YStep dtransform
+       round exch round exch                   % tx ty cmtx a b dy.x dy.y
+       YStep div exch YStep div exch           % tx ty cmtx a b c d
+       7 -3 roll astore                        % { a b c d tx ty }
+    } if
+  grestore
+} bind def
+/PATusp {
+  false PATredef
+  PATDict begin
+    CColor PATsc
+  end
+} bind def
+
+% right30
+11 dict begin
+/PaintType 1 def
+/PatternType 1 def
+/TilingType 1 def
+/BBox [0 0 1 1] def
+/XStep 1 def
+/YStep 1 def
+/PatWidth 1 def
+/PatHeight 1 def
+/Multi 2 def
+/PaintData [
+  { clippath } bind
+  { 32 16 true [ 32 0 0 -16 0 16 ]
+       {<00030003000c000c0030003000c000c0030003000c000c00
+       30003000c000c00000030003000c000c0030003000c000c0
+       030003000c000c0030003000c000c000>}
+     imagemask } bind
+] def
+/PaintProc {
+       pop
+       exec fill
+} def
+currentdict
+end
+/P2 exch def
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+/pageheader {
+save
+newpath 0 227 moveto 0 0 lineto 399 0 lineto 399 227 lineto closepath clip 
newpath
+-194.8 350.2 translate
+1 -1 scale
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
+%
+% Fig objects follow
+%
+% 
+% here starts figure with depth 50
+% Arc
+7.500 slw
+0 slc
+gs  clippath
+3599 4000 m 3567 4148 l 3626 4161 l 3658 4013 l 3658 4013 l 3603 4124 l 3599 
4000 l cp
+eoclip
+n 5449.3 4471.5 1878.7 -70.5453 -169.8379 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+0 slj
+n 3599 4000 m 3603 4124 l 3658 4013 l 3599 4000 l  cp gs 0.00 setgray ef gr  
col0 s
+% Arc
+gs  clippath
+4422 4004 m 4425 4155 l 4485 4154 l 4482 4003 l 4482 4003 l 4455 4124 l 4422 
4004 l cp
+eoclip
+n 5539.0 4051.3 1087.6 -60.4713 175.3232 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+n 4422 4004 m 4455 4124 l 4482 4003 l 4422 4004 l  cp gs 0.00 setgray ef gr  
col0 s
+% Arc
+gs  clippath
+4986 4010 m 5012 4159 l 5072 4149 l 5046 4000 l 5046 4000 l 5037 4124 l 4986 
4010 l cp
+eoclip
+n 5628.8 3967.5 613.5 -36.7999 163.6698 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+n 4986 4010 m 5037 4124 l 5046 4000 l 4986 4010 l  cp gs 0.00 setgray ef gr  
col0 s
+% Arc
+135.000 slw
+gs  clippath
+7736 3835 m 7756 3984 l 7907 3964 l 7887 3814 l 7841 3821 l 7828 3944 l 7782 
3829 l cp
+eoclip
+n 6609.1 4056.9 1224.8 -93.9364 -4.5364 arc
+gs col0 s gr
+ gr
+
+% arrowhead
+7.500 slw
+n 7782 3829 m 7828 3944 l 7841 3821 l  col0 s
+% Polyline
+n 3105 4140 m 6660 4140 l 6660 5085 l 3105 5085 l
+ cp gs col0 s gr 
+% Polyline
+n 6660 4140 m 8730 4140 l 8730 5085 l 6660 5085 l
+ cp gs col7 0.50 shd ef gr gs col0 s gr 
+% Polyline
+n 5805 2610 m 6345 2610 l 6345 3690 l 5805 3690 l
+ cp gs col0 s gr 
+% Polyline
+n 5805 2835 m 6345 2835 l 6345 3015 l 5805 3015 l
+ cp gs col0 s gr 
+% Polyline
+n 5805 3195 m 6345 3195 l 6345 3375 l 5805 3375 l
+ cp gs col0 s gr 
+% Polyline
+n 5805 3510 m 6345 3510 l 6345 3690 l 5805 3690 l
+ cp gs col0 s gr 
+% Polyline
+n 3510 4140 m 3780 4140 l 3780 5085 l 3510 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 234.00 276.00] PATmp PATsp ef gr PATusp gs col0 s 
gr 
+% Polyline
+n 4365 4140 m 4635 4140 l 4635 5085 l 4365 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 291.00 276.00] PATmp PATsp ef gr PATusp gs col0 s 
gr 
+% Polyline
+n 4905 4140 m 5265 4140 l 5265 5085 l 4905 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 327.00 276.00] PATmp PATsp ef gr PATusp gs col0 s 
gr 
+/Times-Roman ff 180.00 scf sf
+3510 5490 m
+gs 1 -1 sc (gawk Main Program Address Space) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+7290 5490 m
+gs 1 -1 sc (Extension) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5985 2115 m
+gs 1 -1 sc (API) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5895 2340 m
+gs 1 -1 sc (Struct) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+7065 2655 m
+gs 1 -1 sc (dl_load\(api_p, id\);) col0 sh gr
+% here ends figure;
+pagefooter
+showpage
+%%Trailer
+end
+%EOF
diff --git a/doc/api-figure1.fig b/doc/api-figure1.fig
new file mode 100644
index 0000000..7bc4784
--- /dev/null
+++ b/doc/api-figure1.fig
@@ -0,0 +1,40 @@
+#FIG 3.2  Produced by xfig version 3.2.5b
+Landscape
+Center
+Metric
+A4      
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 5449.265 4471.471 6075 2700 4320 2970 3600 
4140
+       1 1 1.00 60.00 120.00
+5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 5538.971 4051.323 6075 3105 4725 3330 4455 
4140
+       1 1 1.00 60.00 120.00
+5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 5628.750 3967.500 6120 3600 5220 3510 5040 
4140
+       1 1 1.00 60.00 120.00
+5 1 0 10 0 7 50 -1 -1 0.000 0 0 1 0 6609.079 4056.868 6525 2835 7560 3285 7830 
3960
+       0 0 1.00 60.00 120.00
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+        3105 4140 6660 4140 6660 5085 3105 5085 3105 4140
+2 2 0 1 0 7 50 -1 10 0.000 0 0 -1 0 0 5
+        6660 4140 8730 4140 8730 5085 6660 5085 6660 4140
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+        5805 2610 6345 2610 6345 3690 5805 3690 5805 2610
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+        5805 2835 6345 2835 6345 3015 5805 3015 5805 2835
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+        5805 3195 6345 3195 6345 3375 5805 3375 5805 3195
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+        5805 3510 6345 3510 6345 3690 5805 3690 5805 3510
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+        3510 4140 3780 4140 3780 5085 3510 5085 3510 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+        4365 4140 4635 4140 4635 5085 4365 5085 4365 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+        4905 4140 5265 4140 5265 5085 4905 5085 4905 4140
+4 0 0 50 -1 0 12 0.0000 4 180 2850 3510 5490 gawk Main Program Address 
Space\001
+4 0 0 50 -1 0 12 0.0000 4 135 825 7290 5490 Extension\001
+4 0 0 50 -1 0 12 0.0000 4 135 300 5985 2115 API\001
+4 0 0 50 -1 0 12 0.0000 4 135 480 5895 2340 Struct\001
+4 0 0 50 -1 14 12 0.0000 4 165 2280 7065 2655 dl_load(api_p, id);\001
diff --git a/doc/api-figure1.pdf b/doc/api-figure1.pdf
new file mode 100644
index 0000000..a57a8e1
Binary files /dev/null and b/doc/api-figure1.pdf differ
diff --git a/doc/api-figure2.eps b/doc/api-figure2.eps
new file mode 100644
index 0000000..4ca9e32
--- /dev/null
+++ b/doc/api-figure2.eps
@@ -0,0 +1,517 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Title: api-figure2.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5d
+%%CreationDate: Wed Oct 31 20:16:08 2012
+%%BoundingBox: 0 0 363 179
+%Magnification: 1.0000
+%%EndComments
+%%BeginProlog
+/MyAppDict 100 dict dup begin def
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+
+% This junk string is used by the show operators
+/PATsstr 1 string def
+/PATawidthshow {       % cx cy cchar rx ry string
+  % Loop over each character in the string
+  {  % cx cy cchar rx ry char
+    % Show the character
+    dup                                % cx cy cchar rx ry char char
+    PATsstr dup 0 4 -1 roll put        % cx cy cchar rx ry char (char)
+    false charpath             % cx cy cchar rx ry char
+    /clip load PATdraw
+    % Move past the character (charpath modified the
+    % current point)
+    currentpoint                       % cx cy cchar rx ry char x y
+    newpath
+    moveto                     % cx cy cchar rx ry char
+    % Reposition by cx,cy if the character in the string is cchar
+    3 index eq {                       % cx cy cchar rx ry
+      4 index 4 index rmoveto
+    } if
+    % Reposition all characters by rx ry
+    2 copy rmoveto             % cx cy cchar rx ry
+  } forall
+  pop pop pop pop pop          % -
+  currentpoint
+  newpath
+  moveto
+} bind def
+/PATcg {
+  7 dict dup begin
+    /lw currentlinewidth def
+    /lc currentlinecap def
+    /lj currentlinejoin def
+    /ml currentmiterlimit def
+    /ds [ currentdash ] def
+    /cc [ currentrgbcolor ] def
+    /cm matrix currentmatrix def
+  end
+} bind def
+% PATdraw - calculates the boundaries of the object and
+% fills it with the current pattern
+/PATdraw {                     % proc
+  save exch
+    PATpcalc                   % proc nw nh px py
+    5 -1 roll exec             % nw nh px py
+    newpath
+    PATfill                    % -
+  restore
+} bind def
+% PATfill - performs the tiling for the shape
+/PATfill { % nw nh px py PATfill -
+  PATDict /CurrentPattern get dup begin
+    setfont
+    % Set the coordinate system to Pattern Space
+    PatternGState PATsg
+    % Set the color for uncolored pattezns
+    PaintType 2 eq { PATDict /PColor get PATsc } if
+    % Create the string for showing
+    3 index string             % nw nh px py str
+    % Loop for each of the pattern sources
+    0 1 Multi 1 sub {          % nw nh px py str source
+       % Move to the starting location
+       3 index 3 index         % nw nh px py str source px py
+       moveto                  % nw nh px py str source
+       % For multiple sources, set the appropriate color
+       Multi 1 ne { dup PC exch get PATsc } if
+       % Set the appropriate string for the source
+       0 1 7 index 1 sub { 2 index exch 2 index put } for pop
+       % Loop over the number of vertical cells
+       3 index                 % nw nh px py str nh
+       {                       % nw nh px py str
+         currentpoint          % nw nh px py str cx cy
+         2 index oldshow       % nw nh px py str cx cy
+         YStep add moveto      % nw nh px py str
+       } repeat                % nw nh px py str
+    } for
+    5 { pop } repeat
+  end
+} bind def
+
+% PATkshow - kshow with the current pattezn
+/PATkshow {                    % proc string
+  exch bind                    % string proc
+  1 index 0 get                        % string proc char
+  % Loop over all but the last character in the string
+  0 1 4 index length 2 sub {
+                               % string proc char idx
+    % Find the n+1th character in the string
+    3 index exch 1 add get     % string proc char char+1
+    exch 2 copy                        % strinq proc char+1 char char+1 char
+    % Now show the nth character
+    PATsstr dup 0 4 -1 roll put        % string proc chr+1 chr chr+1 (chr)
+    false charpath             % string proc char+1 char char+1
+    /clip load PATdraw
+    % Move past the character (charpath modified the current point)
+    currentpoint newpath moveto
+    % Execute the user proc (should consume char and char+1)
+    mark 3 1 roll              % string proc char+1 mark char char+1
+    4 index exec               % string proc char+1 mark...
+    cleartomark                        % string proc char+1
+  } for
+  % Now display the last character
+  PATsstr dup 0 4 -1 roll put  % string proc (char+1)
+  false charpath               % string proc
+  /clip load PATdraw
+  neewath
+  pop pop                      % -
+} bind def
+% PATmp - the makepattern equivalent
+/PATmp {                       % patdict patmtx PATmp patinstance
+  exch dup length 7 add                % We will add 6 new entries plus 1 FID
+  dict copy                    % Create a new dictionary
+  begin
+    % Matrix to install when painting the pattern
+    TilingType PATtcalc
+    /PatternGState PATcg def
+    PatternGState /cm 3 -1 roll put
+    % Check for multi pattern sources (Level 1 fast color patterns)
+    currentdict /Multi known not { /Multi 1 def } if
+    % Font dictionary definitions
+    /FontType 3 def
+    % Create a dummy encoding vector
+    /Encoding 256 array def
+    3 string 0 1 255 {
+      Encoding exch dup 3 index cvs cvn put } for pop
+    /FontMatrix matrix def
+    /FontBBox BBox def
+    /BuildChar {
+       mark 3 1 roll           % mark dict char
+       exch begin
+       Multi 1 ne {PaintData exch get}{pop} ifelse  % mark [paintdata]
+         PaintType 2 eq Multi 1 ne or
+         { XStep 0 FontBBox aload pop setcachedevice }
+         { XStep 0 setcharwidth } ifelse
+         currentdict           % mark [paintdata] dict
+         /PaintProc load       % mark [paintdata] dict paintproc
+       end
+       gsave
+         false PATredef exec true PATredef
+       grestore
+       cleartomark             % -
+    } bind def
+    currentdict
+  end                          % newdict
+  /foo exch                    % /foo newlict
+  definefont                   % newfont
+} bind def
+% PATpcalc - calculates the starting point and width/height
+% of the tile fill for the shape
+/PATpcalc {    % - PATpcalc nw nh px py
+  PATDict /CurrentPattern get begin
+    gsave
+       % Set up the coordinate system to Pattern Space
+       % and lock down pattern
+       PatternGState /cm get setmatrix
+       BBox aload pop pop pop translate
+       % Determine the bounding box of the shape
+       pathbbox                        % llx lly urx ury
+    grestore
+    % Determine (nw, nh) the # of cells to paint width and height
+    PatHeight div ceiling              % llx lly urx qh
+    4 1 roll                           % qh llx lly urx
+    PatWidth div ceiling               % qh llx lly qw
+    4 1 roll                           % qw qh llx lly
+    PatHeight div floor                        % qw qh llx ph
+    4 1 roll                           % ph qw qh llx
+    PatWidth div floor                 % ph qw qh pw
+    4 1 roll                           % pw ph qw qh
+    2 index sub cvi abs                        % pw ph qs qh-ph
+    exch 3 index sub cvi abs exch      % pw ph nw=qw-pw nh=qh-ph
+    % Determine the starting point of the pattern fill
+    %(px, py)
+    4 2 roll                           % nw nh pw ph
+    PatHeight mul                      % nw nh pw py
+    exch                               % nw nh py pw
+    PatWidth mul exch                  % nw nh px py
+  end
+} bind def
+
+% Save the original routines so that we can use them later on
+/oldfill       /fill load def
+/oldeofill     /eofill load def
+/oldstroke     /stroke load def
+/oldshow       /show load def
+/oldashow      /ashow load def
+/oldwidthshow  /widthshow load def
+/oldawidthshow /awidthshow load def
+/oldkshow      /kshow load def
+
+% These defs are necessary so that subsequent procs don't bind in
+% the originals
+/fill     { oldfill } bind def
+/eofill           { oldeofill } bind def
+/stroke           { oldstroke } bind def
+/show     { oldshow } bind def
+/ashow    { oldashow } bind def
+/widthshow { oldwidthshow } bind def
+/awidthshow { oldawidthshow } bind def
+/kshow            { oldkshow } bind def
+/PATredef {
+  MyAppDict begin
+    {
+    /fill { /clip load PATdraw newpath } bind def
+    /eofill { /eoclip load PATdraw newpath } bind def
+    /stroke { PATstroke } bind def
+    /show { 0 0 null 0 0 6 -1 roll PATawidthshow } bind def
+    /ashow { 0 0 null 6 3 roll PATawidthshow }
+    bind def
+    /widthshow { 0 0 3 -1 roll PATawidthshow }
+    bind def
+    /awidthshow { PATawidthshow } bind def
+    /kshow { PATkshow } bind def
+  } {
+    /fill   { oldfill } bind def
+    /eofill { oldeofill } bind def
+    /stroke { oldstroke } bind def
+    /show   { oldshow } bind def
+    /ashow  { oldashow } bind def
+    /widthshow { oldwidthshow } bind def
+    /awidthshow { oldawidthshow } bind def
+    /kshow  { oldkshow } bind def
+    } ifelse
+  end
+} bind def
+false PATredef
+% Conditionally define setcmykcolor if not available
+/setcmykcolor where { pop } {
+  /setcmykcolor {
+    1 sub 4 1 roll
+    3 {
+       3 index add neg dup 0 lt { pop 0 } if 3 1 roll
+    } repeat
+    setrgbcolor - pop
+  } bind def
+} ifelse
+/PATsc {               % colorarray
+  aload length         % c1 ... cn length
+    dup 1 eq { pop setgray } { 3 eq { setrgbcolor } { setcmykcolor
+  } ifelse } ifelse
+} bind def
+/PATsg {               % dict
+  begin
+    lw setlinewidth
+    lc setlinecap
+    lj setlinejoin
+    ml setmiterlimit
+    ds aload pop setdash
+    cc aload pop setrgbcolor
+    cm setmatrix
+  end
+} bind def
+
+/PATDict 3 dict def
+/PATsp {
+  true PATredef
+  PATDict begin
+    /CurrentPattern exch def
+    % If it's an uncolored pattern, save the color
+    CurrentPattern /PaintType get 2 eq {
+      /PColor exch def
+    } if
+    /CColor [ currentrgbcolor ] def
+  end
+} bind def
+% PATstroke - stroke with the current pattern
+/PATstroke {
+  countdictstack
+  save
+  mark
+  {
+    currentpoint strokepath moveto
+    PATpcalc                           % proc nw nh px py
+    clip newpath PATfill
+    } stopped {
+       (*** PATstroke Warning: Path is too complex, stroking
+         with gray) =
+    cleartomark
+    restore
+    countdictstack exch sub dup 0 gt
+       { { end } repeat } { pop } ifelse
+    gsave 0.5 setgray oldstroke grestore
+  } { pop restore pop } ifelse
+  newpath
+} bind def
+/PATtcalc {            % modmtx tilingtype PATtcalc tilematrix
+  % Note: tiling types 2 and 3 are not supported
+  gsave
+    exch concat                                        % tilingtype
+    matrix currentmatrix exch                  % cmtx tilingtype
+    % Tiling type 1 and 3: constant spacing
+    2 ne {
+       % Distort the pattern so that it occupies
+       % an integral number of device pixels
+       dup 4 get exch dup 5 get exch           % tx ty cmtx
+       XStep 0 dtransform
+       round exch round exch                   % tx ty cmtx dx.x dx.y
+       XStep div exch XStep div exch           % tx ty cmtx a b
+       0 YStep dtransform
+       round exch round exch                   % tx ty cmtx a b dy.x dy.y
+       YStep div exch YStep div exch           % tx ty cmtx a b c d
+       7 -3 roll astore                        % { a b c d tx ty }
+    } if
+  grestore
+} bind def
+/PATusp {
+  false PATredef
+  PATDict begin
+    CColor PATsc
+  end
+} bind def
+
+% right30
+11 dict begin
+/PaintType 1 def
+/PatternType 1 def
+/TilingType 1 def
+/BBox [0 0 1 1] def
+/XStep 1 def
+/YStep 1 def
+/PatWidth 1 def
+/PatHeight 1 def
+/Multi 2 def
+/PaintData [
+  { clippath } bind
+  { 32 16 true [ 32 0 0 -16 0 16 ]
+       {<00030003000c000c0030003000c000c0030003000c000c00
+       30003000c000c00000030003000c000c0030003000c000c0
+       030003000c000c0030003000c000c000>}
+     imagemask } bind
+] def
+/PaintProc {
+       pop
+       exec fill
+} def
+currentdict
+end
+/P2 exch def
+
+% crosshatch45
+11 dict begin
+/PaintType 1 def
+/PatternType 1 def
+/TilingType 1 def
+/BBox [0 0 1 1] def
+/XStep 1 def
+/YStep 1 def
+/PatWidth 1 def
+/PatHeight 1 def
+/Multi 2 def
+/PaintData [
+  { clippath } bind
+  { 20 20 true [ 20 0 0 -20 0 20 ]
+       {<8020004050102088201104400a02800401000a02
+       8011044020882040501080200040501020882011
+       04400a02800401000a0280110440208820405010>}
+     imagemask } bind
+] def
+/PaintProc {
+       pop
+       exec fill
+} def
+currentdict
+end
+/P6 exch def
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+/pageheader {
+save
+newpath 0 179 moveto 0 0 lineto 363 0 lineto 363 179 lineto closepath clip 
newpath
+-194.8 350.2 translate
+1 -1 scale
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
+%
+% Fig objects follow
+%
+% 
+% here starts figure with depth 50
+% Arc
+7.500 slw
+0 slc
+gs  clippath
+4057 4011 m 3971 4135 l 4021 4169 l 4107 4045 l 4107 4045 l 4014 4127 l 4057 
4011 l cp
+eoclip
+n 6097.5 5512.5 2502.5 -33.2614 -146.7386 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+0 slj
+n 4057 4011 m 4014 4127 l 4107 4045 l 4057 4011 l  cp gs 0.00 setgray ef gr  
col0 s
+% Polyline
+n 3105 4140 m 6660 4140 l 6660 5085 l 3105 5085 l
+ cp gs col0 s gr 
+% Polyline
+n 6660 4140 m 8730 4140 l 8730 5085 l 6660 5085 l
+ cp gs col7 0.50 shd ef gr gs col0 s gr 
+% Polyline
+n 3510 4140 m 3780 4140 l 3780 5085 l 3510 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 234.00 276.00] PATmp PATsp ef gr PATusp gs col0 s 
gr 
+% Polyline
+n 4365 4140 m 4635 4140 l 4635 5085 l 4365 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 291.00 276.00] PATmp PATsp ef gr PATusp gs col0 s 
gr 
+% Polyline
+n 4905 4140 m 5265 4140 l 5265 5085 l 4905 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 327.00 276.00] PATmp PATsp ef gr PATusp gs col0 s 
gr 
+% Polyline
+n 7965 4140 m 8370 4140 l 8370 5085 l 7965 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P6 [16 0 0 -16 531.00 276.00] PATmp PATsp ef gr PATusp gs col0 
s gr 
+/Times-Roman ff 180.00 scf sf
+3510 5490 m
+gs 1 -1 sc (gawk Main Program Address Space) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+7290 5490 m
+gs 1 -1 sc (Extension) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+3420 2880 m
+gs 1 -1 sc (register_ext_func\({ "chdir", do_chdir, 1 }\);) col0 sh gr
+% here ends figure;
+pagefooter
+showpage
+%%Trailer
+end
+%EOF
diff --git a/doc/api-figure2.fig b/doc/api-figure2.fig
new file mode 100644
index 0000000..4b0e010
--- /dev/null
+++ b/doc/api-figure2.fig
@@ -0,0 +1,26 @@
+#FIG 3.2  Produced by xfig version 3.2.5b
+Landscape
+Center
+Metric
+A4      
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 6097.500 5512.500 8190 4140 5940 3015 4005 
4140
+       1 1 1.00 60.00 120.00
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+        3105 4140 6660 4140 6660 5085 3105 5085 3105 4140
+2 2 0 1 0 7 50 -1 10 0.000 0 0 -1 0 0 5
+        6660 4140 8730 4140 8730 5085 6660 5085 6660 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+        3510 4140 3780 4140 3780 5085 3510 5085 3510 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+        4365 4140 4635 4140 4635 5085 4365 5085 4365 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+        4905 4140 5265 4140 5265 5085 4905 5085 4905 4140
+2 2 0 1 0 7 50 -1 46 0.000 0 0 -1 0 0 5
+        7965 4140 8370 4140 8370 5085 7965 5085 7965 4140
+4 0 0 50 -1 0 12 0.0000 4 180 2850 3510 5490 gawk Main Program Address 
Space\001
+4 0 0 50 -1 0 12 0.0000 4 135 825 7290 5490 Extension\001
+4 0 0 50 -1 14 12 0.0000 4 165 5280 3420 2880 register_ext_func({ "chdir", 
do_chdir, 1 });\001
diff --git a/doc/api-figure2.pdf b/doc/api-figure2.pdf
new file mode 100644
index 0000000..6a9c1c6
Binary files /dev/null and b/doc/api-figure2.pdf differ
diff --git a/doc/api-figure3.eps b/doc/api-figure3.eps
new file mode 100644
index 0000000..d713575
--- /dev/null
+++ b/doc/api-figure3.eps
@@ -0,0 +1,526 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Title: api-figure3.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5d
+%%CreationDate: Wed Oct 31 20:16:08 2012
+%%BoundingBox: 0 0 356 175
+%Magnification: 1.0000
+%%EndComments
+%%BeginProlog
+/MyAppDict 100 dict dup begin def
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+
+% This junk string is used by the show operators
+/PATsstr 1 string def
+/PATawidthshow {       % cx cy cchar rx ry string
+  % Loop over each character in the string
+  {  % cx cy cchar rx ry char
+    % Show the character
+    dup                                % cx cy cchar rx ry char char
+    PATsstr dup 0 4 -1 roll put        % cx cy cchar rx ry char (char)
+    false charpath             % cx cy cchar rx ry char
+    /clip load PATdraw
+    % Move past the character (charpath modified the
+    % current point)
+    currentpoint                       % cx cy cchar rx ry char x y
+    newpath
+    moveto                     % cx cy cchar rx ry char
+    % Reposition by cx,cy if the character in the string is cchar
+    3 index eq {                       % cx cy cchar rx ry
+      4 index 4 index rmoveto
+    } if
+    % Reposition all characters by rx ry
+    2 copy rmoveto             % cx cy cchar rx ry
+  } forall
+  pop pop pop pop pop          % -
+  currentpoint
+  newpath
+  moveto
+} bind def
+/PATcg {
+  7 dict dup begin
+    /lw currentlinewidth def
+    /lc currentlinecap def
+    /lj currentlinejoin def
+    /ml currentmiterlimit def
+    /ds [ currentdash ] def
+    /cc [ currentrgbcolor ] def
+    /cm matrix currentmatrix def
+  end
+} bind def
+% PATdraw - calculates the boundaries of the object and
+% fills it with the current pattern
+/PATdraw {                     % proc
+  save exch
+    PATpcalc                   % proc nw nh px py
+    5 -1 roll exec             % nw nh px py
+    newpath
+    PATfill                    % -
+  restore
+} bind def
+% PATfill - performs the tiling for the shape
+/PATfill { % nw nh px py PATfill -
+  PATDict /CurrentPattern get dup begin
+    setfont
+    % Set the coordinate system to Pattern Space
+    PatternGState PATsg
+    % Set the color for uncolored pattezns
+    PaintType 2 eq { PATDict /PColor get PATsc } if
+    % Create the string for showing
+    3 index string             % nw nh px py str
+    % Loop for each of the pattern sources
+    0 1 Multi 1 sub {          % nw nh px py str source
+       % Move to the starting location
+       3 index 3 index         % nw nh px py str source px py
+       moveto                  % nw nh px py str source
+       % For multiple sources, set the appropriate color
+       Multi 1 ne { dup PC exch get PATsc } if
+       % Set the appropriate string for the source
+       0 1 7 index 1 sub { 2 index exch 2 index put } for pop
+       % Loop over the number of vertical cells
+       3 index                 % nw nh px py str nh
+       {                       % nw nh px py str
+         currentpoint          % nw nh px py str cx cy
+         2 index oldshow       % nw nh px py str cx cy
+         YStep add moveto      % nw nh px py str
+       } repeat                % nw nh px py str
+    } for
+    5 { pop } repeat
+  end
+} bind def
+
+% PATkshow - kshow with the current pattezn
+/PATkshow {                    % proc string
+  exch bind                    % string proc
+  1 index 0 get                        % string proc char
+  % Loop over all but the last character in the string
+  0 1 4 index length 2 sub {
+                               % string proc char idx
+    % Find the n+1th character in the string
+    3 index exch 1 add get     % string proc char char+1
+    exch 2 copy                        % strinq proc char+1 char char+1 char
+    % Now show the nth character
+    PATsstr dup 0 4 -1 roll put        % string proc chr+1 chr chr+1 (chr)
+    false charpath             % string proc char+1 char char+1
+    /clip load PATdraw
+    % Move past the character (charpath modified the current point)
+    currentpoint newpath moveto
+    % Execute the user proc (should consume char and char+1)
+    mark 3 1 roll              % string proc char+1 mark char char+1
+    4 index exec               % string proc char+1 mark...
+    cleartomark                        % string proc char+1
+  } for
+  % Now display the last character
+  PATsstr dup 0 4 -1 roll put  % string proc (char+1)
+  false charpath               % string proc
+  /clip load PATdraw
+  neewath
+  pop pop                      % -
+} bind def
+% PATmp - the makepattern equivalent
+/PATmp {                       % patdict patmtx PATmp patinstance
+  exch dup length 7 add                % We will add 6 new entries plus 1 FID
+  dict copy                    % Create a new dictionary
+  begin
+    % Matrix to install when painting the pattern
+    TilingType PATtcalc
+    /PatternGState PATcg def
+    PatternGState /cm 3 -1 roll put
+    % Check for multi pattern sources (Level 1 fast color patterns)
+    currentdict /Multi known not { /Multi 1 def } if
+    % Font dictionary definitions
+    /FontType 3 def
+    % Create a dummy encoding vector
+    /Encoding 256 array def
+    3 string 0 1 255 {
+      Encoding exch dup 3 index cvs cvn put } for pop
+    /FontMatrix matrix def
+    /FontBBox BBox def
+    /BuildChar {
+       mark 3 1 roll           % mark dict char
+       exch begin
+       Multi 1 ne {PaintData exch get}{pop} ifelse  % mark [paintdata]
+         PaintType 2 eq Multi 1 ne or
+         { XStep 0 FontBBox aload pop setcachedevice }
+         { XStep 0 setcharwidth } ifelse
+         currentdict           % mark [paintdata] dict
+         /PaintProc load       % mark [paintdata] dict paintproc
+       end
+       gsave
+         false PATredef exec true PATredef
+       grestore
+       cleartomark             % -
+    } bind def
+    currentdict
+  end                          % newdict
+  /foo exch                    % /foo newlict
+  definefont                   % newfont
+} bind def
+% PATpcalc - calculates the starting point and width/height
+% of the tile fill for the shape
+/PATpcalc {    % - PATpcalc nw nh px py
+  PATDict /CurrentPattern get begin
+    gsave
+       % Set up the coordinate system to Pattern Space
+       % and lock down pattern
+       PatternGState /cm get setmatrix
+       BBox aload pop pop pop translate
+       % Determine the bounding box of the shape
+       pathbbox                        % llx lly urx ury
+    grestore
+    % Determine (nw, nh) the # of cells to paint width and height
+    PatHeight div ceiling              % llx lly urx qh
+    4 1 roll                           % qh llx lly urx
+    PatWidth div ceiling               % qh llx lly qw
+    4 1 roll                           % qw qh llx lly
+    PatHeight div floor                        % qw qh llx ph
+    4 1 roll                           % ph qw qh llx
+    PatWidth div floor                 % ph qw qh pw
+    4 1 roll                           % pw ph qw qh
+    2 index sub cvi abs                        % pw ph qs qh-ph
+    exch 3 index sub cvi abs exch      % pw ph nw=qw-pw nh=qh-ph
+    % Determine the starting point of the pattern fill
+    %(px, py)
+    4 2 roll                           % nw nh pw ph
+    PatHeight mul                      % nw nh pw py
+    exch                               % nw nh py pw
+    PatWidth mul exch                  % nw nh px py
+  end
+} bind def
+
+% Save the original routines so that we can use them later on
+/oldfill       /fill load def
+/oldeofill     /eofill load def
+/oldstroke     /stroke load def
+/oldshow       /show load def
+/oldashow      /ashow load def
+/oldwidthshow  /widthshow load def
+/oldawidthshow /awidthshow load def
+/oldkshow      /kshow load def
+
+% These defs are necessary so that subsequent procs don't bind in
+% the originals
+/fill     { oldfill } bind def
+/eofill           { oldeofill } bind def
+/stroke           { oldstroke } bind def
+/show     { oldshow } bind def
+/ashow    { oldashow } bind def
+/widthshow { oldwidthshow } bind def
+/awidthshow { oldawidthshow } bind def
+/kshow            { oldkshow } bind def
+/PATredef {
+  MyAppDict begin
+    {
+    /fill { /clip load PATdraw newpath } bind def
+    /eofill { /eoclip load PATdraw newpath } bind def
+    /stroke { PATstroke } bind def
+    /show { 0 0 null 0 0 6 -1 roll PATawidthshow } bind def
+    /ashow { 0 0 null 6 3 roll PATawidthshow }
+    bind def
+    /widthshow { 0 0 3 -1 roll PATawidthshow }
+    bind def
+    /awidthshow { PATawidthshow } bind def
+    /kshow { PATkshow } bind def
+  } {
+    /fill   { oldfill } bind def
+    /eofill { oldeofill } bind def
+    /stroke { oldstroke } bind def
+    /show   { oldshow } bind def
+    /ashow  { oldashow } bind def
+    /widthshow { oldwidthshow } bind def
+    /awidthshow { oldawidthshow } bind def
+    /kshow  { oldkshow } bind def
+    } ifelse
+  end
+} bind def
+false PATredef
+% Conditionally define setcmykcolor if not available
+/setcmykcolor where { pop } {
+  /setcmykcolor {
+    1 sub 4 1 roll
+    3 {
+       3 index add neg dup 0 lt { pop 0 } if 3 1 roll
+    } repeat
+    setrgbcolor - pop
+  } bind def
+} ifelse
+/PATsc {               % colorarray
+  aload length         % c1 ... cn length
+    dup 1 eq { pop setgray } { 3 eq { setrgbcolor } { setcmykcolor
+  } ifelse } ifelse
+} bind def
+/PATsg {               % dict
+  begin
+    lw setlinewidth
+    lc setlinecap
+    lj setlinejoin
+    ml setmiterlimit
+    ds aload pop setdash
+    cc aload pop setrgbcolor
+    cm setmatrix
+  end
+} bind def
+
+/PATDict 3 dict def
+/PATsp {
+  true PATredef
+  PATDict begin
+    /CurrentPattern exch def
+    % If it's an uncolored pattern, save the color
+    CurrentPattern /PaintType get 2 eq {
+      /PColor exch def
+    } if
+    /CColor [ currentrgbcolor ] def
+  end
+} bind def
+% PATstroke - stroke with the current pattern
+/PATstroke {
+  countdictstack
+  save
+  mark
+  {
+    currentpoint strokepath moveto
+    PATpcalc                           % proc nw nh px py
+    clip newpath PATfill
+    } stopped {
+       (*** PATstroke Warning: Path is too complex, stroking
+         with gray) =
+    cleartomark
+    restore
+    countdictstack exch sub dup 0 gt
+       { { end } repeat } { pop } ifelse
+    gsave 0.5 setgray oldstroke grestore
+  } { pop restore pop } ifelse
+  newpath
+} bind def
+/PATtcalc {            % modmtx tilingtype PATtcalc tilematrix
+  % Note: tiling types 2 and 3 are not supported
+  gsave
+    exch concat                                        % tilingtype
+    matrix currentmatrix exch                  % cmtx tilingtype
+    % Tiling type 1 and 3: constant spacing
+    2 ne {
+       % Distort the pattern so that it occupies
+       % an integral number of device pixels
+       dup 4 get exch dup 5 get exch           % tx ty cmtx
+       XStep 0 dtransform
+       round exch round exch                   % tx ty cmtx dx.x dx.y
+       XStep div exch XStep div exch           % tx ty cmtx a b
+       0 YStep dtransform
+       round exch round exch                   % tx ty cmtx a b dy.x dy.y
+       YStep div exch YStep div exch           % tx ty cmtx a b c d
+       7 -3 roll astore                        % { a b c d tx ty }
+    } if
+  grestore
+} bind def
+/PATusp {
+  false PATredef
+  PATDict begin
+    CColor PATsc
+  end
+} bind def
+
+% right30
+11 dict begin
+/PaintType 1 def
+/PatternType 1 def
+/TilingType 1 def
+/BBox [0 0 1 1] def
+/XStep 1 def
+/YStep 1 def
+/PatWidth 1 def
+/PatHeight 1 def
+/Multi 2 def
+/PaintData [
+  { clippath } bind
+  { 32 16 true [ 32 0 0 -16 0 16 ]
+       {<00030003000c000c0030003000c000c0030003000c000c00
+       30003000c000c00000030003000c000c0030003000c000c0
+       030003000c000c0030003000c000c000>}
+     imagemask } bind
+] def
+/PaintProc {
+       pop
+       exec fill
+} def
+currentdict
+end
+/P2 exch def
+
+% crosshatch45
+11 dict begin
+/PaintType 1 def
+/PatternType 1 def
+/TilingType 1 def
+/BBox [0 0 1 1] def
+/XStep 1 def
+/YStep 1 def
+/PatWidth 1 def
+/PatHeight 1 def
+/Multi 2 def
+/PaintData [
+  { clippath } bind
+  { 20 20 true [ 20 0 0 -20 0 20 ]
+       {<8020004050102088201104400a02800401000a02
+       8011044020882040501080200040501020882011
+       04400a02800401000a0280110440208820405010>}
+     imagemask } bind
+] def
+/PaintProc {
+       pop
+       exec fill
+} def
+currentdict
+end
+/P6 exch def
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+/pageheader {
+save
+newpath 0 175 moveto 0 0 lineto 356 0 lineto 356 175 lineto closepath clip 
newpath
+-194.8 350.2 translate
+1 -1 scale
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
+%
+% Fig objects follow
+%
+% 
+% here starts figure with depth 50
+% Arc
+7.500 slw
+0 slc
+gs  clippath
+8019 4079 m 8138 4172 l 8175 4125 l 8056 4032 l 8056 4032 l 8132 4130 l 8019 
4079 l cp
+eoclip
+n 6120.0 6627.7 3207.7 -129.1463 -50.8537 arc
+gs col0 s gr
+ gr
+
+% arrowhead
+0 slj
+n 8019 4079 m 8132 4130 l 8056 4032 l 8019 4079 l  cp gs 0.00 setgray ef gr  
col0 s
+% Polyline
+n 3105 4140 m 6660 4140 l 6660 5085 l 3105 5085 l
+ cp gs col0 s gr 
+% Polyline
+n 6660 4140 m 8730 4140 l 8730 5085 l 6660 5085 l
+ cp gs col7 0.50 shd ef gr gs col0 s gr 
+% Polyline
+n 3510 4140 m 3780 4140 l 3780 5085 l 3510 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 234.00 276.00] PATmp PATsp ef gr PATusp gs col0 s 
gr 
+% Polyline
+n 4365 4140 m 4635 4140 l 4635 5085 l 4365 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 291.00 276.00] PATmp PATsp ef gr PATusp gs col0 s 
gr 
+% Polyline
+n 4905 4140 m 5265 4140 l 5265 5085 l 4905 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 327.00 276.00] PATmp PATsp ef gr PATusp gs col0 s 
gr 
+% Polyline
+n 7965 4140 m 8370 4140 l 8370 5085 l 7965 5085 l
+ cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P6 [16 0 0 -16 531.00 276.00] PATmp PATsp ef gr PATusp gs col0 
s gr 
+/Times-Roman ff 180.00 scf sf
+3510 5490 m
+gs 1 -1 sc (gawk Main Program Address Space) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+7290 5490 m
+gs 1 -1 sc (Extension) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+3240 3150 m
+gs 1 -1 sc (    chdir\("/path"\)) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+3330 3375 m
+gs 1 -1 sc (}) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+3375 2925 m
+gs 1 -1 sc (BEGIN {) col0 sh gr
+/Courier-Bold ff 180.00 scf sf
+6660 3150 m
+gs 1 -1 sc (\(*fnptr\)\(1\);) col0 sh gr
+% here ends figure;
+pagefooter
+showpage
+%%Trailer
+end
+%EOF
diff --git a/doc/api-figure3.fig b/doc/api-figure3.fig
new file mode 100644
index 0000000..5c7fdd9
--- /dev/null
+++ b/doc/api-figure3.fig
@@ -0,0 +1,29 @@
+#FIG 3.2  Produced by xfig version 3.2.5b
+Landscape
+Center
+Metric
+A4      
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 -1 -1 0.000 0 0 1 0 6120.000 6627.656 4095 4140 6120 3420 8145 
4140
+       1 1 1.00 60.00 120.00
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+        3105 4140 6660 4140 6660 5085 3105 5085 3105 4140
+2 2 0 1 0 7 50 -1 10 0.000 0 0 -1 0 0 5
+        6660 4140 8730 4140 8730 5085 6660 5085 6660 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+        3510 4140 3780 4140 3780 5085 3510 5085 3510 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+        4365 4140 4635 4140 4635 5085 4365 5085 4365 4140
+2 2 0 1 0 7 50 -1 42 0.000 0 0 -1 0 0 5
+        4905 4140 5265 4140 5265 5085 4905 5085 4905 4140
+2 2 0 1 0 7 50 -1 46 0.000 0 0 -1 0 0 5
+        7965 4140 8370 4140 8370 5085 7965 5085 7965 4140
+4 0 0 50 -1 0 12 0.0000 4 180 2850 3510 5490 gawk Main Program Address 
Space\001
+4 0 0 50 -1 0 12 0.0000 4 135 825 7290 5490 Extension\001
+4 0 0 50 -1 14 12 0.0000 4 180 2160 3240 3150     chdir("/path")\001
+4 0 0 50 -1 14 12 0.0000 4 150 120 3330 3375 }\001
+4 0 0 50 -1 14 12 0.0000 4 150 840 3375 2925 BEGIN {\001
+4 0 0 50 -1 14 12 0.0000 4 165 1440 6660 3150 (*fnptr)(1);\001
diff --git a/doc/api-figure3.pdf b/doc/api-figure3.pdf
new file mode 100644
index 0000000..d6731a8
Binary files /dev/null and b/doc/api-figure3.pdf differ
diff --git a/doc/api.texi b/doc/api.texi
index 9dc2c30..52d1115 100644
--- a/doc/api.texi
+++ b/doc/api.texi
@@ -570,26 +570,66 @@ Pat Rankin suggested the solution that was adopted. 
Communication between
 @command{gawk} and an extension is two-way.  First, when an extension
 is loaded, it is passed a pointer to a @code{struct} whose fields are
 function pointers.
address@hidden
+This is shown in @ref{load-extension}.
address@hidden iftex
 
-FIXME: Figure 1
address@hidden
address@hidden Figure,load-extension
address@hidden the extension}
address@hidden
address@hidden float
address@hidden iftex
address@hidden
address@hidden
+FIGURE 1
address@hidden example
address@hidden ifnottex
 
 The extension can call functions inside @command{gawk} through these
 function pointers, at runtime, without needing (link-time) access
 to @command{gawk}'s symbols.  One of these function pointers is to a
 function for ``registering'' new built-in functions.
address@hidden
+This is shown in @ref{load-new-function}.
address@hidden iftex
 
-FIXME: Figure 2
address@hidden
address@hidden Figure,load-new-function
address@hidden the new function}
address@hidden
address@hidden float
address@hidden iftex
address@hidden
address@hidden
+FIGURE 2
address@hidden example
address@hidden ifnottex
 
 In the other direction, the extension registers its new functions
 with @command{gawk} by passing function pointers to the functions that
 provide the new feature (@code{do_chdir()}, for example).  @command{gawk}
 associates the function pointer with a name and can then call it, using a
-defined calling convention. The @address@hidden()} function, in turn,
-then uses the function pointers in the API @code{struct} to do its work,
-such as updating variables or arrays, printing messages, setting @code{ERRNO},
-and so on.
+defined calling convention.
address@hidden
+This is shown in @ref{call-new-function}.
address@hidden iftex
+
address@hidden
address@hidden Figure,call-new-function
address@hidden the new function}
address@hidden
address@hidden float
address@hidden iftex
address@hidden
address@hidden
+FIGURE 3
address@hidden example
address@hidden ifnottex
 
-FIXME: Figure 3
+The @address@hidden()} function, in turn, then uses the function
+pointers in the API @code{struct} to do its work, such as updating
+variables or arrays, printing messages, setting @code{ERRNO}, and so on.
 
 Convenience macros in the @file{gawkapi.h} header file make calling
 through the function pointers look like regular function calls so that
@@ -735,8 +775,10 @@ Some points about using the API:
 You must include @code{<sys/types.h>} and @code{<sys/stat.h>} before including
 the @file{gawkapi.h} header file. In addition, you must include either
 @code{<stddef.h>} or @code{<stdlib.h>} to get the definition of @code{size_t}.
-Finally, if you wish to use the boilerplate @code{dl_load_func()} macro, you 
will
+If you wish to use the boilerplate @code{dl_load_func()} macro, you will
 need to include @code{<stdio.h>} as well.
+Finally, to pass reasonable integer values for @code{ERRNO}, you
+will need to include @code{<errno.h>}.
 
 @item
 Although the API only uses ISO C 90 features, there is an exception; the

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog           |    2 +
 doc/ChangeLog       |    7 +
 doc/Makefile.am     |    3 +
 doc/Makefile.in     |    3 +
 doc/api-figure1.eps |  536 +++++++++++++++++++++++++++++++++++++++++++++++++++
 doc/api-figure1.fig |   40 ++++
 doc/api-figure1.pdf |  Bin 0 -> 10707 bytes
 doc/api-figure2.eps |  517 +++++++++++++++++++++++++++++++++++++++++++++++++
 doc/api-figure2.fig |   26 +++
 doc/api-figure2.pdf |  Bin 0 -> 12027 bytes
 doc/api-figure3.eps |  526 ++++++++++++++++++++++++++++++++++++++++++++++++++
 doc/api-figure3.fig |   29 +++
 doc/api-figure3.pdf |  Bin 0 -> 12345 bytes
 doc/api.texi        |  424 ++++++++++++++++++++++++-----------------
 gawkapi.h           |    2 +-
 15 files changed, 1941 insertions(+), 174 deletions(-)
 create mode 100644 doc/api-figure1.eps
 create mode 100644 doc/api-figure1.fig
 create mode 100644 doc/api-figure1.pdf
 create mode 100644 doc/api-figure2.eps
 create mode 100644 doc/api-figure2.fig
 create mode 100644 doc/api-figure2.pdf
 create mode 100644 doc/api-figure3.eps
 create mode 100644 doc/api-figure3.fig
 create mode 100644 doc/api-figure3.pdf


hooks/post-receive
-- 
gawk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]