diff --git a/lib/comp.c b/lib/comp.c index 93f17de..390b13a 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -200,7 +200,7 @@ static int store_temporary_variable_count_for_block (hcl_t* hcl, hcl_oow_t tmpr_ newcapa = HCL_ALIGN(hcl->c->blk.depth + 1, BLK_INFO_BUFFER_ALIGN); tmp = (hcl_blk_info_t*)hcl_reallocmem(hcl, hcl->c->blk.info, newcapa * HCL_SIZEOF(*tmp)); - if (!tmp) return -1; + if (HCL_UNLIKELY(!tmp)) return -1; hcl->c->blk.info_capa = newcapa; hcl->c->blk.info = tmp; @@ -1755,6 +1755,7 @@ static int compile_try (hcl_t* hcl, hcl_cnode_t* src) /* (try * (perform this) * (perform that) + * (throw 10) * catch (x) * (perform xxx) * (perform yyy) diff --git a/lib/fmt.c b/lib/fmt.c index 3110ea7..4ca4265 100644 --- a/lib/fmt.c +++ b/lib/fmt.c @@ -2841,3 +2841,189 @@ int hcl_logfmtcallstack (hcl_t* hcl, hcl_ooi_t nargs) return format_stack_args(&fo, nargs, 0); } + + + +/* -------------------------------------------------------------------------- + * DYNAMIC STRING FORMATTING + * -------------------------------------------------------------------------- */ + +struct fmt_uch_buf_t +{ + hcl_t* hcl; + hcl_uch_t* ptr; + hcl_oow_t len; + hcl_oow_t capa; +}; +typedef struct fmt_uch_buf_t fmt_uch_buf_t; + +static int fmt_put_bchars_to_uch_buf (hcl_fmtout_t* fmtout, const hcl_bch_t* ptr, hcl_oow_t len) +{ + fmt_uch_buf_t* b = (fmt_uch_buf_t*)fmtout->ctx; + hcl_oow_t bcslen, ucslen; + int n; + + bcslen = len; + ucslen = b->capa - b->len; + n = hcl_conv_bchars_to_uchars_with_cmgr(ptr, &bcslen, &b->ptr[b->len], &ucslen, b->hcl->_cmgr, 1); + b->len += ucslen; + if (n <= -1) + { + if (n == -2) + { + return 0; /* buffer full. stop */ + } + else + { + hcl_seterrnum (b->hcl, HCL_EECERR); + return -1; + } + } + + return 1; /* success. carry on */ +} + +static int fmt_put_uchars_to_uch_buf (hcl_fmtout_t* fmtout, const hcl_uch_t* ptr, hcl_oow_t len) +{ + fmt_uch_buf_t* b = (fmt_uch_buf_t*)fmtout->ctx; + hcl_oow_t n; + + /* this function null-terminates the destination. so give the restored buffer size */ + n = hcl_copy_uchars_to_ucstr(&b->ptr[b->len], b->capa - b->len + 1, ptr, len); + b->len += n; + if (n < len) + { + hcl_seterrnum (b->hcl, HCL_EBUFFULL); + return 0; /* stop. insufficient buffer */ + } + + return 1; /* success */ +} + +hcl_oow_t hcl_vfmttoucstr (hcl_t* hcl, hcl_uch_t* buf, hcl_oow_t bufsz, const hcl_uch_t* fmt, va_list ap) +{ + hcl_fmtout_t fo; + fmt_uch_buf_t fb; + + if (bufsz <= 0) return 0; + + HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo)); + fo.mmgr = hcl->_mmgr; + fo.putbchars = fmt_put_bchars_to_uch_buf; + fo.putuchars = fmt_put_uchars_to_uch_buf; + fo.ctx = &fb; + + HCL_MEMSET (&fb, 0, HCL_SIZEOF(fb)); + fb.hcl = hcl; + fb.ptr = buf; + fb.capa = bufsz - 1; + + if (hcl_ufmt_outv(&fo, fmt, ap) <= -1) return -1; + + buf[fb.len] = '\0'; + return fb.len; +} + +hcl_oow_t hcl_fmttoucstr (hcl_t* hcl, hcl_uch_t* buf, hcl_oow_t bufsz, const hcl_uch_t* fmt, ...) +{ + hcl_oow_t x; + va_list ap; + + va_start (ap, fmt); + x = hcl_vfmttoucstr(hcl, buf, bufsz, fmt, ap); + va_end (ap); + + return x; +} + +/* ------------------------------------------------------------------------ */ + +struct fmt_bch_buf_t +{ + hcl_t* hcl; + hcl_bch_t* ptr; + hcl_oow_t len; + hcl_oow_t capa; +}; +typedef struct fmt_bch_buf_t fmt_bch_buf_t; + + +static int fmt_put_bchars_to_bch_buf (hcl_fmtout_t* fmtout, const hcl_bch_t* ptr, hcl_oow_t len) +{ + fmt_bch_buf_t* b = (fmt_bch_buf_t*)fmtout->ctx; + hcl_oow_t n; + + /* this function null-terminates the destination. so give the restored buffer size */ + n = hcl_copy_bchars_to_bcstr(&b->ptr[b->len], b->capa - b->len + 1, ptr, len); + b->len += n; + if (n < len) + { + hcl_seterrnum (b->hcl, HCL_EBUFFULL); + return 0; /* stop. insufficient buffer */ + } + + return 1; /* success */ +} + + +static int fmt_put_uchars_to_bch_buf (hcl_fmtout_t* fmtout, const hcl_uch_t* ptr, hcl_oow_t len) +{ + fmt_bch_buf_t* b = (fmt_bch_buf_t*)fmtout->ctx; + hcl_oow_t bcslen, ucslen; + int n; + + bcslen = b->capa - b->len; + ucslen = len; + n = hcl_conv_uchars_to_bchars_with_cmgr(ptr, &ucslen, &b->ptr[b->len], &bcslen, b->hcl->_cmgr); + b->len += bcslen; + if (n <= -1) + { + if (n == -2) + { + return 0; /* buffer full. stop */ + } + else + { + hcl_seterrnum (b->hcl, HCL_EECERR); + return -1; + } + } + + return 1; /* success. carry on */ +} + +hcl_oow_t hcl_vfmttobcstr (hcl_t* hcl, hcl_bch_t* buf, hcl_oow_t bufsz, const hcl_bch_t* fmt, va_list ap) +{ + hcl_fmtout_t fo; + fmt_bch_buf_t fb; + + if (bufsz <= 0) return 0; + + HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo)); + fo.mmgr = hcl->_mmgr; + fo.putbchars = fmt_put_bchars_to_bch_buf; + fo.putuchars = fmt_put_uchars_to_bch_buf; + fo.ctx = &fb; + + HCL_MEMSET (&fb, 0, HCL_SIZEOF(fb)); + fb.hcl = hcl; + fb.ptr = buf; + fb.capa = bufsz - 1; + + if (hcl_bfmt_outv(&fo, fmt, ap) <= -1) return -1; + + buf[fb.len] = '\0'; + return fb.len; +} + +hcl_oow_t hcl_fmttobcstr (hcl_t* hcl, hcl_bch_t* buf, hcl_oow_t bufsz, const hcl_bch_t* fmt, ...) +{ + hcl_oow_t x; + va_list ap; + + va_start (ap, fmt); + x = hcl_vfmttobcstr(hcl, buf, bufsz, fmt, ap); + va_end (ap); + + return x; +} diff --git a/lib/hcl.h b/lib/hcl.h index 7558f9e..98247e0 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -2221,6 +2221,53 @@ HCL_EXPORT hcl_ooi_t hcl_prufmtv ( # define hcl_proofmt hcl_prbfmt # define hcl_proofmtv hcl_prbfmtv #endif + + +/* ========================================================================= + * STRING FORMATTING + * ========================================================================= */ + +HCL_EXPORT hcl_oow_t hcl_vfmttoucstr ( + hcl_t* hcl, + hcl_uch_t* buf, + hcl_oow_t bufsz, + const hcl_uch_t* fmt, + va_list ap +); + +HCL_EXPORT hcl_oow_t hcl_fmttoucstr ( + hcl_t* hcl, + hcl_uch_t* buf, + hcl_oow_t bufsz, + const hcl_uch_t* fmt, + ... +); + +HCL_EXPORT hcl_oow_t hcl_vfmttobcstr ( + hcl_t* hcl, + hcl_bch_t* buf, + hcl_oow_t bufsz, + const hcl_bch_t* fmt, + va_list ap +); + +HCL_EXPORT hcl_oow_t hcl_fmttobcstr ( + hcl_t* hcl, + hcl_bch_t* buf, + hcl_oow_t bufsz, + const hcl_bch_t* fmt, + ... +); + +#if defined(HCL_OOCH_IS_UCH) +# define hcl_vfmttooocstr hcl_vfmttoucstr +# define hcl_fmttooocstr hcl_fmttoucstr +#else +# define hcl_vfmttooocstr hcl_vfmttobcstr +# define hcl_fmttooocstr hcl_fmttobcstr +#endif + + /* ========================================================================= * OBJECT MANAGEMENT * ========================================================================= */ diff --git a/lib/std.c b/lib/std.c index 6d6f847..3f61a13 100644 --- a/lib/std.c +++ b/lib/std.c @@ -2771,23 +2771,40 @@ static void cb_opt_set (hcl_t* hcl, hcl_option_t id, const void* value) #if defined(__OS2__) && defined(TCPV40HDRS) static int os2_socket_pair (int p[2]) { - int x, y, z; + int x = -1, y = -1, z; struct sockaddr_un sa; + PTIB tib; + PPIB pib; + ULONG pid, tid, msec; + + DosGetInfoBlocks(&tib, &pib); + DosQuerySysInfo (QSV_MS_COUNT, QSV_MS_COUNT, &msec, HCL_SIZEOF(msec)); x = socket(PF_OS2, SOCK_STREAM, 0); + if (x <= -1) goto oops; + + for (i = 0; i < 10000; i++) + { + HCL_MEMSET (&sa, 0, HCL_SIZEOF(sa)); + sa.sun_family = AF_OS2; + + /* OS/2 mandates the socket name should begin with \socket\ */ + sprintf (sa.sun_path, "\\socket\\hcl-%lu-%lu-%lu", (unsigned long int)pib->pib_ulpid, (unsigned long int)tib->tib_ultid, (unsigned long int)msec); + + if (bind(x, &sa, HCL_SIZEOF(sa)) <= -1) + { + msec++; + continue; + goto oops; + } + if (listen(x, 1) <= -1) goto oops; + } + y = socket(PF_OS2, SOCK_STREAM, 0); - if (x == -1 || y == -1) goto oops; - - HCL_MEMSET (&sa, 0, HCL_SIZEOF(sa)); - sa.sun_family = AF_OS2; - hcl_copy_bcstr (sa.sun_path, HCL_SIZEOF(sa.sun_path), "\\socket\\XXXXX"); /* TODO: make this address unique*/ - - if (bind(x, &sa, HCL_SIZEOF(sa)) == -1) goto oops; - if (listen(x, 1) == -1) goto oops; - - if (connect(y, &sa, HCL_SIZEOF(sa)) == -1) goto oops; + if (y <= -1) goto oops; + if (connect(y, &sa, HCL_SIZEOF(sa)) <= -1) goto oops; z = accept(x, HCL_NULL, HCL_NULL); - if (z == -1) goto oops; + if (z <= -1) goto oops; soclose (x); p[0] = z;