diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index 1d91fde..79179c2 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -1063,6 +1063,11 @@ int hcl_logfmtst ( hcl_ooi_t nargs ); +int hcl_sprintfmtst ( + hcl_t* hcl, + hcl_ooi_t nargs +); + #if defined(__cplusplus) } #endif diff --git a/lib/hcl.c b/lib/hcl.c index 24bde46..ce8e81c 100644 --- a/lib/hcl.c +++ b/lib/hcl.c @@ -276,6 +276,14 @@ void hcl_fini (hcl_t* hcl) hcl->inttostr.t.ptr = HCL_NULL; hcl->inttostr.t.capa = 0; } + + if (hcl->sprintf.xbuf.ptr) + { + hcl_freemem (hcl, hcl->sprintf.xbuf.ptr); + hcl->sprintf.xbuf.ptr = HCL_NULL; + hcl->sprintf.xbuf.capa = 0; + hcl->sprintf.xbuf.len = 0; + } } void hcl_clear (hcl_t* hcl, int flags) diff --git a/lib/hcl.h b/lib/hcl.h index dbde917..385b80b 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -1082,6 +1082,16 @@ struct hcl_t } inttostr; /* == END BIGINT CONVERSION == */ + struct + { + struct + { + hcl_ooch_t* ptr; + hcl_oow_t capa; + hcl_oow_t len; + } xbuf; /* buffer to support sprintf */ + } sprintf; + hcl_sbuf_t sbuf[64]; struct diff --git a/lib/logfmt.c b/lib/logfmt.c index 3ddbe4b..c3ddbcc 100644 --- a/lib/logfmt.c +++ b/lib/logfmt.c @@ -532,7 +532,7 @@ static hcl_ooi_t __prbfmtv (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...) va_list ap; hcl_fmtout_t fo; - fo.mask = 0; /* not used */ + fo.mask = mask; fo.putch = put_prch; fo.putcs = put_prcs; @@ -549,7 +549,7 @@ hcl_ooi_t hcl_proutbfmt (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...) va_list ap; hcl_fmtout_t fo; - fo.mask = 0; /* not used */ + fo.mask = mask; fo.putch = put_prch; fo.putcs = put_prcs; @@ -566,7 +566,7 @@ hcl_ooi_t hcl_proutufmt (hcl_t* hcl, int mask, const hcl_uch_t* fmt, ...) va_list ap; hcl_fmtout_t fo; - fo.mask = 0; /* not used */ + fo.mask = mask; fo.putch = put_prch; fo.putcs = put_prcs; @@ -634,7 +634,7 @@ static hcl_ooi_t __errbfmtv (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...) va_list ap; hcl_fmtout_t fo; - fo.mask = 0; /* not used */ + fo.mask = mask; fo.putch = put_errch; fo.putcs = put_errcs; @@ -1146,3 +1146,134 @@ int hcl_logfmtst (hcl_t* hcl, hcl_ooi_t nargs) fo.putcs = put_oocs; return print_formatted(hcl, nargs, &fo, hcl_logbfmt); } + + + + + + +/* -------------------------------------------------------------------------- + * SUPPORT FOR THE BUILTIN PRINTF PRIMITIVE FUNCTION + * -------------------------------------------------------------------------- */ + +static int put_sprch (hcl_t* hcl, int mask, hcl_ooch_t ch, 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; + } + + while (len > 0) + { + --len; + hcl->sprintf.xbuf.ptr[hcl->sprintf.xbuf.len++] = ch; + } + + 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) +{ + return __logbfmtv (hcl, fmt, data, ap, __sprbfmtv); +} + +/* +static int _sprufmtv (hcl_t* hcl, const hcl_uch_t* fmt, hcl_fmtout_t* data, va_list ap) +{ + return __logufmtv (hcl, fmt, data, ap, __sprbfmtv); +}*/ + +static hcl_ooi_t __sprbfmtv (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...) +{ + va_list ap; + hcl_fmtout_t fo; + + fo.mask = mask; /* not used */ + fo.putch = put_sprch; + fo.putcs = put_sprcs; + + va_start (ap, fmt); + _sprbfmtv (hcl, fmt, &fo, ap); + va_end (ap); + + return fo.count; +} + +hcl_ooi_t hcl_sproutbfmt (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...) +{ + int x; + va_list ap; + hcl_fmtout_t fo; + + fo.mask = mask; + fo.putch = put_sprch; + fo.putcs = put_sprcs; + + va_start (ap, fmt); + x = _sprbfmtv (hcl, fmt, &fo, ap); + va_end (ap); + + return (x <= -1)? -1: fo.count; +} + +/* +hcl_ooi_t hcl_sproutufmt (hcl_t* hcl, int mask, const hcl_uch_t* fmt, ...) +{ + int x; + va_list ap; + hcl_fmtout_t fo; + + fo.mask = mask; + fo.putch = put_sprch; + fo.putcs = put_sprcs; + + va_start (ap, fmt); + x = _sprufmtv (hcl, fmt, &fo, ap); + va_end (ap); + + return (x <= -1)? -1: fo.count; +}*/ + +int hcl_sprintfmtst (hcl_t* hcl, hcl_ooi_t nargs) +{ + hcl_fmtout_t fo; + HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo)); + fo.putch = put_sprch; + fo.putcs = put_sprcs; + hcl->sprintf.xbuf.len = 0; + return print_formatted(hcl, nargs, &fo, hcl_sproutbfmt); +} diff --git a/lib/prim.c b/lib/prim.c index 1b41825..6ce86fa 100644 --- a/lib/prim.c +++ b/lib/prim.c @@ -197,6 +197,25 @@ static hcl_pfrc_t pf_printf (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) return HCL_PF_SUCCESS; } +static hcl_pfrc_t pf_sprintf (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) +{ + if (hcl_sprintfmtst(hcl, nargs) <= -1) + { + HCL_STACK_SETRETTOERRNUM (hcl, nargs); + } + else + { + hcl_oop_t str; + str = hcl_makestring (hcl, hcl->sprintf.xbuf.ptr, hcl->sprintf.xbuf.len, 0); + if (!str) return HCL_PF_FAILURE; + + HCL_STACK_SETRET (hcl, nargs, str); + } + + return HCL_PF_SUCCESS; +} + + static hcl_pfrc_t pf_gc (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) { @@ -413,6 +432,7 @@ static pf_t builtin_prims[] = { 0, HCL_TYPE_MAX(hcl_oow_t), pf_log, 3, { 'l','o','g' } }, { 1, HCL_TYPE_MAX(hcl_oow_t), pf_logf, 4, { 'l','o','g','f' } }, { 1, HCL_TYPE_MAX(hcl_oow_t), pf_printf, 6, { 'p','r','i','n','t','f' } }, + { 1, HCL_TYPE_MAX(hcl_oow_t), pf_sprintf, 7, { 's','p','r','i','n','t','f' } }, { 0, 0, pf_gc, 2, { 'g','c' } },