1/*	$NetBSD: multibyte_amd1.c,v 1.13 2013/05/28 16:57:56 joerg 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.13 2013/05/28 16:57:56 joerg 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 "multibyte.h"
49
50size_t
51mbrlen_l(const char *s, size_t n, mbstate_t *ps, locale_t loc)
52{
53	size_t ret;
54	int err0;
55
56	_fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
57
58	err0 = _citrus_ctype_mbrlen(_ps_to_ctype(ps, loc), s, n,
59				     _ps_to_private(ps), &ret);
60	if (err0)
61		errno = err0;
62
63	return ret;
64}
65
66size_t
67mbrlen(const char *s, size_t n, mbstate_t *ps)
68{
69	return mbrlen_l(s, n, ps, _current_locale());
70}
71
72int
73mbsinit_l(const mbstate_t *ps, locale_t loc)
74{
75	int ret;
76	int err0;
77	_RuneLocale *rl;
78
79	if (ps == NULL)
80		return 1;
81
82	if (_ps_to_runelocale(ps) == NULL)
83		rl = _RUNE_LOCALE(loc);
84	else
85		rl = _ps_to_runelocale(ps);
86
87	/* mbsinit should cause no error... */
88	err0 = _citrus_ctype_mbsinit(rl->rl_citrus_ctype,
89				      _ps_to_private_const(ps), &ret);
90	if (err0)
91		errno = err0;
92
93	return ret;
94}
95
96int
97mbsinit(const mbstate_t *ps)
98{
99	return mbsinit_l(ps, _current_locale());
100}
101
102size_t
103mbrtowc_l(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps, locale_t loc)
104{
105	size_t ret;
106	int err0;
107
108	_fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
109
110	err0 = _citrus_ctype_mbrtowc(_ps_to_ctype(ps, loc), pwc, s, n,
111				      _ps_to_private(ps), &ret);
112	if (err0)
113		errno = err0;
114
115	return ret;
116}
117
118size_t
119mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
120{
121	return mbrtowc_l(pwc, s, n, ps, _current_locale());
122}
123
124size_t
125mbsrtowcs_l(wchar_t *pwcs, const char **s, size_t n, mbstate_t *ps,
126    locale_t loc)
127{
128	size_t ret;
129	int err0;
130
131	_fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
132
133	err0 = _citrus_ctype_mbsrtowcs(_ps_to_ctype(ps, loc), pwcs, s, n,
134					_ps_to_private(ps), &ret);
135	if (err0)
136		errno = err0;
137
138	return ret;
139}
140
141size_t
142mbsrtowcs(wchar_t *pwcs, const char **s, size_t n, mbstate_t *ps)
143{
144	return mbsrtowcs_l(pwcs, s, n, ps, _current_locale());
145}
146
147size_t
148mbsnrtowcs_l(wchar_t *pwcs, const char **s, size_t in, size_t n, mbstate_t *ps,
149    locale_t loc)
150{
151	size_t ret;
152	int err0;
153
154	_fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
155
156	err0 = _citrus_ctype_mbsnrtowcs(_ps_to_ctype(ps, loc), pwcs, s, in, n,
157					_ps_to_private(ps), &ret);
158	if (err0)
159		errno = err0;
160
161	return ret;
162}
163
164size_t
165mbsnrtowcs(wchar_t *pwcs, const char **s, size_t in, size_t n, mbstate_t *ps)
166{
167	return mbsnrtowcs_l(pwcs, s, in, n, ps, _current_locale());
168}
169
170size_t
171wcrtomb_l(char *s, wchar_t wc, mbstate_t *ps, locale_t loc)
172{
173	size_t ret;
174	int err0;
175
176	_fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
177
178	err0 = _citrus_ctype_wcrtomb(_ps_to_ctype(ps, loc), s, wc,
179				       _ps_to_private(ps), &ret);
180	if (err0)
181		errno = err0;
182
183	return ret;
184}
185
186size_t
187wcrtomb(char *s, wchar_t wc, mbstate_t *ps)
188{
189	return wcrtomb_l(s, wc, ps, _current_locale());
190}
191
192size_t
193wcsrtombs_l(char *s, const wchar_t **ppwcs, size_t n, mbstate_t *ps,
194    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_ctype_wcsrtombs(_ps_to_ctype(ps, loc), s, ppwcs, n,
202					_ps_to_private(ps), &ret);
203	if (err0)
204		errno = err0;
205
206	return ret;
207}
208
209size_t
210wcsrtombs(char *s, const wchar_t **ppwcs, size_t n, mbstate_t *ps)
211{
212	return wcsrtombs_l(s, ppwcs, n, ps, _current_locale());
213}
214
215wint_t
216btowc_l(int c, locale_t loc)
217{
218	wint_t ret;
219	int err0;
220
221	err0 = _citrus_ctype_btowc(_CITRUS_CTYPE(loc), c, &ret);
222	if (err0)
223		errno = err0;
224
225	return ret;
226}
227
228wint_t
229btowc(int c)
230{
231	return btowc_l(c, _current_locale());
232}
233
234int
235wctob_l(wint_t wc, locale_t loc)
236{
237	int ret;
238	int err0;
239
240	err0 = _citrus_ctype_wctob(_CITRUS_CTYPE(loc), wc, &ret);
241	if (err0)
242		errno = err0;
243
244	return ret;
245}
246
247int
248wctob(wint_t wc)
249{
250	return wctob_l(wc, _current_locale());
251}
252
253size_t
254_mb_cur_max_l(locale_t loc)
255{
256
257	return _citrus_ctype_get_mb_cur_max(_CITRUS_CTYPE(loc));
258}
259