From 47396828bbf14f22aefcb96dc6a4528f0027c86f Mon Sep 17 00:00:00 2001 From: tjr Date: Thu, 24 Jun 2004 15:12:29 +0000 Subject: Add support for multibyte characters and characters that take up more than one column position. --- usr.bin/fold/fold.c | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/usr.bin/fold/fold.c b/usr.bin/fold/fold.c index fc5cb16..59d8fc5 100644 --- a/usr.bin/fold/fold.c +++ b/usr.bin/fold/fold.c @@ -49,7 +49,6 @@ static char sccsid[] = "@(#)fold.c 8.1 (Berkeley) 6/6/93"; #include __FBSDID("$FreeBSD$"); -#include #include #include #include @@ -57,11 +56,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #define DEFLINEWIDTH 80 void fold(int); -static int newpos(int, int); +static int newpos(int, wint_t); static void usage(void); int bflag; /* Count bytes, not columns */ @@ -141,64 +142,66 @@ usage(void) void fold(int width) { - static char *buf; + static wchar_t *buf; static int buf_max; - int ch, col, i, indx, space; + int col, i, indx, space; + wint_t ch; col = indx = 0; - while ((ch = getchar()) != EOF) { + while ((ch = getwchar()) != WEOF) { if (ch == '\n') { - if (indx != 0) - fwrite(buf, 1, indx, stdout); - putchar('\n'); + wprintf(L"%.*ls\n", indx, buf); col = indx = 0; continue; } if ((col = newpos(col, ch)) > width) { if (sflag) { i = indx; - while (--i >= 0 && !isblank((unsigned char)buf[i])) + while (--i >= 0 && !iswblank(buf[i])) ; space = i; } if (sflag && space != -1) { space++; - fwrite(buf, 1, space, stdout); - memmove(buf, buf + space, indx - space); + wprintf(L"%.*ls\n", space, buf); + wmemmove(buf, buf + space, indx - space); indx -= space; col = 0; for (i = 0; i < indx; i++) - col = newpos(col, - (unsigned char)buf[i]); + col = newpos(col, buf[i]); } else { - fwrite(buf, 1, indx, stdout); + wprintf(L"%.*ls\n", indx, buf); col = indx = 0; } - putchar('\n'); col = newpos(col, ch); } if (indx + 1 > buf_max) { buf_max += LINE_MAX; - if ((buf = realloc(buf, buf_max)) == NULL) + buf = realloc(buf, sizeof(*buf) * buf_max); + if (buf == NULL) err(1, "realloc()"); } buf[indx++] = ch; } if (indx != 0) - fwrite(buf, 1, indx, stdout); + wprintf(L"%.*ls", indx, buf); } /* * Update the current column position for a character. */ static int -newpos(int col, int ch) +newpos(int col, wint_t ch) { - - if (bflag) - ++col; - else + char buf[MB_LEN_MAX]; + size_t len; + int w; + + if (bflag) { + len = wcrtomb(buf, ch, NULL); + col += len; + } else switch (ch) { case '\b': if (col > 0) @@ -211,8 +214,8 @@ newpos(int col, int ch) col = (col + 8) & ~7; break; default: - if (isprint(ch)) - ++col; + if ((w = wcwidth(ch)) > 0) + col += w; break; } -- cgit v1.1