diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 74bfbe0..6906e52 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -10872,7 +10872,7 @@ static MOO_INLINE int _compile (moo_t* moo, moo_ioimpl_t io) /* Some IO names could have been stored in earlier calls to this function. * I clear such names before i begin this function. i don't clear it - * at the end of this function because i may be referenced as an error + * at the end of this function because it may be referenced as an error * location */ moo_clearcionames (moo); diff --git a/moo/lib/fmt.c b/moo/lib/fmt.c index bbffba0..ee49d00 100644 --- a/moo/lib/fmt.c +++ b/moo/lib/fmt.c @@ -2942,3 +2942,188 @@ int moo_strfmtcallstack (moo_t* moo, moo_ooi_t nargs, int rcv_is_fmtstr) moo->sprintf.xbuf.len = 0; return format_stack_args(&fo, nargs, rcv_is_fmtstr); } + + +/* -------------------------------------------------------------------------- + * DYNAMIC STRING FORMATTING + * -------------------------------------------------------------------------- */ + +struct fmt_uch_buf_t +{ + moo_t* moo; + moo_uch_t* ptr; + moo_oow_t len; + moo_oow_t capa; +}; +typedef struct fmt_uch_buf_t fmt_uch_buf_t; + +static int fmt_put_bchars_to_uch_buf (moo_fmtout_t* fmtout, const moo_bch_t* ptr, moo_oow_t len) +{ + fmt_uch_buf_t* b = (fmt_uch_buf_t*)fmtout->ctx; + moo_oow_t bcslen, ucslen; + int n; + + bcslen = len; + ucslen = b->capa - b->len; + n = moo_conv_bchars_to_uchars_with_cmgr(ptr, &bcslen, &b->ptr[b->len], &ucslen, b->moo->_cmgr, 1); + b->len += ucslen; + if (n <= -1) + { + if (n == -2) + { + return 0; /* buffer full. stop */ + } + else + { + moo_seterrnum (b->moo, MOO_EECERR); + return -1; + } + } + + return 1; /* success. carry on */ +} + +static int fmt_put_uchars_to_uch_buf (moo_fmtout_t* fmtout, const moo_uch_t* ptr, moo_oow_t len) +{ + fmt_uch_buf_t* b = (fmt_uch_buf_t*)fmtout->ctx; + moo_oow_t n; + + /* this function null-terminates the destination. so give the restored buffer size */ + n = moo_copy_uchars_to_ucstr(&b->ptr[b->len], b->capa - b->len + 1, ptr, len); + b->len += n; + if (n < len) + { + moo_seterrnum (b->moo, MOO_EBUFFULL); + return 0; /* stop. insufficient buffer */ + } + + return 1; /* success */ +} + +moo_oow_t moo_vfmttoucstr (moo_t* moo, moo_uch_t* buf, moo_oow_t bufsz, const moo_uch_t* fmt, va_list ap) +{ + moo_fmtout_t fo; + fmt_uch_buf_t fb; + + if (bufsz <= 0) return 0; + + MOO_MEMSET (&fo, 0, MOO_SIZEOF(fo)); + fo.mmgr = moo->_mmgr; + fo.putbchars = fmt_put_bchars_to_uch_buf; + fo.putuchars = fmt_put_uchars_to_uch_buf; + fo.ctx = &fb; + + MOO_MEMSET (&fb, 0, MOO_SIZEOF(fb)); + fb.moo = moo; + fb.ptr = buf; + fb.capa = bufsz - 1; + + if (moo_ufmt_outv(&fo, fmt, ap) <= -1) return -1; + + buf[fb.len] = '\0'; + return fb.len; +} + +moo_oow_t moo_fmttoucstr (moo_t* moo, moo_uch_t* buf, moo_oow_t bufsz, const moo_uch_t* fmt, ...) +{ + moo_oow_t x; + va_list ap; + + va_start (ap, fmt); + x = moo_vfmttoucstr(moo, buf, bufsz, fmt, ap); + va_end (ap); + + return x; +} + +/* ------------------------------------------------------------------------ */ + +struct fmt_bch_buf_t +{ + moo_t* moo; + moo_bch_t* ptr; + moo_oow_t len; + moo_oow_t capa; +}; +typedef struct fmt_bch_buf_t fmt_bch_buf_t; + + +static int fmt_put_bchars_to_bch_buf (moo_fmtout_t* fmtout, const moo_bch_t* ptr, moo_oow_t len) +{ + fmt_bch_buf_t* b = (fmt_bch_buf_t*)fmtout->ctx; + moo_oow_t n; + + /* this function null-terminates the destination. so give the restored buffer size */ + n = moo_copy_bchars_to_bcstr(&b->ptr[b->len], b->capa - b->len + 1, ptr, len); + b->len += n; + if (n < len) + { + moo_seterrnum (b->moo, MOO_EBUFFULL); + return 0; /* stop. insufficient buffer */ + } + + return 1; /* success */ +} + + +static int fmt_put_uchars_to_bch_buf (moo_fmtout_t* fmtout, const moo_uch_t* ptr, moo_oow_t len) +{ + fmt_bch_buf_t* b = (fmt_bch_buf_t*)fmtout->ctx; + moo_oow_t bcslen, ucslen; + int n; + + bcslen = b->capa - b->len; + ucslen = len; + n = moo_conv_uchars_to_bchars_with_cmgr(ptr, &ucslen, &b->ptr[b->len], &bcslen, b->moo->_cmgr); + b->len += bcslen; + if (n <= -1) + { + if (n == -2) + { + return 0; /* buffer full. stop */ + } + else + { + moo_seterrnum (b->moo, MOO_EECERR); + return -1; + } + } + + return 1; /* success. carry on */ +} + +moo_oow_t moo_vfmttobcstr (moo_t* moo, moo_bch_t* buf, moo_oow_t bufsz, const moo_bch_t* fmt, va_list ap) +{ + moo_fmtout_t fo; + fmt_bch_buf_t fb; + + if (bufsz <= 0) return 0; + + MOO_MEMSET (&fo, 0, MOO_SIZEOF(fo)); + fo.mmgr = moo->_mmgr; + fo.putbchars = fmt_put_bchars_to_bch_buf; + fo.putuchars = fmt_put_uchars_to_bch_buf; + fo.ctx = &fb; + + MOO_MEMSET (&fb, 0, MOO_SIZEOF(fb)); + fb.moo = moo; + fb.ptr = buf; + fb.capa = bufsz - 1; + + if (moo_bfmt_outv(&fo, fmt, ap) <= -1) return -1; + + buf[fb.len] = '\0'; + return fb.len; +} + +moo_oow_t moo_fmttobcstr (moo_t* moo, moo_bch_t* buf, moo_oow_t bufsz, const moo_bch_t* fmt, ...) +{ + moo_oow_t x; + va_list ap; + + va_start (ap, fmt); + x = moo_vfmttobcstr(moo, buf, bufsz, fmt, ap); + va_end (ap); + + return x; +} diff --git a/moo/lib/moo.c b/moo/lib/moo.c index cbabce1..ada6e5d 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -1179,193 +1179,3 @@ int moo_ischildclassof (moo_t* moo, moo_oop_class_t c, moo_oop_class_t k) return 0; } - - - - - - - - -/* ----------------------------------------------------------------------- */ - -struct fmt_bch_buf_t -{ - moo_t* moo; - moo_bch_t* ptr; - moo_oow_t len; - moo_oow_t capa; -}; -typedef struct fmt_bch_buf_t fmt_bch_buf_t; - - -static int fmt_put_bchars_to_bch_buf (moo_fmtout_t* fmtout, const moo_bch_t* ptr, moo_oow_t len) -{ - fmt_bch_buf_t* b = (fmt_bch_buf_t*)fmtout->ctx; - moo_oow_t n; - - /* this function null-terminates the destination. so give the restored buffer size */ - n = moo_copy_bchars_to_bcstr(&b->ptr[b->len], b->capa - b->len + 1, ptr, len); - b->len += n; - if (n < len) - { - moo_seterrnum (b->moo, MOO_EBUFFULL); - return 0; /* stop. insufficient buffer */ - } - - return 1; /* success */ -} - -static int fmt_put_uchars_to_bch_buf (moo_fmtout_t* fmtout, const moo_uch_t* ptr, moo_oow_t len) -{ - fmt_bch_buf_t* b = (fmt_bch_buf_t*)fmtout->ctx; - moo_oow_t bcslen, ucslen; - int n; - - bcslen = b->capa - b->len; - ucslen = len; - n = moo_conv_uchars_to_bchars_with_cmgr(ptr, &ucslen, &b->ptr[b->len], &bcslen, moo_getcmgr(b->moo)); - b->len += bcslen; - if (n <= -1) - { - if (n == -2) - { - return 0; /* buffer full. stop */ - } - else - { - moo_seterrnum (b->moo, MOO_EECERR); - return -1; - } - } - - return 1; /* success. carry on */ -} - -moo_oow_t moo_vfmttobcstr (moo_t* moo, moo_bch_t* buf, moo_oow_t bsz, const moo_bch_t* fmt, va_list ap) -{ - moo_fmtout_t fo; - fmt_bch_buf_t fb; - - if (bsz <= 0) return 0; - - MOO_MEMSET (&fo, 0, MOO_SIZEOF(fo)); - //fo.mmgr = moo_getmmgr(moo); - fo.putbchars = fmt_put_bchars_to_bch_buf; - fo.putuchars = fmt_put_uchars_to_bch_buf; - fo.ctx = &fb; - - MOO_MEMSET (&fb, 0, MOO_SIZEOF(fb)); - fb.moo = moo; - fb.ptr = buf; - fb.capa = bsz - 1; - - if (moo_bfmt_outv(&fo, fmt, ap) <= -1) return -1; - - buf[fb.len] = '\0'; - return fb.len; -} - -moo_oow_t moo_fmttobcstr (moo_t* moo, moo_bch_t* buf, moo_oow_t bufsz, const moo_bch_t* fmt, ...) -{ - moo_oow_t x; - va_list ap; - - va_start (ap, fmt); - x = moo_vfmttobcstr(moo, buf, bufsz, fmt, ap); - va_end (ap); - - return x; -} - -/* ----------------------------------------------------------------------- */ - -struct fmt_uch_buf_t -{ - moo_t* moo; - moo_uch_t* ptr; - moo_oow_t len; - moo_oow_t capa; -}; -typedef struct fmt_uch_buf_t fmt_uch_buf_t; - -static int fmt_put_bchars_to_uch_buf (moo_fmtout_t* fmtout, const moo_bch_t* ptr, moo_oow_t len) -{ - fmt_uch_buf_t* b = (fmt_uch_buf_t*)fmtout->ctx; - moo_oow_t bcslen, ucslen; - int n; - - bcslen = len; - ucslen = b->capa - b->len; - n = moo_conv_bchars_to_uchars_with_cmgr(ptr, &bcslen, &b->ptr[b->len], &ucslen, moo_getcmgr(b->moo), 1); - b->len += ucslen; - if (n <= -1) - { - if (n == -2) - { - return 0; /* buffer full. stop */ - } - else - { - moo_seterrnum (b->moo, MOO_EECERR); - return -1; - } - } - - return 1; /* success. carry on */ -} - -static int fmt_put_uchars_to_uch_buf (moo_fmtout_t* fmtout, const moo_uch_t* ptr, moo_oow_t len) -{ - fmt_uch_buf_t* b = (fmt_uch_buf_t*)fmtout->ctx; - moo_oow_t n; - - /* this function null-terminates the destination. so give the restored buffer size */ - n = moo_copy_uchars_to_ucstr(&b->ptr[b->len], b->capa - b->len + 1, ptr, len); - b->len += n; - if (n < len) - { - moo_seterrnum (b->moo, MOO_EBUFFULL); - return 0; /* stop. insufficient buffer */ - } - - return 1; /* success */ -} - - -moo_oow_t moo_vfmttoucstr (moo_t* moo, moo_uch_t* buf, moo_oow_t bsz, const moo_uch_t* fmt, va_list ap) -{ - moo_fmtout_t fo; - fmt_uch_buf_t fb; - - if (bsz <= 0) return 0; - - MOO_MEMSET (&fo, 0, MOO_SIZEOF(fo)); - //fo.mmgr = moo_getmmgr(moo); - fo.putbchars = fmt_put_bchars_to_uch_buf; - fo.putuchars = fmt_put_uchars_to_uch_buf; - fo.ctx = &fb; - - MOO_MEMSET (&fb, 0, MOO_SIZEOF(fb)); - fb.moo = moo; - fb.ptr = buf; - fb.capa = bsz - 1; - - if (moo_ufmt_outv(&fo, fmt, ap) <= -1) return -1; - - buf[fb.len] = '\0'; - return fb.len; -} - -moo_oow_t moo_fmttoucstr (moo_t* moo, moo_uch_t* buf, moo_oow_t bufsz, const moo_uch_t* fmt, ...) -{ - moo_oow_t x; - va_list ap; - - va_start (ap, fmt); - x = moo_vfmttoucstr(moo, buf, bufsz, fmt, ap); - va_end (ap); - - return x; -} - diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 166e8d9..4409e01 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -2826,6 +2826,50 @@ MOO_EXPORT moo_ooi_t moo_logufmtv ( # define moo_logoofmtv moo_logbfmtv #endif +/* ========================================================================= + * STRING FORMATTING + * ========================================================================= */ + +MOO_EXPORT moo_oow_t moo_vfmttoucstr ( + moo_t* moo, + moo_uch_t* buf, + moo_oow_t bufsz, + const moo_uch_t* fmt, + va_list ap +); + +MOO_EXPORT moo_oow_t moo_fmttoucstr ( + moo_t* moo, + moo_uch_t* buf, + moo_oow_t bufsz, + const moo_uch_t* fmt, + ... +); + +MOO_EXPORT moo_oow_t moo_vfmttobcstr ( + moo_t* moo, + moo_bch_t* buf, + moo_oow_t bufsz, + const moo_bch_t* fmt, + va_list ap +); + +MOO_EXPORT moo_oow_t moo_fmttobcstr ( + moo_t* moo, + moo_bch_t* buf, + moo_oow_t bufsz, + const moo_bch_t* fmt, + ... +); + +#if defined(MOO_OOCH_IS_UCH) +# define moo_vfmttooocstr moo_vfmttoucstr +# define moo_fmttooocstr moo_fmttoucstr +#else +# define moo_vfmttooocstr moo_vfmttobcstr +# define moo_fmttooocstr moo_fmttobcstr +#endif + /* ========================================================================= * MISCELLANEOUS HELPER FUNCTIONS * ========================================================================= */