From 54f5f71fb743e58427e2d72f0caaee12a12a5140 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 4 May 2012 14:06:00 +0300 Subject: Add new file, gawkapi.h. --- gawkapi.h | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 gawkapi.h (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h new file mode 100644 index 00000000..e51dccef --- /dev/null +++ b/gawkapi.h @@ -0,0 +1,216 @@ +/* + * gawkpi.h -- Definitions for use by extension functions calling into gawk. + */ + +/* + * Copyright (C) 2012, the Free Software Foundation, Inc. + * + * This file is part of GAWK, the GNU implementation of the + * AWK Programming Language. + * + * GAWK is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GAWK is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * N.B. You must include and + * before including this file! + */ + +#ifndef _GAWK_API_H +#define _GAWK_API_H + + /* Allow the use in C++ code. */ +#ifdef __cplusplus + extern "C" { +#endif + + typedef struct iobuf { + const char *name; /* filename */ + int fd; /* file descriptor */ + struct stat sbuf; /* stat buf */ + char *buf; /* start data buffer */ + char *off; /* start of current record in buffer */ + char *dataend; /* first byte in buffer to hold new data, + NULL if not read yet */ + char *end; /* end of buffer */ + size_t readsize; /* set from fstat call */ + size_t size; /* buffer size */ + ssize_t count; /* amount read last time */ + size_t scanoff; /* where we were in the buffer when we had + to regrow/refill */ + /* + * No argument prototype on read_func. See get_src_buf() + * in awkgram.y. + */ + ssize_t (*read_func)(); + + void *opaque; /* private data for open hooks */ + int (*get_record)(char **out, struct iobuf *, int *errcode); + void (*close_func)(struct iobuf *); /* open and close hooks */ + + int errcode; + + int flag; +# define IOP_IS_TTY 1 +# define IOP_NOFREE_OBJ 2 +# define IOP_AT_EOF 4 +# define IOP_CLOSED 8 +# define IOP_AT_START 16 + } IOBUF; + +#define GAWK_API_MAJOR_VERSION 0 +#define GAWK_API_MINOR_VERSION 0 + +#define DO_FLAGS_SIZE 6 + + typedef enum { + AWK_UNDEFINED, + AWK_NUMBER, + AWK_CONST_STRING, + AWK_STRING, + AWK_ARRAY + } awk_valtype_t; + + typedef struct { + const char *const str; + const size_t len; + } awk_const_string_t; + + typedef struct { + char *str; + size_t len; + } awk_string_t; + + typedef struct { + awk_valtype_t val_type; + union { + awk_const_string cs; + awk_string s; + double d; + void* a; + } u; +#define const_str_val u.cs +#define str_val u.s +#define num_val u.d +#define array_cookie u.a + } awk_value_t; + + + typedef struct { + const char *name; + size_t num_args; + void (*function)(int num_args); + } awk_ext_func_t; + + typedef struct gawk_api { + int major_version; + int minor_version; + + int do_flags[DO_FLAGS_SIZE]; + /* Use these as indices into do_flags[] array to check the values */ +#define gawk_do_lint 0 +#define gawk_do_traditional 1 +#define gawk_do_profile 2 +#define gawk_do_sandbox 3 +#define gawk_do_debug 4 +#define gawk_do_mpfr 5 + + /* get the number of arguments passed in function call */ + /* FIXME: Needed? Won't we pass the count in the real call? */ + size_t (*get_curfunc_arg_count)(void *ext_id); + awk_value_t *(*get_curfunc_param)(void *ext_id, size_t count); + + /* functions to print messages */ + void (*fatal)(void *ext_id, const char *format, ...); + void (*warning)(void *ext_id, const char *format, ...); + void (*lintwarn)(void *ext_id, const char *format, ...); + + /* register an open hook; for opening files read-only */ + int (*register_open_hook)(void *ext_id, + void* (*open_func)(IOBUF *)); + + /* functions to update ERRNO */ + void (*update_ERRNO_int)(void *ext_id, int); + void (*update_ERRNO_string)(void *ext_id, const char *string, + int translate); + void (*unset_ERRNO)(void *ext_id); + + /* check if a value received from gawk is the null string */ + int (*is_null_string)(void *ext_id, void *value); + + /* add a function to the interpreter */ + int *(add_ext_func)(void *ext_id, const awk_ext_func_t *func); + + /* add an exit call back */ + void (*awk_atexit)(void *ext_id, void (*funcp)(void *data, int exit_status), void *arg0); + + /* Symbol table access */ + awk_value_t *(*sym_lookup)(void *ext_id, const char *name); + int (*sym_update)(void *ext_id, const char *name, awk_value_t *value); + int (*sym_remove)(void *ext_id, const char *name); + + /* Array management */ + awk_value_t *(*get_array_element)(void *ext_id, void *a_cookie, const awk_value_t* const index); + awk_value_t *(*set_array_element)(void *ext_id, void *a_cookie, + const awk_value_t* const index, const awk_value_t* const value); + awk_value_t *(*del_array_element)(void *ext_id, void *a_cookie, const awk_value_t* const index); + size_t (*get_element_count)(void *ext_id, void *a_cookie); + + } gawk_api_t; + +#ifndef GAWK /* these are not for the gawk code itself */ + /* + * Use these if you want to define a "global" variable named api + * to make the code a little easier to read. + */ +#define do_lint api->do_flags[gawk_do_lint] +#define do_traditional api->do_flags[gawk_do_traditional] +#define do_profile api->do_flags[gawk_do_profile] +#define do_sandbox api->do_flags[gawk_do_sandbox] +#define do_debug api->do_flags[gawk_do_debug] + +#define get_curfunc_arg_count api->get_curfunc_arg_count +#define get_curfunc_param api->get_curfunc_param + +#define fatal api->fatal +#define warning api->warning +#define lintwarn api->lintwarn + +#define register_open_hook api->register_open_hook + +#define update_ERRNO_int api->update_ERRNO_int +#define update_ERRNO_string api->update_ERRNO_string +#define unset_ERRNO api->unset_ERRNO + +#define is_null_string api->is_null_string + +#define add_ext_func api->add_ext_func +#define awk_atexit api->awk_atexit + +#define sym_lookup api->sym_lookup +#define sym_update api->sym_update +#define sym_remove api->sym_remove + +#define get_array_element api->get_array_element +#define set_array_element api->set_array_element +#define del_array_element api->del_array_element +#define get_element_count api->get_element_count +#endif /* GAWK */ + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* _GAWK_API_H */ -- cgit v1.2.3 From c41908d0b02f7746a67ab7aa2e54058e5b66439a Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Mon, 7 May 2012 23:46:15 -0400 Subject: Fix comment typo in gawkapi.h --- gawkapi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index e51dccef..8361ab2c 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -1,5 +1,5 @@ /* - * gawkpi.h -- Definitions for use by extension functions calling into gawk. + * gawkapi.h -- Definitions for use by extension functions calling into gawk. */ /* -- cgit v1.2.3 From 4f8aff5908706e6f526b61337d10a412f4f66360 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 11 May 2012 15:04:47 +0300 Subject: Fix whitespace in gawkapi.h. --- gawkapi.h | 208 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 104 insertions(+), 104 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 8361ab2c..a09a10d7 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -31,95 +31,95 @@ #ifndef _GAWK_API_H #define _GAWK_API_H - /* Allow the use in C++ code. */ +/* Allow the use in C++ code. */ #ifdef __cplusplus - extern "C" { +extern "C" { #endif - typedef struct iobuf { - const char *name; /* filename */ - int fd; /* file descriptor */ - struct stat sbuf; /* stat buf */ - char *buf; /* start data buffer */ - char *off; /* start of current record in buffer */ - char *dataend; /* first byte in buffer to hold new data, - NULL if not read yet */ - char *end; /* end of buffer */ - size_t readsize; /* set from fstat call */ - size_t size; /* buffer size */ - ssize_t count; /* amount read last time */ - size_t scanoff; /* where we were in the buffer when we had - to regrow/refill */ - /* - * No argument prototype on read_func. See get_src_buf() - * in awkgram.y. - */ - ssize_t (*read_func)(); - - void *opaque; /* private data for open hooks */ - int (*get_record)(char **out, struct iobuf *, int *errcode); - void (*close_func)(struct iobuf *); /* open and close hooks */ - - int errcode; - - int flag; +typedef struct iobuf { + const char *name; /* filename */ + int fd; /* file descriptor */ + struct stat sbuf; /* stat buf */ + char *buf; /* start data buffer */ + char *off; /* start of current record in buffer */ + char *dataend; /* first byte in buffer to hold new data, + NULL if not read yet */ + char *end; /* end of buffer */ + size_t readsize; /* set from fstat call */ + size_t size; /* buffer size */ + ssize_t count; /* amount read last time */ + size_t scanoff; /* where we were in the buffer when we had + to regrow/refill */ + /* + * No argument prototype on read_func. See get_src_buf() + * in awkgram.y. + */ + ssize_t (*read_func)(); + + void *opaque; /* private data for open hooks */ + int (*get_record)(char **out, struct iobuf *, int *errcode); + void (*close_func)(struct iobuf *); /* open and close hooks */ + + int errcode; + + int flag; # define IOP_IS_TTY 1 # define IOP_NOFREE_OBJ 2 # define IOP_AT_EOF 4 # define IOP_CLOSED 8 # define IOP_AT_START 16 - } IOBUF; +} IOBUF; #define GAWK_API_MAJOR_VERSION 0 #define GAWK_API_MINOR_VERSION 0 #define DO_FLAGS_SIZE 6 - typedef enum { - AWK_UNDEFINED, - AWK_NUMBER, - AWK_CONST_STRING, - AWK_STRING, - AWK_ARRAY - } awk_valtype_t; - - typedef struct { - const char *const str; - const size_t len; - } awk_const_string_t; - - typedef struct { - char *str; - size_t len; - } awk_string_t; - - typedef struct { - awk_valtype_t val_type; - union { - awk_const_string cs; - awk_string s; - double d; - void* a; - } u; +typedef enum { + AWK_UNDEFINED, + AWK_NUMBER, + AWK_CONST_STRING, + AWK_STRING, + AWK_ARRAY +} awk_valtype_t; + +typedef struct { + const char *const str; + const size_t len; +} awk_const_string_t; + +typedef struct { + char *str; + size_t len; +} awk_string_t; + +typedef struct { + awk_valtype_t val_type; + union { + awk_const_string cs; + awk_string s; + double d; + void* a; + } u; #define const_str_val u.cs #define str_val u.s #define num_val u.d #define array_cookie u.a - } awk_value_t; +} awk_value_t; - typedef struct { - const char *name; - size_t num_args; - void (*function)(int num_args); - } awk_ext_func_t; +typedef struct { + const char *name; + size_t num_args; + void (*function)(int num_args); +} awk_ext_func_t; - typedef struct gawk_api { - int major_version; - int minor_version; +typedef struct gawk_api { + int major_version; + int minor_version; - int do_flags[DO_FLAGS_SIZE]; - /* Use these as indices into do_flags[] array to check the values */ + int do_flags[DO_FLAGS_SIZE]; +/* Use these as indices into do_flags[] array to check the values */ #define gawk_do_lint 0 #define gawk_do_traditional 1 #define gawk_do_profile 2 @@ -127,54 +127,54 @@ #define gawk_do_debug 4 #define gawk_do_mpfr 5 - /* get the number of arguments passed in function call */ - /* FIXME: Needed? Won't we pass the count in the real call? */ - size_t (*get_curfunc_arg_count)(void *ext_id); - awk_value_t *(*get_curfunc_param)(void *ext_id, size_t count); + /* get the number of arguments passed in function call */ + /* FIXME: Needed? Won't we pass the count in the real call? */ + size_t (*get_curfunc_arg_count)(void *ext_id); + awk_value_t *(*get_curfunc_param)(void *ext_id, size_t count); - /* functions to print messages */ - void (*fatal)(void *ext_id, const char *format, ...); - void (*warning)(void *ext_id, const char *format, ...); - void (*lintwarn)(void *ext_id, const char *format, ...); + /* functions to print messages */ + void (*fatal)(void *ext_id, const char *format, ...); + void (*warning)(void *ext_id, const char *format, ...); + void (*lintwarn)(void *ext_id, const char *format, ...); - /* register an open hook; for opening files read-only */ - int (*register_open_hook)(void *ext_id, - void* (*open_func)(IOBUF *)); + /* register an open hook; for opening files read-only */ + int (*register_open_hook)(void *ext_id, + void* (*open_func)(IOBUF *)); - /* functions to update ERRNO */ - void (*update_ERRNO_int)(void *ext_id, int); - void (*update_ERRNO_string)(void *ext_id, const char *string, - int translate); - void (*unset_ERRNO)(void *ext_id); + /* functions to update ERRNO */ + void (*update_ERRNO_int)(void *ext_id, int); + void (*update_ERRNO_string)(void *ext_id, const char *string, + int translate); + void (*unset_ERRNO)(void *ext_id); - /* check if a value received from gawk is the null string */ - int (*is_null_string)(void *ext_id, void *value); + /* check if a value received from gawk is the null string */ + int (*is_null_string)(void *ext_id, void *value); - /* add a function to the interpreter */ - int *(add_ext_func)(void *ext_id, const awk_ext_func_t *func); + /* add a function to the interpreter */ + int *(add_ext_func)(void *ext_id, const awk_ext_func_t *func); - /* add an exit call back */ - void (*awk_atexit)(void *ext_id, void (*funcp)(void *data, int exit_status), void *arg0); + /* add an exit call back */ + void (*awk_atexit)(void *ext_id, void (*funcp)(void *data, int exit_status), void *arg0); - /* Symbol table access */ - awk_value_t *(*sym_lookup)(void *ext_id, const char *name); - int (*sym_update)(void *ext_id, const char *name, awk_value_t *value); - int (*sym_remove)(void *ext_id, const char *name); + /* Symbol table access */ + awk_value_t *(*sym_lookup)(void *ext_id, const char *name); + int (*sym_update)(void *ext_id, const char *name, awk_value_t *value); + int (*sym_remove)(void *ext_id, const char *name); - /* Array management */ - awk_value_t *(*get_array_element)(void *ext_id, void *a_cookie, const awk_value_t* const index); - awk_value_t *(*set_array_element)(void *ext_id, void *a_cookie, - const awk_value_t* const index, const awk_value_t* const value); - awk_value_t *(*del_array_element)(void *ext_id, void *a_cookie, const awk_value_t* const index); - size_t (*get_element_count)(void *ext_id, void *a_cookie); + /* Array management */ + awk_value_t *(*get_array_element)(void *ext_id, void *a_cookie, const awk_value_t* const index); + awk_value_t *(*set_array_element)(void *ext_id, void *a_cookie, + const awk_value_t* const index, const awk_value_t* const value); + awk_value_t *(*del_array_element)(void *ext_id, void *a_cookie, const awk_value_t* const index); + size_t (*get_element_count)(void *ext_id, void *a_cookie); - } gawk_api_t; +} gawk_api_t; #ifndef GAWK /* these are not for the gawk code itself */ - /* - * Use these if you want to define a "global" variable named api - * to make the code a little easier to read. - */ +/* + * Use these if you want to define a "global" variable named api + * to make the code a little easier to read. + */ #define do_lint api->do_flags[gawk_do_lint] #define do_traditional api->do_flags[gawk_do_traditional] #define do_profile api->do_flags[gawk_do_profile] -- cgit v1.2.3 From 60a3183d9a228569eee98b19c67600e103ae1eac Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 15 May 2012 22:28:11 +0300 Subject: Start fleshing out new extension API. --- gawkapi.h | 253 +++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 200 insertions(+), 53 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index a09a10d7..2a14d334 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -31,11 +31,21 @@ #ifndef _GAWK_API_H #define _GAWK_API_H -/* Allow the use in C++ code. */ +/* + * General introduction: + * + * This API purposely restricts itself to C90 features. + * In paticular, no bool, no // comments, no use of the + * restrict keyword, or anything else, in order to provide + * maximal portability. + */ + +/* Allow use in C++ code. */ #ifdef __cplusplus extern "C" { #endif +/* struct used for reading records and managing buffers */ typedef struct iobuf { const char *name; /* filename */ int fd; /* file descriptor */ @@ -58,7 +68,7 @@ typedef struct iobuf { void *opaque; /* private data for open hooks */ int (*get_record)(char **out, struct iobuf *, int *errcode); - void (*close_func)(struct iobuf *); /* open and close hooks */ + void (*close_func)(struct iobuf *); /* open and close hooks */ int errcode; @@ -75,45 +85,92 @@ typedef struct iobuf { #define DO_FLAGS_SIZE 6 +/* + * This tag defines the type of a value. + * Values are associated with regular variables and with array elements. + * Since arrays can be multidimensional (as can regular variables) + * it's valid to have a "value" that is actually an array. + */ typedef enum { AWK_UNDEFINED, AWK_NUMBER, - AWK_CONST_STRING, AWK_STRING, AWK_ARRAY } awk_valtype_t; -typedef struct { - const char *const str; - const size_t len; -} awk_const_string_t; - +/* + * A mutable string. Gawk owns the memory pointed to if it supplied + * the value. Otherwise, it takes ownership of the memory pointed to. + */ typedef struct { char *str; size_t len; } awk_string_t; +/* Arrays are represented as an opaque type */ +typedef void *awk_array_t; + +/* + * An awk value. The val_type tag indicates what + * is in the union. + */ typedef struct { awk_valtype_t val_type; union { - awk_const_string cs; - awk_string s; - double d; - void* a; + awk_string_t s; + double d; + awk_array_t a; } u; -#define const_str_val u.cs -#define str_val u.s -#define num_val u.d +#define str_value u.s +#define num_value u.d #define array_cookie u.a } awk_value_t; +/* possible kinds of function parameters */ +typedef enum { + AWK_PARAM_STRING, /* expecting a scalar string */ + AWK_PARAM_NUMBER, /* expecting a scalar number */ + AWK_PARAM_ARRAY, /* expecting an array */ +} awk_param_type_t; + +/* + * A "flattened" array element. Gawk produces an array of these. + * 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 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_string_t index; + awk_value_t value; +} awk_element_t; + +/* + * A record describing an extension function. Upon being + * loaded, the extension should pass in one of these for + * each C function. + */ typedef struct { const char *name; - size_t num_args; - void (*function)(int num_args); + int (*function)(int num_args_actual); + size_t num_args_expected; } awk_ext_func_t; +typedef int awk_bool_t; /* we don't use on purpose */ + +typedef void *awk_ext_id_t; /* opaque type for extension id */ + +/* + * The API into gawk. Lots of functions here. We hope that they are + * logically organized. + */ typedef struct gawk_api { int major_version; int minor_version; @@ -127,46 +184,112 @@ typedef struct gawk_api { #define gawk_do_debug 4 #define gawk_do_mpfr 5 - /* get the number of arguments passed in function call */ - /* FIXME: Needed? Won't we pass the count in the real call? */ - size_t (*get_curfunc_arg_count)(void *ext_id); - awk_value_t *(*get_curfunc_param)(void *ext_id, size_t count); + /* + * Get the count'th paramater, zero-based. + * Returns NULL if count is out of range, or if actual paramater + * does not match what is specified in wanted. + */ + awk_value_t *(*get_curfunc_param)(awk_ext_id_t id, size_t count, + awk_param_type_t wanted); - /* functions to print messages */ - void (*fatal)(void *ext_id, const char *format, ...); - void (*warning)(void *ext_id, const char *format, ...); - void (*lintwarn)(void *ext_id, const char *format, ...); + /* Set the return value. Gawk takes ownership of string memory */ + void (*set_return_value)(awk_ext_id_t id, const awk_value_t *retval); - /* register an open hook; for opening files read-only */ - int (*register_open_hook)(void *ext_id, - void* (*open_func)(IOBUF *)); + /* Functions to print messages */ + void (*api_fatal)(awk_ext_id_t id, const char *format, ...); + void (*api_warning)(awk_ext_id_t id, const char *format, ...); + void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...); - /* functions to update ERRNO */ - void (*update_ERRNO_int)(void *ext_id, int); - void (*update_ERRNO_string)(void *ext_id, const char *string, - int translate); - void (*unset_ERRNO)(void *ext_id); + /* Register an open hook; for opening files read-only */ + awk_bool_t (*register_open_hook)(awk_ext_id_t id, void* (*open_func)(IOBUF *)); - /* check if a value received from gawk is the null string */ - int (*is_null_string)(void *ext_id, void *value); + /* Functions to update ERRNO */ + void (*update_ERRNO_int)(awk_ext_id_t id, int errno_val); + void (*update_ERRNO_string)(awk_ext_id_t id, const char *string, + awk_bool_t translate); + void (*unset_ERRNO)(awk_ext_id_t id); - /* add a function to the interpreter */ - int *(add_ext_func)(void *ext_id, const awk_ext_func_t *func); + /* Add a function to the interpreter, returns true upon success */ + awk_bool_t (*add_ext_func)(awk_ext_id_t id, const awk_ext_func_t *func); - /* add an exit call back */ - void (*awk_atexit)(void *ext_id, void (*funcp)(void *data, int exit_status), void *arg0); + /* Add an exit call back, returns true upon success */ + awk_bool_t (*awk_atexit)(awk_ext_id_t id, + void (*funcp)(void *data, int exit_status), + void *arg0); + + /* + * Symbol table access: + * - No access to special variables (NF, etc.) + * - One special exception: PROCINFO. + * - Use sym_update() to change a value, including from UNDEFINED + * to scalar or array. + */ + /* + * Lookup a variable, return its value. No messing with the value + * returned. Return value is NULL if the variable doesn't exist. + */ + const awk_value_t *const (*sym_lookup)(awk_ext_id_t id, const char *name); - /* Symbol table access */ - awk_value_t *(*sym_lookup)(void *ext_id, const char *name); - int (*sym_update)(void *ext_id, const char *name, awk_value_t *value); - int (*sym_remove)(void *ext_id, const char *name); + /* + * Update a value. Adds it to the symbol table if not there. + * Changing types is not allowed. + */ + awk_bool_t (*sym_update)(awk_ext_id_t id, const char *name, awk_value_t *value); /* Array management */ - awk_value_t *(*get_array_element)(void *ext_id, void *a_cookie, const awk_value_t* const index); - awk_value_t *(*set_array_element)(void *ext_id, void *a_cookie, - const awk_value_t* const index, const awk_value_t* const value); - awk_value_t *(*del_array_element)(void *ext_id, void *a_cookie, const awk_value_t* const index); - size_t (*get_element_count)(void *ext_id, void *a_cookie); + /* + * Return the value of an element - read only! + * Use set_array_element to change it. + */ + const awk_value_t *const (*get_array_element)(awk_ext_id_t id, + awk_array_t a_cookie, const awk_value_t *const index); + + /* + * Change (or create) element in existing array with + * element->index and element->value. + */ + awk_bool_t (*set_array_element)(awk_ext_id_t id, awk_array_t a_cookie, + awk_element_t *element); + + /* + * Remove the element with the given index. + * Returns success if removed or if element did not exist. + */ + awk_bool_t (*del_array_element)(awk_ext_id_t id, + awk_array_t a_cookie, const awk_value_t* const index); + + /* + * Retrieve total number of elements in array. + * Returns false if some kind of error. + */ + awk_bool_t (*get_element_count)(awk_ext_id_t id, + awk_array_t a_cookie, size_t *count); + + /* Create a new array cookie to which elements may be added */ + awk_array_t (*create_array)(awk_ext_id_t id); + + /* Clear out an array */ + awk_bool_t (*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 (*flatten_array)(awk_ext_id_t id, + awk_array_t a_cookie, + size_t *count, + awk_element_t **data); + + /* + * When done, release the memory, delete any marked elements + * Count must match what gawk thinks the size is. + */ + awk_bool_t (*release_flattened_array)(awk_ext_id_t id, + awk_array_t a_cookie, + size_t count, + awk_element_t *data); + + /* Constructor functions */ + awk_value_t *(*make_string)(awk_ext_id_t id, + const char *string, size_t length); + awk_value_t *(*make_number)(awk_ext_id_t id, double num); } gawk_api_t; @@ -180,13 +303,14 @@ typedef struct gawk_api { #define do_profile api->do_flags[gawk_do_profile] #define do_sandbox api->do_flags[gawk_do_sandbox] #define do_debug api->do_flags[gawk_do_debug] +#define do_mpfr api->do_flags[gawk_do_mpfr] -#define get_curfunc_arg_count api->get_curfunc_arg_count #define get_curfunc_param api->get_curfunc_param +#define set_return_value api->set_return_value -#define fatal api->fatal -#define warning api->warning -#define lintwarn api->lintwarn +#define fatal api->api_fatal +#define warning api->api_warning +#define lintwarn api->api_lintwarn #define register_open_hook api->register_open_hook @@ -201,14 +325,37 @@ typedef struct gawk_api { #define sym_lookup api->sym_lookup #define sym_update api->sym_update -#define sym_remove api->sym_remove #define get_array_element api->get_array_element #define set_array_element api->set_array_element #define del_array_element api->del_array_element #define get_element_count api->get_element_count +#define clear_array api->clear_array +#define create_array api->create_array +#define flatten_array api->flatten_array +#define release_flattened_array api->release_flattened_array + +#define make_string api->make_string +#define make_number api->make_number + +#define emalloc(pointer, type, size, message) \ + do { \ + if ((pointer = (type) malloc(size)) == 0) \ + fatal(ext_id, "malloc of %d bytes failed\n", size); \ + } while(0) + #endif /* GAWK */ +/* + * Each extension must define a function with this prototype: + * + * int dl_load(gawk_api_t *api_p, awk_ext_id_t id) + * + * For the macros to work, the function should save api_p in a + * global variable named 'api'. The return value should be zero + * on failure and non-zero on success. + */ + #ifdef __cplusplus } #endif /* C++ */ -- cgit v1.2.3 From 85458962f4ca247b4c263a5588150960ee6f3e42 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 16 May 2012 22:22:57 +0300 Subject: More work on extension API. --- gawkapi.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 6 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 2a14d334..c3ddc388 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -210,7 +210,8 @@ typedef struct gawk_api { void (*unset_ERRNO)(awk_ext_id_t id); /* Add a function to the interpreter, returns true upon success */ - awk_bool_t (*add_ext_func)(awk_ext_id_t id, const awk_ext_func_t *func); + awk_bool_t (*add_ext_func)(awk_ext_id_t id, const awk_ext_func_t *func, + const char *namespace); /* Add an exit call back, returns true upon success */ awk_bool_t (*awk_atexit)(awk_ext_id_t id, @@ -287,9 +288,9 @@ typedef struct gawk_api { awk_element_t *data); /* Constructor functions */ - awk_value_t *(*make_string)(awk_ext_id_t id, - const char *string, size_t length); - awk_value_t *(*make_number)(awk_ext_id_t id, double num); + awk_value_t *(*api_make_string)(awk_ext_id_t id, + const char *string, size_t length, awk_bool_t duplicate); + awk_value_t *(*api_make_number)(awk_ext_id_t id, double num); } gawk_api_t; @@ -335,8 +336,9 @@ typedef struct gawk_api { #define flatten_array api->flatten_array #define release_flattened_array api->release_flattened_array -#define make_string api->make_string -#define make_number api->make_number +#define make_string(id, str, len) api->api_make_string(id, str, len, 0) +#define dup_string(id, str, len) api->api_make_string(id, str, len, 1) +#define make_number api->api_make_number #define emalloc(pointer, type, size, message) \ do { \ @@ -356,6 +358,50 @@ typedef struct gawk_api { * on failure and non-zero on success. */ +extern int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id); + + +/* TODO: Turn this into a macro... */ +#if 0 +/* Boiler plate code: */ + +static gawk_api_t *const api; +static awk_ext_id_t ext_id; + +int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id); +{ + static awk_ext_func_t func_table[] = { + { "name", do_name, 1 }, + /* ... */ + }; + size_t i, j; + int errors = 0; + + if (api->major_version != GAWK_API_MAJOR_VERSION + || api->minor_version < GAWK_API_MINOR_VERSION) { + fprintf(stderr, ": version mismatch with gawk!\n"); + fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n", + GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION, + api->major_version, api->minor_version); + exit(1); + } + + api = api_p; + ext_id = id; + + /* load functions */ + for (i = 0, j = sizeof(func_table) / sizeof(func_table[0]); i < j; i++) { + if (! add_ext_func(ext_id, & func_table[i], "" /* "NAME" */)) { + warning(ext_id, ": could not add %s\n", + func_table[i].name); + errors++; + } + } + + return (errors == 0); +} +#endif + #ifdef __cplusplus } #endif /* C++ */ -- cgit v1.2.3 From 0f2e51f9b18a1c4e203e0bd0ac3c68db9faa9b6d Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 16 May 2012 22:55:58 +0300 Subject: More progress on extension API. --- gawkapi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index c3ddc388..335e9628 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -201,7 +201,7 @@ typedef struct gawk_api { void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...); /* Register an open hook; for opening files read-only */ - awk_bool_t (*register_open_hook)(awk_ext_id_t id, void* (*open_func)(IOBUF *)); + void (*register_open_hook)(awk_ext_id_t id, void* (*open_func)(IOBUF *)); /* Functions to update ERRNO */ void (*update_ERRNO_int)(awk_ext_id_t id, int errno_val); -- cgit v1.2.3 From cd9fdf221c0504639a38e773c3d56a32ae80e2cc Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 20 May 2012 22:26:46 +0300 Subject: More extension work. --- gawkapi.h | 140 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 84 insertions(+), 56 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 335e9628..76c10260 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -228,6 +228,15 @@ typedef struct gawk_api { /* * Lookup a variable, return its value. No messing with the value * returned. Return value is NULL if the variable doesn't exist. + * + * Returns a pointer to a static variable. Correct usage is thus: + * + * awk_value_t val, *vp; + * vp = api->sym_lookup(id, name); + * if (vp == NULL) + * error_code(); + * val = *vp; + * // use val from here on */ const awk_value_t *const (*sym_lookup)(awk_ext_id_t id, const char *name); @@ -241,6 +250,9 @@ typedef struct gawk_api { /* * Return the value of an element - read only! * Use set_array_element to change it. + * + * As for sym_lookup(), this also returns a static pointer whose + * value should be copied before use. */ const awk_value_t *const (*get_array_element)(awk_ext_id_t id, awk_array_t a_cookie, const awk_value_t *const index); @@ -306,39 +318,55 @@ typedef struct gawk_api { #define do_debug api->do_flags[gawk_do_debug] #define do_mpfr api->do_flags[gawk_do_mpfr] -#define get_curfunc_param api->get_curfunc_param -#define set_return_value api->set_return_value +#define get_curfunc_param(count, wanted) \ + api->get_curfunc_param(ext_id, count, wanted) + +#define set_return_value(retval) \ + api->set_return_value(ext_id, retval) #define fatal api->api_fatal #define warning api->api_warning #define lintwarn api->api_lintwarn -#define register_open_hook api->register_open_hook +#define register_open_hook(func) api->register_open_hook(ext_id, func) -#define update_ERRNO_int api->update_ERRNO_int -#define update_ERRNO_string api->update_ERRNO_string +#define update_ERRNO_int(e) api->update_ERRNO_int(ext_id, e) +#define update_ERRNO_string(str, translate) \ + api->update_ERRNO_string(ext_id, str, translate) #define unset_ERRNO api->unset_ERRNO -#define is_null_string api->is_null_string +#define add_ext_func(func, ns) api->add_ext_func(ext_id, func, ns) +#define awk_atexit(funcp, arg0) api->awk_atexit(ext_id, funcp, arg0) + +#define sym_lookup(name) api->sym_lookup(ext_id, name) +#define sym_update(name, value) \ + api->sym_update(ext_id, name, value) + +#define get_array_element(array, element) \ + api->get_array_element(ext_id, array, element) + +#define set_array_element(array, element) \ + api->set_array_element(ext_id, array, element) + +#define del_array_element(array, index) \ + api->del_array_element(ext_id, array, index) + +#define get_element_count(array, count_p) \ + api->get_element_count(ext_id, array, count_p) -#define add_ext_func api->add_ext_func -#define awk_atexit api->awk_atexit +#define create_array() api->create_array(ext_id) -#define sym_lookup api->sym_lookup -#define sym_update api->sym_update +#define clear_array(array) api->clear_array(ext_id, array) -#define get_array_element api->get_array_element -#define set_array_element api->set_array_element -#define del_array_element api->del_array_element -#define get_element_count api->get_element_count -#define clear_array api->clear_array -#define create_array api->create_array -#define flatten_array api->flatten_array -#define release_flattened_array api->release_flattened_array +#define flatten_array(array, count, data) \ + api->flatten_array(ext_id, array, count, data) -#define make_string(id, str, len) api->api_make_string(id, str, len, 0) -#define dup_string(id, str, len) api->api_make_string(id, str, len, 1) -#define make_number api->api_make_number +#define release_flattened_array(array, count, data) \ + api->release_flattened_array(ext_id, array, count, data) + +#define make_string(str, len) api->api_make_string(ext_id, str, len, 0) +#define dup_string(str, len) api->api_make_string(ext_id, str, len, 1) +#define make_number(num) api->api_make_number(ext_id, num) #define emalloc(pointer, type, size, message) \ do { \ @@ -360,48 +388,48 @@ typedef struct gawk_api { extern int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id); - -/* TODO: Turn this into a macro... */ #if 0 /* Boiler plate code: */ - static gawk_api_t *const api; static awk_ext_id_t ext_id; +static awk_ext_func_t func_table[] = { + { "name", do_name, 1 }, + /* ... */ +}; -int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id); -{ - static awk_ext_func_t func_table[] = { - { "name", do_name, 1 }, - /* ... */ - }; - size_t i, j; - int errors = 0; - - if (api->major_version != GAWK_API_MAJOR_VERSION - || api->minor_version < GAWK_API_MINOR_VERSION) { - fprintf(stderr, ": version mismatch with gawk!\n"); - fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n", - GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION, - api->major_version, api->minor_version); - exit(1); - } - - api = api_p; - ext_id = id; - - /* load functions */ - for (i = 0, j = sizeof(func_table) / sizeof(func_table[0]); i < j; i++) { - if (! add_ext_func(ext_id, & func_table[i], "" /* "NAME" */)) { - warning(ext_id, ": could not add %s\n", - func_table[i].name); - errors++; - } - } - - return (errors == 0); -} +dl_load_func(api, ext_id, func_table, some_name, "name_space_in_quotes") #endif +#define dl_load_func(global_api_p, global_ext_id, func_table, module, name_space) \ +int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ +{ \ + size_t i, j; \ + int errors = 0; \ + \ + if (api->major_version != GAWK_API_MAJOR_VERSION \ + || api->minor_version < GAWK_API_MINOR_VERSION) { \ + fprintf(stderr, #module ": version mismatch with gawk!\n"); \ + fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n", \ + GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION, \ + api->major_version, api->minor_version); \ + exit(1); \ + } \ + \ + global_api_p = api_p; \ + global_ext_id = id; \ +\ + /* load functions */ \ + for (i = 0, j = sizeof(func_table) / sizeof(func_table[0]); i < j; i++) { \ + if (! add_ext_func(& func_table[i], name_space)) { \ + warning(ext_id, #module ": could not add %s\n", \ + func_table[i].name); \ + errors++; \ + } \ + } \ +\ + return (errors == 0); \ +} + #ifdef __cplusplus } #endif /* C++ */ -- cgit v1.2.3 From 577c3fc31a2718461fba2e599d162de96fe838fa Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 24 May 2012 15:34:17 -0400 Subject: First working version of new API mechanism (probably has memory leaks). --- gawkapi.h | 108 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 60 insertions(+), 48 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 76c10260..3b52bff1 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -126,13 +126,6 @@ typedef struct { #define array_cookie u.a } awk_value_t; -/* possible kinds of function parameters */ -typedef enum { - AWK_PARAM_STRING, /* expecting a scalar string */ - AWK_PARAM_NUMBER, /* expecting a scalar number */ - AWK_PARAM_ARRAY, /* expecting an array */ -} awk_param_type_t; - /* * A "flattened" array element. Gawk produces an array of these. * ALL memory pointed to belongs to gawk. Individual elements may @@ -159,7 +152,7 @@ typedef struct awk_element { */ typedef struct { const char *name; - int (*function)(int num_args_actual); + awk_value_t *(*function)(int num_args_actual, awk_value_t *result); size_t num_args_expected; } awk_ext_func_t; @@ -190,10 +183,8 @@ typedef struct gawk_api { * does not match what is specified in wanted. */ awk_value_t *(*get_curfunc_param)(awk_ext_id_t id, size_t count, - awk_param_type_t wanted); - - /* Set the return value. Gawk takes ownership of string memory */ - void (*set_return_value)(awk_ext_id_t id, const awk_value_t *retval); + awk_valtype_t wanted, + awk_value_t *result); /* Functions to print messages */ void (*api_fatal)(awk_ext_id_t id, const char *format, ...); @@ -231,14 +222,14 @@ typedef struct gawk_api { * * Returns a pointer to a static variable. Correct usage is thus: * - * awk_value_t val, *vp; - * vp = api->sym_lookup(id, name); - * if (vp == NULL) + * awk_value_t val; + * if (api->sym_lookup(id, name, &val) == NULL) * error_code(); - * val = *vp; - * // use val from here on + * else { + * // safe to use val + * } */ - const awk_value_t *const (*sym_lookup)(awk_ext_id_t id, const char *name); + awk_value_t *(*sym_lookup)(awk_ext_id_t id, const char *name, awk_value_t *result); /* * Update a value. Adds it to the symbol table if not there. @@ -250,12 +241,10 @@ typedef struct gawk_api { /* * Return the value of an element - read only! * Use set_array_element to change it. - * - * As for sym_lookup(), this also returns a static pointer whose - * value should be copied before use. */ - const awk_value_t *const (*get_array_element)(awk_ext_id_t id, - awk_array_t a_cookie, const awk_value_t *const index); + awk_value_t *(*get_array_element)(awk_ext_id_t id, + awk_array_t a_cookie, const awk_value_t *const index, + awk_value_t *result); /* * Change (or create) element in existing array with @@ -298,12 +287,6 @@ typedef struct gawk_api { awk_array_t a_cookie, size_t count, awk_element_t *data); - - /* Constructor functions */ - awk_value_t *(*api_make_string)(awk_ext_id_t id, - const char *string, size_t length, awk_bool_t duplicate); - awk_value_t *(*api_make_number)(awk_ext_id_t id, double num); - } gawk_api_t; #ifndef GAWK /* these are not for the gawk code itself */ @@ -318,11 +301,8 @@ typedef struct gawk_api { #define do_debug api->do_flags[gawk_do_debug] #define do_mpfr api->do_flags[gawk_do_mpfr] -#define get_curfunc_param(count, wanted) \ - api->get_curfunc_param(ext_id, count, wanted) - -#define set_return_value(retval) \ - api->set_return_value(ext_id, retval) +#define get_curfunc_param(count, wanted, result) \ + api->get_curfunc_param(ext_id, count, wanted, result) #define fatal api->api_fatal #define warning api->api_warning @@ -338,12 +318,12 @@ typedef struct gawk_api { #define add_ext_func(func, ns) api->add_ext_func(ext_id, func, ns) #define awk_atexit(funcp, arg0) api->awk_atexit(ext_id, funcp, arg0) -#define sym_lookup(name) api->sym_lookup(ext_id, name) +#define sym_lookup(name, result) api->sym_lookup(ext_id, name, result) #define sym_update(name, value) \ api->sym_update(ext_id, name, value) -#define get_array_element(array, element) \ - api->get_array_element(ext_id, array, element) +#define get_array_element(array, element, result) \ + api->get_array_element(ext_id, array, element, result) #define set_array_element(array, element) \ api->set_array_element(ext_id, array, element) @@ -364,17 +344,47 @@ typedef struct gawk_api { #define release_flattened_array(array, count, data) \ api->release_flattened_array(ext_id, array, count, data) -#define make_string(str, len) api->api_make_string(ext_id, str, len, 0) -#define dup_string(str, len) api->api_make_string(ext_id, str, len, 1) -#define make_number(num) api->api_make_number(ext_id, num) - #define emalloc(pointer, type, size, message) \ do { \ if ((pointer = (type) malloc(size)) == 0) \ fatal(ext_id, "malloc of %d bytes failed\n", size); \ } while(0) -#endif /* GAWK */ +/* Constructor functions */ +static inline awk_value_t * +r_make_string(const gawk_api_t *api, + awk_ext_id_t *ext_id, + const char *string, + size_t length, + awk_bool_t duplicate, + awk_value_t *result) +{ + char *cp = NULL; + + result->val_type = AWK_STRING; + result->str_value.len = length; + + if (duplicate) { + emalloc(cp, char *, length + 2, "make_string"); + memcpy(cp, string, length); + cp[length] = '\0'; + result->str_value.str = cp; + } else { + result->str_value.str = (char *) string; + } + return result; +} + +#define make_string(str, len, result) r_make_string(api, ext_id, str, len, 0, result) +#define dup_string(str, len, result) r_make_string(api, ext_id, str, len, 1, result) + +static inline awk_value_t * +make_number(double num, awk_value_t *result) +{ + result->val_type = AWK_NUMBER; + result->num_value = num; + return result; +} /* * Each extension must define a function with this prototype: @@ -397,15 +407,18 @@ static awk_ext_func_t func_table[] = { /* ... */ }; -dl_load_func(api, ext_id, func_table, some_name, "name_space_in_quotes") +dl_load_func(func_table, some_name, "name_space_in_quotes") #endif -#define dl_load_func(global_api_p, global_ext_id, func_table, module, name_space) \ +#define dl_load_func(func_table, module, name_space) \ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ { \ size_t i, j; \ int errors = 0; \ - \ +\ + api = api_p; \ + ext_id = id; \ +\ if (api->major_version != GAWK_API_MAJOR_VERSION \ || api->minor_version < GAWK_API_MINOR_VERSION) { \ fprintf(stderr, #module ": version mismatch with gawk!\n"); \ @@ -414,9 +427,6 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ api->major_version, api->minor_version); \ exit(1); \ } \ - \ - global_api_p = api_p; \ - global_ext_id = id; \ \ /* load functions */ \ for (i = 0, j = sizeof(func_table) / sizeof(func_table[0]); i < j; i++) { \ @@ -430,6 +440,8 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ return (errors == 0); \ } +#endif /* GAWK */ + #ifdef __cplusplus } #endif /* C++ */ -- cgit v1.2.3 From eec7101174a3b2807fb282272f75cc13d4b953c3 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 25 May 2012 15:18:43 +0300 Subject: Additional changes / some cleanups. --- gawkapi.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 3b52bff1..54122cab 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -149,6 +149,11 @@ typedef struct awk_element { * A record describing an extension function. Upon being * loaded, the extension should pass in one of these for * each C function. + * + * Each called function must fill in the result with eiher a number + * or string. Gawk takes ownership of any string memory. + * + * The called function should return the value of `result'. */ typedef struct { const char *name; -- cgit v1.2.3 From 04dc190623f0d99d80387b33ca747b8cbad37724 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 29 May 2012 23:33:27 +0300 Subject: Further API work. --- gawkapi.h | 119 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 69 insertions(+), 50 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 54122cab..5fd2ebe1 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -34,10 +34,14 @@ /* * General introduction: * - * This API purposely restricts itself to C90 features. - * In paticular, no bool, no // comments, no use of the - * restrict keyword, or anything else, in order to provide - * maximal portability. + * This API purposely restricts itself to C90 features. In paticular, no + * bool, no // comments, no use of the restrict keyword, or anything else, + * in order to provide maximal portability. + * + * Exception: the "inline" keyword is used below in the "constructor" + * functions. If your compiler doesn't support it, you should either + * -Dinline='' on your command line, or use the autotools and include a + * config.h in your extensions. */ /* Allow use in C++ code. */ @@ -107,30 +111,27 @@ typedef struct { size_t len; } awk_string_t; -/* Arrays are represented as an opaque type */ +/* Arrays are represented as an opaque type. */ typedef void *awk_array_t; /* * An awk value. The val_type tag indicates what - * is in the union. + * is contained. For scalars, gawk fills in both kinds + * of values and val_type indicates the assigned type. + * For arrays, the scalar types will be set to zero. */ typedef struct { awk_valtype_t val_type; - union { - awk_string_t s; - double d; - awk_array_t a; - } u; -#define str_value u.s -#define num_value u.d -#define array_cookie u.a + awk_string_t str_value; + double num_value; + awk_array_t array_cookie; } awk_value_t; /* * A "flattened" array element. Gawk produces an array of these. * 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 API for that purpose. + * one at a time, using the separate API for that purpose. */ typedef struct awk_element { @@ -154,6 +155,11 @@ typedef struct awk_element { * or string. Gawk takes ownership of any string memory. * * The called function should return the value of `result'. + * This is for the convenience of the calling code inside gawk. + * + * Each extension function may decide what to do if the number of + * arguments isn't what it expected. Following awk functions, it + * is likely OK to ignore extra arguments. */ typedef struct { const char *name; @@ -228,13 +234,14 @@ typedef struct gawk_api { * Returns a pointer to a static variable. Correct usage is thus: * * awk_value_t val; - * if (api->sym_lookup(id, name, &val) == NULL) + * if (api->sym_lookup(id, name, &val, wanted) == NULL) * error_code(); * else { * // safe to use val * } */ - awk_value_t *(*sym_lookup)(awk_ext_id_t id, const char *name, awk_value_t *result); + awk_value_t *(*sym_lookup)(awk_ext_id_t id, const char *name, awk_value_t *result, + awk_valtype_t wanted); /* * Update a value. Adds it to the symbol table if not there. @@ -245,11 +252,11 @@ typedef struct gawk_api { /* Array management */ /* * Return the value of an element - read only! - * Use set_array_element to change it. + * Use set_array_element() to change it. */ awk_value_t *(*get_array_element)(awk_ext_id_t id, awk_array_t a_cookie, const awk_value_t *const index, - awk_value_t *result); + awk_value_t *result, awk_valtype_t wanted); /* * Change (or create) element in existing array with @@ -285,8 +292,9 @@ typedef struct gawk_api { awk_element_t **data); /* - * When done, release the memory, delete any marked elements + * When done, delete any marked elements, release the memory. * Count must match what gawk thinks the size is. + * Otherwise it's a fatal error. */ awk_bool_t (*release_flattened_array)(awk_ext_id_t id, awk_array_t a_cookie, @@ -294,60 +302,60 @@ typedef struct gawk_api { awk_element_t *data); } gawk_api_t; -#ifndef GAWK /* these are not for the gawk code itself */ +#ifndef GAWK /* these are not for the gawk code itself! */ /* - * Use these if you want to define a "global" variable named api - * to make the code a little easier to read. + * Use these if you want to define "global" variables named api + * and ext_id to make the code a little easier to read. */ -#define do_lint api->do_flags[gawk_do_lint] -#define do_traditional api->do_flags[gawk_do_traditional] -#define do_profile api->do_flags[gawk_do_profile] -#define do_sandbox api->do_flags[gawk_do_sandbox] -#define do_debug api->do_flags[gawk_do_debug] -#define do_mpfr api->do_flags[gawk_do_mpfr] +#define do_lint (api->do_flags[gawk_do_lint]) +#define do_traditional (api->do_flags[gawk_do_traditional]) +#define do_profile (api->do_flags[gawk_do_profile]) +#define do_sandbox (api->do_flags[gawk_do_sandbox]) +#define do_debug (api->do_flags[gawk_do_debug]) +#define do_mpfr (api->do_flags[gawk_do_mpfr]) #define get_curfunc_param(count, wanted, result) \ - api->get_curfunc_param(ext_id, count, wanted, result) + (api->get_curfunc_param(ext_id, count, wanted, result)) #define fatal api->api_fatal #define warning api->api_warning #define lintwarn api->api_lintwarn -#define register_open_hook(func) api->register_open_hook(ext_id, func) +#define register_open_hook(func) (api->register_open_hook(ext_id, func)) -#define update_ERRNO_int(e) api->update_ERRNO_int(ext_id, e) +#define update_ERRNO_int(e) (api->update_ERRNO_int(ext_id, e)) #define update_ERRNO_string(str, translate) \ - api->update_ERRNO_string(ext_id, str, translate) -#define unset_ERRNO api->unset_ERRNO + (api->update_ERRNO_string(ext_id, str, translate)) +#define unset_ERRNO() (api->unset_ERRNO(ext_id)) -#define add_ext_func(func, ns) api->add_ext_func(ext_id, func, ns) -#define awk_atexit(funcp, arg0) api->awk_atexit(ext_id, funcp, arg0) +#define add_ext_func(func, ns) (api->add_ext_func(ext_id, func, ns)) +#define awk_atexit(funcp, arg0) (api->awk_atexit(ext_id, funcp, arg0)) -#define sym_lookup(name, result) api->sym_lookup(ext_id, name, result) +#define sym_lookup(name, result, wanted) (api->sym_lookup(ext_id, name, result, wanted)) #define sym_update(name, value) \ - api->sym_update(ext_id, name, value) + (api->sym_update(ext_id, name, value)) -#define get_array_element(array, element, result) \ - api->get_array_element(ext_id, array, element, result) +#define get_array_element(array, element, result, wanted) \ + (api->get_array_element(ext_id, array, element, result, wanted)) #define set_array_element(array, element) \ - api->set_array_element(ext_id, array, element) + (api->set_array_element(ext_id, array, element)) #define del_array_element(array, index) \ - api->del_array_element(ext_id, array, index) + (api->del_array_element(ext_id, array, index)) #define get_element_count(array, count_p) \ - api->get_element_count(ext_id, array, count_p) + (api->get_element_count(ext_id, array, count_p)) -#define create_array() api->create_array(ext_id) +#define create_array() (api->create_array(ext_id)) -#define clear_array(array) api->clear_array(ext_id, array) +#define clear_array(array) (api->clear_array(ext_id, array)) #define flatten_array(array, count, data) \ - api->flatten_array(ext_id, array, count, data) + (api->flatten_array(ext_id, array, count, data)) #define release_flattened_array(array, count, data) \ - api->release_flattened_array(ext_id, array, count, data) + (api->release_flattened_array(ext_id, array, count, data)) #define emalloc(pointer, type, size, message) \ do { \ @@ -356,6 +364,9 @@ typedef struct gawk_api { } while(0) /* Constructor functions */ + +/* r_make_string --- make a string value in result from the passed-in string */ + static inline awk_value_t * r_make_string(const gawk_api_t *api, awk_ext_id_t *ext_id, @@ -366,6 +377,8 @@ r_make_string(const gawk_api_t *api, { char *cp = NULL; + memset(result, 0, sizeof(*result)); + result->val_type = AWK_STRING; result->str_value.len = length; @@ -377,17 +390,23 @@ r_make_string(const gawk_api_t *api, } else { result->str_value.str = (char *) string; } + return result; } #define make_string(str, len, result) r_make_string(api, ext_id, str, len, 0, result) #define dup_string(str, len, result) r_make_string(api, ext_id, str, len, 1, result) +/* make_number --- make a number value in result */ + static inline awk_value_t * make_number(double num, awk_value_t *result) { + memset(result, 0, sizeof(*result)); + result->val_type = AWK_NUMBER; result->num_value = num; + return result; } @@ -396,9 +415,9 @@ make_number(double num, awk_value_t *result) * * int dl_load(gawk_api_t *api_p, awk_ext_id_t id) * - * For the macros to work, the function should save api_p in a - * global variable named 'api'. The return value should be zero - * on failure and non-zero on success. + * For the macros to work, the function should save api_p in a global + * variable named 'api' and save id in a global variable named 'ext_id'. + * The return value should be zero on failure and non-zero on success. */ extern int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id); -- cgit v1.2.3 From e6ddb0631c88b591792e3486f857ca26875de310 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 30 May 2012 21:47:18 +0300 Subject: Continue refining extension API and implementation. --- gawkapi.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 5fd2ebe1..87d2d2f0 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -245,7 +245,9 @@ typedef struct gawk_api { /* * Update a value. Adds it to the symbol table if not there. - * Changing types is not allowed. + * Changing types (scalar <--> array) is not allowed. + * In fact, using this to update an array is not allowed, either. + * Such an attempt returns false. */ awk_bool_t (*sym_update)(awk_ext_id_t id, const char *name, awk_value_t *value); -- cgit v1.2.3 From dab3a678b3f65ae4cde21ca4b1d4fd24e8a71918 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 6 Jun 2012 20:08:02 +0300 Subject: Changes to LINT reflect to extn API. Add API tests. --- gawkapi.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 87d2d2f0..09a1ce79 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -179,6 +179,11 @@ typedef struct gawk_api { int major_version; int minor_version; + /* + * These can change on the fly as things happen within gawk. + * Currently only do_lint is prone to change, but we reserve + * the right to allow the others also. + */ int do_flags[DO_FLAGS_SIZE]; /* Use these as indices into do_flags[] array to check the values */ #define gawk_do_lint 0 -- cgit v1.2.3 From 820b6a2ccb7859e15ade36af6ac1d0d08c1da4b1 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 12 Jun 2012 22:10:31 +0300 Subject: Further cleanups and improvements in API. --- gawkapi.h | 68 +++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 21 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 09a1ce79..7e6a66fc 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -116,15 +116,18 @@ typedef void *awk_array_t; /* * An awk value. The val_type tag indicates what - * is contained. For scalars, gawk fills in both kinds - * of values and val_type indicates the assigned type. - * For arrays, the scalar types will be set to zero. + * is in the union. */ typedef struct { awk_valtype_t val_type; - awk_string_t str_value; - double num_value; - awk_array_t array_cookie; + union { + awk_string_t s; + double d; + awk_array_t a; + } u; +#define str_value u.s +#define num_value u.d +#define array_cookie u.a } awk_value_t; /* @@ -195,10 +198,27 @@ typedef struct gawk_api { /* * Get the count'th paramater, zero-based. - * Returns NULL if count is out of range, or if actual paramater - * does not match what is specified in wanted. + * Returns false if count is out of range, or if actual paramater + * does not match what is specified in wanted. In that case, + * result->val_type will hold the actual type of what was passed. + + Table entry is type returned: + + +-----------------------------------------+ + | Type Requested: | + +----------+----------+-------+-----------+ + | String | Number | Array | Undefined | + +---------+-----------+----------+----------+-------+-----------+ + | Type | String | String | false | false | String | + | of +-----------+----------+----------+-------+-----------+ + | Actual | Number | false | Number | false | Number | + | Value: +-----------+----------+----------+-------+-----------+ + | | Array | false | false | Array | Array | + | +-----------+----------+----------+-------+-----------+ + | | Undefined | false | false | false | Undefined | + +---------+-----------+----------+----------+-------+-----------+ */ - awk_value_t *(*get_curfunc_param)(awk_ext_id_t id, size_t count, + awk_bool_t (*get_argument)(awk_ext_id_t id, size_t count, awk_valtype_t wanted, awk_value_t *result); @@ -221,7 +241,7 @@ typedef struct gawk_api { const char *namespace); /* Add an exit call back, returns true upon success */ - awk_bool_t (*awk_atexit)(awk_ext_id_t id, + void (*awk_atexit)(awk_ext_id_t id, void (*funcp)(void *data, int exit_status), void *arg0); @@ -233,20 +253,23 @@ typedef struct gawk_api { * to scalar or array. */ /* - * Lookup a variable, return its value. No messing with the value - * returned. Return value is NULL if the variable doesn't exist. - * - * Returns a pointer to a static variable. Correct usage is thus: + * Lookup a variable, fills in value. No messing with the value + * returned. Returns false if the variable doesn't exist + * or the wrong type was requested. + * In the latter case, fills in vaule->val_type with the real type. + * Built-in variables (except PROCINFO) may not be accessed by an extension. * * awk_value_t val; - * if (api->sym_lookup(id, name, &val, wanted) == NULL) + * if (! api->sym_lookup(id, name, wanted, & val)) * error_code(); * else { * // safe to use val * } */ - awk_value_t *(*sym_lookup)(awk_ext_id_t id, const char *name, awk_value_t *result, - awk_valtype_t wanted); + awk_bool_t (*sym_lookup)(awk_ext_id_t id, + const char *name, + awk_valtype_t wanted, + awk_value_t *result); /* * Update a value. Adds it to the symbol table if not there. @@ -260,10 +283,13 @@ typedef struct gawk_api { /* * Return the value of an element - read only! * Use set_array_element() to change it. + * Behavior for value and return is same as for get_argument + * and sym_lookup. */ - awk_value_t *(*get_array_element)(awk_ext_id_t id, + awk_bool_t (*get_array_element)(awk_ext_id_t id, awk_array_t a_cookie, const awk_value_t *const index, - awk_value_t *result, awk_valtype_t wanted); + awk_valtype_t wanted, + awk_value_t *result); /* * Change (or create) element in existing array with @@ -321,8 +347,8 @@ typedef struct gawk_api { #define do_debug (api->do_flags[gawk_do_debug]) #define do_mpfr (api->do_flags[gawk_do_mpfr]) -#define get_curfunc_param(count, wanted, result) \ - (api->get_curfunc_param(ext_id, count, wanted, result)) +#define get_argument(count, wanted, result) \ + (api->get_argument(ext_id, count, wanted, result)) #define fatal api->api_fatal #define warning api->api_warning -- cgit v1.2.3 From 5e79fa8735ec2984fee9054cccd51d86fa939621 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 17 Jun 2012 20:47:50 +0300 Subject: Still more API and testext.c work. --- gawkapi.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 7e6a66fc..ca06cea3 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -287,8 +287,8 @@ typedef struct gawk_api { * and sym_lookup. */ awk_bool_t (*get_array_element)(awk_ext_id_t id, - awk_array_t a_cookie, const awk_value_t *const index, - awk_valtype_t wanted, + awk_array_t a_cookie, + const awk_value_t *const index, awk_value_t *result); /* @@ -364,12 +364,12 @@ typedef struct gawk_api { #define add_ext_func(func, ns) (api->add_ext_func(ext_id, func, ns)) #define awk_atexit(funcp, arg0) (api->awk_atexit(ext_id, funcp, arg0)) -#define sym_lookup(name, result, wanted) (api->sym_lookup(ext_id, name, result, wanted)) +#define sym_lookup(name, wanted, result) (api->sym_lookup(ext_id, name, wanted, result)) #define sym_update(name, value) \ (api->sym_update(ext_id, name, value)) -#define get_array_element(array, element, result, wanted) \ - (api->get_array_element(ext_id, array, element, result, wanted)) +#define get_array_element(array, index, result) \ + (api->get_array_element(ext_id, array, index, result)) #define set_array_element(array, element) \ (api->set_array_element(ext_id, array, element)) @@ -401,8 +401,8 @@ typedef struct gawk_api { /* r_make_string --- make a string value in result from the passed-in string */ static inline awk_value_t * -r_make_string(const gawk_api_t *api, - awk_ext_id_t *ext_id, +r_make_string(const gawk_api_t *api, /* needed for emalloc */ + awk_ext_id_t *ext_id, /* ditto */ const char *string, size_t length, awk_bool_t duplicate, -- cgit v1.2.3 From 6311c35dd8984a8516802b3cc111c1f411e098fd Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Mon, 18 Jun 2012 21:13:34 +0300 Subject: More API implementation progress. --- gawkapi.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index ca06cea3..7fdd7634 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -289,6 +289,7 @@ typedef struct gawk_api { awk_bool_t (*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); /* @@ -368,8 +369,8 @@ typedef struct gawk_api { #define sym_update(name, value) \ (api->sym_update(ext_id, name, value)) -#define get_array_element(array, index, result) \ - (api->get_array_element(ext_id, array, index, result)) +#define get_array_element(array, index, wanted, result) \ + (api->get_array_element(ext_id, array, index, wanted, result)) #define set_array_element(array, element) \ (api->set_array_element(ext_id, array, element)) -- cgit v1.2.3 From 1e3ac8a49caeeb991d8163042a576a66db51c74b Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Mon, 18 Jun 2012 23:00:58 +0300 Subject: Get most of array flattening done. --- gawkapi.h | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 7fdd7634..8102f70e 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -145,10 +145,23 @@ typedef struct awk_element { AWK_ELEMENT_DELETE = 1 /* set by extension if should be deleted */ } flags; - awk_string_t index; + awk_value_t index; awk_value_t value; } awk_element_t; +#ifdef GAWK +#define awk_const +#else +#define awk_const const +#endif + +typedef struct awk_flat_array { + void *opaque1; /* private data for use by gawk */ + 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; + /* * A record describing an extension function. Upon being * loaded, the extension should pass in one of these for @@ -222,6 +235,11 @@ typedef struct gawk_api { awk_valtype_t wanted, awk_value_t *result); + /* + * FIXME: Missing update_argument to convert an undefined + * argument into an array or scalar. + */ + /* Functions to print messages */ void (*api_fatal)(awk_ext_id_t id, const char *format, ...); void (*api_warning)(awk_ext_id_t id, const char *format, ...); @@ -257,7 +275,8 @@ typedef struct gawk_api { * returned. Returns false if the variable doesn't exist * or the wrong type was requested. * In the latter case, fills in vaule->val_type with the real type. - * Built-in variables (except PROCINFO) may not be accessed by an extension. + * Built-in variables (except PROCINFO) may not be accessed by an + * extension. * * awk_value_t val; * if (! api->sym_lookup(id, name, wanted, & val)) @@ -322,8 +341,7 @@ typedef struct gawk_api { /* Flatten out an array so that it can be looped over easily. */ awk_bool_t (*flatten_array)(awk_ext_id_t id, awk_array_t a_cookie, - size_t *count, - awk_element_t **data); + awk_flat_array_t **data); /* * When done, delete any marked elements, release the memory. @@ -332,8 +350,7 @@ typedef struct gawk_api { */ awk_bool_t (*release_flattened_array)(awk_ext_id_t id, awk_array_t a_cookie, - size_t count, - awk_element_t *data); + awk_flat_array_t *data); } gawk_api_t; #ifndef GAWK /* these are not for the gawk code itself! */ @@ -385,11 +402,11 @@ typedef struct gawk_api { #define clear_array(array) (api->clear_array(ext_id, array)) -#define flatten_array(array, count, data) \ - (api->flatten_array(ext_id, array, count, data)) +#define flatten_array(array, data) \ + (api->flatten_array(ext_id, array, data)) -#define release_flattened_array(array, count, data) \ - (api->release_flattened_array(ext_id, array, count, data)) +#define release_flattened_array(array, data) \ + (api->release_flattened_array(ext_id, array, data)) #define emalloc(pointer, type, size, message) \ do { \ -- cgit v1.2.3 From fd3c1195711270a001d860770098b8c0d9118c10 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 19 Jun 2012 20:54:19 +0300 Subject: Delete marked elements from flattened array. --- gawkapi.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 8102f70e..7973d7a8 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -131,7 +131,8 @@ typedef struct { } awk_value_t; /* - * A "flattened" array element. Gawk produces an array of these. + * 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. @@ -149,15 +150,20 @@ typedef struct awk_element { awk_value_t value; } awk_element_t; +/* This is used to keep the extension from modifying certain fields. */ #ifdef GAWK #define awk_const #else #define awk_const const #endif +/* + * A "flattened" array. See the description above for how + * to use the elements contained herein. + */ typedef struct awk_flat_array { - void *opaque1; /* private data for use by gawk */ - void *opaque2; /* private data for use by gawk */ + 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; -- cgit v1.2.3 From d66f3c9922e36bb2e760e0ac36364c1a5aa11442 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 20 Jun 2012 21:41:15 +0300 Subject: API: Add set_parameter function and test. --- gawkapi.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 7973d7a8..3325c454 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -242,9 +242,14 @@ typedef struct gawk_api { awk_value_t *result); /* - * FIXME: Missing update_argument to convert an undefined - * argument into an array or scalar. + * Convert a paramter that was undefined into an array + * (provide call-by-reference for arrays). Returns false + * if count is too big, or if the argument's type is + * not undefined. */ + awk_bool_t (*set_argument)(awk_ext_id_t id, + size_t count, + awk_array_t array); /* Functions to print messages */ void (*api_fatal)(awk_ext_id_t id, const char *format, ...); @@ -373,6 +378,8 @@ typedef struct gawk_api { #define get_argument(count, wanted, result) \ (api->get_argument(ext_id, count, wanted, result)) +#define set_argument(count, new_array) \ + (api->set_argument(ext_id, count, new_array)) #define fatal api->api_fatal #define warning api->api_warning -- cgit v1.2.3 From 6139211362667682c3022a72321e0cd8945b6592 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Sun, 24 Jun 2012 18:43:49 -0400 Subject: Hide private parts of IOBUF from extensions. --- gawkapi.h | 44 +++++++++----------------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 3325c454..1954a5e4 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -49,40 +49,14 @@ extern "C" { #endif -/* struct used for reading records and managing buffers */ -typedef struct iobuf { - const char *name; /* filename */ - int fd; /* file descriptor */ - struct stat sbuf; /* stat buf */ - char *buf; /* start data buffer */ - char *off; /* start of current record in buffer */ - char *dataend; /* first byte in buffer to hold new data, - NULL if not read yet */ - char *end; /* end of buffer */ - size_t readsize; /* set from fstat call */ - size_t size; /* buffer size */ - ssize_t count; /* amount read last time */ - size_t scanoff; /* where we were in the buffer when we had - to regrow/refill */ - /* - * No argument prototype on read_func. See get_src_buf() - * in awkgram.y. - */ - ssize_t (*read_func)(); - - void *opaque; /* private data for open hooks */ - int (*get_record)(char **out, struct iobuf *, int *errcode); - void (*close_func)(struct iobuf *); /* open and close hooks */ - - int errcode; - - int flag; -# define IOP_IS_TTY 1 -# define IOP_NOFREE_OBJ 2 -# define IOP_AT_EOF 4 -# define IOP_CLOSED 8 -# define IOP_AT_START 16 -} IOBUF; +/* portions of IOBUF that should be accessible to extension functions: */ +typedef struct iobuf_public { + const char *name; /* filename */ + int fd; /* file descriptor */ + void *opaque; /* private data for open hooks */ + int (*get_record)(char **out, struct iobuf_public *, int *errcode); + void (*close_func)(struct iobuf_public *); +} IOBUF_PUBLIC; #define GAWK_API_MAJOR_VERSION 0 #define GAWK_API_MINOR_VERSION 0 @@ -257,7 +231,7 @@ typedef struct gawk_api { void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...); /* Register an open hook; for opening files read-only */ - void (*register_open_hook)(awk_ext_id_t id, void* (*open_func)(IOBUF *)); + void (*register_open_hook)(awk_ext_id_t id, void* (*open_func)(IOBUF_PUBLIC *)); /* Functions to update ERRNO */ void (*update_ERRNO_int)(awk_ext_id_t id, int errno_val); -- cgit v1.2.3 From 33734338e34ed4588ca05cecd5324d5ab5a1a654 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 29 Jun 2012 12:55:37 +0300 Subject: Minor improvements in doc and in ordchr.c. --- gawkapi.h | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 1954a5e4..10f1e0c3 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -190,7 +190,10 @@ typedef struct gawk_api { #define gawk_do_mpfr 5 /* - * Get the count'th paramater, zero-based. + * All of the functions that return a value from inside gawk + * (get a parameter, get a global variable, get an array element) + * behave in the same way. + * * Returns false if count is out of range, or if actual paramater * does not match what is specified in wanted. In that case, * result->val_type will hold the actual type of what was passed. @@ -202,14 +205,25 @@ typedef struct gawk_api { +----------+----------+-------+-----------+ | String | Number | Array | Undefined | +---------+-----------+----------+----------+-------+-----------+ - | Type | String | String | false | false | String | + | Type | String | String | Number if| false | String | + | | | | it can be| | | + | | | |converted,| | | + | | | | else | | | + | | | | false | | | | of +-----------+----------+----------+-------+-----------+ - | Actual | Number | false | Number | false | Number | + | Actual | Number | String | Number | false | Number | | Value: +-----------+----------+----------+-------+-----------+ | | Array | false | false | Array | Array | | +-----------+----------+----------+-------+-----------+ | | Undefined | false | false | false | Undefined | +---------+-----------+----------+----------+-------+-----------+ + */ + + /* + * Get the count'th paramater, zero-based. + * Returns false if count is out of range, or if actual paramater + * does not match what is specified in wanted. In that case, + * result->val_type is as described above. */ awk_bool_t (*get_argument)(awk_ext_id_t id, size_t count, awk_valtype_t wanted, @@ -258,8 +272,9 @@ typedef struct gawk_api { /* * Lookup a variable, fills in value. No messing with the value * returned. Returns false if the variable doesn't exist - * or the wrong type was requested. - * In the latter case, fills in vaule->val_type with the real type. + * or if the wrong type was requested. + * In the latter case, fills in vaule->val_type with the real type, + * as described above. * Built-in variables (except PROCINFO) may not be accessed by an * extension. * -- cgit v1.2.3 From 7d37bcd5a8066718b15de8c03725708819389931 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Mon, 9 Jul 2012 21:17:10 +0300 Subject: API: Update set_array_element(). Adjust extensions. --- gawkapi.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 10f1e0c3..5be5ea08 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -316,7 +316,8 @@ typedef struct gawk_api { * element->index and element->value. */ awk_bool_t (*set_array_element)(awk_ext_id_t id, awk_array_t a_cookie, - awk_element_t *element); + const awk_value_t *const index, + const awk_value_t *const value); /* * Remove the element with the given index. @@ -391,8 +392,11 @@ typedef struct gawk_api { #define get_array_element(array, index, wanted, result) \ (api->get_array_element(ext_id, array, index, wanted, result)) -#define set_array_element(array, element) \ - (api->set_array_element(ext_id, array, element)) +#define set_array_element(array, index, value) \ + (api->set_array_element(ext_id, array, index, value)) + +#define set_array_element_by_elem(array, elem) \ + (set_array_element(array, & (elem)->index, & (elem)->value)) #define del_array_element(array, index) \ (api->del_array_element(ext_id, array, index)) -- cgit v1.2.3 From 6d1724214a95330b63a6a557f89fb9b40b4a521f Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 11 Jul 2012 21:26:37 +0300 Subject: API clean up and require strings to be malloced. --- gawkapi.h | 179 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 120 insertions(+), 59 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 5be5ea08..2bef258e 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -42,6 +42,26 @@ * functions. If your compiler doesn't support it, you should either * -Dinline='' on your command line, or use the autotools and include a * config.h in your extensions. + * + * Additional important information: + * + * 1. ALL string values in awk_value_t objects need to come from malloc(). + * Gawk will handle releasing the storage if necessary. This is slightly + * awkward, in that you can't take an awk_value_t that you got from gawk + * and reuse it directly, even for something that is conceptually pass + * by value. + * + * 2. The correct way to create new arrays is to work "bottom up". + * + * new_array = create_array(); + * // fill in new array with lots of subscripts and values + * val.val_type = AWK_ARRAY; + * val.array_cookie = new_array; + * sym_update("array", &val); // install array in the symbol table + * + * After doing so, do NOT make further use of the new_array variable; + * instead use sym_lookup to get the array_cookie if you need to do further + * manipulation of the array. */ /* Allow use in C++ code. */ @@ -73,7 +93,8 @@ typedef enum { AWK_UNDEFINED, AWK_NUMBER, AWK_STRING, - AWK_ARRAY + AWK_ARRAY, + AWK_SCALAR, /* opaque access to a variable */ } awk_valtype_t; /* @@ -88,6 +109,9 @@ typedef struct { /* Arrays are represented as an opaque type. */ typedef void *awk_array_t; +/* Scalars can be represented as an opaque type. */ +typedef void *awk_scalar_t; + /* * An awk value. The val_type tag indicates what * is in the union. @@ -98,10 +122,12 @@ typedef struct { awk_string_t s; double d; awk_array_t a; + awk_array_t scl; } u; #define str_value u.s #define num_value u.d #define array_cookie u.a +#define scalar_cookie u.scl } awk_value_t; /* @@ -200,23 +226,23 @@ typedef struct gawk_api { Table entry is type returned: - +-----------------------------------------+ - | Type Requested: | - +----------+----------+-------+-----------+ - | String | Number | Array | Undefined | - +---------+-----------+----------+----------+-------+-----------+ - | Type | String | String | Number if| false | String | - | | | | it can be| | | - | | | |converted,| | | - | | | | else | | | - | | | | false | | | - | of +-----------+----------+----------+-------+-----------+ - | Actual | Number | String | Number | false | Number | - | Value: +-----------+----------+----------+-------+-----------+ - | | Array | false | false | Array | Array | - | +-----------+----------+----------+-------+-----------+ - | | Undefined | false | false | false | Undefined | - +---------+-----------+----------+----------+-------+-----------+ + +---------------------------------------------------+ + | Type Requested: | + +----------+----------+-------+---------+-----------+ + | String | Number | Array | Scalar | Undefined | + +---------+-----------+----------+----------+-------+---------+-----------+ + | Type | String | String | Number if| false | Scalar | String | + | | | | it can be| | | | + | | | |converted,| | | | + | | | | else | | | | + | | | | false | | | | + | of +-----------+----------+----------+-------+---------+-----------+ + | Actual | Number | String | Number | false | Scalar | Number | + | Value: +-----------+----------+----------+-------+---------+-----------+ + | | Array | false | false | Array | false | Array | + | +-----------+----------+----------+-------+---------+-----------+ + | | Undefined | false | false | false | false | Undefined | + +---------+-----------+----------+----------+-------+---------+-----------+ */ /* @@ -225,7 +251,7 @@ typedef struct gawk_api { * does not match what is specified in wanted. In that case, * result->val_type is as described above. */ - awk_bool_t (*get_argument)(awk_ext_id_t id, size_t count, + awk_bool_t (*api_get_argument)(awk_ext_id_t id, size_t count, awk_valtype_t wanted, awk_value_t *result); @@ -235,7 +261,7 @@ typedef struct gawk_api { * if count is too big, or if the argument's type is * not undefined. */ - awk_bool_t (*set_argument)(awk_ext_id_t id, + awk_bool_t (*api_set_argument)(awk_ext_id_t id, size_t count, awk_array_t array); @@ -245,20 +271,20 @@ typedef struct gawk_api { void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...); /* Register an open hook; for opening files read-only */ - void (*register_open_hook)(awk_ext_id_t id, void* (*open_func)(IOBUF_PUBLIC *)); + void (*api_register_open_hook)(awk_ext_id_t id, void* (*open_func)(IOBUF_PUBLIC *)); /* Functions to update ERRNO */ - void (*update_ERRNO_int)(awk_ext_id_t id, int errno_val); - void (*update_ERRNO_string)(awk_ext_id_t id, const char *string, + void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val); + void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string, awk_bool_t translate); - void (*unset_ERRNO)(awk_ext_id_t id); + void (*api_unset_ERRNO)(awk_ext_id_t id); /* Add a function to the interpreter, returns true upon success */ - awk_bool_t (*add_ext_func)(awk_ext_id_t id, const awk_ext_func_t *func, + awk_bool_t (*api_add_ext_func)(awk_ext_id_t id, const awk_ext_func_t *func, const char *namespace); /* Add an exit call back, returns true upon success */ - void (*awk_atexit)(awk_ext_id_t id, + void (*api_awk_atexit)(awk_ext_id_t id, void (*funcp)(void *data, int exit_status), void *arg0); @@ -285,7 +311,7 @@ typedef struct gawk_api { * // safe to use val * } */ - awk_bool_t (*sym_lookup)(awk_ext_id_t id, + awk_bool_t (*api_sym_lookup)(awk_ext_id_t id, const char *name, awk_valtype_t wanted, awk_value_t *result); @@ -296,16 +322,32 @@ typedef struct gawk_api { * In fact, using this to update an array is not allowed, either. * Such an attempt returns false. */ - awk_bool_t (*sym_update)(awk_ext_id_t id, const char *name, awk_value_t *value); + awk_bool_t (*api_sym_update)(awk_ext_id_t id, const char *name, awk_value_t *value); + + /* + * Work with a scalar cookie. + * Flow is + * sym_lookup with wanted == AWK_SCALAR + * if returns false + * sym_update with real initial value + * 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. + */ + awk_bool_t (*api_sym_update_scalar)(awk_ext_id_t id, + awk_scalar_t cookie, awk_value_t *value); /* Array management */ /* * Return the value of an element - read only! * Use set_array_element() to change it. - * Behavior for value and return is same as for get_argument + * Behavior for value and return is same as for api_get_argument * and sym_lookup. */ - awk_bool_t (*get_array_element)(awk_ext_id_t id, + 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, @@ -315,7 +357,7 @@ typedef struct gawk_api { * Change (or create) element in existing array with * element->index and element->value. */ - awk_bool_t (*set_array_element)(awk_ext_id_t id, awk_array_t a_cookie, + 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); @@ -323,24 +365,24 @@ typedef struct gawk_api { * Remove the element with the given index. * Returns success if removed or if element did not exist. */ - awk_bool_t (*del_array_element)(awk_ext_id_t id, + awk_bool_t (*api_del_array_element)(awk_ext_id_t id, awk_array_t a_cookie, const awk_value_t* const index); /* * Retrieve total number of elements in array. * Returns false if some kind of error. */ - awk_bool_t (*get_element_count)(awk_ext_id_t id, + awk_bool_t (*api_get_element_count)(awk_ext_id_t id, awk_array_t a_cookie, size_t *count); /* Create a new array cookie to which elements may be added */ - awk_array_t (*create_array)(awk_ext_id_t id); + awk_array_t (*api_create_array)(awk_ext_id_t id); /* Clear out an array */ - awk_bool_t (*clear_array)(awk_ext_id_t id, awk_array_t a_cookie); + 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 (*flatten_array)(awk_ext_id_t id, + awk_bool_t (*api_flatten_array)(awk_ext_id_t id, awk_array_t a_cookie, awk_flat_array_t **data); @@ -349,7 +391,7 @@ typedef struct gawk_api { * Count must match what gawk thinks the size is. * Otherwise it's a fatal error. */ - awk_bool_t (*release_flattened_array)(awk_ext_id_t id, + awk_bool_t (*api_release_flattened_array)(awk_ext_id_t id, awk_array_t a_cookie, awk_flat_array_t *data); } gawk_api_t; @@ -367,52 +409,54 @@ typedef struct gawk_api { #define do_mpfr (api->do_flags[gawk_do_mpfr]) #define get_argument(count, wanted, result) \ - (api->get_argument(ext_id, count, wanted, result)) + (api->api_get_argument(ext_id, count, wanted, result)) #define set_argument(count, new_array) \ - (api->set_argument(ext_id, count, new_array)) + (api->api_set_argument(ext_id, count, new_array)) #define fatal api->api_fatal #define warning api->api_warning #define lintwarn api->api_lintwarn -#define register_open_hook(func) (api->register_open_hook(ext_id, func)) +#define register_open_hook(func) (api->api_register_open_hook(ext_id, func)) -#define update_ERRNO_int(e) (api->update_ERRNO_int(ext_id, e)) +#define update_ERRNO_int(e) (api->api_update_ERRNO_int(ext_id, e)) #define update_ERRNO_string(str, translate) \ - (api->update_ERRNO_string(ext_id, str, translate)) -#define unset_ERRNO() (api->unset_ERRNO(ext_id)) + (api->api_update_ERRNO_string(ext_id, str, translate)) +#define unset_ERRNO() (api->api_unset_ERRNO(ext_id)) -#define add_ext_func(func, ns) (api->add_ext_func(ext_id, func, ns)) -#define awk_atexit(funcp, arg0) (api->awk_atexit(ext_id, funcp, arg0)) +#define add_ext_func(func, ns) (api->api_add_ext_func(ext_id, func, ns)) +#define awk_atexit(funcp, arg0) (api->api_awk_atexit(ext_id, funcp, arg0)) -#define sym_lookup(name, wanted, result) (api->sym_lookup(ext_id, name, wanted, result)) +#define sym_lookup(name, wanted, result) (api->api_sym_lookup(ext_id, name, wanted, result)) #define sym_update(name, value) \ - (api->sym_update(ext_id, name, value)) + (api->api_sym_update(ext_id, name, value)) +#define sym_update_scalar(scalar_cookie, value) \ + (api->api_sym_update_scalar)(ext_id, scalar_cookie, value) #define get_array_element(array, index, wanted, result) \ - (api->get_array_element(ext_id, array, index, wanted, result)) + (api->api_get_array_element(ext_id, array, index, wanted, result)) #define set_array_element(array, index, value) \ - (api->set_array_element(ext_id, array, index, value)) + (api->api_set_array_element(ext_id, array, index, value)) #define set_array_element_by_elem(array, elem) \ - (set_array_element(array, & (elem)->index, & (elem)->value)) + (api->api_set_array_element(ext_id, array, & (elem)->index, & (elem)->value)) #define del_array_element(array, index) \ - (api->del_array_element(ext_id, array, index)) + (api->api_del_array_element(ext_id, array, index)) #define get_element_count(array, count_p) \ - (api->get_element_count(ext_id, array, count_p)) + (api->api_get_element_count(ext_id, array, count_p)) -#define create_array() (api->create_array(ext_id)) +#define create_array() (api->api_create_array(ext_id)) -#define clear_array(array) (api->clear_array(ext_id, array)) +#define clear_array(array) (api->api_clear_array(ext_id, array)) #define flatten_array(array, data) \ - (api->flatten_array(ext_id, array, data)) + (api->api_flatten_array(ext_id, array, data)) #define release_flattened_array(array, data) \ - (api->release_flattened_array(ext_id, array, data)) + (api->api_release_flattened_array(ext_id, array, data)) #define emalloc(pointer, type, size, message) \ do { \ @@ -420,6 +464,12 @@ typedef struct gawk_api { fatal(ext_id, "malloc of %d bytes failed\n", size); \ } while(0) +#define erealloc(pointer, type, size, message) \ + do { \ + if ((pointer = (type) realloc(pointer, size)) == 0) \ + fatal(ext_id, "realloc of %d bytes failed\n", size); \ + } while(0) + /* Constructor functions */ /* r_make_string --- make a string value in result from the passed-in string */ @@ -440,7 +490,7 @@ r_make_string(const gawk_api_t *api, /* needed for emalloc */ result->str_value.len = length; if (duplicate) { - emalloc(cp, char *, length + 2, "make_string"); + emalloc(cp, char *, length + 2, "r_make_string"); memcpy(cp, string, length); cp[length] = '\0'; result->str_value.str = cp; @@ -451,8 +501,19 @@ r_make_string(const gawk_api_t *api, /* needed for emalloc */ return result; } -#define make_string(str, len, result) r_make_string(api, ext_id, str, len, 0, result) -#define dup_string(str, len, result) r_make_string(api, ext_id, str, len, 1, result) +#define make_const_string(str, len, result) r_make_string(api, ext_id, str, len, 1, result) +#define make_malloced_string(str, len, result) r_make_string(api, ext_id, str, len, 0, result) + +/* make_null_string --- make a null string value */ + +static inline awk_value_t * +make_null_string(awk_value_t *result) +{ + memset(result, 0, sizeof(*result)); + result->val_type = AWK_UNDEFINED; + + return result; +} /* make_number --- make a number value in result */ -- cgit v1.2.3 From 73533707616e119778993fe18540098239ecbb2e Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 11 Jul 2012 21:41:54 +0300 Subject: Add ability to call an initialization routine. --- gawkapi.h | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 2bef258e..9f541cfc 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -533,9 +533,13 @@ make_number(double num, awk_value_t *result) * * int dl_load(gawk_api_t *api_p, awk_ext_id_t id) * + * The return value should be zero on failure and non-zero on success. + * * For the macros to work, the function should save api_p in a global * variable named 'api' and save id in a global variable named 'ext_id'. - * The return value should be zero on failure and non-zero on success. + * In addition, a global function pointer named 'init_func' should be + * defined and set to either NULL or an initialization function that + * returns non-zero on success and zero upon failure. */ extern int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id); @@ -549,6 +553,19 @@ static awk_ext_func_t func_table[] = { /* ... */ }; +/* EITHER: */ + +static awk_bool_t (*init_func)(void) = NULL; + +/* OR: */ + +static awk_bool_t init_my_module(void) +{ + ... +} + +static awk_bool_t (*init_func)(void) = init_my_module; + dl_load_func(func_table, some_name, "name_space_in_quotes") #endif @@ -578,6 +595,13 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ errors++; \ } \ } \ +\ + if (init_func != NULL) { \ + if (! init_func()) { \ + warning(ext_id, #module ": initialization function failed\n"); \ + errors++; \ + } \ + } \ \ return (errors == 0); \ } -- cgit v1.2.3 From dda2495337929a86cc40017d8f1cd72a46876618 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 12 Jul 2012 09:24:55 -0400 Subject: Add sym_lookup_scalar to API for fast scalar_cookie value retrieval. --- gawkapi.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 9f541cfc..50ca327a 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -34,7 +34,7 @@ /* * General introduction: * - * This API purposely restricts itself to C90 features. In paticular, no + * This API purposely restricts itself to C90 features. In particular, no * bool, no // comments, no use of the restrict keyword, or anything else, * in order to provide maximal portability. * @@ -122,7 +122,7 @@ typedef struct { awk_string_t s; double d; awk_array_t a; - awk_array_t scl; + awk_scalar_t scl; } u; #define str_value u.s #define num_value u.d @@ -316,6 +316,18 @@ typedef struct gawk_api { awk_valtype_t wanted, awk_value_t *result); + /* + * Retrieve 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. + */ + 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 a value. Adds it to the symbol table if not there. * Changing types (scalar <--> array) is not allowed. @@ -427,7 +439,10 @@ typedef struct gawk_api { #define add_ext_func(func, ns) (api->api_add_ext_func(ext_id, func, ns)) #define awk_atexit(funcp, arg0) (api->api_awk_atexit(ext_id, funcp, arg0)) -#define sym_lookup(name, wanted, result) (api->api_sym_lookup(ext_id, name, wanted, result)) +#define sym_lookup(name, wanted, result) \ + (api->api_sym_lookup(ext_id, name, wanted, result)) +#define sym_lookup_scalar(scalar_cookie, wanted, result) \ + (api->api_sym_lookup_scalar(ext_id, scalar_cookie, wanted, result)) #define sym_update(name, value) \ (api->api_sym_update(ext_id, name, value)) #define sym_update_scalar(scalar_cookie, value) \ -- cgit v1.2.3 From 28daef44c3c08f16002c678319a30b816f6972fd Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 12 Jul 2012 22:45:25 +0300 Subject: Allow creation of constants from extensions. --- gawkapi.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 50ca327a..a84fbf52 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -334,7 +334,15 @@ typedef struct gawk_api { * In fact, using this to update an array is not allowed, either. * Such an attempt returns false. */ - awk_bool_t (*api_sym_update)(awk_ext_id_t id, const char *name, awk_value_t *value); + awk_bool_t (*api_sym_update)(awk_ext_id_t id, + const char *name, + awk_value_t *value); + /* + * Install a constant value. + */ + awk_bool_t (*api_sym_constant)(awk_ext_id_t id, + const char *name, + awk_value_t *value); /* * Work with a scalar cookie. @@ -445,6 +453,8 @@ typedef struct gawk_api { (api->api_sym_lookup_scalar(ext_id, scalar_cookie, wanted, result)) #define sym_update(name, value) \ (api->api_sym_update(ext_id, name, value)) +#define sym_constant(name, value) \ + (api->api_sym_constant(ext_id, name, value)) #define sym_update_scalar(scalar_cookie, value) \ (api->api_sym_update_scalar)(ext_id, scalar_cookie, value) -- cgit v1.2.3 From 0907dd281b71fb440c83fc53e6b4c7312f1c1f47 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 17 Jul 2012 23:13:14 +0300 Subject: Add AWK_VALUE_COOKIE. And performance speedup. --- gawkapi.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index a84fbf52..29631cdd 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -95,6 +95,7 @@ typedef enum { AWK_STRING, AWK_ARRAY, AWK_SCALAR, /* opaque access to a variable */ + AWK_VALUE_COOKIE, /* for updating to a previously created value */ } awk_valtype_t; /* @@ -112,6 +113,9 @@ typedef void *awk_array_t; /* Scalars can be represented as an opaque type. */ typedef void *awk_scalar_t; +/* Any value can be stored as a cookie. */ +typedef void *awk_value_cookie_t; + /* * An awk value. The val_type tag indicates what * is in the union. @@ -123,11 +127,13 @@ typedef struct { double d; awk_array_t a; awk_scalar_t scl; + awk_value_cookie_t vc; } u; #define str_value u.s #define num_value u.d #define array_cookie u.a #define scalar_cookie u.scl +#define value_cookie u.vc } awk_value_t; /* @@ -414,6 +420,11 @@ typedef struct gawk_api { awk_bool_t (*api_release_flattened_array)(awk_ext_id_t id, awk_array_t a_cookie, awk_flat_array_t *data); + + awk_bool_t (*api_create_value)(awk_ext_id_t id, awk_value_t *value, + awk_value_cookie_t *result); + + awk_bool_t (*api_release_value)(awk_ext_id_t id, awk_value_cookie_t vc); } gawk_api_t; #ifndef GAWK /* these are not for the gawk code itself! */ @@ -483,6 +494,12 @@ typedef struct gawk_api { #define release_flattened_array(array, data) \ (api->api_release_flattened_array(ext_id, array, data)) +#define create_value(value, result) \ + (api->api_create_value(ext_id, value,result)) + +#define release_value(value) \ + (api->api_release_value(ext_id, value)) + #define emalloc(pointer, type, size, message) \ do { \ if ((pointer = (type) malloc(size)) == 0) \ -- cgit v1.2.3 From ffbf8454171c0ef037db425f436c735da3691d9f Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 17 Jul 2012 17:23:42 -0400 Subject: Clean up support for AWK_SCALAR and AWK_VALUE_COOKIE. --- gawkapi.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 29631cdd..5d9936fb 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -421,9 +421,20 @@ typedef struct gawk_api { awk_array_t a_cookie, awk_flat_array_t *data); + /* + * Cache a 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); } gawk_api_t; -- cgit v1.2.3 From 50831fa7f402480d83d5e3647d09acdad7cd0eeb Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 20 Jul 2012 12:00:31 +0300 Subject: Update doc in header. Redo update_scalar. --- gawkapi.h | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 29631cdd..5cc8fc10 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -232,23 +232,28 @@ typedef struct gawk_api { Table entry is type returned: - +---------------------------------------------------+ - | Type Requested: | - +----------+----------+-------+---------+-----------+ - | String | Number | Array | Scalar | Undefined | - +---------+-----------+----------+----------+-------+---------+-----------+ - | Type | String | String | Number if| false | Scalar | String | - | | | | it can be| | | | - | | | |converted,| | | | - | | | | else | | | | - | | | | false | | | | - | of +-----------+----------+----------+-------+---------+-----------+ - | Actual | Number | String | Number | false | Scalar | Number | - | Value: +-----------+----------+----------+-------+---------+-----------+ - | | Array | false | false | Array | false | Array | - | +-----------+----------+----------+-------+---------+-----------+ - | | Undefined | false | false | false | false | Undefined | - +---------+-----------+----------+----------+-------+---------+-----------+ + + +-------------------------------------------------+ + | Type of Actual Value: | + +------------+------------+-----------+-----------+ + | String | Number | Array | Undefined | + +-----------+-----------+------------+------------+-----------+-----------+ + | | String | String | String | false | false | + | |-----------+------------+------------+-----------+-----------+ + | | Number | Number if | Number | false | false | + | | | can be | | | | + | | | converted, | | | | + | | | else false | | | | + | |-----------+------------+------------+-----------+-----------+ + | Type | Array | false | false | Array | false | + | Requested |-----------+------------+------------+-----------+-----------+ + | | Scalar | Scalar | Scalar | false | false | + | |-----------+------------+------------+-----------+-----------+ + | | Undefined | String | Number | Array | Undefined | + | |-----------+------------+------------+-----------+-----------+ + | | Value | false | false | false | false | + | | Cookie | | | | | + +-----------+-----------+------------+------------+-----------+-----------+ */ /* -- cgit v1.2.3 From 3d2d6b46bf3325c0273b35a202184ab09d38e0cd Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 25 Jul 2012 22:34:19 +0300 Subject: Start refactoring iop handling. Add readdir extension. --- gawkapi.h | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 90df6293..58162002 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -69,6 +69,13 @@ extern "C" { #endif +/* This is used to keep the extension from modifying certain fields in some structs. */ +#ifdef GAWK +#define awk_const +#else +#define awk_const const +#endif + /* portions of IOBUF that should be accessible to extension functions: */ typedef struct iobuf_public { const char *name; /* filename */ @@ -78,6 +85,14 @@ typedef struct iobuf_public { void (*close_func)(struct iobuf_public *); } IOBUF_PUBLIC; +typedef struct input_parser { + const char *name; /* name of parser */ + int (*can_take_file)(IOBUF_PUBLIC *iobuf); + int (*take_control_of)(IOBUF_PUBLIC *iobuf); + struct input_parser *awk_const next; /* for use by gawk */ +} awk_input_parser_t; + + #define GAWK_API_MAJOR_VERSION 0 #define GAWK_API_MINOR_VERSION 0 @@ -156,13 +171,6 @@ typedef struct awk_element { awk_value_t value; } awk_element_t; -/* This is used to keep the extension from modifying certain fields. */ -#ifdef GAWK -#define awk_const -#else -#define awk_const const -#endif - /* * A "flattened" array. See the description above for how * to use the elements contained herein. @@ -281,8 +289,8 @@ typedef struct gawk_api { void (*api_warning)(awk_ext_id_t id, const char *format, ...); void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...); - /* Register an open hook; for opening files read-only */ - void (*api_register_open_hook)(awk_ext_id_t id, void* (*open_func)(IOBUF_PUBLIC *)); + /* Register an input parser; for opening files read-only */ + void (*api_register_input_parser)(awk_ext_id_t id, awk_input_parser_t *input_parser); /* Functions to update ERRNO */ void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val); @@ -464,7 +472,7 @@ typedef struct gawk_api { #define warning api->api_warning #define lintwarn api->api_lintwarn -#define register_open_hook(func) (api->api_register_open_hook(ext_id, func)) +#define register_input_parser(parser) (api->api_register_input_parser(ext_id, parser)) #define update_ERRNO_int(e) (api->api_update_ERRNO_int(ext_id, e)) #define update_ERRNO_string(str, translate) \ -- cgit v1.2.3 From 40eefdd931066129d0bb2f6144a0ec7741c6cc2b Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 25 Jul 2012 22:56:37 +0300 Subject: Remove translation of errno strings from API. --- gawkapi.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 58162002..b8422db5 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -294,8 +294,7 @@ typedef struct gawk_api { /* Functions to update ERRNO */ void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val); - void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string, - awk_bool_t translate); + void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string); void (*api_unset_ERRNO)(awk_ext_id_t id); /* Add a function to the interpreter, returns true upon success */ @@ -475,8 +474,8 @@ typedef struct gawk_api { #define register_input_parser(parser) (api->api_register_input_parser(ext_id, parser)) #define update_ERRNO_int(e) (api->api_update_ERRNO_int(ext_id, e)) -#define update_ERRNO_string(str, translate) \ - (api->api_update_ERRNO_string(ext_id, str, translate)) +#define update_ERRNO_string(str) \ + (api->api_update_ERRNO_string(ext_id, str)) #define unset_ERRNO() (api->api_unset_ERRNO(ext_id)) #define add_ext_func(func, ns) (api->api_add_ext_func(ext_id, func, ns)) -- cgit v1.2.3 From ca83de0ec92b56c712f7a7376b21a1a1337b3107 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 26 Jul 2012 11:56:00 -0400 Subject: Document the parser interface and remove some excessive readdir paranoia. --- gawkapi.h | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index b8422db5..bc7001c7 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -81,13 +81,45 @@ typedef struct iobuf_public { const char *name; /* filename */ int fd; /* file descriptor */ void *opaque; /* private data for open hooks */ + /* + * The get_record function is called to read the next record of data. + * It should return the length of the input record (or EOF), and + * it should set *out to point to the contents of $0. Note that + * gawk will make a copy of the record in *out, so the parser is + * responsible for managing its own memory buffer. If an error + * occurs, the function should return EOF and set *errcode + * to a non-zero value. In that case, if *errcode does not equal + * -1, gawk will automatically update the ERRNO variable based on + * the value of *errcode (e.g. setting *errcode = errno should do + * the right thing). It is guaranteed that errcode is a valid + * pointer, so there is no need to test for a NULL value. The + * caller sets *errcode to 0, so there is no need to set it unless + * an error occurs. + */ int (*get_record)(char **out, struct iobuf_public *, int *errcode); + /* + * The close_func is called to allow the parser to free private data. + * Gawk itself will close the fd unless close_func sets it to -1. + */ void (*close_func)(struct iobuf_public *); + } IOBUF_PUBLIC; typedef struct input_parser { const char *name; /* name of parser */ - int (*can_take_file)(IOBUF_PUBLIC *iobuf); + /* + * The can_take_file function should return non-zero if the parser + * would like to parse this file. It should not change any gawk + * state! + */ + int (*can_take_file)(const IOBUF_PUBLIC *iobuf); + /* + * If this parser is selected, then take_control_of will be called. + * It can assume that a previous call to can_take_file was successful, + * and no gawk state has changed since that call. It should populate + * the IOBUF_PUBLIC get_record, close_func, and opaque values as needed. + * It should return non-zero if successful. + */ int (*take_control_of)(IOBUF_PUBLIC *iobuf); struct input_parser *awk_const next; /* for use by gawk */ } awk_input_parser_t; -- cgit v1.2.3 From 652a11e5fbe9862a2b8e961b32b9748b3c2c418b Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 26 Jul 2012 22:27:54 +0300 Subject: Add set_RT to API and to readdir extension. --- gawkapi.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index bc7001c7..db650fb2 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -324,6 +324,9 @@ typedef struct gawk_api { /* Register an input parser; for opening files read-only */ void (*api_register_input_parser)(awk_ext_id_t id, awk_input_parser_t *input_parser); + /* Set RT - pass AWK_UNDEFINED to set to null string */ + void (*api_set_RT)(awk_ext_id_t id, awk_value_t *value); + /* Functions to update ERRNO */ void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val); void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string); @@ -504,6 +507,7 @@ typedef struct gawk_api { #define lintwarn api->api_lintwarn #define register_input_parser(parser) (api->api_register_input_parser(ext_id, parser)) +#define set_RT(value) (api->api_set_RT(ext_id, value)) #define update_ERRNO_int(e) (api->api_update_ERRNO_int(ext_id, e)) #define update_ERRNO_string(str) \ -- cgit v1.2.3 From 207fc1458c7f168822e454a89f23428c64163427 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 27 Jul 2012 15:25:05 +0300 Subject: Fix bug in API set_RT, bug in readdir.c. --- gawkapi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index db650fb2..0204053a 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -80,7 +80,7 @@ extern "C" { typedef struct iobuf_public { const char *name; /* filename */ int fd; /* file descriptor */ - void *opaque; /* private data for open hooks */ + void *opaque; /* private data for input parsers */ /* * The get_record function is called to read the next record of data. * It should return the length of the input record (or EOF), and -- cgit v1.2.3 From 0eaab9127d090da073a53695583837fcbd2be9d3 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 29 Jul 2012 17:13:13 +0300 Subject: Update input_parser interface for RT. --- gawkapi.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 0204053a..7e20d3d1 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -94,9 +94,14 @@ typedef struct iobuf_public { * the right thing). It is guaranteed that errcode is a valid * pointer, so there is no need to test for a NULL value. The * caller sets *errcode to 0, so there is no need to set it unless - * an error occurs. + * an error occurs. The rt_start and rt_len arguments should be + * used to return RT to gawk. Gawk will make its own copy of RT, + * so the parser is responsible for managing this memory. If EOF is + * not returned, the parser must set *rt_len (and *rt_start if *rt_len + * is non-zero). */ - int (*get_record)(char **out, struct iobuf_public *, int *errcode); + int (*get_record)(char **out, struct iobuf_public *, int *errcode, + char **rt_start, size_t *rt_len); /* * The close_func is called to allow the parser to free private data. * Gawk itself will close the fd unless close_func sets it to -1. @@ -324,9 +329,6 @@ typedef struct gawk_api { /* Register an input parser; for opening files read-only */ void (*api_register_input_parser)(awk_ext_id_t id, awk_input_parser_t *input_parser); - /* Set RT - pass AWK_UNDEFINED to set to null string */ - void (*api_set_RT)(awk_ext_id_t id, awk_value_t *value); - /* Functions to update ERRNO */ void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val); void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string); @@ -507,7 +509,6 @@ typedef struct gawk_api { #define lintwarn api->api_lintwarn #define register_input_parser(parser) (api->api_register_input_parser(ext_id, parser)) -#define set_RT(value) (api->api_set_RT(ext_id, value)) #define update_ERRNO_int(e) (api->api_update_ERRNO_int(ext_id, e)) #define update_ERRNO_string(str) \ -- cgit v1.2.3 From 88e81c931345aa485e55c6d6c7f3ad61dc200fed Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 8 Aug 2012 22:37:55 +0300 Subject: Add fts() extension, support, doc, and test. --- gawkapi.h | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 7e20d3d1..f345d07a 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -51,17 +51,37 @@ * and reuse it directly, even for something that is conceptually pass * by value. * - * 2. The correct way to create new arrays is to work "bottom up". + * 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: * * new_array = create_array(); - * // fill in new array with lots of subscripts and values * val.val_type = AWK_ARRAY; * val.array_cookie = new_array; - * sym_update("array", &val); // install array in the symbol table + * sym_update("array", & val); // install array in the symbol table + * + * new_array = val.array_cookie; // MUST DO THIS + * + * // fill in new array with lots of subscripts and values + * + * Similarly, if installing a new array as a subarray of an existing + * array, you must add the new array to its parent before adding any + * elements to it. + * + * You must also retrieve the value of the array_cookie after the call + * to set_element(). + * + * Thus, the correct way to build an array is to work "top down". + * Create the array, and immediately install it in gawk's symbol table + * using sym_update(), or install it as an element in a previously + * existing array using set_element(). * - * After doing so, do NOT make further use of the new_array variable; - * instead use sym_lookup to get the array_cookie if you need to do further - * manipulation of the array. + * The new array must ultimately be rooted in a global symbol. This is + * necessary before installing any subarrays in it, due to gawk's + * internal implementation. Strictly speaking, this is required only + * for arrays that will have subarrays as elements; however it is + * a good idea to always do this. This restriction may be relaxed + * in a subsequent revision of the API. */ /* Allow use in C++ code. */ @@ -249,15 +269,15 @@ typedef void *awk_ext_id_t; /* opaque type for extension id */ * logically organized. */ typedef struct gawk_api { - int major_version; - int minor_version; + awk_const int major_version; + awk_const int minor_version; /* * These can change on the fly as things happen within gawk. * Currently only do_lint is prone to change, but we reserve * the right to allow the others also. */ - int do_flags[DO_FLAGS_SIZE]; + awk_const int do_flags[DO_FLAGS_SIZE]; /* Use these as indices into do_flags[] array to check the values */ #define gawk_do_lint 0 #define gawk_do_traditional 1 -- cgit v1.2.3 From 49658bfd0ef5d4efccd210c48560c43bf455ee16 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 8 Aug 2012 22:51:53 +0300 Subject: Move struct stat into IOBUF_PUBLIC. --- gawkapi.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index f345d07a..b516787a 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -100,6 +100,7 @@ extern "C" { typedef struct iobuf_public { const char *name; /* filename */ int fd; /* file descriptor */ +#define INVALID_HANDLE (-1) void *opaque; /* private data for input parsers */ /* * The get_record function is called to read the next record of data. @@ -127,6 +128,9 @@ typedef struct iobuf_public { * Gawk itself will close the fd unless close_func sets it to -1. */ void (*close_func)(struct iobuf_public *); + + /* put last, for alignment. bleah */ + struct stat sbuf; /* stat buf */ } IOBUF_PUBLIC; -- cgit v1.2.3 From 88f8278587c7f254d4c5bb2e8f996f3947da32e9 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 12 Aug 2012 11:00:42 +0300 Subject: Make api versions into enum, not defines. --- gawkapi.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index b516787a..9b89e425 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -121,7 +121,7 @@ typedef struct iobuf_public { * not returned, the parser must set *rt_len (and *rt_start if *rt_len * is non-zero). */ - int (*get_record)(char **out, struct iobuf_public *, int *errcode, + int (*get_record)(char **out, struct iobuf_public *iobuf, int *errcode, char **rt_start, size_t *rt_len); /* * The close_func is called to allow the parser to free private data. @@ -154,8 +154,10 @@ typedef struct input_parser { } awk_input_parser_t; -#define GAWK_API_MAJOR_VERSION 0 -#define GAWK_API_MINOR_VERSION 0 +enum { + GAWK_API_MAJOR_VERSION = 0, + GAWK_API_MINOR_VERSION = 0 +}; #define DO_FLAGS_SIZE 6 -- cgit v1.2.3 From 8970970f3f3bc3d757fe491e90e608366fb7e604 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 24 Aug 2012 13:25:52 +0300 Subject: Add output and two-way processors to API. Update Mac config stuff. --- gawkapi.h | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 9b89e425..3c369a8f 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -150,9 +150,68 @@ typedef struct input_parser { * It should return non-zero if successful. */ int (*take_control_of)(IOBUF_PUBLIC *iobuf); - struct input_parser *awk_const next; /* for use by gawk */ + awk_const struct input_parser *awk_const next; /* for use by gawk */ } awk_input_parser_t; +/* + * Similar for output wrapper. + */ + +typedef struct { + const char *name; + const char *mode; /* mode argument to fopen */ + FILE *fp; + int redirected; /* true if a wrapper is active */ + void *opaque; /* for use by output wrapper */ + + /* + * Replacement functions for I/O. Just like the regular + * versions but also take the opaque pointer argument. + */ + size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count, FILE *fp, void *opaque); + int (*gawk_fflush)(FILE *fp, void *opaque); + int (*gawk_ferror)(FILE *fp, void *opaque); + int (*gawk_fclose)(FILE *fp, void *opaque); +} awk_output_buf_t; + +typedef struct output_wrapper { + const char *name; + /* + * The can_take_file function should return non-zero if the wrapper + * would like to process this file. It should not change any gawk + * state! + */ + int (*can_take_file)(const awk_output_buf_t *outbuf); + /* + * If this wrapper is selected, then take_control_of will be called. + * It can assume that a previous call to can_take_file was successful, + * and no gawk state has changed since that call. It should populate + * the awk_output_buf_t function pointers and opaque pointer as needed. + * It should return non-zero if successful. + */ + int (*take_control_of)(awk_output_buf_t *outbuf); + awk_const struct output_wrapper *awk_const next; /* for use by gawk */ +} awk_output_wrapper_t; + +typedef struct two_way_processor { + const char *name; + /* + * The can_take_file function should return non-zero if the two-way processor + * would like to parse this file. It should not change any gawk + * state! + */ + int (*can_take_two_way)(const char *name); + /* + * If this processor is selected, then take_control_of will be called. + * It can assume that a previous call to can_take_file was successful, + * and no gawk state has changed since that call. It should populate + * the IOBUF_PUBLIC and awk_otuput_buf_t structures as needed. + * It should return non-zero if successful. + */ + int (*take_control_of)(const char *name, IOBUF_PUBLIC *inbuf, awk_output_buf_t *outbuf); + awk_const struct two_way_processor *awk_const next; /* for use by gawk */ +} awk_two_way_processor_t; + enum { GAWK_API_MAJOR_VERSION = 0, @@ -355,6 +414,12 @@ typedef struct gawk_api { /* Register an input parser; for opening files read-only */ void (*api_register_input_parser)(awk_ext_id_t id, awk_input_parser_t *input_parser); + /* Register an output wrapper, for writing files / two-way pipes */ + void (*api_register_output_wrapper)(awk_ext_id_t id, awk_output_wrapper_t *output_wrapper); + + /* Register a processor for two way I/O */ + void (*api_register_two_way_processor)(awk_ext_id_t id, awk_two_way_processor_t *two_way_processor); + /* Functions to update ERRNO */ void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val); void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string); @@ -535,6 +600,9 @@ typedef struct gawk_api { #define lintwarn api->api_lintwarn #define register_input_parser(parser) (api->api_register_input_parser(ext_id, parser)) +#define register_output_wrapper(wrapper) (api->api_register_output_wrapper(ext_id, wrapper)) +#define register_two_way_processor(processor) \ + (api->api_register_two_way_processor(ext_id, processor)) #define update_ERRNO_int(e) (api->api_update_ERRNO_int(ext_id, e)) #define update_ERRNO_string(str) \ @@ -717,6 +785,8 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ \ /* load functions */ \ for (i = 0, j = sizeof(func_table) / sizeof(func_table[0]); i < j; i++) { \ + if (func_table[i].name == NULL) \ + break; \ if (! add_ext_func(& func_table[i], name_space)) { \ warning(ext_id, #module ": could not add %s\n", \ func_table[i].name); \ -- cgit v1.2.3 From 759f2234c9bfa689151277fd2215bc0927cfc9c3 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 24 Aug 2012 13:40:22 +0300 Subject: Add facility to get vesion info from extensions. --- gawkapi.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 3c369a8f..95effd9a 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -576,6 +576,11 @@ typedef struct gawk_api { * 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); + + /* + * Register a version string for this extension with gawk. + */ + void (*api_register_ext_version)(awk_ext_id_t id, const char *version); } gawk_api_t; #ifndef GAWK /* these are not for the gawk code itself! */ @@ -654,6 +659,9 @@ typedef struct gawk_api { #define release_value(value) \ (api->api_release_value(ext_id, value)) +#define register_ext_version(version) \ + (api->api_register_ext_version(ext_id, version)) + #define emalloc(pointer, type, size, message) \ do { \ if ((pointer = (type) malloc(size)) == 0) \ @@ -748,6 +756,7 @@ static awk_ext_func_t func_table[] = { { "name", do_name, 1 }, /* ... */ }; +static const char *ext_version = NULL; /* or ... = "some string" */ /* EITHER: */ @@ -800,6 +809,9 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ errors++; \ } \ } \ +\ + if (ext_version != NULL) \ + register_ext_version(ext_version); \ \ return (errors == 0); \ } -- cgit v1.2.3 From fc9109734ddcf57c5f1faaedfadc432ec6841aa8 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 14 Sep 2012 00:16:48 +0300 Subject: Allow extensions read-only access to built-in vars. --- gawkapi.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 95effd9a..e8b7ebff 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -447,8 +447,8 @@ typedef struct gawk_api { * or if the wrong type was requested. * In the latter case, fills in vaule->val_type with the real type, * as described above. - * Built-in variables (except PROCINFO) may not be accessed by an - * extension. + * Built-in variables may be accessed by an extension, but, with + * the exception of PROCINFO, they may not be modified. * * awk_value_t val; * if (! api->sym_lookup(id, name, wanted, & val)) @@ -495,13 +495,15 @@ typedef struct gawk_api { * Flow is * sym_lookup with wanted == AWK_SCALAR * if returns false - * sym_update with real initial value + * 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); @@ -522,6 +524,8 @@ typedef struct gawk_api { /* * 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, -- cgit v1.2.3 From 8eb78103a37e75819388c2a175caf40bf0f7b4c9 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 10 Oct 2012 14:46:22 +0200 Subject: Cleanups in gawkapi.h and adjustments for them. --- gawkapi.h | 363 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 209 insertions(+), 154 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index e8b7ebff..0f6cfec3 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -26,6 +26,8 @@ /* * N.B. You must include and * before including this file! + * You should also include if you intend to use + * the dl_load_func convenience macro. */ #ifndef _GAWK_API_H @@ -34,7 +36,7 @@ /* * General introduction: * - * This API purposely restricts itself to C90 features. In particular, no + * This API purposely restricts itself to ISO C 90 features. In particular, no * bool, no // comments, no use of the restrict keyword, or anything else, * in order to provide maximal portability. * @@ -76,7 +78,7 @@ * using sym_update(), or install it as an element in a previously * existing array using set_element(). * - * The new array must ultimately be rooted in a global symbol. This is + * Thus the new array must ultimately be rooted in a global symbol. This is * necessary before installing any subarrays in it, due to gawk's * internal implementation. Strictly speaking, this is required only * for arrays that will have subarrays as elements; however it is @@ -89,14 +91,16 @@ extern "C" { #endif -/* This is used to keep the extension from modifying certain fields in some structs. */ +/* This is used to keep extensions from modifying certain fields in some structs. */ #ifdef GAWK #define awk_const #else #define awk_const const #endif -/* portions of IOBUF that should be accessible to extension functions: */ +typedef int awk_bool_t; /* we don't use on purpose */ + +/* Portions of IOBUF that should be accessible to extension functions: */ typedef struct iobuf_public { const char *name; /* filename */ int fd; /* file descriptor */ @@ -104,28 +108,35 @@ typedef struct iobuf_public { void *opaque; /* private data for input parsers */ /* * The get_record function is called to read the next record of data. - * It should return the length of the input record (or EOF), and - * it should set *out to point to the contents of $0. Note that - * gawk will make a copy of the record in *out, so the parser is - * responsible for managing its own memory buffer. If an error - * occurs, the function should return EOF and set *errcode - * to a non-zero value. In that case, if *errcode does not equal - * -1, gawk will automatically update the ERRNO variable based on - * the value of *errcode (e.g. setting *errcode = errno should do - * the right thing). It is guaranteed that errcode is a valid - * pointer, so there is no need to test for a NULL value. The - * caller sets *errcode to 0, so there is no need to set it unless - * an error occurs. The rt_start and rt_len arguments should be - * used to return RT to gawk. Gawk will make its own copy of RT, - * so the parser is responsible for managing this memory. If EOF is - * not returned, the parser must set *rt_len (and *rt_start if *rt_len - * is non-zero). + * + * It should return the length of the input record or EOF, and it + * should set *out to point to the contents of $0. The rt_start + * and rt_len arguments should be used to return RT to gawk. + * If EOF is not returned, the parser must set *rt_len (and + * *rt_start if *rt_len is non-zero). + * + * Note that gawk will make a copy of the record in *out, so the + * parser is responsible for managing its own memory buffer. + * Similarly, gawk will make its own copy of RT, so the parser + * is also responsible for managing this memory. + * + * It is guaranteed that errcode is a valid pointer, so there is + * no need to test for a NULL value. The caller sets *errcode to 0, + * so there is no need to set it unless an error occurs. + * + * If an error does occur, the function should return EOF and set + * *errcode to a non-zero value. In that case, if *errcode does not + * equal -1, gawk will automatically update the ERRNO variable based + * on the value of *errcode (e.g., setting *errcode = errno should do + * the right thing). */ int (*get_record)(char **out, struct iobuf_public *iobuf, int *errcode, char **rt_start, size_t *rt_len); + /* * The close_func is called to allow the parser to free private data. - * Gawk itself will close the fd unless close_func sets it to -1. + * Gawk itself will close the fd unless close_func first sets it to + * INVALID_HANDLE. */ void (*close_func)(struct iobuf_public *); @@ -136,12 +147,14 @@ typedef struct iobuf_public { typedef struct input_parser { const char *name; /* name of parser */ + /* * The can_take_file function should return non-zero if the parser * would like to parse this file. It should not change any gawk * state! */ - int (*can_take_file)(const IOBUF_PUBLIC *iobuf); + awk_bool_t (*can_take_file)(const IOBUF_PUBLIC *iobuf); + /* * If this parser is selected, then take_control_of will be called. * It can assume that a previous call to can_take_file was successful, @@ -149,7 +162,8 @@ typedef struct input_parser { * the IOBUF_PUBLIC get_record, close_func, and opaque values as needed. * It should return non-zero if successful. */ - int (*take_control_of)(IOBUF_PUBLIC *iobuf); + awk_bool_t (*take_control_of)(IOBUF_PUBLIC *iobuf); + awk_const struct input_parser *awk_const next; /* for use by gawk */ } awk_input_parser_t; @@ -157,31 +171,36 @@ typedef struct input_parser { * Similar for output wrapper. */ +/* First the data structure */ typedef struct { - const char *name; + const char *name; /* name of output file */ const char *mode; /* mode argument to fopen */ - FILE *fp; - int redirected; /* true if a wrapper is active */ + FILE *fp; /* stdio file pointer */ + awk_bool_t redirected; /* true if a wrapper is active */ void *opaque; /* for use by output wrapper */ /* * Replacement functions for I/O. Just like the regular * versions but also take the opaque pointer argument. */ - size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count, FILE *fp, void *opaque); + size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count, + FILE *fp, void *opaque); int (*gawk_fflush)(FILE *fp, void *opaque); int (*gawk_ferror)(FILE *fp, void *opaque); int (*gawk_fclose)(FILE *fp, void *opaque); } awk_output_buf_t; +/* Next the output wrapper registered with gawk */ typedef struct output_wrapper { - const char *name; + const char *name; /* name of the wrapper */ + /* * The can_take_file function should return non-zero if the wrapper * would like to process this file. It should not change any gawk * state! */ - int (*can_take_file)(const awk_output_buf_t *outbuf); + awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf); + /* * If this wrapper is selected, then take_control_of will be called. * It can assume that a previous call to can_take_file was successful, @@ -189,18 +208,22 @@ typedef struct output_wrapper { * the awk_output_buf_t function pointers and opaque pointer as needed. * It should return non-zero if successful. */ - int (*take_control_of)(awk_output_buf_t *outbuf); + awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf); + awk_const struct output_wrapper *awk_const next; /* for use by gawk */ } awk_output_wrapper_t; +/* A two-way processor combines an input parser and an output wrapper. */ typedef struct two_way_processor { - const char *name; + const char *name; /* name of the two-way processor */ + /* - * The can_take_file function should return non-zero if the two-way processor - * would like to parse this file. It should not change any gawk - * state! + * The can_take_file function should return non-zero if the two-way + * processor would like to parse this file. It should not change + * any gawk state! */ - int (*can_take_two_way)(const char *name); + awk_bool_t (*can_take_two_way)(const char *name); + /* * If this processor is selected, then take_control_of will be called. * It can assume that a previous call to can_take_file was successful, @@ -208,40 +231,30 @@ typedef struct two_way_processor { * the IOBUF_PUBLIC and awk_otuput_buf_t structures as needed. * It should return non-zero if successful. */ - int (*take_control_of)(const char *name, IOBUF_PUBLIC *inbuf, awk_output_buf_t *outbuf); + awk_bool_t (*take_control_of)(const char *name, IOBUF_PUBLIC *inbuf, awk_output_buf_t *outbuf); + awk_const struct two_way_processor *awk_const next; /* for use by gawk */ } awk_two_way_processor_t; - +/* Current version of the API. */ enum { GAWK_API_MAJOR_VERSION = 0, GAWK_API_MINOR_VERSION = 0 }; -#define DO_FLAGS_SIZE 6 - -/* - * This tag defines the type of a value. - * Values are associated with regular variables and with array elements. - * Since arrays can be multidimensional (as can regular variables) - * it's valid to have a "value" that is actually an array. - */ -typedef enum { - AWK_UNDEFINED, - AWK_NUMBER, - AWK_STRING, - AWK_ARRAY, - AWK_SCALAR, /* opaque access to a variable */ - AWK_VALUE_COOKIE, /* for updating to a previously created value */ -} awk_valtype_t; +/* A number of typedefs related to different types of values. */ /* * A mutable string. Gawk owns the memory pointed to if it supplied * the value. Otherwise, it takes ownership of the memory pointed to. + * + * The API deals exclusively with regular chars; these strings may + * be multibyte encoded in the current locale's encoding and character + * set. Gawk will convert internally to wide characters if necessary. */ typedef struct { - char *str; - size_t len; + char *str; /* data */ + size_t len; /* length thereof, in chars */ } awk_string_t; /* Arrays are represented as an opaque type. */ @@ -253,6 +266,22 @@ typedef void *awk_scalar_t; /* Any value can be stored as a cookie. */ typedef void *awk_value_cookie_t; +/* + * This tag defines the type of a value. + * + * Values are associated with regular variables and with array elements. + * Since arrays can be multidimensional (as can regular variables) + * it's valid to have a "value" that is actually an array. + */ +typedef enum { + AWK_UNDEFINED, + AWK_NUMBER, + AWK_STRING, + AWK_ARRAY, + AWK_SCALAR, /* opaque access to a variable */ + AWK_VALUE_COOKIE, /* for updating a previously created value */ +} awk_valtype_t; + /* * An awk value. The val_type tag indicates what * is in the union. @@ -306,13 +335,13 @@ typedef struct awk_flat_array { /* * A record describing an extension function. Upon being - * loaded, the extension should pass in one of these for + * loaded, the extension should pass in one of these to gawk for * each C function. * * Each called function must fill in the result with eiher a number * or string. Gawk takes ownership of any string memory. * - * The called function should return the value of `result'. + * The called function must return the value of `result'. * This is for the convenience of the calling code inside gawk. * * Each extension function may decide what to do if the number of @@ -321,12 +350,10 @@ typedef struct awk_flat_array { */ typedef struct { const char *name; - awk_value_t *(*function)(int num_args_actual, awk_value_t *result); - size_t num_args_expected; + awk_value_t *(*function)(int num_actual_args, awk_value_t *result); + size_t num_expected_args; } awk_ext_func_t; -typedef int awk_bool_t; /* we don't use on purpose */ - typedef void *awk_ext_id_t; /* opaque type for extension id */ /* @@ -334,6 +361,9 @@ typedef void *awk_ext_id_t; /* opaque type for extension id */ * logically organized. */ typedef struct gawk_api { + /* First, data fields. */ + + /* These are what gawk thinks the API version is. */ awk_const int major_version; awk_const int minor_version; @@ -342,6 +372,7 @@ typedef struct gawk_api { * Currently only do_lint is prone to change, but we reserve * the right to allow the others also. */ +#define DO_FLAGS_SIZE 6 awk_const int do_flags[DO_FLAGS_SIZE]; /* Use these as indices into do_flags[] array to check the values */ #define gawk_do_lint 0 @@ -351,14 +382,59 @@ typedef struct gawk_api { #define gawk_do_debug 4 #define gawk_do_mpfr 5 + /* Next, registration functions: */ + + /* Add a function to the interpreter, returns true upon success */ + awk_bool_t (*api_add_ext_func)(awk_ext_id_t id, const char *namespace, + const awk_ext_func_t *func); + + /* Register an input parser; for opening files read-only */ + void (*api_register_input_parser)(awk_ext_id_t id, awk_input_parser_t *input_parser); + + /* Register an output wrapper, for writing files */ + void (*api_register_output_wrapper)(awk_ext_id_t id, awk_output_wrapper_t *output_wrapper); + + /* Register a processor for two way I/O */ + void (*api_register_two_way_processor)(awk_ext_id_t id, awk_two_way_processor_t *two_way_processor); + + /* + * Add an exit call back. + * + * arg0 is a private data pointer for use by the extension; + * gawk saves it and passes it into the function pointed + * to by funcp at exit. + */ + void (*api_awk_atexit)(awk_ext_id_t id, + void (*funcp)(void *data, int exit_status), + void *arg0); + + /* Register a version string for this extension with gawk. */ + void (*api_register_ext_version)(awk_ext_id_t id, const char *version); + + /* Functions to print messages */ + void (*api_fatal)(awk_ext_id_t id, const char *format, ...); + void (*api_warning)(awk_ext_id_t id, const char *format, ...); + void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...); + + /* Functions to update ERRNO */ + void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val); + void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string); + void (*api_unset_ERRNO)(awk_ext_id_t id); + /* * All of the functions that return a value from inside gawk * (get a parameter, get a global variable, get an array element) * behave in the same way. * - * Returns false if count is out of range, or if actual paramater - * does not match what is specified in wanted. In that case, - * result->val_type will hold the actual type of what was passed. + * For a function parameter, the return is false if the argument + * count is out of range, or if actual paramater does not match + * what is specified in wanted. In that case, result->val_type + * will hold the actual type of what was passed. + * + * Similarly for symbol table access to variables and array elements, + * the return is false if the actual variable or array element does + * not match what was requested, and the result->val_type will hold + * the actual type. Table entry is type returned: @@ -386,6 +462,8 @@ typedef struct gawk_api { +-----------+-----------+------------+------------+-----------+-----------+ */ + /* Functions to handle parameters passed to the extension. */ + /* * Get the count'th paramater, zero-based. * Returns false if count is out of range, or if actual paramater @@ -406,53 +484,23 @@ typedef struct gawk_api { size_t count, awk_array_t array); - /* Functions to print messages */ - void (*api_fatal)(awk_ext_id_t id, const char *format, ...); - void (*api_warning)(awk_ext_id_t id, const char *format, ...); - void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...); - - /* Register an input parser; for opening files read-only */ - void (*api_register_input_parser)(awk_ext_id_t id, awk_input_parser_t *input_parser); - - /* Register an output wrapper, for writing files / two-way pipes */ - void (*api_register_output_wrapper)(awk_ext_id_t id, awk_output_wrapper_t *output_wrapper); - - /* Register a processor for two way I/O */ - void (*api_register_two_way_processor)(awk_ext_id_t id, awk_two_way_processor_t *two_way_processor); - - /* Functions to update ERRNO */ - void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val); - void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string); - void (*api_unset_ERRNO)(awk_ext_id_t id); - - /* Add a function to the interpreter, returns true upon success */ - awk_bool_t (*api_add_ext_func)(awk_ext_id_t id, const awk_ext_func_t *func, - const char *namespace); - - /* Add an exit call back, returns true upon success */ - void (*api_awk_atexit)(awk_ext_id_t id, - void (*funcp)(void *data, int exit_status), - void *arg0); - /* * Symbol table access: - * - No access to special variables (NF, etc.) + * - Read-only access to special variables (NF, etc.) * - One special exception: PROCINFO. * - Use sym_update() to change a value, including from UNDEFINED * to scalar or array. */ /* - * Lookup a variable, fills in value. No messing with the value - * returned. Returns false if the variable doesn't exist - * or if the wrong type was requested. - * In the latter case, fills in vaule->val_type with the real type, - * as described above. - * Built-in variables may be accessed by an extension, but, with - * the exception of PROCINFO, they may not be modified. + * Lookup a variable, fill in value. No messing with the value + * returned. + * Returns false if the variable doesn't exist* or if the wrong type + * was requested. In the latter case, vaule->val_type will have + * the real type, as described above. * * awk_value_t val; * if (! api->sym_lookup(id, name, wanted, & val)) - * error_code(); + * error_code_here(); * else { * // safe to use val * } @@ -462,18 +510,6 @@ typedef struct gawk_api { awk_valtype_t wanted, awk_value_t *result); - /* - * Retrieve 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. - */ - 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 a value. Adds it to the symbol table if not there. * Changing types (scalar <--> array) is not allowed. @@ -483,15 +519,39 @@ typedef struct gawk_api { awk_bool_t (*api_sym_update)(awk_ext_id_t id, const char *name, awk_value_t *value); - /* - * Install a constant value. - */ + + /* Install a constant value. Intended to be used only with scalars. */ awk_bool_t (*api_sym_constant)(awk_ext_id_t id, const char *name, awk_value_t *value); /* - * Work with a scalar 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 @@ -508,7 +568,33 @@ typedef struct gawk_api { awk_bool_t (*api_sym_update_scalar)(awk_ext_id_t id, awk_scalar_t cookie, awk_value_t *value); + /* Cached values */ + + /* + * Cache a 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); + /* Array management */ + + /* + * 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. @@ -538,13 +624,6 @@ typedef struct gawk_api { awk_bool_t (*api_del_array_element)(awk_ext_id_t id, awk_array_t a_cookie, const awk_value_t* const index); - /* - * 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); - /* Create a new array cookie to which elements may be added */ awk_array_t (*api_create_array)(awk_ext_id_t id); @@ -556,41 +635,17 @@ typedef struct gawk_api { awk_array_t a_cookie, awk_flat_array_t **data); - /* - * When done, delete any marked elements, release the memory. - * Count must match what gawk thinks the size is. - * Otherwise it's a fatal error. - */ + /* 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); - - /* - * Cache a 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); - - /* - * Register a version string for this extension with gawk. - */ - void (*api_register_ext_version)(awk_ext_id_t id, const char *version); } gawk_api_t; #ifndef GAWK /* these are not for the gawk code itself! */ /* * Use these if you want to define "global" variables named api * and ext_id to make the code a little easier to read. + * See the sample boilerplate code, below. */ #define do_lint (api->do_flags[gawk_do_lint]) #define do_traditional (api->do_flags[gawk_do_traditional]) @@ -618,7 +673,7 @@ typedef struct gawk_api { (api->api_update_ERRNO_string(ext_id, str)) #define unset_ERRNO() (api->api_unset_ERRNO(ext_id)) -#define add_ext_func(func, ns) (api->api_add_ext_func(ext_id, func, ns)) +#define add_ext_func(ns, func) (api->api_add_ext_func(ext_id, ns, func)) #define awk_atexit(funcp, arg0) (api->api_awk_atexit(ext_id, funcp, arg0)) #define sym_lookup(name, wanted, result) \ @@ -669,13 +724,13 @@ typedef struct gawk_api { #define emalloc(pointer, type, size, message) \ do { \ if ((pointer = (type) malloc(size)) == 0) \ - fatal(ext_id, "malloc of %d bytes failed\n", size); \ + fatal(ext_id, "%s: malloc of %d bytes failed\n", message, size); \ } while(0) #define erealloc(pointer, type, size, message) \ do { \ if ((pointer = (type) realloc(pointer, size)) == 0) \ - fatal(ext_id, "realloc of %d bytes failed\n", size); \ + fatal(ext_id, "%s: realloc of %d bytes failed\n", message, size); \ } while(0) /* Constructor functions */ @@ -800,7 +855,7 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \ for (i = 0, j = sizeof(func_table) / sizeof(func_table[0]); i < j; i++) { \ if (func_table[i].name == NULL) \ break; \ - if (! add_ext_func(& func_table[i], name_space)) { \ + if (! add_ext_func(name_space, & func_table[i])) { \ warning(ext_id, #module ": could not add %s\n", \ func_table[i].name); \ errors++; \ -- cgit v1.2.3 From a892293556960b0813098ede7da7a34774da7d3c Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 14 Oct 2012 18:56:06 +0200 Subject: API cleanups and doc additions. --- gawkapi.h | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 0f6cfec3..5b942521 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -26,6 +26,7 @@ /* * N.B. You must include and * before including this file! + * You must include or to get size_t's definition. * You should also include if you intend to use * the dl_load_func convenience macro. */ @@ -100,8 +101,8 @@ extern "C" { typedef int awk_bool_t; /* we don't use on purpose */ -/* Portions of IOBUF that should be accessible to extension functions: */ -typedef struct iobuf_public { +/* The information about input files that input parsers need to know: */ +typedef struct awk_input { const char *name; /* filename */ int fd; /* file descriptor */ #define INVALID_HANDLE (-1) @@ -121,7 +122,7 @@ typedef struct iobuf_public { * is also responsible for managing this memory. * * It is guaranteed that errcode is a valid pointer, so there is - * no need to test for a NULL value. The caller sets *errcode to 0, + * no need to test for a NULL value. Gawk sets *errcode to 0, * so there is no need to set it unless an error occurs. * * If an error does occur, the function should return EOF and set @@ -130,7 +131,7 @@ typedef struct iobuf_public { * on the value of *errcode (e.g., setting *errcode = errno should do * the right thing). */ - int (*get_record)(char **out, struct iobuf_public *iobuf, int *errcode, + int (*get_record)(char **out, struct awk_input *iobuf, int *errcode, char **rt_start, size_t *rt_len); /* @@ -138,12 +139,12 @@ typedef struct iobuf_public { * Gawk itself will close the fd unless close_func first sets it to * INVALID_HANDLE. */ - void (*close_func)(struct iobuf_public *); + void (*close_func)(struct awk_input *); /* put last, for alignment. bleah */ struct stat sbuf; /* stat buf */ -} IOBUF_PUBLIC; +} awk_input_buf_t; typedef struct input_parser { const char *name; /* name of parser */ @@ -153,16 +154,16 @@ typedef struct input_parser { * would like to parse this file. It should not change any gawk * state! */ - awk_bool_t (*can_take_file)(const IOBUF_PUBLIC *iobuf); + awk_bool_t (*can_take_file)(const awk_input_buf_t *iobuf); /* * If this parser is selected, then take_control_of will be called. * It can assume that a previous call to can_take_file was successful, * and no gawk state has changed since that call. It should populate - * the IOBUF_PUBLIC get_record, close_func, and opaque values as needed. + * the awk_input_buf_t's get_record, close_func, and opaque values as needed. * It should return non-zero if successful. */ - awk_bool_t (*take_control_of)(IOBUF_PUBLIC *iobuf); + awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf); awk_const struct input_parser *awk_const next; /* for use by gawk */ } awk_input_parser_t; @@ -228,10 +229,11 @@ typedef struct two_way_processor { * If this processor is selected, then take_control_of will be called. * It can assume that a previous call to can_take_file was successful, * and no gawk state has changed since that call. It should populate - * the IOBUF_PUBLIC and awk_otuput_buf_t structures as needed. + * the awk_input_buf_t and awk_otuput_buf_t structures as needed. * It should return non-zero if successful. */ - awk_bool_t (*take_control_of)(const char *name, IOBUF_PUBLIC *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; @@ -338,7 +340,7 @@ typedef struct awk_flat_array { * loaded, the extension should pass in one of these to gawk for * each C function. * - * Each called function must fill in the result with eiher a number + * Each called function must fill in the result with either a number * or string. Gawk takes ownership of any string memory. * * The called function must return the value of `result'. @@ -403,6 +405,8 @@ typedef struct gawk_api { * arg0 is a private data pointer for use by the extension; * gawk saves it and passes it into the function pointed * to by funcp at exit. + * + * Exit callback functions are called in LIFO order. */ void (*api_awk_atexit)(awk_ext_id_t id, void (*funcp)(void *data, int exit_status), -- cgit v1.2.3 From bada9c9a2562ad850757988effc848fb55850c98 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 21 Oct 2012 12:28:48 +0200 Subject: z/OS fixes. --- gawkapi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 5b942521..17ce9c10 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -281,7 +281,7 @@ typedef enum { AWK_STRING, AWK_ARRAY, AWK_SCALAR, /* opaque access to a variable */ - AWK_VALUE_COOKIE, /* for updating a previously created value */ + AWK_VALUE_COOKIE /* for updating a previously created value */ } awk_valtype_t; /* -- cgit v1.2.3 From fd0df9b0201fcb59831828e6a1c5bd177108d677 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 21 Oct 2012 17:31:12 +0200 Subject: Minor API doc edits. --- gawkapi.h | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 17ce9c10..cf269066 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -372,7 +372,7 @@ typedef struct gawk_api { /* * These can change on the fly as things happen within gawk. * Currently only do_lint is prone to change, but we reserve - * the right to allow the others also. + * the right to allow the others to do so also. */ #define DO_FLAGS_SIZE 6 awk_const int do_flags[DO_FLAGS_SIZE]; @@ -391,13 +391,16 @@ typedef struct gawk_api { const awk_ext_func_t *func); /* Register an input parser; for opening files read-only */ - void (*api_register_input_parser)(awk_ext_id_t id, awk_input_parser_t *input_parser); + void (*api_register_input_parser)(awk_ext_id_t id, + awk_input_parser_t *input_parser); /* Register an output wrapper, for writing files */ - void (*api_register_output_wrapper)(awk_ext_id_t id, awk_output_wrapper_t *output_wrapper); + void (*api_register_output_wrapper)(awk_ext_id_t id, + awk_output_wrapper_t *output_wrapper); /* Register a processor for two way I/O */ - void (*api_register_two_way_processor)(awk_ext_id_t id, awk_two_way_processor_t *two_way_processor); + void (*api_register_two_way_processor)(awk_ext_id_t id, + awk_two_way_processor_t *two_way_processor); /* * Add an exit call back. @@ -575,11 +578,12 @@ typedef struct gawk_api { /* Cached values */ /* - * Cache a 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. + * 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); -- cgit v1.2.3 From 684e0459f9209b11d796636949ec5cf6c9269a94 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 23 Oct 2012 21:58:00 +0200 Subject: More documentation work. --- gawkapi.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index cf269066..5cdef871 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -329,10 +329,10 @@ typedef struct awk_element { * 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_const void *awk_const opaque1; /* private data for use by gawk */ + awk_const void *awk_const 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; /* -- cgit v1.2.3 From b9392f1328394ba9b5601af8e9ef6f2e73042048 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 24 Oct 2012 22:49:18 +0200 Subject: Doc additions. --- gawkapi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 5cdef871..c4f3081b 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -617,7 +617,7 @@ typedef struct gawk_api { /* * Change (or create) element in existing array with - * element->index and element->value. + * index and value. * * ARGV and ENVIRON may not be updated. */ @@ -627,7 +627,7 @@ typedef struct gawk_api { /* * Remove the element with the given index. - * Returns success if removed or if element did not exist. + * Returns success if removed or false 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); -- cgit v1.2.3 From 4a267501525be3157b0d41e9030e9d4a9c7f5897 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 26 Oct 2012 12:47:21 +0200 Subject: API doc additions and related other edits. --- gawkapi.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index c4f3081b..2b436a28 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -817,13 +817,16 @@ extern int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id); #if 0 /* Boiler plate code: */ +int plugin_is_GPL_compatible; + static gawk_api_t *const api; static awk_ext_id_t ext_id; +static const char *ext_version = NULL; /* or ... = "some string" */ + static awk_ext_func_t func_table[] = { { "name", do_name, 1 }, /* ... */ }; -static const char *ext_version = NULL; /* or ... = "some string" */ /* EITHER: */ @@ -831,7 +834,8 @@ static awk_bool_t (*init_func)(void) = NULL; /* OR: */ -static awk_bool_t init_my_module(void) +static awk_bool_t +init_my_module(void) { ... } -- cgit v1.2.3 From 154ca7ba84b1f8db0f0bb48e294d2fc26b3f7fbe Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sat, 27 Oct 2012 22:01:37 +0200 Subject: Doc updates. --- gawkapi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 2b436a28..67cff698 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -306,7 +306,7 @@ typedef struct { /* * A "flattened" array element. Gawk produces an array of these - * inside the awk_flattened_array_t. + * inside the awk_flat_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. -- cgit v1.2.3 From cea7b7eb1c73fd0680ccf637e9d762f0d26ff6bf Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sat, 27 Oct 2012 23:26:43 +0200 Subject: Finished basic text of API chapter! --- gawkapi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 67cff698..30b0e939 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -539,7 +539,7 @@ typedef struct gawk_api { * 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 + * Once you have obtained a scalar_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. -- cgit v1.2.3 From 993eaa708f7785e0ab5c1b1e53ddf4abe1d835e4 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 31 Oct 2012 19:51:04 +0200 Subject: Some minor fixes. See ChangeLog. --- gawkapi.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 30b0e939..4466ef31 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -29,6 +29,8 @@ * You must include or to get size_t's definition. * You should also include if you intend to use * the dl_load_func convenience macro. + * To pass reasonable integer values for ERRNO, you will need to + * include . */ #ifndef _GAWK_API_H -- cgit v1.2.3 From c4206d92d5bb73c1fc55484fbf938d2d59f18679 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 31 Oct 2012 21:36:49 +0200 Subject: Forging ahead with API documentation. --- gawkapi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 4466ef31..45f86a0f 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 */ -- cgit v1.2.3 From 5d3c11459bf9c8870cfc599722118b910aa17394 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 4 Nov 2012 15:01:50 +0200 Subject: More doc edits. Finish up api.texi. --- gawkapi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index 45f86a0f..dec87e53 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -28,7 +28,7 @@ * before including this file! * You must include or to get size_t's definition. * You should also include if you intend to use - * the dl_load_func convenience macro. + * the dl_load_func() convenience macro. * To pass reasonable integer values for ERRNO, you will need to * include . */ -- cgit v1.2.3 From 30b18b839b49213383f7dcbb430b3185a21efa99 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 22 Nov 2012 20:51:43 +0200 Subject: API minor fixes and doc update. --- gawkapi.h | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'gawkapi.h') diff --git a/gawkapi.h b/gawkapi.h index dec87e53..e4dff73c 100644 --- a/gawkapi.h +++ b/gawkapi.h @@ -24,12 +24,24 @@ */ /* - * N.B. You must include and - * before including this file! - * You must include or to get size_t's definition. - * You should also include if you intend to use - * the dl_load_func() convenience macro. - * To pass reasonable integer values for ERRNO, you will need to + * The following types and/or macros and/or functions are referenced + * in this file. For correct use, you must therefore include the + * corresponding standard header file BEFORE including this file. + * + * FILE - + * NULL - + * malloc() - + * memset(), memcpy() - + * size_t - + * struct stat - + * + * Due to portability concerns, especially to systems that are not + * fully standards-compliant, it is your responsibility to include + * the correct files in the correct way. This requirement is necessary + * in order to keep this file clean, instead of becoming a portability + * hodge-podge as can be seen in the gawk source code. + * + * To pass reasonable integer values for ERRNO, you will also need to * include . */ @@ -148,7 +160,7 @@ typedef struct awk_input { } awk_input_buf_t; -typedef struct input_parser { +typedef struct awk_input_parser { const char *name; /* name of parser */ /* @@ -167,7 +179,7 @@ typedef struct input_parser { */ awk_bool_t (*take_control_of)(awk_input_buf_t *iobuf); - awk_const struct input_parser *awk_const next; /* for use by gawk */ + awk_const struct awk_input_parser *awk_const next; /* for use by gawk */ } awk_input_parser_t; /* @@ -175,7 +187,7 @@ typedef struct input_parser { */ /* First the data structure */ -typedef struct { +typedef struct awk_output_buf { const char *name; /* name of output file */ const char *mode; /* mode argument to fopen */ FILE *fp; /* stdio file pointer */ @@ -194,7 +206,7 @@ typedef struct { } awk_output_buf_t; /* Next the output wrapper registered with gawk */ -typedef struct output_wrapper { +typedef struct awk_output_wrapper { const char *name; /* name of the wrapper */ /* @@ -213,11 +225,11 @@ typedef struct output_wrapper { */ awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf); - awk_const struct output_wrapper *awk_const next; /* for use by gawk */ + awk_const struct awk_output_wrapper *awk_const next; /* for use by gawk */ } awk_output_wrapper_t; /* A two-way processor combines an input parser and an output wrapper. */ -typedef struct two_way_processor { +typedef struct awk_two_way_processor { const char *name; /* name of the two-way processor */ /* @@ -237,7 +249,7 @@ typedef struct two_way_processor { 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_const struct awk_two_way_processor *awk_const next; /* for use by gawk */ } awk_two_way_processor_t; /* Current version of the API. */ @@ -256,7 +268,7 @@ enum { * be multibyte encoded in the current locale's encoding and character * set. Gawk will convert internally to wide characters if necessary. */ -typedef struct { +typedef struct awk_string { char *str; /* data */ size_t len; /* length thereof, in chars */ } awk_string_t; @@ -290,7 +302,7 @@ typedef enum { * An awk value. The val_type tag indicates what * is in the union. */ -typedef struct { +typedef struct awk_value { awk_valtype_t val_type; union { awk_string_t s; @@ -352,7 +364,7 @@ typedef struct awk_flat_array { * arguments isn't what it expected. Following awk functions, it * is likely OK to ignore extra arguments. */ -typedef struct { +typedef struct awk_ext_func { const char *name; awk_value_t *(*function)(int num_actual_args, awk_value_t *result); size_t num_expected_args; -- cgit v1.2.3