diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2012-10-21 17:31:38 +0200 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2012-10-21 17:31:38 +0200 |
commit | 599e89596c2a813b084e40645d801eb1c7de1ee1 (patch) | |
tree | b9d2951fd39a049c4aa4511586588b273e1dfe4d | |
parent | fd0df9b0201fcb59831828e6a1c5bd177108d677 (diff) | |
download | egawk-599e89596c2a813b084e40645d801eb1c7de1ee1.tar.gz egawk-599e89596c2a813b084e40645d801eb1c7de1ee1.tar.bz2 egawk-599e89596c2a813b084e40645d801eb1c7de1ee1.zip |
More API doc.
-rw-r--r-- | doc/api.texi | 256 |
1 files changed, 240 insertions, 16 deletions
diff --git a/doc/api.texi b/doc/api.texi index ab4ea632..144c6b93 100644 --- a/doc/api.texi +++ b/doc/api.texi @@ -43,7 +43,9 @@ @set DOCUMENT Info file @set CHAPTER major node @set APPENDIX major node -@set SECTION minor node +@set SECTION minor noderese +`v + @set SUBSECTION node @set DARKCORNER (d.c.) @set COMMONEXT (c.e.) @@ -68,7 +70,9 @@ @end ifdocbook @ifplaintext @set DOCUMENT book -@set CHAPTER chapter +@set CHAPTER chapterrese +`v + @set APPENDIX appendix @set SECTION section @set SUBSECTION subsection @@ -719,7 +723,7 @@ multibyte encoding. @itemx @ @ @ @ AWK_STRING, @itemx @ @ @ @ AWK_ARRAY, @itemx @ @ @ @ AWK_SCALAR,@ @ @ @ @ @ @ @ @ /* opaque access to a variable */ -@itemx @ @ @ @ AWK_VALUE_COOKIE,@ @ @ /* for updating a previously created value */ +@itemx @ @ @ @ AWK_VALUE_COOKIE@ @ @ /* for updating a previously created value */ @itemx @} awk_valtype_t; This @code{enum} indicates the type of a value. It is used in the following @code{struct}. @@ -1458,14 +1462,133 @@ Unset @code{ERRNO}. @node Accessing Parameters @subsection Accessing and Updating Parameters +Two functions give you access to the arguments (parameters) +passed to your extension function. They are: + +@table @code +@item awk_bool_t get_argument(size_t count, awk_valtype_t wanted, awk_value_t *result); +Fill in the @code{awk_value_t} structure pointed to by @code{result} +with the @code{count}'th argument. Counts are zero based---the first argument is +numbered zero, the second one, and so on. @code{wanted} indicates the type of +value expected. Return true if the actual type matches @code{wanted}, false otherwise +In the latter case, @code{result->val_type} indicates the actual type. + +@item awk_bool_t set_argument(size_t count, awk_array_t array); +Convert a paramter that was undefined into an array; this provides +call-by-reference for arrays. Return false +if @code{count} is too big, or if the argument's type is +not undefined. +@end table + @node Symbol Table Access @subsection Symbol Table Access -@c @menu -@c @end menu -@c subsubsection - regular routines -@c subsubsection - cookie routines -@c subsubsection - value routines +Three sets of routines provide access to global variables. + +@menu +@end menu + +@node Symbol table by name +@subsubsection Variable Access and Update by Name + +The following routines provide the ability to access and update +global @command{awk}-level variables by name. In compiler terminology, +identifiers of different kinds are termed @dfn{symbols}, thus the ``sym'' +in the routines' names. The data structure which stores information +about symbols is termed a @dfn{symbol table}. + +@table @code +@item awk_bool_t sym_lookup(const char *name, awk_valtype_t wanted, awk_value_t *result); +Fill in the @code{awk_value_t} structure pointed to by @code{result} +with the value of the variable named by the string @code{name}, which is +a regular C string. @code{wanted} indicates the type of value expected. +Return true if the actual type matches @code{wanted}, false otherwise +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 +if it is not there. Return true if everything worked, false otherwise. + +Changing types (scalar to array or vice versa) of an existing variable +is @emph{not} allowed, nor may this routine be used to update an array. +This routine can also not be be used to update any of the predefined +variables (such as @code{ARGC} or @code{NF}). + +@item awk_bool_t sym_constant(const char *name, awk_value_t *value); +Create a variable named by the string @code{name}, which is +a regular C string, that has the constant value as given by +@code{value}. @command{awk}-level code cannot change the value of this +variable.@footnote{There (currently) is no @code{awk}-level feature that +provides this ability.} The extension may change the value @code{name}'s +variable with subsequent calls to this routine, and may also convert +a variable created by @code{sym_update()} into a constant. However, +once a variable becomes a constant it cannot later be reverted into a +mutable variable. + +@node Symbol table by cookie +@subsubsection Variable Access and Update by Cookie + /* + * A ``scalar cookie'' is an opaque handle that provide access + * to a global variable or array. It is an optimization that + * avoids looking up variables in gawk's symbol table every time + * access is needed. + * + * This function retrieves the current value of a scalar cookie. + * Once you have obtained a saclar_cookie using sym_lookup, you can + * use this function to get its value more efficiently. + * + * Return will be false if the value cannot be retrieved. + * + * Flow is thus + * awk_value_t val; + * awk_scalar_t cookie; + * api->sym_lookup(id, "variable", AWK_SCALAR, & val); // get the cookie + * cookie = val.scalar_cookie; + * ... + * api->sym_lookup_scalar(id, cookie, wanted, & val); // get the value + */ + awk_bool_t (*api_sym_lookup_scalar)(awk_ext_id_t id, + awk_scalar_t cookie, + awk_valtype_t wanted, + awk_value_t *result); + + /* + * Update the value associated with a scalar cookie. + * Flow is + * sym_lookup with wanted == AWK_SCALAR + * if returns false + * sym_update with real initial value to install it + * sym_lookup again with AWK_SCALAR + * else + * use the scalar cookie + * + * Return will be false if the new value is not one of + * AWK_STRING or AWK_NUMBER. + * + * Here too, the built-in variables may not be updated. + */ + awk_bool_t (*api_sym_update_scalar)(awk_ext_id_t id, + awk_scalar_t cookie, awk_value_t *value); + +@node Cached values +@subsubsection Creating and Using Cached Values + /* + * Create a cached string or numeric value for efficient later + * assignment. This improves performance when you want to assign + * the same value to one or more variables repeatedly. Only + * AWK_NUMBER and AWK_STRING values are allowed. Any other type + * is rejected. We disallow AWK_UNDEFINED since that case would + * result in inferior performance. + */ + awk_bool_t (*api_create_value)(awk_ext_id_t id, awk_value_t *value, + awk_value_cookie_t *result); + + /* + * Release the memory associated with a cookie from api_create_value. + * Please call this to free memory when the value is no longer needed. + */ + awk_bool_t (*api_release_value)(awk_ext_id_t id, awk_value_cookie_t vc); @node Array Manipulation @subsection Array Manipulation @@ -1487,6 +1610,37 @@ functions. This is very similar to way @samp{FILE *} values are used with the @code{<stdio.h>} library routines. FIXME: XREF, for how to use the value. +/* + * A "flattened" array element. Gawk produces an array of these + * inside the awk_flattened_array_t. + * ALL memory pointed to belongs to gawk. Individual elements may + * be marked for deletion. New elements must be added individually, + * one at a time, using the separate API for that purpose. + */ + +typedef struct awk_element { + /* convenience linked list pointer, not used by gawk */ + struct awk_element *next; + enum { + AWK_ELEMENT_DEFAULT = 0, /* set by gawk */ + AWK_ELEMENT_DELETE = 1 /* set by extension if + should be deleted */ + } flags; + awk_value_t index; + awk_value_t value; +} awk_element_t; + +/* + * A "flattened" array. See the description above for how + * to use the elements contained herein. + */ +typedef struct awk_flat_array { + awk_const void *opaque1; /* private data for use by gawk */ + awk_const void *opaque2; /* private data for use by gawk */ + awk_const size_t count; /* how many elements */ + awk_element_t elements[1]; /* will be extended */ +} awk_flat_array_t; + * 2. Due to gawk internals, after using sym_update() to install an array * into gawk, you have to retrieve the array cookie from the value * passed in to sym_update(). Like so: @@ -1519,6 +1673,59 @@ the value. * a good idea to always do this. This restriction may be relaxed * in a subsequent revision of the API. +@c @table + /* + * Retrieve total number of elements in array. + * Returns false if some kind of error. + */ + awk_bool_t (*api_get_element_count)(awk_ext_id_t id, + awk_array_t a_cookie, size_t *count); + + /* + * Return the value of an element - read only! + * Use set_array_element() to change it. + * Behavior for value and return is same as for api_get_argument + * and sym_lookup. + */ + awk_bool_t (*api_get_array_element)(awk_ext_id_t id, + awk_array_t a_cookie, + const awk_value_t *const index, + awk_valtype_t wanted, + awk_value_t *result); + + /* + * Change (or create) element in existing array with + * element->index and element->value. + * + * ARGV and ENVIRON may not be updated. + */ + awk_bool_t (*api_set_array_element)(awk_ext_id_t id, awk_array_t a_cookie, + const awk_value_t *const index, + const awk_value_t *const value); + + /* + * Remove the element with the given index. + * Returns success if removed or if element did not exist. + */ + awk_bool_t (*api_del_array_element)(awk_ext_id_t id, + awk_array_t a_cookie, const awk_value_t* const index); + + /* Create a new array cookie to which elements may be added */ + awk_array_t (*api_create_array)(awk_ext_id_t id); + + /* Clear out an array */ + awk_bool_t (*api_clear_array)(awk_ext_id_t id, awk_array_t a_cookie); + + /* Flatten out an array so that it can be looped over easily. */ + awk_bool_t (*api_flatten_array)(awk_ext_id_t id, + awk_array_t a_cookie, + awk_flat_array_t **data); + + /* When done, delete any marked elements, release the memory. */ + awk_bool_t (*api_release_flattened_array)(awk_ext_id_t id, + awk_array_t a_cookie, + awk_flat_array_t *data); +@c @end table @node Extension API Variables @subsection Variables @@ -1583,7 +1790,6 @@ if (api->major_version != GAWK_API_MAJOR_VERSION Such code is included in the boilerplate @code{dl_load_func} macro provided in @file{gawkapi.h} (discussed later, in PXREF). - @node Extension API Informational Variables @subsubsection Informational Variables @@ -1624,9 +1830,6 @@ The others should not change during execution. @c It's enough to show chdir and stat, no need for fts -@node Extension Samples -@section Example: Directory and File Operation Built-ins - Two useful functions that are not in @command{awk} are @code{chdir()} (so that an @command{awk} program can change its directory) and @code{stat()} (so that an @command{awk} program can gather information about @@ -1936,6 +2139,9 @@ to support the @code{fts()} extension which is included in the same file but whose code is not shown here. (FIXME: XREF to section with documentation.) +The first part of the function is variable declarations, +including a table to map file types to strings: + @example /* fill_stat_array --- do the work to fill an array with stat info */ @@ -1967,7 +2173,12 @@ fill_stat_array(const char *name, awk_array_t array, struct stat *sbuf) #endif /* S_IFDOOR */ @}; int j, k; +@end example +The destination array is cleared, and then code fills in +various elements based on values in the @code{struct stat}: + +@example /* empty out the array */ clear_array(array); @@ -1991,7 +2202,15 @@ fill_stat_array(const char *name, awk_array_t array, struct stat *sbuf) array_set_numeric(array, "major", major(sbuf->st_rdev)); array_set_numeric(array, "minor", minor(sbuf->st_rdev)); @} +@end example +@noindent +The latter part of the function makes selective additions +to the destinatino array, depending upon the availability of +certain members and/or the type of the file. In the returns zero, +for success: + +@example #ifdef HAVE_ST_BLKSIZE array_set_numeric(array, "blksize", sbuf->st_blksize); #endif /* HAVE_ST_BLKSIZE */ @@ -2026,7 +2245,7 @@ fill_stat_array(const char *name, awk_array_t array, struct stat *sbuf) @} @end example -Finall, here is the @code{do_stat()} function. It starts with +Finally, here is the @code{do_stat()} function. It starts with variable declarations and argument checking: @ignore @@ -2080,8 +2299,7 @@ If there's an error, it sets @code{ERRNO} and returns: @end example The tedious work is done by @code{fill_stat_array()}, shown -earlier. -When done, return the result from @code{fill_stat_array()}: +earlier. When done, return the result from @code{fill_stat_array()}: @example ret = fill_stat_array(name, array, & sbuf); @@ -2108,7 +2326,7 @@ init_filefuncs(void) @} @end example -Almost done. We need an array of @code{awk_ext_func_t} +We are almost done. We need an array of @code{awk_ext_func_t} structures for loading each function into @command{gawk}: @example @@ -2212,6 +2430,12 @@ $ @kbd{gawk -f testff.awk} @print{} JUNK modified: 01 01 70 02:00:00 @end example +@node Extension Samples +@section The Sample Extensions in the @command{gawk} Distribution + +@menu +@end menu + @node Extension Sample File Functions @subsection File Related Functions |