diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 35ee3e37..982e52d6 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -2484,6 +2484,11 @@ qse_awk_val_t* qse_awk_rtx_makembsval ( qse_size_t len ); +qse_awk_val_t* qse_awk_rtx_makembsvalwithmxstr ( + qse_awk_rtx_t* rtx, + const qse_mcstr_t* mxstr +); + /** * The qse_awk_rtx_makerexval() function creates a regular expression value. * \return value on success, #QSE_NULL on failure @@ -2789,6 +2794,19 @@ QSE_EXPORT void qse_awk_rtx_freevalstr ( qse_char_t* str /**< string pointer */ ); + +QSE_EXPORT qse_mchar_t* qse_awk_rtx_getvalmbs ( + qse_awk_rtx_t* rtx, /**< runtime context */ + const qse_awk_val_t* val, /**< value to convert */ + qse_size_t* len /**< result length */ +); + +QSE_EXPORT void qse_awk_rtx_freevalmbs ( + qse_awk_rtx_t* rtx, /**< runtime context */ + const qse_awk_val_t* val, /**< value to convert */ + qse_mchar_t* str /**< string pointer */ +); + /** * The qse_awk_rtx_valtonum() function converts a value to a number. * If the value is converted to an integer, it is stored in the memory diff --git a/qse/lib/awk/fnc.c b/qse/lib/awk/fnc.c index 14205b59..b2ea0603 100644 --- a/qse/lib/awk/fnc.c +++ b/qse/lib/awk/fnc.c @@ -1303,48 +1303,95 @@ int qse_awk_fnc_sprintf (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) { qse_size_t nargs; qse_awk_val_t* a0; - qse_str_t out, fbu; - int out_inited = 0, fbu_inited = 0; - qse_cstr_t cs0; - qse_cstr_t x; + qse_awk_val_type_t vtype; nargs = qse_awk_rtx_getnargs (rtx); QSE_ASSERT (nargs > 0); - if (qse_str_init (&out, rtx->awk->mmgr, 256) <= -1) + a0 = qse_awk_rtx_getarg(rtx, 0); + vtype = QSE_AWK_RTX_GETVALTYPE(rtx, a0); + if (vtype == QSE_AWK_VAL_MBS) { - qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL); - goto oops; - } - out_inited = 1; + qse_mbs_t out, fbu; + int out_inited = 0, fbu_inited = 0; + qse_mcstr_t cs0; + qse_mcstr_t x; - if (qse_str_init (&fbu, rtx->awk->mmgr, 256) <= -1) + if (qse_mbs_init(&out, rtx->awk->mmgr, 256) <= -1) + { + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL); + goto oops_mbs; + } + out_inited = 1; + + if (qse_mbs_init(&fbu, rtx->awk->mmgr, 256) <= -1) + { + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL); + goto oops_mbs; + } + fbu_inited = 1; + + cs0.ptr = qse_awk_rtx_getvalmbs(rtx, a0, &cs0.len); + if (cs0.ptr == QSE_NULL) goto oops_mbs; + + x.ptr = qse_awk_rtx_formatmbs(rtx, &out, &fbu, cs0.ptr, cs0.len, nargs, QSE_NULL, &x.len); + qse_awk_rtx_freevalmbs (rtx, a0, cs0.ptr); + if (!x.ptr) goto oops_mbs; + + a0 = qse_awk_rtx_makembsvalwithmxstr(rtx, &x); + if (a0 == QSE_NULL) goto oops_mbs; + + qse_mbs_fini (&fbu); + qse_mbs_fini (&out); + qse_awk_rtx_setretval (rtx, a0); + return 0; + + oops_mbs: + if (fbu_inited) qse_mbs_fini (&fbu); + if (out_inited) qse_mbs_fini (&out); + return -1; + } + else { - qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL); - goto oops; + qse_str_t out, fbu; + int out_inited = 0, fbu_inited = 0; + qse_cstr_t cs0; + qse_cstr_t x; + + if (qse_str_init(&out, rtx->awk->mmgr, 256) <= -1) + { + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL); + goto oops; + } + out_inited = 1; + + if (qse_str_init(&fbu, rtx->awk->mmgr, 256) <= -1) + { + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL); + goto oops; + } + fbu_inited = 1; + + cs0.ptr = qse_awk_rtx_getvalstr(rtx, a0, &cs0.len); + if (cs0.ptr == QSE_NULL) goto oops; + + x.ptr = qse_awk_rtx_format(rtx, &out, &fbu, cs0.ptr, cs0.len, nargs, QSE_NULL, &x.len); + qse_awk_rtx_freevalstr (rtx, a0, cs0.ptr); + if (!x.ptr) goto oops; + + a0 = qse_awk_rtx_makestrvalwithxstr(rtx, &x); + if (a0 == QSE_NULL) goto oops; + + qse_str_fini (&fbu); + qse_str_fini (&out); + qse_awk_rtx_setretval (rtx, a0); + return 0; + + oops: + if (fbu_inited) qse_str_fini (&fbu); + if (out_inited) qse_str_fini (&out); + return -1; } - fbu_inited = 1; - - a0 = qse_awk_rtx_getarg (rtx, 0); - cs0.ptr = qse_awk_rtx_getvalstr(rtx, a0, &cs0.len); - if (cs0.ptr == QSE_NULL) goto oops; - - x.ptr = qse_awk_rtx_format(rtx, &out, &fbu, cs0.ptr, cs0.len, nargs, QSE_NULL, &x.len); - qse_awk_rtx_freevalstr (rtx, a0, cs0.ptr); - if (!x.ptr) goto oops; - - a0 = qse_awk_rtx_makestrvalwithxstr(rtx, &x); - if (a0 == QSE_NULL) goto oops; - - qse_str_fini (&fbu); - qse_str_fini (&out); - qse_awk_rtx_setretval (rtx, a0); - return 0; - -oops: - if (fbu_inited) qse_str_fini (&fbu); - if (out_inited) qse_str_fini (&out); - return -1; } static int fnc_int (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi) diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index ede25fca..2086fe66 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -422,6 +422,11 @@ qse_awk_val_t* qse_awk_rtx_makembsval (qse_awk_rtx_t* rtx, const qse_mchar_t* pt return (qse_awk_val_t*)val; } +qse_awk_val_t* qse_awk_rtx_makembsvalwithmxstr (qse_awk_rtx_t* rtx, const qse_mcstr_t* mxstr) +{ + return qse_awk_rtx_makembsval(rtx, mxstr->ptr, mxstr->len); +} + qse_awk_val_t* qse_awk_rtx_makerexval (qse_awk_rtx_t* rtx, const qse_cstr_t* str, void* code[2]) { qse_awk_val_rex_t* val; @@ -571,38 +576,38 @@ qse_awk_val_t* qse_awk_rtx_makemapvalwithdata (qse_awk_rtx_t* rtx, qse_awk_val_m switch (p->type) { case QSE_AWK_VAL_MAP_DATA_INT: - tmp = qse_awk_rtx_makeintval (rtx, *(qse_awk_int_t*)p->vptr); + tmp = qse_awk_rtx_makeintval(rtx, *(qse_awk_int_t*)p->vptr); break; case QSE_AWK_VAL_MAP_DATA_FLT: - tmp = qse_awk_rtx_makefltval (rtx, *(qse_awk_flt_t*)p->vptr); + tmp = qse_awk_rtx_makefltval(rtx, *(qse_awk_flt_t*)p->vptr); break; case QSE_AWK_VAL_MAP_DATA_STR: - tmp = qse_awk_rtx_makestrvalwithstr (rtx, (qse_char_t*)p->vptr); + tmp = qse_awk_rtx_makestrvalwithstr(rtx, (qse_char_t*)p->vptr); break; case QSE_AWK_VAL_MAP_DATA_MBS: - tmp = qse_awk_rtx_makestrvalwithmbs (rtx, (qse_mchar_t*)p->vptr); + tmp = qse_awk_rtx_makestrvalwithmbs(rtx, (qse_mchar_t*)p->vptr); break; case QSE_AWK_VAL_MAP_DATA_WCS: - tmp = qse_awk_rtx_makestrvalwithwcs (rtx, (qse_wchar_t*)p->vptr); + tmp = qse_awk_rtx_makestrvalwithwcs(rtx, (qse_wchar_t*)p->vptr); break; case QSE_AWK_VAL_MAP_DATA_XSTR: case QSE_AWK_VAL_MAP_DATA_CSTR: - tmp = qse_awk_rtx_makestrvalwithxstr (rtx, (qse_cstr_t*)p->vptr); + tmp = qse_awk_rtx_makestrvalwithxstr(rtx, (qse_cstr_t*)p->vptr); break; case QSE_AWK_VAL_MAP_DATA_MXSTR: case QSE_AWK_VAL_MAP_DATA_MCSTR: - tmp = qse_awk_rtx_makestrvalwithmxstr (rtx, (qse_mcstr_t*)p->vptr); + tmp = qse_awk_rtx_makestrvalwithmxstr(rtx, (qse_mcstr_t*)p->vptr); break; case QSE_AWK_VAL_MAP_DATA_WXSTR: case QSE_AWK_VAL_MAP_DATA_WCSTR: - tmp = qse_awk_rtx_makestrvalwithwxstr (rtx, (qse_wcstr_t*)p->vptr); + tmp = qse_awk_rtx_makestrvalwithwxstr(rtx, (qse_wcstr_t*)p->vptr); break; default: @@ -1570,7 +1575,7 @@ qse_char_t* qse_awk_rtx_getvalstr (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, q } else { - return qse_awk_rtx_valtostrdup (rtx, v, len); + return qse_awk_rtx_valtostrdup(rtx, v, len); } } @@ -1583,6 +1588,29 @@ void qse_awk_rtx_freevalstr (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_cha } } + +qse_mchar_t* qse_awk_rtx_getvalmbs (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_size_t* len) +{ + if (QSE_AWK_RTX_GETVALTYPE(rtx, v) == QSE_AWK_VAL_MBS) + { + if (len) *len = ((qse_awk_val_mbs_t*)v)->val.len; + return ((qse_awk_val_mbs_t*)v)->val.ptr; + } + else + { + return qse_awk_rtx_valtombsdup(rtx, v, len); + } +} + +void qse_awk_rtx_freevalmbs (qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_mchar_t* str) +{ + if (QSE_AWK_RTX_GETVALTYPE(rtx, v) != QSE_AWK_VAL_MBS || + str != ((qse_awk_val_mbs_t*)v)->val.ptr) + { + qse_awk_rtx_freemem (rtx, str); + } +} + static int val_ref_to_num (qse_awk_rtx_t* rtx, const qse_awk_val_ref_t* ref, qse_awk_int_t* l, qse_awk_flt_t* r) { switch (ref->id)