Add nfe(4)
[dragonfly.git] / lib / libc / citrus / citrus_ctype_template.h
blob9231958113ab56c3dbe00305a94f99f6a48cd7a6
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 $ */
5 /*-
6 * Copyright (c)2002 Citrus Project,
7 * All rights reserved.
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.
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.
31 /*-
32 * Copyright (c) 1993
33 * The Regents of the University of California. All rights reserved.
35 * This code is derived from software contributed to Berkeley by
36 * Paul Borman at Krystal Technologies.
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.
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.
65 * CAUTION: THIS IS NOT STANDALONE FILE
67 * function templates of ctype encoding handler for each encodings.
69 * you need to define the macros below:
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.
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".
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.
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,
109 * _ENCODING_IS_STATE_DEPENDENT :
110 * If the encoding is state dependent, this should be expanded to
111 * non-zero integral value. Otherwise, 0.
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.
122 /* prototypes */
124 __BEGIN_DECLS
125 static void _FUNCNAME(init_state)(_ENCODING_INFO * __restrict,
126 _ENCODING_STATE * __restrict);
127 static void _FUNCNAME(pack_state)(_ENCODING_INFO * __restrict,
128 void * __restrict,
129 const _ENCODING_STATE * __restrict);
130 static void _FUNCNAME(unpack_state)(_ENCODING_INFO * __restrict,
131 _ENCODING_STATE * __restrict,
132 const void * __restrict);
133 #if _ENCODING_IS_STATE_DEPENDENT
134 static int _FUNCNAME(put_state_reset)(_ENCODING_INFO * __restrict,
135 char * __restrict, size_t,
136 _ENCODING_STATE * __restrict,
137 size_t * __restrict);
138 #endif
141 * standard form of mbrtowc_priv.
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.
154 static 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);
161 * standard form of wcrtomb_priv.
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)
173 static 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
181 * macros
184 #define _TO_CEI(_cl_) ((_CTYPE_INFO*)(_cl_))
188 * templates
191 /* internal routines */
193 static __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)
199 _ENCODING_STATE state;
200 size_t nr;
201 int err = 0;
203 _DIAGASSERT(ei != NULL);
204 _DIAGASSERT(psenc != NULL);
206 if (s == NULL) {
207 _FUNCNAME(init_state)(ei, psenc);
208 *nresult = _ENCODING_IS_STATE_DEPENDENT;
209 return (0);
212 state = *psenc;
213 err = _FUNCNAME(mbrtowc_priv)(ei, pwc, (const char **)&s, n, psenc, &nr);
214 if (nr == (size_t)-2)
215 err = EILSEQ;
216 if (err) {
217 /* In error case, we should restore the state. */
218 *psenc = state;
219 *nresult = -1;
220 return (err);
223 *nresult = (int)nr;
225 return (0);
228 static 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)
235 int err, cnt;
236 size_t siz;
237 const char *s0;
238 size_t mbcurmax;
240 _DIAGASSERT(nresult != 0);
241 _DIAGASSERT(ei != NULL);
242 _DIAGASSERT(psenc != NULL);
243 _DIAGASSERT(s == NULL);
244 _DIAGASSERT(*s == NULL);
246 /* if pwcs is NULL, ignore n */
247 if (pwcs == NULL)
248 n = 1; /* arbitrary >0 value */
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;
262 switch (siz) {
263 case 0:
264 if (pwcs) {
265 _FUNCNAME(init_state)(ei, psenc);
267 s0 = 0;
268 goto bye;
269 default:
270 if (pwcs) {
271 pwcs++;
272 n--;
274 cnt++;
275 break;
278 bye:
279 if (pwcs)
280 *s = s0;
282 *nresult = (size_t)cnt;
284 return err;
288 static 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)
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
302 pwcs0 = *pwcs;
304 if (!s)
305 n = 1;
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);
318 if (s) {
319 if (n < siz) {
320 #if _ENCODING_IS_STATE_DEPENDENT
321 *psenc = state;
322 #endif
323 break;
325 memcpy(s, buf, siz);
326 s += siz;
327 n -= siz;
329 cnt += siz;
330 if (!*pwcs0) {
331 if (s) {
332 _FUNCNAME(init_state)(ei, psenc);
334 pwcs0 = 0;
335 cnt--; /* don't include terminating null */
336 break;
338 pwcs0++;
340 if (s)
341 *pwcs = pwcs0;
343 *nresult = (size_t)cnt;
344 return (0);
348 /* ----------------------------------------------------------------------
349 * templates for public functions
352 #define _RESTART_BEGIN(_func_, _cei_, _pspriv_, _pse_) \
353 do { \
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_); \
366 } while (/*CONSTCOND*/0)
368 #define _RESTART_END(_func_, _cei_, _pspriv_, _pse_) \
369 if (_pspriv_ != NULL) { \
370 _FUNCNAME(pack_state)(_CEI_TO_EI(_cei_), _pspriv_, \
371 _pse_); \
373 } while (/*CONSTCOND*/0)
376 _FUNCNAME(ctype_getops)(_citrus_ctype_ops_rec_t *ops, size_t lenops,
377 uint32_t expected_version)
379 if (expected_version<_CITRUS_CTYPE_ABI_VERSION || lenops<sizeof(*ops))
380 return (EINVAL);
382 memcpy(ops, &_FUNCNAME(ctype_ops), sizeof(_FUNCNAME(ctype_ops)));
384 return (0);
387 static int
388 _FUNCNAME(ctype_init)(void ** __restrict cl,
389 void * __restrict var, size_t lenvar, size_t lenps)
391 _CTYPE_INFO *cei;
393 _DIAGASSERT(cl != NULL);
395 /* sanity check to avoid overruns */
396 if (sizeof(_ENCODING_STATE) > lenps)
397 return (EINVAL);
399 cei = calloc(1, sizeof(_CTYPE_INFO));
400 if (cei == NULL)
401 return (ENOMEM);
403 *cl = (void *)cei;
405 return _FUNCNAME(encoding_module_init)(_CEI_TO_EI(cei), var, lenvar);
408 static void
409 _FUNCNAME(ctype_uninit)(void *cl)
411 if (cl) {
412 _FUNCNAME(encoding_module_uninit)(_CEI_TO_EI(_TO_CEI(cl)));
413 free(cl);
417 static unsigned
418 /*ARGSUSED*/
419 _FUNCNAME(ctype_get_mb_cur_max)(void *cl)
421 return _ENCODING_MB_CUR_MAX(_CEI_TO_EI(_TO_CEI(cl)));
424 static int
425 _FUNCNAME(ctype_mblen)(void * __restrict cl,
426 const char * __restrict s, size_t n,
427 int * __restrict nresult)
429 _ENCODING_STATE *psenc;
430 _ENCODING_INFO *ei;
432 _DIAGASSERT(cl != NULL);
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);
441 static int
442 _FUNCNAME(ctype_mbrlen)(void * __restrict cl, const char * __restrict s,
443 size_t n, void * __restrict pspriv,
444 size_t * __restrict nresult)
446 _ENCODING_STATE *psenc;
447 _ENCODING_INFO *ei;
448 int err = 0;
450 _DIAGASSERT(cl != NULL);
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);
461 _RESTART_END(mbrlen, _TO_CEI(cl), pspriv, psenc);
463 return (err);
466 static 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)
471 _ENCODING_STATE *psenc;
472 _ENCODING_INFO *ei;
473 int err = 0;
475 _DIAGASSERT(cl != NULL);
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);
486 _RESTART_END(mbrtowc, _TO_CEI(cl), pspriv, psenc);
488 return (err);
491 static int
492 /*ARGSUSED*/
493 _FUNCNAME(ctype_mbsinit)(void * __restrict cl, const void * __restrict pspriv,
494 int * __restrict nresult)
496 _ENCODING_STATE state;
498 if (pspriv == NULL) {
499 *nresult = 1;
500 return (0);
503 _FUNCNAME(unpack_state)(_CEI_TO_EI(_TO_CEI(cl)), &state, pspriv);
505 *nresult = (state.chlen == 0); /* XXX: FIXME */
507 return (0);
510 static 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)
516 _ENCODING_STATE *psenc;
517 _ENCODING_INFO *ei;
518 int err = 0;
520 _DIAGASSERT(cl != NULL);
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);
527 return (err);
530 static 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)
535 int err;
536 _ENCODING_STATE state;
537 _ENCODING_INFO *ei;
539 _DIAGASSERT(cl != NULL);
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;
550 return (err);
553 static int
554 _FUNCNAME(ctype_mbtowc)(void * __restrict cl, wchar_t * __restrict pwc,
555 const char * __restrict s, size_t n,
556 int * __restrict nresult)
558 _ENCODING_STATE *psenc;
559 _ENCODING_INFO *ei;
561 _DIAGASSERT(cl != NULL);
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);
570 static int
571 _FUNCNAME(ctype_wcrtomb)(void * __restrict cl, char * __restrict s, wchar_t wc,
572 void * __restrict pspriv, size_t * __restrict nresult)
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
582 _DIAGASSERT(cl != NULL);
584 if (s == NULL) {
586 * use internal buffer.
588 s = buf;
589 wc = L'\0'; /* SUSv3 */
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;
603 s += rsz;
604 sz -= rsz;
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;
612 quit:
613 #endif
614 if (err == E2BIG)
615 err = EINVAL;
616 _RESTART_END(wcrtomb, _TO_CEI(cl), pspriv, psenc);
618 return err;
621 static 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)
628 _ENCODING_STATE *psenc;
629 _ENCODING_INFO *ei;
630 int err = 0;
632 _DIAGASSERT(cl != NULL);
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);
639 return err;
642 static 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)
648 _ENCODING_STATE state;
649 _ENCODING_INFO *ei;
650 int err;
652 _DIAGASSERT(cl != NULL);
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);
659 return err;
662 static int
663 _FUNCNAME(ctype_wctomb)(void * __restrict cl, char * __restrict s, wchar_t wc,
664 int * __restrict nresult)
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;
674 _DIAGASSERT(cl != NULL);
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;
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;
695 s += rsz;
696 sz -= rsz;
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;
707 return 0;
710 static int
711 /*ARGSUSED*/
712 _FUNCNAME(ctype_btowc)(_citrus_ctype_rec_t * __restrict cc,
713 int c, wint_t * __restrict wcresult)
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;
723 _DIAGASSERT(cc != NULL && cc->cc_closure != NULL);
725 if (c == EOF) {
726 *wcresult = WEOF;
727 return 0;
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;
739 return 0;
742 static int
743 /*ARGSUSED*/
744 _FUNCNAME(ctype_wctob)(_citrus_ctype_rec_t * __restrict cc,
745 wint_t wc, int * __restrict cresult)
747 _ENCODING_STATE state;
748 _ENCODING_INFO *ei;
749 char buf[MB_LEN_MAX];
750 size_t nr;
751 int err;
753 _DIAGASSERT(cc != NULL && cc->cc_closure != NULL);
755 if (wc == WEOF) {
756 *cresult = EOF;
757 return 0;
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;
768 return 0;