diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2012-05-29 23:33:27 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2012-05-29 23:33:27 +0300 |
commit | 04dc190623f0d99d80387b33ca747b8cbad37724 (patch) | |
tree | 2a54d44dc62160ee6f14ec55442508fce0246810 | |
parent | 62d890d4384a70c7550876c617b3a34e28dab234 (diff) | |
download | egawk-04dc190623f0d99d80387b33ca747b8cbad37724.tar.gz egawk-04dc190623f0d99d80387b33ca747b8cbad37724.tar.bz2 egawk-04dc190623f0d99d80387b33ca747b8cbad37724.zip |
Further API work.
-rw-r--r-- | ChangeLog | 17 | ||||
-rwxr-xr-x | bootstrap.sh | 6 | ||||
-rw-r--r-- | extension/ChangeLog | 5 | ||||
-rw-r--r-- | extension/filefuncs.c | 187 | ||||
-rw-r--r-- | extension/fork.c | 7 | ||||
-rw-r--r-- | extension/ordchr.c | 5 | ||||
-rw-r--r-- | extension/readfile.c | 3 | ||||
-rw-r--r-- | gawkapi.c | 56 | ||||
-rw-r--r-- | gawkapi.h | 119 | ||||
-rw-r--r-- | test/ChangeLog | 4 | ||||
-rw-r--r-- | test/Makefile.am | 2 | ||||
-rw-r--r-- | test/Makefile.in | 2 |
12 files changed, 222 insertions, 191 deletions
@@ -1,3 +1,18 @@ +2012-05-29 Arnold D. Robbins <arnold@skeeve.com> + + * gawkapi.c (node_to_awk_value): Add third parameter indicating type + of value desired. Based on that, do force_string or force_number + to get the "other" type. + (awk_value_to_node): Clean up the code a bit. + (get_curfunc_param): Move forcing of values into node_to_awk_value. + (api_sym_lookup): Add third parameter indicating type of value wanted. + (api_get_array_element): Ditto. + * gawk_api.h: Additional comments and clarifications. Revise APIs + to take third 'wanted' argument as above. + (awk_value_t): No longer a union so that both values may be accessed. + All macros: Parenthesized the bodies. + * bootstrap.sh: Rationalize a bit. + 2012-05-26 Andrew J. Schorr <aschorr@telemetry-investments.com> * Makefile.am (include_HEADERS): Add so gawkapi.h will be installed. @@ -13,7 +28,7 @@ * awk.h (is_off_limits_var): Declare it. * gawkapi.c (api_sym_lookup): Use it. - * bootstrap.h: Touch various files in the extension directory also. + * bootstrap.sh: Touch various files in the extension directory also. 2012-05-24 Andrew J. Schorr <aschorr@telemetry-investments.com> diff --git a/bootstrap.sh b/bootstrap.sh index 67faf76a..535ae8fb 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -26,8 +26,10 @@ touch aclocal.m4 find awklib -type f -print | xargs touch sleep 1 touch configure +touch extension/configure sleep 2 touch configh.in +touch extension/configh.in sleep 1 touch test/Maketests find . -name Makefile.in -print | xargs touch @@ -37,7 +39,3 @@ touch po/stamp-po touch awkgram.c touch command.c touch version.c - -touch extension/configure -sleep 2 -touch extension/configh.in diff --git a/extension/ChangeLog b/extension/ChangeLog index 4fa1a7f5..0bafd39d 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,8 @@ +2012-05-29 Arnold D. Robbins <arnold@skeeve.com> + + * filefuncs.c: Further cleanup and condensation of code into tables. + * fork.c, ordchr.c, readfile.c: Update copyright, general cleanup. + 2012-05-25 Arnold D. Robbins <arnold@skeeve.com> * filefuncs.c (array_set_numeric): Don't return a value from diff --git a/extension/filefuncs.c b/extension/filefuncs.c index fb19f2b3..46b1596e 100644 --- a/extension/filefuncs.c +++ b/extension/filefuncs.c @@ -4,6 +4,7 @@ * * Arnold Robbins, update for 3.1, Mon Nov 23 12:53:39 EST 1998 * Arnold Robbins and John Haque, update for 3.1.4, applied Mon Jun 14 13:55:30 IDT 2004 + * Arnold Robbins and Andrew Schorr, revised for new extension API, May 2012. */ /* @@ -36,6 +37,7 @@ #include <sys/types.h> #include <sys/stat.h> + #include "config.h" #include "gawkapi.h" @@ -53,9 +55,9 @@ do_chdir(int nargs, awk_value_t *result) int ret = -1; if (do_lint && nargs != 1) - lintwarn(ext_id, "chdir: called with incorrect number of arguments"); + lintwarn(ext_id, "chdir: called with incorrect number of arguments, expecting 1"); - if (get_curfunc_param(0, AWK_STRING, &newdir) != NULL) { + if (get_curfunc_param(0, AWK_STRING, & newdir) != NULL) { ret = chdir(newdir.str_value.str); if (ret < 0) update_ERRNO_int(errno); @@ -70,6 +72,27 @@ static char * format_mode(unsigned long fmode) { static char outbuf[12]; + static struct ftype_map { + int mask; + int charval; + } ftype_map[] = { + { S_IFREG, '-' }, /* redundant */ + { S_IFBLK, 'b' }, + { S_IFCHR, 'c' }, + { S_IFDIR, 'd' }, +#ifdef S_IFSOCK + { S_IFSOCK, 's' }, +#endif +#ifdef S_IFIFO + { S_IFIFO, 'p' }, +#endif +#ifdef S_IFLNK + { S_IFLNK, 'l' }, +#endif +#ifdef S_IFDOOR /* Solaris weirdness */ + { S_IFDOOR, 'D' }, +#endif /* S_IFDOOR */ + }; static struct mode_map { int mask; int rep; @@ -78,46 +101,30 @@ format_mode(unsigned long fmode) { S_IRGRP, 'r' }, { S_IWGRP, 'w' }, { S_IXGRP, 'x' }, { S_IROTH, 'r' }, { S_IWOTH, 'w' }, { S_IXOTH, 'x' }, }; + static struct setuid_map { + int mask; + int index; + int small_rep; + int big_rep; + } setuid_map[] = { + { S_ISUID, 3, 's', 'S' }, /* setuid bit */ + { S_ISGID, 6, 's', 'l' }, /* setgid without execute == locking */ + { S_ISVTX, 9, 't', 'T' }, /* the so-called "sticky" bit */ + }; int i, j, k; strcpy(outbuf, "----------"); + /* first, get the file type */ i = 0; - switch (fmode & S_IFMT) { -#ifdef S_IFSOCK - case S_IFSOCK: - outbuf[i] = 's'; - break; -#endif -#ifdef S_IFLNK - case S_IFLNK: - outbuf[i] = 'l'; - break; -#endif - case S_IFREG: - outbuf[i] = '-'; /* redundant */ - break; - case S_IFBLK: - outbuf[i] = 'b'; - break; - case S_IFDIR: - outbuf[i] = 'd'; - break; -#ifdef S_IFDOOR /* Solaris weirdness */ - case S_IFDOOR: - outbuf[i] = 'D'; - break; -#endif /* S_IFDOOR */ - case S_IFCHR: - outbuf[i] = 'c'; - break; -#ifdef S_IFIFO - case S_IFIFO: - outbuf[i] = 'p'; - break; -#endif + for (j = 0, k = sizeof(ftype_map)/sizeof(ftype_map[0]); j < k; j++) { + if ((fmode & S_IFMT) == ftype_map[j].mask) { + outbuf[i] = ftype_map[j].charval; + break; + } } + /* now the permissions */ for (j = 0, k = sizeof(map)/sizeof(map[0]); j < k; j++) { i++; if ((fmode & map[j].mask) != 0) @@ -127,28 +134,14 @@ format_mode(unsigned long fmode) i++; outbuf[i] = '\0'; - /* setuid bit */ - if ((fmode & S_ISUID) != 0) { - if (outbuf[3] == 'x') - outbuf[3] = 's'; - else - outbuf[3] = 'S'; - } - - /* setgid without execute == locking */ - if ((fmode & S_ISGID) != 0) { - if (outbuf[6] == 'x') - outbuf[6] = 's'; - else - outbuf[6] = 'l'; - } - - /* the so-called "sticky" bit */ - if ((fmode & S_ISVTX) != 0) { - if (outbuf[9] == 'x') - outbuf[9] = 't'; - else - outbuf[9] = 'T'; + /* tweaks for the setuid / setgid / sticky bits */ + for (j = 0, k = sizeof(setuid_map)/sizeof(setuid_map[0]); j < k; j++) { + if (fmode & setuid_map[j].mask) { + if (outbuf[setuid_map[j].index] == 'x') + outbuf[setuid_map[j].index] = setuid_map[j].small_rep; + else + outbuf[setuid_map[j].index] = setuid_map[j].big_rep; + } } return outbuf; @@ -226,10 +219,13 @@ array_set(awk_array_t array, const char *sub, awk_value_t *value) set_array_element(array, & element); } +/* array_set_numeric --- set an array element with a number */ + static void array_set_numeric(awk_array_t array, const char *sub, double num) { awk_value_t tmp; + array_set(array, sub, make_number(num, & tmp)); } @@ -242,22 +238,41 @@ do_stat(int nargs, awk_value_t *result) char *name; awk_array_t array; struct stat sbuf; - int ret; + int ret, j, k; char *pmode; /* printable mode */ char *type = "unknown"; awk_value_t tmp; + static struct ftype_map { + int mask; + const char *type; + } ftype_map[] = { + { S_IFREG, "file" }, + { S_IFBLK, "blockdev" }, + { S_IFCHR, "chardev" }, + { S_IFDIR, "directory" }, +#ifdef S_IFSOCK + { S_IFSOCK, "socket" }, +#endif +#ifdef S_IFIFO + { S_IFIFO, "fifo" }, +#endif +#ifdef S_IFLNK + { S_IFLNK, "symlink" }, +#endif +#ifdef S_IFDOOR /* Solaris weirdness */ + { S_IFDOOR, "door" }, +#endif /* S_IFDOOR */ + }; if (do_lint && nargs != 2) { lintwarn(ext_id, "stat: called with wrong number of arguments"); - /* XXX previous version returned 0; why? */ return make_number(-1, result); } /* file is first arg, array to hold results is second */ - if (get_curfunc_param(0, AWK_STRING, &file_param) == NULL || - get_curfunc_param(1, AWK_ARRAY, &array_param) == NULL) { + if ( get_curfunc_param(0, AWK_STRING, & file_param) == NULL + || get_curfunc_param(1, AWK_ARRAY, & array_param) == NULL) { warning(ext_id, "stat: bad parameters"); - /* XXX previous version returned 0; why? */ return make_number(-1, result); } @@ -271,7 +286,6 @@ do_stat(int nargs, awk_value_t *result) ret = lstat(name, & sbuf); if (ret < 0) { update_ERRNO_int(errno); - /* XXX previous version returned 0; why? */ return make_number(-1, result); } @@ -301,7 +315,7 @@ do_stat(int nargs, awk_value_t *result) #endif /* HAVE_ST_BLKSIZE */ pmode = format_mode(sbuf.st_mode); - array_set(array, "pmode", make_string(pmode, strlen(pmode), &tmp)); + array_set(array, "pmode", make_string(pmode, strlen(pmode), & tmp)); /* for symbolic links, add a linkval field */ if (S_ISLNK(sbuf.st_mode)) { @@ -309,46 +323,19 @@ do_stat(int nargs, awk_value_t *result) ssize_t linksize; if ((buf = read_symlink(name, sbuf.st_size, - &linksize)) != NULL) - array_set(array, "linkval", make_string(buf, linksize, &tmp)); + & linksize)) != NULL) + array_set(array, "linkval", make_string(buf, linksize, & tmp)); else - warning(ext_id, "unable to read symbolic link `%s'", name); + warning(ext_id, "stat: unable to read symbolic link `%s'", name); } /* add a type field */ - switch (sbuf.st_mode & S_IFMT) { -#ifdef S_IFSOCK - case S_IFSOCK: - type = "socket"; - break; -#endif -#ifdef S_IFLNK - case S_IFLNK: - type = "symlink"; - break; -#endif - case S_IFREG: - type = "file"; - break; - case S_IFBLK: - type = "blockdev"; - break; - case S_IFDIR: - type = "directory"; - break; -#ifdef S_IFDOOR - case S_IFDOOR: - type = "door"; - break; -#endif - case S_IFCHR: - type = "chardev"; - break; -#ifdef S_IFIFO - case S_IFIFO: - type = "fifo"; - break; -#endif + type = "unknown"; /* shouldn't happen */ + for (j = 0, k = sizeof(ftype_map)/sizeof(ftype_map[0]); j < k; j++) { + if ((sbuf.st_mode & S_IFMT) == ftype_map[j].mask) { + type = ftype_map[j].type; + break; + } } array_set(array, "type", make_string(type, strlen(type), &tmp)); diff --git a/extension/fork.c b/extension/fork.c index a7f96017..1d4ad82c 100644 --- a/extension/fork.c +++ b/extension/fork.c @@ -2,10 +2,11 @@ * fork.c - Provide fork and waitpid functions for gawk. * * Revised 6/2004 + * Revised 5/2012 for new extension API. */ /* - * Copyright (C) 2001, 2004, 2011 the Free Software Foundation, Inc. + * Copyright (C) 2001, 2004, 2011, 2012 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. @@ -76,7 +77,8 @@ do_fork(int nargs, awk_value_t *result) else if (ret == 0) { /* update PROCINFO in the child, if the array exists */ awk_value_t procinfo; - if (sym_lookup("PROCINFO", &procinfo) != NULL) { + + if (sym_lookup("PROCINFO", & procinfo, AWK_ARRAY) != NULL) { if (procinfo.val_type != AWK_ARRAY) { if (do_lint) lintwarn(ext_id, "fork: PROCINFO is not an array!"); @@ -91,7 +93,6 @@ do_fork(int nargs, awk_value_t *result) return make_number(ret, result); } - /* do_waitpid --- provide dynamically loaded waitpid() builtin for gawk */ static awk_value_t * diff --git a/extension/ordchr.c b/extension/ordchr.c index 95401650..c5d2bb45 100644 --- a/extension/ordchr.c +++ b/extension/ordchr.c @@ -5,10 +5,11 @@ * arnold@skeeve.com * 8/2001 * Revised 6/2004 + * Revised 5/2012 */ /* - * Copyright (C) 2001, 2004, 2011 the Free Software Foundation, Inc. + * Copyright (C) 2001, 2004, 2011, 2012 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. @@ -55,7 +56,7 @@ do_ord(int nargs, awk_value_t *result) if (do_lint && nargs > 1) lintwarn(ext_id, "ord: called with too many arguments"); - if (get_curfunc_param(0, AWK_STRING, &str) != NULL) { + if (get_curfunc_param(0, AWK_STRING, & str) != NULL) { ret = str.str_value.str[0]; } else if (do_lint) lintwarn(ext_id, "ord: called with no arguments"); diff --git a/extension/readfile.c b/extension/readfile.c index 639c897a..ca513912 100644 --- a/extension/readfile.c +++ b/extension/readfile.c @@ -7,10 +7,11 @@ * Mon Jun 9 17:05:11 IDT 2003 * Revised for new dynamic function facilities * Mon Jun 14 14:53:07 IDT 2004 + * Revised for formal API May 2012 */ /* - * Copyright (C) 2002, 2003, 2004, 2011 the Free Software Foundation, Inc. + * Copyright (C) 2002, 2003, 2004, 2011, 2012 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. @@ -25,7 +25,7 @@ #include "awk.h" -static awk_value_t *node_to_awk_value(NODE *node, awk_value_t *result); +static awk_value_t *node_to_awk_value(NODE *node, awk_value_t *result, awk_valtype_t wanted); /* * Get the count'th paramater, zero-based. @@ -44,32 +44,24 @@ api_get_curfunc_param(awk_ext_id_t id, size_t count, if (arg == NULL) return NULL; - if (arg->type != Node_var_array) { - if (wanted == AWK_NUMBER) { - (void) force_number(arg); - } else { - (void) force_string(arg); - } - } - - return node_to_awk_value(arg, result); + return node_to_awk_value(arg, result, wanted); } -/* Set the return value. Gawk takes ownership of string memory */ +/* awk_value_to_node --- convert a value into a NODE */ + NODE * awk_value_to_node(const awk_value_t *retval) { NODE *ext_ret_val; if (retval == NULL) - fatal(_("api_set_return_value: received null retval")); + fatal(_("awk_value_to_node: received null retval")); ext_ret_val = NULL; - getnode(ext_ret_val); if (retval->val_type == AWK_ARRAY) { + getnode(ext_ret_val); *ext_ret_val = *((NODE *) retval->array_cookie); } else if (retval->val_type == AWK_UNDEFINED) { - /* free node */ ext_ret_val = dupnode(Nnull_string); } else if (retval->val_type == AWK_NUMBER) { ext_ret_val = make_number(retval->num_value); @@ -212,39 +204,45 @@ api_awk_atexit(awk_ext_id_t id, * to scalar or array. */ static awk_value_t * -node_to_awk_value(NODE *node, awk_value_t *val) +node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) { memset(val, 0, sizeof(*val)); + + if (node->type != Node_var_array) { + /* make sure both values are valid */ + (void) force_number(node); + (void) force_string(node); + } + switch (node->type) { + case Node_var: + node = node->var_value; + /* FALL THROUGH */ case Node_val: if (node->flags & NUMBER) { val->val_type = AWK_NUMBER; val->num_value = get_number_d(node); + val->str_value.str = node->stptr; + val->str_value.len = node->stlen; } else if (node->flags & STRING) { val->val_type = AWK_STRING; val->str_value.str = node->stptr; val->str_value.len = node->stlen; + val->num_value = get_number_d(node); } else { return NULL; } + break; case Node_var_new: val->val_type = AWK_UNDEFINED; break; - case Node_var: - if ((node->var_value->flags & NUMBER) != 0) { - val->val_type = AWK_NUMBER; - val->num_value = get_number_d(node->var_value); - } else { - val->val_type = AWK_STRING; - val->str_value.str = node->var_value->stptr; - val->str_value.len = node->var_value->stlen; - } - break; + case Node_var_array: val->val_type = AWK_ARRAY; val->array_cookie = node; break; + default: return NULL; } @@ -258,7 +256,9 @@ node_to_awk_value(NODE *node, awk_value_t *val) * Built-in variables (except PROCINFO) may not be changed by an extension. */ static awk_value_t * -api_sym_lookup(awk_ext_id_t id, const char *name, awk_value_t *result) +api_sym_lookup(awk_ext_id_t id, + const char *name, awk_value_t *result, + awk_valtype_t wanted) { NODE *node; @@ -268,7 +268,7 @@ api_sym_lookup(awk_ext_id_t id, const char *name, awk_value_t *result) || (node = lookup(name)) == NULL) return NULL; - return node_to_awk_value(node, result); + return node_to_awk_value(node, result, wanted); } /* @@ -289,7 +289,7 @@ api_sym_update(awk_ext_id_t id, const char *name, awk_value_t *value) static awk_value_t * api_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) { return NULL; /* for now */ } @@ -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); diff --git a/test/ChangeLog b/test/ChangeLog index 6031ca09..c4ac50de 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,7 @@ +2012-05-29 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (clean): Add readfile.ok to list of files to removed. + 2012-05-26 Andrew J. Schorr <aschorr@telemetry-investments.com> * Makefile.am (readfile): Revert previous patch, and add comment diff --git a/test/Makefile.am b/test/Makefile.am index c0293ba5..348d4df2 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1586,7 +1586,7 @@ $(srcdir)/Maketests: $(srcdir)/Makefile.am $(srcdir)/Gentests $(AWK) -f $(srcdir)/Gentests "$(srcdir)/Makefile.am" $$files > $(srcdir)/Maketests clean: - rm -fr _* core core.* fmtspcl.ok junk out1 out2 out3 strftime.ok test1 test2 seq *~ + rm -fr _* core core.* fmtspcl.ok junk out1 out2 out3 strftime.ok test1 test2 seq *~ readfile.ok # An attempt to print something that can be grepped for in build logs pass-fail: diff --git a/test/Makefile.in b/test/Makefile.in index 683ba8a9..0afe5e05 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -3188,7 +3188,7 @@ $(srcdir)/Maketests: $(srcdir)/Makefile.am $(srcdir)/Gentests $(AWK) -f $(srcdir)/Gentests "$(srcdir)/Makefile.am" $$files > $(srcdir)/Maketests clean: - rm -fr _* core core.* fmtspcl.ok junk out1 out2 out3 strftime.ok test1 test2 seq *~ + rm -fr _* core core.* fmtspcl.ok junk out1 out2 out3 strftime.ok test1 test2 seq *~ readfile.ok # An attempt to print something that can be grepped for in build logs pass-fail: |