Home | History | Annotate | Line # | Download | only in locale
multibyte_amd1.c revision 1.14.20.1
      1 /*	$NetBSD: multibyte_amd1.c,v 1.14.20.1 2017/07/14 15:53:08 perseant Exp $	*/
      2 
      3 /*-
      4  * Copyright (c)2002, 2008 Citrus Project,
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 #if defined(LIBC_SCCS) && !defined(lint)
     31 __RCSID("$NetBSD: multibyte_amd1.c,v 1.14.20.1 2017/07/14 15:53:08 perseant Exp $");
     32 #endif /* LIBC_SCCS and not lint */
     33 
     34 #include <sys/types.h>
     35 #include <assert.h>
     36 #include <errno.h>
     37 #include <langinfo.h>
     38 #include <stdlib.h>
     39 #define __SETLOCALE_SOURCE__
     40 #include <locale.h>
     41 #include <wchar.h>
     42 
     43 #include "setlocale_local.h"
     44 
     45 #include "citrus_module.h"
     46 #include "citrus_ctype.h"
     47 #include "runetype_local.h"
     48 #include "rune_iso10646.h"
     49 #include "multibyte.h"
     50 
     51 size_t
     52 mbrlen_l(const char *s, size_t n, mbstate_t *ps, locale_t loc)
     53 {
     54 	size_t ret;
     55 	int err0;
     56 
     57 	_fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
     58 
     59 	err0 = _citrus_ctype_mbrlen(_ps_to_ctype(ps, loc), s, n,
     60 				     _ps_to_private(ps), &ret);
     61 	if (err0)
     62 		errno = err0;
     63 
     64 	return ret;
     65 }
     66 
     67 size_t
     68 mbrlen(const char *s, size_t n, mbstate_t *ps)
     69 {
     70 	return mbrlen_l(s, n, ps, _current_locale());
     71 }
     72 
     73 int
     74 mbsinit_l(const mbstate_t *ps, locale_t loc)
     75 {
     76 	int ret;
     77 	int err0;
     78 	_RuneLocale *rl;
     79 
     80 	if (ps == NULL)
     81 		return 1;
     82 
     83 	if (_ps_to_runelocale(ps) == NULL)
     84 		rl = _RUNE_LOCALE(loc);
     85 	else
     86 		rl = _ps_to_runelocale(ps);
     87 
     88 	/* mbsinit should cause no error... */
     89 	err0 = _citrus_ctype_mbsinit(rl->rl_citrus_ctype,
     90 				      _ps_to_private_const(ps), &ret);
     91 	if (err0)
     92 		errno = err0;
     93 
     94 	return ret;
     95 }
     96 
     97 int
     98 mbsinit(const mbstate_t *ps)
     99 {
    100 	return mbsinit_l(ps, _current_locale());
    101 }
    102 
    103 size_t
    104 mbrtowc_l(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps, locale_t loc)
    105 {
    106 	size_t ret;
    107 	int err0;
    108 
    109 	_fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
    110 
    111 	err0 = _citrus_ctype_mbrtowc(_ps_to_ctype(ps, loc), pwc, s, n,
    112 				      _ps_to_private(ps), &ret);
    113 	if (err0) {
    114 		errno = err0;
    115 		return -1;
    116 	}
    117 
    118 	if (s != NULL && pwc != NULL) {
    119 		err0 = _citrus_kuten_to_unicode(_RUNE_LOCALE(loc), *pwc, pwc);
    120 		if (err0)
    121 			errno = err0;
    122 	}
    123 
    124 	return ret;
    125 }
    126 
    127 size_t
    128 mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
    129 {
    130 	return mbrtowc_l(pwc, s, n, ps, _current_locale());
    131 }
    132 
    133 size_t
    134 mbsrtowcs_l(wchar_t *pwcs, const char **s, size_t n, mbstate_t *ps,
    135     locale_t loc)
    136 {
    137 	size_t ret;
    138 	int err0;
    139 
    140 	_fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
    141 
    142 	err0 = _citrus_ctype_mbsrtowcs(_ps_to_ctype(ps, loc), pwcs, s, n,
    143 					_ps_to_private(ps), &ret);
    144 	if (err0) {
    145 		errno = err0;
    146 		return -1;
    147 	}
    148 
    149 	if (s != NULL && pwcs != NULL) {
    150 		err0 = _citrus_wcs_kuten_to_unicode(_RUNE_LOCALE(loc), pwcs, pwcs, ret);
    151 		if (err0)
    152 			errno = err0;
    153 	}
    154 
    155 	return ret;
    156 }
    157 
    158 size_t
    159 mbsrtowcs(wchar_t *pwcs, const char **s, size_t n, mbstate_t *ps)
    160 {
    161 	return mbsrtowcs_l(pwcs, s, n, ps, _current_locale());
    162 }
    163 
    164 size_t
    165 mbsnrtowcs_l(wchar_t *pwcs, const char **s, size_t in, size_t n, mbstate_t *ps,
    166     locale_t loc)
    167 {
    168 	size_t ret;
    169 	int err0;
    170 
    171 	_fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
    172 
    173 	err0 = _citrus_ctype_mbsnrtowcs(_ps_to_ctype(ps, loc), pwcs, s, in, n,
    174 					_ps_to_private(ps), &ret);
    175 	if (err0) {
    176 		errno = err0;
    177 		return -1;
    178 	}
    179 
    180 	err0 = _citrus_wcs_kuten_to_unicode(_RUNE_LOCALE(loc), pwcs, pwcs, ret);
    181 	if (err0)
    182 		errno = err0;
    183 
    184 	return ret;
    185 }
    186 
    187 size_t
    188 mbsnrtowcs(wchar_t *pwcs, const char **s, size_t in, size_t n, mbstate_t *ps)
    189 {
    190 	return mbsnrtowcs_l(pwcs, s, in, n, ps, _current_locale());
    191 }
    192 
    193 size_t
    194 wcrtomb_l(char *s, wchar_t wc, mbstate_t *ps, locale_t loc)
    195 {
    196 	size_t ret;
    197 	int err0;
    198 
    199 	_fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
    200 
    201 	err0 = _citrus_unicode_to_kuten(_RUNE_LOCALE(loc), wc, &wc);
    202 	if (err0) {
    203 		errno = err0;
    204 		return -1;
    205 	}
    206 
    207 	err0 = _citrus_ctype_wcrtomb(_ps_to_ctype(ps, loc), s, wc,
    208 				       _ps_to_private(ps), &ret);
    209 	if (err0)
    210 		errno = err0;
    211 
    212 	return ret;
    213 }
    214 
    215 size_t
    216 wcrtomb(char *s, wchar_t wc, mbstate_t *ps)
    217 {
    218 	return wcrtomb_l(s, wc, ps, _current_locale());
    219 }
    220 
    221 size_t
    222 wcsrtombs_l(char *s, const wchar_t **ppwcs, size_t n, mbstate_t *ps,
    223     locale_t loc)
    224 {
    225 	size_t ret;
    226 	int err0;
    227 #ifdef __STDC_ISO_10646__
    228 	wchar_t *wcskt, *owcskt;
    229 	int nn;
    230 #endif
    231 
    232 	_fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
    233 
    234 #ifdef __STDC_ISO_10646__
    235 	nn = wcsnlen(*ppwcs, n) + 1;
    236 	owcskt = wcskt = (wchar_t *)malloc(nn * sizeof(*wcskt));
    237 	err0 = _citrus_wcs_unicode_to_kuten(_RUNE_LOCALE(loc), *ppwcs, wcskt, nn);
    238 	if (err0)
    239 		ret = -1;
    240 	else
    241 		err0 = _citrus_ctype_wcsrtombs(_ps_to_ctype(ps, loc), s, (const wchar_t **)(void *)&wcskt, n,
    242 					       _ps_to_private(ps), &ret);
    243 	if (wcskt == NULL)
    244 		*ppwcs = NULL;
    245 	else
    246 		*ppwcs += (wcskt - owcskt);
    247 	free(owcskt);
    248 #else /* ! __STDC_ISO_10646__ */
    249 	err0 = _citrus_ctype_wcsrtombs(_ps_to_ctype(ps, loc), s, ppwcs, n,
    250 				       _ps_to_private(ps), &ret);
    251 #endif /* ! __STDC_ISO_10646__ */
    252 	if (err0)
    253 		errno = err0;
    254 
    255 	return ret;
    256 }
    257 
    258 size_t
    259 wcsrtombs(char *s, const wchar_t **ppwcs, size_t n, mbstate_t *ps)
    260 {
    261 	return wcsrtombs_l(s, ppwcs, n, ps, _current_locale());
    262 }
    263 
    264 wint_t
    265 btowc_l(int c, locale_t loc)
    266 {
    267 	wint_t ret;
    268 	int err0;
    269 
    270 	err0 = _citrus_ctype_btowc(_CITRUS_CTYPE(loc), c, &ret);
    271 	if (err0) {
    272 		errno = err0;
    273 		return -1;
    274 	}
    275 
    276 	err0 = _citrus_kuten_to_unicode(_RUNE_LOCALE(loc), ret, &ret);
    277 	if (err0)
    278 		errno = err0;
    279 
    280 	return ret;
    281 }
    282 
    283 wint_t
    284 btowc(int c)
    285 {
    286 	return btowc_l(c, _current_locale());
    287 }
    288 
    289 int
    290 wctob_l(wint_t wc, locale_t loc)
    291 {
    292 	int ret;
    293 	int err0;
    294 
    295 	err0 = _citrus_unicode_to_kuten(_RUNE_LOCALE(loc), wc, &wc);
    296 	if (err0) {
    297 		errno = err0;
    298 		return -1;
    299 	}
    300 
    301 	err0 = _citrus_ctype_wctob(_CITRUS_CTYPE(loc), wc, &ret);
    302 	if (err0)
    303 		errno = err0;
    304 
    305 	return ret;
    306 }
    307 
    308 int
    309 wctob(wint_t wc)
    310 {
    311 	return wctob_l(wc, _current_locale());
    312 }
    313 
    314 size_t
    315 _mb_cur_max_l(locale_t loc)
    316 {
    317 
    318 	return _citrus_ctype_get_mb_cur_max(_CITRUS_CTYPE(loc));
    319 }
    320