1 /* $NetBSD: citrus_mskanji.c,v 1.5 2002/03/28 10:53:49 yamt Exp $ */ 2 3 /*- 4 * Copyright (c)2002 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 /* 30 * ja_JP.SJIS locale table for BSD4.4/rune 31 * version 1.0 32 * (C) Sin'ichiro MIYATANI / Phase One, Inc 33 * May 12, 1995 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. All advertising materials mentioning features or use of this software 44 * must display the following acknowledgement: 45 * This product includes software developed by Phase One, Inc. 46 * 4. The name of Phase One, Inc. may be used to endorse or promote products 47 * derived from this software without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 */ 61 62 63 #include <sys/cdefs.h> 64 #if defined(LIBC_SCCS) && !defined(lint) 65 __RCSID("$NetBSD: citrus_mskanji.c,v 1.5 2002/03/28 10:53:49 yamt Exp $"); 66 #endif /* LIBC_SCCS and not lint */ 67 68 #include <assert.h> 69 #include <errno.h> 70 #include <string.h> 71 #include <stdio.h> 72 #include <stdlib.h> 73 #include <stddef.h> 74 #include <locale.h> 75 #include <wchar.h> 76 #include <sys/types.h> 77 #include <limits.h> 78 #include "citrus_module.h" 79 #include "citrus_ctype.h" 80 #include "citrus_mskanji.h" 81 82 83 /* ---------------------------------------------------------------------- 84 * private stuffs used by templates 85 */ 86 87 typedef struct _MSKanjiState { 88 char ch[2]; 89 int chlen; 90 } _MSKanjiState; 91 92 typedef struct { 93 int dummy; 94 } _MSKanjiEncodingInfo; 95 96 typedef struct { 97 _MSKanjiEncodingInfo ei; 98 struct { 99 /* for future multi-locale facility */ 100 _MSKanjiState s_mblen; 101 _MSKanjiState s_mbrlen; 102 _MSKanjiState s_mbrtowc; 103 _MSKanjiState s_mbtowc; 104 _MSKanjiState s_mbsrtowcs; 105 _MSKanjiState s_wcrtomb; 106 _MSKanjiState s_wcsrtombs; 107 _MSKanjiState s_wctomb; 108 } states; 109 } _MSKanjiCTypeInfo; 110 111 #define _CEI_TO_EI(_cei_) (&(_cei_)->ei) 112 #define _CEI_TO_STATE(_cei_, _func_) (_cei_)->states.s_##_func_ 113 114 #define _FUNCNAME(m) _citrus_MSKanji_##m 115 #define _ENCODING_INFO _MSKanjiEncodingInfo 116 #define _CTYPE_INFO _MSKanjiCTypeInfo 117 #define _ENCODING_STATE _MSKanjiState 118 #define _ENCODING_MB_CUR_MAX(_ei_) 2 119 #define _ENCODING_IS_STATE_DEPENDENT 0 120 #define _STATE_NEEDS_EXPLICIT_INIT(_ps_) 0 121 122 123 static int 124 _mskanji1(int c) 125 { 126 127 if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xef)) 128 return 1; 129 else 130 return 0; 131 } 132 133 static int 134 _mskanji2(int c) 135 { 136 137 if ((c >= 0x40 && c <= 0x7e) || (c >= 0x80 && c <= 0xfc)) 138 return 1; 139 else 140 return 0; 141 } 142 143 static __inline void 144 /*ARGSUSED*/ 145 _citrus_MSKanji_init_state(_MSKanjiEncodingInfo * __restrict ei, 146 _MSKanjiState * __restrict s) 147 { 148 memset(s, 0, sizeof(*s)); 149 } 150 151 static __inline void 152 /*ARGSUSED*/ 153 _citrus_MSKanji_pack_state(_MSKanjiEncodingInfo * __restrict ei, 154 void * __restrict pspriv, 155 const _MSKanjiState * __restrict s) 156 { 157 memcpy(pspriv, (const void *)s, sizeof(*s)); 158 } 159 160 static __inline void 161 /*ARGSUSED*/ 162 _citrus_MSKanji_unpack_state(_MSKanjiEncodingInfo * __restrict ei, 163 _MSKanjiState * __restrict s, 164 const void * __restrict pspriv) 165 { 166 memcpy((void *)s, pspriv, sizeof(*s)); 167 } 168 169 static int 170 /*ARGSUSED*/ 171 _citrus_MSKanji_mbrtowc_priv(_MSKanjiEncodingInfo * __restrict ei, 172 wchar_t * __restrict pwc, 173 const char ** __restrict s, size_t n, 174 _MSKanjiState * __restrict psenc, 175 size_t * __restrict nresult) 176 { 177 wchar_t wchar; 178 int len; 179 int chlenbak; 180 const char *s0; 181 182 _DIAGASSERT(nresult != 0); 183 _DIAGASSERT(ei != NULL); 184 _DIAGASSERT(s != NULL); 185 _DIAGASSERT(psenc != NULL); 186 187 s0 = *s; 188 189 if (s0 == NULL) { 190 _citrus_MSKanji_init_state(ei, psenc); 191 *nresult = 0; /* state independent */ 192 return (0); 193 } 194 195 chlenbak = psenc->chlen; 196 197 /* make sure we have the first byte in the buffer */ 198 switch (psenc->chlen) { 199 case 0: 200 if (n < 1) 201 goto restart; 202 psenc->ch[0] = *s0++; 203 psenc->chlen = 1; 204 n--; 205 break; 206 case 1: 207 break; 208 default: 209 /* illegal state */ 210 goto encoding_error; 211 } 212 213 len = _mskanji1(psenc->ch[0] & 0xff) ? 2 : 1; 214 while (psenc->chlen < len) { 215 if (n < 1) 216 goto restart; 217 psenc->ch[psenc->chlen] = *s0++; 218 psenc->chlen++; 219 n--; 220 } 221 222 *s = s0; 223 224 switch (len) { 225 case 1: 226 wchar = psenc->ch[0] & 0xff; 227 break; 228 case 2: 229 if (!_mskanji2(psenc->ch[1] & 0xff)) 230 goto encoding_error; 231 wchar = ((psenc->ch[0] & 0xff) << 8) | (psenc->ch[1] & 0xff); 232 break; 233 default: 234 /* illegal state */ 235 goto encoding_error; 236 } 237 238 psenc->chlen = 0; 239 240 if (pwc) 241 *pwc = wchar; 242 243 if (!wchar) 244 *nresult = 0; 245 else 246 *nresult = len - chlenbak; 247 248 return (0); 249 250 encoding_error: 251 psenc->chlen = 0; 252 *nresult = (size_t)-1; 253 return (EILSEQ); 254 255 restart: 256 *nresult = (size_t)-2; 257 *s = s0; 258 return (0); 259 } 260 261 262 static int 263 _citrus_MSKanji_wcrtomb_priv(_MSKanjiEncodingInfo * __restrict ei, 264 char * __restrict s, size_t n, wchar_t wc, 265 _MSKanjiState * __restrict psenc, 266 size_t * __restrict nresult) 267 { 268 269 _DIAGASSERT(ei != NULL); 270 _DIAGASSERT(psenc != NULL); 271 _DIAGASSERT(s != NULL); 272 273 /* check invalid sequence */ 274 if (wc & ~0xffff) 275 goto ilseq; 276 277 if (wc & 0xff00) { 278 if (n < 2) 279 goto ilseq; 280 281 s[0] = (wc >> 8) & 0xff; 282 s[1] = wc & 0xff; 283 if (!_mskanji1(s[0] & 0xff) || !_mskanji2(s[1] & 0xff)) 284 goto ilseq; 285 286 *nresult = 2; 287 return (0); 288 } else { 289 s[0] = wc & 0xff; 290 if (_mskanji1(s[0] & 0xff)) 291 goto ilseq; 292 293 *nresult = 1; 294 return (0); 295 } 296 297 ilseq: 298 *nresult = (size_t)-1; 299 return EILSEQ; 300 } 301 302 303 static int 304 /*ARGSUSED*/ 305 _citrus_MSKanji_stdencoding_init(_MSKanjiEncodingInfo * __restrict ei, 306 const void * __restrict var, size_t lenvar) 307 { 308 309 _DIAGASSERT(cl != NULL); 310 311 return (0); 312 } 313 314 static void 315 _citrus_MSKanji_stdencoding_uninit(_MSKanjiEncodingInfo *ei) 316 { 317 } 318 319 /* ---------------------------------------------------------------------- 320 * public interface for ctype 321 */ 322 323 _CITRUS_CTYPE_DECLS(MSKanji); 324 _CITRUS_CTYPE_DEF_OPS(MSKanji); 325 326 #include "citrus_ctype_template.h" 327