diff --git a/qse/include/qse/cmn/str.h b/qse/include/qse/cmn/str.h index 36e8a577..0fe0d984 100644 --- a/qse/include/qse/cmn/str.h +++ b/qse/include/qse/cmn/str.h @@ -692,6 +692,21 @@ QSE_EXPORT qse_size_t qse_mbsfmt ( ... ); +/** + * The qse_mbsxfmt() function writes a formatted string into the buffer \a buf + * of the size \a bsz using the format \a fmt and the variable arguments. It + * doesn't write more than bsz characters including the terminating null + * chracter. If \a buf is #QSE_NULL, no characters are written to the buffer. + * If conversion from a wide character string fails, the formatting is aborted + * and the output buffer gets null-terminated. + * + * \return + * It returns the number of characters written to the buffer excluding the + * terminating null. When \a buf is #QSE_NULL, it returns the number of + * characters that would have been written excluding the terminating null + * if \a buf has not been #QSE_NULL. If conversion from a wide-character + * string failure, it returns (qse_size_t)-1. + */ QSE_EXPORT qse_size_t qse_mbsxfmt ( qse_mchar_t* buf, qse_size_t bsz, @@ -705,6 +720,21 @@ QSE_EXPORT qse_size_t qse_wcsfmt ( ... ); +/** + * The qse_wcsxfmt() function writes a formatted string into the buffer \a buf + * of the size \a bsz using the format \a fmt and the variable arguments. It + * doesn't write more than bsz characters including the terminating null + * chracter. If \a buf is #QSE_NULL, no characters are written to the buffer. + * If conversion from a multi-byte string fails, the formatting is aborted and + * the output buffer gets null-terminated. + * + * \return + * It returns the number of characters written to the buffer excluding the + * terminating null. When \a buf is #QSE_NULL, it returns the number of + * characters that would have been written excluding the terminating null + * if \a buf has not been #QSE_NULL. If conversion from a multi-byte string + * fails, it returns (qse_size_t)-1. + */ QSE_EXPORT qse_size_t qse_wcsxfmt ( qse_wchar_t* buf, qse_size_t bsz, diff --git a/qse/lib/cmn/Makefile.am b/qse/lib/cmn/Makefile.am index 3812411d..2feef4fe 100644 --- a/qse/lib/cmn/Makefile.am +++ b/qse/lib/cmn/Makefile.am @@ -14,6 +14,7 @@ noinst_HEADERS = \ fmt-out.h \ fs.h \ mem.h \ + str-dyn.h \ str-fcpy.h \ str-fmt.h \ str-join.h \ @@ -81,8 +82,7 @@ libqsecmn_la_SOURCES = \ str-cpy.c \ str-del.c \ str-dup.c \ - str-dynm.c \ - str-dynw.c \ + str-dyn.c \ str-end.c \ str-excl.c \ str-fcpy.c \ diff --git a/qse/lib/cmn/Makefile.in b/qse/lib/cmn/Makefile.in index b5ebf96d..44fd6161 100644 --- a/qse/lib/cmn/Makefile.in +++ b/qse/lib/cmn/Makefile.in @@ -92,12 +92,12 @@ am__libqsecmn_la_SOURCES_DIST = alg-base64.c alg-rand.c alg-search.c \ nwad.c nwad-skad.c nwif.c nwif-cfg.c nwio.c oht.c opt.c \ path-basename.c path-canon.c pio.c pma.c rbt.c rex.c sio.c \ sll.c slmb.c stdio.c str-beg.c str-cat.c str-chr.c str-cnv.c \ - str-cmp.c str-cpy.c str-del.c str-dup.c str-dynm.c str-dynw.c \ - str-end.c str-excl.c str-fcpy.c str-fmt.c str-fnmat.c \ - str-incl.c str-join.c str-len.c str-pac.c str-pbrk.c str-put.c \ - str-rev.c str-rot.c str-set.c str-spl.c str-spn.c str-str.c \ - str-subst.c str-tok.c str-trm.c str-word.c task.c time.c tio.c \ - tre.c tre-ast.c tre-compile.c tre-match-backtrack.c \ + str-cmp.c str-cpy.c str-del.c str-dup.c str-dyn.c str-end.c \ + str-excl.c str-fcpy.c str-fmt.c str-fnmat.c str-incl.c \ + str-join.c str-len.c str-pac.c str-pbrk.c str-put.c str-rev.c \ + str-rot.c str-set.c str-spl.c str-spn.c str-str.c str-subst.c \ + str-tok.c str-trm.c str-word.c task.c time.c tio.c tre.c \ + tre-ast.c tre-compile.c tre-match-backtrack.c \ tre-match-parallel.c tre-parse.c tre-stack.c uri.c utf8.c \ xma.c uni.c cp949.c cp950.c @ENABLE_BUNDLED_UNICODE_TRUE@am__objects_1 = uni.lo @@ -110,15 +110,15 @@ am_libqsecmn_la_OBJECTS = alg-base64.lo alg-rand.lo alg-search.lo \ nwif-cfg.lo nwio.lo oht.lo opt.lo path-basename.lo \ path-canon.lo pio.lo pma.lo rbt.lo rex.lo sio.lo sll.lo \ slmb.lo stdio.lo str-beg.lo str-cat.lo str-chr.lo str-cnv.lo \ - str-cmp.lo str-cpy.lo str-del.lo str-dup.lo str-dynm.lo \ - str-dynw.lo str-end.lo str-excl.lo str-fcpy.lo str-fmt.lo \ - str-fnmat.lo str-incl.lo str-join.lo str-len.lo str-pac.lo \ - str-pbrk.lo str-put.lo str-rev.lo str-rot.lo str-set.lo \ - str-spl.lo str-spn.lo str-str.lo str-subst.lo str-tok.lo \ - str-trm.lo str-word.lo task.lo time.lo tio.lo tre.lo \ - tre-ast.lo tre-compile.lo tre-match-backtrack.lo \ - tre-match-parallel.lo tre-parse.lo tre-stack.lo uri.lo utf8.lo \ - xma.lo $(am__objects_1) $(am__objects_2) + str-cmp.lo str-cpy.lo str-del.lo str-dup.lo str-dyn.lo \ + str-end.lo str-excl.lo str-fcpy.lo str-fmt.lo str-fnmat.lo \ + str-incl.lo str-join.lo str-len.lo str-pac.lo str-pbrk.lo \ + str-put.lo str-rev.lo str-rot.lo str-set.lo str-spl.lo \ + str-spn.lo str-str.lo str-subst.lo str-tok.lo str-trm.lo \ + str-word.lo task.lo time.lo tio.lo tre.lo tre-ast.lo \ + tre-compile.lo tre-match-backtrack.lo tre-match-parallel.lo \ + tre-parse.lo tre-stack.lo uri.lo utf8.lo xma.lo \ + $(am__objects_1) $(am__objects_2) libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -372,6 +372,7 @@ noinst_HEADERS = \ fmt-out.h \ fs.h \ mem.h \ + str-dyn.h \ str-fcpy.h \ str-fmt.h \ str-join.h \ @@ -392,12 +393,12 @@ libqsecmn_la_SOURCES = alg-base64.c alg-rand.c alg-search.c alg-sort.c \ nwad-skad.c nwif.c nwif-cfg.c nwio.c oht.c opt.c \ path-basename.c path-canon.c pio.c pma.c rbt.c rex.c sio.c \ sll.c slmb.c stdio.c str-beg.c str-cat.c str-chr.c str-cnv.c \ - str-cmp.c str-cpy.c str-del.c str-dup.c str-dynm.c str-dynw.c \ - str-end.c str-excl.c str-fcpy.c str-fmt.c str-fnmat.c \ - str-incl.c str-join.c str-len.c str-pac.c str-pbrk.c str-put.c \ - str-rev.c str-rot.c str-set.c str-spl.c str-spn.c str-str.c \ - str-subst.c str-tok.c str-trm.c str-word.c task.c time.c tio.c \ - tre.c tre-ast.c tre-compile.c tre-match-backtrack.c \ + str-cmp.c str-cpy.c str-del.c str-dup.c str-dyn.c str-end.c \ + str-excl.c str-fcpy.c str-fmt.c str-fnmat.c str-incl.c \ + str-join.c str-len.c str-pac.c str-pbrk.c str-put.c str-rev.c \ + str-rot.c str-set.c str-spl.c str-spn.c str-str.c str-subst.c \ + str-tok.c str-trm.c str-word.c task.c time.c tio.c tre.c \ + tre-ast.c tre-compile.c tre-match-backtrack.c \ tre-match-parallel.c tre-parse.c tre-stack.c uri.c utf8.c \ xma.c $(am__append_1) $(am__append_2) libqsecmn_la_LDFLAGS = -version-info 1:0:0 -no-undefined @@ -540,8 +541,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-cpy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-del.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-dup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-dynm.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-dynw.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-dyn.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-end.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-excl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-fcpy.Plo@am__quote@ diff --git a/qse/lib/cmn/fmt-out.c b/qse/lib/cmn/fmt-out.c index 3d63c792..2add3193 100644 --- a/qse/lib/cmn/fmt-out.c +++ b/qse/lib/cmn/fmt-out.c @@ -27,6 +27,9 @@ #include "fmt.h" #include /* for snrintf() */ +#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200)) +# define snprintf _snprintf +#endif /* TODO: remove stdio.h once snprintf gets replaced by own floting-point conversion implementation*/ diff --git a/qse/lib/cmn/fmt-out.h b/qse/lib/cmn/fmt-out.h index 5f0b7e8a..e00e8c4b 100644 --- a/qse/lib/cmn/fmt-out.h +++ b/qse/lib/cmn/fmt-out.h @@ -91,7 +91,7 @@ static char_t* sprintn (char_t* nbuf, qse_uintmax_t num, int base, int *lenp, in if (data->count >= data->limit) goto done; \ if ((xx = data->put (c, data->ctx)) <= -1) goto oops; \ if (xx == 0) goto done; \ - data->count += xx; \ + data->count++; \ } while (0) int fmtout (const char_t* fmt, fmtout_t* data, va_list ap) diff --git a/qse/lib/cmn/str-dyn.c b/qse/lib/cmn/str-dyn.c new file mode 100644 index 00000000..bec6ae44 --- /dev/null +++ b/qse/lib/cmn/str-dyn.c @@ -0,0 +1,174 @@ +/* + * $Id$ + * + Copyright 2006-2012 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . + */ + +#include +#include "mem.h" + +#undef char_t +#undef xstr_t +#undef str_sizer_t +#undef T +#undef strlen +#undef strncpy +#undef strxpac +#undef strxtrm +#undef str_t +#undef str_open +#undef str_close +#undef str_init +#undef str_fini +#undef str_getmmgr +#undef str_getxtn +#undef str_yield +#undef str_yieldptr +#undef str_getsizer +#undef str_setsizer +#undef str_getcapa +#undef str_setcapa +#undef str_getlen +#undef str_setlen +#undef str_clear +#undef str_swap +#undef str_cpy +#undef str_ncpy +#undef str_cat +#undef resize_for_ncat +#undef str_ncat +#undef str_nrcat +#undef str_ccat +#undef str_nccat +#undef str_del +#undef str_trm +#undef str_pac + +#define char_t qse_mchar_t +#define xstr_t qse_mxstr_t +#define str_sizer_t qse_mbs_sizer_t +#define T(x) QSE_MT(x) +#define strlen(x) qse_mbslen(x) +#define strncpy(x,y,z) qse_mbsncpy(x,y,z) +#define strxpac(x,y) qse_mbsxpac(x,y) +#define strxtrm(x,y) qse_mbsxtrm(x,y) +#define str_t qse_mbs_t +#define str_open qse_mbs_open +#define str_close qse_mbs_close +#define str_init qse_mbs_init +#define str_fini qse_mbs_fini +#define str_getmmgr qse_mbs_getmmgr +#define str_getxtn qse_mbs_getxtn +#define str_yield qse_mbs_yield +#define str_yieldptr qse_mbs_yieldptr +#define str_getsizer qse_mbs_getsizer +#define str_setsizer qse_mbs_setsizer +#define str_getcapa qse_mbs_getcapa +#define str_setcapa qse_mbs_setcapa +#define str_getlen qse_mbs_getlen +#define str_setlen qse_mbs_setlen +#define str_clear qse_mbs_clear +#define str_swap qse_mbs_swap +#define str_cpy qse_mbs_cpy +#define str_ncpy qse_mbs_ncpy +#define str_cat qse_mbs_cat +#define resize_for_ncat resize_for_mbs_ncat +#define str_ncat qse_mbs_ncat +#define str_nrcat qse_mbs_nrcat +#define str_ccat qse_mbs_ccat +#define str_nccat qse_mbs_nccat +#define str_del qse_mbs_del +#define str_trm qse_mbs_trm +#define str_pac qse_mbs_pac +#include "str-dyn.h" + +/* -------------------------------------------------------- */ + +#undef char_t +#undef xstr_t +#undef str_sizer_t +#undef T +#undef strlen +#undef strncpy +#undef strxpac +#undef strxtrm +#undef str_t +#undef str_open +#undef str_close +#undef str_init +#undef str_fini +#undef str_getmmgr +#undef str_getxtn +#undef str_yield +#undef str_yieldptr +#undef str_getsizer +#undef str_setsizer +#undef str_getcapa +#undef str_setcapa +#undef str_getlen +#undef str_setlen +#undef str_clear +#undef str_swap +#undef str_cpy +#undef str_ncpy +#undef str_cat +#undef resize_for_ncat +#undef str_ncat +#undef str_nrcat +#undef str_ccat +#undef str_nccat +#undef str_del +#undef str_trm +#undef str_pac + +#define char_t qse_wchar_t +#define xstr_t qse_wxstr_t +#define str_sizer_t qse_wcs_sizer_t +#define T(x) QSE_WT(x) +#define strlen(x) qse_wcslen(x) +#define strncpy(x,y,z) qse_wcsncpy(x,y,z) +#define strxpac(x,y) qse_wcsxpac(x,y) +#define strxtrm(x,y) qse_wcsxtrm(x,y) +#define str_t qse_wcs_t +#define str_open qse_wcs_open +#define str_close qse_wcs_close +#define str_init qse_wcs_init +#define str_fini qse_wcs_fini +#define str_getmmgr qse_wcs_getmmgr +#define str_getxtn qse_wcs_getxtn +#define str_yield qse_wcs_yield +#define str_yieldptr qse_wcs_yieldptr +#define str_getsizer qse_wcs_getsizer +#define str_setsizer qse_wcs_setsizer +#define str_getcapa qse_wcs_getcapa +#define str_setcapa qse_wcs_setcapa +#define str_getlen qse_wcs_getlen +#define str_setlen qse_wcs_setlen +#define str_clear qse_wcs_clear +#define str_swap qse_wcs_swap +#define str_cpy qse_wcs_cpy +#define str_ncpy qse_wcs_ncpy +#define str_cat qse_wcs_cat +#define resize_for_ncat resize_for_wcs_ncat +#define str_ncat qse_wcs_ncat +#define str_nrcat qse_wcs_nrcat +#define str_ccat qse_wcs_ccat +#define str_nccat qse_wcs_nccat +#define str_del qse_wcs_del +#define str_trm qse_wcs_trm +#define str_pac qse_wcs_pac +#include "str-dyn.h" diff --git a/qse/lib/cmn/str-dynm.c b/qse/lib/cmn/str-dyn.h similarity index 55% rename from qse/lib/cmn/str-dynm.c rename to qse/lib/cmn/str-dyn.h index 7936157f..bf360d20 100644 --- a/qse/lib/cmn/str-dynm.c +++ b/qse/lib/cmn/str-dyn.h @@ -21,14 +21,14 @@ #include #include "mem.h" -qse_mbs_t* qse_mbs_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_size_t capa) +str_t* str_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_size_t capa) { - qse_mbs_t* str; + str_t* str; - str = (qse_mbs_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_mbs_t) + xtnsize); + str = (str_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(str_t) + xtnsize); if (str) { - if (qse_mbs_init (str, mmgr, capa) <= -1) + if (str_init (str, mmgr, capa) <= -1) { QSE_MMGR_FREE (mmgr, str); str = QSE_NULL; @@ -41,15 +41,15 @@ qse_mbs_t* qse_mbs_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_size_t capa) return str; } -void qse_mbs_close (qse_mbs_t* str) +void str_close (str_t* str) { - qse_mbs_fini (str); + str_fini (str); QSE_MMGR_FREE (str->mmgr, str); } -int qse_mbs_init (qse_mbs_t* str, qse_mmgr_t* mmgr, qse_size_t capa) +int str_init (str_t* str, qse_mmgr_t* mmgr, qse_size_t capa) { - QSE_MEMSET (str, 0, QSE_SIZEOF(qse_mbs_t)); + QSE_MEMSET (str, 0, QSE_SIZEOF(str_t)); str->mmgr = mmgr; str->sizer = QSE_NULL; @@ -57,10 +57,10 @@ int qse_mbs_init (qse_mbs_t* str, qse_mmgr_t* mmgr, qse_size_t capa) if (capa == 0) str->val.ptr = QSE_NULL; else { - str->val.ptr = (qse_mchar_t*) QSE_MMGR_ALLOC ( - mmgr, QSE_SIZEOF(qse_mchar_t) * (capa + 1)); + str->val.ptr = (char_t*) QSE_MMGR_ALLOC ( + mmgr, QSE_SIZEOF(char_t) * (capa + 1)); if (str->val.ptr == QSE_NULL) return -1; - str->val.ptr[0] = QSE_MT('\0'); + str->val.ptr[0] = T('\0'); } str->val.len = 0; @@ -69,32 +69,32 @@ int qse_mbs_init (qse_mbs_t* str, qse_mmgr_t* mmgr, qse_size_t capa) return 0; } -void qse_mbs_fini (qse_mbs_t* str) +void str_fini (str_t* str) { if (str->val.ptr != QSE_NULL) QSE_MMGR_FREE (str->mmgr, str->val.ptr); } -qse_mmgr_t* qse_mbs_getmmgr (qse_mbs_t* mbs) +qse_mmgr_t* str_getmmgr (str_t* mbs) { return mbs->mmgr; } -void* qse_mbs_getxtn (qse_mbs_t* mbs) +void* str_getxtn (str_t* mbs) { return QSE_XTN (mbs); } -int qse_mbs_yield (qse_mbs_t* str, qse_mxstr_t* buf, qse_size_t newcapa) +int str_yield (str_t* str, xstr_t* buf, qse_size_t newcapa) { - qse_mchar_t* tmp; + char_t* tmp; if (newcapa == 0) tmp = QSE_NULL; else { - tmp = (qse_mchar_t*) QSE_MMGR_ALLOC ( - str->mmgr, QSE_SIZEOF(qse_mchar_t) * (newcapa + 1)); + tmp = (char_t*) QSE_MMGR_ALLOC ( + str->mmgr, QSE_SIZEOF(char_t) * (newcapa + 1)); if (tmp == QSE_NULL) return -1; - tmp[0] = QSE_MT('\0'); + tmp[0] = T('\0'); } if (buf != QSE_NULL) @@ -110,52 +110,52 @@ int qse_mbs_yield (qse_mbs_t* str, qse_mxstr_t* buf, qse_size_t newcapa) return 0; } -qse_mchar_t* qse_mbs_yieldptr (qse_mbs_t* str, qse_size_t newcapa) +char_t* str_yieldptr (str_t* str, qse_size_t newcapa) { - qse_mxstr_t mx; - if (qse_mbs_yield (str, &mx, newcapa) <= -1) return QSE_NULL; + xstr_t mx; + if (str_yield (str, &mx, newcapa) <= -1) return QSE_NULL; return mx.ptr; } -qse_mbs_sizer_t qse_mbs_getsizer (qse_mbs_t* str) +str_sizer_t str_getsizer (str_t* str) { return str->sizer; } -void qse_mbs_setsizer (qse_mbs_t* str, qse_mbs_sizer_t sizer) +void str_setsizer (str_t* str, str_sizer_t sizer) { str->sizer = sizer; } -qse_size_t qse_mbs_getcapa (qse_mbs_t* str) +qse_size_t str_getcapa (str_t* str) { return str->capa; } -qse_size_t qse_mbs_setcapa (qse_mbs_t* str, qse_size_t capa) +qse_size_t str_setcapa (str_t* str, qse_size_t capa) { - qse_mchar_t* tmp; + char_t* tmp; if (capa == str->capa) return capa; if (str->mmgr->realloc != QSE_NULL && str->val.ptr != QSE_NULL) { - tmp = (qse_mchar_t*) QSE_MMGR_REALLOC ( + tmp = (char_t*) QSE_MMGR_REALLOC ( str->mmgr, str->val.ptr, - QSE_SIZEOF(qse_mchar_t)*(capa+1)); + QSE_SIZEOF(char_t)*(capa+1)); if (tmp == QSE_NULL) return (qse_size_t)-1; } else { - tmp = (qse_mchar_t*) QSE_MMGR_ALLOC ( - str->mmgr, QSE_SIZEOF(qse_mchar_t)*(capa+1)); + tmp = (char_t*) QSE_MMGR_ALLOC ( + str->mmgr, QSE_SIZEOF(char_t)*(capa+1)); if (tmp == QSE_NULL) return (qse_size_t)-1; if (str->val.ptr != QSE_NULL) { qse_size_t ncopy = (str->val.len <= capa)? str->val.len: capa; QSE_MEMCPY (tmp, str->val.ptr, - QSE_SIZEOF(qse_mchar_t)*(ncopy+1)); + QSE_SIZEOF(char_t)*(ncopy+1)); QSE_MMGR_FREE (str->mmgr, str->val.ptr); } } @@ -163,7 +163,7 @@ qse_size_t qse_mbs_setcapa (qse_mbs_t* str, qse_size_t capa) if (capa < str->val.len) { str->val.len = capa; - tmp[capa] = QSE_MT('\0'); + tmp[capa] = T('\0'); } str->capa = capa; @@ -172,45 +172,45 @@ qse_size_t qse_mbs_setcapa (qse_mbs_t* str, qse_size_t capa) return str->capa; } -qse_size_t qse_mbs_getlen (qse_mbs_t* str) +qse_size_t str_getlen (str_t* str) { return QSE_MBS_LEN (str); } -qse_size_t qse_mbs_setlen (qse_mbs_t* str, qse_size_t len) +qse_size_t str_setlen (str_t* str, qse_size_t len) { if (len == str->val.len) return len; if (len < str->val.len) { str->val.len = len; - str->val.ptr[len] = QSE_MT('\0'); + str->val.ptr[len] = T('\0'); return len; } if (len > str->capa) { - if (qse_mbs_setcapa (str, len) == (qse_size_t)-1) + if (str_setcapa (str, len) == (qse_size_t)-1) return (qse_size_t)-1; } - while (str->val.len < len) str->val.ptr[str->val.len++] = QSE_MT(' '); - str->val.ptr[str->val.len] = QSE_MT('\0'); + while (str->val.len < len) str->val.ptr[str->val.len++] = T(' '); + str->val.ptr[str->val.len] = T('\0'); return str->val.len; } -void qse_mbs_clear (qse_mbs_t* str) +void str_clear (str_t* str) { str->val.len = 0; if (str->val.ptr != QSE_NULL) { QSE_ASSERT (str->capa >= 1); - str->val.ptr[0] = QSE_MT('\0'); + str->val.ptr[0] = T('\0'); } } -void qse_mbs_swap (qse_mbs_t* str, qse_mbs_t* str1) +void str_swap (str_t* str, str_t* str1) { - qse_mbs_t tmp; + str_t tmp; tmp.val.ptr = str->val.ptr; tmp.val.len = str->val.len; @@ -228,13 +228,13 @@ void qse_mbs_swap (qse_mbs_t* str, qse_mbs_t* str1) str1->mmgr = tmp.mmgr; } -qse_size_t qse_mbs_cpy (qse_mbs_t* str, const qse_mchar_t* s) +qse_size_t str_cpy (str_t* str, const char_t* s) { /* TODO: improve it */ - return qse_mbs_ncpy (str, s, qse_mbslen(s)); + return str_ncpy (str, s, strlen(s)); } -qse_size_t qse_mbs_ncpy (qse_mbs_t* str, const qse_mchar_t* s, qse_size_t len) +qse_size_t str_ncpy (str_t* str, const char_t* s, qse_size_t len) { if (len > str->capa || str->capa <= 0) { @@ -242,35 +242,35 @@ qse_size_t qse_mbs_ncpy (qse_mbs_t* str, const qse_mchar_t* s, qse_size_t len) /* if the current capacity is 0 and the string len to copy is 0 * we can't simply pass 'len' as the new capapcity. - * qse_mbs_setcapa() won't do anything the current capacity of 0 + * str_setcapa() won't do anything the current capacity of 0 * is the same as new capacity required. note that when str->capa * is 0, str->val.ptr is QSE_NULL. However, this is copying operation. * Copying a zero-length string may indicate that str->val.ptr must * not be QSE_NULL. so I simply pass 1 as the new capacity */ - tmp = qse_mbs_setcapa ( + tmp = str_setcapa ( str, ((str->capa <= 0 && len <= 0)? 1: len) ); if (tmp == (qse_size_t)-1) return (qse_size_t)-1; } QSE_MEMCPY (&str->val.ptr[0], s, len*QSE_SIZEOF(*s)); - str->val.ptr[len] = QSE_MT('\0'); + str->val.ptr[len] = T('\0'); str->val.len = len; return len; #if 0 - str->val.len = qse_mbsncpy (str->val.ptr, s, len); - /*str->val.ptr[str->val.len] = QSE_MT('\0'); -> mbsncpy does this*/ + str->val.len = strncpy (str->val.ptr, s, len); + /*str->val.ptr[str->val.len] = T('\0'); -> mbsncpy does this*/ return str->val.len; #endif } -qse_size_t qse_mbs_cat (qse_mbs_t* str, const qse_mchar_t* s) +qse_size_t str_cat (str_t* str, const char_t* s) { /* TODO: improve it */ - return qse_mbs_ncat (str, s, qse_mbslen(s)); + return str_ncat (str, s, strlen(s)); } -static int resize_for_ncat (qse_mbs_t* str, qse_size_t len) +static int resize_for_ncat (str_t* str, qse_size_t len) { if (len > str->capa - str->val.len) { @@ -300,7 +300,7 @@ static int resize_for_ncat (qse_mbs_t* str, qse_size_t len) /* change the capacity */ do { - if (qse_mbs_setcapa (str, ncapa) != (qse_size_t)-1) break; + if (str_setcapa (str, ncapa) != (qse_size_t)-1) break; if (ncapa <= mincapa) return -1; ncapa--; } @@ -310,57 +310,16 @@ static int resize_for_ncat (qse_mbs_t* str, qse_size_t len) { QSE_ASSERT (str->val.ptr == QSE_NULL); QSE_ASSERT (str->val.len <= 0); - if (qse_mbs_setcapa (str, 1) == (qse_size_t)-1) return -1; + if (str_setcapa (str, 1) == (qse_size_t)-1) return -1; } return 1; } -qse_size_t qse_mbs_ncat (qse_mbs_t* str, const qse_mchar_t* s, qse_size_t len) +qse_size_t str_ncat (str_t* str, const char_t* s, qse_size_t len) { -#if 0 - if (len > str->capa - str->val.len) - { - qse_size_t ncapa, mincapa; - - /* let the minimum capacity be as large as - * to fit in the new substring */ - mincapa = str->val.len + len; - - if (str->sizer == QSE_NULL) - { - /* increase the capacity by the length to add */ - ncapa = mincapa; - /* if the new capacity is less than the double, - * just double it */ - if (ncapa < str->capa * 2) ncapa = str->capa * 2; - } - else - { - /* let the user determine the new capacity. - * pass the minimum capacity required as a hint */ - ncapa = str->sizer (str, mincapa); - /* if no change in capacity, return current length */ - if (ncapa == str->capa) return str->val.len; - } - - /* change the capacity */ - do - { - if (qse_mbs_setcapa (str, ncapa) != (qse_size_t)-1) break; - if (ncapa <= mincapa) return (qse_size_t)-1; - ncapa--; - } - while (1); - } - else if (str->capa <= 0 && len <= 0) - { - QSE_ASSERT (str->val.ptr == QSE_NULL); - QSE_ASSERT (str->val.len <= 0); - if (qse_mbs_setcapa (str, 1) == (qse_size_t)-1) return (qse_size_t)-1; - } -#endif int n; + qse_size_t i, j; n = resize_for_ncat (str, len); if (n <= -1) return (qse_size_t)-1; @@ -373,21 +332,19 @@ qse_size_t qse_mbs_ncat (qse_mbs_t* str, const qse_mchar_t* s, qse_size_t len) len = str->capa - str->val.len; } -#if 0 - if (len > 0) - { -#endif - QSE_MEMCPY (&str->val.ptr[str->val.len], s, len*QSE_SIZEOF(*s)); - str->val.len += len; - str->val.ptr[str->val.len] = QSE_MT('\0'); -#if 0 - } -#endif + /* + QSE_MEMCPY (&str->val.ptr[str->val.len], s, len*QSE_SIZEOF(*s)); + str->val.len += len; + str->val.ptr[str->val.len] = T('\0'); + */ + for (i = 0, j = str->val.len ; i < len; j++, i++) str->val.ptr[j] = s[i]; + str->val.ptr[j] = T('\0'); + str->val.len = j; return str->val.len; } -qse_size_t qse_mbs_nrcat (qse_mbs_t* str, const qse_mchar_t* s, qse_size_t len) +qse_size_t str_nrcat (str_t* str, const char_t* s, qse_size_t len) { int n; qse_size_t i, j; @@ -399,22 +356,22 @@ qse_size_t qse_mbs_nrcat (qse_mbs_t* str, const qse_mchar_t* s, qse_size_t 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]; - str->val.ptr[j] = QSE_MT('\0'); + str->val.ptr[j] = T('\0'); str->val.len = j; return str->val.len; } -qse_size_t qse_mbs_ccat (qse_mbs_t* str, qse_mchar_t c) +qse_size_t str_ccat (str_t* str, char_t c) { - return qse_mbs_ncat (str, &c, 1); + return str_ncat (str, &c, 1); } -qse_size_t qse_mbs_nccat (qse_mbs_t* str, qse_mchar_t c, qse_size_t len) +qse_size_t str_nccat (str_t* str, char_t c, qse_size_t len) { while (len > 0) { - if (qse_mbs_ncat (str, &c, 1) == (qse_size_t)-1) + if (str_ncat (str, &c, 1) == (qse_size_t)-1) { return (qse_size_t)-1; } @@ -424,19 +381,19 @@ qse_size_t qse_mbs_nccat (qse_mbs_t* str, qse_mchar_t c, qse_size_t len) return str->val.len; } -qse_size_t qse_mbs_del (qse_mbs_t* str, qse_size_t index, qse_size_t size) +qse_size_t str_del (str_t* str, qse_size_t index, qse_size_t size) { if (str->val.ptr != QSE_NULL && index < str->val.len && size > 0) { qse_size_t nidx = index + size; if (nidx >= str->val.len) { - str->val.ptr[index] = QSE_MT('\0'); + str->val.ptr[index] = T('\0'); str->val.len = index; } else { - qse_mbsncpy ( + strncpy ( &str->val.ptr[index], &str->val.ptr[nidx], str->val.len - nidx); str->val.len -= size; @@ -446,21 +403,21 @@ qse_size_t qse_mbs_del (qse_mbs_t* str, qse_size_t index, qse_size_t size) return str->val.len; } -qse_size_t qse_mbs_trm (qse_mbs_t* str) +qse_size_t str_trm (str_t* str) { if (str->val.ptr != QSE_NULL) { - str->val.len = qse_mbsxtrm (str->val.ptr, str->val.len); + str->val.len = strxtrm (str->val.ptr, str->val.len); } return str->val.len; } -qse_size_t qse_mbs_pac (qse_mbs_t* str) +qse_size_t str_pac (str_t* str) { if (str->val.ptr != QSE_NULL) { - str->val.len = qse_mbsxpac (str->val.ptr, str->val.len); + str->val.len = strxpac (str->val.ptr, str->val.len); } return str->val.len; diff --git a/qse/lib/cmn/str-dynw.c b/qse/lib/cmn/str-dynw.c deleted file mode 100644 index 816e4d74..00000000 --- a/qse/lib/cmn/str-dynw.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * $Id$ - * - Copyright 2006-2012 Chung, Hyung-Hwan. - This file is part of QSE. - - QSE is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - QSE is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with QSE. If not, see . - */ - -#include -#include "mem.h" - -qse_wcs_t* qse_wcs_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_size_t capa) -{ - qse_wcs_t* str; - - str = (qse_wcs_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_wcs_t) + xtnsize); - if (str) - { - if (qse_wcs_init (str, mmgr, capa) <= -1) - { - QSE_MMGR_FREE (mmgr, str); - str = QSE_NULL; - } - else - { - QSE_MEMSET (str + 1, 0, xtnsize); - } - } - return str; -} - -void qse_wcs_close (qse_wcs_t* str) -{ - qse_wcs_fini (str); - QSE_MMGR_FREE (str->mmgr, str); -} - -int qse_wcs_init (qse_wcs_t* str, qse_mmgr_t* mmgr, qse_size_t capa) -{ - QSE_MEMSET (str, 0, QSE_SIZEOF(qse_wcs_t)); - - str->mmgr = mmgr; - str->sizer = QSE_NULL; - - if (capa == 0) str->val.ptr = QSE_NULL; - else - { - str->val.ptr = (qse_wchar_t*) QSE_MMGR_ALLOC ( - mmgr, QSE_SIZEOF(qse_wchar_t) * (capa + 1)); - if (str->val.ptr == QSE_NULL) return -1; - str->val.ptr[0] = QSE_WT('\0'); - } - - str->val.len = 0; - str->capa = capa; - - return 0; -} - -void qse_wcs_fini (qse_wcs_t* str) -{ - if (str->val.ptr != QSE_NULL) QSE_MMGR_FREE (str->mmgr, str->val.ptr); -} - -qse_mmgr_t* qse_wcs_getmmgr (qse_wcs_t* wcs) -{ - return wcs->mmgr; -} - -void* qse_wcs_getxtn (qse_wcs_t* wcs) -{ - return QSE_XTN (wcs); -} - -int qse_wcs_yield (qse_wcs_t* str, qse_wxstr_t* buf, qse_size_t newcapa) -{ - qse_wchar_t* tmp; - - if (newcapa == 0) tmp = QSE_NULL; - else - { - tmp = (qse_wchar_t*) QSE_MMGR_ALLOC ( - str->mmgr, QSE_SIZEOF(qse_wchar_t) * (newcapa + 1)); - if (tmp == QSE_NULL) return -1; - tmp[0] = QSE_WT('\0'); - } - - if (buf != QSE_NULL) - { - buf->ptr = str->val.ptr; - buf->len = str->val.len; - } - - str->val.ptr = tmp; - str->val.len = 0; - str->capa = newcapa; - - return 0; -} - -qse_wchar_t* qse_wcs_yieldptr (qse_wcs_t* str, qse_size_t newcapa) -{ - qse_wxstr_t wx; - if (qse_wcs_yield (str, &wx, newcapa) <= -1) return QSE_NULL; - return wx.ptr; -} - -qse_wcs_sizer_t qse_wcs_getsizer (qse_wcs_t* str) -{ - return str->sizer; -} - -void qse_wcs_setsizer (qse_wcs_t* str, qse_wcs_sizer_t sizer) -{ - str->sizer = sizer; -} - -qse_size_t qse_wcs_getcapa (qse_wcs_t* str) -{ - return str->capa; -} - -qse_size_t qse_wcs_setcapa (qse_wcs_t* str, qse_size_t capa) -{ - qse_wchar_t* tmp; - - if (capa == str->capa) return capa; - - if (str->mmgr->realloc != QSE_NULL && str->val.ptr != QSE_NULL) - { - tmp = (qse_wchar_t*) QSE_MMGR_REALLOC ( - str->mmgr, str->val.ptr, - QSE_SIZEOF(qse_wchar_t)*(capa+1)); - if (tmp == QSE_NULL) return (qse_size_t)-1; - } - else - { - tmp = (qse_wchar_t*) QSE_MMGR_ALLOC ( - str->mmgr, QSE_SIZEOF(qse_wchar_t)*(capa+1)); - if (tmp == QSE_NULL) return (qse_size_t)-1; - - if (str->val.ptr != QSE_NULL) - { - qse_size_t ncopy = (str->val.len <= capa)? str->val.len: capa; - QSE_MEMCPY (tmp, str->val.ptr, - QSE_SIZEOF(qse_wchar_t)*(ncopy+1)); - QSE_MMGR_FREE (str->mmgr, str->val.ptr); - } - } - - if (capa < str->val.len) - { - str->val.len = capa; - tmp[capa] = QSE_WT('\0'); - } - - str->capa = capa; - str->val.ptr = tmp; - - return str->capa; -} - -qse_size_t qse_wcs_getlen (qse_wcs_t* str) -{ - return QSE_WCS_LEN (str); -} - -qse_size_t qse_wcs_setlen (qse_wcs_t* str, qse_size_t len) -{ - if (len == str->val.len) return len; - if (len < str->val.len) - { - str->val.len = len; - str->val.ptr[len] = QSE_WT('\0'); - return len; - } - - if (len > str->capa) - { - if (qse_wcs_setcapa (str, len) == (qse_size_t)-1) - return (qse_size_t)-1; - } - - while (str->val.len < len) str->val.ptr[str->val.len++] = QSE_WT(' '); - str->val.ptr[str->val.len] = QSE_WT('\0'); - return str->val.len; -} - -void qse_wcs_clear (qse_wcs_t* str) -{ - str->val.len = 0; - if (str->val.ptr != QSE_NULL) - { - QSE_ASSERT (str->capa >= 1); - str->val.ptr[0] = QSE_WT('\0'); - } -} - -void qse_wcs_swap (qse_wcs_t* str, qse_wcs_t* str1) -{ - qse_wcs_t tmp; - - tmp.val.ptr = str->val.ptr; - tmp.val.len = str->val.len; - tmp.capa = str->capa; - tmp.mmgr = str->mmgr; - - str->val.ptr = str1->val.ptr; - str->val.len = str1->val.len; - str->capa = str1->capa; - str->mmgr = str1->mmgr; - - str1->val.ptr = tmp.val.ptr; - str1->val.len = tmp.val.len; - str1->capa = tmp.capa; - str1->mmgr = tmp.mmgr; -} - -qse_size_t qse_wcs_cpy (qse_wcs_t* str, const qse_wchar_t* s) -{ - /* TODO: improve it */ - return qse_wcs_ncpy (str, s, qse_wcslen(s)); -} - -qse_size_t qse_wcs_ncpy (qse_wcs_t* str, const qse_wchar_t* s, qse_size_t len) -{ - if (len > str->capa || str->capa <= 0) - { - qse_size_t tmp; - - /* if the current capacity is 0 and the string len to copy is 0 - * we can't simply pass 'len' as the new capapcity. - * qse_wcs_setcapa() won't do anything the current capacity of 0 - * is the same as new capacity required. note that when str->capa - * is 0, str->val.ptr is QSE_NULL. However, this is copying operation. - * Copying a zero-length string may indicate that str->val.ptr must - * not be QSE_NULL. so I simply pass 1 as the new capacity */ - tmp = qse_wcs_setcapa ( - str, ((str->capa <= 0 && len <= 0)? 1: len) - ); - if (tmp == (qse_size_t)-1) return (qse_size_t)-1; - } - - QSE_MEMCPY (&str->val.ptr[0], s, len*QSE_SIZEOF(*s)); - str->val.ptr[len] = QSE_WT('\0'); - str->val.len = len; - return len; -#if 0 - str->val.len = qse_wcsncpy (str->val.ptr, s, len); - /*str->val.ptr[str->val.len] = QSE_WT('\0'); -> wcsncpy does this*/ - return str->val.len; -#endif -} - -qse_size_t qse_wcs_cat (qse_wcs_t* str, const qse_wchar_t* s) -{ - /* TODO: improve it */ - return qse_wcs_ncat (str, s, qse_wcslen(s)); -} - -static int resize_for_ncat (qse_wcs_t* str, qse_size_t len) -{ - if (len > str->capa - str->val.len) - { - qse_size_t ncapa, mincapa; - - /* let the minimum capacity be as large as - * to fit in the new substring */ - mincapa = str->val.len + len; - - if (str->sizer == QSE_NULL) - { - /* increase the capacity by the length to add */ - ncapa = mincapa; - /* if the new capacity is less than the double, - * just double it */ - if (ncapa < str->capa * 2) ncapa = str->capa * 2; - } - else - { - /* let the user determine the new capacity. - * pass the minimum capacity required as a hint */ - ncapa = str->sizer (str, mincapa); - /* if no change in capacity, return current length */ - if (ncapa == str->capa) return 0; - } - - /* change the capacity */ - do - { - if (qse_wcs_setcapa (str, ncapa) != (qse_size_t)-1) break; - if (ncapa <= mincapa) return -1; - ncapa--; - } - while (1); - } - else if (str->capa <= 0 && len <= 0) - { - QSE_ASSERT (str->val.ptr == QSE_NULL); - QSE_ASSERT (str->val.len <= 0); - if (qse_wcs_setcapa (str, 1) == (qse_size_t)-1) return -1; - } - - return 1; -} - -qse_size_t qse_wcs_ncat (qse_wcs_t* str, const qse_wchar_t* s, qse_size_t len) -{ -#if 0 - if (len > str->capa - str->val.len) - { - qse_size_t ncapa, mincapa; - - /* let the minimum capacity be as large as - * to fit in the new substring */ - mincapa = str->val.len + len; - - if (str->sizer == QSE_NULL) - { - /* increase the capacity by the length to add */ - ncapa = mincapa; - /* if the new capacity is less than the double, - * just double it */ - if (ncapa < str->capa * 2) ncapa = str->capa * 2; - } - else - { - /* let the user determine the new capacity. - * pass the minimum capacity required as a hint */ - ncapa = str->sizer (str, mincapa); - /* if no change in capacity, return current length */ - if (ncapa == str->capa) return str->val.len; - } - - /* change the capacity */ - do - { - if (qse_wcs_setcapa (str, ncapa) != (qse_size_t)-1) break; - if (ncapa <= mincapa) return (qse_size_t)-1; - ncapa--; - } - while (1); - } - else if (str->capa <= 0 && len <= 0) - { - QSE_ASSERT (str->val.ptr == QSE_NULL); - QSE_ASSERT (str->val.len <= 0); - if (qse_wcs_setcapa (str, 1) == (qse_size_t)-1) return (qse_size_t)-1; - } -#endif - int n; - - 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) - { - /* copy as many characters as the number of cells available. - * if the capacity has been decreased, len is adjusted here */ - len = str->capa - str->val.len; - } - -#if 0 - if (len > 0) - { -#endif - QSE_MEMCPY (&str->val.ptr[str->val.len], s, len*QSE_SIZEOF(*s)); - str->val.len += len; - str->val.ptr[str->val.len] = QSE_WT('\0'); -#if 0 - } -#endif - - return str->val.len; -} - -qse_size_t qse_wcs_nrcat (qse_wcs_t* str, const qse_wchar_t* s, qse_size_t len) -{ - int n; - qse_size_t i, j; - - 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]; - str->val.ptr[j] = QSE_WT('\0'); - str->val.len = j; - - return str->val.len; -} - -qse_size_t qse_wcs_ccat (qse_wcs_t* str, qse_wchar_t c) -{ - return qse_wcs_ncat (str, &c, 1); -} - -qse_size_t qse_wcs_nccat (qse_wcs_t* str, qse_wchar_t c, qse_size_t len) -{ - while (len > 0) - { - if (qse_wcs_ncat (str, &c, 1) == (qse_size_t)-1) - { - return (qse_size_t)-1; - } - - len--; - } - return str->val.len; -} - -qse_size_t qse_wcs_del (qse_wcs_t* str, qse_size_t index, qse_size_t size) -{ - if (str->val.ptr != QSE_NULL && index < str->val.len && size > 0) - { - qse_size_t nidx = index + size; - if (nidx >= str->val.len) - { - str->val.ptr[index] = QSE_WT('\0'); - str->val.len = index; - } - else - { - qse_wcsncpy ( - &str->val.ptr[index], &str->val.ptr[nidx], - str->val.len - nidx); - str->val.len -= size; - } - } - - return str->val.len; -} - -qse_size_t qse_wcs_trm (qse_wcs_t* str) -{ - if (str->val.ptr != QSE_NULL) - { - str->val.len = qse_wcsxtrm (str->val.ptr, str->val.len); - } - - return str->val.len; -} - -qse_size_t qse_wcs_pac (qse_wcs_t* str) -{ - if (str->val.ptr != QSE_NULL) - { - str->val.len = qse_wcsxpac (str->val.ptr, str->val.len); - } - - return str->val.len; -} - - diff --git a/qse/lib/cmn/str-fmt.c b/qse/lib/cmn/str-fmt.c index b2bf7321..7807b078 100644 --- a/qse/lib/cmn/str-fmt.c +++ b/qse/lib/cmn/str-fmt.c @@ -42,25 +42,46 @@ typedef struct wbuf_t wbuf_t; static int put_mchar (qse_mchar_t c, void* ctx) { mbuf_t* buf = (mbuf_t*)ctx; - if (buf->len < buf->capa) + + /* do not copy but return success if the buffer pointer + * points to NULL. this is to let the caller specify + * NULL as a buffer to get the length required for the + * full formatting excluding the terminating NULL. + * The actual length required is the return value + 1. */ + if (buf->ptr == QSE_NULL) + { + buf->len++; + return 1; + } + else if (buf->len < buf->capa) { buf->ptr[buf->len++] = c; return 1; } - return 0; /* stop. but no error */ + /* buffer is full stop. but no error */ + return 0; } static int put_wchar (qse_wchar_t c, void* ctx) { wbuf_t* buf = (wbuf_t*)ctx; + + /* do not copy but return success if the buffer pointer + * points to NULL. this is to let the caller specify + * NULL as a buffer to get the length required for the + * full formatting excluding the terminating NULL. + * The actual length required is the return value + 1. */ + if (buf->ptr == QSE_NULL) return 1; + if (buf->len < buf->capa) { buf->ptr[buf->len++] = c; return 1; } - return 0; /* stop. but no error */ + /* buffer is full stop. but no error */ + return 0; } static int wcs_to_mbs ( diff --git a/qse/lib/cmn/str-fmt.h b/qse/lib/cmn/str-fmt.h index 8d7d523d..75a19e81 100644 --- a/qse/lib/cmn/str-fmt.h +++ b/qse/lib/cmn/str-fmt.h @@ -24,6 +24,7 @@ qse_size_t strfmt (char_t* buf, const char_t* fmt, ...) buf_t b; va_list ap; fmtout_t fo; + int x; b.ptr = buf; b.len = 0; @@ -34,15 +35,23 @@ qse_size_t strfmt (char_t* buf, const char_t* fmt, ...) fo.put = put_char; fo.conv = conv_char; - /* no error must be returned by fmtout since - * the callback function never fails. */ + /* no I/O error must occurred by fmtout but there can be + * encoding conversion error by fmtout */ va_start (ap, fmt); - fmtout (fmt, &fo, ap); + x = fmtout (fmt, &fo, ap); va_end (ap); + /* fmtout must produce no I/O error but it can produce + * an encoding conversion error. if you didn't use a conversion + * specifier that requires encoding conversion (%S, %C, etc), + * you don't need to worry about an error. */ + + /* null-terminate regardless of error */ b.ptr[b.len] = T('\0'); - /*return fo.count;*/ + if (x <= -1) return QSE_TYPE_MAX(qse_size_t); + + QSE_ASSERT (fo.count == b.len); return b.len; } @@ -51,6 +60,7 @@ qse_size_t strxfmt (char_t* buf, qse_size_t len, const char_t* fmt, ...) buf_t b; va_list ap; fmtout_t fo; + int x; b.ptr = buf; b.len = 0; @@ -67,15 +77,20 @@ qse_size_t strxfmt (char_t* buf, qse_size_t len, const char_t* fmt, ...) fo.put = put_char; fo.conv = conv_char; - /* no error must be returned by fmtout since - * the callback function never fails. */ va_start (ap, fmt); - fmtout (fmt, &fo, ap); + x = fmtout (fmt, &fo, ap); va_end (ap); - if (len > 0) b.ptr[b.len] = T('\0'); + /* fmtout must produce no I/O error but it can produce + * an encoding conversion error. if you didn't use a conversion + * specifier that requires encoding conversion (%S, %C, etc), + * you don't need to worry about an error. */ - /*return fo.count;*/ + /* null-terminate regardless of error */ + if (len > 0) b.ptr[b.len] = T('\0'); + if (x <= -1) return QSE_TYPE_MAX(qse_size_t); + + QSE_ASSERT (fo.count == b.len); return b.len; }