use hawk_rtx_getvaloocstr()/hawk_rtx_getfreeoocstr() more wherever possible

trying to make character handling sane
This commit is contained in:
hyung-hwan 2020-12-07 16:22:39 +00:00
parent dfb7b2aa2d
commit 792f38acae
7 changed files with 158 additions and 121 deletions

View File

@ -378,6 +378,12 @@ struct hawk_chain_t
hawk_chain_t* next;
};
typedef struct hawk_ctos_b_t hawk_ctos_b_t;
struct hawk_ctos_b_t
{
hawk_ooch_t c[2];
};
struct hawk_rtx_t
{
HAWK_RTX_HDR;
@ -411,6 +417,16 @@ struct hawk_rtx_t
hawk_val_chunk_t* rchunk;
} vmgr;
struct
{
#if defined(HAWK_OOCH_IS_UCH)
hawk_ctos_b_t b[512];
#else
hawk_ctos_b_t b[256]; /* it must not be larger than 256 */
#endif
hawk_oow_t fi;
} ctos; /* char/nil to string conversion */
struct
{
/* lists of values under gc management */

View File

@ -43,7 +43,7 @@ static int fnc_normspace (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
hawk_oow_t len0;
str0 = hawk_rtx_valtobcstrdup(rtx, a0, &len0);
if (!str0) return -1;
if (HAWK_UNLIKELY(!str0)) return -1;
len0 = hawk_compact_bchars(str0, len0);
retv = hawk_rtx_makembsvalwithbchars(rtx, str0, len0);
hawk_rtx_freemem (rtx, str0);
@ -54,7 +54,7 @@ static int fnc_normspace (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
hawk_oow_t len0;
str0 = hawk_rtx_valtooocstrdup(rtx, a0, &len0);
if (!str0) return -1;
if (HAWK_UNLIKELY(!str0)) return -1;
len0 = hawk_compact_oochars(str0, len0);
retv = hawk_rtx_makestrvalwithoochars(rtx, str0, len0);
hawk_rtx_freemem (rtx, str0);

View File

@ -489,7 +489,7 @@ static int recomp_record_fields (hawk_rtx_t* rtx, hawk_oow_t lv, const hawk_oocs
int hawk_rtx_truncrec (hawk_rtx_t* rtx, hawk_oow_t nflds)
{
hawk_val_t* v;
hawk_val_t* v = HAWK_NULL, * w;
hawk_ooch_t* ofs_free = HAWK_NULL, * ofs_ptr;
hawk_oow_t ofs_len, i;
hawk_ooecs_t tmp;
@ -509,62 +509,47 @@ int hawk_rtx_truncrec (hawk_rtx_t* rtx, hawk_oow_t nflds)
ofs_ptr = HAWK_T(" ");
ofs_len = 1;
}
else if (vtype == HAWK_VAL_STR)
{
ofs_ptr = ((hawk_val_str_t*)v)->val.ptr;
ofs_len = ((hawk_val_str_t*)v)->val.len;
}
else
{
hawk_rtx_valtostr_out_t out;
out.type = HAWK_RTX_VALTOSTR_CPLDUP;
if (hawk_rtx_valtostr(rtx, v, &out) <= -1) return -1;
ofs_ptr = out.u.cpldup.ptr;
ofs_len = out.u.cpldup.len;
ofs_ptr = hawk_rtx_getvaloocstr(rtx, v, &ofs_len);
if (HAWK_UNLIKELY(!ofs_ptr)) goto oops;
ofs_free = ofs_ptr;
}
}
if (hawk_ooecs_init(&tmp, hawk_rtx_getgem(rtx), HAWK_OOECS_LEN(&rtx->inrec.line)) <= -1)
{
if (ofs_free) hawk_rtx_freemem (rtx, ofs_free);
if (nflds > 1) hawk_rtx_refdownval (rtx, v);
return -1;
}
if (hawk_ooecs_init(&tmp, hawk_rtx_getgem(rtx), HAWK_OOECS_LEN(&rtx->inrec.line)) <= -1) goto oops;
for (i = 0; i < nflds; i++)
{
if (i > 0 && hawk_ooecs_ncat(&tmp,ofs_ptr,ofs_len) == (hawk_oow_t)-1)
{
hawk_ooecs_fini (&tmp);
if (ofs_free) hawk_rtx_freemem (rtx, ofs_free);
if (nflds > 1) hawk_rtx_refdownval (rtx, v);
return -1;
goto oops;
}
if (hawk_ooecs_ncat(&tmp, rtx->inrec.flds[i].ptr, rtx->inrec.flds[i].len) == (hawk_oow_t)-1)
{
hawk_ooecs_fini (&tmp);
if (ofs_free) hawk_rtx_freemem (rtx, ofs_free);
if (nflds > 1) hawk_rtx_refdownval (rtx, v);
return -1;
goto oops;
}
}
if (ofs_free) hawk_rtx_freemem (rtx, ofs_free);
if (nflds > 1) hawk_rtx_refdownval (rtx, v);
if (v)
{
if (ofs_free) hawk_rtx_freevaloocstr (rtx, v, ofs_free);
hawk_rtx_refdownval(rtx, v);
v = HAWK_NULL;
}
v = (hawk_val_t*)hawk_rtx_makestrvalwithoocs(rtx, HAWK_OOECS_OOCS(&tmp));
if (!v)
w = (hawk_val_t*)hawk_rtx_makestrvalwithoocs(rtx, HAWK_OOECS_OOCS(&tmp));
if (!w)
{
hawk_ooecs_fini (&tmp);
return -1;
}
if (HAWK_RTX_GETVALTYPE(rtx, rtx->inrec.d0) != HAWK_VAL_NIL) hawk_rtx_refdownval (rtx, rtx->inrec.d0);
rtx->inrec.d0 = v;
rtx->inrec.d0 = w;
hawk_rtx_refupval (rtx, rtx->inrec.d0);
hawk_ooecs_swap (&tmp, &rtx->inrec.line);
@ -577,4 +562,12 @@ int hawk_rtx_truncrec (hawk_rtx_t* rtx, hawk_oow_t nflds)
rtx->inrec.nflds = nflds;
return 0;
oops:
if (v)
{
if (ofs_free) hawk_rtx_freevaloocstr (rtx, v, ofs_free);
hawk_rtx_refdownval(rtx, v);
}
return -1;
}

View File

@ -325,26 +325,25 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t
case HAWK_GBL_CONVFMT:
{
hawk_oow_t i;
hawk_rtx_valtostr_out_t out;
hawk_oocs_t str;
out.type = HAWK_RTX_VALTOSTR_CPLDUP;
if (hawk_rtx_valtostr (rtx, val, &out) <= -1)
return -1;
str.ptr = hawk_rtx_valtooocstrdup(rtx, val, &str.len);
if (HAWK_UNLIKELY(!str.ptr)) return -1;
for (i = 0; i < out.u.cpldup.len; i++)
for (i = 0; i < str.len; i++)
{
if (out.u.cpldup.ptr[i] == HAWK_T('\0'))
if (str.ptr[i] == '\0')
{
/* '\0' is included in the value */
hawk_rtx_freemem (rtx, out.u.cpldup.ptr);
hawk_rtx_freemem (rtx, str.ptr);
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ECONVFMTCHR);
return -1;
}
}
if (rtx->gbl.convfmt.ptr) hawk_rtx_freemem (rtx, rtx->gbl.convfmt.ptr);
rtx->gbl.convfmt.ptr = out.u.cpldup.ptr;
rtx->gbl.convfmt.len = out.u.cpldup.len;
rtx->gbl.convfmt.ptr = str.ptr;
rtx->gbl.convfmt.len = str.len;
break;
}
@ -365,24 +364,12 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t
hawk_ooch_t* fs_ptr;
hawk_oow_t fs_len;
if (vtype == HAWK_VAL_STR)
{
fs_ptr = ((hawk_val_str_t*)val)->val.ptr;
fs_len = ((hawk_val_str_t*)val)->val.len;
}
else
{
hawk_rtx_valtostr_out_t out;
/* due to the expression evaluation rule, the
* regular expression can not be an assigned value */
HAWK_ASSERT (vtype != HAWK_VAL_REX);
out.type = HAWK_RTX_VALTOSTR_CPLDUP;
if (hawk_rtx_valtostr(rtx, val, &out) <= -1) return -1;
fs_ptr = out.u.cpldup.ptr;
fs_len = out.u.cpldup.len;
}
fs_ptr = hawk_rtx_getvaloocstr(rtx, val, &fs_len);
if (HAWK_UNLIKELY(!fs_ptr)) return -1;
if (fs_len > 1 && !(fs_len == 5 && fs_ptr[0] == '?'))
{
@ -393,7 +380,7 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t
if (hawk_rtx_buildrex(rtx, fs_ptr, fs_len, &rex, &irex) <= -1)
{
if (vtype != HAWK_VAL_STR) hawk_rtx_freemem (rtx, fs_ptr);
hawk_rtx_freevaloocstr (rtx, val, fs_ptr);
return -1;
}
@ -403,7 +390,7 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t
rtx->gbl.fs[1] = irex;
}
if (vtype != HAWK_VAL_STR) hawk_rtx_freemem (rtx, fs_ptr);
hawk_rtx_freevaloocstr (rtx, val, fs_ptr);
break;
}
@ -487,50 +474,51 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t
case HAWK_GBL_OFMT:
{
hawk_oow_t i;
hawk_rtx_valtostr_out_t out;
hawk_oocs_t str;
out.type = HAWK_RTX_VALTOSTR_CPLDUP;
if (hawk_rtx_valtostr(rtx, val, &out) <= -1) return -1;
str.ptr = hawk_rtx_valtooocstrdup(rtx, val, &str.len);
if (HAWK_UNLIKELY(!str.ptr)) return -1;
for (i = 0; i < out.u.cpldup.len; i++)
for (i = 0; i < str.len; i++)
{
if (out.u.cpldup.ptr[i] == HAWK_T('\0'))
if (str.ptr[i] == '\0')
{
hawk_rtx_freemem (rtx, out.u.cpldup.ptr);
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EOFMTCHR);
/* '\0' is included in the value */
hawk_rtx_freemem (rtx, str.ptr);
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ECONVFMTCHR);
return -1;
}
}
if (rtx->gbl.ofmt.ptr) hawk_rtx_freemem (rtx, rtx->gbl.ofmt.ptr);
rtx->gbl.ofmt.ptr = out.u.cpldup.ptr;
rtx->gbl.ofmt.len = out.u.cpldup.len;
break;
rtx->gbl.ofmt.ptr = str.ptr;
rtx->gbl.ofmt.len = str.len;
}
case HAWK_GBL_OFS:
{
hawk_rtx_valtostr_out_t out;
hawk_oocs_t str;
str.ptr = hawk_rtx_valtooocstrdup(rtx, val, &str.len);
if (HAWK_UNLIKELY(!str.ptr)) return -1;
out.type = HAWK_RTX_VALTOSTR_CPLDUP;
if (hawk_rtx_valtostr(rtx, val, &out) <= -1) return -1;
if (rtx->gbl.ofs.ptr) hawk_rtx_freemem (rtx, rtx->gbl.ofs.ptr);
rtx->gbl.ofs.ptr = out.u.cpldup.ptr;
rtx->gbl.ofs.len = out.u.cpldup.len;
rtx->gbl.ofs.ptr = str.ptr;
rtx->gbl.ofs.len = str.len;
break;
}
case HAWK_GBL_ORS:
{
hawk_rtx_valtostr_out_t out;
hawk_oocs_t str;
str.ptr = hawk_rtx_valtooocstrdup(rtx, val, &str.len);
if (HAWK_UNLIKELY(!str.ptr)) return -1;
out.type = HAWK_RTX_VALTOSTR_CPLDUP;
if (hawk_rtx_valtostr(rtx, val, &out) <= -1) return -1;
if (rtx->gbl.ors.ptr) hawk_rtx_freemem (rtx, rtx->gbl.ors.ptr);
rtx->gbl.ors.ptr = out.u.cpldup.ptr;
rtx->gbl.ors.len = out.u.cpldup.len;
rtx->gbl.ors.ptr = str.ptr;
rtx->gbl.ors.len = str.len;
break;
}
@ -607,14 +595,14 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t
case HAWK_GBL_SUBSEP:
{
hawk_rtx_valtostr_out_t out;
hawk_oocs_t str;
out.type = HAWK_RTX_VALTOSTR_CPLDUP;
if (hawk_rtx_valtostr(rtx, val, &out) <= -1) return -1;
str.ptr = hawk_rtx_valtooocstrdup(rtx, val, &str.len);
if (HAWK_UNLIKELY(!str.ptr)) return -1;
if (rtx->gbl.subsep.ptr) hawk_rtx_freemem (rtx, rtx->gbl.subsep.ptr);
rtx->gbl.subsep.ptr = out.u.cpldup.ptr;
rtx->gbl.subsep.len = out.u.cpldup.len;
rtx->gbl.subsep.ptr = str.ptr;
rtx->gbl.subsep.len = str.len;
break;
}
@ -835,6 +823,7 @@ hawk_rtx_t* hawk_rtx_open (hawk_t* hawk, hawk_oow_t xtnsize, hawk_rio_cbs_t* rio
{
hawk_rtx_t* rtx;
struct module_init_ctx_t mic;
hawk_oow_t i;
/* clear the hawk error code */
hawk_seterrnum (hawk, HAWK_NULL, HAWK_ENOERR);
@ -897,6 +886,16 @@ hawk_rtx_t* hawk_rtx_open (hawk_t* hawk, hawk_oow_t xtnsize, hawk_rio_cbs_t* rio
return HAWK_NULL;
}
/* chain the ctos slots */
rtx->ctos.fi = HAWK_COUNTOF(rtx->ctos.b) - 1;
for (i = HAWK_COUNTOF(rtx->ctos.b); i > 1;)
{
--i;
rtx->ctos.b[i].c[0] = i - 1;
}
/* rtx->ctos.b[0] is not used as the free index of 0 indicates the end of the list.
* see hawk_rtx_getvaloocstr(). */
return rtx;
}
@ -8335,12 +8334,12 @@ wp_mod_main:
break;
case HAWK_VAL_CHAR:
ch = (hawk_ooch_t)HAWK_RTX_GETCHARFROMVAL (rtx, v);
ch = (hawk_ooch_t)HAWK_RTX_GETCHARFROMVAL(rtx, v);
ch_len = 1;
break;
case HAWK_VAL_INT:
ch = (hawk_ooch_t)HAWK_RTX_GETINTFROMVAL (rtx, v);
ch = (hawk_ooch_t)HAWK_RTX_GETINTFROMVAL(rtx, v);
ch_len = 1;
break;

View File

@ -3246,7 +3246,7 @@ done:
if (rv)
{
hawk_rtx_refupval (rtx, rv);
ret = hawk_rtx_setrefval (rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 2), rv);
ret = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 2), rv);
hawk_rtx_refdownval (rtx, rv);
if (ret >= 0) hawk_rtx_setretval (rtx, HAWK_VAL_ZERO);
}

