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