| 2691 | } |
| 2692 | |
| 2693 | static int |
| 2694 | xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, |
| 2695 | xo_xff_flags_t flags, |
| 2696 | const wchar_t *wcp, const char *cp, |
| 2697 | ssize_t len, int max, |
| 2698 | int need_enc, int have_enc) |
| 2699 | { |
| 2700 | int cols = 0; |
| 2701 | wchar_t wc = 0; |
| 2702 | ssize_t ilen, olen; |
| 2703 | ssize_t width; |
| 2704 | int attr = XOF_BIT_ISSET(flags, XFF_ATTR); |
| 2705 | const char *sp; |
| 2706 | |
| 2707 | if (len > 0 && !xo_buf_has_room(xbp, len)) |
| 2708 | return 0; |
| 2709 | |
| 2710 | for (;;) { |
| 2711 | if (len == 0) |
| 2712 | break; |
| 2713 | |
| 2714 | if (cp) { |
| 2715 | if (*cp == '\0') |
| 2716 | break; |
| 2717 | if ((flags & XFF_UNESCAPE) && (*cp == '\\' || *cp == '%')) { |
| 2718 | cp += 1; |
| 2719 | len -= 1; |
| 2720 | if (len == 0 || *cp == '\0') |
| 2721 | break; |
| 2722 | } |
| 2723 | } |
| 2724 | |
| 2725 | if (wcp && *wcp == L'\0') |
| 2726 | break; |
| 2727 | |
| 2728 | ilen = 0; |
| 2729 | |
| 2730 | switch (have_enc) { |
| 2731 | case XF_ENC_WIDE: /* Wide character */ |
| 2732 | wc = *wcp++; |
| 2733 | ilen = 1; |
| 2734 | break; |
| 2735 | |
| 2736 | case XF_ENC_UTF8: /* UTF-8 */ |
| 2737 | ilen = xo_utf8_to_wc_len(cp); |
| 2738 | if (ilen < 0) { |
| 2739 | xo_failure(xop, "invalid UTF-8 character: %02hhx", *cp); |
| 2740 | return -1; /* Can't continue; we can't find the end */ |
| 2741 | } |
| 2742 | |
| 2743 | if (len > 0 && len < ilen) { |
| 2744 | len = 0; /* Break out of the loop */ |
| 2745 | continue; |
| 2746 | } |
| 2747 | |
| 2748 | wc = xo_utf8_char(cp, ilen); |
| 2749 | if (wc == (wchar_t) -1) { |
| 2750 | xo_failure(xop, "invalid UTF-8 character: %02hhx/%d", |
no test coverage detected