1 /* $NetBSD: src/lib/libc/citrus/citrus_ctype_template.h,v 1.32 2005/03/05 17:31:03 tnozaki Exp $ */
2 /* $DragonFly: src/lib/libc/citrus/citrus_ctype_template.h,v 1.1 2005/03/11 23:33:53 joerg Exp $ */
6 * Copyright (c)2002 Citrus Project,
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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
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
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
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:
72 * It should convine the real function name for the method.
73 * e.g. _FUNCNAME(mbrtowc) should be expanded to
77 * _CEI_TO_STATE(cei, method) :
78 * It should be expanded to the pointer of the method-internal state
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:
93 * These need to be keeped in the ctype encoding information structure,
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
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.
125 static void _FUNCNAME(init_state)(_ENCODING_INFO * __restrict,
126 _ENCODING_STATE * __restrict);
127 static void _FUNCNAME(pack_state)(_ENCODING_INFO * __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);
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);
184 #define _TO_CEI(_cl_) ((_CTYPE_INFO*)(_cl_))
191 /* internal routines */
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;
203 _DIAGASSERT(ei != NULL);
204 _DIAGASSERT(psenc != NULL);
207 *nresult = _ENCODING_IS_STATE_DEPENDENT;
212 err = _FUNCNAME(mbrtowc_priv)(ei, pwc, (const char **)&s, n, psenc, &nr);
217 if (nr == (size_t)-2) {
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)
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 */
248 n = 1; /* arbitrary >0 value */
251 s0 = *s; /* to keep *s unchanged for now, use copy instead. */
252 mbcurmax = _ENCODING_MB_CUR_MAX(ei);
254 err = _FUNCNAME(mbrtowc_priv)(ei, pwcs, &s0, mbcurmax,
256 if (siz == (size_t)-2)
265 _FUNCNAME(init_state)(ei, psenc);
282 *nresult = (size_t)cnt;
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)
295 char buf[MB_LEN_MAX];
297 const wchar_t* pwcs0;
298 #if _ENCODING_IS_STATE_DEPENDENT
299 _ENCODING_STATE state;
308 #if _ENCODING_IS_STATE_DEPENDENT
311 err = _FUNCNAME(wcrtomb_priv)(ei, buf, sizeof(buf),
312 *pwcs0, psenc, &siz);
313 if (siz == (size_t)-1) {
320 #if _ENCODING_IS_STATE_DEPENDENT
332 _FUNCNAME(init_state)(ei, psenc);
335 cnt--; /* don't include terminating null */
343 *nresult = (size_t)cnt;
348 /* ----------------------------------------------------------------------
349 * templates for public functions
352 #define _RESTART_BEGIN(_func_, _cei_, _pspriv_, _pse_) \
354 _ENCODING_STATE _state; \
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_), \
363 _FUNCNAME(unpack_state)(_CEI_TO_EI(_cei_), \
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_, \
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))
382 memcpy(ops, &_FUNCNAME(ctype_ops), sizeof(_FUNCNAME(ctype_ops)));
388 _FUNCNAME(ctype_init)(void ** __restrict cl,
389 void * __restrict var, size_t lenvar, size_t lenps)
393 _DIAGASSERT(cl != NULL);
395 /* sanity check to avoid overruns */
396 if (sizeof(_ENCODING_STATE) > lenps)
399 cei = calloc(1, sizeof(_CTYPE_INFO));
405 return _FUNCNAME(encoding_module_init)(_CEI_TO_EI(cei), var, lenvar);
409 _FUNCNAME(ctype_uninit)(void *cl)
412 _FUNCNAME(encoding_module_uninit)(_CEI_TO_EI(_TO_CEI(cl)));
419 _FUNCNAME(ctype_get_mb_cur_max)(void *cl)
421 return _ENCODING_MB_CUR_MAX(_CEI_TO_EI(_TO_CEI(cl)));
425 _FUNCNAME(ctype_mblen)(void * __restrict cl,
426 const char * __restrict s, size_t n,
427 int * __restrict nresult)
429 _ENCODING_STATE *psenc;
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);
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;
450 _DIAGASSERT(cl != NULL);
452 ei = _CEI_TO_EI(_TO_CEI(cl));
453 _RESTART_BEGIN(mbrlen, _TO_CEI(cl), pspriv, psenc);
455 _FUNCNAME(init_state)(ei, psenc);
458 err = _FUNCNAME(mbrtowc_priv)(ei, NULL, (const char **)&s, n,
459 (void *)psenc, nresult);
461 _RESTART_END(mbrlen, _TO_CEI(cl), pspriv, psenc);
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;
475 _DIAGASSERT(cl != NULL);
477 ei = _CEI_TO_EI(_TO_CEI(cl));
478 _RESTART_BEGIN(mbrtowc, _TO_CEI(cl), pspriv, psenc);
480 _FUNCNAME(init_state)(ei, psenc);
483 err = _FUNCNAME(mbrtowc_priv)(ei, pwc, (const char **)&s, n,
484 (void *)psenc, nresult);
486 _RESTART_END(mbrtowc, _TO_CEI(cl), pspriv, psenc);
493 _FUNCNAME(ctype_mbsinit)(void * __restrict cl, const void * __restrict pspriv,
494 int * __restrict nresult)
496 _ENCODING_STATE state;
498 if (pspriv == NULL) {
503 _FUNCNAME(unpack_state)(_CEI_TO_EI(_TO_CEI(cl)), &state, pspriv);
505 *nresult = (state.chlen == 0); /* XXX: FIXME */
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;
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);
531 _FUNCNAME(ctype_mbstowcs)(void * __restrict cl, wchar_t * __restrict pwcs,
532 const char * __restrict s, size_t n,
533 size_t * __restrict nresult)
536 _ENCODING_STATE state;
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,
545 if (*nresult == (size_t)-2) {
547 *nresult = (size_t)-1;
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;
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);
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];
578 #if _ENCODING_IS_STATE_DEPENDENT
582 _DIAGASSERT(cl != NULL);
586 * use internal buffer.
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
597 err = _FUNCNAME(put_state_reset)(_CEI_TO_EI(_TO_CEI(cl)), s,
607 err = _FUNCNAME(wcrtomb_priv)(_CEI_TO_EI(_TO_CEI(cl)), s, sz,
609 #if _ENCODING_IS_STATE_DEPENDENT
616 _RESTART_END(wcrtomb, _TO_CEI(cl), pspriv, psenc);
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;
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);
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;
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,
663 _FUNCNAME(ctype_wctomb)(void * __restrict cl, char * __restrict s, wchar_t wc,
664 int * __restrict nresult)
666 _ENCODING_STATE *psenc;
669 #if _ENCODING_IS_STATE_DEPENDENT
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);
681 _FUNCNAME(init_state)(ei, psenc);
682 *nresult = _ENCODING_IS_STATE_DEPENDENT;
685 sz = _ENCODING_MB_CUR_MAX(_CEI_TO_EI(_TO_CEI(cl)));
686 #if _ENCODING_IS_STATE_DEPENDENT
689 err = _FUNCNAME(put_state_reset)(_CEI_TO_EI(_TO_CEI(cl)), s,
692 *nresult = -1; /* XXX */
699 err = _FUNCNAME(wcrtomb_priv)(ei, s, sz, wc, psenc, &nr);
700 #if _ENCODING_IS_STATE_DEPENDENT
702 *nresult = (int)(nr + rsz);
712 _FUNCNAME(ctype_btowc)(_citrus_ctype_rec_t * __restrict cc,
713 int c, wint_t * __restrict wcresult)
715 _ENCODING_STATE state;
723 _DIAGASSERT(cc != NULL && cc->cc_closure != NULL);
729 ei = _CEI_TO_EI(_TO_CEI(cc->cc_closure));
730 _FUNCNAME(init_state)(ei, &state);
731 mb = (char)(unsigned)c;
733 err = _FUNCNAME(mbrtowc_priv)(ei, &wc, &s, 1, &state, &nr);
734 if (!err && (nr == 0 || nr == 1))
735 *wcresult = (wint_t)wc;
744 _FUNCNAME(ctype_wctob)(_citrus_ctype_rec_t * __restrict cc,
745 wint_t wc, int * __restrict cresult)
747 _ENCODING_STATE state;
749 char buf[MB_LEN_MAX];
753 _DIAGASSERT(cc != NULL && cc->cc_closure != NULL);
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);