Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: bug: zformat is not multibyte aware
On Wed, 13 May 2015 20:10:21 +0200
Daniel Hahler <genml+zsh-workers@xxxxxxxxxx> wrote:
> TEST CASE:
>
> % foo=("äöü:asdf" "aou:asdf")
> % zformat -a foo "/" $foo
> % print -l $foo
> äöü/asdf
> aou /asdf
>
> The two columns should be aligned, but it seems like zformat aligns them
> according to bytes, not chars.
I love turning array arithmetic into character handling. Grumble.
Er... how about...
As it's for output, I've gone for the character widths rather than
counting 1 per character, but sometimes I get told off for that.
pws
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index c894950..376cd84 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -914,6 +914,9 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
{
char **ap, *cp;
int nbc = 0, colon = 0, pre = 0, suf = 0;
+#ifdef MULTIBYTE_SUPPORT
+ int prechars = 0;
+#endif /* MULTIBYTE_SUPPORT */
for (ap = args + 2; *ap; ap++) {
for (nbc = 0, cp = *ap; *cp && *cp != ':'; cp++)
@@ -921,10 +924,23 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
cp++, nbc++;
if (*cp == ':' && cp[1]) {
int d;
+#ifdef MULTIBYTE_SUPPORT
+ int dchars = 0;
+#endif /* MULTIBYTE_SUPPORT */
colon++;
if ((d = cp - *ap - nbc) > pre)
pre = d;
+#ifdef MULTIBYTE_SUPPORT
+ if (isset(MULTIBYTE)) {
+ *cp = '\0';
+ dchars = MB_METASTRWIDTH(*ap) - nbc;
+ *cp = ':';
+ } else
+ dchars = d;
+ if (dchars > prechars)
+ prechars = dchars;
+#endif /* MULTIBYTE_SUPPORT */
if ((d = strlen(cp + 1)) > suf)
suf = d;
}
@@ -937,8 +953,10 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
ret = (char **) zalloc((arrlen(args + 2) + 1) *
sizeof(char *));
+#ifndef MULTIBYTE_SUPPORT
memcpy(buf + pre, args[1], sl);
suf = pre + sl;
+#endif /* MULTIBYTE_SUPPORT */
for (rp = ret, ap = args + 2; *ap; ap++) {
copy = dupstring(*ap);
@@ -950,9 +968,27 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
oldc = *cpp;
*cpp = '\0';
if (((cpp == cp && oldc == ':') || *cp == ':') && cp[1]) {
+#ifdef MULTIBYTE_SUPPORT
+ int rempad;
+ char *ptr;
+ memcpy(buf, copy, (cpp - copy));
+ *cp = '\0';
+ if (isset(MULTIBYTE))
+ rempad = prechars - MB_METASTRWIDTH(copy);
+ else
+ rempad = prechars - strlen(copy);
+ ptr = buf + (cpp - copy);
+ if (rempad)
+ memset(ptr, ' ', rempad);
+ ptr += rempad;
+ memcpy(ptr, args[1], sl);
+ ptr += sl;
+ strcpy(ptr, cp + 1);
+#else /* MULTIBYTE_SUPPORT */
memset(buf, ' ', pre);
memcpy(buf, copy, (cpp - copy));
strcpy(buf + suf, cp + 1);
+#endif /* MULTIBYTE_SUPPORT */
*rp++ = ztrdup(buf);
} else
*rp++ = ztrdup(copy);
Messages sorted by:
Reverse Date,
Date,
Thread,
Author