minix/lib/libc/citrus/citrus_ctype_template.h
Lionel Sambuc 84d9c625bf Synchronize on NetBSD-CVS (2013/12/1 12:00:00 UTC)
- Fix for possible unset uid/gid in toproto
 - Fix for default mtree style
 - Update libelf
 - Importing libexecinfo
 - Resynchronize GCC, mpc, gmp, mpfr
 - build.sh: Replace params with show-params.
     This has been done as the make target has been renamed in the same
     way, while a new target named params has been added. This new
     target generates a file containing all the parameters, instead of
     printing it on the console.
 - Update test48 with new etc/services (Fix by Ben Gras <ben@minix3.org)
     get getservbyport() out of the inner loop

Change-Id: Ie6ad5226fa2621ff9f0dee8782ea48f9443d2091
2014-07-28 17:05:06 +02:00

935 lines
22 KiB
C

/* $NetBSD: citrus_ctype_template.h,v 1.36 2013/05/28 16:57:56 joerg Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Paul Borman at Krystal Technologies.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* CAUTION: THIS IS NOT STANDALONE FILE
*
* function templates of ctype encoding handler for each encodings.
*
* you need to define the macros below:
*
* _FUNCNAME(method) :
* It should convine the real function name for the method.
* e.g. _FUNCNAME(mbrtowc) should be expanded to
* _EUC_ctype_mbrtowc
* for EUC locale.
*
* _CEI_TO_STATE(cei, method) :
* It should be expanded to the pointer of the method-internal state
* structures.
* e.g. _CEI_TO_STATE(cei, mbrtowc) might be expanded to
* (cei)->states.s_mbrtowc
* This structure may use if the function is called as
* mbrtowc(&wc, s, n, NULL);
* Such individual structures are needed by:
* mblen
* mbrlen
* mbrtowc
* mbtowc
* mbsrtowcs
* mbsnrtowcs
* wcrtomb
* wcsrtombs
* wcsnrtombs
* wctomb
* These need to be keeped in the ctype encoding information structure,
* pointed by "cei".
*
* _ENCODING_INFO :
* It should be expanded to the name of the encoding information structure.
* e.g. For EUC encoding, this macro is expanded to _EUCInfo.
* Encoding information structure need to contain the common informations
* for the codeset.
*
* _ENCODING_STATE :
* It should be expanded to the name of the encoding state structure.
* e.g. For EUC encoding, this macro is expanded to _EUCState.
* Encoding state structure need to contain the context-dependent states,
* which are "unpacked-form" of mbstate_t type and keeped during sequent
* calls of mb/wc functions,
*
* _ENCODING_IS_STATE_DEPENDENT :
* If the encoding is state dependent, this should be expanded to
* non-zero integral value. Otherwise, 0.
*
* _STATE_NEEDS_EXPLICIT_INIT(ps) :
* some encodings, states needs some explicit initialization.
* (ie. initialization with memset isn't enough.)
* If the encoding state pointed by "ps" needs to be initialized
* explicitly, return non-zero. Otherwize, 0.
*
*/
/* prototypes */
__BEGIN_DECLS
static void _FUNCNAME(init_state)(_ENCODING_INFO * __restrict,
_ENCODING_STATE * __restrict);
static void _FUNCNAME(pack_state)(_ENCODING_INFO * __restrict,
void * __restrict,
const _ENCODING_STATE * __restrict);
static void _FUNCNAME(unpack_state)(_ENCODING_INFO * __restrict,
_ENCODING_STATE * __restrict,
const void * __restrict);
#if _ENCODING_IS_STATE_DEPENDENT
static int _FUNCNAME(put_state_reset)(_ENCODING_INFO * __restrict,
char * __restrict, size_t,
_ENCODING_STATE * __restrict,
size_t * __restrict);
#endif
/*
* standard form of mbrtowc_priv.
*
* note (differences from real mbrtowc):
* - 3rd parameter is not "const char *s" but "const char **s".
* after the call of the function, *s will point the first byte of
* the next character.
* - additional 4th parameter is the size of src buffer.
* - 5th parameter is unpacked encoding-dependent state structure.
* - additional 6th parameter is the storage to be stored
* the return value in the real mbrtowc context.
* - return value means "errno" in the real mbrtowc context.
*/
static int _FUNCNAME(mbrtowc_priv)(_ENCODING_INFO * __restrict,
wchar_t * __restrict,
const char ** __restrict,
size_t, _ENCODING_STATE * __restrict,
size_t * __restrict);
/*
* standard form of wcrtomb_priv.
*
* note (differences from real wcrtomb):
* - additional 3th parameter is the size of src buffer.
* - 5th parameter is unpacked encoding-dependent state structure.
* - additional 6th parameter is the storage to be stored
* the return value in the real mbrtowc context.
* - return value means "errno" in the real wcrtomb context.
* - caller should ensure that 2nd parameter isn't NULL.
* (XXX inconsist with mbrtowc_priv)
*/
static int _FUNCNAME(wcrtomb_priv)(_ENCODING_INFO * __restrict,
char * __restrict, size_t, wchar_t,
_ENCODING_STATE * __restrict,
size_t * __restrict);
__END_DECLS
/*
* macros
*/
#define _TO_CEI(_cl_) ((_CTYPE_INFO*)(_cl_))
/*
* templates
*/
/* internal routines */
static __inline int
_FUNCNAME(mbtowc_priv)(_ENCODING_INFO * __restrict ei,
wchar_t * __restrict pwc, const char * __restrict s,
size_t n, _ENCODING_STATE * __restrict psenc,
int * __restrict nresult)
{
_ENCODING_STATE state;
size_t nr;
int err = 0;
_DIAGASSERT(ei != NULL);
_DIAGASSERT(psenc != NULL);
if (s == NULL) {
_FUNCNAME(init_state)(ei, psenc);
*nresult = _ENCODING_IS_STATE_DEPENDENT;
return (0);
}
state = *psenc;
err = _FUNCNAME(mbrtowc_priv)(ei, pwc, (const char **)&s, n, psenc, &nr);
if (nr == (size_t)-2)
err = EILSEQ;
if (err) {
/* In error case, we should restore the state. */
*psenc = state;
*nresult = -1;
return (err);
}
*nresult = (int)nr;
return (0);
}
static int
_FUNCNAME(mbsrtowcs_priv)(_ENCODING_INFO * __restrict ei,
wchar_t * __restrict pwcs,
const char ** __restrict s,
size_t n, _ENCODING_STATE * __restrict psenc,
size_t * __restrict nresult)
{
int err, cnt;
size_t siz;
const char *s0;
size_t mbcurmax;
_DIAGASSERT(nresult != 0);
_DIAGASSERT(ei != NULL);
_DIAGASSERT(psenc != NULL);
_DIAGASSERT(s != NULL);
_DIAGASSERT(*s != NULL);
/* if pwcs is NULL, ignore n */
if (pwcs == NULL)
n = 1; /* arbitrary >0 value */
err = cnt = 0;
s0 = *s; /* to keep *s unchanged for now, use copy instead. */
mbcurmax = _ENCODING_MB_CUR_MAX(ei);
while (n > 0) {
err = _FUNCNAME(mbrtowc_priv)(ei, pwcs, &s0, mbcurmax,
psenc, &siz);
if (siz == (size_t)-2)
err = EILSEQ;
if (err) {
cnt = -1;
goto bye;
}
switch (siz) {
case 0:
if (pwcs) {
_FUNCNAME(init_state)(ei, psenc);
}
s0 = 0;
goto bye;
default:
if (pwcs) {
pwcs++;
n--;
}
cnt++;
break;
}
}
bye:
if (pwcs)
*s = s0;
*nresult = (size_t)cnt;
return err;
}
static int
_FUNCNAME(mbsnrtowcs_priv)(_ENCODING_INFO * __restrict ei,
wchar_t * __restrict pwcs,
const char ** __restrict s, size_t in,
size_t n, _ENCODING_STATE * __restrict psenc,
size_t * __restrict nresult)
{
int err;
size_t cnt, siz;
const char *s0, *se;
_DIAGASSERT(nresult != 0);
_DIAGASSERT(ei != NULL);
_DIAGASSERT(psenc != NULL);
_DIAGASSERT(s != NULL);
_DIAGASSERT(*s != NULL);
/* if pwcs is NULL, ignore n */
if (pwcs == NULL)
n = 1; /* arbitrary >0 value */
err = 0;
cnt = 0;
se = *s + in;
s0 = *s; /* to keep *s unchanged for now, use copy instead. */
while (s0 < se && n > 0) {
err = _FUNCNAME(mbrtowc_priv)(ei, pwcs, &s0, se - s0,
psenc, &siz);
if (err) {
cnt = (size_t)-1;
goto bye;
}
if (siz == (size_t)-2) {
s0 = se;
goto bye;
}
switch (siz) {
case 0:
if (pwcs) {
_FUNCNAME(init_state)(ei, psenc);
}
s0 = 0;
goto bye;
default:
if (pwcs) {
pwcs++;
n--;
}
cnt++;
break;
}
}
bye:
if (pwcs)
*s = s0;
*nresult = cnt;
return err;
}
static int
_FUNCNAME(wcsrtombs_priv)(_ENCODING_INFO * __restrict ei, char * __restrict s,
const wchar_t ** __restrict pwcs,
size_t n, _ENCODING_STATE * __restrict psenc,
size_t * __restrict nresult)
{
int err;
char buf[MB_LEN_MAX];
size_t cnt, siz;
const wchar_t* pwcs0;
#if _ENCODING_IS_STATE_DEPENDENT
_ENCODING_STATE state;
#endif
pwcs0 = *pwcs;
cnt = 0;
if (!s)
n = 1;
while (n > 0) {
#if _ENCODING_IS_STATE_DEPENDENT
state = *psenc;
#endif
err = _FUNCNAME(wcrtomb_priv)(ei, buf, sizeof(buf),
*pwcs0, psenc, &siz);
if (siz == (size_t)-1) {
*nresult = siz;
return (err);
}
if (s) {
if (n < siz) {
#if _ENCODING_IS_STATE_DEPENDENT
*psenc = state;
#endif
break;
}
memcpy(s, buf, siz);
s += siz;
n -= siz;
}
cnt += siz;
if (!*pwcs0) {
if (s) {
_FUNCNAME(init_state)(ei, psenc);
}
pwcs0 = 0;
cnt--; /* don't include terminating null */
break;
}
pwcs0++;
}
if (s)
*pwcs = pwcs0;
*nresult = cnt;
return (0);
}
static int
_FUNCNAME(wcsnrtombs_priv)(_ENCODING_INFO * __restrict ei, char * __restrict s,
const wchar_t ** __restrict pwcs, size_t in,
size_t n, _ENCODING_STATE * __restrict psenc,
size_t * __restrict nresult)
{
int cnt = 0, err;
char buf[MB_LEN_MAX];
size_t siz;
const wchar_t* pwcs0;
#if _ENCODING_IS_STATE_DEPENDENT
_ENCODING_STATE state;
#endif
pwcs0 = *pwcs;
if (!s)
n = 1;
while (in > 0 && n > 0) {
#if _ENCODING_IS_STATE_DEPENDENT
state = *psenc;
#endif
err = _FUNCNAME(wcrtomb_priv)(ei, buf, sizeof(buf),
*pwcs0, psenc, &siz);
if (siz == (size_t)-1) {
*nresult = siz;
return (err);
}
if (s) {
if (n < siz) {
#if _ENCODING_IS_STATE_DEPENDENT
*psenc = state;
#endif
break;
}
memcpy(s, buf, siz);
s += siz;
n -= siz;
}
cnt += siz;
if (!*pwcs0) {
if (s) {
_FUNCNAME(init_state)(ei, psenc);
}
pwcs0 = 0;
cnt--; /* don't include terminating null */
break;
}
pwcs0++;
--in;
}
if (s)
*pwcs = pwcs0;
*nresult = (size_t)cnt;
return (0);
}
/* ----------------------------------------------------------------------
* templates for public functions
*/
#define _RESTART_BEGIN(_func_, _cei_, _pspriv_, _pse_) \
do { \
_ENCODING_STATE _state; \
do { \
if (_pspriv_ == NULL) { \
_pse_ = &_CEI_TO_STATE(_cei_, _func_); \
if (_STATE_NEEDS_EXPLICIT_INIT(_pse_)) \
_FUNCNAME(init_state)(_CEI_TO_EI(_cei_), \
(_pse_)); \
} else { \
_pse_ = &_state; \
_FUNCNAME(unpack_state)(_CEI_TO_EI(_cei_), \
_pse_, _pspriv_); \
} \
} while (/*CONSTCOND*/0)
#define _RESTART_END(_func_, _cei_, _pspriv_, _pse_) \
if (_pspriv_ != NULL) { \
_FUNCNAME(pack_state)(_CEI_TO_EI(_cei_), _pspriv_, \
_pse_); \
} \
} while (/*CONSTCOND*/0)
int
_FUNCNAME(ctype_getops)(_citrus_ctype_ops_rec_t *ops, size_t lenops,
uint32_t expected_version)
{
if (expected_version<_CITRUS_CTYPE_ABI_VERSION || lenops<sizeof(*ops))
return (EINVAL);
memcpy(ops, &_FUNCNAME(ctype_ops), sizeof(_FUNCNAME(ctype_ops)));
return (0);
}
static int
_FUNCNAME(ctype_init)(void ** __restrict cl,
void * __restrict var, size_t lenvar, size_t lenps)
{
_CTYPE_INFO *cei;
_DIAGASSERT(cl != NULL);
/* sanity check to avoid overruns */
if (sizeof(_ENCODING_STATE) > lenps)
return (EINVAL);
cei = calloc(1, sizeof(_CTYPE_INFO));
if (cei == NULL)
return (ENOMEM);
*cl = (void *)cei;
return _FUNCNAME(encoding_module_init)(_CEI_TO_EI(cei), var, lenvar);
}
static void
_FUNCNAME(ctype_uninit)(void *cl)
{
if (cl) {
_FUNCNAME(encoding_module_uninit)(_CEI_TO_EI(_TO_CEI(cl)));
free(cl);
}
}
static unsigned
/*ARGSUSED*/
_FUNCNAME(ctype_get_mb_cur_max)(void *cl)
{
return _ENCODING_MB_CUR_MAX(_CEI_TO_EI(_TO_CEI(cl)));
}
static int
_FUNCNAME(ctype_mblen)(void * __restrict cl,
const char * __restrict s, size_t n,
int * __restrict nresult)
{
_ENCODING_STATE *psenc;
_ENCODING_INFO *ei;
_DIAGASSERT(cl != NULL);
psenc = &_CEI_TO_STATE(_TO_CEI(cl), mblen);
ei = _CEI_TO_EI(_TO_CEI(cl));
if (_STATE_NEEDS_EXPLICIT_INIT(psenc))
_FUNCNAME(init_state)(ei, psenc);
return _FUNCNAME(mbtowc_priv)(ei, NULL, s, n, psenc, nresult);
}
static int
_FUNCNAME(ctype_mbrlen)(void * __restrict cl, const char * __restrict s,
size_t n, void * __restrict pspriv,
size_t * __restrict nresult)
{
_ENCODING_STATE *psenc;
_ENCODING_INFO *ei;
int err = 0;
_DIAGASSERT(cl != NULL);
ei = _CEI_TO_EI(_TO_CEI(cl));
_RESTART_BEGIN(mbrlen, _TO_CEI(cl), pspriv, psenc);
if (s == NULL) {
_FUNCNAME(init_state)(ei, psenc);
*nresult = 0;
} else {
err = _FUNCNAME(mbrtowc_priv)(ei, NULL, (const char **)&s, n,
(void *)psenc, nresult);
}
_RESTART_END(mbrlen, _TO_CEI(cl), pspriv, psenc);
return (err);
}
static int
_FUNCNAME(ctype_mbrtowc)(void * __restrict cl, wchar_t * __restrict pwc,
const char * __restrict s, size_t n,
void * __restrict pspriv, size_t * __restrict nresult)
{
_ENCODING_STATE *psenc;
_ENCODING_INFO *ei;
int err = 0;
_DIAGASSERT(cl != NULL);
ei = _CEI_TO_EI(_TO_CEI(cl));
_RESTART_BEGIN(mbrtowc, _TO_CEI(cl), pspriv, psenc);
if (s == NULL) {
_FUNCNAME(init_state)(ei, psenc);
*nresult = 0;
} else {
err = _FUNCNAME(mbrtowc_priv)(ei, pwc, (const char **)&s, n,
(void *)psenc, nresult);
}
_RESTART_END(mbrtowc, _TO_CEI(cl), pspriv, psenc);
return (err);
}
static int
/*ARGSUSED*/
_FUNCNAME(ctype_mbsinit)(void * __restrict cl, const void * __restrict pspriv,
int * __restrict nresult)
{
_ENCODING_STATE state;
if (pspriv == NULL) {
*nresult = 1;
return (0);
}
_FUNCNAME(unpack_state)(_CEI_TO_EI(_TO_CEI(cl)), &state, pspriv);
*nresult = (state.chlen == 0); /* XXX: FIXME */
return (0);
}
static int
_FUNCNAME(ctype_mbsrtowcs)(void * __restrict cl, wchar_t * __restrict pwcs,
const char ** __restrict s, size_t n,
void * __restrict pspriv,
size_t * __restrict nresult)
{
_ENCODING_STATE *psenc;
_ENCODING_INFO *ei;
int err = 0;
_DIAGASSERT(cl != NULL);
ei = _CEI_TO_EI(_TO_CEI(cl));
_RESTART_BEGIN(mbsrtowcs, _TO_CEI(cl), pspriv, psenc);
err = _FUNCNAME(mbsrtowcs_priv)(ei, pwcs, s, n, psenc, nresult);
_RESTART_END(mbsrtowcs, _TO_CEI(cl), pspriv, psenc);
return (err);
}
static int __used
_FUNCNAME(ctype_mbsnrtowcs)(_citrus_ctype_rec_t * __restrict cc, wchar_t * __restrict pwcs,
const char ** __restrict s, size_t in, size_t n,
void * __restrict pspriv,
size_t * __restrict nresult)
{
void *cl = cc->cc_closure;
_ENCODING_STATE *psenc;
_ENCODING_INFO *ei;
int err = 0;
_DIAGASSERT(cl != NULL);
ei = _CEI_TO_EI(_TO_CEI(cl));
_RESTART_BEGIN(mbsnrtowcs, _TO_CEI(cl), pspriv, psenc);
err = _FUNCNAME(mbsnrtowcs_priv)(ei, pwcs, s, in, n, psenc, nresult);
_RESTART_END(mbsnrtowcs, _TO_CEI(cl), pspriv, psenc);
return (err);
}
static int
_FUNCNAME(ctype_mbstowcs)(void * __restrict cl, wchar_t * __restrict pwcs,
const char * __restrict s, size_t n,
size_t * __restrict nresult)
{
int err;
_ENCODING_STATE state;
_ENCODING_INFO *ei;
_DIAGASSERT(cl != NULL);
ei = _CEI_TO_EI(_TO_CEI(cl));
_FUNCNAME(init_state)(ei, &state);
err = _FUNCNAME(mbsrtowcs_priv)(ei, pwcs, (const char **)&s, n,
&state, nresult);
if (*nresult == (size_t)-2) {
err = EILSEQ;
*nresult = (size_t)-1;
}
return (err);
}
static int
_FUNCNAME(ctype_mbtowc)(void * __restrict cl, wchar_t * __restrict pwc,
const char * __restrict s, size_t n,
int * __restrict nresult)
{
_ENCODING_STATE *psenc;
_ENCODING_INFO *ei;
_DIAGASSERT(cl != NULL);
psenc = &_CEI_TO_STATE(_TO_CEI(cl), mbtowc);
ei = _CEI_TO_EI(_TO_CEI(cl));
if (_STATE_NEEDS_EXPLICIT_INIT(psenc))
_FUNCNAME(init_state)(ei, psenc);
return _FUNCNAME(mbtowc_priv)(ei, pwc, s, n, psenc, nresult);
}
static int
_FUNCNAME(ctype_wcrtomb)(void * __restrict cl, char * __restrict s, wchar_t wc,
void * __restrict pspriv, size_t * __restrict nresult)
{
_ENCODING_STATE *psenc;
char buf[MB_LEN_MAX];
int err = 0;
size_t sz;
#if _ENCODING_IS_STATE_DEPENDENT
size_t rsz = 0;
#endif
_DIAGASSERT(cl != NULL);
if (s == NULL) {
/*
* use internal buffer.
*/
s = buf;
wc = L'\0'; /* SUSv3 */
}
_RESTART_BEGIN(wcrtomb, _TO_CEI(cl), pspriv, psenc);
sz = _ENCODING_MB_CUR_MAX(_CEI_TO_EI(_TO_CEI(cl)));
#if _ENCODING_IS_STATE_DEPENDENT
if (wc == L'\0') {
/* reset state */
err = _FUNCNAME(put_state_reset)(_CEI_TO_EI(_TO_CEI(cl)), s,
sz, psenc, &rsz);
if (err) {
*nresult = -1;
goto quit;
}
s += rsz;
sz -= rsz;
}
#endif
err = _FUNCNAME(wcrtomb_priv)(_CEI_TO_EI(_TO_CEI(cl)), s, sz,
wc, psenc, nresult);
#if _ENCODING_IS_STATE_DEPENDENT
if (err == 0)
*nresult += rsz;
quit:
#endif
if (err == E2BIG)
err = EINVAL;
_RESTART_END(wcrtomb, _TO_CEI(cl), pspriv, psenc);
return err;
}
static int
/*ARGSUSED*/
_FUNCNAME(ctype_wcsrtombs)(void * __restrict cl, char * __restrict s,
const wchar_t ** __restrict pwcs, size_t n,
void * __restrict pspriv,
size_t * __restrict nresult)
{
_ENCODING_STATE *psenc;
_ENCODING_INFO *ei;
int err = 0;
_DIAGASSERT(cl != NULL);
ei = _CEI_TO_EI(_TO_CEI(cl));
_RESTART_BEGIN(wcsrtombs, _TO_CEI(cl), pspriv, psenc);
err = _FUNCNAME(wcsrtombs_priv)(ei, s, pwcs, n, psenc, nresult);
_RESTART_END(wcsrtombs, _TO_CEI(cl), pspriv, psenc);
return err;
}
static int __used
/*ARGSUSED*/
_FUNCNAME(ctype_wcsnrtombs)(_citrus_ctype_rec_t * __restrict cc,
char * __restrict s,
const wchar_t ** __restrict pwcs, size_t in,
size_t n, void * __restrict pspriv,
size_t * __restrict nresult)
{
void *cl = cc->cc_closure;
_ENCODING_STATE *psenc;
_ENCODING_INFO *ei;
int err = 0;
_DIAGASSERT(cl != NULL);
ei = _CEI_TO_EI(_TO_CEI(cl));
_RESTART_BEGIN(wcsnrtombs, _TO_CEI(cl), pspriv, psenc);
err = _FUNCNAME(wcsnrtombs_priv)(ei, s, pwcs, in, n, psenc, nresult);
_RESTART_END(wcsnrtombs, _TO_CEI(cl), pspriv, psenc);
return err;
}
static int
/*ARGSUSED*/
_FUNCNAME(ctype_wcstombs)(void * __restrict cl, char * __restrict s,
const wchar_t * __restrict pwcs, size_t n,
size_t * __restrict nresult)
{
_ENCODING_STATE state;
_ENCODING_INFO *ei;
int err;
_DIAGASSERT(cl != NULL);
ei = _CEI_TO_EI(_TO_CEI(cl));
_FUNCNAME(init_state)(ei, &state);
err = _FUNCNAME(wcsrtombs_priv)(ei, s, (const wchar_t **)&pwcs, n,
&state, nresult);
return err;
}
static int
_FUNCNAME(ctype_wctomb)(void * __restrict cl, char * __restrict s, wchar_t wc,
int * __restrict nresult)
{
_ENCODING_STATE *psenc;
_ENCODING_INFO *ei;
size_t nr, sz;
#if _ENCODING_IS_STATE_DEPENDENT
size_t rsz = 0;
#endif
int err = 0;
_DIAGASSERT(cl != NULL);
ei = _CEI_TO_EI(_TO_CEI(cl));
psenc = &_CEI_TO_STATE(_TO_CEI(cl), wctomb);
if (_STATE_NEEDS_EXPLICIT_INIT(psenc))
_FUNCNAME(init_state)(ei, psenc);
if (s == NULL) {
_FUNCNAME(init_state)(ei, psenc);
*nresult = _ENCODING_IS_STATE_DEPENDENT;
return 0;
}
sz = _ENCODING_MB_CUR_MAX(_CEI_TO_EI(_TO_CEI(cl)));
#if _ENCODING_IS_STATE_DEPENDENT
if (wc == L'\0') {
/* reset state */
err = _FUNCNAME(put_state_reset)(_CEI_TO_EI(_TO_CEI(cl)), s,
sz, psenc, &rsz);
if (err) {
*nresult = -1; /* XXX */
return 0;
}
s += rsz;
sz -= rsz;
}
#endif
err = _FUNCNAME(wcrtomb_priv)(ei, s, sz, wc, psenc, &nr);
#if _ENCODING_IS_STATE_DEPENDENT
if (err == 0)
*nresult = (int)(nr + rsz);
else
#endif
*nresult = (int)nr;
return 0;
}
static int
/*ARGSUSED*/
_FUNCNAME(ctype_btowc)(_citrus_ctype_rec_t * __restrict cc,
int c, wint_t * __restrict wcresult)
{
_ENCODING_STATE state;
_ENCODING_INFO *ei;
char mb;
char const *s;
wchar_t wc;
size_t nr;
int err;
_DIAGASSERT(cc != NULL && cc->cc_closure != NULL);
if (c == EOF) {
*wcresult = WEOF;
return 0;
}
ei = _CEI_TO_EI(_TO_CEI(cc->cc_closure));
_FUNCNAME(init_state)(ei, &state);
mb = (char)(unsigned)c;
s = &mb;
err = _FUNCNAME(mbrtowc_priv)(ei, &wc, &s, 1, &state, &nr);
if (!err && (nr == 0 || nr == 1))
*wcresult = (wint_t)wc;
else
*wcresult = WEOF;
return 0;
}
static int
/*ARGSUSED*/
_FUNCNAME(ctype_wctob)(_citrus_ctype_rec_t * __restrict cc,
wint_t wc, int * __restrict cresult)
{
_ENCODING_STATE state;
_ENCODING_INFO *ei;
char buf[MB_LEN_MAX];
size_t nr;
int err;
_DIAGASSERT(cc != NULL && cc->cc_closure != NULL);
if (wc == WEOF) {
*cresult = EOF;
return 0;
}
ei = _CEI_TO_EI(_TO_CEI(cc->cc_closure));
_FUNCNAME(init_state)(ei, &state);
err = _FUNCNAME(wcrtomb_priv)(ei, buf, _ENCODING_MB_CUR_MAX(ei),
(wchar_t)wc, &state, &nr);
if (!err && nr == 1)
*cresult = buf[0];
else
*cresult = EOF;
return 0;
}