diff --git a/lib/hcl.h b/lib/hcl.h index 2cf48af..eae0bfb 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -790,9 +790,14 @@ struct hcl_ioinarg_t void* handle; /** - * [OUT] place data here + * [OUT] place data here for #HCL_IO_READ */ - hcl_ooch_t buf[1024]; + hcl_ooch_t buf[2048]; + + /** + * [OUT] place the number of characters read here for #HCL_IO_READ + */ + hcl_oow_t xlen; /** * [IN] points to the data of the includer. It is #HCL_NULL for the @@ -804,7 +809,9 @@ struct hcl_ioinarg_t /*----------- from here down, internal use only -------------------*/ struct { - int pos, len, state; + hcl_oow_t pos; + hcl_oow_t len; + int state; } b; unsigned long int line; @@ -818,12 +825,36 @@ struct hcl_ioinarg_t typedef struct hcl_iooutarg_t hcl_iooutarg_t; struct hcl_iooutarg_t { + /** + * [OUT] I/O handle set by a handler. + * The source stream handler can set this field when it opens a stream. + * All subsequent operations on the stream see this field as set + * during opening. + */ void* handle; + + /** + * [IN] the pointer to the beginning of the character string + * to write + */ hcl_ooch_t* ptr; - hcl_oow_t len; + + /** + * [IN] total number of characters to write + */ + hcl_oow_t len; + + /** + * [OUT] place the number of characters written here for HCL_IO_WRITE + */ + hcl_oow_t xlen; }; -typedef hcl_ooi_t (*hcl_ioimpl_t) ( +/** + * The hcl_ioimpl_t type defines a callback function prototype + * for I/O operations. + */ +typedef int (*hcl_ioimpl_t) ( hcl_t* hcl, hcl_iocmd_t cmd, void* arg /* hcl_ioinarg_t* or hcl_iooutarg_t* */ diff --git a/lib/logfmt.c b/lib/logfmt.c index c3ddbcc..bda5503 100644 --- a/lib/logfmt.c +++ b/lib/logfmt.c @@ -182,9 +182,9 @@ static hcl_bch_t* sprintn_upper (hcl_bch_t* nbuf, hcl_uintmax_t num, int base, h } /* ------------------------------------------------------------------------- */ -static int put_ooch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len) +static int put_logch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len) { - /* this is not equivalent to put_oocs(hcl,mask,&ch,1); + /* this is not equivalent to put_logcs(hcl,mask,&ch,1); * this function is to emit a single character multiple times */ hcl_oow_t rem; @@ -276,7 +276,7 @@ redo: return 1; /* success */ } -static int put_oocs (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hcl_oow_t len) +static int put_logcs (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hcl_oow_t len) { hcl_oow_t rem; @@ -424,8 +424,8 @@ hcl_ooi_t hcl_logbfmt (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...) } fo.mask = mask; - fo.putch = put_ooch; - fo.putcs = put_oocs; + fo.putch = put_logch; + fo.putcs = put_logcs; va_start (ap, fmt); x = _logbfmtv (hcl, fmt, &fo, ap); @@ -452,8 +452,8 @@ hcl_ooi_t hcl_logufmt (hcl_t* hcl, int mask, const hcl_uch_t* fmt, ...) } fo.mask = mask; - fo.putch = put_ooch; - fo.putcs = put_oocs; + fo.putch = put_logch; + fo.putcs = put_logcs; va_start (ap, fmt); x = _logufmtv (hcl, fmt, &fo, ap); @@ -472,26 +472,40 @@ hcl_ooi_t hcl_logufmt (hcl_t* hcl, int mask, const hcl_uch_t* fmt, ...) * HELPER FOR PRINTING * -------------------------------------------------------------------------- */ +static int put_prcs (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hcl_oow_t len) +{ + hcl_ooch_t* optr; + + optr = (hcl_ooch_t*)ptr; + while (len > 0) + { + hcl->c->outarg.ptr = optr; + hcl->c->outarg.len = len; + + if (hcl->c->printer(hcl, HCL_IO_WRITE, &hcl->c->outarg) <= -1) return -1; + if (hcl->c->outarg.xlen <= 0) return 0; /* end of stream. but not failure */ + + HCL_ASSERT (hcl, hcl->c->outarg.xlen <= len); + optr += hcl->c->outarg.xlen; + len -= hcl->c->outarg.xlen; + } + + return 1; /* success */ +} + static int put_prch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len) { -/* TODO: better error handling, buffering. - * should buffering be done by the printer callback? */ - hcl_ooi_t n; hcl_ooch_t str[256]; hcl_oow_t seglen, i; + int n; while (len > 0) { seglen = (len > HCL_COUNTOF(str))? len = HCL_COUNTOF(str): len; for (i = 0; i < seglen; i++) str[i] = ch; - hcl->c->outarg.ptr = str; - hcl->c->outarg.len = seglen; - - n = hcl->c->printer(hcl, HCL_IO_WRITE, &hcl->c->outarg); - - if (n <= -1) return -1; - if (n == 0) return 0; + n = put_prcs (hcl, mask, str, seglen); + if (n <= 0) return n; len -= seglen; } @@ -499,22 +513,6 @@ static int put_prch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len) return 1; /* success */ } -static int put_prcs (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hcl_oow_t len) -{ -/* TODO: better error handling, buffering - * should buffering be done by the printer callback? */ - hcl_ooi_t n; - - hcl->c->outarg.ptr = (hcl_ooch_t*)ptr; - hcl->c->outarg.len = len; - - n = hcl->c->printer(hcl, HCL_IO_WRITE, &hcl->c->outarg); - - if (n <= -1) return -1; - if (n == 0) return 0; - return 1; /* success */ -} - static hcl_ooi_t __prbfmtv (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...); static int _prbfmtv (hcl_t* hcl, const hcl_bch_t* fmt, hcl_fmtout_t* data, va_list ap) @@ -581,6 +579,22 @@ hcl_ooi_t hcl_proutufmt (hcl_t* hcl, int mask, const hcl_uch_t* fmt, ...) * ERROR MESSAGE FORMATTING * -------------------------------------------------------------------------- */ +static int put_errcs (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hcl_oow_t len) +{ + hcl_oow_t max; + + max = HCL_COUNTOF(hcl->errmsg.buf) - hcl->errmsg.len - 1; + if (len > max) len = max; + + if (len <= 0) return 1; + + HCL_MEMCPY (&hcl->errmsg.buf[hcl->errmsg.len], ptr, len * HCL_SIZEOF(*ptr)); + hcl->errmsg.len += len; + hcl->errmsg.buf[hcl->errmsg.len] = '\0'; + + return 1; /* success */ +} + static int put_errch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len) { hcl_oow_t max; @@ -600,23 +614,6 @@ static int put_errch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len) return 1; /* success */ } -static int put_errcs (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hcl_oow_t len) -{ - hcl_oow_t max; - - max = HCL_COUNTOF(hcl->errmsg.buf) - hcl->errmsg.len - 1; - if (len > max) len = max; - - if (len <= 0) return 1; - - HCL_MEMCPY (&hcl->errmsg.buf[hcl->errmsg.len], ptr, len * HCL_SIZEOF(*ptr)); - hcl->errmsg.len += len; - hcl->errmsg.buf[hcl->errmsg.len] = '\0'; - - return 1; /* success */ -} - - static hcl_ooi_t __errbfmtv (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...); static int _errbfmtv (hcl_t* hcl, const hcl_bch_t* fmt, hcl_fmtout_t* data, va_list ap) @@ -716,9 +713,8 @@ void hcl_seterrufmtv (hcl_t* hcl, hcl_errnum_t errnum, const hcl_uch_t* fmt, va_ _errufmtv (hcl, fmt, &fo, ap); } - /* -------------------------------------------------------------------------- - * SUPPORT FOR THE BUILTIN PRINTF PRIMITIVE FUNCTION + * SUPPORT FOR FORMATTED OUTPUT TO BE USED BY BUILTIN PRIMITIVE FUNCTIONS * -------------------------------------------------------------------------- */ #define PRINT_OOCH(c,n) do { \ @@ -749,7 +745,7 @@ void hcl_seterrufmtv (hcl_t* hcl, hcl_errnum_t errnum, const hcl_uch_t* fmt, va_ if (fmt >= fmtend) ch = HCL_OOCI_EOF; \ else { ch = *(fmt); (fmt)++; }\ } while(0) - + static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t* data, hcl_outbfmt_t outbfmt) { const hcl_ooch_t* fmt, * fmtend; @@ -1115,6 +1111,10 @@ oops: return -1; } +/* -------------------------------------------------------------------------- + * SUPPORT FOR THE BUILTIN PRINTF PRIMITIVE FUNCTION + * -------------------------------------------------------------------------- */ + int hcl_printfmtst (hcl_t* hcl, hcl_ooi_t nargs) { hcl_fmtout_t fo; @@ -1124,6 +1124,10 @@ int hcl_printfmtst (hcl_t* hcl, hcl_ooi_t nargs) return print_formatted(hcl, nargs, &fo, hcl_proutbfmt); } +/* -------------------------------------------------------------------------- + * SUPPORT FOR THE BUILTIN LOGF PRIMITIVE FUNCTION + * -------------------------------------------------------------------------- */ + int hcl_logfmtst (hcl_t* hcl, hcl_ooi_t nargs) { hcl_fmtout_t fo; @@ -1142,19 +1146,35 @@ int hcl_logfmtst (hcl_t* hcl, hcl_ooi_t nargs) fo.mask |= (hcl->log.default_type_mask & HCL_LOG_ALL_TYPES); } - fo.putch = put_ooch; - fo.putcs = put_oocs; + fo.putch = put_logch; + fo.putcs = put_logcs; return print_formatted(hcl, nargs, &fo, hcl_logbfmt); } - - - - - /* -------------------------------------------------------------------------- - * SUPPORT FOR THE BUILTIN PRINTF PRIMITIVE FUNCTION + * SUPPORT FOR THE BUILTIN SPRINTF PRIMITIVE FUNCTION * -------------------------------------------------------------------------- */ +static int put_sprcs (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hcl_oow_t len) +{ + if (hcl->sprintf.xbuf.len >= hcl->sprintf.xbuf.capa) + { + hcl_ooch_t* tmp; + hcl_oow_t newcapa; + + newcapa = hcl->sprintf.xbuf.len + len + 1; + newcapa = HCL_ALIGN_POW2(newcapa, 256); + + tmp = (hcl_ooch_t*)hcl_reallocmem(hcl, hcl->sprintf.xbuf.ptr, newcapa * HCL_SIZEOF(*tmp)); + if (!tmp) return -1; + + hcl->sprintf.xbuf.ptr = tmp; + hcl->sprintf.xbuf.capa = newcapa; + } + + HCL_MEMCPY (&hcl->sprintf.xbuf.ptr[hcl->sprintf.xbuf.len], ptr, len * HCL_SIZEOF(*ptr)); + hcl->sprintf.xbuf.len += len; + return 1; /* success */ +} static int put_sprch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len) { @@ -1182,28 +1202,6 @@ static int put_sprch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len) return 1; /* success */ } -static int put_sprcs (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hcl_oow_t len) -{ - if (hcl->sprintf.xbuf.len >= hcl->sprintf.xbuf.capa) - { - hcl_ooch_t* tmp; - hcl_oow_t newcapa; - - newcapa = hcl->sprintf.xbuf.len + len + 1; - newcapa = HCL_ALIGN_POW2(newcapa, 256); - - tmp = (hcl_ooch_t*)hcl_reallocmem(hcl, hcl->sprintf.xbuf.ptr, newcapa * HCL_SIZEOF(*tmp)); - if (!tmp) return -1; - - hcl->sprintf.xbuf.ptr = tmp; - hcl->sprintf.xbuf.capa = newcapa; - } - - HCL_MEMCPY (&hcl->sprintf.xbuf.ptr[hcl->sprintf.xbuf.len], ptr, len * HCL_SIZEOF(*ptr)); - hcl->sprintf.xbuf.len += len; - return 1; /* success */ -} - static hcl_ooi_t __sprbfmtv (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...); static int _sprbfmtv (hcl_t* hcl, const hcl_bch_t* fmt, hcl_fmtout_t* data, va_list ap) diff --git a/lib/main.c b/lib/main.c index 223e0c0..044788a 100644 --- a/lib/main.c +++ b/lib/main.c @@ -333,7 +333,9 @@ static HCL_INLINE hcl_ooi_t read_input (hcl_t* hcl, hcl_ioinarg_t* arg) remlen = bb->len - bcslen; if (remlen > 0) memmove (bb->buf, &bb->buf[bcslen], remlen); bb->len = remlen; - return ucslen; + + arg->xlen = ucslen; + return 0; } @@ -406,7 +408,7 @@ static HCL_INLINE hcl_ooi_t write_output (hcl_t* hcl, hcl_iooutarg_t* arg) #if defined(HCL_OOCH_IS_UCH) bcslen = HCL_COUNTOF(bcsbuf); ucslen = arg->len - donelen; - x = hcl_convootobchars (hcl, &arg->ptr[donelen], &ucslen, bcsbuf, &bcslen); + x = hcl_convootobchars(hcl, &arg->ptr[donelen], &ucslen, bcsbuf, &bcslen); if (x <= -1 && ucslen <= 0) return -1; #else bcslen = HCL_COUNTOF(bcsbuf); @@ -416,7 +418,7 @@ static HCL_INLINE hcl_ooi_t write_output (hcl_t* hcl, hcl_iooutarg_t* arg) hcl_copybchars (bcsbuf, &arg->ptr[donelen], bcslen); #endif - if (fwrite (bcsbuf, HCL_SIZEOF(bcsbuf[0]), bcslen, (FILE*)arg->handle) < bcslen) + if (fwrite(bcsbuf, HCL_SIZEOF(bcsbuf[0]), bcslen, (FILE*)arg->handle) < bcslen) { hcl_seterrnum (hcl, HCL_EIOERR); return -1; @@ -426,7 +428,8 @@ static HCL_INLINE hcl_ooi_t write_output (hcl_t* hcl, hcl_iooutarg_t* arg) } while (donelen < arg->len); - return arg->len; + arg->xlen = arg->len; + return 0; } static hcl_ooi_t print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg) diff --git a/lib/read.c b/lib/read.c index 7015151..25291cd 100644 --- a/lib/read.c +++ b/lib/read.c @@ -393,7 +393,6 @@ static HCL_INLINE void unget_char (hcl_t* hcl, const hcl_iolxc_t* c) static int get_char (hcl_t* hcl) { - hcl_ooi_t n; hcl_ooci_t lc; if (hcl->c->nungots > 0) @@ -416,10 +415,9 @@ static int get_char (hcl_t* hcl) if (hcl->c->curinp->b.pos >= hcl->c->curinp->b.len) { - n = hcl->c->reader (hcl, HCL_IO_READ, hcl->c->curinp); - if (n <= -1) return -1; - - if (n == 0) + if (hcl->c->reader(hcl, HCL_IO_READ, hcl->c->curinp) <= -1) return -1; + + if (hcl->c->curinp->xlen <= 0) { return_eof: hcl->c->curinp->lxc.c = HCL_OOCI_EOF; @@ -433,7 +431,7 @@ static int get_char (hcl_t* hcl) } hcl->c->curinp->b.pos = 0; - hcl->c->curinp->b.len = n; + hcl->c->curinp->b.len = hcl->c->curinp->xlen; } if (hcl->c->curinp->lxc.c == '\n' || hcl->c->curinp->lxc.c == '\r')