1 /* $NetBSD: citrus_none.c,v 1.17 2005/12/02 11:14:20 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 #include <sys/cdefs.h> 30 #if defined(LIBC_SCCS) && !defined(lint) 31 __RCSID("$NetBSD: citrus_none.c,v 1.17 2005/12/02 11:14:20 yamt Exp $"); 32 #endif /* LIBC_SCCS and not lint */ 33 34 #include <assert.h> 35 #include <errno.h> 36 #include <string.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <stddef.h> 40 #include <locale.h> 41 #include <wchar.h> 42 #include <sys/types.h> 43 44 #include "citrus_namespace.h" 45 #include "citrus_types.h" 46 #include "citrus_module.h" 47 #include "citrus_ctype.h" 48 #include "citrus_none.h" 49 #include "citrus_stdenc.h" 50 51 /* ---------------------------------------------------------------------- */ 52 53 _CITRUS_CTYPE_DECLS(NONE); 54 _CITRUS_CTYPE_DEF_OPS(NONE); 55 56 57 /* ---------------------------------------------------------------------- */ 58 59 static int 60 /*ARGSUSED*/ 61 _citrus_NONE_ctype_init(void ** __restrict cl, void * __restrict var, 62 size_t lenvar, size_t lenps) 63 { 64 *cl = NULL; 65 return (0); 66 } 67 68 static void 69 /*ARGSUSED*/ 70 _citrus_NONE_ctype_uninit(void *cl) 71 { 72 } 73 74 static unsigned 75 /*ARGSUSED*/ 76 _citrus_NONE_ctype_get_mb_cur_max(void *cl) 77 { 78 return (1); 79 } 80 81 static int 82 /*ARGSUSED*/ 83 _citrus_NONE_ctype_mblen(void * __restrict cl, const char * __restrict s, 84 size_t n, int * __restrict nresult) 85 { 86 if (!s) { 87 *nresult = 0; /* state independent */ 88 return (0); 89 } 90 if (n==0) { 91 *nresult = -1; 92 return (EILSEQ); 93 } 94 *nresult = (*s == 0) ? 0 : 1; 95 return (0); 96 } 97 98 static int 99 /*ARGSUSED*/ 100 _citrus_NONE_ctype_mbrlen(void * __restrict cl, const char * __restrict s, 101 size_t n, void * __restrict pspriv, 102 size_t * __restrict nresult) 103 { 104 if (!s) { 105 *nresult = 0; 106 return (0); 107 } 108 if (n==0) { 109 *nresult = (size_t)-2; 110 return (0); 111 } 112 *nresult = (*s == 0) ? 0 : 1; 113 return (0); 114 } 115 116 static int 117 /*ARGSUSED*/ 118 _citrus_NONE_ctype_mbrtowc(void * __restrict cl, wchar_t * __restrict pwc, 119 const char * __restrict s, size_t n, 120 void * __restrict pspriv, 121 size_t * __restrict nresult) 122 { 123 if (s == NULL) { 124 *nresult = 0; 125 return (0); 126 } 127 if (n == 0) { 128 *nresult = (size_t)-2; 129 return (0); 130 } 131 132 if (pwc != NULL) 133 *pwc = (wchar_t)(unsigned char) *s; 134 135 *nresult = *s == '\0' ? 0 : 1; 136 return (0); 137 } 138 139 static int 140 /*ARGSUSED*/ 141 _citrus_NONE_ctype_mbsinit(void * __restrict cl, 142 const void * __restrict pspriv, 143 int * __restrict nresult) 144 { 145 *nresult = 1; /* always initial state */ 146 return (0); 147 } 148 149 static int 150 /*ARGSUSED*/ 151 _citrus_NONE_ctype_mbsrtowcs(void * __restrict cl, wchar_t * __restrict pwcs, 152 const char ** __restrict s, size_t n, 153 void * __restrict pspriv, 154 size_t * __restrict nresult) 155 { 156 int cnt; 157 const char *s0; 158 159 /* if pwcs is NULL, ignore n */ 160 if (pwcs == NULL) 161 n = 1; /* arbitrary >0 value */ 162 163 cnt = 0; 164 s0 = *s; /* to keep *s unchanged for now, use copy instead. */ 165 while (n > 0) { 166 if (pwcs != NULL) { 167 *pwcs = (wchar_t)(unsigned char)*s0; 168 } 169 if (*s0 == '\0') { 170 s0 = NULL; 171 break; 172 } 173 s0++; 174 if (pwcs != NULL) { 175 pwcs++; 176 n--; 177 } 178 cnt++; 179 } 180 if (pwcs) 181 *s = s0; 182 183 *nresult = (size_t)cnt; 184 185 return (0); 186 } 187 188 static int 189 _citrus_NONE_ctype_mbstowcs(void * __restrict cl, wchar_t * __restrict wcs, 190 const char * __restrict s, size_t n, 191 size_t * __restrict nresult) 192 { 193 const char *rs = s; 194 195 return (_citrus_NONE_ctype_mbsrtowcs(cl, wcs, &rs, n, NULL, nresult)); 196 } 197 198 static int 199 /*ARGSUSED*/ 200 _citrus_NONE_ctype_mbtowc(void * __restrict cl, wchar_t * __restrict pwc, 201 const char * __restrict s, size_t n, 202 int * __restrict nresult) 203 { 204 205 if (s == NULL) { 206 *nresult = 0; /* state independent */ 207 return (0); 208 } 209 if (n == 0) { 210 return (EILSEQ); 211 } 212 if (pwc == NULL) { 213 if (*s == '\0') { 214 *nresult = 0; 215 } else { 216 *nresult = 1; 217 } 218 return (0); 219 } 220 221 *pwc = (wchar_t)(unsigned char)*s; 222 *nresult = *s == '\0' ? 0 : 1; 223 224 return (0); 225 } 226 227 static int 228 /*ARGSUSED*/ 229 _citrus_NONE_ctype_wcrtomb(void * __restrict cl, char * __restrict s, 230 wchar_t wc, void * __restrict pspriv, 231 size_t * __restrict nresult) 232 { 233 if ((wc&~0xFFU) != 0) { 234 *nresult = (size_t)-1; 235 return (EILSEQ); 236 } 237 238 *nresult = 1; 239 if (s!=NULL) 240 *s = (char)wc; 241 242 return (0); 243 } 244 245 static int 246 /*ARGSUSED*/ 247 _citrus_NONE_ctype_wcsrtombs(void * __restrict cl, char * __restrict s, 248 const wchar_t ** __restrict pwcs, size_t n, 249 void * __restrict pspriv, 250 size_t * __restrict nresult) 251 { 252 size_t count; 253 const wchar_t *pwcs0; 254 255 pwcs0 = *pwcs; 256 count = 0; 257 258 if (s == NULL) 259 n = 1; 260 261 while (n > 0) { 262 if ((*pwcs0 & ~0xFFU) != 0) { 263 *nresult = (size_t)-1; 264 return (EILSEQ); 265 } 266 if (s != NULL) { 267 *s++ = (char)*pwcs0; 268 n--; 269 } 270 if (*pwcs0 == L'\0') { 271 pwcs0 = NULL; 272 break; 273 } 274 count++; 275 pwcs0++; 276 } 277 if (s != NULL) 278 *pwcs = pwcs0; 279 280 *nresult = count; 281 282 return (0); 283 } 284 285 static int 286 _citrus_NONE_ctype_wcstombs(void * __restrict cl, char * __restrict s, 287 const wchar_t * __restrict pwcs, size_t n, 288 size_t * __restrict nresult) 289 { 290 const wchar_t *rpwcs = pwcs; 291 292 return (_citrus_NONE_ctype_wcsrtombs(cl, s, &rpwcs, n, NULL, nresult)); 293 } 294 295 static int 296 _citrus_NONE_ctype_wctomb(void * __restrict cl, char * __restrict s, 297 wchar_t wc, int * __restrict nresult) 298 { 299 int ret; 300 size_t nr; 301 302 if (s == 0) { 303 /* 304 * initialize state here. 305 * (nothing to do for us.) 306 */ 307 *nresult = 0; /* we're state independent */ 308 return (0); 309 } 310 311 ret = _citrus_NONE_ctype_wcrtomb(cl, s, wc, NULL, &nr); 312 *nresult = (int)nr; 313 314 return (ret); 315 } 316 317 static int 318 /*ARGSUSED*/ 319 _citrus_NONE_ctype_btowc(_citrus_ctype_rec_t * __restrict cc, 320 int c, wint_t * __restrict wcresult) 321 { 322 if (c == EOF || c & ~0xFF) 323 *wcresult = WEOF; 324 else 325 *wcresult = (wint_t)c; 326 return (0); 327 } 328 329 static int 330 /*ARGSUSED*/ 331 _citrus_NONE_ctype_wctob(_citrus_ctype_rec_t * __restrict cc, 332 wint_t wc, int * __restrict cresult) 333 { 334 if (wc == WEOF || wc & ~0xFF) 335 *cresult = EOF; 336 else 337 *cresult = (int)wc; 338 return (0); 339 } 340 341 /* ---------------------------------------------------------------------- */ 342 343 _CITRUS_STDENC_DECLS(NONE); 344 _CITRUS_STDENC_DEF_OPS(NONE); 345 struct _citrus_stdenc_traits _citrus_NONE_stdenc_traits = { 346 0, /* et_state_size */ 347 1, /* mb_cur_max */ 348 }; 349 350 static int 351 /*ARGSUSED*/ 352 _citrus_NONE_stdenc_init(struct _citrus_stdenc * __restrict ce, 353 const void *var, size_t lenvar, 354 struct _citrus_stdenc_traits * __restrict et) 355 { 356 357 et->et_state_size = 0; 358 et->et_mb_cur_max = 1; 359 360 ce->ce_closure = NULL; 361 362 return (0); 363 } 364 365 static void 366 /*ARGSUSED*/ 367 _citrus_NONE_stdenc_uninit(struct _citrus_stdenc *ce) 368 { 369 } 370 371 static int 372 /*ARGSUSED*/ 373 _citrus_NONE_stdenc_init_state(struct _citrus_stdenc * __restrict ce, 374 void * __restrict ps) 375 { 376 return (0); 377 } 378 379 static int 380 /*ARGSUSED*/ 381 _citrus_NONE_stdenc_mbtocs(struct _citrus_stdenc * __restrict ce, 382 _csid_t *csid, _index_t *idx, 383 const char **s, size_t n, 384 void *ps, size_t *nresult) 385 { 386 387 _DIAGASSERT(csid != NULL && idx != NULL); 388 389 if (n<1) { 390 *nresult = (size_t)-2; 391 return (0); 392 } 393 394 *csid = 0; 395 *idx = (_index_t)(unsigned char)*(*s)++; 396 *nresult = *idx == 0 ? 0 : 1; 397 398 return (0); 399 } 400 401 static int 402 /*ARGSUSED*/ 403 _citrus_NONE_stdenc_cstomb(struct _citrus_stdenc * __restrict ce, 404 char *s, size_t n, 405 _csid_t csid, _index_t idx, 406 void *ps, size_t *nresult) 407 { 408 409 if (csid == _CITRUS_CSID_INVALID) { 410 *nresult = 0; 411 return (0); 412 } 413 if (n<1) { 414 *nresult = (size_t)-1; 415 return (E2BIG); 416 } 417 if (csid != 0 || (idx&0xFF) != idx) 418 return (EILSEQ); 419 420 *s = (char)idx; 421 *nresult = 1; 422 423 return (0); 424 } 425 426 static int 427 /*ARGSUSED*/ 428 _citrus_NONE_stdenc_mbtowc(struct _citrus_stdenc * __restrict ce, 429 _wc_t * __restrict pwc, 430 const char ** __restrict s, size_t n, 431 void * __restrict pspriv, 432 size_t * __restrict nresult) 433 { 434 if (s == NULL) { 435 *nresult = 0; 436 return (0); 437 } 438 if (n == 0) { 439 *nresult = (size_t)-2; 440 return (0); 441 } 442 443 if (pwc != NULL) 444 *pwc = (_wc_t)(unsigned char) **s; 445 446 *nresult = *s == '\0' ? 0 : 1; 447 return (0); 448 } 449 450 static int 451 /*ARGSUSED*/ 452 _citrus_NONE_stdenc_wctomb(struct _citrus_stdenc * __restrict ce, 453 char * __restrict s, size_t n, 454 _wc_t wc, void * __restrict pspriv, 455 size_t * __restrict nresult) 456 { 457 if ((wc&~0xFFU) != 0) { 458 *nresult = (size_t)-1; 459 return (EILSEQ); 460 } 461 if (n==0) { 462 *nresult = (size_t)-1; 463 return (E2BIG); 464 } 465 466 *nresult = 1; 467 if (s!=NULL && n>0) 468 *s = (char)wc; 469 470 return (0); 471 } 472 473 static int 474 /*ARGSUSED*/ 475 _citrus_NONE_stdenc_put_state_reset(struct _citrus_stdenc * __restrict ce, 476 char * __restrict s, size_t n, 477 void * __restrict pspriv, 478 size_t * __restrict nresult) 479 { 480 481 *nresult = 0; 482 483 return (0); 484 } 485 486 static int 487 /*ARGSUSED*/ 488 _citrus_NONE_stdenc_get_state_desc(struct _stdenc * __restrict ce, 489 void * __restrict ps, 490 int id, 491 struct _stdenc_state_desc * __restrict d) 492 { 493 int ret = 0; 494 495 switch (id) { 496 case _STDENC_SDID_GENERIC: 497 d->u.generic.state = _STDENC_SDGEN_INITIAL; 498 break; 499 default: 500 ret = EOPNOTSUPP; 501 } 502 503 return ret; 504 } 505