From 2332d6a4e7c2716e306aaab75d52ad0ab9301af8 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 20 Feb 2020 14:59:49 +0000 Subject: [PATCH] renamed some utility functions --- mio/lib/mio-prv.h | 28 -- mio/lib/mio-utl.h | 25 +- mio/lib/mio.h | 26 +- mio/lib/pro.c | 4 +- mio/lib/utl.c | 832 +++++++++++++++++++++++++++++----------------- 5 files changed, 563 insertions(+), 352 deletions(-) diff --git a/mio/lib/mio-prv.h b/mio/lib/mio-prv.h index d592402..fb839bf 100644 --- a/mio/lib/mio-prv.h +++ b/mio/lib/mio-prv.h @@ -114,34 +114,6 @@ int mio_makesyshndasync ( mio_syshnd_t hnd ); - -mio_bch_t* mio_mbsdup ( - mio_t* mio, - const mio_bch_t* src -); - -mio_oow_t mio_mbscpy ( - mio_bch_t* buf, - const mio_bch_t* str -); - -int mio_mbsspltrn ( - mio_bch_t* s, - const mio_bch_t* delim, - mio_bch_t lquote, - mio_bch_t rquote, - mio_bch_t escape, - const mio_bch_t* trset -); - -int mio_mbsspl ( - mio_bch_t* s, - const mio_bch_t* delim, - mio_bch_t lquote, - mio_bch_t rquote, - mio_bch_t escape -); - void mio_cleartmrjobs ( mio_t* mio ); diff --git a/mio/lib/mio-utl.h b/mio/lib/mio-utl.h index ad22bf6..0458bd5 100644 --- a/mio/lib/mio-utl.h +++ b/mio/lib/mio-utl.h @@ -345,6 +345,22 @@ MIO_EXPORT mio_bch_t* mio_find_bchar_in_bcstr ( mio_bch_t c ); +MIO_EXPORT int mio_split_ucstr ( + mio_uch_t* s, + const mio_uch_t* delim, + mio_uch_t lquote, + mio_uch_t rquote, + mio_uch_t escape +); + +MIO_EXPORT int mio_split_bcstr ( + mio_bch_t* s, + const mio_bch_t* delim, + mio_bch_t lquote, + mio_bch_t rquote, + mio_bch_t escape +); + MIO_EXPORT mio_oow_t mio_count_ucstr ( const mio_uch_t* str ); @@ -362,7 +378,6 @@ MIO_EXPORT mio_oow_t mio_count_bcstr ( # define mio_comp_oochars_oocstr(str1,len1,str2) mio_comp_uchars_ucstr(str1,len1,str2) # define mio_comp_oocstr(str1,str2) mio_comp_ucstr(str1,str2) - # define mio_copy_oochars mio_copy_uchars # define mio_copy_bchars_to_oochars mio_copy_bchars_to_uchars # define mio_copy_oochars_to_bchars mio_copy_uchars_to_bchars @@ -378,7 +393,9 @@ MIO_EXPORT mio_oow_t mio_count_bcstr ( # define mio_find_oochar(ptr,len,c) mio_find_uchar(ptr,len,c) # define mio_rfind_oochar(ptr,len,c) mio_rfind_uchar(ptr,len,c) # define mio_find_oochar_in_oocstr(ptr,c) mio_find_uchar_in_ucstr(ptr,c) -# define mio_count_oocstr(str) mio_count_ucstr(str) + +# define mio_split_oocstr mio_split_ucstr +# define mio_count_oocstr mio_count_ucstr #else # define mio_equal_oochars(str1,str2,len) mio_equal_bchars(str1,str2,len) # define mio_comp_oochars(str1,len1,str2,len2) mio_comp_bchars(str1,len1,str2,len2) @@ -403,7 +420,9 @@ MIO_EXPORT mio_oow_t mio_count_bcstr ( # define mio_find_oochar(ptr,len,c) mio_find_bchar(ptr,len,c) # define mio_rfind_oochar(ptr,len,c) mio_rfind_bchar(ptr,len,c) # define mio_find_oochar_in_oocstr(ptr,c) mio_find_bchar_in_bcstr(ptr,c) -# define mio_count_oocstr(str) mio_count_bcstr(str) + +# define mio_split_oocstr mio_split_bcstr +# define mio_count_oocstr mio_count_bcstr #endif /* ------------------------------------------------------------------------- */ diff --git a/mio/lib/mio.h b/mio/lib/mio.h index 523e257..11560ff 100644 --- a/mio/lib/mio.h +++ b/mio/lib/mio.h @@ -1029,11 +1029,6 @@ MIO_EXPORT mio_bch_t* mio_duputobcstr ( ); -#if defined(MIO_OOCH_IS_UCH) -# define mio_dupoochars(mio,oocs,oocslen) mio_dupuchars(mio,oocs,oocslen) -#else -# define mio_dupoochars(mio,oocs,oocslen) mio_dupbchars(mio,oocs,oocslen) -#endif MIO_EXPORT mio_uch_t* mio_dupuchars ( mio_t* mio, @@ -1048,6 +1043,27 @@ MIO_EXPORT mio_bch_t* mio_dupbchars ( ); +MIO_EXPORT mio_uch_t* mio_dupucstr ( + mio_t* mio, + const mio_uch_t* ucs, + mio_oow_t* ucslen /* [OUT] length*/ +); + +MIO_EXPORT mio_bch_t* mio_dupbcstr ( + mio_t* mio, + const mio_bch_t* bcs, + mio_oow_t* bcslen /* [OUT] length */ +); + +#if defined(MIO_OOCH_IS_UCH) +# define mio_dupoochars(mio,oocs,oocslen) mio_dupuchars(mio,oocs,oocslen) +# define mio_dupoocstr(mio,oocs,oocslen) mio_dupucstr(mio,oocs,oocslen) +#else +# define mio_dupoochars(mio,oocs,oocslen) mio_dupbchars(mio,oocs,oocslen) +# define mio_dupoocstr(mio,oocs,oocslen) mio_dupbcstr(mio,oocs,oocslen) +#endif + + /* ========================================================================= * MIO VM LOGGING * ========================================================================= */ diff --git a/mio/lib/pro.c b/mio/lib/pro.c index cbfaaef..63ce5a5 100644 --- a/mio/lib/pro.c +++ b/mio/lib/pro.c @@ -88,10 +88,10 @@ static int make_param (mio_t* mio, const mio_bch_t* cmd, int flags, param_t* par mio_bch_t** argv; mio_bch_t* mcmdptr; - mcmd = mio_mbsdup (mio, cmd); + mcmd = mio_dupbcstr(mio, cmd, MIO_NULL); if (!mcmd) goto oops; - fcnt = mio_mbsspl(mcmd, "", '\"', '\"', '\\'); + fcnt = mio_split_bcstr(mcmd, "", '\"', '\"', '\\'); if (fcnt <= 0) { /* no field or an error */ diff --git a/mio/lib/utl.c b/mio/lib/utl.c index e8e386a..903ed19 100644 --- a/mio/lib/utl.c +++ b/mio/lib/utl.c @@ -1,4 +1,4 @@ -/* +/*m * $Id$ * Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved. @@ -26,319 +26,6 @@ #include "mio-prv.h" - -#define MIO_MT(x) (x) -#define IS_MSPACE(x) ((x) == MIO_MT(' ') || (x) == MIO_MT('\t') || (x) == MIO_MT('\n') || (x) == MIO_MT('\r')) - -mio_bch_t* mio_mbsdup (mio_t* mio, const mio_bch_t* src) -{ - mio_bch_t* dst; - mio_oow_t len; - - dst = (mio_bch_t*)src; - while (*dst != MIO_MT('\0')) dst++; - len = dst - src; - - dst = mio_allocmem(mio, (len + 1) * MIO_SIZEOF(*src)); - if (!dst) return MIO_NULL; - - MIO_MEMCPY (dst, src, (len + 1) * MIO_SIZEOF(*src)); - return dst; -} - -mio_oow_t mio_mbscpy (mio_bch_t* buf, const mio_bch_t* str) -{ - mio_bch_t* org = buf; - while ((*buf++ = *str++) != MIO_MT('\0')); - return buf - org - 1; -} - -int mio_mbsspltrn ( - mio_bch_t* s, const mio_bch_t* delim, - mio_bch_t lquote, mio_bch_t rquote, - mio_bch_t escape, const mio_bch_t* trset) -{ - mio_bch_t* p = s, *d; - mio_bch_t* sp = MIO_NULL, * ep = MIO_NULL; - int delim_mode; - int cnt = 0; - - if (delim == MIO_NULL) delim_mode = 0; - else - { - delim_mode = 1; - for (d = (mio_bch_t*)delim; *d != MIO_MT('\0'); d++) - if (!IS_MSPACE(*d)) delim_mode = 2; - } - - if (delim_mode == 0) - { - /* skip preceding space characters */ - while (IS_MSPACE(*p)) p++; - - /* when 0 is given as "delim", it has an effect of cutting - preceding and trailing space characters off "s". */ - if (lquote != MIO_MT('\0') && *p == lquote) - { - mio_mbscpy (p, p + 1); - - for (;;) - { - if (*p == MIO_MT('\0')) return -1; - - if (escape != MIO_MT('\0') && *p == escape) - { - if (trset != MIO_NULL && p[1] != MIO_MT('\0')) - { - const mio_bch_t* ep = trset; - while (*ep != MIO_MT('\0')) - { - if (p[1] == *ep++) - { - p[1] = *ep; - break; - } - } - } - - mio_mbscpy (p, p + 1); - } - else - { - if (*p == rquote) - { - p++; - break; - } - } - - if (sp == 0) sp = p; - ep = p; - p++; - } - while (IS_MSPACE(*p)) p++; - if (*p != MIO_MT('\0')) return -1; - - if (sp == 0 && ep == 0) s[0] = MIO_MT('\0'); - else - { - ep[1] = MIO_MT('\0'); - if (s != (mio_bch_t*)sp) mio_mbscpy (s, sp); - cnt++; - } - } - else - { - while (*p) - { - if (!IS_MSPACE(*p)) - { - if (sp == 0) sp = p; - ep = p; - } - p++; - } - - if (sp == 0 && ep == 0) s[0] = MIO_MT('\0'); - else - { - ep[1] = MIO_MT('\0'); - if (s != (mio_bch_t*)sp) mio_mbscpy (s, sp); - cnt++; - } - } - } - else if (delim_mode == 1) - { - mio_bch_t* o; - - while (*p) - { - o = p; - while (IS_MSPACE(*p)) p++; - if (o != p) { mio_mbscpy (o, p); p = o; } - - if (lquote != MIO_MT('\0') && *p == lquote) - { - mio_mbscpy (p, p + 1); - - for (;;) - { - if (*p == MIO_MT('\0')) return -1; - - if (escape != MIO_MT('\0') && *p == escape) - { - if (trset != MIO_NULL && p[1] != MIO_MT('\0')) - { - const mio_bch_t* ep = trset; - while (*ep != MIO_MT('\0')) - { - if (p[1] == *ep++) - { - p[1] = *ep; - break; - } - } - } - mio_mbscpy (p, p + 1); - } - else - { - if (*p == rquote) - { - *p++ = MIO_MT('\0'); - cnt++; - break; - } - } - p++; - } - } - else - { - o = p; - for (;;) - { - if (*p == MIO_MT('\0')) - { - if (o != p) cnt++; - break; - } - if (IS_MSPACE (*p)) - { - *p++ = MIO_MT('\0'); - cnt++; - break; - } - p++; - } - } - } - } - else /* if (delim_mode == 2) */ - { - mio_bch_t* o; - int ok; - - while (*p != MIO_MT('\0')) - { - o = p; - while (IS_MSPACE(*p)) p++; - if (o != p) { mio_mbscpy (o, p); p = o; } - - if (lquote != MIO_MT('\0') && *p == lquote) - { - mio_mbscpy (p, p + 1); - - for (;;) - { - if (*p == MIO_MT('\0')) return -1; - - if (escape != MIO_MT('\0') && *p == escape) - { - if (trset != MIO_NULL && p[1] != MIO_MT('\0')) - { - const mio_bch_t* ep = trset; - while (*ep != MIO_MT('\0')) - { - if (p[1] == *ep++) - { - p[1] = *ep; - break; - } - } - } - - mio_mbscpy (p, p + 1); - } - else - { - if (*p == rquote) - { - *p++ = MIO_MT('\0'); - cnt++; - break; - } - } - p++; - } - - ok = 0; - while (IS_MSPACE(*p)) p++; - if (*p == MIO_MT('\0')) ok = 1; - for (d = (mio_bch_t*)delim; *d != MIO_MT('\0'); d++) - { - if (*p == *d) - { - ok = 1; - mio_mbscpy (p, p + 1); - break; - } - } - if (ok == 0) return -1; - } - else - { - o = p; sp = ep = 0; - - for (;;) - { - if (*p == MIO_MT('\0')) - { - if (ep) - { - ep[1] = MIO_MT('\0'); - p = &ep[1]; - } - cnt++; - break; - } - for (d = (mio_bch_t*)delim; *d != MIO_MT('\0'); d++) - { - if (*p == *d) - { - if (sp == MIO_NULL) - { - mio_mbscpy (o, p); p = o; - *p++ = MIO_MT('\0'); - } - else - { - mio_mbscpy (&ep[1], p); - mio_mbscpy (o, sp); - o[ep - sp + 1] = MIO_MT('\0'); - p = &o[ep - sp + 2]; - } - cnt++; - /* last empty field after delim */ - if (*p == MIO_MT('\0')) cnt++; - goto exit_point; - } - } - - if (!IS_MSPACE (*p)) - { - if (sp == MIO_NULL) sp = p; - ep = p; - } - p++; - } -exit_point: - ; - } - } - } - - return cnt; -} - -int mio_mbsspl ( - mio_bch_t* s, const mio_bch_t* delim, - mio_bch_t lquote, mio_bch_t rquote, mio_bch_t escape) -{ - return mio_mbsspltrn (s, delim, lquote, rquote, escape, MIO_NULL); -} - /* ========================================================================= */ int mio_equal_uchars (const mio_uch_t* str1, const mio_uch_t* str2, mio_oow_t len) @@ -716,6 +403,486 @@ mio_bch_t* mio_find_bchar_in_bcstr (const mio_bch_t* ptr, mio_bch_t c) return MIO_NULL; } +/* ========================================================================= */ +#define IS_UCH_SPACE(x) ((x) ==' ' || (x) == '\t' || (x) == '\n' || (x) == '\r') +#define IS_BCH_SPACE(x) ((x) ==' ' || (x) == '\t' || (x) == '\n' || (x) == '\r') + +int mio_split_ucstr (mio_uch_t* s, const mio_uch_t* delim, mio_uch_t lquote, mio_uch_t rquote, mio_uch_t escape) +{ + mio_uch_t* p = s, *d; + mio_uch_t* sp = MIO_NULL, * ep = MIO_NULL; + int delim_mode; + int cnt = 0; + + if (delim == MIO_NULL) delim_mode = 0; + else + { + delim_mode = 1; + for (d = (mio_uch_t*)delim; *d != '\0'; d++) + if (!IS_UCH_SPACE(*d)) delim_mode = 2; + } + + if (delim_mode == 0) + { + /* skip preceding space characters */ + while (IS_UCH_SPACE(*p)) p++; + + /* when 0 is given as "delim", it has an effect of cutting + preceding and trailing space characters off "s". */ + if (lquote != '\0' && *p == lquote) + { + mio_copy_ucstr_unlimited (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + mio_copy_ucstr_unlimited (p, p + 1); + } + else + { + if (*p == rquote) + { + p++; + break; + } + } + + if (sp == 0) sp = p; + ep = p; + p++; + } + while (IS_UCH_SPACE(*p)) p++; + if (*p != '\0') return -1; + + if (sp == 0 && ep == 0) s[0] = '\0'; + else + { + ep[1] = '\0'; + if (s != (mio_uch_t*)sp) mio_copy_ucstr_unlimited (s, sp); + cnt++; + } + } + else + { + while (*p) + { + if (!IS_UCH_SPACE(*p)) + { + if (sp == 0) sp = p; + ep = p; + } + p++; + } + + if (sp == 0 && ep == 0) s[0] = '\0'; + else + { + ep[1] = '\0'; + if (s != (mio_uch_t*)sp) mio_copy_ucstr_unlimited (s, sp); + cnt++; + } + } + } + else if (delim_mode == 1) + { + mio_uch_t* o; + + while (*p) + { + o = p; + while (IS_UCH_SPACE(*p)) p++; + if (o != p) { mio_copy_ucstr_unlimited (o, p); p = o; } + + if (lquote != '\0' && *p == lquote) + { + mio_copy_ucstr_unlimited (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + mio_copy_ucstr_unlimited (p, p + 1); + } + else + { + if (*p == rquote) + { + *p++ = '\0'; + cnt++; + break; + } + } + p++; + } + } + else + { + o = p; + for (;;) + { + if (*p == '\0') + { + if (o != p) cnt++; + break; + } + if (IS_UCH_SPACE (*p)) + { + *p++ = '\0'; + cnt++; + break; + } + p++; + } + } + } + } + else /* if (delim_mode == 2) */ + { + mio_uch_t* o; + int ok; + + while (*p != '\0') + { + o = p; + while (IS_UCH_SPACE(*p)) p++; + if (o != p) { mio_copy_ucstr_unlimited (o, p); p = o; } + + if (lquote != '\0' && *p == lquote) + { + mio_copy_ucstr_unlimited (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + mio_copy_ucstr_unlimited (p, p + 1); + } + else + { + if (*p == rquote) + { + *p++ = '\0'; + cnt++; + break; + } + } + p++; + } + + ok = 0; + while (IS_UCH_SPACE(*p)) p++; + if (*p == '\0') ok = 1; + for (d = (mio_uch_t*)delim; *d != '\0'; d++) + { + if (*p == *d) + { + ok = 1; + mio_copy_ucstr_unlimited (p, p + 1); + break; + } + } + if (ok == 0) return -1; + } + else + { + o = p; sp = ep = 0; + + for (;;) + { + if (*p == '\0') + { + if (ep) + { + ep[1] = '\0'; + p = &ep[1]; + } + cnt++; + break; + } + for (d = (mio_uch_t*)delim; *d != '\0'; d++) + { + if (*p == *d) + { + if (sp == MIO_NULL) + { + mio_copy_ucstr_unlimited (o, p); p = o; + *p++ = '\0'; + } + else + { + mio_copy_ucstr_unlimited (&ep[1], p); + mio_copy_ucstr_unlimited (o, sp); + o[ep - sp + 1] = '\0'; + p = &o[ep - sp + 2]; + } + cnt++; + /* last empty field after delim */ + if (*p == '\0') cnt++; + goto exit_point; + } + } + + if (!IS_UCH_SPACE (*p)) + { + if (sp == MIO_NULL) sp = p; + ep = p; + } + p++; + } +exit_point: + ; + } + } + } + + return cnt; +} + +int mio_split_bcstr (mio_bch_t* s, const mio_bch_t* delim, mio_bch_t lquote, mio_bch_t rquote, mio_bch_t escape) +{ + mio_bch_t* p = s, *d; + mio_bch_t* sp = MIO_NULL, * ep = MIO_NULL; + int delim_mode; + int cnt = 0; + + if (delim == MIO_NULL) delim_mode = 0; + else + { + delim_mode = 1; + for (d = (mio_bch_t*)delim; *d != '\0'; d++) + if (!IS_BCH_SPACE(*d)) delim_mode = 2; + } + + if (delim_mode == 0) + { + /* skip preceding space characters */ + while (IS_BCH_SPACE(*p)) p++; + + /* when 0 is given as "delim", it has an effect of cutting + preceding and trailing space characters off "s". */ + if (lquote != '\0' && *p == lquote) + { + mio_copy_bcstr_unlimited (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + mio_copy_bcstr_unlimited (p, p + 1); + } + else + { + if (*p == rquote) + { + p++; + break; + } + } + + if (sp == 0) sp = p; + ep = p; + p++; + } + while (IS_BCH_SPACE(*p)) p++; + if (*p != '\0') return -1; + + if (sp == 0 && ep == 0) s[0] = '\0'; + else + { + ep[1] = '\0'; + if (s != (mio_bch_t*)sp) mio_copy_bcstr_unlimited (s, sp); + cnt++; + } + } + else + { + while (*p) + { + if (!IS_BCH_SPACE(*p)) + { + if (sp == 0) sp = p; + ep = p; + } + p++; + } + + if (sp == 0 && ep == 0) s[0] = '\0'; + else + { + ep[1] = '\0'; + if (s != (mio_bch_t*)sp) mio_copy_bcstr_unlimited (s, sp); + cnt++; + } + } + } + else if (delim_mode == 1) + { + mio_bch_t* o; + + while (*p) + { + o = p; + while (IS_BCH_SPACE(*p)) p++; + if (o != p) { mio_copy_bcstr_unlimited (o, p); p = o; } + + if (lquote != '\0' && *p == lquote) + { + mio_copy_bcstr_unlimited (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + mio_copy_bcstr_unlimited (p, p + 1); + } + else + { + if (*p == rquote) + { + *p++ = '\0'; + cnt++; + break; + } + } + p++; + } + } + else + { + o = p; + for (;;) + { + if (*p == '\0') + { + if (o != p) cnt++; + break; + } + if (IS_BCH_SPACE (*p)) + { + *p++ = '\0'; + cnt++; + break; + } + p++; + } + } + } + } + else /* if (delim_mode == 2) */ + { + mio_bch_t* o; + int ok; + + while (*p != '\0') + { + o = p; + while (IS_BCH_SPACE(*p)) p++; + if (o != p) { mio_copy_bcstr_unlimited (o, p); p = o; } + + if (lquote != '\0' && *p == lquote) + { + mio_copy_bcstr_unlimited (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + mio_copy_bcstr_unlimited (p, p + 1); + } + else + { + if (*p == rquote) + { + *p++ = '\0'; + cnt++; + break; + } + } + p++; + } + + ok = 0; + while (IS_BCH_SPACE(*p)) p++; + if (*p == '\0') ok = 1; + for (d = (mio_bch_t*)delim; *d != '\0'; d++) + { + if (*p == *d) + { + ok = 1; + mio_copy_bcstr_unlimited (p, p + 1); + break; + } + } + if (ok == 0) return -1; + } + else + { + o = p; sp = ep = 0; + + for (;;) + { + if (*p == '\0') + { + if (ep) + { + ep[1] = '\0'; + p = &ep[1]; + } + cnt++; + break; + } + for (d = (mio_bch_t*)delim; *d != '\0'; d++) + { + if (*p == *d) + { + if (sp == MIO_NULL) + { + mio_copy_bcstr_unlimited (o, p); p = o; + *p++ = '\0'; + } + else + { + mio_copy_bcstr_unlimited (&ep[1], p); + mio_copy_bcstr_unlimited (o, sp); + o[ep - sp + 1] = '\0'; + p = &o[ep - sp + 2]; + } + cnt++; + /* last empty field after delim */ + if (*p == '\0') cnt++; + goto exit_point; + } + } + + if (!IS_BCH_SPACE (*p)) + { + if (sp == MIO_NULL) sp = p; + ep = p; + } + p++; + } +exit_point: + ; + } + } + } + + return cnt; +} + /* ========================================================================= */ mio_oow_t mio_byte_to_bcstr (mio_uint8_t byte, mio_bch_t* buf, mio_oow_t size, int flagged_radix, mio_bch_t fill) @@ -1292,4 +1459,41 @@ mio_bch_t* mio_dupbchars (mio_t* mio, const mio_bch_t* bcs, mio_oow_t bcslen) return ptr; } + +/* ========================================================================= */ +mio_uch_t* mio_dupucstr (mio_t* mio, const mio_uch_t* ucs, mio_oow_t* ucslen) +{ + mio_uch_t* ptr; + mio_oow_t len; + + len = mio_count_ucstr(ucs); + + ptr = (mio_uch_t*)mio_allocmem(mio, (len + 1) * MIO_SIZEOF(mio_uch_t)); + if (!ptr) return MIO_NULL; + + mio_copy_uchars (ptr, ucs, len); + ptr[len] = '\0'; + + if (ucslen) *ucslen = len; + return ptr; +} + +mio_bch_t* mio_dupbcstr (mio_t* mio, const mio_bch_t* bcs, mio_oow_t* bcslen) +{ + mio_bch_t* ptr; + mio_oow_t len; + + len = mio_count_bcstr(bcs); + + ptr = (mio_bch_t*)mio_allocmem(mio, (len + 1) * MIO_SIZEOF(mio_bch_t)); + if (!ptr) return MIO_NULL; + + mio_copy_bchars (ptr, bcs, len); + ptr[len] = '\0'; + + if (bcslen) *bcslen = len; + return ptr; +} + + /* ========================================================================= */