aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog26
-rw-r--r--TODO.xgawk5
-rw-r--r--awk.h11
-rw-r--r--ext.c5
-rw-r--r--gawkapi.c2
-rw-r--r--gawkapi.h44
-rw-r--r--interpret.h2
-rw-r--r--io.c66
8 files changed, 77 insertions, 84 deletions
diff --git a/ChangeLog b/ChangeLog
index 9f6cad4d..0043aaf9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2012-06-24 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * TODO.xgawk: Most of IOBUF has been hidden.
+ * gawkapi.h (IOBUF): Remove declaration (now back in awk.h).
+ (IOBUF_PUBLIC): Declare new structure defining subset of IOBUF fields
+ that should be exposed to extensions.
+ (gawk_api): Update register_open_hook argument from IOBUF to
+ IOBUF_PUBLIC.
+ * awk.h (IOBUF): Restore declaration with 5 fields moved to new
+ IOBUF_PUBLIC structure.
+ (register_open_hook): Update open_func argument from IOBUF to
+ IOBUF_PUBLIC.
+ * gawkapi.c (api_register_open_hook): Ditto.
+ * io.c (after_beginfile, nextfile, iop_close, gawk_pclose): Some fields
+ such as fd and name are now inside the IOBUF public structure.
+ (struct open_hook): Update open_func argument from IOBUF to
+ (register_open_hook): Ditto.
+ (find_open_hook): opaque now inside IOBUF_PUBLIC.
+ (iop_alloc): fd and name now in IOBUF_PUBLIC.
+ (get_a_record): If the get_record hook returns EOF, set the IOP_AT_EOF
+ flag. Access fd inside IOBUF_PUBLIC.
+ (get_read_timeout): File name now inside IOBUF_PUBLIC.
+ * interpret.h (r_interpret): File name now inside IOBUF_PUBLIC.
+ * ext.c (load_ext): No need to call return at the end of a void
+ function.
+
2012-06-24 Arnold D. Robbins <arnold@skeeve.com>
* ext.c (load_ext): Don't retun a value from a void function.
diff --git a/TODO.xgawk b/TODO.xgawk
index 7ea135af..3ea20297 100644
--- a/TODO.xgawk
+++ b/TODO.xgawk
@@ -40,9 +40,6 @@ To-do list for xgawk enhancements:
(somehow). More discussion / explanation of the vision behind this
would be welcome.
-- Can the IOBUF internals be removed from gawkapi.h? I think this may be
- possible if we revise the open hook implementation.
-
Separate projects for major standalone extensions. We need to set up
hosting for these projects:
@@ -160,3 +157,5 @@ Done:
- must update the API do_lint value when changed by set_LINT
- what is the proper return value for load_ext? It does not matter
unless called by the "extension" function that nobody uses.
+
+- Hide private parts of IOBUF from extensions.
diff --git a/awk.h b/awk.h
index 6450cbdc..a2e0e390 100644
--- a/awk.h
+++ b/awk.h
@@ -887,10 +887,8 @@ typedef struct exp_instruction {
/* Op_store_var */
#define initval x.xn
-#if 0
typedef struct iobuf {
- const char *name; /* filename */
- int fd; /* file descriptor */
+ IOBUF_PUBLIC public; /* exposed to extensions */
struct stat sbuf; /* stat buf */
char *buf; /* start data buffer */
char *off; /* start of current record in buffer */
@@ -908,10 +906,6 @@ typedef struct iobuf {
*/
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;
@@ -921,7 +915,6 @@ typedef struct iobuf {
# define IOP_CLOSED 8
# define IOP_AT_START 16
} IOBUF;
-#endif
typedef void (*Func_ptr)(void);
@@ -1549,7 +1542,7 @@ extern int isdirpunct(int c);
/* io.c */
extern void init_io(void);
-extern void register_open_hook(void *(*open_func)(IOBUF *));
+extern void register_open_hook(void *(*open_func)(IOBUF_PUBLIC *));
extern void set_FNR(void);
extern void set_NR(void);
diff --git a/ext.c b/ext.c
index 0b87def9..14d55c5f 100644
--- a/ext.c
+++ b/ext.c
@@ -66,12 +66,9 @@ load_ext(const char *lib_name)
fatal(_("load_ext: library `%s': cannot call function `%s' (%s)\n"),
lib_name, INIT_FUNC, dlerror());
- if (install_func(& api_impl, NULL /* ext_id */) == 0) {
+ if (install_func(& api_impl, NULL /* ext_id */) == 0)
warning(_("load_ext: library `%s' initialization routine `%s' failed\n"),
lib_name, INIT_FUNC);
- return;
- }
- return;
}
diff --git a/gawkapi.c b/gawkapi.c
index f87c7759..0a00be69 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -199,7 +199,7 @@ api_lintwarn(awk_ext_id_t id, const char *format, ...)
/* api_register_open_hook --- register an open hook; for opening files read-only */
static void
-api_register_open_hook(awk_ext_id_t id, void* (*open_func)(IOBUF *))
+api_register_open_hook(awk_ext_id_t id, void* (*open_func)(IOBUF_PUBLIC *))
{
(void) id;
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);
diff --git a/interpret.h b/interpret.h
index abffbda4..c7380bd4 100644
--- a/interpret.h
+++ b/interpret.h
@@ -1043,7 +1043,7 @@ match_re:
if (inrec(curfile, & errcode) != 0) {
if (errcode > 0 && (do_traditional || ! pc->has_endfile))
fatal(_("error reading input file `%s': %s"),
- curfile->name, strerror(errcode));
+ curfile->public.name, strerror(errcode));
JUMPTO(ni);
} /* else
diff --git a/io.c b/io.c
index a9fb3455..ab204e09 100644
--- a/io.c
+++ b/io.c
@@ -312,11 +312,11 @@ after_beginfile(IOBUF **curfile)
iop = *curfile;
assert(iop != NULL);
- if (iop->fd == INVALID_HANDLE) {
+ if (iop->public.fd == INVALID_HANDLE) {
const char *fname;
int errcode;
- fname = iop->name;
+ fname = iop->public.name;
errcode = iop->errcode;
iop->errcode = 0;
errno = 0;
@@ -366,7 +366,7 @@ nextfile(IOBUF **curfile, bool skipping)
if (iop != NULL) {
if (at_eof(iop)) {
- assert(iop->fd != INVALID_HANDLE);
+ assert(iop->public.fd != INVALID_HANDLE);
(void) iop_close(iop);
*curfile = NULL;
return 1; /* run endfile block */
@@ -430,7 +430,7 @@ nextfile(IOBUF **curfile, bool skipping)
iop = *curfile = iop_alloc(fileno(stdin), fname, & mybuf, false);
iop->flag |= IOP_NOFREE_OBJ;
- if (iop->fd == INVALID_HANDLE) {
+ if (iop->public.fd == INVALID_HANDLE) {
errcode = errno;
errno = 0;
update_ERRNO_int(errno);
@@ -539,7 +539,7 @@ iop_close(IOBUF *iop)
if (iop == NULL)
return 0;
- if (iop->fd == INVALID_HANDLE) { /* from nextfile(...) above */
+ if (iop->public.fd == INVALID_HANDLE) { /* from nextfile(...) above */
assert(iop->buf == NULL);
assert((iop->flag & IOP_NOFREE_OBJ) != 0);
return 0;
@@ -555,19 +555,19 @@ iop_close(IOBUF *iop)
* So we remap the standard file to /dev/null.
* Thanks to Jim Meyering for the suggestion.
*/
- if (iop->fd == fileno(stdin)
- || iop->fd == fileno(stdout)
- || iop->fd == fileno(stderr))
- ret = remap_std_file(iop->fd);
+ if (iop->public.fd == fileno(stdin)
+ || iop->public.fd == fileno(stdout)
+ || iop->public.fd == fileno(stderr))
+ ret = remap_std_file(iop->public.fd);
else
- ret = close(iop->fd);
+ ret = close(iop->public.fd);
- if (iop->close_func != NULL)
- iop->close_func(iop);
+ if (iop->public.close_func != NULL)
+ iop->public.close_func(&iop->public);
if (ret == -1)
- warning(_("close of fd %d (`%s') failed (%s)"), iop->fd,
- iop->name, strerror(errno));
+ warning(_("close of fd %d (`%s') failed (%s)"), iop->public.fd,
+ iop->public.name, strerror(errno));
/*
* Be careful -- $0 may still reference the buffer even though
* an explicit close is being done; in the future, maybe we
@@ -1073,7 +1073,7 @@ close_rp(struct redirect *rp, two_way_close_type how)
if ((rp->flag & RED_SOCKET) != 0 && rp->iop != NULL) {
#ifdef HAVE_SOCKETS
if ((rp->flag & RED_TCP) != 0)
- (void) shutdown(rp->iop->fd, SHUT_RD);
+ (void) shutdown(rp->iop->public.fd, SHUT_RD);
#endif /* HAVE_SOCKETS */
(void) iop_close(rp->iop);
} else
@@ -2224,10 +2224,10 @@ gawk_popen(const char *cmd, struct redirect *rp)
static int
gawk_pclose(struct redirect *rp)
{
- int rval, aval, fd = rp->iop->fd;
+ int rval, aval, fd = rp->iop->public.fd;
if (rp->iop != NULL) {
- rp->iop->fd = dup(fd); /* kludge to allow close() + pclose() */
+ rp->iop->public.fd = dup(fd); /* kludge to allow close() + pclose() */
rval = iop_close(rp->iop);
}
rp->iop = NULL;
@@ -2589,13 +2589,13 @@ srcopen(SRCFILE *s)
static struct open_hook {
struct open_hook *next;
- void *(*open_func)(IOBUF *);
+ void *(*open_func)(IOBUF_PUBLIC *);
} *open_hooks;
/* register_open_hook --- add an open hook to the list */
void
-register_open_hook(void *(*open_func)(IOBUF *))
+register_open_hook(void *(*open_func)(IOBUF_PUBLIC *))
{
struct open_hook *oh;
@@ -2614,7 +2614,7 @@ find_open_hook(IOBUF *iop)
/* walk through open hooks, stop at first one that responds */
for (oh = open_hooks; oh != NULL; oh = oh->next) {
- if ((iop->opaque = (*oh->open_func)(iop)) != NULL)
+ if ((iop->public.opaque = (*oh->open_func)(&iop->public)) != NULL)
break;
}
}
@@ -2632,24 +2632,24 @@ iop_alloc(int fd, const char *name, IOBUF *iop, bool do_openhooks)
iop_malloced = true;
}
memset(iop, '\0', sizeof(IOBUF));
- iop->fd = fd;
- iop->name = name;
+ iop->public.fd = fd;
+ iop->public.name = name;
iop->read_func = ( ssize_t(*)() ) read;
if (do_openhooks) {
find_open_hook(iop);
/* tried to find open hook and could not */
- if (iop->fd == INVALID_HANDLE) {
+ if (iop->public.fd == INVALID_HANDLE) {
if (iop_malloced)
efree(iop);
return NULL;
}
- } else if (iop->fd == INVALID_HANDLE)
+ } else if (iop->public.fd == INVALID_HANDLE)
return iop;
- if (os_isatty(iop->fd))
+ if (os_isatty(iop->public.fd))
iop->flag |= IOP_IS_TTY;
- iop->readsize = iop->size = optimal_bufsize(iop->fd, & sbuf);
+ iop->readsize = iop->size = optimal_bufsize(iop->public.fd, & sbuf);
iop->sbuf = sbuf;
if (do_lint && S_ISREG(sbuf.st_mode) && sbuf.st_size == 0)
lintwarn(_("data file `%s' is empty"), name);
@@ -3052,12 +3052,16 @@ get_a_record(char **out, /* pointer to pointer to data */
if (read_can_timeout)
read_timeout = get_read_timeout(iop);
- if (iop->get_record != NULL)
- return iop->get_record(out, iop, errcode);
+ if (iop->public.get_record != NULL) {
+ int rc = iop->public.get_record(out, &iop->public, errcode);
+ if (rc == EOF)
+ iop->flag |= IOP_AT_EOF;
+ return rc;
+ }
/* fill initial buffer */
if (has_no_data(iop) || no_data_left(iop)) {
- iop->count = iop->read_func(iop->fd, iop->buf, iop->readsize);
+ iop->count = iop->read_func(iop->public.fd, iop->buf, iop->readsize);
if (iop->count == 0) {
iop->flag |= IOP_AT_EOF;
return EOF;
@@ -3124,7 +3128,7 @@ get_a_record(char **out, /* pointer to pointer to data */
amt_to_read = min(amt_to_read, SSIZE_MAX);
#endif
- iop->count = iop->read_func(iop->fd, iop->dataend, amt_to_read);
+ iop->count = iop->read_func(iop->public.fd, iop->dataend, amt_to_read);
if (iop->count == -1) {
*errcode = errno;
iop->flag |= IOP_AT_EOF;
@@ -3397,7 +3401,7 @@ get_read_timeout(IOBUF *iop)
long tmout = 0;
if (PROCINFO_node != NULL) {
- const char *name = iop->name;
+ const char *name = iop->public.name;
NODE *val = NULL;
static NODE *full_idx = NULL;
static const char *last_name = NULL;