aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim J. Robbins <tjr@FreeBSD.org>2004-06-24 13:42:26 +0000
committerTim J. Robbins <tjr@FreeBSD.org>2004-06-24 13:42:26 +0000
commite545e3c55c86637fa2d86ab91aa97c257483d816 (patch)
tree33fa4f6262f1d0b0103fad7bd11b3b8608a11fa8
parentb46f884b807317b6e258c0d7fbb17c166daaee4a (diff)
Add support for multibyte characters and for characters that take up
more than one column position.
Notes
Notes: svn path=/head/; revision=131051
-rw-r--r--usr.bin/expand/expand.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/usr.bin/expand/expand.c b/usr.bin/expand/expand.c
index 927c3ab36c4c..6c99db806856 100644
--- a/usr.bin/expand/expand.c
+++ b/usr.bin/expand/expand.c
@@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <wchar.h>
+#include <wctype.h>
/*
* expand - expand tabs to equivalent spaces
@@ -64,9 +66,12 @@ static void usage(void);
int
main(int argc, char *argv[])
{
+ const char *curfile;
+ wint_t wc;
int c, column;
int n;
int rval;
+ int width;
setlocale(LC_CTYPE, "");
@@ -100,22 +105,24 @@ main(int argc, char *argv[])
argc--, argv++;
continue;
}
+ curfile = argv[0];
argc--, argv++;
- }
+ } else
+ curfile = "stdin";
column = 0;
- while ((c = getchar()) != EOF) {
- switch (c) {
+ while ((wc = getwchar()) != WEOF) {
+ switch (wc) {
case '\t':
if (nstops == 0) {
do {
- putchar(' ');
+ putwchar(' ');
column++;
} while (column & 07);
continue;
}
if (nstops == 1) {
do {
- putchar(' ');
+ putwchar(' ');
column++;
} while (((column - 1) % tabstops[0]) != (tabstops[0] - 1));
continue;
@@ -124,12 +131,12 @@ main(int argc, char *argv[])
if (tabstops[n] > column)
break;
if (n == nstops) {
- putchar(' ');
+ putwchar(' ');
column++;
continue;
}
while (column < tabstops[n]) {
- putchar(' ');
+ putwchar(' ');
column++;
}
continue;
@@ -137,21 +144,25 @@ main(int argc, char *argv[])
case '\b':
if (column)
column--;
- putchar('\b');
+ putwchar('\b');
continue;
default:
- putchar(c);
- if (isprint(c))
- column++;
+ putwchar(wc);
+ if ((width = wcwidth(wc)) > 0)
+ column += width;
continue;
case '\n':
- putchar(c);
+ putwchar(wc);
column = 0;
continue;
}
}
+ if (ferror(stdin)) {
+ warn("%s", curfile);
+ rval = 1;
+ }
} while (argc > 0);
exit(rval);
}