* istrsenvisx() * The main internal function. * All user-visible functions call this one. */
| 372 | * All user-visible functions call this one. |
| 373 | */ |
| 374 | static int |
| 375 | istrsenvisx(char *mbdst, size_t *dlen, const char *mbsrc, size_t mblength, |
| 376 | int flags, const char *mbextra, int *cerr_ptr) |
| 377 | { |
| 378 | wchar_t *dst, *src, *pdst, *psrc, *start, *extra; |
| 379 | size_t len, olen; |
| 380 | uint64_t bmsk, wmsk; |
| 381 | wint_t c; |
| 382 | visfun_t f; |
| 383 | int clen = 0, cerr = 0, error = -1, i, shft; |
| 384 | ssize_t mbslength, maxolen; |
| 385 | |
| 386 | _DIAGASSERT(mbdst != NULL); |
| 387 | _DIAGASSERT(mbsrc != NULL || mblength == 0); |
| 388 | _DIAGASSERT(mbextra != NULL); |
| 389 | |
| 390 | /* |
| 391 | * Input (mbsrc) is a char string considered to be multibyte |
| 392 | * characters. The input loop will read this string pulling |
| 393 | * one character, possibly multiple bytes, from mbsrc and |
| 394 | * converting each to wchar_t in src. |
| 395 | * |
| 396 | * The vis conversion will be done using the wide char |
| 397 | * wchar_t string. |
| 398 | * |
| 399 | * This will then be converted back to a multibyte string to |
| 400 | * return to the caller. |
| 401 | */ |
| 402 | |
| 403 | /* Allocate space for the wide char strings */ |
| 404 | psrc = pdst = extra = NULL; |
| 405 | if ((psrc = calloc(mblength + 1, sizeof(*psrc))) == NULL) |
| 406 | return -1; |
| 407 | if ((pdst = calloc((4 * mblength) + 1, sizeof(*pdst))) == NULL) |
| 408 | goto out; |
| 409 | dst = pdst; |
| 410 | src = psrc; |
| 411 | |
| 412 | /* Use caller's multibyte conversion error flag. */ |
| 413 | if (cerr_ptr) |
| 414 | cerr = *cerr_ptr; |
| 415 | |
| 416 | /* |
| 417 | * Input loop. |
| 418 | * Handle up to mblength characters (not bytes). We do not |
| 419 | * stop at NULs because we may be processing a block of data |
| 420 | * that includes NULs. |
| 421 | */ |
| 422 | mbslength = (ssize_t)mblength; |
| 423 | /* |
| 424 | * When inputing a single character, must also read in the |
| 425 | * next character for nextc, the look-ahead character. |
| 426 | */ |
| 427 | if (mbslength == 1) |
| 428 | mbslength++; |
| 429 | while (mbslength > 0) { |
| 430 | /* Convert one multibyte character to wchar_t. */ |
| 431 | if (!cerr) |