changed the hcl_ioimpl_t prototype to return 'int' instead of 'hcl_ooi_t'.

changed the io arguments to have a new 'xlen' field that holds the result of IO operations where 0 means end of stream
This commit is contained in:
hyung-hwan 2018-03-09 05:05:09 +00:00
parent a60bd0c898
commit 3acdae2cdf
4 changed files with 128 additions and 98 deletions

View File

@ -790,9 +790,14 @@ struct hcl_ioinarg_t
void* handle; 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 * [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 -------------------*/ /*----------- from here down, internal use only -------------------*/
struct struct
{ {
int pos, len, state; hcl_oow_t pos;
hcl_oow_t len;
int state;
} b; } b;
unsigned long int line; unsigned long int line;
@ -818,12 +825,36 @@ struct hcl_ioinarg_t
typedef struct hcl_iooutarg_t hcl_iooutarg_t; typedef struct hcl_iooutarg_t hcl_iooutarg_t;
struct 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; void* handle;
/**
* [IN] the pointer to the beginning of the character string
* to write
*/
hcl_ooch_t* ptr; 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_t* hcl,
hcl_iocmd_t cmd, hcl_iocmd_t cmd,
void* arg /* hcl_ioinarg_t* or hcl_iooutarg_t* */ void* arg /* hcl_ioinarg_t* or hcl_iooutarg_t* */

View File

@ -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 */ * this function is to emit a single character multiple times */
hcl_oow_t rem; hcl_oow_t rem;
@ -276,7 +276,7 @@ redo:
return 1; /* success */ 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; 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.mask = mask;
fo.putch = put_ooch; fo.putch = put_logch;
fo.putcs = put_oocs; fo.putcs = put_logcs;
va_start (ap, fmt); va_start (ap, fmt);
x = _logbfmtv (hcl, fmt, &fo, ap); 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.mask = mask;
fo.putch = put_ooch; fo.putch = put_logch;
fo.putcs = put_oocs; fo.putcs = put_logcs;
va_start (ap, fmt); va_start (ap, fmt);
x = _logufmtv (hcl, fmt, &fo, ap); 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 * 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) 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_ooch_t str[256];
hcl_oow_t seglen, i; hcl_oow_t seglen, i;
int n;
while (len > 0) while (len > 0)
{ {
seglen = (len > HCL_COUNTOF(str))? len = HCL_COUNTOF(str): len; seglen = (len > HCL_COUNTOF(str))? len = HCL_COUNTOF(str): len;
for (i = 0; i < seglen; i++) str[i] = ch; for (i = 0; i < seglen; i++) str[i] = ch;
hcl->c->outarg.ptr = str; n = put_prcs (hcl, mask, str, seglen);
hcl->c->outarg.len = seglen; if (n <= 0) return n;
n = hcl->c->printer(hcl, HCL_IO_WRITE, &hcl->c->outarg);
if (n <= -1) return -1;
if (n == 0) return 0;
len -= seglen; 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 */ 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 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) 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 * 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) static int put_errch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len)
{ {
hcl_oow_t max; 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 */ 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 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) 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); _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 { \ #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; \ if (fmt >= fmtend) ch = HCL_OOCI_EOF; \
else { ch = *(fmt); (fmt)++; }\ else { ch = *(fmt); (fmt)++; }\
} while(0) } while(0)
static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t* data, hcl_outbfmt_t outbfmt) 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; const hcl_ooch_t* fmt, * fmtend;
@ -1115,6 +1111,10 @@ oops:
return -1; return -1;
} }
/* --------------------------------------------------------------------------
* SUPPORT FOR THE BUILTIN PRINTF PRIMITIVE FUNCTION
* -------------------------------------------------------------------------- */
int hcl_printfmtst (hcl_t* hcl, hcl_ooi_t nargs) int hcl_printfmtst (hcl_t* hcl, hcl_ooi_t nargs)
{ {
hcl_fmtout_t fo; 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); 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) int hcl_logfmtst (hcl_t* hcl, hcl_ooi_t nargs)
{ {
hcl_fmtout_t fo; 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.mask |= (hcl->log.default_type_mask & HCL_LOG_ALL_TYPES);
} }
fo.putch = put_ooch; fo.putch = put_logch;
fo.putcs = put_oocs; fo.putcs = put_logcs;
return print_formatted(hcl, nargs, &fo, hcl_logbfmt); 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) 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 */ 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 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) static int _sprbfmtv (hcl_t* hcl, const hcl_bch_t* fmt, hcl_fmtout_t* data, va_list ap)

View File

@ -333,7 +333,9 @@ static HCL_INLINE hcl_ooi_t read_input (hcl_t* hcl, hcl_ioinarg_t* arg)
remlen = bb->len - bcslen; remlen = bb->len - bcslen;
if (remlen > 0) memmove (bb->buf, &bb->buf[bcslen], remlen); if (remlen > 0) memmove (bb->buf, &bb->buf[bcslen], remlen);
bb->len = 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) #if defined(HCL_OOCH_IS_UCH)
bcslen = HCL_COUNTOF(bcsbuf); bcslen = HCL_COUNTOF(bcsbuf);
ucslen = arg->len - donelen; 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; if (x <= -1 && ucslen <= 0) return -1;
#else #else
bcslen = HCL_COUNTOF(bcsbuf); 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); hcl_copybchars (bcsbuf, &arg->ptr[donelen], bcslen);
#endif #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); hcl_seterrnum (hcl, HCL_EIOERR);
return -1; 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); 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) static hcl_ooi_t print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)

View File

@ -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) static int get_char (hcl_t* hcl)
{ {
hcl_ooi_t n;
hcl_ooci_t lc; hcl_ooci_t lc;
if (hcl->c->nungots > 0) 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) if (hcl->c->curinp->b.pos >= hcl->c->curinp->b.len)
{ {
n = hcl->c->reader (hcl, HCL_IO_READ, hcl->c->curinp); if (hcl->c->reader(hcl, HCL_IO_READ, hcl->c->curinp) <= -1) return -1;
if (n <= -1) return -1;
if (hcl->c->curinp->xlen <= 0)
if (n == 0)
{ {
return_eof: return_eof:
hcl->c->curinp->lxc.c = HCL_OOCI_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.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') if (hcl->c->curinp->lxc.c == '\n' || hcl->c->curinp->lxc.c == '\r')