- if (ljust) {
- if (cp + remaining > ep)
- remaining = ep - cp;
- ep = cp + remaining;
- if (remaining > 0) {
- /* copy string to the right */
- while (--cp >= *dest)
- *(cp + remaining) = *cp;
- /* add padding at the beginning */
- cp += remaining;
- for (c=remaining; c>0; c--)
- *cp-- = fill;
- }
- *dest = ep;
- } else {
- /* pad remaining space */
- while (remaining-- > 0 && cp < ep)
- *cp++ = fill;
- *dest = cp;
+ while (remaining-- > 0) {
+ charstring_push_back(dest, fill);
+ }
+
+ if (rjust) {
+ charstring_append(dest, trimmed);
+ charstring_free(trimmed);
+ }
+}
+
+#ifdef MULTIBYTE_SUPPORT
+static void
+cpstripped (charstring_t dest, size_t max, char *str)
+{
+ static bool deja_vu;
+ static char *oddchar;
+ static size_t oddlen;
+ static char *spacechar;
+ static size_t spacelen;
+ char *end;
+ bool squash;
+ char *src;
+ int srclen;
+ wchar_t rune;
+ int w;
+
+ if (!deja_vu) {
+ size_t two;
+
+ deja_vu = true;
+
+ two = MB_CUR_MAX * 2; /* Varies at run-time. */
+
+ oddchar = mh_xmalloc(two);
+ oddlen = wcstombs(oddchar, L"?", two);
+ assert(oddlen > 0);
+
+ assert(wcwidth(L' ') == 1); /* Need to pad in ones. */
+ spacechar = mh_xmalloc(two);
+ spacelen = wcstombs(spacechar, L" ", two);
+ assert(spacelen > 0);
+ }
+
+ if (!str)
+ return; /* It's unclear why no padding in this case. */
+ end = str + strlen(str);
+
+ if (mbtowc(NULL, NULL, 0))
+ {} /* Reset shift state. */
+
+ squash = true; /* Trim `space' or `cntrl' from the start. */
+ while (max) {
+ if (!*str)
+ return; /* It's unclear why no padding in this case. */
+
+ srclen = mbtowc(&rune, str, end - str);
+ if (srclen == -1) {
+ /* Invalid rune, or not enough bytes to finish it. */
+ rune = L'?';
+ src = oddchar;
+ srclen = oddlen;
+ str++; /* Skip one byte. */
+ } else {
+ src = str;
+ str += srclen;
+ }
+
+ if (iswspace(rune) || iswcntrl(rune)) {
+ if (squash)
+ continue; /* Amidst a run of these. */
+ rune = L' ';
+ src = spacechar;
+ srclen = spacelen;
+ squash = true;
+ } else
+ squash = false;
+
+ w = wcwidth(rune);
+ if (w == -1) {
+ rune = L'?';
+ w = wcwidth(rune);
+ assert(w != -1);
+ src = oddchar;
+ srclen = oddlen;
+ }
+
+ if ((size_t)w > max) {
+ /* No room for rune; pad. */
+ while (max--)
+ charstring_push_back_chars(dest, spacechar, spacelen, 1);
+ return;
+ }
+
+ charstring_push_back_chars(dest, src, srclen, w);
+ max -= w;