1/* $NetBSD: citrus_none.c,v 1.23 2019/07/28 13:52:23 christos 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.23 2019/07/28 13:52:23 christos 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 58static 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 67static void 68/*ARGSUSED*/ 69_citrus_NONE_ctype_uninit(void *cl) 70{ 71} 72 73static unsigned 74/*ARGSUSED*/ 75_citrus_NONE_ctype_get_mb_cur_max(void *cl) 76{ 77 return (1); 78} 79 80static 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 97static 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 115static 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 138static 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 148static 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 187static int 188/*ARGSUSED*/ 189_citrus_NONE_ctype_mbsnrtowcs(_citrus_ctype_rec_t * __restrict cc, 190 wchar_t * __restrict pwcs, 191 const char ** __restrict s, size_t in, size_t n, 192 void * __restrict pspriv, 193 size_t * __restrict nresult) 194{ 195 int cnt; 196 const char *s0; 197 198 /* if pwcs is NULL, ignore n */ 199 if (pwcs == NULL) 200 n = 1; /* arbitrary >0 value */ 201 202 cnt = 0; 203 s0 = *s; /* to keep *s unchanged for now, use copy instead. */ 204 while (in > 0 && n > 0) { 205 if (pwcs != NULL) { 206 *pwcs = (wchar_t)(unsigned char)*s0; 207 } 208 if (*s0 == '\0') { 209 s0 = NULL; 210 break; 211 } 212 s0++; 213 --in; 214 if (pwcs != NULL) { 215 pwcs++; 216 n--; 217 } 218 cnt++; 219 } 220 if (pwcs) 221 *s = s0; 222 223 *nresult = (size_t)cnt; 224 225 return (0); 226} 227 228static int 229_citrus_NONE_ctype_mbstowcs(void * __restrict cl, wchar_t * __restrict wcs, 230 const char * __restrict s, size_t n, 231 size_t * __restrict nresult) 232{ 233 const char *rs = s; 234 235 return (_citrus_NONE_ctype_mbsrtowcs(cl, wcs, &rs, n, NULL, nresult)); 236} 237 238static int 239/*ARGSUSED*/ 240_citrus_NONE_ctype_mbtowc(void * __restrict cl, wchar_t * __restrict pwc, 241 const char * __restrict s, size_t n, 242 int * __restrict nresult) 243{ 244 245 if (s == NULL) { 246 *nresult = 0; /* state independent */ 247 return (0); 248 } 249 if (n == 0) { 250 return (EILSEQ); 251 } 252 if (pwc == NULL) { 253 if (*s == '\0') { 254 *nresult = 0; 255 } else { 256 *nresult = 1; 257 } 258 return (0); 259 } 260 261 *pwc = (wchar_t)(unsigned char)*s; 262 *nresult = *s == '\0' ? 0 : 1; 263 264 return (0); 265} 266 267static int 268/*ARGSUSED*/ 269_citrus_NONE_ctype_wcrtomb(void * __restrict cl, char * __restrict s, 270 wchar_t wc, void * __restrict pspriv, 271 size_t * __restrict nresult) 272{ 273 if ((wc&~0xFFU) != 0) { 274 *nresult = (size_t)-1; 275 return (EILSEQ); 276 } 277 278 *nresult = 1; 279 if (s!=NULL) 280 *s = (char)wc; 281 282 return (0); 283} 284 285static int 286/*ARGSUSED*/ 287_citrus_NONE_ctype_wcsrtombs(void * __restrict cl, char * __restrict s, 288 const wchar_t ** __restrict pwcs, size_t n, 289 void * __restrict pspriv, 290 size_t * __restrict nresult) 291{ 292 size_t count; 293 const wchar_t *pwcs0; 294 295 pwcs0 = *pwcs; 296 count = 0; 297 298 if (s == NULL) 299 n = 1; 300 301 while (n > 0) { 302 if ((*pwcs0 & ~0xFFU) != 0) { 303 *pwcs = pwcs0; 304 *nresult = (size_t)-1; 305 return (EILSEQ); 306 } 307 if (s != NULL) { 308 *s++ = (char)*pwcs0; 309 n--; 310 } 311 if (*pwcs0 == L'\0') { 312 pwcs0 = NULL; 313 break; 314 } 315 count++; 316 pwcs0++; 317 } 318 if (s != NULL) 319 *pwcs = pwcs0; 320 321 *nresult = count; 322 323 return (0); 324} 325 326static int 327/*ARGSUSED*/ 328_citrus_NONE_ctype_wcsnrtombs(_citrus_ctype_rec_t * __restrict cc, 329 char * __restrict s, 330 const wchar_t ** __restrict pwcs, size_t in, 331 size_t n, void * __restrict pspriv, 332 size_t * __restrict nresult) 333{ 334 size_t count; 335 const wchar_t *pwcs0; 336 337 pwcs0 = *pwcs; 338 count = 0; 339 340 if (s == NULL) 341 n = 1; 342 343 while (in > 0 && n > 0) { 344 if ((*pwcs0 & ~0xFFU) != 0) { 345 *nresult = (size_t)-1; 346 return (EILSEQ); 347 } 348 if (s != NULL) { 349 *s++ = (char)*pwcs0; 350 n--; 351 } 352 if (*pwcs0 == L'\0') { 353 pwcs0 = NULL; 354 break; 355 } 356 count++; 357 pwcs0++; 358 --in; 359 } 360 if (s != NULL) 361 *pwcs = pwcs0; 362 363 *nresult = count; 364 365 return (0); 366} 367 368static int 369_citrus_NONE_ctype_wcstombs(void * __restrict cl, char * __restrict s, 370 const wchar_t * __restrict pwcs, size_t n, 371 size_t * __restrict nresult) 372{ 373 const wchar_t *rpwcs = pwcs; 374 375 return (_citrus_NONE_ctype_wcsrtombs(cl, s, &rpwcs, n, NULL, nresult)); 376} 377 378static int 379_citrus_NONE_ctype_wctomb(void * __restrict cl, char * __restrict s, 380 wchar_t wc, int * __restrict nresult) 381{ 382 int ret; 383 size_t nr; 384 385 if (s == 0) { 386 /* 387 * initialize state here. 388 * (nothing to do for us.) 389 */ 390 *nresult = 0; /* we're state independent */ 391 return (0); 392 } 393 394 ret = _citrus_NONE_ctype_wcrtomb(cl, s, wc, NULL, &nr); 395 *nresult = (int)nr; 396 397 return (ret); 398} 399 400static int 401/*ARGSUSED*/ 402_citrus_NONE_ctype_btowc(_citrus_ctype_rec_t * __restrict cc, 403 int c, wint_t * __restrict wcresult) 404{ 405 if (c == EOF || c & ~0xFF) 406 *wcresult = WEOF; 407 else 408 *wcresult = (wint_t)c; 409 return (0); 410} 411 412static int 413/*ARGSUSED*/ 414_citrus_NONE_ctype_wctob(_citrus_ctype_rec_t * __restrict cc, 415 wint_t wc, int * __restrict cresult) 416{ 417 if (wc == WEOF || wc & ~0xFF) 418 *cresult = EOF; 419 else 420 *cresult = (int)wc; 421 return (0); 422} 423 424/* ---------------------------------------------------------------------- */ 425 426_CITRUS_STDENC_DECLS(NONE); 427_CITRUS_STDENC_DEF_OPS(NONE); 428struct _citrus_stdenc_traits _citrus_NONE_stdenc_traits = { 429 0, /* et_state_size */ 430 1, /* mb_cur_max */ 431}; 432 433static int 434/*ARGSUSED*/ 435_citrus_NONE_stdenc_init(struct _citrus_stdenc * __restrict ce, 436 const void *var, size_t lenvar, 437 struct _citrus_stdenc_traits * __restrict et) 438{ 439 440 et->et_state_size = 0; 441 et->et_mb_cur_max = 1; 442 443 ce->ce_closure = NULL; 444 445 return (0); 446} 447 448static void 449/*ARGSUSED*/ 450_citrus_NONE_stdenc_uninit(struct _citrus_stdenc *ce) 451{ 452} 453 454static int 455/*ARGSUSED*/ 456_citrus_NONE_stdenc_init_state(struct _citrus_stdenc * __restrict ce, 457 void * __restrict ps) 458{ 459 return (0); 460} 461 462static int 463/*ARGSUSED*/ 464_citrus_NONE_stdenc_mbtocs(struct _citrus_stdenc * __restrict ce, 465 _csid_t *csid, _index_t *idx, 466 const char **s, size_t n, 467 void *ps, size_t *nresult) 468{ 469 470 _DIAGASSERT(csid != NULL && idx != NULL); 471 472 if (n<1) { 473 *nresult = (size_t)-2; 474 return (0); 475 } 476 477 *csid = 0; 478 *idx = (_index_t)(unsigned char)*(*s)++; 479 *nresult = *idx == 0 ? 0 : 1; 480 481 return (0); 482} 483 484static int 485/*ARGSUSED*/ 486_citrus_NONE_stdenc_cstomb(struct _citrus_stdenc * __restrict ce, 487 char *s, size_t n, 488 _csid_t csid, _index_t idx, 489 void *ps, size_t *nresult) 490{ 491 492 if (csid == _CITRUS_CSID_INVALID) { 493 *nresult = 0; 494 return (0); 495 } 496 if (n<1) { 497 *nresult = (size_t)-1; 498 return (E2BIG); 499 } 500 if (csid != 0 || (idx&0xFF) != idx) 501 return (EILSEQ); 502 503 *s = (char)idx; 504 *nresult = 1; 505 506 return (0); 507} 508 509static int 510/*ARGSUSED*/ 511_citrus_NONE_stdenc_mbtowc(struct _citrus_stdenc * __restrict ce, 512 _wc_t * __restrict pwc, 513 const char ** __restrict s, size_t n, 514 void * __restrict pspriv, 515 size_t * __restrict nresult) 516{ 517 518 _DIAGASSERT(s != NULL); 519 520 if (*s == NULL) { 521 *nresult = 0; 522 return (0); 523 } 524 if (n == 0) { 525 *nresult = (size_t)-2; 526 return (0); 527 } 528 529 if (pwc != NULL) 530 *pwc = (_wc_t)(unsigned char) **s; 531 532 *nresult = **s == '\0' ? 0 : 1; 533 return (0); 534} 535 536static int 537/*ARGSUSED*/ 538_citrus_NONE_stdenc_wctomb(struct _citrus_stdenc * __restrict ce, 539 char * __restrict s, size_t n, 540 _wc_t wc, void * __restrict pspriv, 541 size_t * __restrict nresult) 542{ 543 if ((wc&~0xFFU) != 0) { 544 *nresult = (size_t)-1; 545 return (EILSEQ); 546 } 547 if (n==0) { 548 *nresult = (size_t)-1; 549 return (E2BIG); 550 } 551 552 *nresult = 1; 553 if (s!=NULL && n>0) 554 *s = (char)wc; 555 556 return (0); 557} 558 559static int 560/*ARGSUSED*/ 561_citrus_NONE_stdenc_put_state_reset(struct _citrus_stdenc * __restrict ce, 562 char * __restrict s, size_t n, 563 void * __restrict pspriv, 564 size_t * __restrict nresult) 565{ 566 567 *nresult = 0; 568 569 return (0); 570} 571 572static int 573/*ARGSUSED*/ 574_citrus_NONE_stdenc_get_state_desc(struct _stdenc * __restrict ce, 575 void * __restrict ps, 576 int id, 577 struct _stdenc_state_desc * __restrict d) 578{ 579 int ret = 0; 580 581 switch (id) { 582 case _STDENC_SDID_GENERIC: 583 d->u.generic.state = _STDENC_SDGEN_INITIAL; 584 break; 585 default: 586 ret = EOPNOTSUPP; 587 } 588 589 return ret; 590} 591