There is important information about booting non-ack images in docs/UPDATING. ack/aout-format images can't be built any more, and booting clang/ELF-format ones is a little different. Updating to the new boot monitor is recommended. Changes in this commit: . drop boot monitor -> allowing dropping ack support . facility to copy ELF boot files to /boot so that old boot monitor can still boot fairly easily, see UPDATING . no more ack-format libraries -> single-case libraries . some cleanup of OBJECT_FMT, COMPILER_TYPE, etc cases . drop several ack toolchain commands, but not all support commands (e.g. aal is gone but acksize is not yet). . a few libc files moved to netbsd libc dir . new /bin/date as minix date used code in libc/ . test compile fix . harmonize includes . /usr/lib is no longer special: without ack, /usr/lib plays no kind of special bootstrapping role any more and bootstrapping is done exclusively through packages, so releases depend even less on the state of the machine making them now. . rename nbsd_lib* to lib* . reduce mtree
767 lines
19 KiB
C
767 lines
19 KiB
C
/* $NetBSD: citrus_ctype_template.h,v 1.35 2008/02/09 14:56:20 junyoung 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
|
|
* wcrtomb
|
|
* wcsrtombs
|
|
* 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(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 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 (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 = (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
|
|
_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
|
|
/*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;
|
|
}
|