diff --git a/qse/include/qse/cmn/str.h b/qse/include/qse/cmn/str.h index 0f63d7fe..5f683ac1 100644 --- a/qse/include/qse/cmn/str.h +++ b/qse/include/qse/cmn/str.h @@ -3634,6 +3634,28 @@ QSE_EXPORT qse_size_t qse_wcs_vfmt ( # define qse_str_vfmt qse_wcs_vfmt #endif + + +QSE_EXPORT qse_size_t qse_mbs_ncatwcs ( + qse_mbs_t* str, + const qse_wchar_t* s, + qse_size_t len +); + +qse_size_t qse_wcs_ncatmbs ( + qse_wcs_t* str, + const qse_mchar_t* s, + qse_size_t len +); + +#if defined(QSE_CHAR_IS_MCHAR) +# define qse_str_ncatwcs(str,s,len) qse_mbs_ncatwcs(str,s,len) +# define qse_str_ncatmbs(str,s,len) qse_mbs_ncat(str,s,len) +#else +# define qse_str_ncatwcs(str,s,len) qse_wcs_ncat(str,s,len) +# define qse_str_ncatmbs(str,s,len) qse_wcs_ncatmbs(str,s,len) +#endif + #if defined(__cplusplus) } #endif diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index ec6932c9..83673c00 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -1011,7 +1011,7 @@ static int str_to_str (qse_awk_rtx_t* rtx, const qse_char_t* str, qse_size_t str if (str_len >= out->u.cplcpy.len) { qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL); - out->u.cplcpy.len = str_len + 1; /* set the required length */ + /*out->u.cplcpy.len = str_len + 1;*/ /* set the required length */ return -1; } @@ -1085,17 +1085,15 @@ static int mbs_to_str (qse_awk_rtx_t* rtx, const qse_mchar_t* str, qse_size_t st mbslen = str_len; wcslen = out->u.cplcpy.len; - if (qse_mbsntowcsnwithcmgr(str, &mbslen, out->u.cplcpy.ptr, &wcslen, rtx->cmgr) <= -1) + if (qse_mbsntowcsnallwithcmgr(str, &mbslen, out->u.cplcpy.ptr, &wcslen, rtx->cmgr) <= -1 || wcslen >= out->u.cplcpy.len) { qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL); /* TODO: change error code */ return -1; } - if (mbslen < str_len) - { - /* TODO: ... */ - } + out->u.cplcpy.ptr[wcslen] = QSE_T('\0'); out->u.cplcpy.len = wcslen; + return 0; } @@ -1105,7 +1103,7 @@ static int mbs_to_str (qse_awk_rtx_t* rtx, const qse_mchar_t* str, qse_size_t st qse_size_t mbslen, wcslen; mbslen = str_len; - tmp = qse_mbsntowcsdupwithcmgr(str, &mbslen, &wcslen, rtx->awk->mmgr, rtx->cmgr); + tmp = qse_mbsntowcsalldupwithcmgr(str, &mbslen, &wcslen, rtx->awk->mmgr, rtx->cmgr); if (!tmp) { qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL); @@ -1122,7 +1120,7 @@ static int mbs_to_str (qse_awk_rtx_t* rtx, const qse_mchar_t* str, qse_size_t st qse_size_t n; qse_str_clear (out->u.strp); - n = qse_str_ncat(out->u.strp, str, str_len); + n = qse_str_ncatmbs(out->u.strp, str, str_len); if (n == (qse_size_t)-1) { qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL); @@ -1135,7 +1133,7 @@ static int mbs_to_str (qse_awk_rtx_t* rtx, const qse_mchar_t* str, qse_size_t st { qse_size_t n; - n = qse_str_ncat(out->u.strpcat, str, str_len); + n = qse_str_ncatmbs(out->u.strpcat, str, str_len); if (n == (qse_size_t)-1) { qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL); @@ -1399,7 +1397,7 @@ static int val_ref_to_str (qse_awk_rtx_t* rtx, const qse_awk_val_ref_t* ref, qse idx = (qse_size_t)ref->adr; if (idx == 0) { - return str_to_str ( + return str_to_str( rtx, QSE_STR_PTR(&rtx->inrec.line), QSE_STR_LEN(&rtx->inrec.line), @@ -1408,7 +1406,7 @@ static int val_ref_to_str (qse_awk_rtx_t* rtx, const qse_awk_val_ref_t* ref, qse } else if (idx <= rtx->inrec.nflds) { - return str_to_str ( + return str_to_str( rtx, rtx->inrec.flds[idx-1].ptr, rtx->inrec.flds[idx-1].len, @@ -1417,7 +1415,7 @@ static int val_ref_to_str (qse_awk_rtx_t* rtx, const qse_awk_val_ref_t* ref, qse } else { - return str_to_str (rtx, QSE_T(""), 0, out); + return str_to_str(rtx, QSE_T(""), 0, out); } } @@ -1548,9 +1546,9 @@ qse_wchar_t* qse_awk_rtx_valtowcsdup (qse_awk_rtx_t* rtx, const qse_awk_val_t* v qse_wchar_t* wcs; out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; - if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) return QSE_NULL; + if (qse_awk_rtx_valtostr(rtx, v, &out) <= -1) return QSE_NULL; - wcs = qse_mbsntowcsdup (out.u.cpldup.ptr, out.u.cpldup.len, len, rtx->awk->mmgr); + wcs = qse_mbsntowcsdup(out.u.cpldup.ptr, out.u.cpldup.len, len, rtx->awk->mmgr); QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr); return wcs; #else diff --git a/qse/lib/cmn/str-dyn.c b/qse/lib/cmn/str-dyn.c index dd48c918..ca0bf528 100644 --- a/qse/lib/cmn/str-dyn.c +++ b/qse/lib/cmn/str-dyn.c @@ -71,14 +71,14 @@ static int wcs_to_mbs ( const qse_wchar_t* wcs, qse_size_t* wcslen, qse_mchar_t* mbs, qse_size_t* mbslen, void* ctx) { - return qse_wcsntombsnwithcmgr (wcs, wcslen, mbs, mbslen, qse_getdflcmgr()); + return qse_wcsntombsnwithcmgr(wcs, wcslen, mbs, mbslen, qse_getdflcmgr()); } static int mbs_to_wcs ( const qse_mchar_t* mbs, qse_size_t* mbslen, qse_wchar_t* wcs, qse_size_t* wcslen, void* ctx) { - return qse_mbsntowcsnwithcmgr (mbs, mbslen, wcs, wcslen, qse_getdflcmgr()); + return qse_mbsntowcsnwithcmgr(mbs, mbslen, wcs, wcslen, qse_getdflcmgr()); } /* -------------------------------------------------------- */ @@ -278,3 +278,42 @@ static int mbs_to_wcs ( #define str_fcat qse_wcs_fcat #define str_vfcat qse_wcs_vfcat #include "str-dyn.h" + + +qse_size_t qse_mbs_ncatwcs (qse_mbs_t* str, const qse_wchar_t* s, qse_size_t len) +{ + qse_size_t mbslen, wcslen; + qse_cmgr_t* cmgr = qse_getdflcmgr(); + + wcslen = len; + if (qse_wcsntombsnwithcmgr(s, &wcslen, QSE_NULL, &mbslen, cmgr) <= -1) return (qse_size_t)-1; + + if (resize_for_mbs_ncat(str, mbslen) <= 0) return -1; + + wcslen = len; + mbslen = str->capa - str->val.len; + qse_wcsntombsnwithcmgr(s, &wcslen, &str->val.ptr[str->val.len], &mbslen, cmgr); + str->val.len += mbslen; + str->val.ptr[str->val.len] = QSE_MT('\0'); + + return str->val.len; +} + +qse_size_t qse_wcs_ncatmbs (qse_wcs_t* str, const qse_mchar_t* s, qse_size_t len) +{ + qse_size_t mbslen, wcslen; + qse_cmgr_t* cmgr = qse_getdflcmgr(); + + mbslen = len; + if (qse_mbsntowcsnallwithcmgr(s, &mbslen, QSE_NULL, &wcslen, cmgr) <= -1) return (qse_size_t)-1; + + if (resize_for_wcs_ncat(str, wcslen) <= 0) return -1; + + mbslen = len; + wcslen = str->capa - str->val.len; + qse_mbsntowcsnallwithcmgr(s, &mbslen, &str->val.ptr[str->val.len], &wcslen, cmgr); + str->val.len += wcslen; + str->val.ptr[str->val.len] = QSE_WT('\0'); + + return str->val.len; +} diff --git a/qse/lib/cmn/str-dyn.h b/qse/lib/cmn/str-dyn.h index 58754411..7cc969f6 100644 --- a/qse/lib/cmn/str-dyn.h +++ b/qse/lib/cmn/str-dyn.h @@ -300,7 +300,7 @@ static int resize_for_ncat (str_t* str, qse_size_t len) { /* let the user determine the new capacity. * pass the minimum capacity required as a hint */ - ncapa = str->sizer (str, mincapa); + ncapa = str->sizer(str, mincapa); /* if no change in capacity, return current length */ if (ncapa == str->capa) return 0; } @@ -308,7 +308,7 @@ static int resize_for_ncat (str_t* str, qse_size_t len) /* change the capacity */ do { - if (str_setcapa (str, ncapa) != (qse_size_t)-1) break; + if (str_setcapa(str, ncapa) != (qse_size_t)-1) break; if (ncapa <= mincapa) return -1; ncapa--; } @@ -318,7 +318,7 @@ static int resize_for_ncat (str_t* str, qse_size_t len) { QSE_ASSERT (str->val.ptr == QSE_NULL); QSE_ASSERT (str->val.len <= 0); - if (str_setcapa (str, 1) == (qse_size_t)-1) return -1; + if (str_setcapa(str, 1) == (qse_size_t)-1) return -1; } return 1; @@ -329,7 +329,7 @@ qse_size_t str_ncat (str_t* str, const char_t* s, qse_size_t len) int n; qse_size_t i, j; - n = resize_for_ncat (str, len); + n = resize_for_ncat(str, len); if (n <= -1) return (qse_size_t)-1; if (n == 0) return str->val.len; @@ -357,13 +357,13 @@ qse_size_t str_nrcat (str_t* str, const char_t* s, qse_size_t len) int n; qse_size_t i, j; - n = resize_for_ncat (str, len); + n = resize_for_ncat(str, len); if (n <= -1) return (qse_size_t)-1; if (n == 0) return str->val.len; if (len > str->capa - str->val.len) len = str->capa - str->val.len; - for (i = len, j = str->val.len ; i > 0; j++) str->val.ptr[j] = s[--i]; + for (i = len, j = str->val.len ; i > 0; j++) str->val.ptr[j] = s[--i]; str->val.ptr[j] = T('\0'); str->val.len = j; @@ -483,7 +483,7 @@ qse_size_t str_vfcat (str_t* str, const char_t* fmt, va_list ap) str->val.len = old_len; /* resizing is required */ - x = resize_for_ncat (str, fo.count); + x = resize_for_ncat(str, fo.count); if (x <= -1) return (qse_size_t)-1; if (x >= 1) @@ -524,7 +524,7 @@ qse_size_t str_vfmt (str_t* str, const char_t* fmt, va_list ap) if (fmtout (fmt, &fo, ap) <= -1) return (qse_size_t)-1; str_clear (str); - x = resize_for_ncat (str, fo.count); + x = resize_for_ncat(str, fo.count); if (x <= -1) return (qse_size_t)-1; if (x >= 1) diff --git a/qse/samples/cmn/str01.c b/qse/samples/cmn/str01.c index 1d502218..dfbd69a4 100644 --- a/qse/samples/cmn/str01.c +++ b/qse/samples/cmn/str01.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -399,6 +400,50 @@ static int test17 (void) return 0; } +static int test18 (void) +{ + qse_str_t* s1 = QSE_NULL; + + s1 = qse_str_open (QSE_MMGR_GETDFL(), 0, 5); + if (s1 == QSE_NULL) + { + qse_printf (QSE_T("cannot open a string\n")); + return -1; + } + + qse_str_ncat (s1, QSE_T("["), 1); + qse_str_ncatwcs (s1, QSE_WT("hello"), 5); + qse_str_ncatmbs (s1, QSE_MT("world"), 5); + qse_str_ncat (s1, QSE_T("]"), 1); + + QSE_TESASSERT1 (QSE_STR_LEN(s1) == 12, QSE_T("wrong length of dynamic string")); + + qse_str_ncatmbs (s1, QSE_MT("\xEB\xAC\xB4\xEB\xAC\xB4\xEB\xAC\xB4"), 9); + +#if defined(QSE_CHAR_IS_MCHAR) + QSE_TESASSERT1 (QSE_STR_LEN(s1) == 21, QSE_T("wrong length of dynamic string")); +#else + QSE_TESASSERT1 (QSE_STR_LEN(s1) == 15, QSE_T("wrong length of dynamic string")); +#endif + + qse_str_ncatwcs (s1, QSE_WT("날아올라라"), 5); + +#if defined(QSE_CHAR_IS_MCHAR) + QSE_TESASSERT1 (QSE_STR_LEN(s1) == 36, QSE_T("wrong length of dynamic string")); +#else + QSE_TESASSERT1 (QSE_STR_LEN(s1) == 20, QSE_T("wrong length of dynamic string")); +#endif + + qse_printf (QSE_T("\t%js\n"), QSE_STR_PTR(s1)); + qse_str_close (s1); + + qse_printf (QSE_T("\tOK\n")); + return 0; + +oops: + if (s1) qse_str_close (s1); + return -1; +} int main () { @@ -433,6 +478,7 @@ int main () R (test15); R (test16); R (test17); + R (test18); qse_close_stdsios ();