View File

@ -107,7 +107,7 @@ struct hawk_val_rchunk_t
#define HAWK_QUICKINT_TO_VTR(i) \
((hawk_val_t*)(((i) < 0)? HAWK_QUICKINT_TO_VTR_NEGATIVE(i): HAWK_QUICKINT_TO_VTR_POSITIVE(i)))
#define HAWK_QUICKCHAR_TO_VTR(i) (((hawk_uintptr_t)(i) << HAWK_VTR_NUM_TYPE_BITS) | HAWK_VTR_TYPE_BITS_QUICKCHAR)
#define HAWK_QUICKCHAR_TO_VTR(i) ((hawk_val_t*)(((hawk_uintptr_t)(i) << HAWK_VTR_NUM_TYPE_BITS) | HAWK_VTR_TYPE_BITS_QUICKCHAR))
#define HAWK_VTR_ZERO ((hawk_val_t*)HAWK_QUICKINT_TO_VTR_POSITIVE(0))
#define HAWK_VTR_ONE ((hawk_val_t*)HAWK_QUICKINT_TO_VTR_POSITIVE(1))

View File

@ -1663,7 +1663,8 @@ int hawk_rtx_valtobool (hawk_rtx_t* rtx, const hawk_val_t* val)
case HAWK_VAL_NIL:
return 0;
case HAWK_VAL_CHAR:
return HAWK_RTX_GETCHARFROMVAL(rtx, val) != 0;
/* 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:
@ -1949,7 +1950,7 @@ static int val_flt_to_str (hawk_rtx_t* rtx, const hawk_val_flt_t* v, hawk_rtx_va
fbu_inited = 1;
tmp = hawk_rtx_format(rtx, &buf, &fbu, tmp, tmp_len, (hawk_oow_t)-1, (hawk_nde_t*)v, &tmp_len);
if (tmp == HAWK_NULL) goto oops;
if (HAWK_UNLIKELY(!tmp)) goto oops;
switch (type)
{
@ -2270,8 +2271,32 @@ hawk_uch_t* hawk_rtx_valtoucstrdupwithcmgr (hawk_rtx_t* rtx, const hawk_val_t* v
hawk_ooch_t* hawk_rtx_getvaloocstrwithcmgr (hawk_rtx_t* rtx, hawk_val_t* v, hawk_oow_t* len, hawk_cmgr_t* cmgr)
{
hawk_ooch_t c;
hawk_oow_t l;
switch (HAWK_RTX_GETVALTYPE(rtx, v))
{
case HAWK_VAL_NIL:
c = '\0';
l = 0;
goto ctos;
case HAWK_VAL_CHAR:
c = HAWK_RTX_GETCHARFROMVAL(rtx, v);
l = 1;
ctos:
if (rtx->ctos.fi) /* free slot available */
{
/* use a ctos slot to avoid duplication */
hawk_oow_t fi;
fi = rtx->ctos.fi;
rtx->ctos.fi = rtx->ctos.b[rtx->ctos.fi].c[0];
rtx->ctos.b[fi].c[0] = c;
rtx->ctos.b[fi].c[1] = '\0';
if (len) *len = l;
return &rtx->ctos.b[fi];
}
goto duplicate;
case HAWK_VAL_STR:
#if 0
plain_str:
@ -2291,6 +2316,7 @@ hawk_ooch_t* hawk_rtx_getvaloocstrwithcmgr (hawk_rtx_t* rtx, hawk_val_t* v, hawk
#endif
default:
duplicate:
return hawk_rtx_valtooocstrdupwithcmgr(rtx, v, len, cmgr);
}
}
@ -2299,6 +2325,22 @@ void hawk_rtx_freevaloocstr (hawk_rtx_t* rtx, hawk_val_t* v, hawk_ooch_t* str)
{
switch (HAWK_RTX_GETVALTYPE(rtx, v))
{
case HAWK_VAL_NIL:
case HAWK_VAL_CHAR:
{
hawk_ctos_b_t* b = (hawk_ctos_b_t*)str;
if (b >= &rtx->ctos.b[0] && b < &rtx->ctos.b[HAWK_COUNTOF(rtx->ctos.b)])
{
hawk_oow_t fi;
fi = b - &rtx->ctos.b[0];
rtx->ctos.b[fi].c[0] = rtx->ctos.fi;
rtx->ctos.fi = fi;
break;
}
goto freemem;
}
case HAWK_VAL_STR:
#if 0
plain_str:
@ -2314,6 +2356,7 @@ void hawk_rtx_freevaloocstr (hawk_rtx_t* rtx, hawk_val_t* v, hawk_ooch_t* str)
#endif
default:
freemem:
hawk_rtx_freemem (rtx, str);
break;
}
@ -2436,8 +2479,14 @@ int hawk_rtx_valtonum (hawk_rtx_t* rtx, const hawk_val_t* v, hawk_int_t* l, hawk
return 0;
case HAWK_VAL_CHAR:
*l = HAWK_RTX_GETCHARFROMVAL(rtx, v);
return 0; /* long */
{
/* treat it as if it is a 1-letter string */
hawk_ooch_t tmp = HAWK_RTX_GETCHARFROMVAL(rtx, v);
return hawk_oochars_to_num(
HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, 0, HAWK_RTX_IS_STRIPSTRSPC_ON(rtx), 0),
&tmp, 1, l, r
);
}
case HAWK_VAL_INT:
*l = HAWK_RTX_GETINTFROMVAL(rtx, v);
@ -2748,41 +2797,21 @@ int hawk_rtx_setrefval (hawk_rtx_t* rtx, hawk_val_ref_t* ref, hawk_val_t* val)
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENONSCATOPOS);
return -1;
case HAWK_VAL_STR:
{
int x;
/* handle this separately from the default case
* for no duplication. jumping to the default case
* and callinghawk_rtx_valtooocstrdup() would also work, anyway. */
hawk_rtx_refupval (rtx, val);
x = hawk_rtx_setrec(rtx, (hawk_oow_t)ref->adr, &((hawk_val_str_t*)val)->val, 0);
hawk_rtx_refdownval (rtx, val);
return x;
}
case HAWK_VAL_MBS:
#if defined(HAWK_OOCH_IS_BCH)
{
/* same as str in the mchar mode */
int x;
hawk_rtx_refupval (rtx, val);
x = hawk_rtx_setrec(rtx, (hawk_oow_t)ref->adr, &((hawk_val_mbs_t*)val)->val, 0);
hawk_rtx_refdownval (rtx, val);
return x;
}
#endif
/* fall thru otherwise */
default:
{
hawk_oocs_t str;
int x;
str.ptr = hawk_rtx_valtooocstrdup(rtx, val, &str.len);
hawk_rtx_refupval (rtx, val);
x = hawk_rtx_setrec(rtx, (hawk_oow_t)ref->adr, &str, 0);
str.ptr = hawk_rtx_getvaloocstr(rtx, val, &str.len);
if (HAWK_UNLIKELY(!str.ptr))
{
hawk_rtx_refdownval (rtx, val);
return -1;
}
x = hawk_rtx_setrec(rtx, (hawk_oow_t)ref->adr, &str, 0);
hawk_rtx_freevaloocstr (rtx, val, str.ptr);
hawk_rtx_refdownval (rtx, val);
hawk_rtx_freemem (rtx, str.ptr);
return x;
}
}