resolved numerous bugs regarding byte-characters and byte-strings
changed the way to handle %s/%k/%K contained inside CONVFMT - treat the format specifier as if it is %g instead of returning an error. removed HAWK_EFMTCNV for the CONVFMT formatting change
This commit is contained in:
parent
e983d7701a
commit
0de14c4744
@ -166,7 +166,6 @@ const hawk_ooch_t* hawk_dfl_errstr (hawk_errnum_t errnum)
|
||||
HAWK_T("I/O name empty"),
|
||||
HAWK_T("I/O name containing '\\0'"),
|
||||
HAWK_T("not sufficient arguments to formatting sequence"),
|
||||
HAWK_T("recursion detected in format conversion"),
|
||||
HAWK_T("invalid character in CONVFMT"),
|
||||
HAWK_T("invalid character in OFMT"),
|
||||
|
||||
|
393
hawk/lib/fnc.c
393
hawk/lib/fnc.c
@ -566,94 +566,101 @@ static int index_or_rindex (hawk_rtx_t* rtx, int rindex)
|
||||
if (n <= -1) return -1;
|
||||
}
|
||||
|
||||
if (HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MBS)
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, a0))
|
||||
{
|
||||
hawk_bch_t* str0, * str1, * ptr;
|
||||
hawk_oow_t len0, len1;
|
||||
|
||||
str0 = ((hawk_val_mbs_t*)a0)->val.ptr;
|
||||
len0 = ((hawk_val_mbs_t*)a0)->val.len;
|
||||
|
||||
str1 = hawk_rtx_getvalbcstr(rtx, a1, &len1);
|
||||
if (!str1) return -1;
|
||||
|
||||
if (nargs < 3)
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_MBS:
|
||||
{
|
||||
boundary = rindex? len0: 1;
|
||||
hawk_bch_t* str0, * str1, * ptr;
|
||||
hawk_oow_t len0, len1;
|
||||
|
||||
str0 = ((hawk_val_mbs_t*)a0)->val.ptr;
|
||||
len0 = ((hawk_val_mbs_t*)a0)->val.len;
|
||||
|
||||
str1 = hawk_rtx_getvalbcstr(rtx, a1, &len1);
|
||||
if (HAWK_UNLIKELY(!str0)) return -1;
|
||||
|
||||
if (nargs < 3)
|
||||
{
|
||||
boundary = rindex? len0: 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (boundary == 0) boundary = 1;
|
||||
else if (boundary < 0) boundary = len0 + boundary + 1;
|
||||
}
|
||||
|
||||
if (boundary > len0 || boundary <= 0)
|
||||
{
|
||||
ptr = HAWK_NULL;
|
||||
}
|
||||
else if (rindex)
|
||||
{
|
||||
/* 'boundary' acts as an end position */
|
||||
ptr = hawk_rfind_bchars_in_bchars(&str0[0], boundary, str1, len1, rtx->gbl.ignorecase);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 'boundary' acts as an start position */
|
||||
ptr = hawk_find_bchars_in_bchars(&str0[boundary-1], len0 - boundary + 1, str1, len1, rtx->gbl.ignorecase);
|
||||
}
|
||||
|
||||
idx = (ptr == HAWK_NULL)? 0: ((hawk_int_t)(ptr - str0) + 1);
|
||||
|
||||
hawk_rtx_freevalbcstr (rtx, a1, str1);
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
||||
default:
|
||||
{
|
||||
if (boundary == 0) boundary = 1;
|
||||
else if (boundary < 0) boundary = len0 + boundary + 1;
|
||||
}
|
||||
hawk_ooch_t* str0, * str1, * ptr;
|
||||
hawk_oow_t len0, len1;
|
||||
|
||||
if (boundary > len0 || boundary <= 0)
|
||||
{
|
||||
ptr = HAWK_NULL;
|
||||
}
|
||||
else if (rindex)
|
||||
{
|
||||
/* 'boundary' acts as an end position */
|
||||
ptr = hawk_rfind_bchars_in_bchars(&str0[0], boundary, str1, len1, rtx->gbl.ignorecase);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 'boundary' acts as an start position */
|
||||
ptr = hawk_find_bchars_in_bchars(&str0[boundary-1], len0 - boundary + 1, str1, len1, rtx->gbl.ignorecase);
|
||||
}
|
||||
str0 = hawk_rtx_getvaloocstr(rtx, a0, &len0);
|
||||
if (HAWK_UNLIKELY(!str0)) return -1;
|
||||
|
||||
idx = (ptr == HAWK_NULL)? 0: ((hawk_int_t)(ptr - str0) + 1);
|
||||
str1 = hawk_rtx_getvaloocstr(rtx, a1, &len1);
|
||||
if (!str1)
|
||||
{
|
||||
hawk_rtx_freevaloocstr (rtx, a0, str0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hawk_rtx_freevalbcstr (rtx, a1, str1);
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_ooch_t* str0, * str1, * ptr;
|
||||
hawk_oow_t len0, len1;
|
||||
if (nargs < 3)
|
||||
{
|
||||
boundary = rindex? len0: 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (boundary == 0) boundary = 1;
|
||||
else if (boundary < 0) boundary = len0 + boundary + 1;
|
||||
}
|
||||
|
||||
str0 = hawk_rtx_getvaloocstr(rtx, a0, &len0);
|
||||
if (!str0) return -1;
|
||||
if (boundary > len0 || boundary <= 0)
|
||||
{
|
||||
ptr = HAWK_NULL;
|
||||
}
|
||||
else if (rindex)
|
||||
{
|
||||
/* 'boundary' acts as an end position */
|
||||
ptr = hawk_rfind_oochars_in_oochars(&str0[0], boundary, str1, len1, rtx->gbl.ignorecase);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 'boundary' acts as an start position */
|
||||
ptr = hawk_find_oochars_in_oochars(&str0[boundary-1], len0 - boundary + 1, str1, len1, rtx->gbl.ignorecase);
|
||||
}
|
||||
|
||||
str1 = hawk_rtx_getvaloocstr(rtx, a1, &len1);
|
||||
if (!str1)
|
||||
{
|
||||
idx = (ptr == HAWK_NULL)? 0: ((hawk_int_t)(ptr - str0) + 1);
|
||||
|
||||
hawk_rtx_freevaloocstr (rtx, a1, str1);
|
||||
hawk_rtx_freevaloocstr (rtx, a0, str0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nargs < 3)
|
||||
{
|
||||
boundary = rindex? len0: 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (boundary == 0) boundary = 1;
|
||||
else if (boundary < 0) boundary = len0 + boundary + 1;
|
||||
}
|
||||
|
||||
if (boundary > len0 || boundary <= 0)
|
||||
{
|
||||
ptr = HAWK_NULL;
|
||||
}
|
||||
else if (rindex)
|
||||
{
|
||||
/* 'boundary' acts as an end position */
|
||||
ptr = hawk_rfind_oochars_in_oochars(&str0[0], boundary, str1, len1, rtx->gbl.ignorecase);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 'boundary' acts as an start position */
|
||||
ptr = hawk_find_oochars_in_oochars(&str0[boundary-1], len0 - boundary + 1, str1, len1, rtx->gbl.ignorecase);
|
||||
}
|
||||
|
||||
idx = (ptr == HAWK_NULL)? 0: ((hawk_int_t)(ptr - str0) + 1);
|
||||
|
||||
hawk_rtx_freevaloocstr (rtx, a1, str1);
|
||||
hawk_rtx_freevaloocstr (rtx, a0, str0);
|
||||
break;
|
||||
}
|
||||
|
||||
a0 = hawk_rtx_makeintval(rtx, idx);
|
||||
if (a0 == HAWK_NULL) return -1;
|
||||
if (HAWK_UNLIKELY(!a0)) return -1;
|
||||
|
||||
hawk_rtx_setretval (rtx, a0);
|
||||
return 0;
|
||||
@ -661,12 +668,12 @@ static int index_or_rindex (hawk_rtx_t* rtx, int rindex)
|
||||
|
||||
int hawk_fnc_index (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
return index_or_rindex (rtx, 0);
|
||||
return index_or_rindex(rtx, 0);
|
||||
}
|
||||
|
||||
int hawk_fnc_rindex (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
return index_or_rindex (rtx, 1);
|
||||
return index_or_rindex(rtx, 1);
|
||||
}
|
||||
|
||||
int hawk_fnc_length (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
@ -701,15 +708,23 @@ int hawk_fnc_length (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
len = HAWK_ARR_TALLY(((hawk_val_arr_t*)v)->arr);
|
||||
break;
|
||||
|
||||
case HAWK_VAL_STR:
|
||||
/* string length */
|
||||
len = ((hawk_val_str_t*)v)->val.len;
|
||||
case HAWK_VAL_BCHR:
|
||||
len = 1;
|
||||
break;
|
||||
|
||||
case HAWK_VAL_MBS:
|
||||
len = ((hawk_val_mbs_t*)v)->val.len;
|
||||
break;
|
||||
|
||||
case HAWK_VAL_CHAR:
|
||||
len = 1;
|
||||
break;
|
||||
|
||||
case HAWK_VAL_STR:
|
||||
/* string length */
|
||||
len = ((hawk_val_str_t*)v)->val.len;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* convert to string and get length */
|
||||
str = hawk_rtx_valtooocstrdup(rtx, v, &len);
|
||||
@ -753,34 +768,42 @@ int hawk_fnc_substr (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
lindex = lindex - 1;
|
||||
if (lindex < 0) lindex = 0;
|
||||
|
||||
if (HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MBS)
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, a0))
|
||||
{
|
||||
hawk_bch_t* str;
|
||||
hawk_oow_t len;
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_MBS:
|
||||
{
|
||||
hawk_bch_t* str;
|
||||
hawk_oow_t len;
|
||||
|
||||
str = ((hawk_val_mbs_t*)a0)->val.ptr;
|
||||
len = ((hawk_val_mbs_t*)a0)->val.len;
|
||||
str = hawk_rtx_getvalbcstr(rtx, a0, &len);
|
||||
if (HAWK_UNLIKELY(!str)) return -1;
|
||||
|
||||
if (lindex >= (hawk_int_t)len) lindex = (hawk_int_t)len;
|
||||
if (lcount > (hawk_int_t)len - lindex) lcount = (hawk_int_t)len - lindex;
|
||||
if (lindex >= (hawk_int_t)len) lindex = (hawk_int_t)len;
|
||||
if (lcount > (hawk_int_t)len - lindex) lcount = (hawk_int_t)len - lindex;
|
||||
|
||||
r = hawk_rtx_makembsvalwithbchars(rtx, &str[lindex], (hawk_oow_t)lcount);
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_ooch_t* str;
|
||||
hawk_oow_t len;
|
||||
r = hawk_rtx_makembsvalwithbchars(rtx, &str[lindex], (hawk_oow_t)lcount);
|
||||
hawk_rtx_freevalbcstr (rtx, a0, str);
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
str = hawk_rtx_getvaloocstr(rtx, a0, &len);
|
||||
if (!str) return -1;
|
||||
default:
|
||||
{
|
||||
hawk_ooch_t* str;
|
||||
hawk_oow_t len;
|
||||
|
||||
if (lindex >= (hawk_int_t)len) lindex = (hawk_int_t)len;
|
||||
if (lcount > (hawk_int_t)len - lindex) lcount = (hawk_int_t)len - lindex;
|
||||
str = hawk_rtx_getvaloocstr(rtx, a0, &len);
|
||||
if (HAWK_UNLIKELY(!str)) return -1;
|
||||
|
||||
r = hawk_rtx_makestrvalwithoochars(rtx, &str[lindex], (hawk_oow_t)lcount);
|
||||
hawk_rtx_freevaloocstr (rtx, a0, str);
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
if (lindex >= (hawk_int_t)len) lindex = (hawk_int_t)len;
|
||||
if (lcount > (hawk_int_t)len - lindex) lcount = (hawk_int_t)len - lindex;
|
||||
|
||||
r = hawk_rtx_makestrvalwithoochars(rtx, &str[lindex], (hawk_oow_t)lcount);
|
||||
hawk_rtx_freevaloocstr (rtx, a0, str);
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hawk_rtx_setretval (rtx, r);
|
||||
@ -836,6 +859,9 @@ static int fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int use_array)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no distinction between byte-string and normal string for the lack of hawk_rtx_buildrex() with a byte string.
|
||||
* TODO: distingish byte strings from normal strings once the regular expresson builder supports them */
|
||||
|
||||
fs.ptr = hawk_rtx_getvaloocstr(rtx, t0, &fs.len);
|
||||
if (HAWK_UNLIKELY(!fs.ptr)) goto oops;
|
||||
|
||||
@ -864,17 +890,20 @@ static int fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int use_array)
|
||||
}
|
||||
|
||||
/* the first parameter - string to split */
|
||||
if (HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MBS)
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, a0))
|
||||
{
|
||||
byte_str = 1;
|
||||
str.ptr = do_fld? hawk_rtx_valtobcstrdup(rtx, a0, &str.len):
|
||||
hawk_rtx_getvalbcstr(rtx, a0, &str.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte_str = 0;
|
||||
str.ptr = do_fld? hawk_rtx_valtooocstrdup(rtx, a0, &str.len):
|
||||
hawk_rtx_getvaloocstr(rtx, a0, &str.len);
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_MBS:
|
||||
byte_str = 1;
|
||||
str.ptr = do_fld? hawk_rtx_valtobcstrdup(rtx, a0, &str.len):
|
||||
hawk_rtx_getvalbcstr(rtx, a0, &str.len);
|
||||
break;
|
||||
|
||||
default:
|
||||
byte_str = 0;
|
||||
str.ptr = do_fld? hawk_rtx_valtooocstrdup(rtx, a0, &str.len):
|
||||
hawk_rtx_getvaloocstr(rtx, a0, &str.len);
|
||||
break;
|
||||
}
|
||||
if (HAWK_UNLIKELY(!str.ptr)) goto oops;
|
||||
|
||||
@ -1016,6 +1045,15 @@ int hawk_fnc_tolower (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:
|
||||
{
|
||||
hawk_bch_t tmp = HAWK_RTX_GETBCHRFROMVAL(rtx, a0);
|
||||
tmp = hawk_to_bch_lower(tmp);
|
||||
r = hawk_rtx_makebchrval(rtx, tmp);
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
case HAWK_VAL_MBS:
|
||||
{
|
||||
hawk_bcs_t str;
|
||||
@ -1033,7 +1071,7 @@ int hawk_fnc_tolower (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
case HAWK_VAL_CHAR:
|
||||
{
|
||||
hawk_ooch_t tmp = HAWK_RTX_GETCHARFROMVAL(rtx, a0);
|
||||
tmp = hawk_to_bch_lower(tmp);
|
||||
tmp = hawk_to_ooch_lower(tmp);
|
||||
r = hawk_rtx_makecharval(rtx, tmp);
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
break;
|
||||
@ -1066,6 +1104,15 @@ int hawk_fnc_toupper (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:
|
||||
{
|
||||
hawk_bch_t tmp = HAWK_RTX_GETCHARFROMVAL(rtx, a0);
|
||||
tmp = hawk_to_bch_upper(tmp);
|
||||
r = hawk_rtx_makebchrval(rtx, tmp);
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
case HAWK_VAL_MBS:
|
||||
{
|
||||
hawk_bcs_t str;
|
||||
@ -1083,7 +1130,7 @@ int hawk_fnc_toupper (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
case HAWK_VAL_CHAR:
|
||||
{
|
||||
hawk_ooch_t tmp = HAWK_RTX_GETCHARFROMVAL(rtx, a0);
|
||||
tmp = hawk_to_bch_upper(tmp);
|
||||
tmp = hawk_to_ooch_upper(tmp);
|
||||
r = hawk_rtx_makecharval(rtx, tmp);
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
break;
|
||||
@ -1373,23 +1420,26 @@ static int __substitute (hawk_rtx_t* rtx, hawk_oow_t max_count)
|
||||
{
|
||||
r2 = hawk_rtx_getrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 2));
|
||||
|
||||
if (HAWK_RTX_GETVALTYPE(rtx, r2) == HAWK_VAL_MBS)
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, r2))
|
||||
{
|
||||
s2.ptr = hawk_rtx_getvalbcstr(rtx, r2, &s2.len);
|
||||
s2_free = 2;
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_MBS:
|
||||
s2.ptr = hawk_rtx_getvalbcstr(rtx, r2, &s2.len);
|
||||
s2_free = 2;
|
||||
|
||||
/* the second argument - substitute */
|
||||
s1.ptr = hawk_rtx_getvalbcstr(rtx, a1, &s1.len);
|
||||
s1_free = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
s2.ptr = hawk_rtx_getvaloocstr(rtx, r2, &s2.len);
|
||||
s2_free = 1;
|
||||
/* the second argument - substitute */
|
||||
s1.ptr = hawk_rtx_getvalbcstr(rtx, a1, &s1.len);
|
||||
s1_free = 2;
|
||||
break;
|
||||
|
||||
/* the second argument - substitute */
|
||||
s1.ptr = hawk_rtx_getvaloocstr(rtx, a1, &s1.len);
|
||||
s1_free = 1;
|
||||
default:
|
||||
s2.ptr = hawk_rtx_getvaloocstr(rtx, r2, &s2.len);
|
||||
s2_free = 1;
|
||||
|
||||
/* the second argument - substitute */
|
||||
s1.ptr = hawk_rtx_getvaloocstr(rtx, a1, &s1.len);
|
||||
s1_free = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1738,61 +1788,66 @@ int hawk_fnc_sprintf (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
HAWK_ASSERT (nargs > 0);
|
||||
|
||||
a0 = hawk_rtx_getarg(rtx, 0);
|
||||
if (HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MBS)
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, a0))
|
||||
{
|
||||
hawk_becs_t fbu;
|
||||
int fbu_inited = 0;
|
||||
hawk_bcs_t cs0;
|
||||
hawk_bcs_t x;
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_MBS:
|
||||
{
|
||||
hawk_becs_t fbu;
|
||||
int fbu_inited = 0;
|
||||
hawk_bcs_t cs0;
|
||||
hawk_bcs_t x;
|
||||
|
||||
if (hawk_becs_init(&fbu, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_mbs;
|
||||
fbu_inited = 1;
|
||||
if (hawk_becs_init(&fbu, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_mbs;
|
||||
fbu_inited = 1;
|
||||
|
||||
cs0.ptr = hawk_rtx_getvalbcstr(rtx, a0, &cs0.len);
|
||||
if (HAWK_UNLIKELY(!cs0.ptr)) goto oops_mbs;
|
||||
cs0.ptr = hawk_rtx_getvalbcstr(rtx, a0, &cs0.len);
|
||||
if (HAWK_UNLIKELY(!cs0.ptr)) goto oops_mbs;
|
||||
|
||||
x.ptr = hawk_rtx_formatmbs(rtx, &rtx->fnc.bout, &fbu, cs0.ptr, cs0.len, nargs, HAWK_NULL, &x.len);
|
||||
hawk_rtx_freevalbcstr (rtx, a0, cs0.ptr);
|
||||
if (HAWK_UNLIKELY(!x.ptr)) goto oops_mbs;
|
||||
|
||||
a0 = hawk_rtx_makembsvalwithbcs(rtx, &x);
|
||||
if (HAWK_UNLIKELY(!a0)) goto oops_mbs;
|
||||
x.ptr = hawk_rtx_formatmbs(rtx, &rtx->fnc.bout, &fbu, cs0.ptr, cs0.len, nargs, HAWK_NULL, &x.len);
|
||||
hawk_rtx_freevalbcstr (rtx, a0, cs0.ptr);
|
||||
if (HAWK_UNLIKELY(!x.ptr)) goto oops_mbs;
|
||||
|
||||
a0 = hawk_rtx_makembsvalwithbcs(rtx, &x);
|
||||
if (HAWK_UNLIKELY(!a0)) goto oops_mbs;
|
||||
|
||||
hawk_becs_fini (&fbu);
|
||||
hawk_rtx_setretval (rtx, a0);
|
||||
return 0;
|
||||
hawk_becs_fini (&fbu);
|
||||
hawk_rtx_setretval (rtx, a0);
|
||||
return 0;
|
||||
|
||||
oops_mbs:
|
||||
if (fbu_inited) hawk_becs_fini (&fbu);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_ooecs_t fbu;
|
||||
int fbu_inited = 0;
|
||||
hawk_oocs_t cs0;
|
||||
hawk_oocs_t x;
|
||||
oops_mbs:
|
||||
if (fbu_inited) hawk_becs_fini (&fbu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hawk_ooecs_init(&fbu, hawk_rtx_getgem(rtx), 256) <= -1) goto oops;
|
||||
fbu_inited = 1;
|
||||
default:
|
||||
{
|
||||
hawk_ooecs_t fbu;
|
||||
int fbu_inited = 0;
|
||||
hawk_oocs_t cs0;
|
||||
hawk_oocs_t x;
|
||||
|
||||
cs0.ptr = hawk_rtx_getvaloocstr(rtx, a0, &cs0.len);
|
||||
if (HAWK_UNLIKELY(!cs0.ptr)) goto oops;
|
||||
if (hawk_ooecs_init(&fbu, hawk_rtx_getgem(rtx), 256) <= -1) goto oops;
|
||||
fbu_inited = 1;
|
||||
|
||||
x.ptr = hawk_rtx_format(rtx, &rtx->fnc.oout, &fbu, cs0.ptr, cs0.len, nargs, HAWK_NULL, &x.len);
|
||||
hawk_rtx_freevaloocstr (rtx, a0, cs0.ptr);
|
||||
if (HAWK_UNLIKELY(!x.ptr)) goto oops;
|
||||
cs0.ptr = hawk_rtx_getvaloocstr(rtx, a0, &cs0.len);
|
||||
if (HAWK_UNLIKELY(!cs0.ptr)) goto oops;
|
||||
|
||||
a0 = hawk_rtx_makestrvalwithoocs(rtx, &x);
|
||||
if (HAWK_UNLIKELY(!a0)) goto oops;
|
||||
x.ptr = hawk_rtx_format(rtx, &rtx->fnc.oout, &fbu, cs0.ptr, cs0.len, nargs, HAWK_NULL, &x.len);
|
||||
hawk_rtx_freevaloocstr (rtx, a0, cs0.ptr);
|
||||
if (HAWK_UNLIKELY(!x.ptr)) goto oops;
|
||||
|
||||
hawk_ooecs_fini (&fbu);
|
||||
hawk_rtx_setretval (rtx, a0);
|
||||
return 0;
|
||||
a0 = hawk_rtx_makestrvalwithoocs(rtx, &x);
|
||||
if (HAWK_UNLIKELY(!a0)) goto oops;
|
||||
|
||||
oops:
|
||||
if (fbu_inited) hawk_ooecs_fini (&fbu);
|
||||
return -1;
|
||||
hawk_ooecs_fini (&fbu);
|
||||
hawk_rtx_setretval (rtx, a0);
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
if (fbu_inited) hawk_ooecs_fini (&fbu);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1021,7 +1021,6 @@ enum hawk_errnum_t
|
||||
HAWK_EIONMEM, /**< I/O name empty */
|
||||
HAWK_EIONMNL, /**< I/O name containing '\\0' */
|
||||
HAWK_EFMTARG, /**< not sufficient arguments to formatting sequence */
|
||||
HAWK_EFMTCNV, /**< recursion detected in format conversion */
|
||||
HAWK_ECONVFMTCHR, /**< invalid character in CONVFMT */
|
||||
HAWK_EOFMTCHR, /**< invalid character in OFMT */
|
||||
|
||||
|
@ -381,7 +381,13 @@ struct hawk_chain_t
|
||||
typedef struct hawk_ctos_b_t hawk_ctos_b_t;
|
||||
struct hawk_ctos_b_t
|
||||
{
|
||||
hawk_ooch_t c[2];
|
||||
hawk_oochu_t c[2]; /* ensure the unsigned type to hold not only a character but also a free slot index */
|
||||
};
|
||||
|
||||
typedef struct hawk_bctos_b_t hawk_bctos_b_t;
|
||||
struct hawk_bctos_b_t
|
||||
{
|
||||
hawk_bchu_t c[2]; /* ensure the unsigned type to hold not only a byte character but also a free slot index */
|
||||
};
|
||||
|
||||
struct hawk_rtx_t
|
||||
@ -427,6 +433,12 @@ struct hawk_rtx_t
|
||||
hawk_oow_t fi;
|
||||
} ctos; /* char/nil to string conversion */
|
||||
|
||||
struct
|
||||
{
|
||||
hawk_bctos_b_t b[256];
|
||||
hawk_oow_t fi;
|
||||
} bctos;
|
||||
|
||||
struct
|
||||
{
|
||||
/* lists of values under gc management */
|
||||
|
@ -37,30 +37,36 @@ static int fnc_normspace (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
hawk_val_t* a0;
|
||||
|
||||
a0 = hawk_rtx_getarg(rtx, 0);
|
||||
if (HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MBS)
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, a0))
|
||||
{
|
||||
hawk_bch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_MBS:
|
||||
{
|
||||
hawk_bch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
|
||||
str0 = hawk_rtx_valtobcstrdup(rtx, a0, &len0);
|
||||
if (HAWK_UNLIKELY(!str0)) return -1;
|
||||
len0 = hawk_compact_bchars(str0, len0);
|
||||
retv = hawk_rtx_makembsvalwithbchars(rtx, str0, len0);
|
||||
hawk_rtx_freemem (rtx, str0);
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_ooch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
str0 = hawk_rtx_valtobcstrdup(rtx, a0, &len0);
|
||||
if (HAWK_UNLIKELY(!str0)) return -1;
|
||||
len0 = hawk_compact_bchars(str0, len0);
|
||||
retv = hawk_rtx_makembsvalwithbchars(rtx, str0, len0);
|
||||
hawk_rtx_freemem (rtx, str0);
|
||||
break;
|
||||
}
|
||||
|
||||
str0 = hawk_rtx_valtooocstrdup(rtx, a0, &len0);
|
||||
if (HAWK_UNLIKELY(!str0)) return -1;
|
||||
len0 = hawk_compact_oochars(str0, len0);
|
||||
retv = hawk_rtx_makestrvalwithoochars(rtx, str0, len0);
|
||||
hawk_rtx_freemem (rtx, str0);
|
||||
default:
|
||||
{
|
||||
hawk_ooch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
|
||||
str0 = hawk_rtx_valtooocstrdup(rtx, a0, &len0);
|
||||
if (HAWK_UNLIKELY(!str0)) return -1;
|
||||
len0 = hawk_compact_oochars(str0, len0);
|
||||
retv = hawk_rtx_makestrvalwithoochars(rtx, str0, len0);
|
||||
hawk_rtx_freemem (rtx, str0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!retv) return -1;
|
||||
if (HAWK_UNLIKELY(!retv)) return -1;
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
|
||||
return 0;
|
||||
@ -73,31 +79,39 @@ static int trim (hawk_rtx_t* rtx, int flags)
|
||||
|
||||
a0 = hawk_rtx_getarg(rtx, 0);
|
||||
|
||||
if (HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MBS)
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, a0))
|
||||
{
|
||||
hawk_bcs_t path;
|
||||
hawk_bch_t* npath;
|
||||
path.ptr = ((hawk_val_mbs_t*)a0)->val.ptr;
|
||||
path.len = ((hawk_val_mbs_t*)a0)->val.len;
|
||||
npath = hawk_trim_bchars(path.ptr, &path.len, flags);
|
||||
retv = hawk_rtx_makembsvalwithbchars(rtx, npath, path.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_oocs_t path;
|
||||
hawk_ooch_t* npath;
|
||||
path.ptr = hawk_rtx_getvaloocstr(rtx, a0, &path.len);
|
||||
if (!path.ptr) return -1;
|
||||
/* because hawk_strxtrmx() returns the pointer and the length without
|
||||
* affecting the string given, it's safe to pass the original value.
|
||||
* hawk_rtx_getvaloocstr() doesn't duplicate the value if it's of
|
||||
* the string type. */
|
||||
npath = hawk_trim_oochars(path.ptr, &path.len, flags);
|
||||
retv = hawk_rtx_makestrvalwithoochars(rtx, npath, path.len);
|
||||
hawk_rtx_freevaloocstr (rtx, a0, path.ptr);
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_MBS:
|
||||
{
|
||||
hawk_bcs_t path;
|
||||
hawk_bch_t* npath;
|
||||
path.ptr = hawk_rtx_getvalbcstr(rtx, a0, &path.len);
|
||||
if (HAWK_UNLIKELY(!path.ptr)) return -1;
|
||||
npath = hawk_trim_bchars(path.ptr, &path.len, flags);
|
||||
retv = hawk_rtx_makembsvalwithbchars(rtx, npath, path.len);
|
||||
hawk_rtx_freevalbcstr (rtx, a0, path.ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
hawk_oocs_t path;
|
||||
hawk_ooch_t* npath;
|
||||
path.ptr = hawk_rtx_getvaloocstr(rtx, a0, &path.len);
|
||||
if (HAWK_UNLIKELY(!path.ptr)) return -1;
|
||||
/* because hawk_trim_oochars() returns the pointer and the length without
|
||||
* affecting the string given, it's safe to pass the original value.
|
||||
* hawk_rtx_getvaloocstr() doesn't duplicate the value if it's of
|
||||
* the string type. */
|
||||
npath = hawk_trim_oochars(path.ptr, &path.len, flags);
|
||||
retv = hawk_rtx_makestrvalwithoochars(rtx, npath, path.len);
|
||||
hawk_rtx_freevaloocstr (rtx, a0, path.ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!retv) return -1;
|
||||
if (HAWK_UNLIKELY(!retv)) return -1;
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
return 0;
|
||||
}
|
||||
@ -106,6 +120,8 @@ static int trim (hawk_rtx_t* rtx, int flags)
|
||||
|
||||
static int fnc_trim (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
/* str::trim(" test string ");
|
||||
str::trim(" test string ", str::TRIM_PAC_SPACES); */
|
||||
if (hawk_rtx_getnargs(rtx) >= 2)
|
||||
{
|
||||
hawk_int_t iv;
|
||||
@ -131,58 +147,67 @@ static int is_class (hawk_rtx_t* rtx, hawk_ooch_prop_t ctype)
|
||||
|
||||
a0 = hawk_rtx_getarg(rtx, 0);
|
||||
|
||||
if (HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MBS)
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, a0))
|
||||
{
|
||||
hawk_bch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
|
||||
str0 = ((hawk_val_mbs_t*)a0)->val.ptr;
|
||||
len0 = ((hawk_val_mbs_t*)a0)->val.len;
|
||||
|
||||
if (len0 <= 0) tmp = 0;
|
||||
else
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_MBS:
|
||||
{
|
||||
tmp = 1;
|
||||
do
|
||||
hawk_bch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
|
||||
str0 = hawk_rtx_getvalbcstr(rtx, a0, &len0);
|
||||
if (HAWK_UNLIKELY(!str0)) return -1;
|
||||
|
||||
if (len0 <= 0) tmp = 0;
|
||||
else
|
||||
{
|
||||
len0--;
|
||||
if (!hawk_is_bch_type(str0[len0], ctype))
|
||||
tmp = 1;
|
||||
do
|
||||
{
|
||||
tmp = 0;
|
||||
break;
|
||||
len0--;
|
||||
if (!hawk_is_bch_type(str0[len0], ctype))
|
||||
{
|
||||
tmp = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (len0 > 0);
|
||||
}
|
||||
while (len0 > 0);
|
||||
|
||||
hawk_rtx_freevalbcstr (rtx, a0, str0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_ooch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
|
||||
str0 = hawk_rtx_getvaloocstr(rtx, a0, &len0);
|
||||
if (!str0) return -1;
|
||||
|
||||
if (len0 <= 0) tmp = 0;
|
||||
else
|
||||
default:
|
||||
{
|
||||
tmp = 1;
|
||||
do
|
||||
hawk_ooch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
|
||||
str0 = hawk_rtx_getvaloocstr(rtx, a0, &len0);
|
||||
if (HAWK_UNLIKELY(!str0)) return -1;
|
||||
|
||||
if (len0 <= 0) tmp = 0;
|
||||
else
|
||||
{
|
||||
len0--;
|
||||
if (!hawk_is_ooch_type(str0[len0], ctype))
|
||||
tmp = 1;
|
||||
do
|
||||
{
|
||||
tmp = 0;
|
||||
break;
|
||||
len0--;
|
||||
if (!hawk_is_ooch_type(str0[len0], ctype))
|
||||
{
|
||||
tmp = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (len0 > 0);
|
||||
}
|
||||
while (len0 > 0);
|
||||
hawk_rtx_freevaloocstr (rtx, a0, str0);
|
||||
break;
|
||||
}
|
||||
hawk_rtx_freevaloocstr (rtx, a0, str0);
|
||||
}
|
||||
|
||||
a0 = hawk_rtx_makeintval (rtx, tmp);
|
||||
if (!a0) return -1;
|
||||
if (HAWK_UNLIKELY(!a0)) return -1;
|
||||
|
||||
hawk_rtx_setretval (rtx, a0);
|
||||
return 0;
|
||||
@ -248,6 +273,59 @@ static int fnc_isxdigit (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
return is_class(rtx, HAWK_OOCH_PROP_XDIGIT);
|
||||
}
|
||||
|
||||
static int fnc_frombcharcode (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
/* 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" */
|
||||
|
||||
/* TODO: how to support byte string? */
|
||||
|
||||
hawk_val_t* retv;
|
||||
hawk_oow_t nargs, i;
|
||||
hawk_bchu_t* ptr0; /* to guarantee the unsigned code conversion */
|
||||
|
||||
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_makembsvalwithbchars(rtx, HAWK_NULL, nargs);
|
||||
if (HAWK_UNLIKELY(!retv)) return -1;
|
||||
|
||||
ptr0 = (hawk_bchu_t*)((hawk_val_mbs_t*)retv)->val.ptr;
|
||||
|
||||
for (i = 0; i < nargs; i++)
|
||||
{
|
||||
hawk_val_t* a0;
|
||||
hawk_int_t cc;
|
||||
|
||||
a0 = hawk_rtx_getarg(rtx, i);
|
||||
if (hawk_rtx_valtoint(rtx, a0, &cc) <= -1)
|
||||
{
|
||||
hawk_rtx_freeval (rtx, retv, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr0[i] = cc;
|
||||
}
|
||||
}
|
||||
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_fromcharcode (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
/* create a string from a series of character codes.
|
||||
@ -255,6 +333,8 @@ static int fnc_fromcharcode (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
* - str::fromcharcode(65) for 'A'
|
||||
* - str::fromcharcode(65, 66, 67) for "ABC" */
|
||||
|
||||
/* TODO: how to support byte string? */
|
||||
|
||||
hawk_val_t* retv;
|
||||
hawk_oow_t nargs, i;
|
||||
hawk_oochu_t* ptr0; /* to guarantee the unsigned code conversion */
|
||||
@ -318,49 +398,50 @@ static int fnc_tocharcode (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
pos--; /* 1 based indexing. range check to be done before accessing below */
|
||||
}
|
||||
|
||||
if (HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MBS)
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, a0))
|
||||
{
|
||||
hawk_bch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
|
||||
str0 = ((hawk_val_mbs_t*)a0)->val.ptr;
|
||||
len0 = ((hawk_val_mbs_t*)a0)->val.len;
|
||||
|
||||
if (pos >= 0 && pos < len0)
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_MBS:
|
||||
{
|
||||
#if defined(HAWK_OOCH_IS_BCH)
|
||||
/* typecasting in case hawk_bch_t is signed */
|
||||
iv = (unsigned char)str0[pos];
|
||||
#else
|
||||
iv = str0[pos];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_ooch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
hawk_bch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
|
||||
str0 = hawk_rtx_getvaloocstr(rtx, a0, &len0);
|
||||
if (!str0) return -1;
|
||||
str0 = hawk_rtx_getvalbcstr(rtx, a0, &len0);
|
||||
if (HAWK_UNLIKELY(!str0)) return -1;
|
||||
|
||||
if (pos >= 0 && pos < len0)
|
||||
{
|
||||
#if defined(HAWK_OOCH_IS_BCH)
|
||||
/* typecasting in case hawk_bch_t is signed */
|
||||
iv = (unsigned char)str0[pos];
|
||||
#else
|
||||
iv = str0[pos];
|
||||
#endif
|
||||
if (pos >= 0 && pos < len0)
|
||||
{
|
||||
/* typecasting in case hawk_bch_t is signed */
|
||||
iv = (hawk_bchu_t)str0[pos];
|
||||
}
|
||||
|
||||
hawk_rtx_freevalbcstr(rtx, a0, str0);
|
||||
break;
|
||||
}
|
||||
|
||||
hawk_rtx_freevaloocstr(rtx, a0, str0);
|
||||
default:
|
||||
{
|
||||
hawk_ooch_t* str0;
|
||||
hawk_oow_t len0;
|
||||
|
||||
str0 = hawk_rtx_getvaloocstr(rtx, a0, &len0);
|
||||
if (HAWK_UNLIKELY(!str0)) return -1;
|
||||
|
||||
if (pos >= 0 && pos < len0)
|
||||
{
|
||||
/* typecasting in case hawk_bch_t is signed */
|
||||
iv = (hawk_oochu_t)str0[pos];
|
||||
}
|
||||
|
||||
hawk_rtx_freevaloocstr(rtx, a0, str0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (iv >= 0)
|
||||
{
|
||||
retv = hawk_rtx_makeintval(rtx, iv);
|
||||
if (!retv) return -1;
|
||||
if (HAWK_UNLIKELY(!retv)) return -1;
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
}
|
||||
|
||||
@ -498,6 +579,22 @@ static int fnc_tonum (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, a0))
|
||||
{
|
||||
case HAWK_VAL_BCHR:
|
||||
{
|
||||
/* if the value is known to be a string, it supports the optional
|
||||
* base parameter */
|
||||
hawk_val_t* a1 = hawk_rtx_getarg(rtx, 1);
|
||||
hawk_int_t base;
|
||||
hawk_bch_t tmp = HAWK_RTX_GETBCHRFROMVAL(rtx, a0);
|
||||
|
||||
if (hawk_rtx_valtoint(rtx, a1, &base) <= -1) return -1;
|
||||
rx = hawk_bchars_to_num(
|
||||
HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, 0, HAWK_RTX_IS_STRIPSTRSPC_ON(rtx), base),
|
||||
&tmp, 1, &lv, &rv
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case HAWK_VAL_MBS:
|
||||
{
|
||||
/* if the value is known to be a byte string, it supports the optional
|
||||
@ -595,38 +692,45 @@ static int fnc_subchar (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
|
||||
lindex = lindex - 1;
|
||||
|
||||
if (HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MBS)
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, a0))
|
||||
{
|
||||
hawk_bch_t* str;
|
||||
hawk_oow_t len;
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_MBS:
|
||||
{
|
||||
hawk_bch_t* str;
|
||||
hawk_oow_t len;
|
||||
|
||||
str = ((hawk_val_mbs_t*)a0)->val.ptr;
|
||||
len = ((hawk_val_mbs_t*)a0)->val.len;
|
||||
str = hawk_rtx_getvalbcstr(rtx, a0, &len);
|
||||
if (!str) return -1;
|
||||
|
||||
if (lindex >= 0 && lindex < (hawk_int_t)len)
|
||||
r = hawk_rtx_makebchrval(rtx, str[lindex]);
|
||||
else
|
||||
r = hawk_rtx_makenilval(rtx);
|
||||
if (lindex >= 0 && lindex < (hawk_int_t)len)
|
||||
r = hawk_rtx_makebchrval(rtx, str[lindex]);
|
||||
else
|
||||
r = hawk_rtx_makenilval(rtx);
|
||||
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_ooch_t* str;
|
||||
hawk_oow_t len;
|
||||
hawk_rtx_freevalbcstr (rtx, a0, str);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
hawk_ooch_t* str;
|
||||
hawk_oow_t len;
|
||||
|
||||
str = hawk_rtx_getvaloocstr(rtx, a0, &len);
|
||||
if (!str) return -1;
|
||||
str = hawk_rtx_getvaloocstr(rtx, a0, &len);
|
||||
if (!str) return -1;
|
||||
|
||||
if (lindex >= 0 && lindex < (hawk_int_t)len)
|
||||
r = hawk_rtx_makecharval(rtx, str[lindex]);
|
||||
else
|
||||
r = hawk_rtx_makenilval(rtx);
|
||||
if (lindex >= 0 && lindex < (hawk_int_t)len)
|
||||
r = hawk_rtx_makecharval(rtx, str[lindex]);
|
||||
else
|
||||
r = hawk_rtx_makenilval(rtx);
|
||||
|
||||
hawk_rtx_freevaloocstr (rtx, a0, str);
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
hawk_rtx_freevaloocstr (rtx, a0, str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
hawk_rtx_setretval (rtx, r);
|
||||
return 0;
|
||||
}
|
||||
@ -650,40 +754,41 @@ struct inttab_t
|
||||
static fnctab_t fnctab[] =
|
||||
{
|
||||
/* keep this table sorted for binary search in query(). */
|
||||
{ HAWK_T("fromcharcode"), { { 0, A_MAX, HAWK_NULL }, fnc_fromcharcode, 0 } },
|
||||
{ HAWK_T("frommbs"), { { 1, 2, HAWK_NULL }, fnc_frommbs, 0 } },
|
||||
{ HAWK_T("gsub"), { { 2, 3, HAWK_T("xvr")}, hawk_fnc_gsub, 0 } },
|
||||
{ HAWK_T("index"), { { 2, 3, HAWK_NULL }, hawk_fnc_index, 0 } },
|
||||
{ HAWK_T("isalnum"), { { 1, 1, HAWK_NULL }, fnc_isalnum, 0 } },
|
||||
{ HAWK_T("isalpha"), { { 1, 1, HAWK_NULL }, fnc_isalpha, 0 } },
|
||||
{ HAWK_T("isblank"), { { 1, 1, HAWK_NULL }, fnc_isblank, 0 } },
|
||||
{ HAWK_T("iscntrl"), { { 1, 1, HAWK_NULL }, fnc_iscntrl, 0 } },
|
||||
{ HAWK_T("isdigit"), { { 1, 1, HAWK_NULL }, fnc_isdigit, 0 } },
|
||||
{ HAWK_T("isgraph"), { { 1, 1, HAWK_NULL }, fnc_isgraph, 0 } },
|
||||
{ HAWK_T("islower"), { { 1, 1, HAWK_NULL }, fnc_islower, 0 } },
|
||||
{ HAWK_T("isprint"), { { 1, 1, HAWK_NULL }, fnc_isprint, 0 } },
|
||||
{ HAWK_T("ispunct"), { { 1, 1, HAWK_NULL }, fnc_ispunct, 0 } },
|
||||
{ HAWK_T("isspace"), { { 1, 1, HAWK_NULL }, fnc_isspace, 0 } },
|
||||
{ HAWK_T("isupper"), { { 1, 1, HAWK_NULL }, fnc_isupper, 0 } },
|
||||
{ HAWK_T("isxdigit"), { { 1, 1, HAWK_NULL }, fnc_isxdigit, 0 } },
|
||||
{ HAWK_T("length"), { { 1, 1, HAWK_NULL }, hawk_fnc_length, 0 } },
|
||||
{ HAWK_T("ltrim"), { { 1, 1, HAWK_NULL }, fnc_ltrim, 0 } },
|
||||
{ HAWK_T("match"), { { 2, 4, HAWK_T("vxvr") }, hawk_fnc_match, 0 } },
|
||||
{ HAWK_T("normspace"), { { 1, 1, HAWK_NULL }, fnc_normspace, 0 } }, /* deprecated, use trim("xxx", str::TRIM_PAC_SPACES) */
|
||||
{ HAWK_T("printf"), { { 1, A_MAX, HAWK_NULL }, hawk_fnc_sprintf, 0 } },
|
||||
{ HAWK_T("rindex"), { { 2, 3, HAWK_NULL }, hawk_fnc_rindex, 0 } },
|
||||
{ HAWK_T("rtrim"), { { 1, 1, HAWK_NULL }, fnc_rtrim, 0 } },
|
||||
{ HAWK_T("split"), { { 2, 3, HAWK_T("vrx") }, hawk_fnc_split, 0 } },
|
||||
{ HAWK_T("splita"), { { 2, 3, HAWK_T("vrx") }, hawk_fnc_splita, 0 } }, /* split to array. asplit is not a good name for this */
|
||||
{ HAWK_T("sub"), { { 2, 3, HAWK_T("xvr") }, hawk_fnc_sub, 0 } },
|
||||
{ HAWK_T("subchar"), { { 2, 2, HAWK_NULL }, fnc_subchar, 0 } },
|
||||
{ HAWK_T("substr"), { { 2, 3, HAWK_NULL }, hawk_fnc_substr, 0 } },
|
||||
{ HAWK_T("tocharcode"), { { 1, 2, HAWK_NULL }, fnc_tocharcode, 0 } },
|
||||
{ HAWK_T("tolower"), { { 1, 1, HAWK_NULL }, hawk_fnc_tolower, 0 } },
|
||||
{ HAWK_T("tombs"), { { 1, 2, HAWK_NULL }, fnc_tombs, 0 } },
|
||||
{ HAWK_T("tonum"), { { 1, 2, HAWK_NULL }, fnc_tonum, 0 } },
|
||||
{ HAWK_T("toupper"), { { 1, 1, HAWK_NULL }, hawk_fnc_toupper, 0 } },
|
||||
{ HAWK_T("trim"), { { 1, 2, HAWK_NULL }, fnc_trim, 0 } }
|
||||
{ HAWK_T("frombcharcode"), { { 0, A_MAX, HAWK_NULL }, fnc_frombcharcode, 0 } },
|
||||
{ HAWK_T("fromcharcode"), { { 0, A_MAX, HAWK_NULL }, fnc_fromcharcode, 0 } },
|
||||
{ HAWK_T("frommbs"), { { 1, 2, HAWK_NULL }, fnc_frommbs, 0 } },
|
||||
{ HAWK_T("gsub"), { { 2, 3, HAWK_T("xvr")}, hawk_fnc_gsub, 0 } },
|
||||
{ HAWK_T("index"), { { 2, 3, HAWK_NULL }, hawk_fnc_index, 0 } },
|
||||
{ HAWK_T("isalnum"), { { 1, 1, HAWK_NULL }, fnc_isalnum, 0 } },
|
||||
{ HAWK_T("isalpha"), { { 1, 1, HAWK_NULL }, fnc_isalpha, 0 } },
|
||||
{ HAWK_T("isblank"), { { 1, 1, HAWK_NULL }, fnc_isblank, 0 } },
|
||||
{ HAWK_T("iscntrl"), { { 1, 1, HAWK_NULL }, fnc_iscntrl, 0 } },
|
||||
{ HAWK_T("isdigit"), { { 1, 1, HAWK_NULL }, fnc_isdigit, 0 } },
|
||||
{ HAWK_T("isgraph"), { { 1, 1, HAWK_NULL }, fnc_isgraph, 0 } },
|
||||
{ HAWK_T("islower"), { { 1, 1, HAWK_NULL }, fnc_islower, 0 } },
|
||||
{ HAWK_T("isprint"), { { 1, 1, HAWK_NULL }, fnc_isprint, 0 } },
|
||||
{ HAWK_T("ispunct"), { { 1, 1, HAWK_NULL }, fnc_ispunct, 0 } },
|
||||
{ HAWK_T("isspace"), { { 1, 1, HAWK_NULL }, fnc_isspace, 0 } },
|
||||
{ HAWK_T("isupper"), { { 1, 1, HAWK_NULL }, fnc_isupper, 0 } },
|
||||
{ HAWK_T("isxdigit"), { { 1, 1, HAWK_NULL }, fnc_isxdigit, 0 } },
|
||||
{ HAWK_T("length"), { { 1, 1, HAWK_NULL }, hawk_fnc_length, 0 } },
|
||||
{ HAWK_T("ltrim"), { { 1, 1, HAWK_NULL }, fnc_ltrim, 0 } },
|
||||
{ HAWK_T("match"), { { 2, 4, HAWK_T("vxvr") }, hawk_fnc_match, 0 } },
|
||||
{ HAWK_T("normspace"), { { 1, 1, HAWK_NULL }, fnc_normspace, 0 } }, /* deprecated, use trim("xxx", str::TRIM_PAC_SPACES) */
|
||||
{ HAWK_T("printf"), { { 1, A_MAX, HAWK_NULL }, hawk_fnc_sprintf, 0 } },
|
||||
{ HAWK_T("rindex"), { { 2, 3, HAWK_NULL }, hawk_fnc_rindex, 0 } },
|
||||
{ HAWK_T("rtrim"), { { 1, 1, HAWK_NULL }, fnc_rtrim, 0 } },
|
||||
{ HAWK_T("split"), { { 2, 3, HAWK_T("vrx") }, hawk_fnc_split, 0 } },
|
||||
{ HAWK_T("splita"), { { 2, 3, HAWK_T("vrx") }, hawk_fnc_splita, 0 } }, /* split to array. asplit is not a good name for this */
|
||||
{ HAWK_T("sub"), { { 2, 3, HAWK_T("xvr") }, hawk_fnc_sub, 0 } },
|
||||
{ HAWK_T("subchar"), { { 2, 2, HAWK_NULL }, fnc_subchar, 0 } },
|
||||
{ HAWK_T("substr"), { { 2, 3, HAWK_NULL }, hawk_fnc_substr, 0 } },
|
||||
{ HAWK_T("tocharcode"), { { 1, 2, HAWK_NULL }, fnc_tocharcode, 0 } },
|
||||
{ HAWK_T("tolower"), { { 1, 1, HAWK_NULL }, hawk_fnc_tolower, 0 } },
|
||||
{ HAWK_T("tombs"), { { 1, 2, HAWK_NULL }, fnc_tombs, 0 } },
|
||||
{ HAWK_T("tonum"), { { 1, 2, HAWK_NULL }, fnc_tonum, 0 } },
|
||||
{ HAWK_T("toupper"), { { 1, 1, HAWK_NULL }, hawk_fnc_toupper, 0 } },
|
||||
{ HAWK_T("trim"), { { 1, 2, HAWK_NULL }, fnc_trim, 0 } }
|
||||
};
|
||||
|
||||
static inttab_t inttab[] =
|
||||
|
@ -4666,7 +4666,7 @@ static hawk_nde_t* parse_primary_char (hawk_t* hawk, const hawk_loc_t* xloc)
|
||||
{
|
||||
hawk_nde_char_t* nde;
|
||||
|
||||
nde = (hawk_nde_char_t*)hawk_callocmem (hawk, HAWK_SIZEOF(*nde));
|
||||
nde = (hawk_nde_char_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*nde));
|
||||
if (HAWK_UNLIKELY(!nde))
|
||||
{
|
||||
ADJERR_LOC (hawk, xloc);
|
||||
@ -4691,7 +4691,7 @@ static hawk_nde_t* parse_primary_bchr (hawk_t* hawk, const hawk_loc_t* xloc)
|
||||
{
|
||||
hawk_nde_bchr_t* nde;
|
||||
|
||||
nde = (hawk_nde_bchr_t*)hawk_callocmem (hawk, HAWK_SIZEOF(*nde));
|
||||
nde = (hawk_nde_bchr_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*nde));
|
||||
if (HAWK_UNLIKELY(!nde))
|
||||
{
|
||||
ADJERR_LOC (hawk, xloc);
|
||||
@ -4717,7 +4717,7 @@ static hawk_nde_t* parse_primary_int (hawk_t* hawk, const hawk_loc_t* xloc)
|
||||
hawk_nde_int_t* nde;
|
||||
|
||||
/* create the node for the literal */
|
||||
nde = (hawk_nde_int_t*)new_int_node (
|
||||
nde = (hawk_nde_int_t*)new_int_node(
|
||||
hawk,
|
||||
hawk_oochars_to_int (HAWK_OOECS_PTR(hawk->tok.name), HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOCHARS_TO_INT_MAKE_OPTION(0, 0, 0), HAWK_NULL, HAWK_NULL),
|
||||
xloc
|
||||
@ -4801,7 +4801,7 @@ static hawk_nde_t* parse_primary_mbs (hawk_t* hawk, const hawk_loc_t* xloc)
|
||||
hawk_nde_mbs_t* nde;
|
||||
|
||||
nde = (hawk_nde_mbs_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*nde));
|
||||
if (nde == HAWK_NULL)
|
||||
if (HAWK_UNLIKELY(!nde))
|
||||
{
|
||||
ADJERR_LOC (hawk, xloc);
|
||||
return HAWK_NULL;
|
||||
@ -5212,7 +5212,7 @@ static hawk_nde_t* parse_primary (hawk_t* hawk, const hawk_loc_t* xloc)
|
||||
hawk_loc_t ploc;
|
||||
|
||||
left = parse_primary_nopipe(hawk, xloc);
|
||||
if (left == HAWK_NULL) goto oops;
|
||||
if (!left) goto oops;
|
||||
|
||||
/* handle the piping part */
|
||||
do
|
||||
@ -5288,7 +5288,7 @@ static hawk_nde_t* parse_primary (hawk_t* hawk, const hawk_loc_t* xloc)
|
||||
|
||||
novar:
|
||||
nde = (hawk_nde_getline_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*nde));
|
||||
if (nde == HAWK_NULL)
|
||||
if (HAWK_UNLIKELY(!nde))
|
||||
{
|
||||
ADJERR_LOC (hawk, xloc);
|
||||
goto oops;
|
||||
@ -7243,7 +7243,7 @@ static int deparse (hawk_t* hawk)
|
||||
*/
|
||||
}
|
||||
|
||||
if (flush_out (hawk) <= -1) EXIT_DEPARSE ();
|
||||
if (flush_out(hawk) <= -1) EXIT_DEPARSE ();
|
||||
|
||||
exit_deparse:
|
||||
if (hawk->sio.outf(hawk, HAWK_SIO_CMD_CLOSE, &hawk->sio.arg, HAWK_NULL, 0) != 0 && n == 0) n = -1;
|
||||
|
@ -996,9 +996,21 @@ int hawk_rtx_writeioval (hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* name,
|
||||
|
||||
switch (vtype)
|
||||
{
|
||||
case HAWK_VAL_CHAR:
|
||||
{
|
||||
hawk_ooch_t tmp = HAWK_RTX_GETCHARFROMVAL(rtx, v);
|
||||
return hawk_rtx_writeiostr(rtx, out_type, name, &tmp, 1);
|
||||
}
|
||||
|
||||
case HAWK_VAL_STR:
|
||||
return hawk_rtx_writeiostr(rtx, out_type, name, ((hawk_val_str_t*)v)->val.ptr, ((hawk_val_str_t*)v)->val.len);
|
||||
|
||||
case HAWK_VAL_BCHR:
|
||||
{
|
||||
hawk_bch_t tmp = HAWK_RTX_GETBCHRFROMVAL(rtx, v);
|
||||
return hawk_rtx_writeiobytes(rtx, out_type, name, &tmp, 1);
|
||||
}
|
||||
|
||||
case HAWK_VAL_MBS:
|
||||
return hawk_rtx_writeiobytes(rtx, out_type, name, ((hawk_val_mbs_t*)v)->val.ptr, ((hawk_val_mbs_t*)v)->val.len);
|
||||
|
||||
@ -1006,7 +1018,6 @@ int hawk_rtx_writeioval (hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* name,
|
||||
{
|
||||
hawk_rtx_valtostr_out_t out;
|
||||
int n;
|
||||
|
||||
out.type = HAWK_RTX_VALTOSTR_CPLDUP | HAWK_RTX_VALTOSTR_PRINT;
|
||||
if (hawk_rtx_valtostr(rtx, v, &out) <= -1) return -1;
|
||||
n = hawk_rtx_writeiostr(rtx, out_type, name, out.u.cpldup.ptr, out.u.cpldup.len);
|
||||
|
778
hawk/lib/run.c
778
hawk/lib/run.c
File diff suppressed because it is too large
Load Diff
@ -318,18 +318,18 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde)
|
||||
#if defined(HAWK_OOCH_IS_UCH)
|
||||
else if (tmp <= 0xFFFF)
|
||||
{
|
||||
hawk_fmttooocstr (hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\u%04x"), tmp);
|
||||
hawk_fmttooocstr (hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\u%04x"), (hawk_oochu_t)tmp);
|
||||
PUT_SRCSTR (hawk, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_fmttooocstr (hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\U%08x"), tmp);
|
||||
hawk_fmttooocstr (hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\U%08x"), (hawk_oochu_t)tmp);
|
||||
PUT_SRCSTR (hawk, buf);
|
||||
}
|
||||
#else
|
||||
else
|
||||
{
|
||||
hawk_fmttooocstr (hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\x%02x"), tmp);
|
||||
hawk_fmttooocstr (hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\x%02x"), (hawk_oochu_t)tmp);
|
||||
PUT_SRCSTR (hawk, buf);
|
||||
}
|
||||
#endif
|
||||
@ -349,10 +349,13 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde)
|
||||
else if (tmp == '\'')
|
||||
PUT_SRCSTR (hawk, HAWK_T("\\'"));
|
||||
else if (hawk_is_bch_print(tmp))
|
||||
PUT_SRCSTRN (hawk, &tmp, 1);
|
||||
{
|
||||
hawk_ooch_t oc = (hawk_bchu_t)tmp;
|
||||
PUT_SRCSTRN (hawk, &oc, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_fmttooocstr (hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\x%02x"), tmp);
|
||||
hawk_fmttooocstr (hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\x%02x"), (hawk_bchu_t)tmp);
|
||||
PUT_SRCSTR (hawk, buf);
|
||||
}
|
||||
|
||||
@ -364,9 +367,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde)
|
||||
{
|
||||
if (((hawk_nde_int_t*)nde)->str)
|
||||
{
|
||||
PUT_SRCSTRN (hawk,
|
||||
((hawk_nde_int_t*)nde)->str,
|
||||
((hawk_nde_int_t*)nde)->len);
|
||||
PUT_SRCSTRN (hawk, ((hawk_nde_int_t*)nde)->str, ((hawk_nde_int_t*)nde)->len);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -399,9 +400,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde)
|
||||
{
|
||||
if (((hawk_nde_flt_t*)nde)->str)
|
||||
{
|
||||
PUT_SRCSTRN (hawk,
|
||||
((hawk_nde_flt_t*)nde)->str,
|
||||
((hawk_nde_flt_t*)nde)->len);
|
||||
PUT_SRCSTRN (hawk, ((hawk_nde_flt_t*)nde)->str, ((hawk_nde_flt_t*)nde)->len);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -519,18 +518,18 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde)
|
||||
#if defined(HAWK_OOCH_IS_BCH)
|
||||
PUT_SRCSTRN (hawk, &ptr[i], 1);
|
||||
#else
|
||||
hawk_ooch_t wc = ptr[i];
|
||||
if (HAWK_BYTE_PRINTABLE(wc))
|
||||
hawk_ooch_t oc = (hawk_bchu_t)ptr[i];
|
||||
if (HAWK_BYTE_PRINTABLE(oc))
|
||||
{
|
||||
PUT_SRCSTRN (hawk, &wc, 1);
|
||||
PUT_SRCSTRN (hawk, &oc, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_bch_t xbuf[3];
|
||||
hawk_byte_to_bcstr (wc, xbuf, HAWK_COUNTOF(xbuf), 16, '0');
|
||||
hawk_byte_to_bcstr (oc, xbuf, HAWK_COUNTOF(xbuf), 16, '0');
|
||||
PUT_SRCSTR (hawk, HAWK_T("\\x"));
|
||||
wc = xbuf[0]; PUT_SRCSTRN (hawk, &wc, 1);
|
||||
wc = xbuf[1]; PUT_SRCSTRN (hawk, &wc, 1);
|
||||
oc = (hawk_bchu_t)xbuf[0]; PUT_SRCSTRN (hawk, &oc, 1);
|
||||
oc = (hawk_bchu_t)xbuf[1]; PUT_SRCSTRN (hawk, &oc, 1);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
@ -81,7 +81,7 @@ static HAWK_INLINE __utf8_t* get_utf8_slot (hawk_uch_t uc)
|
||||
|
||||
hawk_oow_t hawk_uc_to_utf8 (hawk_uch_t uc, hawk_bch_t* utf8, hawk_oow_t size)
|
||||
{
|
||||
__utf8_t* cur = get_utf8_slot (uc);
|
||||
__utf8_t* cur = get_utf8_slot(uc);
|
||||
|
||||
if (cur == HAWK_NULL) return 0; /* illegal character */
|
||||
|
||||
|
@ -3495,9 +3495,7 @@ int hawk_conv_bcstr_to_ucstr_with_cmgr (
|
||||
return n;
|
||||
}
|
||||
|
||||
int hawk_conv_uchars_to_bchars_with_cmgr (
|
||||
const hawk_uch_t* ucs, hawk_oow_t* ucslen,
|
||||
hawk_bch_t* bcs, hawk_oow_t* bcslen, hawk_cmgr_t* cmgr)
|
||||
int hawk_conv_uchars_to_bchars_with_cmgr (const hawk_uch_t* ucs, hawk_oow_t* ucslen, hawk_bch_t* bcs, hawk_oow_t* bcslen, hawk_cmgr_t* cmgr)
|
||||
{
|
||||
const hawk_uch_t* p = ucs;
|
||||
const hawk_uch_t* end = ucs + *ucslen;
|
||||
|
@ -66,7 +66,7 @@ struct hawk_val_rchunk_t
|
||||
* add a field to indicate if a value is static.
|
||||
*
|
||||
|
||||
#define HAWK_IS_STATICVAL(val) ((val) == HAWK_NULL || (val) == hawk_val_nil || (val) == hawk_val_zls || (val) == hawk_val_zlm)
|
||||
#define HAWK_IS_STATICVAL(val) ((val) == HAWK_NULL || (val) == hawk_val_nil || (val) == hawk_val_zls || (val) == hawk_val_zlbs)
|
||||
*/
|
||||
#define HAWK_IS_STATICVAL(val) ((val)->v_static)
|
||||
|
||||
@ -169,11 +169,14 @@ extern hawk_val_t* hawk_val_nil;
|
||||
/* represents an empty string */
|
||||
extern hawk_val_t* hawk_val_zls;
|
||||
|
||||
/* represents an empty byte string */
|
||||
extern hawk_val_t* hawk_val_zlbs;
|
||||
|
||||
|
||||
void hawk_rtx_freeval (
|
||||
hawk_rtx_t* rtx,
|
||||
hawk_val_t* val,
|
||||
int flags
|
||||
hawk_rtx_t* rtx,
|
||||
hawk_val_t* val,
|
||||
int flags
|
||||
);
|
||||
|
||||
void hawk_rtx_freevalchunk (
|
||||
|
151
hawk/lib/val.c
151
hawk/lib/val.c
@ -30,11 +30,11 @@
|
||||
|
||||
static hawk_val_nil_t hawk_nil = { HAWK_VAL_NIL, 0, 1, 0, 0 };
|
||||
static hawk_val_str_t hawk_zls = { HAWK_VAL_STR, 0, 1, 0, 0, { HAWK_T(""), 0 } };
|
||||
static hawk_val_mbs_t hawk_zlm = { HAWK_VAL_MBS, 0, 1, 0, 0, { HAWK_BT(""), 0 } };
|
||||
static hawk_val_mbs_t hawk_zlbs = { HAWK_VAL_MBS, 0, 1, 0, 0, { HAWK_BT(""), 0 } };
|
||||
|
||||
hawk_val_t* hawk_val_nil = (hawk_val_t*)&hawk_nil;
|
||||
hawk_val_t* hawk_val_zls = (hawk_val_t*)&hawk_zls;
|
||||
hawk_val_t* hawk_val_zlm = (hawk_val_t*)&hawk_zlm;
|
||||
hawk_val_t* hawk_val_zlbs = (hawk_val_t*)&hawk_zlbs;
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -734,7 +734,7 @@ hawk_val_t* hawk_rtx_makenumorstrvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_
|
||||
hawk_int_t l;
|
||||
hawk_flt_t r;
|
||||
|
||||
if (ptr[0] == '.' && len == 1) goto make_str;
|
||||
if (len == 1 && ptr[0] == '.') goto make_str;
|
||||
|
||||
x = hawk_uchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 1, HAWK_RTX_IS_STRIPSTRSPC_ON(rtx), 0), ptr, len, &l, &r);
|
||||
if (x == 0) return hawk_rtx_makeintval(rtx, l);
|
||||
@ -750,7 +750,7 @@ hawk_val_t* hawk_rtx_makenumorstrvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_
|
||||
hawk_int_t l;
|
||||
hawk_flt_t r;
|
||||
|
||||
if (ptr[0] == '.' && len == 1) goto make_str;
|
||||
if (len == 1 && ptr[0] == '.') goto make_str;
|
||||
|
||||
x = hawk_bchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 1, HAWK_RTX_IS_STRIPSTRSPC_ON(rtx), 0), ptr, len, &l, &r);
|
||||
if (x == 0) return hawk_rtx_makeintval(rtx, l);
|
||||
@ -838,7 +838,7 @@ static HAWK_INLINE hawk_val_t* make_mbs_val (hawk_rtx_t* rtx, const hawk_bch_t*
|
||||
hawk_oow_t i;
|
||||
#endif
|
||||
|
||||
if (HAWK_UNLIKELY(len1 <= 0 && len2 <= 0)) return hawk_val_zls;
|
||||
if (HAWK_UNLIKELY(len1 <= 0 && len2 <= 0)) return hawk_val_zlbs;
|
||||
aligned_len = HAWK_ALIGN_POW2((len1 + len2 + 1), HAWK_MBS_CACHE_BLOCK_UNIT);
|
||||
|
||||
#if defined(HAWK_ENABLE_MBS_CACHE)
|
||||
@ -887,7 +887,7 @@ hawk_val_t* hawk_rtx_makembsvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_t* uc
|
||||
hawk_bch_t* bcs;
|
||||
hawk_oow_t bcslen;
|
||||
|
||||
if (HAWK_UNLIKELY(len <= 0)) return hawk_val_zlm;
|
||||
if (HAWK_UNLIKELY(len <= 0)) return hawk_val_zlbs;
|
||||
|
||||
bcs = hawk_rtx_duputobchars(rtx, ucs, len, &bcslen);
|
||||
if (HAWK_UNLIKELY(!bcs)) return HAWK_NULL;
|
||||
@ -954,10 +954,13 @@ hawk_val_t* hawk_rtx_makenumormbsvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_
|
||||
hawk_int_t l;
|
||||
hawk_flt_t r;
|
||||
|
||||
if (len == 1 && ptr[0] == '.') goto make_str;
|
||||
|
||||
x = hawk_uchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 1, HAWK_RTX_IS_STRIPSTRSPC_ON(rtx), 0), ptr, len, &l, &r);
|
||||
if (x == 0) return hawk_rtx_makeintval(rtx, l);
|
||||
else if (x >= 1) return hawk_rtx_makefltval(rtx, r);
|
||||
|
||||
make_str:
|
||||
return hawk_rtx_makembsvalwithuchars(rtx, ptr, len);
|
||||
}
|
||||
|
||||
@ -967,10 +970,13 @@ hawk_val_t* hawk_rtx_makenumormbsvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_
|
||||
hawk_int_t l;
|
||||
hawk_flt_t r;
|
||||
|
||||
if (len == 1 && ptr[0] == '.') goto make_str;
|
||||
|
||||
x = hawk_bchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 1, HAWK_RTX_IS_STRIPSTRSPC_ON(rtx), 0), ptr, len, &l, &r);
|
||||
if (x == 0) return hawk_rtx_makeintval(rtx, l);
|
||||
else if (x >= 1) return hawk_rtx_makefltval(rtx, r);
|
||||
|
||||
make_str:
|
||||
return hawk_rtx_makembsvalwithbchars(rtx, ptr, len);
|
||||
}
|
||||
|
||||
@ -1465,6 +1471,7 @@ void hawk_rtx_freeval (hawk_rtx_t* rtx, hawk_val_t* val, int flags)
|
||||
break;
|
||||
}
|
||||
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_CHAR:
|
||||
{
|
||||
/* this never happens */
|
||||
@ -1713,9 +1720,12 @@ int hawk_rtx_valtobool (hawk_rtx_t* rtx, const hawk_val_t* val)
|
||||
{
|
||||
case HAWK_VAL_NIL:
|
||||
return 0;
|
||||
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_CHAR:
|
||||
/* return always true - treat it like a 1-letter string */
|
||||
return 1;
|
||||
|
||||
case HAWK_VAL_INT:
|
||||
return HAWK_RTX_GETINTFROMVAL(rtx, val) != 0;
|
||||
case HAWK_VAL_FLT:
|
||||
@ -2134,6 +2144,16 @@ int hawk_rtx_valtostr (hawk_rtx_t* rtx, const hawk_val_t* v, hawk_rtx_valtostr_o
|
||||
case HAWK_VAL_NIL:
|
||||
return str_to_str(rtx, HAWK_T(""), 0, out);
|
||||
|
||||
case HAWK_VAL_BCHR:
|
||||
{
|
||||
hawk_bch_t tmp = HAWK_RTX_GETBCHRFROMVAL(rtx, v);
|
||||
#if defined(HAWK_OOCH_IS_BCH)
|
||||
return str_to_str(rtx, &tmp, 1, out);
|
||||
#else
|
||||
return mbs_to_str(rtx, &tmp, 1, out);
|
||||
#endif
|
||||
}
|
||||
|
||||
case HAWK_VAL_CHAR:
|
||||
{
|
||||
hawk_ooch_t tmp = HAWK_RTX_GETCHARFROMVAL(rtx, v);
|
||||
@ -2416,8 +2436,33 @@ void hawk_rtx_freevaloocstr (hawk_rtx_t* rtx, hawk_val_t* v, hawk_ooch_t* str)
|
||||
|
||||
hawk_bch_t* hawk_rtx_getvalbcstrwithcmgr (hawk_rtx_t* rtx, hawk_val_t* v, hawk_oow_t* len, hawk_cmgr_t* cmgr)
|
||||
{
|
||||
hawk_bch_t c;
|
||||
hawk_oow_t l;
|
||||
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, v))
|
||||
{
|
||||
case HAWK_VAL_NIL:
|
||||
c = '\0';
|
||||
l = 0;
|
||||
goto bctos;
|
||||
case HAWK_VAL_BCHR:
|
||||
c = HAWK_RTX_GETBCHRFROMVAL(rtx, v);
|
||||
l = 1;
|
||||
bctos:
|
||||
if (rtx->bctos.fi) /* free slot available */
|
||||
{
|
||||
/* use a bctos slot to avoid duplication */
|
||||
hawk_oow_t fi;
|
||||
fi = rtx->bctos.fi;
|
||||
rtx->bctos.fi = rtx->bctos.b[rtx->bctos.fi].c[0];
|
||||
rtx->bctos.b[fi].c[0] = c;
|
||||
rtx->bctos.b[fi].c[1] = '\0';
|
||||
if (len) *len = l;
|
||||
HAWK_ASSERT ((void*)&rtx->bctos.b[fi] == (void*)rtx->bctos.b[fi].c);
|
||||
return rtx->bctos.b[fi].c;
|
||||
}
|
||||
goto duplicate;
|
||||
|
||||
case HAWK_VAL_MBS:
|
||||
#if 0
|
||||
plain_mbs:
|
||||
@ -2436,19 +2481,8 @@ 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:
|
||||
duplicate:
|
||||
return hawk_rtx_valtobcstrdupwithcmgr(rtx, v, len, cmgr);
|
||||
}
|
||||
}
|
||||
@ -2457,6 +2491,22 @@ void hawk_rtx_freevalbcstr (hawk_rtx_t* rtx, hawk_val_t* v, hawk_bch_t* str)
|
||||
{
|
||||
switch (HAWK_RTX_GETVALTYPE(rtx, v))
|
||||
{
|
||||
case HAWK_VAL_NIL:
|
||||
case HAWK_VAL_BCHR:
|
||||
{
|
||||
hawk_bctos_b_t* b = (hawk_bctos_b_t*)str;
|
||||
if (b >= &rtx->bctos.b[0] && b < &rtx->bctos.b[HAWK_COUNTOF(rtx->bctos.b)])
|
||||
{
|
||||
hawk_oow_t fi;
|
||||
fi = b - &rtx->bctos.b[0];
|
||||
rtx->bctos.b[fi].c[0] = rtx->bctos.fi;
|
||||
rtx->bctos.fi = fi;
|
||||
break;
|
||||
}
|
||||
|
||||
goto freemem;
|
||||
}
|
||||
|
||||
case HAWK_VAL_MBS:
|
||||
#if 0
|
||||
plain_mbs:
|
||||
@ -2472,6 +2522,7 @@ void hawk_rtx_freevalbcstr (hawk_rtx_t* rtx, hawk_val_t* v, hawk_bch_t* str)
|
||||
#endif
|
||||
|
||||
default:
|
||||
freemem:
|
||||
hawk_rtx_freemem (rtx, str);
|
||||
break;
|
||||
}
|
||||
@ -2542,6 +2593,15 @@ int hawk_rtx_valtonum (hawk_rtx_t* rtx, const hawk_val_t* v, hawk_int_t* l, hawk
|
||||
*l = 0;
|
||||
return 0;
|
||||
|
||||
case HAWK_VAL_BCHR:
|
||||
{
|
||||
hawk_bch_t tmp = HAWK_RTX_GETBCHRFROMVAL(rtx, v);
|
||||
return hawk_bchars_to_num(
|
||||
HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, 0, HAWK_RTX_IS_STRIPSTRSPC_ON(rtx), 0),
|
||||
&tmp, 1, l, r
|
||||
);
|
||||
}
|
||||
|
||||
case HAWK_VAL_CHAR:
|
||||
{
|
||||
/* treat it as if it is a 1-letter string */
|
||||
@ -2651,17 +2711,39 @@ hawk_fun_t* hawk_rtx_valtofun (hawk_rtx_t* rtx, hawk_val_t* v)
|
||||
fun = ((hawk_val_fun_t*)v)->fun;
|
||||
break;
|
||||
|
||||
case HAWK_VAL_STR:
|
||||
if (hawk_count_oocstr(((hawk_val_str_t*)v)->val.ptr) != ((hawk_val_str_t*)v)->val.len) goto error_inval;
|
||||
fun = hawk_rtx_findfunwithoocstr(rtx, ((hawk_val_str_t*)v)->val.ptr);
|
||||
if (!fun) return HAWK_NULL;
|
||||
break;
|
||||
|
||||
case HAWK_VAL_BCHR:
|
||||
case HAWK_VAL_MBS:
|
||||
if (hawk_count_bcstr(((hawk_val_mbs_t*)v)->val.ptr) != ((hawk_val_mbs_t*)v)->val.len) goto error_inval;
|
||||
fun = hawk_rtx_findfunwithbcstr(rtx, ((hawk_val_mbs_t*)v)->val.ptr);
|
||||
{
|
||||
hawk_bcs_t x;
|
||||
x.ptr = hawk_rtx_getvalbcstr(rtx, v, &x.len);
|
||||
if (HAWK_UNLIKELY(!x.ptr)) return HAWK_NULL;
|
||||
if (hawk_count_bcstr(x.ptr) != x.len)
|
||||
{
|
||||
hawk_rtx_freevalbcstr (rtx, v, x.ptr);
|
||||
goto error_inval;
|
||||
}
|
||||
fun = hawk_rtx_findfunwithbcstr(rtx, x.ptr);
|
||||
hawk_rtx_freevalbcstr (rtx, v, x.ptr);
|
||||
if (!fun) return HAWK_NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
case HAWK_VAL_CHAR:
|
||||
case HAWK_VAL_STR:
|
||||
{
|
||||
hawk_oocs_t x;
|
||||
x.ptr = hawk_rtx_getvaloocstr(rtx, v, &x.len);
|
||||
if (HAWK_UNLIKELY(!x.ptr)) return HAWK_NULL;
|
||||
if (hawk_count_oocstr(x.ptr) != x.len)
|
||||
{
|
||||
hawk_rtx_freevaloocstr (rtx, v, x.ptr);
|
||||
goto error_inval;
|
||||
}
|
||||
fun = hawk_rtx_findfunwithoocstr(rtx, x.ptr);
|
||||
hawk_rtx_freevaloocstr (rtx, v, x.ptr);
|
||||
if (!fun) return HAWK_NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
error_inval:
|
||||
@ -2693,6 +2775,13 @@ hawk_int_t hawk_rtx_hashval (hawk_rtx_t* rtx, hawk_val_t* v)
|
||||
hv = 0;
|
||||
break;
|
||||
|
||||
case HAWK_VAL_BCHR:
|
||||
{
|
||||
hawk_bch_t tmp = HAWK_RTX_GETBCHRFROMVAL(rtx, v);
|
||||
hv = (hawk_int_t)hash((hawk_uint8_t*)&tmp, HAWK_SIZEOF(tmp));
|
||||
break;
|
||||
}
|
||||
|
||||
case HAWK_VAL_CHAR:
|
||||
{
|
||||
hawk_ooch_t tmp = HAWK_RTX_GETCHARFROMVAL(rtx, v);
|
||||
@ -3008,8 +3097,16 @@ void hawk_dprintval (hawk_rtx_t* run, hawk_val_t* val)
|
||||
break;
|
||||
}
|
||||
|
||||
case HAWK_VAL_BCHR:
|
||||
hawk_errputstrf (HAWK_T("%hc"), HAWK_GETBCHRFROMVAL(val));
|
||||
break;
|
||||
|
||||
case HAWK_VAL_CHAR:
|
||||
hawk_errputstrf (HAWK_T("%jc"), HAWK_GETCHARFROMVAL(val));
|
||||
break;
|
||||
|
||||
case HAWK_VAL_INT:
|
||||
hawk_errputstrf (HAWK_T("%jd"), (hawk_intmax_t)((hawk_val_int_t*)val)->val);
|
||||
hawk_errputstrf (HAWK_T("%jd"), (hawk_intmax_t)HAWK_GETINTFROMVAL(val));
|
||||
break;
|
||||
|
||||
case HAWK_VAL_FLT:
|
||||
|
@ -3,6 +3,11 @@
|
||||
|
||||
@include "ensure.inc";
|
||||
|
||||
function f(a, b, c)
|
||||
{
|
||||
return a + b + c;
|
||||
}
|
||||
|
||||
function call_by_ref_1(&a, b, &c)
|
||||
{
|
||||
c = "hello, world";
|
||||
@ -23,8 +28,17 @@ function call_by_ref_3(&x)
|
||||
|
||||
function main()
|
||||
{
|
||||
|
||||
{
|
||||
ensure (@b"" !== "", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (@b"" === "", 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (@b"" != "", 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (@b"" == "", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (@b' ' !== ' ', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (@b' ' === ' ', 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (@b' ' != ' ', 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (@b' ' == ' ', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure ((@nil == 'A'), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure ((@nil != 'A'), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure ((@nil > 'A'), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
@ -41,6 +55,14 @@ function main()
|
||||
|
||||
ensure (('A' == @b'A'), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (('\u00FF' == @b'\xFF'), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (('A' < @b'\xFF'), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure ((@b'A' < @b'\xFF'), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (('A' > @b'\xFF'), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure ((@b'A' > @b'\xFF'), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (('A' < @b'B'), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure ((@b'A' < @b'B'), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (('A' > @b'B'), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure ((@b'A' > @b'B'), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (("10" == 10), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (("10" == 10.00), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
@ -146,6 +168,11 @@ function main()
|
||||
ensure (length(b), 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (b[1], 99, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (b[2], "perfect", @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (hawk::call('f', 1, 2, 3), 6, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (hawk::call("f", 1, 2, 3), 6, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (hawk::call(@b'f', 1, 2, 3), 6, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (hawk::call(@b"f", 1, 2, 3), 6, @SCRIPTNAME, @SCRIPTLINE);
|
||||
}
|
||||
|
||||
|
||||
@ -262,6 +289,8 @@ function main()
|
||||
|
||||
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" @b'\xFF') === @b"hawk\xFF", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure ((str::subchar(@b"\xFF\xFE", 1) str::subchar(@b"\xFF\xFE", 2)) === @b"\xFF\xFE", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure ((@b"hawk" %% 10) === @b"hawk10", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (("hawk" %% 10) === "hawk10", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
@ -44,6 +44,54 @@ function main()
|
||||
gsub("\\\\", "A", y);
|
||||
ensure (x, "xAy", @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (y, "xAAy", @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
|
||||
x = y = @b"x\\\\y";
|
||||
gsub(/\\\\/, "A", x);
|
||||
gsub("\\\\", "A", y);
|
||||
ensure (x === @b"xAy", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (y === @b"xAAy", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
x = y = @b"x\\\\y";
|
||||
gsub(/\\\\/, 'A', x);
|
||||
gsub("\\\\", 'A', y);
|
||||
ensure (x === @b"xAy", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (y === @b"xAAy", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
x = y = "x\\\\y";
|
||||
gsub(/\\\\/, @b'A', x);
|
||||
gsub("\\\\", @b'A', y);
|
||||
ensure (x === "xAy", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (y === "xAAy", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
x = y = "x\\\\y";
|
||||
gsub(/\\\\/, @b"A", x);
|
||||
gsub("\\\\", @b"A", y);
|
||||
ensure (x === "xAy", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (y === "xAAy", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
x = y = '\\';
|
||||
gsub(/\\/, @b"A", x);
|
||||
gsub("\\\\", @b"A", y);
|
||||
ensure (x === "A", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (y === "A", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
x = y = '\\';
|
||||
gsub(/\\/, @b'A', x);
|
||||
gsub("\\\\", @b'A', y);
|
||||
ensure (x === "A", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
x = y = @b'\\';
|
||||
gsub(/\\/, @b"A", x);
|
||||
gsub("\\\\", @b"A", y);
|
||||
ensure (x === @b"A", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (y === @b"A", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
x = y = @b'\\';
|
||||
gsub(/\\/, @b'A', x);
|
||||
gsub("\\\\", @b'A', y);
|
||||
ensure (x === @b"A", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (y === @b"A", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
}
|
||||
|
||||
## gsub - POSIX rule for &, \&, \\&, \\\&
|
||||
@ -248,6 +296,10 @@ function main()
|
||||
|
||||
ensure (sprintf("%+d %d", 3, 4), "+3 4", @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (sprintf(@b"%+d %d", 3, 4), @b"+3 4", @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
|
||||
ensure (sprintf(@b'A') === @b"A", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (sprintf('A') === "A", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
}
|
||||
|
||||
{
|
||||
@ -282,29 +334,74 @@ function main()
|
||||
ensure (substr(1000+10000, 2) === "1000", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (substr(1000+5000, 2) === "000", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::subchar("abc", -1) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar("abc", 0) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar("abc", 1) === 'a', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar("abc", 2) === 'b', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar("abc", 3) === 'c', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar("abc", 4) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::subchar("abc", -1) === @nil, 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar("abc", 0) === @nil, 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar("abc", 1) === 'a', 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar("abc", 2) === 'b', 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar("abc", 3) === 'c', 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar("abc", 4) === @nil, 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar("☕⛄", -1) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar("☕⛄", 0) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar("☕⛄", 1) === '☕', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar("☕⛄", 2) === '⛄', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar("☕⛄", 3) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar("☕⛄", 4) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::subchar("☕⛄", -1) === @nil, 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar("☕⛄", 0) === @nil, 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar("☕⛄", 1) === '☕', 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar("☕⛄", 2) === '⛄', 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar("☕⛄", 3) === @nil, 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar("☕⛄", 4) === @nil, 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar(@b"abc", -1) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar(@b"abc", 0) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar(@b"abc", 1) === @b'a', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar(@b"abc", 2) === @b'b', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar(@b"abc", 3) === @b'c', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar(@b"abc", 4) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::subchar(@b"abc", -1) === @nil, 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar(@b"abc", 0) === @nil, 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar(@b"abc", 1) === @b'a', 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar(@b"abc", 2) === @b'b', 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar(@b"abc", 3) === @b'c', 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar(@b"abc", 4) === @nil, 1, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::subchar('a', 0) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar('a', 1) === 'a', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar('a', 2) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::subchar(@b'a', 0) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar(@b'a', 1) === @b'a', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar(@b'a', 2) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::subchar(123, 0) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar(123, 1) === '1', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar(123, 2) === '2', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar(123, 3) === '3', 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::subchar(123, 4) === @nil, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
}
|
||||
|
||||
{
|
||||
ensure (str::substr("☕Q⛄", 0) === "☕Q⛄", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::substr("☕Q⛄", 1) === "☕Q⛄", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::substr("☕Q⛄", 2) === "Q⛄", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::substr("☕Q⛄", 3) === "⛄", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
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('☕', 1, 4) === "☕", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::substr(@b"\xAD\xAA\xBB\CC", 2, 2) === @b"\xAA\xBB", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::substr(@b'\xAD', 1, 1) === @b"\xAD", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
}
|
||||
|
||||
{
|
||||
ensure (str::index("☕Q⛄X⛄Z", '⛄'), 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::index("☕Q⛄X⛄Z", "⛄"), 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::index("☕Q⛄X⛄Z", "Q⛄"), 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::rindex("☕Q⛄X⛄Z", '⛄'), 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::rindex("☕Q⛄X⛄Z", "⛄"), 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::rindex("☕Q⛄X⛄Z", "Q⛄"), 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::rindex("☕Q⛄X⛄Z", "Q⛄Q"), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::index(@b"\xFFQ\xABX\xABZ", @b'\xAB'), 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::index(@b"\xFFQ\xABX\xABZ", @b"\xAB"), 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::index(@b"\xFFQ\xABX\xABZ", @b"Q\xAB"), 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::rindex(@b"\xFFQ\xABX\xABZ", @b'\xAB'), 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::rindex(@b"\xFFQ\xABX\xABZ", @b"\xAB"), 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::rindex(@b"\xFFQ\xABX\xABZ", @b"Q\xAB"), 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::rindex(@b"\xFFQ\xABX\xABZ", @b"Q\xABQ"), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
}
|
||||
|
||||
{
|
||||
# split, str::split, str::splita
|
||||
@ -365,6 +462,26 @@ function main()
|
||||
ensure (a[3], "", @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[4], "b\t\tc", @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[5], "d", @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::split('a', a, /a/), 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[1] === "", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[2] === "", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::split('a', a, 'a'), 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[1] === "", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[2] === "", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::split('a', a, @b'a'), 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[1] === "", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[2] === "", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::split(@b'a', a, /a/), 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[1] === @b"", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[2] === @b"", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::split(@b'a', a, @b'a'), 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[1] === @b"", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (a[2] === @b"", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
}
|
||||
|
||||
|
||||
@ -413,10 +530,26 @@ function main()
|
||||
ensure (str::tolower(@b"ABC") === @b"abc", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
ensure (str::tocharcode(str::fromcharcode('2')), 2, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::tonum('a', 16), 10, @SCRIPTNAME, @SCRIPTNAME);
|
||||
ensure (str::tocharcode(@b'\xFF'), 0xFF, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::tocharcode('\u3321'), 0x3321, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::tocharcode(@b'\xFF', 0), @nil, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::tocharcode('\u3321', 0), @nil, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::tocharcode(@b'\xFF', 1), 0xFF, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::tocharcode('\u3321', 1), 0x3321, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::tocharcode(@b'\xFF', 2), @nil, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::tocharcode('\u3321', 2), @nil, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::tocharcode(str::fromcharcode('2')), 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::tonum('a', 16), 10, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::fromcharcode(65, 66, 67) === "ABC", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::frombcharcode(65, 66, 67) === @b"ABC", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
ensure (str::trim(" hello world ") === "hello world", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::trim(" hello world ", str::TRIM_PAC_SPACES) === "hello world", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::trim(@b" hello world ") === @b"hello world", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
ensure (str::trim(@b" hello world ", str::TRIM_PAC_SPACES) === @b"hello world", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
}
|
||||
|
||||
print "SUCCESS";
|
||||
|
Loading…
Reference in New Issue
Block a user