1 /* $NetBSD: src/lib/libc/citrus/citrus_none.c,v 1.12 2004/01/18 03:57:30 yamt Exp $ */ 2 /* $DragonFly: src/lib/libc/citrus/citrus_none.c,v 1.3 2005/04/26 14:03:57 joerg Exp $ */ 3 4 /*- 5 * Copyright (c)2002 Citrus Project, 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <assert.h> 31 #include <errno.h> 32 #include <string.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <stddef.h> 36 #include <locale.h> 37 #include <wchar.h> 38 #include <sys/types.h> 39 40 #include "citrus_namespace.h" 41 #include "citrus_types.h" 42 #include "citrus_module.h" 43 #include "citrus_ctype.h" 44 #include "citrus_none.h" 45 #include "citrus_stdenc.h" 46 47 /* ---------------------------------------------------------------------- */ 48 49 _CITRUS_CTYPE_DECLS(NONE); 50 _CITRUS_CTYPE_DEF_OPS(NONE); 51 52 53 /* ---------------------------------------------------------------------- */ 54 55 static int 56 /*ARGSUSED*/ 57 _citrus_NONE_ctype_init(void ** __restrict cl, void * __restrict var __unused, 58 size_t lenvar __unused, size_t lenps __unused) 59 { 60 *cl = NULL; 61 return (0); 62 } 63 64 static void 65 /*ARGSUSED*/ 66 _citrus_NONE_ctype_uninit(void *cl __unused) 67 { 68 } 69 70 static unsigned 71 /*ARGSUSED*/ 72 _citrus_NONE_ctype_get_mb_cur_max(void *cl __unused) 73 { 74 return (1); 75 } 76 77 static int 78 /*ARGSUSED*/ 79 _citrus_NONE_ctype_mblen(void * __restrict cl __unused, 80 const char * __restrict s, size_t n, 81 int * __restrict nresult) 82 { 83 if (!s) { 84 *nresult = 0; /* state independent */ 85 return (0); 86 } 87 if (n==0) { 88 *nresult = -1; 89 return (EILSEQ); 90 } 91 *nresult = (*s == 0) ? 0 : 1; 92 return (0); 93 } 94 95 static int 96 /*ARGSUSED*/ 97 _citrus_NONE_ctype_mbrlen(void * __restrict cl __unused, 98 const char * __restrict s, size_t n, 99 void * __restrict pspriv __unused, 100 size_t * __restrict nresult) 101 { 102 if (!s) { 103 *nresult = 0; 104 return (0); 105 } 106 if (n==0) { 107 *nresult = (size_t)-2; 108 return (0); 109 } 110 *nresult = (*s == 0) ? 0 : 1; 111 return (0); 112 } 113 114 static int 115 /*ARGSUSED*/ 116 _citrus_NONE_ctype_mbrtowc(void * __restrict cl __unused, 117 wchar_t * __restrict pwc, 118 const char * __restrict s, size_t n, 119 void * __restrict pspriv __unused, 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 __unused, 141 const void * __restrict pspriv __unused, 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 __unused, 151 wchar_t * __restrict pwcs, 152 const char ** __restrict s, size_t n, 153 void * __restrict pspriv __unused, 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 *tmp_s = __DEQUALIFY(const char *, s); 194 195 return (_citrus_NONE_ctype_mbsrtowcs(cl, wcs, &tmp_s, n, NULL, nresult)); 196 } 197 198 static int 199 /*ARGSUSED*/ 200 _citrus_NONE_ctype_mbtowc(void * __restrict cl __unused, 201 wchar_t * __restrict pwc, 202 const char * __restrict s, size_t n, 203 int * __restrict nresult) 204 { 205 206 if (s == NULL) { 207 *nresult = 0; /* state independent */ 208 return (0); 209 } 210 if (n == 0) { 211 return (EILSEQ); 212 } 213 if (pwc == NULL) { 214 if (*s == '\0') { 215 *nresult = 0; 216 } else { 217 *nresult = 1; 218 } 219 return (0); 220 } 221 222 *pwc = (wchar_t)*s; 223 *nresult = *s == '\0' ? 0 : 1; 224 225 return (0); 226 } 227 228 static int 229 /*ARGSUSED*/ 230 _citrus_NONE_ctype_wcrtomb(void * __restrict cl __unused, 231 char * __restrict s, wchar_t wc, 232 void * __restrict pspriv __unused, 233 size_t * __restrict nresult) 234 { 235 if ((wc&~0xFFU) != 0) { 236 *nresult = (size_t)-1; 237 return (EILSEQ); 238 } 239 240 *nresult = 1; 241 if (s!=NULL) 242 *s = (char)wc; 243 244 return (0); 245 } 246 247 static int 248 /*ARGSUSED*/ 249 _citrus_NONE_ctype_wcsrtombs(void * __restrict cl __unused, 250 char * __restrict s, 251 const wchar_t ** __restrict pwcs, size_t n, 252 void * __restrict pspriv __unused, 253 size_t * __restrict nresult) 254 { 255 size_t count; 256 const wchar_t *pwcs0; 257 258 pwcs0 = *pwcs; 259 count = 0; 260 261 if (s == NULL) 262 n = 1; 263 264 while (n > 0) { 265 if ((*pwcs0 & ~0xFFU) != 0) { 266 *nresult = (size_t)-1; 267 return (EILSEQ); 268 } 269 if (s != NULL) { 270 *s++ = (char)*pwcs0; 271 n--; 272 } 273 if (*pwcs0 == L'\0') { 274 pwcs0 = NULL; 275 break; 276 } 277 count++; 278 pwcs0++; 279 } 280 if (s != NULL) 281 *pwcs = pwcs0; 282 283 *nresult = count; 284 285 return (0); 286 } 287 288 static int 289 _citrus_NONE_ctype_wcstombs(void * __restrict cl, char * __restrict s, 290 const wchar_t * __restrict pwcs, size_t n, 291 size_t * __restrict nresult) 292 { 293 const wchar_t *tmp_pwcs = __DEQUALIFY(const wchar_t *, pwcs); 294 295 return (_citrus_NONE_ctype_wcsrtombs(cl, s, &tmp_pwcs, n, NULL, nresult)); 296 } 297 298 static int 299 _citrus_NONE_ctype_wctomb(void * __restrict cl, char * __restrict s, 300 wchar_t wc, int * __restrict nresult) 301 { 302 int ret; 303 size_t nr; 304 305 if (s == 0) { 306 /* 307 * initialize state here. 308 * (nothing to do for us.) 309 */ 310 *nresult = 0; /* we're state independent */ 311 return (0); 312 } 313 314 ret = _citrus_NONE_ctype_wcrtomb(cl, s, wc, NULL, &nr); 315 *nresult = (int)nr; 316 317 return (ret); 318 } 319 320 static int 321 /*ARGSUSED*/ 322 _citrus_NONE_ctype_btowc(_citrus_ctype_rec_t * __restrict cc __unused, 323 int c, wint_t * __restrict wcresult) 324 { 325 if (c == EOF || c & ~0xFF) 326 *wcresult = WEOF; 327 else 328 *wcresult = (wint_t)c; 329 return (0); 330 } 331 332 static int 333 /*ARGSUSED*/ 334 _citrus_NONE_ctype_wctob(_citrus_ctype_rec_t * __restrict cc __unused, 335 wint_t wc, int * __restrict cresult) 336 { 337 if (wc == WEOF || wc & ~0xFF) 338 *cresult = EOF; 339 else 340 *cresult = (int)wc; 341 return (0); 342 } 343 344 /* ---------------------------------------------------------------------- */ 345 346 _CITRUS_STDENC_DECLS(NONE); 347 _CITRUS_STDENC_DEF_OPS(NONE); 348 struct _citrus_stdenc_traits _citrus_NONE_stdenc_traits = { 349 0, /* et_state_size */ 350 1, /* mb_cur_max */ 351 }; 352 353 static int 354 /*ARGSUSED*/ 355 _citrus_NONE_stdenc_init(struct _citrus_stdenc * __restrict ce, 356 const void *var __unused, size_t lenvar __unused, 357 struct _citrus_stdenc_traits * __restrict et) 358 { 359 360 et->et_state_size = 0; 361 et->et_mb_cur_max = 1; 362 363 ce->ce_closure = NULL; 364 365 return (0); 366 } 367 368 static void 369 /*ARGSUSED*/ 370 _citrus_NONE_stdenc_uninit(struct _citrus_stdenc *ce __unused) 371 { 372 } 373 374 static int 375 /*ARGSUSED*/ 376 _citrus_NONE_stdenc_init_state(struct _citrus_stdenc * __restrict ce __unused, 377 void * __restrict ps __unused) 378 { 379 return (0); 380 } 381 382 static int 383 /*ARGSUSED*/ 384 _citrus_NONE_stdenc_mbtocs(struct _citrus_stdenc * __restrict ce __unused, 385 _csid_t *csid, _index_t *idx, 386 const char **s, size_t n, 387 void *ps __unused, size_t *nresult) 388 { 389 390 _DIAGASSERT(csid != NULL && idx != NULL); 391 392 if (n<1) { 393 *nresult = (size_t)-2; 394 return (0); 395 } 396 397 *csid = 0; 398 *idx = (_index_t)(unsigned char)*(*s)++; 399 *nresult = *idx == 0 ? 0 : 1; 400 401 return (0); 402 } 403 404 static int 405 /*ARGSUSED*/ 406 _citrus_NONE_stdenc_cstomb(struct _citrus_stdenc * __restrict ce __unused, 407 char *s, size_t n, 408 _csid_t csid, _index_t idx, 409 void *ps __unused, size_t *nresult) 410 { 411 412 if (csid == _CITRUS_CSID_INVALID) { 413 *nresult = 0; 414 return (0); 415 } 416 if (n<1) { 417 *nresult = (size_t)-1; 418 return (E2BIG); 419 } 420 if (csid != 0 || (idx&0xFF) != idx) 421 return (EILSEQ); 422 423 *s = (char)idx; 424 *nresult = 1; 425 426 return (0); 427 } 428 429 static int 430 /*ARGSUSED*/ 431 _citrus_NONE_stdenc_mbtowc(struct _citrus_stdenc * __restrict ce __unused, 432 _wc_t * __restrict pwc, 433 const char ** __restrict s, size_t n, 434 void * __restrict pspriv __unused, 435 size_t * __restrict nresult) 436 { 437 if (s == NULL) { 438 *nresult = 0; 439 return (0); 440 } 441 if (n == 0) { 442 *nresult = (size_t)-2; 443 return (0); 444 } 445 446 if (pwc != NULL) 447 *pwc = (_wc_t)(unsigned char) **s; 448 449 *nresult = *s == '\0' ? 0 : 1; 450 return (0); 451 } 452 453 static int 454 /*ARGSUSED*/ 455 _citrus_NONE_stdenc_wctomb(struct _citrus_stdenc * __restrict ce __unused, 456 char * __restrict s, size_t n, _wc_t wc, 457 void * __restrict pspriv __unused, 458 size_t * __restrict nresult) 459 { 460 if ((wc&~0xFFU) != 0) { 461 *nresult = (size_t)-1; 462 return (EILSEQ); 463 } 464 if (n==0) { 465 *nresult = (size_t)-1; 466 return (E2BIG); 467 } 468 469 *nresult = 1; 470 if (s!=NULL && n>0) 471 *s = (char)wc; 472 473 return (0); 474 } 475 476 static int 477 /*ARGSUSED*/ 478 _citrus_NONE_stdenc_put_state_reset(struct _citrus_stdenc * __restrict ce __unused, 479 char * __restrict s __unused, 480 size_t n __unused, 481 void * __restrict pspriv __unused, 482 size_t * __restrict nresult) 483 { 484 485 *nresult = 0; 486 487 return (0); 488 } 489