enhanced the concat operator handler to process mbs properly

This commit is contained in:
hyung-hwan 2020-12-09 04:02:04 +00:00
parent 1d83f8cfe7
commit 2e25911bfd
7 changed files with 227 additions and 78 deletions

View File

@ -594,7 +594,7 @@ static HAWK_INLINE void HAWK_RTX_STACK_POP (hawk_rtx_t* rtx)
(refval)->v_type = HAWK_VAL_REF; \
(refval)->v_refs = (_nrefs); \
(refval)->v_static = 0; \
(refval)->nstr = 0; \
(refval)->v_nstr = 0; \
(refval)->v_gc = 0; \
(refval)->id = (_id); \
(refval)->adr = (_adr); \

View File

@ -161,21 +161,22 @@ static HAWK_INLINE hawk_gch_t* hawk_val_to_gch(hawk_val_t* v)
* - v_type - type of a value from #hawk_val_type_t
* - v_refs - reference count
* - v_static - static value indicator
* - nstr - numeric string marker, 1 -> integer, 2 -> floating-point number
* - v_nstr - numeric string marker, 1 -> integer, 2 -> floating-point number
* - v_gc - used for garbage collection together with v_refs
*/
/*
#define HAWK_VAL_HDR \
unsigned int v_type: 4; \
unsigned int v_refs: 24; \
unsigned int v_static: 1; \
unsigned int nstr: 2; \
unsigned int v_nstr: 2; \
unsigned int v_gc: 1
*/
#define HAWK_VAL_HDR \
hawk_uintptr_t v_type: 4; \
hawk_uintptr_t v_refs: ((HAWK_SIZEOF_UINTPTR_T * 8) - 8); \
hawk_uintptr_t v_static: 1; \
hawk_uintptr_t nstr: 2; \
hawk_uintptr_t v_nstr: 2; \
hawk_uintptr_t v_gc: 1
/**
@ -2841,28 +2842,44 @@ HAWK_EXPORT hawk_val_t* hawk_rtx_makenstrvalwithbcs (
* The hawk_rtx_makembsvalwithbchars() function create a byte array value.
* \return value on success, #HAWK_NULL on failure
*/
hawk_val_t* hawk_rtx_makembsvalwithbchars (
HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithbchars (
hawk_rtx_t* rtx,
const hawk_bch_t* ptr,
hawk_oow_t len
);
hawk_val_t* hawk_rtx_makembsvalwithuchars (
HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithuchars (
hawk_rtx_t* rtx,
const hawk_uch_t* ptr,
hawk_oow_t len
);
hawk_val_t* hawk_rtx_makembsvalwithbcs (
HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithbcs (
hawk_rtx_t* rtx,
const hawk_bcs_t* bcs
);
hawk_val_t* hawk_rtx_makembsvalwithucs (
HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithucs (
hawk_rtx_t* rtx,
const hawk_ucs_t* ucs
);
HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithuchars2 (
hawk_rtx_t* rtx,
const hawk_uch_t* ucs1,
hawk_oow_t len1,
const hawk_uch_t* ucs2,
hawk_oow_t len2
);
HAWK_EXPORT hawk_val_t* hawk_rtx_makembsvalwithbchars2 (
hawk_rtx_t* rtx,
const hawk_bch_t* bcs1,
hawk_oow_t len1,
const hawk_bch_t* bcs2,
hawk_oow_t len2
);
/* -------------------------------------------------------------------------- */
HAWK_EXPORT hawk_val_t* hawk_rtx_makenumormbsvalwithuchars (

View File

@ -250,7 +250,10 @@ static int fnc_isxdigit (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
static int fnc_fromcharcode (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
/* create a string from a series of charcter codes */
/* create a string from a series of character codes.
* create a character from a single character code.
* - str::fromcharcode(65) for 'A'
* - str::fromcharcode(65, 66, 67) for "ABC" */
hawk_val_t* retv;
hawk_oow_t nargs, i;
@ -258,8 +261,21 @@ static int fnc_fromcharcode (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
nargs = hawk_rtx_getnargs(rtx);
if (nargs == 1)
{
hawk_val_t* a0;
hawk_int_t cc;
a0 = hawk_rtx_getarg(rtx, 0);
if (hawk_rtx_valtoint(rtx, a0, &cc) <= -1) return -1;
retv = hawk_rtx_makecharval(rtx, (hawk_ooch_t)cc);
if (HAWK_UNLIKELY(!retv)) return -1;
}
else
{
retv = hawk_rtx_makestrvalwithoochars(rtx, HAWK_NULL, nargs);
if (!retv) return -1;
if (HAWK_UNLIKELY(!retv)) return -1;
ptr0 = (hawk_oochu_t*)((hawk_val_str_t*)retv)->val.ptr;
@ -277,6 +293,7 @@ static int fnc_fromcharcode (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
ptr0[i] = cc;
}
}
hawk_rtx_setretval (rtx, retv);
return 0;
@ -466,7 +483,7 @@ done:
static int fnc_tonum (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
/* str::tonum(value) */
/* str::tonum(string, base) */
/* str::tonum(string/character, base) */
/*hawk_t* hawk = hawk_rtx_gethawk(rtx);*/
hawk_val_t* retv;

View File

@ -4772,8 +4772,8 @@ static HAWK_INLINE int __cmp_int_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
hawk_oow_t len0;
int n;
/* SCO CC doesn't seem to handle right->nstr > 0 properly */
if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->nstr /*> 0*/)
/* SCO CC doesn't seem to handle right->v_nstr > 0 properly */
if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->v_nstr /*> 0*/)
{
hawk_int_t ll, v1;
hawk_flt_t rr;
@ -4813,7 +4813,7 @@ static HAWK_INLINE int __cmp_int_mbs (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
hawk_oow_t len0;
int n;
if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->nstr /*> 0*/)
if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->v_nstr /*> 0*/)
{
hawk_int_t ll, v1;
hawk_flt_t rr;
@ -4902,8 +4902,8 @@ static HAWK_INLINE int __cmp_flt_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
hawk_oow_t len0;
int n;
/* SCO CC doesn't seem to handle right->nstr > 0 properly */
if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->nstr /*> 0*/)
/* SCO CC doesn't seem to handle right->v_nstr > 0 properly */
if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->v_nstr /*> 0*/)
{
const hawk_ooch_t* end;
hawk_flt_t rr;
@ -4931,7 +4931,7 @@ static HAWK_INLINE int __cmp_flt_mbs (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
hawk_oow_t len0;
int n;
if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->nstr /*> 0*/)
if ((hawk->opt.trait & HAWK_NCMPONSTR) || right->v_nstr /*> 0*/)
{
const hawk_bch_t* end;
hawk_flt_t rr;
@ -5005,7 +5005,7 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
ls = (hawk_val_str_t*)left;
rs = (hawk_val_str_t*)right;
if (HAWK_LIKELY(ls->nstr == 0 || rs->nstr == 0))
if (HAWK_LIKELY(ls->v_nstr == 0 || rs->v_nstr == 0))
{
/* both are definitely strings */
return hawk_comp_oochars(ls->val.ptr, ls->val.len, rs->val.ptr, rs->val.len, rtx->gbl.ignorecase);
@ -5013,13 +5013,13 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
stripspc = HAWK_RTX_IS_STRIPSTRSPC_ON(rtx);
if (ls->nstr == 1)
if (ls->v_nstr == 1)
{
hawk_int_t ll;
ll = hawk_oochars_to_int(ls->val.ptr, ls->val.len, HAWK_OOCHARS_TO_INT_MAKE_OPTION(stripspc, stripspc, 0), HAWK_NULL, HAWK_NULL);
if (rs->nstr == 1)
if (rs->v_nstr == 1)
{
hawk_int_t rr;
@ -5032,7 +5032,7 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
{
hawk_flt_t rr;
HAWK_ASSERT (rs->nstr == 2);
HAWK_ASSERT (rs->v_nstr == 2);
rr = hawk_oochars_to_flt(rs->val.ptr, rs->val.len, HAWK_NULL, stripspc);
@ -5044,11 +5044,11 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
{
hawk_flt_t ll;
HAWK_ASSERT (ls->nstr == 2);
HAWK_ASSERT (ls->v_nstr == 2);
ll = hawk_oochars_to_flt(ls->val.ptr, ls->val.len, HAWK_NULL, stripspc);
if (rs->nstr == 1)
if (rs->v_nstr == 1)
{
hawk_int_t rr;
@ -5061,7 +5061,7 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va
{
hawk_flt_t rr;
HAWK_ASSERT (rs->nstr == 2);
HAWK_ASSERT (rs->v_nstr == 2);
rr = hawk_oochars_to_flt(rs->val.ptr, rs->val.len, HAWK_NULL, stripspc);
@ -5786,26 +5786,46 @@ static hawk_val_t* eval_binop_exp (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t
static hawk_val_t* eval_binop_concat (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right)
{
hawk_val_t* res;
hawk_rtx_valtostr_out_t lout, rout;
lout.type = HAWK_RTX_VALTOSTR_CPLDUP;
if (hawk_rtx_valtostr(rtx, left, &lout) <= -1) return HAWK_NULL;
rout.type = HAWK_RTX_VALTOSTR_CPLDUP;
if (hawk_rtx_valtostr(rtx, right, &rout) <= -1)
if (HAWK_RTX_GETVALTYPE(rtx, left) == HAWK_VAL_MBS)
{
hawk_rtx_freemem (rtx, lout.u.cpldup.ptr);
hawk_bcs_t l, r;
l.ptr = hawk_rtx_getvalbcstr(rtx, left, &l.len);
if (HAWK_UNLIKELY(!l.ptr)) return HAWK_NULL;
r.ptr = hawk_rtx_getvalbcstr(rtx, right, &r.len);
if (HAWK_UNLIKELY(!r.ptr))
{
hawk_rtx_freevalbcstr (rtx, left, l.ptr);
return HAWK_NULL;
}
res = hawk_rtx_makestrvalwithoochars2(
rtx,
lout.u.cpldup.ptr, lout.u.cpldup.len,
rout.u.cpldup.ptr, rout.u.cpldup.len
);
res = (hawk_val_t*)hawk_rtx_makembsvalwithbchars2(rtx, l.ptr, l.len, r.ptr, r.len);
hawk_rtx_freemem (rtx, rout.u.cpldup.ptr);
hawk_rtx_freemem (rtx, lout.u.cpldup.ptr);
hawk_rtx_freevalbcstr (rtx, right, r.ptr);
hawk_rtx_freevalbcstr (rtx, left, l.ptr);
}
else
{
hawk_oocs_t l, r;
l.ptr = hawk_rtx_getvaloocstr(rtx, left, &l.len);
if (HAWK_UNLIKELY(!l.ptr)) return HAWK_NULL;
r.ptr = hawk_rtx_getvaloocstr(rtx, right, &r.len);
if (HAWK_UNLIKELY(!r.ptr))
{
hawk_rtx_freevaloocstr (rtx, left, l.ptr);
return HAWK_NULL;
}
res = (hawk_val_t*)hawk_rtx_makestrvalwithoochars2(rtx, l.ptr, l.len, r.ptr, r.len);
hawk_rtx_freevaloocstr (rtx, right, r.ptr);
hawk_rtx_freevaloocstr (rtx, left, l.ptr);
}
return res;
}

View File

@ -2187,7 +2187,7 @@ static const hawk_uch_t* scan_dollar_for_subst_u (const hawk_uch_t* f, hawk_oow_
HAWK_ASSERT (l >= 2);
f += 2; /* skip ${ */
if (ident) ident->ptr = f;
if (ident) ident->ptr = (hawk_uch_t*)f;
while (1)
{
@ -2208,7 +2208,7 @@ static const hawk_uch_t* scan_dollar_for_subst_u (const hawk_uch_t* f, hawk_oow_
f += 2; /* skip := */
if (dfl) dfl->ptr = f;
if (dfl) dfl->ptr = (hawk_uch_t*)f;
while (1)
{
if (f >= end) return HAWK_NULL;
@ -2340,7 +2340,7 @@ static const hawk_bch_t* scan_dollar_for_subst_b (const hawk_bch_t* f, hawk_oow_
HAWK_ASSERT (l >= 2);
f += 2; /* skip ${ */
if (ident) ident->ptr = f;
if (ident) ident->ptr = (hawk_bch_t*)f;
while (1)
{
@ -2361,7 +2361,7 @@ static const hawk_bch_t* scan_dollar_for_subst_b (const hawk_bch_t* f, hawk_oow_
f += 2; /* skip := */
if (dfl) dfl->ptr = f;
if (dfl) dfl->ptr = (hawk_bch_t*)f;
while (1)
{
if (f >= end) return HAWK_NULL;

View File

@ -533,7 +533,7 @@ hawk_val_t* hawk_rtx_makeintval (hawk_rtx_t* rtx, hawk_int_t v)
val->v_type = HAWK_VAL_INT;
val->v_refs = 0;
val->v_static = 0;
val->nstr = 0;
val->v_nstr = 0;
val->v_gc = 0;
val->i_val = v;
val->nde = HAWK_NULL;
@ -572,7 +572,7 @@ hawk_val_t* hawk_rtx_makefltval (hawk_rtx_t* rtx, hawk_flt_t v)
val->v_type = HAWK_VAL_FLT;
val->v_refs = 0;
val->v_static = 0;
val->nstr = 0;
val->v_nstr = 0;
val->v_gc = 0;
val->val = v;
val->nde = HAWK_NULL;
@ -615,7 +615,7 @@ init:
val->v_type = HAWK_VAL_STR;
val->v_refs = 0;
val->v_static = 0;
val->nstr = 0;
val->v_nstr = 0;
val->v_gc = 0;
val->val.len = len1 + len2;
val->val.ptr = (hawk_ooch_t*)(val + 1);
@ -775,7 +775,7 @@ hawk_val_t* hawk_rtx_makenstrvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_t* p
/* set the numeric string flag if a string
* can be converted to a number */
HAWK_ASSERT (x == 0 || x == 1);
v->nstr = x + 1; /* long -> 1, real -> 2 */
v->v_nstr = x + 1; /* long -> 1, real -> 2 */
}
return v;
@ -797,7 +797,7 @@ hawk_val_t* hawk_rtx_makenstrvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_t* p
/* set the numeric string flag if a string
* can be converted to a number */
HAWK_ASSERT (x == 0 || x == 1);
v->nstr = x + 1; /* long -> 1, real -> 2 */
v->v_nstr = x + 1; /* long -> 1, real -> 2 */
}
return v;
@ -825,17 +825,16 @@ hawk_val_t* hawk_rtx_makenstrvalwithbcs (hawk_rtx_t* rtx, const hawk_bcs_t* str)
/* --------------------------------------------------------------------- */
hawk_val_t* hawk_rtx_makembsvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_t* ptr, hawk_oow_t len)
static HAWK_INLINE hawk_val_t* make_mbs_val (hawk_rtx_t* rtx, const hawk_bch_t* mbs1, hawk_oow_t len1, const hawk_bch_t* mbs2, hawk_oow_t len2)
{
hawk_val_mbs_t* val;
hawk_val_mbs_t* val = HAWK_NULL;
hawk_oow_t aligned_len;
#if defined(HAWK_ENABLE_MBS_CACHE)
hawk_oow_t i;
#endif
if (HAWK_UNLIKELY(len <= 0)) return hawk_val_zlm;
aligned_len = HAWK_ALIGN_POW2((len + 1), HAWK_MBS_CACHE_BLOCK_UNIT);
if (HAWK_UNLIKELY(len1 <= 0 && len2 <= 0)) return hawk_val_zls;
aligned_len = HAWK_ALIGN_POW2((len1 + len2 + 1), HAWK_MBS_CACHE_BLOCK_UNIT);
#if defined(HAWK_ENABLE_MBS_CACHE)
i = aligned_len / HAWK_MBS_CACHE_BLOCK_UNIT;
@ -858,16 +857,24 @@ init:
val->v_type = HAWK_VAL_MBS;
val->v_refs = 0;
val->v_static = 0;
val->nstr = 0;
val->v_nstr = 0;
val->v_gc = 0;
val->val.len = len;
val->val.len = len1 + len2;
val->val.ptr = (hawk_bch_t*)(val + 1);
if (ptr) HAWK_MEMCPY (val->val.ptr, ptr, len);
val->val.ptr[len] = '\0';
if (HAWK_LIKELY(mbs1)) hawk_copy_bchars_to_bcstr_unlimited (&val->val.ptr[0], mbs1, len1);
if (mbs2) hawk_copy_bchars_to_bcstr_unlimited (&val->val.ptr[len1], mbs2, len2);
val->val.ptr[val->val.len] = '\0';
#if defined(DEBUG_VAL)
hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_LOG_STDERR, HAWK_T("make_mbs_val => %p - [%O]\n"), val, val);
#endif
return (hawk_val_t*)val;
}
hawk_val_t* hawk_rtx_makembsvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_t* ptr, hawk_oow_t len)
{
return make_mbs_val(rtx, ptr, len, HAWK_NULL, 0);
}
hawk_val_t* hawk_rtx_makembsvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_t* ucs, hawk_oow_t len)
{
@ -880,16 +887,15 @@ hawk_val_t* hawk_rtx_makembsvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_t* uc
bcs = hawk_rtx_duputobchars(rtx, ucs, len, &bcslen);
if (HAWK_UNLIKELY(!bcs)) return HAWK_NULL;
val = hawk_rtx_makembsvalwithbchars(rtx, bcs, bcslen);
val = make_mbs_val(rtx, bcs, bcslen, HAWK_NULL, 0);
hawk_rtx_freemem (rtx, bcs);
return val;
}
hawk_val_t* hawk_rtx_makembsvalwithbcs (hawk_rtx_t* rtx, const hawk_bcs_t* bcs)
{
return hawk_rtx_makembsvalwithbchars(rtx, bcs->ptr, bcs->len);
return make_mbs_val(rtx, bcs->ptr, bcs->len, HAWK_NULL, 0);
}
hawk_val_t* hawk_rtx_makembsvalwithucs (hawk_rtx_t* rtx, const hawk_ucs_t* ucs)
@ -899,6 +905,44 @@ hawk_val_t* hawk_rtx_makembsvalwithucs (hawk_rtx_t* rtx, const hawk_ucs_t* ucs)
/* --------------------------------------------------------------------- */
hawk_val_t* hawk_rtx_makembsvalwithuchars2 (hawk_rtx_t* rtx, const hawk_uch_t* ucs1, hawk_oow_t len1, const hawk_uch_t* ucs2, hawk_oow_t len2)
{
#if defined(HAWK_OOCH_IS_UCH)
hawk_val_t* v;
hawk_bch_t* bcs;
hawk_oow_t bcslen;
bcs = hawk_rtx_dupu2tobchars(rtx, ucs1, len1, ucs2, len2, &bcslen);
if (HAWK_UNLIKELY(!bcs)) return HAWK_NULL;
v = make_mbs_val(rtx, bcs, bcslen, HAWK_NULL, 0);
hawk_rtx_freemem (rtx, bcs);
return v;
#else
return make_mbs_val(rtx, ucs1, len1, ucs2, len2);
#endif
}
hawk_val_t* hawk_rtx_makembsvalwithbchars2 (hawk_rtx_t* rtx, const hawk_bch_t* bcs1, hawk_oow_t len1, const hawk_bch_t* bcs2, hawk_oow_t len2)
{
#if defined(HAWK_OOCH_IS_UCH)
return make_mbs_val(rtx, bcs1, len1, bcs2, len2);
#else
hawk_val_t* v;
hawk_uch_t* ucs;
hawk_oow_t ucslen;
ucs = hawk_rtx_dupb2tobchars(rtx, bcs1, len1, bcs2, len2, &ucslen, 1);
if (HAWK_UNLIKELY(!ucs)) return HAWK_NULL;
v = make_mbs_val(rtx, ucs, ucslen, HAWK_NULL, 0);
hawk_rtx_freemem (rtx, ucs);
return v;
#endif
}
/* --------------------------------------------------------------------- */
hawk_val_t* hawk_rtx_makenumormbsvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_t* ptr, hawk_oow_t len)
{
int x;
@ -944,7 +988,7 @@ hawk_val_t* hawk_rtx_makerexval (hawk_rtx_t* rtx, const hawk_oocs_t* str, hawk_t
val->v_type = HAWK_VAL_REX;
val->v_refs = 0;
val->v_static = 0;
val->nstr = 0;
val->v_nstr = 0;
val->v_gc = 0;
val->str.len = str->len;
@ -1022,7 +1066,7 @@ retry:
val->v_type = HAWK_VAL_ARR;
val->v_refs = 0;
val->v_static = 0;
val->nstr = 0;
val->v_nstr = 0;
val->v_gc = 0;
val->arr = (hawk_arr_t*)(val + 1);
@ -1130,7 +1174,7 @@ retry:
val->v_type = HAWK_VAL_MAP;
val->v_refs = 0;
val->v_static = 0;
val->nstr = 0;
val->v_nstr = 0;
val->v_gc = 0;
val->map = (hawk_map_t*)(val + 1);
@ -1350,7 +1394,7 @@ hawk_val_t* hawk_rtx_makefunval (hawk_rtx_t* rtx, const hawk_fun_t* fun)
val->v_type = HAWK_VAL_FUN;
val->v_refs = 0;
val->v_static = 0;
val->nstr = 0;
val->v_nstr = 0;
val->v_gc = 0;
val->fun = (hawk_fun_t*)fun;
@ -1449,7 +1493,7 @@ void hawk_rtx_freeval (hawk_rtx_t* rtx, hawk_val_t* val, int flags)
rtx->str_cache_count[i] < HAWK_COUNTOF(rtx->str_cache[i]))
{
rtx->str_cache[i][rtx->str_cache_count[i]++] = v;
v->nstr = 0;
v->v_nstr = 0;
}
else hawk_rtx_freemem (rtx, val);
break;
@ -2385,6 +2429,18 @@ hawk_bch_t* hawk_rtx_getvalbcstrwithcmgr (hawk_rtx_t* rtx, hawk_val_t* v, hawk_o
/* fall through */
#endif
#if 0
case HAWK_VAL_CHAR:
i can treat a character value between 0 and 255 as a byte.
but doing so can cause inconsitency between the two ranges:
* 128 - 255 (kept as a single byte)
* 255 - max character value (encoded to multiple bytes)
it looks more consistent that 255 becomes \xc3\xbf (assuming utf8).
so no special handling for HAWK_VAL_CHAR here.
#endif
default:
return hawk_rtx_valtobcstrdupwithcmgr(rtx, v, len, cmgr);
}

View File

@ -141,5 +141,44 @@ function main()
ensure (((10,30,30) in c), 0, @SCRIPTNAME, @SCRIPTLINE);
}
{
# concatenation operator
ensure ((@b"hawk" 10) === @b"hawk10", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (("hawk" 10) === "hawk10", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure ((@b"hawk" "hawk") === @b"hawkhawk", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (("hawk" @b"hawk") === "hawkhawk", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure ((@b"hawk" '1') === @b"hawk1", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (("hawk" '1') === "hawk1", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (('*' @b"hawk" '1') === "*hawk1", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (('*' "hawk" '1') === "*hawk1", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure ((@b"hawk" '⚾') === @b"hawk\xe2\x9a\xbe", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (("hawk" '⚾') === "hawk⚾", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure ((@b"hawk" str::fromcharcode(0x26be)) === @b"hawk\xe2\x9a\xbe", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (("hawk" str::fromcharcode(0x26be)) === "hawk⚾", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure ((@b"hawk" %% 10) === @b"hawk10", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (("hawk" %% 10) === "hawk10", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure ((@b"hawk" %% "hawk") === @b"hawkhawk", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (("hawk" %% @b"hawk") === "hawkhawk", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure ((@b"hawk" %% '1') === @b"hawk1", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (("hawk" %% '1') === "hawk1", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (('*' %% @b"hawk" %% '1') === "*hawk1", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (('*' %% "hawk" %% '1') === "*hawk1", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure ((@b"hawk" %% '⚾') === @b"hawk\xe2\x9a\xbe", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (("hawk" %% '⚾') === "hawk⚾", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure ((@b"hawk" %% str::fromcharcode(0x26be)) === @b"hawk\xe2\x9a\xbe", 1, @SCRIPTNAME, @SCRIPTLINE);
ensure (("hawk" %% str::fromcharcode(0x26be)) === "hawk⚾", 1, @SCRIPTNAME, @SCRIPTLINE);
}
print "SUCCESS"
}