1*84d9c625SLionel Sambuc /* $NetBSD: citrus_ues.c,v 1.4 2013/05/28 16:57:56 joerg Exp $ */
22fe8fb19SBen Gras
32fe8fb19SBen Gras /*-
42fe8fb19SBen Gras * Copyright (c)2006 Citrus Project,
52fe8fb19SBen Gras * All rights reserved.
62fe8fb19SBen Gras *
72fe8fb19SBen Gras * Redistribution and use in source and binary forms, with or without
82fe8fb19SBen Gras * modification, are permitted provided that the following conditions
92fe8fb19SBen Gras * are met:
102fe8fb19SBen Gras * 1. Redistributions of source code must retain the above copyright
112fe8fb19SBen Gras * notice, this list of conditions and the following disclaimer.
122fe8fb19SBen Gras * 2. Redistributions in binary form must reproduce the above copyright
132fe8fb19SBen Gras * notice, this list of conditions and the following disclaimer in the
142fe8fb19SBen Gras * documentation and/or other materials provided with the distribution.
152fe8fb19SBen Gras *
162fe8fb19SBen Gras * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
172fe8fb19SBen Gras * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
182fe8fb19SBen Gras * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
192fe8fb19SBen Gras * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
202fe8fb19SBen Gras * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
212fe8fb19SBen Gras * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
222fe8fb19SBen Gras * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
232fe8fb19SBen Gras * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
242fe8fb19SBen Gras * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
252fe8fb19SBen Gras * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
262fe8fb19SBen Gras * SUCH DAMAGE.
272fe8fb19SBen Gras */
282fe8fb19SBen Gras
292fe8fb19SBen Gras #include <sys/cdefs.h>
302fe8fb19SBen Gras #if defined(LIBC_SCCS) && !defined(lint)
31*84d9c625SLionel Sambuc __RCSID("$NetBSD: citrus_ues.c,v 1.4 2013/05/28 16:57:56 joerg Exp $");
322fe8fb19SBen Gras #endif /* LIBC_SCCS and not lint */
332fe8fb19SBen Gras
342fe8fb19SBen Gras #include <assert.h>
352fe8fb19SBen Gras #include <errno.h>
362fe8fb19SBen Gras #include <string.h>
372fe8fb19SBen Gras #include <stdio.h>
382fe8fb19SBen Gras #include <stdint.h>
392fe8fb19SBen Gras #include <stdlib.h>
402fe8fb19SBen Gras #include <limits.h>
412fe8fb19SBen Gras #include <wchar.h>
422fe8fb19SBen Gras
432fe8fb19SBen Gras #include "citrus_namespace.h"
442fe8fb19SBen Gras #include "citrus_types.h"
452fe8fb19SBen Gras #include "citrus_bcs.h"
462fe8fb19SBen Gras #include "citrus_module.h"
472fe8fb19SBen Gras #include "citrus_ctype.h"
482fe8fb19SBen Gras #include "citrus_stdenc.h"
492fe8fb19SBen Gras #include "citrus_ues.h"
502fe8fb19SBen Gras
512fe8fb19SBen Gras typedef struct {
522fe8fb19SBen Gras int mode;
532fe8fb19SBen Gras #define MODE_C99 1
542fe8fb19SBen Gras size_t mb_cur_max;
552fe8fb19SBen Gras } _UESEncodingInfo;
562fe8fb19SBen Gras
572fe8fb19SBen Gras typedef struct {
582fe8fb19SBen Gras int chlen;
592fe8fb19SBen Gras char ch[12];
602fe8fb19SBen Gras } _UESState;
612fe8fb19SBen Gras
622fe8fb19SBen Gras typedef struct {
632fe8fb19SBen Gras _UESEncodingInfo ei;
642fe8fb19SBen Gras struct {
652fe8fb19SBen Gras /* for future multi-locale facility */
662fe8fb19SBen Gras _UESState s_mblen;
672fe8fb19SBen Gras _UESState s_mbrlen;
682fe8fb19SBen Gras _UESState s_mbrtowc;
692fe8fb19SBen Gras _UESState s_mbtowc;
702fe8fb19SBen Gras _UESState s_mbsrtowcs;
71*84d9c625SLionel Sambuc _UESState s_mbsnrtowcs;
722fe8fb19SBen Gras _UESState s_wcrtomb;
732fe8fb19SBen Gras _UESState s_wcsrtombs;
74*84d9c625SLionel Sambuc _UESState s_wcsnrtombs;
752fe8fb19SBen Gras _UESState s_wctomb;
762fe8fb19SBen Gras } states;
772fe8fb19SBen Gras } _UESCTypeInfo;
782fe8fb19SBen Gras
792fe8fb19SBen Gras #define _CEI_TO_EI(_cei_) (&(_cei_)->ei)
802fe8fb19SBen Gras #define _CEI_TO_STATE(_cei_, _func_) (_cei_)->states.s_##_func_
812fe8fb19SBen Gras
822fe8fb19SBen Gras #define _FUNCNAME(m) _citrus_UES_##m
832fe8fb19SBen Gras #define _ENCODING_INFO _UESEncodingInfo
842fe8fb19SBen Gras #define _CTYPE_INFO _UESCTypeInfo
852fe8fb19SBen Gras #define _ENCODING_STATE _UESState
862fe8fb19SBen Gras #define _ENCODING_MB_CUR_MAX(_ei_) (_ei_)->mb_cur_max
872fe8fb19SBen Gras #define _ENCODING_IS_STATE_DEPENDENT 0
882fe8fb19SBen Gras #define _STATE_NEEDS_EXPLICIT_INIT(_ps_) 0
892fe8fb19SBen Gras
902fe8fb19SBen Gras static __inline void
912fe8fb19SBen Gras /*ARGSUSED*/
_citrus_UES_init_state(_UESEncodingInfo * __restrict ei,_UESState * __restrict psenc)922fe8fb19SBen Gras _citrus_UES_init_state(_UESEncodingInfo * __restrict ei,
932fe8fb19SBen Gras _UESState * __restrict psenc)
942fe8fb19SBen Gras {
952fe8fb19SBen Gras psenc->chlen = 0;
962fe8fb19SBen Gras }
972fe8fb19SBen Gras
982fe8fb19SBen Gras static __inline void
992fe8fb19SBen Gras /*ARGSUSED*/
_citrus_UES_pack_state(_UESEncodingInfo * __restrict ei,void * __restrict pspriv,const _UESState * __restrict psenc)1002fe8fb19SBen Gras _citrus_UES_pack_state(_UESEncodingInfo * __restrict ei,
1012fe8fb19SBen Gras void *__restrict pspriv, const _UESState * __restrict psenc)
1022fe8fb19SBen Gras {
1032fe8fb19SBen Gras /* ei seem to be unused */
1042fe8fb19SBen Gras _DIAGASSERT(pspriv != NULL);
1052fe8fb19SBen Gras _DIAGASSERT(psenc != NULL);
1062fe8fb19SBen Gras
1072fe8fb19SBen Gras memcpy(pspriv, (const void *)psenc, sizeof(*psenc));
1082fe8fb19SBen Gras }
1092fe8fb19SBen Gras
1102fe8fb19SBen Gras static __inline void
1112fe8fb19SBen Gras /*ARGSUSED*/
_citrus_UES_unpack_state(_UESEncodingInfo * __restrict ei,_UESState * __restrict psenc,const void * __restrict pspriv)1122fe8fb19SBen Gras _citrus_UES_unpack_state(_UESEncodingInfo * __restrict ei,
1132fe8fb19SBen Gras _UESState * __restrict psenc, const void * __restrict pspriv)
1142fe8fb19SBen Gras {
1152fe8fb19SBen Gras /* ei seem to be unused */
1162fe8fb19SBen Gras _DIAGASSERT(psenc != NULL);
1172fe8fb19SBen Gras _DIAGASSERT(pspriv != NULL);
1182fe8fb19SBen Gras
1192fe8fb19SBen Gras memcpy((void *)psenc, pspriv, sizeof(*psenc));
1202fe8fb19SBen Gras }
1212fe8fb19SBen Gras
1222fe8fb19SBen Gras static __inline int
to_int(int ch)1232fe8fb19SBen Gras to_int(int ch)
1242fe8fb19SBen Gras {
1252fe8fb19SBen Gras if (ch >= '0' && ch <= '9')
1262fe8fb19SBen Gras return ch - '0';
1272fe8fb19SBen Gras else if (ch >= 'A' && ch <= 'F')
1282fe8fb19SBen Gras return (ch - 'A') + 10;
1292fe8fb19SBen Gras else if (ch >= 'a' && ch <= 'f')
1302fe8fb19SBen Gras return (ch - 'a') + 10;
1312fe8fb19SBen Gras return -1;
1322fe8fb19SBen Gras }
1332fe8fb19SBen Gras
1342fe8fb19SBen Gras #define ESCAPE '\\'
1352fe8fb19SBen Gras #define UCS2_ESC 'u'
1362fe8fb19SBen Gras #define UCS4_ESC 'U'
1372fe8fb19SBen Gras
1382fe8fb19SBen Gras #define UCS2_BIT 16
1392fe8fb19SBen Gras #define UCS4_BIT 32
1402fe8fb19SBen Gras #define BMP_MAX UINT32_C(0xFFFF)
1412fe8fb19SBen Gras #define UCS2_MAX UINT32_C(0x10FFFF)
1422fe8fb19SBen Gras #define UCS4_MAX UINT32_C(0x7FFFFFFF)
1432fe8fb19SBen Gras
1442fe8fb19SBen Gras static const char *xdig = "0123456789abcdef";
1452fe8fb19SBen Gras
1462fe8fb19SBen Gras static __inline int
to_str(char * s,wchar_t wc,int bit)1472fe8fb19SBen Gras to_str(char *s, wchar_t wc, int bit)
1482fe8fb19SBen Gras {
1492fe8fb19SBen Gras char *p;
1502fe8fb19SBen Gras
1512fe8fb19SBen Gras p = s;
1522fe8fb19SBen Gras *p++ = ESCAPE;
1532fe8fb19SBen Gras switch (bit) {
1542fe8fb19SBen Gras case UCS2_BIT:
1552fe8fb19SBen Gras *p++ = UCS2_ESC;
1562fe8fb19SBen Gras break;
1572fe8fb19SBen Gras case UCS4_BIT:
1582fe8fb19SBen Gras *p++ = UCS4_ESC;
1592fe8fb19SBen Gras break;
1602fe8fb19SBen Gras default:
1612fe8fb19SBen Gras abort();
1622fe8fb19SBen Gras }
1632fe8fb19SBen Gras do {
1642fe8fb19SBen Gras *p++ = xdig[(wc >> (bit -= 4)) & 0xF];
1652fe8fb19SBen Gras } while (bit > 0);
1662fe8fb19SBen Gras return p - s;
1672fe8fb19SBen Gras }
1682fe8fb19SBen Gras
1692fe8fb19SBen Gras static __inline int
is_hi_surrogate(wchar_t wc)1702fe8fb19SBen Gras is_hi_surrogate(wchar_t wc)
1712fe8fb19SBen Gras {
1722fe8fb19SBen Gras return wc >= 0xD800 && wc <= 0xDBFF;
1732fe8fb19SBen Gras }
1742fe8fb19SBen Gras
1752fe8fb19SBen Gras static __inline int
is_lo_surrogate(wchar_t wc)1762fe8fb19SBen Gras is_lo_surrogate(wchar_t wc)
1772fe8fb19SBen Gras {
1782fe8fb19SBen Gras return wc >= 0xDC00 && wc <= 0xDFFF;
1792fe8fb19SBen Gras }
1802fe8fb19SBen Gras
1812fe8fb19SBen Gras static __inline wchar_t
surrogate_to_ucs(wchar_t hi,wchar_t lo)1822fe8fb19SBen Gras surrogate_to_ucs(wchar_t hi, wchar_t lo)
1832fe8fb19SBen Gras {
1842fe8fb19SBen Gras _DIAGASSERT(is_hi_surrogate(hi));
1852fe8fb19SBen Gras _DIAGASSERT(is_lo_surrogate(lo));
1862fe8fb19SBen Gras
1872fe8fb19SBen Gras hi -= 0xD800;
1882fe8fb19SBen Gras lo -= 0xDC00;
1892fe8fb19SBen Gras return (hi << 10 | lo) + 0x10000;
1902fe8fb19SBen Gras }
1912fe8fb19SBen Gras
1922fe8fb19SBen Gras static __inline void
ucs_to_surrogate(wchar_t wc,wchar_t * __restrict hi,wchar_t * __restrict lo)1932fe8fb19SBen Gras ucs_to_surrogate(wchar_t wc, wchar_t * __restrict hi, wchar_t * __restrict lo)
1942fe8fb19SBen Gras {
1952fe8fb19SBen Gras _DIAGASSERT(hi != NULL);
1962fe8fb19SBen Gras _DIAGASSERT(lo != NULL);
1972fe8fb19SBen Gras _DIAGASSERT(wc >= 0x10000);
1982fe8fb19SBen Gras
1992fe8fb19SBen Gras wc -= 0x10000;
2002fe8fb19SBen Gras *hi = (wc >> 10) + 0xD800;
2012fe8fb19SBen Gras *lo = (wc & 0x3FF) + 0xDC00;
2022fe8fb19SBen Gras }
2032fe8fb19SBen Gras
2042fe8fb19SBen Gras static __inline int
is_basic(wchar_t wc)2052fe8fb19SBen Gras is_basic(wchar_t wc)
2062fe8fb19SBen Gras {
2072fe8fb19SBen Gras return (uint32_t)wc <= 0x9F &&
2082fe8fb19SBen Gras wc != 0x24 && wc != 0x40 && wc != 0x60;
2092fe8fb19SBen Gras }
2102fe8fb19SBen Gras
2112fe8fb19SBen Gras static int
_citrus_UES_mbrtowc_priv(_UESEncodingInfo * __restrict ei,wchar_t * __restrict pwc,const char ** __restrict s,size_t n,_UESState * __restrict psenc,size_t * __restrict nresult)2122fe8fb19SBen Gras _citrus_UES_mbrtowc_priv(_UESEncodingInfo * __restrict ei,
2132fe8fb19SBen Gras wchar_t * __restrict pwc, const char ** __restrict s, size_t n,
2142fe8fb19SBen Gras _UESState * __restrict psenc, size_t * __restrict nresult)
2152fe8fb19SBen Gras {
2162fe8fb19SBen Gras const char *s0;
217f14fb602SLionel Sambuc int ch, head, tail, num;
2182fe8fb19SBen Gras wchar_t hi, wc;
2192fe8fb19SBen Gras
2202fe8fb19SBen Gras _DIAGASSERT(ei != NULL);
2212fe8fb19SBen Gras /* pwc may be null */
2222fe8fb19SBen Gras _DIAGASSERT(s != NULL);
2232fe8fb19SBen Gras _DIAGASSERT(psenc != NULL);
2242fe8fb19SBen Gras _DIAGASSERT(nresult != NULL);
2252fe8fb19SBen Gras
2262fe8fb19SBen Gras if (*s == NULL) {
2272fe8fb19SBen Gras _citrus_UES_init_state(ei, psenc);
2282fe8fb19SBen Gras *nresult = 0;
2292fe8fb19SBen Gras return 0;
2302fe8fb19SBen Gras }
2312fe8fb19SBen Gras s0 = *s;
2322fe8fb19SBen Gras
2332fe8fb19SBen Gras hi = (wchar_t)0;
2342fe8fb19SBen Gras tail = 0;
2352fe8fb19SBen Gras
2362fe8fb19SBen Gras surrogate:
2372fe8fb19SBen Gras wc = (wchar_t)0;
2382fe8fb19SBen Gras head = tail;
2392fe8fb19SBen Gras if (psenc->chlen == head) {
2402fe8fb19SBen Gras if (n-- < 1)
2412fe8fb19SBen Gras goto restart;
2422fe8fb19SBen Gras psenc->ch[psenc->chlen++] = *s0++;
2432fe8fb19SBen Gras }
2442fe8fb19SBen Gras ch = (unsigned char)psenc->ch[head++];
2452fe8fb19SBen Gras if (ch == ESCAPE) {
2462fe8fb19SBen Gras if (psenc->chlen == head) {
2472fe8fb19SBen Gras if (n-- < 1)
2482fe8fb19SBen Gras goto restart;
2492fe8fb19SBen Gras psenc->ch[psenc->chlen++] = *s0++;
2502fe8fb19SBen Gras }
2512fe8fb19SBen Gras switch (psenc->ch[head]) {
2522fe8fb19SBen Gras case UCS2_ESC:
2532fe8fb19SBen Gras tail += 6;
2542fe8fb19SBen Gras break;
2552fe8fb19SBen Gras case UCS4_ESC:
2562fe8fb19SBen Gras if (ei->mode & MODE_C99) {
2572fe8fb19SBen Gras tail = 10;
2582fe8fb19SBen Gras break;
2592fe8fb19SBen Gras }
2602fe8fb19SBen Gras /*FALLTHROUGH*/
2612fe8fb19SBen Gras default:
2622fe8fb19SBen Gras tail = 0;
2632fe8fb19SBen Gras }
2642fe8fb19SBen Gras ++head;
2652fe8fb19SBen Gras }
2662fe8fb19SBen Gras for (; head < tail; ++head) {
2672fe8fb19SBen Gras if (psenc->chlen == head) {
2682fe8fb19SBen Gras if (n-- < 1) {
2692fe8fb19SBen Gras restart:
2702fe8fb19SBen Gras *s = s0;
2712fe8fb19SBen Gras *nresult = (size_t)-2;
2722fe8fb19SBen Gras return 0;
2732fe8fb19SBen Gras }
2742fe8fb19SBen Gras psenc->ch[psenc->chlen++] = *s0++;
2752fe8fb19SBen Gras }
2762fe8fb19SBen Gras num = to_int((int)(unsigned char)psenc->ch[head]);
2772fe8fb19SBen Gras if (num < 0) {
2782fe8fb19SBen Gras tail = 0;
2792fe8fb19SBen Gras break;
2802fe8fb19SBen Gras }
2812fe8fb19SBen Gras wc = (wc << 4) | num;
2822fe8fb19SBen Gras }
2832fe8fb19SBen Gras head = 0;
2842fe8fb19SBen Gras switch (tail) {
2852fe8fb19SBen Gras case 0:
2862fe8fb19SBen Gras break;
2872fe8fb19SBen Gras case 6:
2882fe8fb19SBen Gras if (hi != (wchar_t)0)
2892fe8fb19SBen Gras break;
2902fe8fb19SBen Gras if ((ei->mode & MODE_C99) == 0) {
2912fe8fb19SBen Gras if (is_hi_surrogate(wc) != 0) {
2922fe8fb19SBen Gras hi = wc;
2932fe8fb19SBen Gras goto surrogate;
2942fe8fb19SBen Gras }
2952fe8fb19SBen Gras if ((uint32_t)wc <= 0x7F /* XXX */ ||
2962fe8fb19SBen Gras is_lo_surrogate(wc) != 0)
2972fe8fb19SBen Gras break;
2982fe8fb19SBen Gras goto done;
2992fe8fb19SBen Gras }
3002fe8fb19SBen Gras /*FALLTHROUGH*/
3012fe8fb19SBen Gras case 10:
3022fe8fb19SBen Gras if (is_basic(wc) == 0 && (uint32_t)wc <= UCS4_MAX &&
3032fe8fb19SBen Gras is_hi_surrogate(wc) == 0 && is_lo_surrogate(wc) == 0)
3042fe8fb19SBen Gras goto done;
3052fe8fb19SBen Gras *nresult = (size_t)-1;
3062fe8fb19SBen Gras return EILSEQ;
3072fe8fb19SBen Gras case 12:
3082fe8fb19SBen Gras if (is_lo_surrogate(wc) == 0)
3092fe8fb19SBen Gras break;
3102fe8fb19SBen Gras wc = surrogate_to_ucs(hi, wc);
3112fe8fb19SBen Gras goto done;
3122fe8fb19SBen Gras }
3132fe8fb19SBen Gras ch = (unsigned char)psenc->ch[0];
3142fe8fb19SBen Gras head = psenc->chlen;
3152fe8fb19SBen Gras if (--head > 0)
3162fe8fb19SBen Gras memmove(&psenc->ch[0], &psenc->ch[1], head);
3172fe8fb19SBen Gras wc = (wchar_t)ch;
3182fe8fb19SBen Gras done:
3192fe8fb19SBen Gras psenc->chlen = head;
3202fe8fb19SBen Gras if (pwc != NULL)
3212fe8fb19SBen Gras *pwc = wc;
3222fe8fb19SBen Gras *nresult = (size_t)((wc == 0) ? 0 : (s0 - *s));
3232fe8fb19SBen Gras *s = s0;
3242fe8fb19SBen Gras
3252fe8fb19SBen Gras return 0;
3262fe8fb19SBen Gras }
3272fe8fb19SBen Gras
3282fe8fb19SBen Gras static int
_citrus_UES_wcrtomb_priv(_UESEncodingInfo * __restrict ei,char * __restrict s,size_t n,wchar_t wc,_UESState * __restrict psenc,size_t * __restrict nresult)3292fe8fb19SBen Gras _citrus_UES_wcrtomb_priv(_UESEncodingInfo * __restrict ei,
3302fe8fb19SBen Gras char * __restrict s, size_t n, wchar_t wc,
3312fe8fb19SBen Gras _UESState * __restrict psenc, size_t * __restrict nresult)
3322fe8fb19SBen Gras {
3332fe8fb19SBen Gras wchar_t hi, lo;
3342fe8fb19SBen Gras
3352fe8fb19SBen Gras if (psenc->chlen != 0)
3362fe8fb19SBen Gras return EINVAL;
3372fe8fb19SBen Gras
3382fe8fb19SBen Gras if ((ei->mode & MODE_C99) ? is_basic(wc) : (uint32_t)wc <= 0x7F) {
3392fe8fb19SBen Gras if (n-- < 1)
3402fe8fb19SBen Gras goto e2big;
3412fe8fb19SBen Gras psenc->ch[psenc->chlen++] = (char)wc;
3422fe8fb19SBen Gras } else if ((uint32_t)wc <= BMP_MAX) {
3432fe8fb19SBen Gras if (n < 6)
3442fe8fb19SBen Gras goto e2big;
3452fe8fb19SBen Gras psenc->chlen = to_str(&psenc->ch[0], wc, UCS2_BIT);
3462fe8fb19SBen Gras } else if ((ei->mode & MODE_C99) == 0 && (uint32_t)wc <= UCS2_MAX) {
3472fe8fb19SBen Gras if (n < 12)
3482fe8fb19SBen Gras goto e2big;
3492fe8fb19SBen Gras ucs_to_surrogate(wc, &hi, &lo);
3502fe8fb19SBen Gras psenc->chlen += to_str(&psenc->ch[0], hi, UCS2_BIT);
3512fe8fb19SBen Gras psenc->chlen += to_str(&psenc->ch[6], lo, UCS2_BIT);
3522fe8fb19SBen Gras } else if ((ei->mode & MODE_C99) && (uint32_t)wc <= UCS4_MAX) {
3532fe8fb19SBen Gras if (n < 10)
3542fe8fb19SBen Gras goto e2big;
3552fe8fb19SBen Gras psenc->chlen = to_str(&psenc->ch[0], wc, UCS4_BIT);
3562fe8fb19SBen Gras } else {
3572fe8fb19SBen Gras *nresult = (size_t)-1;
3582fe8fb19SBen Gras return EILSEQ;
3592fe8fb19SBen Gras }
3602fe8fb19SBen Gras memcpy(s, psenc->ch, psenc->chlen);
3612fe8fb19SBen Gras *nresult = psenc->chlen;
3622fe8fb19SBen Gras psenc->chlen = 0;
3632fe8fb19SBen Gras
3642fe8fb19SBen Gras return 0;
3652fe8fb19SBen Gras
3662fe8fb19SBen Gras e2big:
3672fe8fb19SBen Gras *nresult = (size_t)-1;
3682fe8fb19SBen Gras return E2BIG;
3692fe8fb19SBen Gras }
3702fe8fb19SBen Gras
3712fe8fb19SBen Gras /*ARGSUSED*/
3722fe8fb19SBen Gras static int
_citrus_UES_stdenc_wctocs(_UESEncodingInfo * __restrict ei,_csid_t * __restrict csid,_index_t * __restrict idx,wchar_t wc)3732fe8fb19SBen Gras _citrus_UES_stdenc_wctocs(_UESEncodingInfo * __restrict ei,
3742fe8fb19SBen Gras _csid_t * __restrict csid, _index_t * __restrict idx, wchar_t wc)
3752fe8fb19SBen Gras {
3762fe8fb19SBen Gras /* ei seem to be unused */
3772fe8fb19SBen Gras _DIAGASSERT(csid != NULL);
3782fe8fb19SBen Gras _DIAGASSERT(idx != NULL);
3792fe8fb19SBen Gras
3802fe8fb19SBen Gras *csid = 0;
3812fe8fb19SBen Gras *idx = (_index_t)wc;
3822fe8fb19SBen Gras
3832fe8fb19SBen Gras return 0;
3842fe8fb19SBen Gras }
3852fe8fb19SBen Gras
3862fe8fb19SBen Gras static __inline int
3872fe8fb19SBen Gras /*ARGSUSED*/
_citrus_UES_stdenc_cstowc(_UESEncodingInfo * __restrict ei,wchar_t * __restrict wc,_csid_t csid,_index_t idx)3882fe8fb19SBen Gras _citrus_UES_stdenc_cstowc(_UESEncodingInfo * __restrict ei,
3892fe8fb19SBen Gras wchar_t * __restrict wc, _csid_t csid, _index_t idx)
3902fe8fb19SBen Gras {
3912fe8fb19SBen Gras /* ei seem to be unused */
3922fe8fb19SBen Gras _DIAGASSERT(wc != NULL);
3932fe8fb19SBen Gras
3942fe8fb19SBen Gras if (csid != 0)
3952fe8fb19SBen Gras return EILSEQ;
3962fe8fb19SBen Gras *wc = (wchar_t)idx;
3972fe8fb19SBen Gras
3982fe8fb19SBen Gras return 0;
3992fe8fb19SBen Gras }
4002fe8fb19SBen Gras
4012fe8fb19SBen Gras static __inline int
4022fe8fb19SBen Gras /*ARGSUSED*/
_citrus_UES_stdenc_get_state_desc_generic(_UESEncodingInfo * __restrict ei,_UESState * __restrict psenc,int * __restrict rstate)4032fe8fb19SBen Gras _citrus_UES_stdenc_get_state_desc_generic(_UESEncodingInfo * __restrict ei,
4042fe8fb19SBen Gras _UESState * __restrict psenc, int * __restrict rstate)
4052fe8fb19SBen Gras {
4062fe8fb19SBen Gras _DIAGASSERT(psenc != NULL);
4072fe8fb19SBen Gras _DIAGASSERT(rstate != NULL);
4082fe8fb19SBen Gras
4092fe8fb19SBen Gras if (psenc->chlen == 0)
4102fe8fb19SBen Gras *rstate = _STDENC_SDGEN_INITIAL;
4112fe8fb19SBen Gras else
4122fe8fb19SBen Gras *rstate = _STDENC_SDGEN_INCOMPLETE_CHAR; /* XXX */
4132fe8fb19SBen Gras
4142fe8fb19SBen Gras return 0;
4152fe8fb19SBen Gras }
4162fe8fb19SBen Gras
4172fe8fb19SBen Gras static void
4182fe8fb19SBen Gras /*ARGSUSED*/
_citrus_UES_encoding_module_uninit(_UESEncodingInfo * ei)4192fe8fb19SBen Gras _citrus_UES_encoding_module_uninit(_UESEncodingInfo *ei)
4202fe8fb19SBen Gras {
4212fe8fb19SBen Gras /* ei seems to be unused */
4222fe8fb19SBen Gras }
4232fe8fb19SBen Gras
4242fe8fb19SBen Gras static int
4252fe8fb19SBen Gras /*ARGSUSED*/
_citrus_UES_encoding_module_init(_UESEncodingInfo * __restrict ei,const void * __restrict var,size_t lenvar)4262fe8fb19SBen Gras _citrus_UES_encoding_module_init(_UESEncodingInfo * __restrict ei,
4272fe8fb19SBen Gras const void * __restrict var, size_t lenvar)
4282fe8fb19SBen Gras {
4292fe8fb19SBen Gras const char *p;
4302fe8fb19SBen Gras
4312fe8fb19SBen Gras _DIAGASSERT(ei != NULL);
4322fe8fb19SBen Gras
4332fe8fb19SBen Gras p = var;
4342fe8fb19SBen Gras #define MATCH(x, act) \
4352fe8fb19SBen Gras do { \
4362fe8fb19SBen Gras if (lenvar >= (sizeof(#x)-1) && \
4372fe8fb19SBen Gras _bcs_strncasecmp(p, #x, sizeof(#x)-1) == 0) { \
4382fe8fb19SBen Gras act; \
4392fe8fb19SBen Gras lenvar -= sizeof(#x)-1; \
4402fe8fb19SBen Gras p += sizeof(#x)-1; \
4412fe8fb19SBen Gras } \
4422fe8fb19SBen Gras } while (/*CONSTCOND*/0)
4432fe8fb19SBen Gras memset((void *)ei, 0, sizeof(*ei));
4442fe8fb19SBen Gras while (lenvar > 0) {
4452fe8fb19SBen Gras switch (_bcs_toupper(*p)) {
4462fe8fb19SBen Gras case 'C':
4472fe8fb19SBen Gras MATCH(C99, ei->mode |= MODE_C99);
4482fe8fb19SBen Gras break;
4492fe8fb19SBen Gras }
4502fe8fb19SBen Gras ++p;
4512fe8fb19SBen Gras --lenvar;
4522fe8fb19SBen Gras }
4532fe8fb19SBen Gras ei->mb_cur_max = (ei->mode & MODE_C99) ? 10 : 12;
4542fe8fb19SBen Gras
4552fe8fb19SBen Gras return 0;
4562fe8fb19SBen Gras }
4572fe8fb19SBen Gras
4582fe8fb19SBen Gras /* ----------------------------------------------------------------------
4592fe8fb19SBen Gras * public interface for ctype
4602fe8fb19SBen Gras */
4612fe8fb19SBen Gras
4622fe8fb19SBen Gras _CITRUS_CTYPE_DECLS(UES);
4632fe8fb19SBen Gras _CITRUS_CTYPE_DEF_OPS(UES);
4642fe8fb19SBen Gras
4652fe8fb19SBen Gras #include "citrus_ctype_template.h"
4662fe8fb19SBen Gras
4672fe8fb19SBen Gras /* ----------------------------------------------------------------------
4682fe8fb19SBen Gras * public interface for stdenc
4692fe8fb19SBen Gras */
4702fe8fb19SBen Gras
4712fe8fb19SBen Gras _CITRUS_STDENC_DECLS(UES);
4722fe8fb19SBen Gras _CITRUS_STDENC_DEF_OPS(UES);
4732fe8fb19SBen Gras
4742fe8fb19SBen Gras #include "citrus_stdenc_template.h"
475