Replace legacy make with bmake
[dragonfly.git] / lib / libc / citrus / citrus_ctype_template.h
CommitLineData
52347f71
HT
1/* $NetBSD: citrus_ctype_template.h,v 1.35 2008/02/09 14:56:20 junyoung Exp $ */
2/* $DragonFly: src/lib/libc/citrus/citrus_ctype_template.h,v 1.2 2008/04/10 10:21:01 hasso Exp $ */
2180e8af
JS
3
4
5/*-
6 * Copyright (c)2002 Citrus Project,
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31/*-
32 * Copyright (c) 1993
33 * The Regents of the University of California. All rights reserved.
34 *
35 * This code is derived from software contributed to Berkeley by
36 * Paul Borman at Krystal Technologies.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. Neither the name of the University nor the names of its contributors
47 * may be used to endorse or promote products derived from this software
48 * without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * SUCH DAMAGE.
61 */
62
63
64/*
65 * CAUTION: THIS IS NOT STANDALONE FILE
66 *
67 * function templates of ctype encoding handler for each encodings.
68 *
69 * you need to define the macros below:
70 *
71 * _FUNCNAME(method) :
72 * It should convine the real function name for the method.
73 * e.g. _FUNCNAME(mbrtowc) should be expanded to
74 * _EUC_ctype_mbrtowc
75 * for EUC locale.
76 *
77 * _CEI_TO_STATE(cei, method) :
78 * It should be expanded to the pointer of the method-internal state
79 * structures.
80 * e.g. _CEI_TO_STATE(cei, mbrtowc) might be expanded to
81 * (cei)->states.s_mbrtowc
82 * This structure may use if the function is called as
83 * mbrtowc(&wc, s, n, NULL);
84 * Such individual structures are needed by:
85 * mblen
86 * mbrlen
87 * mbrtowc
88 * mbtowc
89 * mbsrtowcs
90 * wcrtomb
91 * wcsrtombs
92 * wctomb
93 * These need to be keeped in the ctype encoding information structure,
94 * pointed by "cei".
95 *
96 * _ENCODING_INFO :
97 * It should be expanded to the name of the encoding information structure.
98 * e.g. For EUC encoding, this macro is expanded to _EUCInfo.
99 * Encoding information structure need to contain the common informations
100 * for the codeset.
101 *
102 * _ENCODING_STATE :
103 * It should be expanded to the name of the encoding state structure.
104 * e.g. For EUC encoding, this macro is expanded to _EUCState.
105 * Encoding state structure need to contain the context-dependent states,
106 * which are "unpacked-form" of mbstate_t type and keeped during sequent
107 * calls of mb/wc functions,
108 *
109 * _ENCODING_IS_STATE_DEPENDENT :
110 * If the encoding is state dependent, this should be expanded to
111 * non-zero integral value. Otherwise, 0.
112 *
113 * _STATE_NEEDS_EXPLICIT_INIT(ps) :
114 * some encodings, states needs some explicit initialization.
115 * (ie. initialization with memset isn't enough.)
116 * If the encoding state pointed by "ps" needs to be initialized
117 * explicitly, return non-zero. Otherwize, 0.
118 *
119 */
120
121
122/* prototypes */
123
124__BEGIN_DECLS
125static void _FUNCNAME(init_state)(_ENCODING_INFO * __restrict,
126 _ENCODING_STATE * __restrict);
127static void _FUNCNAME(pack_state)(_ENCODING_INFO * __restrict,
128 void * __restrict,
129 const _ENCODING_STATE * __restrict);
130static void _FUNCNAME(unpack_state)(_ENCODING_INFO * __restrict,
131 _ENCODING_STATE * __restrict,
132 const void * __restrict);
133#if _ENCODING_IS_STATE_DEPENDENT
134static int _FUNCNAME(put_state_reset)(_ENCODING_INFO * __restrict,
135 char * __restrict, size_t,
136 _ENCODING_STATE * __restrict,
137 size_t * __restrict);
138#endif
139
140/*
141 * standard form of mbrtowc_priv.
142 *
143 * note (differences from real mbrtowc):
144 * - 3rd parameter is not "const char *s" but "const char **s".
145 * after the call of the function, *s will point the first byte of
146 * the next character.
147 * - additional 4th parameter is the size of src buffer.
148 * - 5th parameter is unpacked encoding-dependent state structure.
149 * - additional 6th parameter is the storage to be stored
150 * the return value in the real mbrtowc context.
151 * - return value means "errno" in the real mbrtowc context.
152 */
153
154static int _FUNCNAME(mbrtowc_priv)(_ENCODING_INFO * __restrict,
155 wchar_t * __restrict,
156 const char ** __restrict,
157 size_t, _ENCODING_STATE * __restrict,
158 size_t * __restrict);
159
160/*
161 * standard form of wcrtomb_priv.
162 *
163 * note (differences from real wcrtomb):
164 * - additional 3th parameter is the size of src buffer.
165 * - 5th parameter is unpacked encoding-dependent state structure.
166 * - additional 6th parameter is the storage to be stored
167 * the return value in the real mbrtowc context.
168 * - return value means "errno" in the real wcrtomb context.
169 * - caller should ensure that 2nd parameter isn't NULL.
170 * (XXX inconsist with mbrtowc_priv)
171 */
172
173static int _FUNCNAME(wcrtomb_priv)(_ENCODING_INFO * __restrict,
174 char * __restrict, size_t, wchar_t,
175 _ENCODING_STATE * __restrict,
176 size_t * __restrict);
177__END_DECLS
178
179
180/*
181 * macros
182 */
183
184#define _TO_CEI(_cl_) ((_CTYPE_INFO*)(_cl_))
185
186
187/*
188 * templates
189 */
190
191/* internal routines */
192
193static __inline int
194_FUNCNAME(mbtowc_priv)(_ENCODING_INFO * __restrict ei,
195 wchar_t * __restrict pwc, const char * __restrict s,
196 size_t n, _ENCODING_STATE * __restrict psenc,
197 int * __restrict nresult)
198{
199 _ENCODING_STATE state;
200 size_t nr;
201 int err = 0;
202
203 _DIAGASSERT(ei != NULL);
204 _DIAGASSERT(psenc != NULL);
205
206 if (s == NULL) {
52347f71 207 _FUNCNAME(init_state)(ei, psenc);
2180e8af
JS
208 *nresult = _ENCODING_IS_STATE_DEPENDENT;
209 return (0);
210 }
211
212 state = *psenc;
213 err = _FUNCNAME(mbrtowc_priv)(ei, pwc, (const char **)&s, n, psenc, &nr);
52347f71
HT
214 if (nr == (size_t)-2)
215 err = EILSEQ;
2180e8af 216 if (err) {
52347f71 217 /* In error case, we should restore the state. */
2180e8af
JS
218 *psenc = state;
219 *nresult = -1;
52347f71 220 return (err);
2180e8af
JS
221 }
222
223 *nresult = (int)nr;
224
225 return (0);
226}
227
228static int
229_FUNCNAME(mbsrtowcs_priv)(_ENCODING_INFO * __restrict ei,
230 wchar_t * __restrict pwcs,
231 const char ** __restrict s,
232 size_t n, _ENCODING_STATE * __restrict psenc,
233 size_t * __restrict nresult)
234{
235 int err, cnt;
236 size_t siz;
237 const char *s0;
238 size_t mbcurmax;
239
240 _DIAGASSERT(nresult != 0);
241 _DIAGASSERT(ei != NULL);
242 _DIAGASSERT(psenc != NULL);
243 _DIAGASSERT(s == NULL);
244 _DIAGASSERT(*s == NULL);
245
246 /* if pwcs is NULL, ignore n */
247 if (pwcs == NULL)
248 n = 1; /* arbitrary >0 value */
249
250 err = cnt = 0;
251 s0 = *s; /* to keep *s unchanged for now, use copy instead. */
252 mbcurmax = _ENCODING_MB_CUR_MAX(ei);
253 while (n > 0) {
254 err = _FUNCNAME(mbrtowc_priv)(ei, pwcs, &s0, mbcurmax,
255 psenc, &siz);
256 if (siz == (size_t)-2)
257 err = EILSEQ;
258 if (err) {
259 cnt = -1;
260 goto bye;
261 }
262 switch (siz) {
263 case 0:
264 if (pwcs) {
265 _FUNCNAME(init_state)(ei, psenc);
266 }
267 s0 = 0;
268 goto bye;
269 default:
270 if (pwcs) {
271 pwcs++;
272 n--;
273 }
274 cnt++;
275 break;
276 }
277 }
278bye:
279 if (pwcs)
280 *s = s0;
281
282 *nresult = (size_t)cnt;
283
284 return err;
285}
286
287
288static int
289_FUNCNAME(wcsrtombs_priv)(_ENCODING_INFO * __restrict ei, char * __restrict s,
290 const wchar_t ** __restrict pwcs,
291 size_t n, _ENCODING_STATE * __restrict psenc,
292 size_t * __restrict nresult)
293{
294 int cnt = 0, err;
295 char buf[MB_LEN_MAX];
296 size_t siz;
297 const wchar_t* pwcs0;
298#if _ENCODING_IS_STATE_DEPENDENT
299 _ENCODING_STATE state;
300#endif
301
302 pwcs0 = *pwcs;
303
304 if (!s)
305 n = 1;
306
307 while (n > 0) {
308#if _ENCODING_IS_STATE_DEPENDENT
309 state = *psenc;
310#endif
311 err = _FUNCNAME(wcrtomb_priv)(ei, buf, sizeof(buf),
312 *pwcs0, psenc, &siz);
313 if (siz == (size_t)-1) {
314 *nresult = siz;
315 return (err);
316 }
317
318 if (s) {
319 if (n < siz) {
320#if _ENCODING_IS_STATE_DEPENDENT
321 *psenc = state;
322#endif
323 break;
324 }
325 memcpy(s, buf, siz);
326 s += siz;
327 n -= siz;
328 }
329 cnt += siz;
330 if (!*pwcs0) {
331 if (s) {
332 _FUNCNAME(init_state)(ei, psenc);
333 }
334 pwcs0 = 0;
335 cnt--; /* don't include terminating null */
336 break;
337 }
338 pwcs0++;
339 }
340 if (s)
341 *pwcs = pwcs0;
342
343 *nresult = (size_t)cnt;
344 return (0);
345}
346
347
348/* ----------------------------------------------------------------------
349 * templates for public functions
350 */
351
352#define _RESTART_BEGIN(_func_, _cei_, _pspriv_, _pse_) \
353do { \
354 _ENCODING_STATE _state; \
355 do { \
356 if (_pspriv_ == NULL) { \
357 _pse_ = &_CEI_TO_STATE(_cei_, _func_); \
358 if (_STATE_NEEDS_EXPLICIT_INIT(_pse_)) \
359 _FUNCNAME(init_state)(_CEI_TO_EI(_cei_), \
360 (_pse_)); \
361 } else { \
362 _pse_ = &_state; \
363 _FUNCNAME(unpack_state)(_CEI_TO_EI(_cei_), \
364 _pse_, _pspriv_); \
365 } \
366 } while (/*CONSTCOND*/0)
367
368#define _RESTART_END(_func_, _cei_, _pspriv_, _pse_) \
369 if (_pspriv_ != NULL) { \
370 _FUNCNAME(pack_state)(_CEI_TO_EI(_cei_), _pspriv_, \
371 _pse_); \
372 } \
373} while (/*CONSTCOND*/0)
374
375int
376_FUNCNAME(ctype_getops)(_citrus_ctype_ops_rec_t *ops, size_t lenops,
377 uint32_t expected_version)
378{
379 if (expected_version<_CITRUS_CTYPE_ABI_VERSION || lenops<sizeof(*ops))
380 return (EINVAL);
381
382 memcpy(ops, &_FUNCNAME(ctype_ops), sizeof(_FUNCNAME(ctype_ops)));
383
384 return (0);
385}
386
387static int
388_FUNCNAME(ctype_init)(void ** __restrict cl,
389 void * __restrict var, size_t lenvar, size_t lenps)
390{
391 _CTYPE_INFO *cei;
392
393 _DIAGASSERT(cl != NULL);
394
395 /* sanity check to avoid overruns */
396 if (sizeof(_ENCODING_STATE) > lenps)
397 return (EINVAL);
398
399 cei = calloc(1, sizeof(_CTYPE_INFO));
400 if (cei == NULL)
401 return (ENOMEM);
402
403 *cl = (void *)cei;
404
405 return _FUNCNAME(encoding_module_init)(_CEI_TO_EI(cei), var, lenvar);
406}
407
408static void
409_FUNCNAME(ctype_uninit)(void *cl)
410{
411 if (cl) {
412 _FUNCNAME(encoding_module_uninit)(_CEI_TO_EI(_TO_CEI(cl)));
413 free(cl);
414 }
415}
416
417static unsigned
418/*ARGSUSED*/
419_FUNCNAME(ctype_get_mb_cur_max)(void *cl)
420{
421 return _ENCODING_MB_CUR_MAX(_CEI_TO_EI(_TO_CEI(cl)));
422}
423
424static int
425_FUNCNAME(ctype_mblen)(void * __restrict cl,
426 const char * __restrict s, size_t n,
427 int * __restrict nresult)
428{
429 _ENCODING_STATE *psenc;
430 _ENCODING_INFO *ei;
431
432 _DIAGASSERT(cl != NULL);
433
434 psenc = &_CEI_TO_STATE(_TO_CEI(cl), mblen);
435 ei = _CEI_TO_EI(_TO_CEI(cl));
436 if (_STATE_NEEDS_EXPLICIT_INIT(psenc))
437 _FUNCNAME(init_state)(ei, psenc);
438 return _FUNCNAME(mbtowc_priv)(ei, NULL, s, n, psenc, nresult);
439}
440
441static int
442_FUNCNAME(ctype_mbrlen)(void * __restrict cl, const char * __restrict s,
443 size_t n, void * __restrict pspriv,
444 size_t * __restrict nresult)
445{
446 _ENCODING_STATE *psenc;
447 _ENCODING_INFO *ei;
448 int err = 0;
449
450 _DIAGASSERT(cl != NULL);
451
452 ei = _CEI_TO_EI(_TO_CEI(cl));
453 _RESTART_BEGIN(mbrlen, _TO_CEI(cl), pspriv, psenc);
454 if (s == NULL) {
455 _FUNCNAME(init_state)(ei, psenc);
456 *nresult = 0;
457 } else {
458 err = _FUNCNAME(mbrtowc_priv)(ei, NULL, (const char **)&s, n,
459 (void *)psenc, nresult);
460 }
461 _RESTART_END(mbrlen, _TO_CEI(cl), pspriv, psenc);
462
463 return (err);
464}
465
466static int
467_FUNCNAME(ctype_mbrtowc)(void * __restrict cl, wchar_t * __restrict pwc,
468 const char * __restrict s, size_t n,
469 void * __restrict pspriv, size_t * __restrict nresult)
470{
471 _ENCODING_STATE *psenc;
472 _ENCODING_INFO *ei;
473 int err = 0;
474
475 _DIAGASSERT(cl != NULL);
476
477 ei = _CEI_TO_EI(_TO_CEI(cl));
478 _RESTART_BEGIN(mbrtowc, _TO_CEI(cl), pspriv, psenc);
479 if (s == NULL) {
480 _FUNCNAME(init_state)(ei, psenc);
481 *nresult = 0;
482 } else {
483 err = _FUNCNAME(mbrtowc_priv)(ei, pwc, (const char **)&s, n,
484 (void *)psenc, nresult);
485 }
486 _RESTART_END(mbrtowc, _TO_CEI(cl), pspriv, psenc);
487
488 return (err);
489}
490
491static int
492/*ARGSUSED*/
493_FUNCNAME(ctype_mbsinit)(void * __restrict cl, const void * __restrict pspriv,
494 int * __restrict nresult)
495{
496 _ENCODING_STATE state;
497
498 if (pspriv == NULL) {
499 *nresult = 1;
500 return (0);
501 }
502
503 _FUNCNAME(unpack_state)(_CEI_TO_EI(_TO_CEI(cl)), &state, pspriv);
504
505 *nresult = (state.chlen == 0); /* XXX: FIXME */
506
507 return (0);
508}
509
510static int
511_FUNCNAME(ctype_mbsrtowcs)(void * __restrict cl, wchar_t * __restrict pwcs,
512 const char ** __restrict s, size_t n,
513 void * __restrict pspriv,
514 size_t * __restrict nresult)
515{
516 _ENCODING_STATE *psenc;
517 _ENCODING_INFO *ei;
518 int err = 0;
519
520 _DIAGASSERT(cl != NULL);
521
522 ei = _CEI_TO_EI(_TO_CEI(cl));
523 _RESTART_BEGIN(mbsrtowcs, _TO_CEI(cl), pspriv, psenc);
524 err = _FUNCNAME(mbsrtowcs_priv)(ei, pwcs, s, n, psenc, nresult);
525 _RESTART_END(mbsrtowcs, _TO_CEI(cl), pspriv, psenc);
526
527 return (err);
528}
529
530static int
531_FUNCNAME(ctype_mbstowcs)(void * __restrict cl, wchar_t * __restrict pwcs,
532 const char * __restrict s, size_t n,
533 size_t * __restrict nresult)
534{
535 int err;
536 _ENCODING_STATE state;
537 _ENCODING_INFO *ei;
538
539 _DIAGASSERT(cl != NULL);
540
541 ei = _CEI_TO_EI(_TO_CEI(cl));
542 _FUNCNAME(init_state)(ei, &state);
543 err = _FUNCNAME(mbsrtowcs_priv)(ei, pwcs, (const char **)&s, n,
544 &state, nresult);
545 if (*nresult == (size_t)-2) {
546 err = EILSEQ;
547 *nresult = (size_t)-1;
548 }
549
550 return (err);
551}
552
553static int
554_FUNCNAME(ctype_mbtowc)(void * __restrict cl, wchar_t * __restrict pwc,
555 const char * __restrict s, size_t n,
556 int * __restrict nresult)
557{
558 _ENCODING_STATE *psenc;
559 _ENCODING_INFO *ei;
560
561 _DIAGASSERT(cl != NULL);
562
563 psenc = &_CEI_TO_STATE(_TO_CEI(cl), mbtowc);
564 ei = _CEI_TO_EI(_TO_CEI(cl));
565 if (_STATE_NEEDS_EXPLICIT_INIT(psenc))
566 _FUNCNAME(init_state)(ei, psenc);
567 return _FUNCNAME(mbtowc_priv)(ei, pwc, s, n, psenc, nresult);
568}
569
570static int
571_FUNCNAME(ctype_wcrtomb)(void * __restrict cl, char * __restrict s, wchar_t wc,
572 void * __restrict pspriv, size_t * __restrict nresult)
573{
574 _ENCODING_STATE *psenc;
575 char buf[MB_LEN_MAX];
576 int err = 0;
577 size_t sz;
578#if _ENCODING_IS_STATE_DEPENDENT
579 size_t rsz = 0;
580#endif
581
582 _DIAGASSERT(cl != NULL);
583
584 if (s == NULL) {
585 /*
586 * use internal buffer.
587 */
588 s = buf;
589 wc = L'\0'; /* SUSv3 */
590 }
591
592 _RESTART_BEGIN(wcrtomb, _TO_CEI(cl), pspriv, psenc);
593 sz = _ENCODING_MB_CUR_MAX(_CEI_TO_EI(_TO_CEI(cl)));
594#if _ENCODING_IS_STATE_DEPENDENT
595 if (wc == L'\0') {
596 /* reset state */
597 err = _FUNCNAME(put_state_reset)(_CEI_TO_EI(_TO_CEI(cl)), s,
598 sz, psenc, &rsz);
599 if (err) {
600 *nresult = -1;
601 goto quit;
602 }
603 s += rsz;
604 sz -= rsz;
605 }
606#endif
607 err = _FUNCNAME(wcrtomb_priv)(_CEI_TO_EI(_TO_CEI(cl)), s, sz,
608 wc, psenc, nresult);
609#if _ENCODING_IS_STATE_DEPENDENT
610 if (err == 0)
611 *nresult += rsz;
612quit:
613#endif
614 if (err == E2BIG)
615 err = EINVAL;
616 _RESTART_END(wcrtomb, _TO_CEI(cl), pspriv, psenc);
617
618 return err;
619}
620
621static int
622/*ARGSUSED*/
623_FUNCNAME(ctype_wcsrtombs)(void * __restrict cl, char * __restrict s,
624 const wchar_t ** __restrict pwcs, size_t n,
625 void * __restrict pspriv,
626 size_t * __restrict nresult)
627{
628 _ENCODING_STATE *psenc;
629 _ENCODING_INFO *ei;
630 int err = 0;
631
632 _DIAGASSERT(cl != NULL);
633
634 ei = _CEI_TO_EI(_TO_CEI(cl));
635 _RESTART_BEGIN(wcsrtombs, _TO_CEI(cl), pspriv, psenc);
636 err = _FUNCNAME(wcsrtombs_priv)(ei, s, pwcs, n, psenc, nresult);
637 _RESTART_END(wcsrtombs, _TO_CEI(cl), pspriv, psenc);
638
639 return err;
640}
641
642static int
643/*ARGSUSED*/
644_FUNCNAME(ctype_wcstombs)(void * __restrict cl, char * __restrict s,
645 const wchar_t * __restrict pwcs, size_t n,
646 size_t * __restrict nresult)
647{
648 _ENCODING_STATE state;
649 _ENCODING_INFO *ei;
650 int err;
651
652 _DIAGASSERT(cl != NULL);
653
654 ei = _CEI_TO_EI(_TO_CEI(cl));
655 _FUNCNAME(init_state)(ei, &state);
656 err = _FUNCNAME(wcsrtombs_priv)(ei, s, (const wchar_t **)&pwcs, n,
657 &state, nresult);
658
659 return err;
660}
661
662static int
663_FUNCNAME(ctype_wctomb)(void * __restrict cl, char * __restrict s, wchar_t wc,
664 int * __restrict nresult)
665{
666 _ENCODING_STATE *psenc;
667 _ENCODING_INFO *ei;
668 size_t nr, sz;
669#if _ENCODING_IS_STATE_DEPENDENT
670 size_t rsz = 0;
671#endif
672 int err = 0;
673
674 _DIAGASSERT(cl != NULL);
675
676 ei = _CEI_TO_EI(_TO_CEI(cl));
677 psenc = &_CEI_TO_STATE(_TO_CEI(cl), wctomb);
678 if (_STATE_NEEDS_EXPLICIT_INIT(psenc))
679 _FUNCNAME(init_state)(ei, psenc);
680 if (s == NULL) {
681 _FUNCNAME(init_state)(ei, psenc);
682 *nresult = _ENCODING_IS_STATE_DEPENDENT;
683 return 0;
684 }
685 sz = _ENCODING_MB_CUR_MAX(_CEI_TO_EI(_TO_CEI(cl)));
686#if _ENCODING_IS_STATE_DEPENDENT
687 if (wc == L'\0') {
688 /* reset state */
689 err = _FUNCNAME(put_state_reset)(_CEI_TO_EI(_TO_CEI(cl)), s,
690 sz, psenc, &rsz);
691 if (err) {
692 *nresult = -1; /* XXX */
693 return 0;
694 }
695 s += rsz;
696 sz -= rsz;
697 }
698#endif
699 err = _FUNCNAME(wcrtomb_priv)(ei, s, sz, wc, psenc, &nr);
700#if _ENCODING_IS_STATE_DEPENDENT
701 if (err == 0)
702 *nresult = (int)(nr + rsz);
703 else
704#endif
705 *nresult = (int)nr;
706
707 return 0;
708}
709
710static int
711/*ARGSUSED*/
712_FUNCNAME(ctype_btowc)(_citrus_ctype_rec_t * __restrict cc,
713 int c, wint_t * __restrict wcresult)
714{
715 _ENCODING_STATE state;
716 _ENCODING_INFO *ei;
717 char mb;
718 char const *s;
719 wchar_t wc;
720 size_t nr;
721 int err;
722
723 _DIAGASSERT(cc != NULL && cc->cc_closure != NULL);
724
725 if (c == EOF) {
726 *wcresult = WEOF;
727 return 0;
728 }
729 ei = _CEI_TO_EI(_TO_CEI(cc->cc_closure));
730 _FUNCNAME(init_state)(ei, &state);
731 mb = (char)(unsigned)c;
732 s = &mb;
733 err = _FUNCNAME(mbrtowc_priv)(ei, &wc, &s, 1, &state, &nr);
734 if (!err && (nr == 0 || nr == 1))
735 *wcresult = (wint_t)wc;
736 else
737 *wcresult = WEOF;
738
739 return 0;
740}
741
742static int
743/*ARGSUSED*/
744_FUNCNAME(ctype_wctob)(_citrus_ctype_rec_t * __restrict cc,
745 wint_t wc, int * __restrict cresult)
746{
747 _ENCODING_STATE state;
748 _ENCODING_INFO *ei;
749 char buf[MB_LEN_MAX];
750 size_t nr;
751 int err;
752
753 _DIAGASSERT(cc != NULL && cc->cc_closure != NULL);
754
755 if (wc == WEOF) {
756 *cresult = EOF;
757 return 0;
758 }
759 ei = _CEI_TO_EI(_TO_CEI(cc->cc_closure));
760 _FUNCNAME(init_state)(ei, &state);
761 err = _FUNCNAME(wcrtomb_priv)(ei, buf, _ENCODING_MB_CUR_MAX(ei),
762 (wchar_t)wc, &state, &nr);
763 if (!err && nr == 1)
764 *cresult = buf[0];
765 else
766 *cresult = EOF;
767
768 return 0;
769}