Home | History | Annotate | Line # | Download | only in modules
citrus_ues.c revision 1.4.22.1
      1  1.4.22.1  perseant /* $NetBSD: citrus_ues.c,v 1.4.22.1 2017/07/14 15:53:07 perseant Exp $ */
      2       1.1   tnozaki 
      3       1.1   tnozaki /*-
      4       1.1   tnozaki  * Copyright (c)2006 Citrus Project,
      5       1.1   tnozaki  * All rights reserved.
      6       1.1   tnozaki  *
      7       1.1   tnozaki  * Redistribution and use in source and binary forms, with or without
      8       1.1   tnozaki  * modification, are permitted provided that the following conditions
      9       1.1   tnozaki  * are met:
     10       1.1   tnozaki  * 1. Redistributions of source code must retain the above copyright
     11       1.1   tnozaki  *    notice, this list of conditions and the following disclaimer.
     12       1.1   tnozaki  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1   tnozaki  *    notice, this list of conditions and the following disclaimer in the
     14       1.1   tnozaki  *    documentation and/or other materials provided with the distribution.
     15       1.1   tnozaki  *
     16       1.1   tnozaki  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17       1.1   tnozaki  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18       1.1   tnozaki  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19       1.1   tnozaki  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20       1.1   tnozaki  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21       1.1   tnozaki  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22       1.1   tnozaki  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23       1.1   tnozaki  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24       1.1   tnozaki  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25       1.1   tnozaki  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26       1.1   tnozaki  * SUCH DAMAGE.
     27       1.1   tnozaki  */
     28       1.1   tnozaki 
     29       1.1   tnozaki #include <sys/cdefs.h>
     30       1.1   tnozaki #if defined(LIBC_SCCS) && !defined(lint)
     31  1.4.22.1  perseant __RCSID("$NetBSD: citrus_ues.c,v 1.4.22.1 2017/07/14 15:53:07 perseant Exp $");
     32       1.1   tnozaki #endif /* LIBC_SCCS and not lint */
     33       1.1   tnozaki 
     34       1.1   tnozaki #include <assert.h>
     35       1.1   tnozaki #include <errno.h>
     36       1.1   tnozaki #include <string.h>
     37       1.1   tnozaki #include <stdio.h>
     38       1.1   tnozaki #include <stdint.h>
     39       1.1   tnozaki #include <stdlib.h>
     40       1.1   tnozaki #include <limits.h>
     41       1.1   tnozaki #include <wchar.h>
     42       1.1   tnozaki 
     43       1.1   tnozaki #include "citrus_namespace.h"
     44       1.1   tnozaki #include "citrus_types.h"
     45       1.1   tnozaki #include "citrus_bcs.h"
     46       1.1   tnozaki #include "citrus_module.h"
     47       1.1   tnozaki #include "citrus_ctype.h"
     48       1.1   tnozaki #include "citrus_stdenc.h"
     49       1.1   tnozaki #include "citrus_ues.h"
     50       1.1   tnozaki 
     51       1.1   tnozaki typedef struct {
     52       1.1   tnozaki 	int mode;
     53       1.1   tnozaki #define MODE_C99	1
     54       1.1   tnozaki 	size_t mb_cur_max;
     55       1.1   tnozaki } _UESEncodingInfo;
     56       1.1   tnozaki 
     57       1.1   tnozaki typedef struct {
     58       1.1   tnozaki 	int chlen;
     59       1.1   tnozaki 	char ch[12];
     60       1.1   tnozaki } _UESState;
     61       1.1   tnozaki 
     62       1.1   tnozaki typedef struct {
     63       1.1   tnozaki 	_UESEncodingInfo	ei;
     64       1.1   tnozaki 	struct {
     65       1.1   tnozaki 		/* for future multi-locale facility */
     66       1.1   tnozaki 		_UESState	s_mblen;
     67       1.1   tnozaki 		_UESState	s_mbrlen;
     68       1.1   tnozaki 		_UESState	s_mbrtowc;
     69       1.1   tnozaki 		_UESState	s_mbtowc;
     70       1.1   tnozaki 		_UESState	s_mbsrtowcs;
     71       1.4     joerg 		_UESState	s_mbsnrtowcs;
     72       1.1   tnozaki 		_UESState	s_wcrtomb;
     73       1.1   tnozaki 		_UESState	s_wcsrtombs;
     74       1.4     joerg 		_UESState	s_wcsnrtombs;
     75       1.1   tnozaki 		_UESState	s_wctomb;
     76       1.1   tnozaki 	} states;
     77       1.1   tnozaki } _UESCTypeInfo;
     78       1.1   tnozaki 
     79       1.1   tnozaki #define _CEI_TO_EI(_cei_)               (&(_cei_)->ei)
     80       1.1   tnozaki #define _CEI_TO_STATE(_cei_, _func_)    (_cei_)->states.s_##_func_
     81       1.1   tnozaki 
     82       1.1   tnozaki #define _FUNCNAME(m)			_citrus_UES_##m
     83       1.1   tnozaki #define _ENCODING_INFO			_UESEncodingInfo
     84       1.1   tnozaki #define _CTYPE_INFO			_UESCTypeInfo
     85       1.1   tnozaki #define _ENCODING_STATE			_UESState
     86       1.1   tnozaki #define _ENCODING_MB_CUR_MAX(_ei_)	(_ei_)->mb_cur_max
     87       1.1   tnozaki #define _ENCODING_IS_STATE_DEPENDENT		0
     88       1.1   tnozaki #define _STATE_NEEDS_EXPLICIT_INIT(_ps_)	0
     89       1.1   tnozaki 
     90       1.1   tnozaki static __inline void
     91       1.1   tnozaki /*ARGSUSED*/
     92       1.1   tnozaki _citrus_UES_init_state(_UESEncodingInfo * __restrict ei,
     93       1.1   tnozaki 	_UESState * __restrict psenc)
     94       1.1   tnozaki {
     95       1.1   tnozaki 	psenc->chlen = 0;
     96       1.1   tnozaki }
     97       1.1   tnozaki 
     98       1.1   tnozaki static __inline void
     99       1.1   tnozaki /*ARGSUSED*/
    100       1.1   tnozaki _citrus_UES_pack_state(_UESEncodingInfo * __restrict ei,
    101       1.1   tnozaki 	void *__restrict pspriv, const _UESState * __restrict psenc)
    102       1.1   tnozaki {
    103       1.1   tnozaki 	/* ei seem to be unused */
    104       1.1   tnozaki 	_DIAGASSERT(pspriv != NULL);
    105       1.1   tnozaki 	_DIAGASSERT(psenc != NULL);
    106       1.1   tnozaki 
    107       1.1   tnozaki 	memcpy(pspriv, (const void *)psenc, sizeof(*psenc));
    108       1.1   tnozaki }
    109       1.1   tnozaki 
    110       1.1   tnozaki static __inline void
    111       1.1   tnozaki /*ARGSUSED*/
    112       1.1   tnozaki _citrus_UES_unpack_state(_UESEncodingInfo * __restrict ei,
    113       1.1   tnozaki 	_UESState * __restrict psenc, const void * __restrict pspriv)
    114       1.1   tnozaki {
    115       1.1   tnozaki 	/* ei seem to be unused */
    116       1.1   tnozaki 	_DIAGASSERT(psenc != NULL);
    117       1.1   tnozaki 	_DIAGASSERT(pspriv != NULL);
    118       1.1   tnozaki 
    119       1.1   tnozaki 	memcpy((void *)psenc, pspriv, sizeof(*psenc));
    120       1.1   tnozaki }
    121       1.1   tnozaki 
    122       1.1   tnozaki static __inline int
    123       1.1   tnozaki to_int(int ch)
    124       1.1   tnozaki {
    125       1.1   tnozaki 	if (ch >= '0' && ch <= '9')
    126       1.1   tnozaki 		return ch - '0';
    127       1.1   tnozaki 	else if (ch >= 'A' && ch <= 'F')
    128       1.1   tnozaki 		return (ch - 'A') + 10;
    129       1.1   tnozaki 	else if (ch >= 'a' && ch <= 'f')
    130       1.1   tnozaki 		return (ch - 'a') + 10;
    131       1.1   tnozaki 	return -1;
    132       1.1   tnozaki }
    133       1.1   tnozaki 
    134       1.1   tnozaki #define ESCAPE		'\\'
    135       1.1   tnozaki #define UCS2_ESC	'u'
    136       1.1   tnozaki #define UCS4_ESC	'U'
    137       1.1   tnozaki 
    138       1.1   tnozaki #define UCS2_BIT	16
    139       1.1   tnozaki #define UCS4_BIT	32
    140       1.1   tnozaki #define BMP_MAX		UINT32_C(0xFFFF)
    141       1.1   tnozaki #define UCS2_MAX	UINT32_C(0x10FFFF)
    142       1.1   tnozaki #define UCS4_MAX	UINT32_C(0x7FFFFFFF)
    143       1.1   tnozaki 
    144       1.1   tnozaki static const char *xdig = "0123456789abcdef";
    145       1.1   tnozaki 
    146       1.1   tnozaki static __inline int
    147       1.1   tnozaki to_str(char *s, wchar_t wc, int bit)
    148       1.1   tnozaki {
    149       1.1   tnozaki 	char *p;
    150       1.1   tnozaki 
    151       1.1   tnozaki 	p = s;
    152       1.1   tnozaki 	*p++ = ESCAPE;
    153       1.1   tnozaki 	switch (bit) {
    154       1.1   tnozaki 	case UCS2_BIT:
    155       1.1   tnozaki 		*p++ = UCS2_ESC;
    156       1.1   tnozaki 		break;
    157       1.1   tnozaki 	case UCS4_BIT:
    158       1.1   tnozaki 		*p++ = UCS4_ESC;
    159       1.1   tnozaki 		break;
    160       1.1   tnozaki 	default:
    161       1.1   tnozaki 		abort();
    162       1.1   tnozaki 	}
    163       1.1   tnozaki 	do {
    164       1.1   tnozaki 		*p++ = xdig[(wc >> (bit -= 4)) & 0xF];
    165       1.1   tnozaki 	} while (bit > 0);
    166       1.1   tnozaki 	return p - s;
    167       1.1   tnozaki }
    168       1.1   tnozaki 
    169       1.1   tnozaki static __inline int
    170       1.1   tnozaki is_hi_surrogate(wchar_t wc)
    171       1.1   tnozaki {
    172       1.1   tnozaki 	return wc >= 0xD800 && wc <= 0xDBFF;
    173       1.1   tnozaki }
    174       1.1   tnozaki 
    175       1.1   tnozaki static __inline int
    176       1.1   tnozaki is_lo_surrogate(wchar_t wc)
    177       1.1   tnozaki {
    178       1.1   tnozaki 	return wc >= 0xDC00 && wc <= 0xDFFF;
    179       1.1   tnozaki }
    180       1.1   tnozaki 
    181       1.1   tnozaki static __inline wchar_t
    182       1.1   tnozaki surrogate_to_ucs(wchar_t hi, wchar_t lo)
    183       1.1   tnozaki {
    184       1.1   tnozaki 	_DIAGASSERT(is_hi_surrogate(hi));
    185       1.1   tnozaki 	_DIAGASSERT(is_lo_surrogate(lo));
    186       1.1   tnozaki 
    187       1.1   tnozaki 	hi -= 0xD800;
    188       1.1   tnozaki 	lo -= 0xDC00;
    189       1.1   tnozaki 	return (hi << 10 | lo) + 0x10000;
    190       1.1   tnozaki }
    191       1.1   tnozaki 
    192       1.1   tnozaki static __inline void
    193       1.1   tnozaki ucs_to_surrogate(wchar_t wc, wchar_t * __restrict hi, wchar_t * __restrict lo)
    194       1.1   tnozaki {
    195       1.1   tnozaki 	_DIAGASSERT(hi != NULL);
    196       1.1   tnozaki 	_DIAGASSERT(lo != NULL);
    197       1.1   tnozaki 	_DIAGASSERT(wc >= 0x10000);
    198       1.1   tnozaki 
    199       1.1   tnozaki 	wc -= 0x10000;
    200       1.1   tnozaki 	*hi = (wc >> 10) + 0xD800;
    201       1.1   tnozaki 	*lo = (wc & 0x3FF) + 0xDC00;
    202       1.1   tnozaki }
    203       1.1   tnozaki 
    204       1.1   tnozaki static __inline int
    205       1.1   tnozaki is_basic(wchar_t wc)
    206       1.1   tnozaki {
    207       1.1   tnozaki 	return (uint32_t)wc <= 0x9F &&
    208       1.1   tnozaki 	    wc != 0x24 && wc != 0x40 && wc != 0x60;
    209       1.1   tnozaki }
    210       1.1   tnozaki 
    211       1.1   tnozaki static int
    212       1.1   tnozaki _citrus_UES_mbrtowc_priv(_UESEncodingInfo * __restrict ei,
    213       1.1   tnozaki 	wchar_t * __restrict pwc, const char ** __restrict s, size_t n,
    214       1.1   tnozaki 	_UESState * __restrict psenc, size_t * __restrict nresult)
    215       1.1   tnozaki {
    216       1.1   tnozaki 	const char *s0;
    217       1.3       wiz 	int ch, head, tail, num;
    218       1.1   tnozaki 	wchar_t hi, wc;
    219       1.1   tnozaki 
    220       1.1   tnozaki 	_DIAGASSERT(ei != NULL);
    221       1.1   tnozaki 	/* pwc may be null */
    222       1.1   tnozaki 	_DIAGASSERT(s != NULL);
    223       1.1   tnozaki 	_DIAGASSERT(psenc != NULL);
    224       1.1   tnozaki 	_DIAGASSERT(nresult != NULL);
    225       1.1   tnozaki 
    226       1.1   tnozaki 	if (*s == NULL) {
    227       1.1   tnozaki 		_citrus_UES_init_state(ei, psenc);
    228       1.1   tnozaki 		*nresult = 0;
    229       1.1   tnozaki 		return 0;
    230       1.1   tnozaki 	}
    231       1.1   tnozaki 	s0 = *s;
    232       1.1   tnozaki 
    233       1.1   tnozaki 	hi = (wchar_t)0;
    234       1.1   tnozaki 	tail = 0;
    235       1.1   tnozaki 
    236       1.1   tnozaki surrogate:
    237       1.1   tnozaki 	wc = (wchar_t)0;
    238       1.1   tnozaki 	head = tail;
    239       1.1   tnozaki 	if (psenc->chlen == head) {
    240       1.1   tnozaki 		if (n-- < 1)
    241       1.1   tnozaki 			goto restart;
    242       1.1   tnozaki 		psenc->ch[psenc->chlen++] = *s0++;
    243       1.1   tnozaki 	}
    244       1.1   tnozaki 	ch = (unsigned char)psenc->ch[head++];
    245       1.1   tnozaki 	if (ch == ESCAPE) {
    246       1.1   tnozaki 		if (psenc->chlen == head) {
    247       1.1   tnozaki 			if (n-- < 1)
    248       1.1   tnozaki 				goto restart;
    249       1.1   tnozaki 			psenc->ch[psenc->chlen++] = *s0++;
    250       1.1   tnozaki 		}
    251       1.1   tnozaki 		switch (psenc->ch[head]) {
    252       1.1   tnozaki 		case UCS2_ESC:
    253       1.1   tnozaki 			tail += 6;
    254       1.1   tnozaki 			break;
    255       1.1   tnozaki 		case UCS4_ESC:
    256       1.1   tnozaki 			if (ei->mode & MODE_C99) {
    257       1.1   tnozaki 				tail = 10;
    258       1.1   tnozaki 				break;
    259       1.1   tnozaki 			}
    260       1.1   tnozaki 		/*FALLTHROUGH*/
    261       1.1   tnozaki 		default:
    262       1.1   tnozaki 			tail = 0;
    263       1.1   tnozaki 		}
    264       1.1   tnozaki 		++head;
    265       1.1   tnozaki 	}
    266       1.1   tnozaki 	for (; head < tail; ++head) {
    267       1.1   tnozaki 		if (psenc->chlen == head) {
    268       1.1   tnozaki 			if (n-- < 1) {
    269       1.1   tnozaki restart:
    270       1.1   tnozaki 				*s = s0;
    271       1.1   tnozaki 				*nresult = (size_t)-2;
    272       1.1   tnozaki 				return 0;
    273       1.1   tnozaki 			}
    274       1.1   tnozaki 			psenc->ch[psenc->chlen++] = *s0++;
    275       1.1   tnozaki 		}
    276       1.1   tnozaki 		num = to_int((int)(unsigned char)psenc->ch[head]);
    277       1.1   tnozaki 		if (num < 0) {
    278       1.1   tnozaki 			tail = 0;
    279       1.1   tnozaki 			break;
    280       1.1   tnozaki 		}
    281       1.1   tnozaki 		wc = (wc << 4) | num;
    282       1.1   tnozaki 	}
    283       1.1   tnozaki 	head = 0;
    284       1.1   tnozaki 	switch (tail) {
    285       1.1   tnozaki 	case 0:
    286       1.1   tnozaki 		break;
    287       1.1   tnozaki 	case 6:
    288       1.1   tnozaki 		if (hi != (wchar_t)0)
    289       1.1   tnozaki 			break;
    290       1.1   tnozaki 		if ((ei->mode & MODE_C99) == 0) {
    291       1.1   tnozaki 			if (is_hi_surrogate(wc) != 0) {
    292       1.1   tnozaki 				hi = wc;
    293       1.1   tnozaki 				goto surrogate;
    294       1.1   tnozaki 			}
    295       1.1   tnozaki 			if ((uint32_t)wc <= 0x7F /* XXX */ ||
    296       1.1   tnozaki 			    is_lo_surrogate(wc) != 0)
    297       1.1   tnozaki 				break;
    298       1.1   tnozaki 			goto done;
    299       1.1   tnozaki 		}
    300       1.1   tnozaki 	/*FALLTHROUGH*/
    301       1.1   tnozaki 	case 10:
    302       1.1   tnozaki 		if (is_basic(wc) == 0 && (uint32_t)wc <= UCS4_MAX &&
    303       1.1   tnozaki 		    is_hi_surrogate(wc) == 0 && is_lo_surrogate(wc) == 0)
    304       1.1   tnozaki 			goto done;
    305       1.1   tnozaki 		*nresult = (size_t)-1;
    306       1.1   tnozaki 		return EILSEQ;
    307       1.1   tnozaki 	case 12:
    308       1.1   tnozaki 		if (is_lo_surrogate(wc) == 0)
    309       1.1   tnozaki 			break;
    310       1.1   tnozaki 		wc = surrogate_to_ucs(hi, wc);
    311       1.1   tnozaki 		goto done;
    312       1.1   tnozaki 	}
    313       1.1   tnozaki 	ch = (unsigned char)psenc->ch[0];
    314       1.1   tnozaki 	head = psenc->chlen;
    315       1.1   tnozaki 	if (--head > 0)
    316       1.1   tnozaki 		memmove(&psenc->ch[0], &psenc->ch[1], head);
    317       1.1   tnozaki 	wc = (wchar_t)ch;
    318       1.1   tnozaki done:
    319       1.1   tnozaki 	psenc->chlen = head;
    320       1.1   tnozaki 	if (pwc != NULL)
    321       1.1   tnozaki 		*pwc = wc;
    322       1.1   tnozaki 	*nresult = (size_t)((wc == 0) ? 0 : (s0 - *s));
    323       1.1   tnozaki 	*s = s0;
    324       1.1   tnozaki 
    325       1.1   tnozaki 	return 0;
    326       1.1   tnozaki }
    327       1.1   tnozaki 
    328       1.1   tnozaki static int
    329       1.1   tnozaki _citrus_UES_wcrtomb_priv(_UESEncodingInfo * __restrict ei,
    330       1.1   tnozaki 	char * __restrict s, size_t n, wchar_t wc,
    331       1.1   tnozaki 	_UESState * __restrict psenc, size_t * __restrict nresult)
    332       1.1   tnozaki {
    333       1.1   tnozaki 	wchar_t hi, lo;
    334       1.1   tnozaki 
    335       1.1   tnozaki 	if (psenc->chlen != 0)
    336       1.1   tnozaki 		return EINVAL;
    337       1.1   tnozaki 
    338       1.1   tnozaki 	if ((ei->mode & MODE_C99) ? is_basic(wc) : (uint32_t)wc <= 0x7F) {
    339       1.1   tnozaki 		if (n-- < 1)
    340       1.1   tnozaki 			goto e2big;
    341       1.1   tnozaki 		psenc->ch[psenc->chlen++] = (char)wc;
    342       1.1   tnozaki 	} else if ((uint32_t)wc <= BMP_MAX) {
    343       1.1   tnozaki 		if (n < 6)
    344       1.1   tnozaki 			goto e2big;
    345       1.1   tnozaki 		psenc->chlen = to_str(&psenc->ch[0], wc, UCS2_BIT);
    346       1.1   tnozaki 	} else if ((ei->mode & MODE_C99) == 0 && (uint32_t)wc <= UCS2_MAX) {
    347       1.1   tnozaki 		if (n < 12)
    348       1.1   tnozaki 			goto e2big;
    349       1.1   tnozaki 		ucs_to_surrogate(wc, &hi, &lo);
    350       1.1   tnozaki 		psenc->chlen += to_str(&psenc->ch[0], hi, UCS2_BIT);
    351       1.1   tnozaki 		psenc->chlen += to_str(&psenc->ch[6], lo, UCS2_BIT);
    352       1.1   tnozaki 	} else if ((ei->mode & MODE_C99) && (uint32_t)wc <= UCS4_MAX) {
    353       1.1   tnozaki 		if (n < 10)
    354       1.1   tnozaki 			goto e2big;
    355       1.1   tnozaki 		psenc->chlen = to_str(&psenc->ch[0], wc, UCS4_BIT);
    356       1.1   tnozaki 	} else {
    357       1.1   tnozaki 		*nresult = (size_t)-1;
    358       1.1   tnozaki 		return EILSEQ;
    359       1.1   tnozaki 	}
    360       1.1   tnozaki 	memcpy(s, psenc->ch, psenc->chlen);
    361       1.1   tnozaki 	*nresult = psenc->chlen;
    362       1.1   tnozaki 	psenc->chlen = 0;
    363       1.1   tnozaki 
    364       1.1   tnozaki 	return 0;
    365       1.1   tnozaki 
    366       1.1   tnozaki e2big:
    367       1.1   tnozaki 	*nresult = (size_t)-1;
    368       1.1   tnozaki 	return E2BIG;
    369       1.1   tnozaki }
    370       1.1   tnozaki 
    371       1.1   tnozaki /*ARGSUSED*/
    372       1.2     joerg static int
    373  1.4.22.1  perseant _citrus_UES_stdenc_wctocs(struct _citrus_stdenc *ce,
    374       1.1   tnozaki 	_csid_t * __restrict csid, _index_t * __restrict idx, wchar_t wc)
    375       1.1   tnozaki {
    376       1.1   tnozaki 	/* ei seem to be unused */
    377       1.1   tnozaki 	_DIAGASSERT(csid != NULL);
    378       1.1   tnozaki 	_DIAGASSERT(idx != NULL);
    379       1.1   tnozaki 
    380       1.1   tnozaki 	*csid = 0;
    381       1.1   tnozaki 	*idx = (_index_t)wc;
    382       1.1   tnozaki 
    383       1.1   tnozaki 	return 0;
    384       1.1   tnozaki }
    385       1.1   tnozaki 
    386  1.4.22.1  perseant static int
    387       1.1   tnozaki /*ARGSUSED*/
    388  1.4.22.1  perseant _citrus_UES_stdenc_cstowc(struct _citrus_stdenc *ce,
    389       1.1   tnozaki 	wchar_t * __restrict wc, _csid_t csid, _index_t idx)
    390       1.1   tnozaki {
    391       1.1   tnozaki 	/* ei seem to be unused */
    392       1.1   tnozaki 	_DIAGASSERT(wc != NULL);
    393       1.1   tnozaki 
    394       1.1   tnozaki 	if (csid != 0)
    395       1.1   tnozaki 		return EILSEQ;
    396       1.1   tnozaki 	*wc = (wchar_t)idx;
    397       1.1   tnozaki 
    398       1.1   tnozaki 	return 0;
    399       1.1   tnozaki }
    400       1.1   tnozaki 
    401       1.1   tnozaki static __inline int
    402       1.1   tnozaki /*ARGSUSED*/
    403       1.1   tnozaki _citrus_UES_stdenc_get_state_desc_generic(_UESEncodingInfo * __restrict ei,
    404       1.1   tnozaki 	_UESState * __restrict psenc, int * __restrict rstate)
    405       1.1   tnozaki {
    406       1.1   tnozaki 	_DIAGASSERT(psenc != NULL);
    407       1.1   tnozaki 	_DIAGASSERT(rstate != NULL);
    408       1.1   tnozaki 
    409       1.1   tnozaki 	if (psenc->chlen == 0)
    410       1.1   tnozaki 		*rstate = _STDENC_SDGEN_INITIAL;
    411       1.1   tnozaki 	else
    412       1.1   tnozaki 		*rstate = _STDENC_SDGEN_INCOMPLETE_CHAR; /* XXX */
    413       1.1   tnozaki 
    414       1.1   tnozaki 	return 0;
    415       1.1   tnozaki }
    416       1.1   tnozaki 
    417       1.1   tnozaki static void
    418       1.1   tnozaki /*ARGSUSED*/
    419       1.1   tnozaki _citrus_UES_encoding_module_uninit(_UESEncodingInfo *ei)
    420       1.1   tnozaki {
    421       1.1   tnozaki 	/* ei seems to be unused */
    422       1.1   tnozaki }
    423       1.1   tnozaki 
    424       1.1   tnozaki static int
    425       1.1   tnozaki /*ARGSUSED*/
    426       1.1   tnozaki _citrus_UES_encoding_module_init(_UESEncodingInfo * __restrict ei,
    427       1.1   tnozaki 	const void * __restrict var, size_t lenvar)
    428       1.1   tnozaki {
    429       1.1   tnozaki 	const char *p;
    430       1.1   tnozaki 
    431       1.1   tnozaki 	_DIAGASSERT(ei != NULL);
    432       1.1   tnozaki 
    433       1.1   tnozaki 	p = var;
    434       1.1   tnozaki #define MATCH(x, act)						\
    435       1.1   tnozaki do {								\
    436       1.1   tnozaki         if (lenvar >= (sizeof(#x)-1) &&				\
    437       1.1   tnozaki             _bcs_strncasecmp(p, #x, sizeof(#x)-1) == 0) {	\
    438       1.1   tnozaki                 act;						\
    439       1.1   tnozaki                 lenvar -= sizeof(#x)-1;				\
    440       1.1   tnozaki                 p += sizeof(#x)-1;				\
    441       1.1   tnozaki         }							\
    442       1.1   tnozaki } while (/*CONSTCOND*/0)
    443       1.1   tnozaki 	memset((void *)ei, 0, sizeof(*ei));
    444       1.1   tnozaki 	while (lenvar > 0) {
    445       1.1   tnozaki 		switch (_bcs_toupper(*p)) {
    446       1.1   tnozaki 		case 'C':
    447       1.1   tnozaki 			MATCH(C99, ei->mode |= MODE_C99);
    448       1.1   tnozaki 			break;
    449       1.1   tnozaki 		}
    450       1.1   tnozaki 		++p;
    451       1.1   tnozaki 		--lenvar;
    452       1.1   tnozaki 	}
    453       1.1   tnozaki 	ei->mb_cur_max = (ei->mode & MODE_C99) ? 10 : 12;
    454       1.1   tnozaki 
    455       1.1   tnozaki 	return 0;
    456       1.1   tnozaki }
    457       1.1   tnozaki 
    458       1.1   tnozaki /* ----------------------------------------------------------------------
    459       1.1   tnozaki  * public interface for ctype
    460       1.1   tnozaki  */
    461       1.1   tnozaki 
    462       1.1   tnozaki _CITRUS_CTYPE_DECLS(UES);
    463       1.1   tnozaki _CITRUS_CTYPE_DEF_OPS(UES);
    464       1.1   tnozaki 
    465       1.1   tnozaki #include "citrus_ctype_template.h"
    466       1.1   tnozaki 
    467       1.1   tnozaki /* ----------------------------------------------------------------------
    468       1.1   tnozaki  * public interface for stdenc
    469       1.1   tnozaki  */
    470       1.1   tnozaki 
    471       1.1   tnozaki _CITRUS_STDENC_DECLS(UES);
    472       1.1   tnozaki _CITRUS_STDENC_DEF_OPS(UES);
    473       1.1   tnozaki 
    474       1.1   tnozaki #include "citrus_stdenc_template.h"
    475