diff --git a/hawk/lib/mod-hawk.c b/hawk/lib/mod-hawk.c index 98f17d77..9e71e904 100644 --- a/hawk/lib/mod-hawk.c +++ b/hawk/lib/mod-hawk.c @@ -147,6 +147,30 @@ static int fnc_function_exists (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx)); return 0; } +/* -------------------------------------------------------------------------- */ + +static int fnc_cmgr_exists (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) +{ + hawk_val_t* a0; + hawk_ooch_t* str; + hawk_oow_t len; + int rx; + + a0 = hawk_rtx_getarg(rtx, 0); + str = hawk_rtx_getvaloocstr(rtx, a0, &len); + if (HAWK_UNLIKELY(!str)) + { + rx = 0; + } + else + { + rx = (hawk_get_cmgr_by_name(str) != HAWK_NULL); + hawk_rtx_freevaloocstr (rtx, a0, str); + } + + hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, rx)); + return 0; +} /* -------------------------------------------------------------------------- */ @@ -364,6 +388,7 @@ static int fnc_typename (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) hawk_rtx_setretval (rtx, r); return 0; } + /* -------------------------------------------------------------------------- */ #if 0 static int pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk_fnc_info_t* fi) @@ -378,7 +403,7 @@ static int pack_data (hawk_rtx_t* rtx, const hawk_oocs_t* fmt, const hawk_fnc_in bp = buf; fmte = fmt->ptr + fmt->len; - for (fmtp = fmt,ptr; fmtp < fmte; fmtp++) + for (fmtp = fmt->ptr; fmtp < fmte; fmtp++) { switch (*fmtp) { @@ -581,6 +606,7 @@ static fnctab_t fnctab[] = /* keep this table sorted for binary search in query(). */ { HAWK_T("array"), { { 0, A_MAX, HAWK_NULL }, fnc_array, 0 } }, { HAWK_T("call"), { { 1, A_MAX, HAWK_T("vR") }, fnc_call, 0 } }, + { HAWK_T("cmgr_exists"), { { 1, 1, HAWK_NULL }, fnc_cmgr_exists, 0 } }, { HAWK_T("function_exists"), { { 1, 1, HAWK_NULL }, fnc_function_exists, 0 } }, { HAWK_T("gc"), { { 0, 1, HAWK_NULL }, fnc_gc, 0 } }, { HAWK_T("gcrefs"), { { 1, 1, HAWK_NULL }, fnc_gcrefs, 0 } }, diff --git a/hawk/lib/mod-str.c b/hawk/lib/mod-str.c index 4a425023..f02f7175 100644 --- a/hawk/lib/mod-str.c +++ b/hawk/lib/mod-str.c @@ -540,7 +540,17 @@ static int fnc_tombs (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) a0 = hawk_rtx_getarg(rtx, 0); switch (HAWK_RTX_GETVALTYPE(rtx, a0)) { + case HAWK_VAL_BCHR: + { + /* no conversion, but make it a byte string */ + hawk_bch_t tmp = HAWK_RTX_GETBCHRFROMVAL(rtx, a0); + r = hawk_rtx_makembsvalwithbchars(rtx, &tmp, 1); + if (HAWK_UNLIKELY(!r)) return -1; + break; + } + case HAWK_VAL_MBS: + /* no conversion */ r = a0; break; @@ -551,7 +561,7 @@ static int fnc_tombs (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) if (HAWK_UNLIKELY(!str.ptr)) return -1; r = hawk_rtx_makembsvalwithbcs(rtx, &str); hawk_rtx_freevalbcstr (rtx, a0, str.ptr); - if (!r) return -1; + if (HAWK_UNLIKELY(!r)) return -1; break; } } diff --git a/hawk/lib/utl-str.c b/hawk/lib/utl-str.c index ed849192..550fb9e0 100644 --- a/hawk/lib/utl-str.c +++ b/hawk/lib/utl-str.c @@ -3716,7 +3716,6 @@ hawk_cmgr_t* hawk_get_cmgr_by_id (hawk_cmgr_id_t id) return &builtin_cmgr[id]; } - static struct { const hawk_bch_t* name; diff --git a/hawk/lib/val.c b/hawk/lib/val.c index 19e41f83..4cc28eec 100644 --- a/hawk/lib/val.c +++ b/hawk/lib/val.c @@ -2222,22 +2222,47 @@ hawk_bch_t* hawk_rtx_valtobcstrdupwithcmgr (hawk_rtx_t* rtx, const hawk_val_t* v switch (vtype) { + case HAWK_VAL_BCHR: + { + hawk_bch_t tmp = HAWK_RTX_GETBCHRFROMVAL(rtx, v); + mbs = hawk_rtx_dupbchars(rtx, &v, 1); + if (!mbs) return HAWK_NULL; + if (len) *len = 1; + break; + } + case HAWK_VAL_MBS: mbs = hawk_rtx_dupbchars(rtx, ((hawk_val_mbs_t*)v)->val.ptr, ((hawk_val_mbs_t*)v)->val.len); if (!mbs) return HAWK_NULL; if (len) *len = ((hawk_val_mbs_t*)v)->val.len; break; + case HAWK_VAL_CHAR: case HAWK_VAL_STR: { + const hawk_ooch_t* ptr; + hawk_oow_t slen; + hawk_ooch_t tmp; + + if (vtype == HAWK_VAL_CHAR) + { + tmp = HAWK_RTX_GETCHARFROMVAL(rtx, v); + ptr = &tmp; + slen = 1; + } + else + { + ptr = ((hawk_val_str_t*)v)->val.ptr; + slen = ((hawk_val_str_t*)v)->val.len; + } #if defined(HAWK_OOCH_IS_BCH) - mbs = hawk_rtx_dupbchars(rtx, ((hawk_val_str_t*)v)->val.ptr, ((hawk_val_str_t*)v)->val.len); + mbs = hawk_rtx_dupbchars(rtx, (ptr, slen); if (!mbs) return HAWK_NULL; - if (len) *len = ((hawk_val_str_t*)v)->val.len; + if (len) *len = slen; #else hawk_oow_t mbslen, wcslen; - wcslen = ((hawk_val_str_t*)v)->val.len; - mbs = hawk_rtx_duputobcharswithcmgr(rtx, ((hawk_val_str_t*)v)->val.ptr, wcslen, &mbslen, cmgr); + wcslen = slen; + mbs = hawk_rtx_duputobcharswithcmgr(rtx, ptr, wcslen, &mbslen, cmgr); if (!mbs) return HAWK_NULL; if (len) *len = mbslen; #endif diff --git a/hawk/t/h-002.hawk b/hawk/t/h-002.hawk index 375f3d92..57536d85 100644 --- a/hawk/t/h-002.hawk +++ b/hawk/t/h-002.hawk @@ -378,7 +378,7 @@ function main() ensure (str::substr("☕Q⛄", 4) === "", 1, @SCRIPTNAME, @SCRIPTLINE); ensure (str::substr("☕Q⛄", 1, 2) === "☕Q", 1, @SCRIPTNAME, @SCRIPTLINE); ensure (str::substr("☕Q⛄", 1, 4) === "☕Q⛄", 1, @SCRIPTNAME, @SCRIPTLINE); - ###ensure (str::substr("☕Q⛄", -1, 1) === "⛄", 1, @SCRIPTNAME, @SCRIPTLINE); + ###ensure (str::substr("☕Q⛄", -1, 1) === "⛄", 1, @SCRIPTNAME, @SCRIPTLINE); ## not supported yet ensure (str::substr('☕', 1, 4) === "☕", 1, @SCRIPTNAME, @SCRIPTLINE); ensure (str::substr(@b"\xAD\xAA\xBB\CC", 2, 2) === @b"\xAA\xBB", 1, @SCRIPTNAME, @SCRIPTLINE);