diff options
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | TODO.xgawk | 5 | ||||
-rw-r--r-- | awk.h | 11 | ||||
-rw-r--r-- | ext.c | 5 | ||||
-rw-r--r-- | gawkapi.c | 2 | ||||
-rw-r--r-- | gawkapi.h | 44 | ||||
-rw-r--r-- | interpret.h | 2 | ||||
-rw-r--r-- | io.c | 66 |
8 files changed, 77 insertions, 84 deletions
@@ -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. @@ -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. @@ -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); @@ -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; } @@ -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; @@ -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 @@ -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; |