* PATCH: multibyte print column widths
@ 2007-05-20 17:53 Peter Stephenson
0 siblings, 0 replies; only message in thread
From: Peter Stephenson @ 2007-05-20 17:53 UTC (permalink / raw)
To: Zsh hackers list
print's column width calculator doesn't take into account
multibyte characters.
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.176
diff -u -r1.176 builtin.c
--- Src/builtin.c 11 Feb 2007 00:40:19 -0000 1.176
+++ Src/builtin.c 20 May 2007 17:52:07 -0000
@@ -3617,12 +3617,58 @@
/* -c -- output in columns */
if (!fmt && (OPT_ISSET(ops,'c') || OPT_ISSET(ops,'C'))) {
int l, nc, nr, sc, n, t, i;
+#ifdef MULTIBYTE_SUPPORT
+ int *widths;
+
+ if (isset(MULTIBYTE)) {
+ int *wptr;
+
+ /*
+ * We need the character widths to align output in
+ * columns.
+ */
+ wptr = widths = (int *) zhalloc(argc * sizeof(int));
+ for (i = 0; i < argc && args[i]; i++, wptr++) {
+ int l = len[i], width = 0;
+ char *aptr = args[i];
+ mbstate_t mbs;
+
+ memset(&mbs, 0, sizeof(mbstate_t));
+ while (l > 0) {
+ wchar_t wc;
+ size_t cnt = mbrtowc(&wc, aptr, l, &mbs);
+ int wcw;
+
+ if (cnt == MB_INCOMPLETE || cnt == MB_INVALID)
+ {
+ /* treat as ordinary string */
+ width += l;
+ break;
+ }
+ wcw = wcwidth(wc);
+ /* treat unprintable as 0 */
+ if (wcw > 0)
+ width += wcw;
+ /* skip over NUL normally */
+ if (cnt == 0)
+ cnt = 1;
+ aptr += cnt;
+ l -= cnt;
+ }
+ widths[i] = width;
+ }
+ }
+ else
+ widths = len;
+#else
+ int *widths = len;
+#endif
if (OPT_ISSET(ops,'C')) {
char *eptr, *argptr = OPT_ARG(ops,'C');
nc = (int)zstrtol(argptr, &eptr, 10);
if (*eptr) {
- zwarnnam(name, "number expected after -%c: %s", 'C', argptr);
+ zwarnnam(name, "number expcted after -%c: %s", 'C', argptr);
return 1;
}
if (nc <= 0) {
@@ -3652,8 +3698,8 @@
if (i >= nr * (nc - 1))
break;
}
- if (l < len[i])
- l = len[i];
+ if (l < widths[i])
+ l = widths[i];
}
sc = l + 2;
}
@@ -3664,8 +3710,8 @@
* l: maximum length seen
*/
for (n = l = 0; n < argc; n++)
- if (l < len[n])
- l = len[n];
+ if (l < widths[n])
+ l = widths[n];
/*
* sc: column width
@@ -3686,8 +3732,8 @@
int ic;
for (ic = 0; ic < nc && n < argc; ic++, n++)
{
- l = len[n];
- fwrite(args[n], l, 1, fout);
+ fwrite(args[n], len[n], 1, fout);
+ l = widths[n];
if (n < argc)
for (; l < sc; l++)
fputc(' ', fout);
@@ -3697,8 +3743,8 @@
{
n = i;
do {
- l = len[n];
- fwrite(args[n], l, 1, fout);
+ fwrite(args[n], len[n], 1, fout);
+ l = widths[n];
for (t = nr; t && n < argc; t--, n++);
if (n < argc)
for (; l < sc; l++)
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-05-20 17:54 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-20 17:53 PATCH: multibyte print column widths Peter Stephenson
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).