From eb63b9b8f4cecb34c2478282567862bc48ef256d Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 7 Dec 2006 00:25:41 +0100 Subject: Imported from util-linux-2.10f tarball. --- text-utils/Makefile | 44 +++++++------ text-utils/col.c | 21 ++++--- text-utils/colcrt.c | 44 ++++++++----- text-utils/colrm.c | 52 ++++++++------- text-utils/column.1 | 4 +- text-utils/column.c | 178 ++++++++++++++++++++++++++++++++++++---------------- text-utils/more.c | 11 ++-- text-utils/rev.c | 36 ++++++----- text-utils/ul.c | 80 +++++++++++++++-------- 9 files changed, 291 insertions(+), 179 deletions(-) (limited to 'text-utils') diff --git a/text-utils/Makefile b/text-utils/Makefile index 66fda287e..3c4343bfb 100644 --- a/text-utils/Makefile +++ b/text-utils/Makefile @@ -24,31 +24,34 @@ endif # Where to put datebase files? -USRLIB= more.help +MOREHELP= more.help +MOREHELPFILE=$(MOREHELPDIR)/$(MOREHELP) +# MOREHELPDIR set in ../MCONFIG +CFLAGS:=$(CFLAGS) -DMOREHELPFILE=\"$(MOREHELPFILE)\" all: $(BIN) $(USRBIN) -# Programs requiring special compilation - -NEEDS_NCURSES= ul - -ifeq "$(HAVE_TERMCAP)" "no" -NEEDS_NCURSES:=$(NEEDS_NCURSES) more -else -more: - $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBTERMCAP) -endif - -$(NEEDS_NCURSES): +# more and ul use curses - maybe we can't compile them ifeq "$(HAVE_NCURSES)" "yes" +# Have ncurses - make more and ul +more ul: $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBCURSES) +more: more.o +ul: ul.o else +# Do not have ncurses - give up on ul +ul: @echo $@ not made since it requires ncurses +ifeq "$(HAVE_TERMCAP)" "yes" +more: more.o + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBTERMCAP) +else +more: + @echo $@ not made since it requires ncurses or termcap +endif endif - # Rules for hexdump - hexdump: hexdump.o conv.o display.o hexsyntax.o odsyntax.o parse.o hexdump.o: hexdump.c hexdump.h conv.o: conv.c hexdump.h @@ -58,24 +61,19 @@ odsyntax.o: odsyntax.c hexdump.h parse.o: parse.c hexdump.h # Rules for everything else - col: col.o colcrt: colcrt.o colrm: colrm.o +column.o: $(LIB)/errs.h column: column.o $(ERR_O) -more: more.o more.o: more.c $(LIB)/pathnames.h rev: rev.o -ifeq "$(HAVE_NCURSES)" "yes" -ul: ul.o -endif - install install.shadow install.text-utils: all - $(INSTALLDIR) $(BINDIR) $(USRBINDIR) $(USRLIBDIR) $(MAN1DIR) + $(INSTALLDIR) $(BINDIR) $(USRBINDIR) $(MOREHELPDIR) $(MAN1DIR) $(INSTALLBIN) $(BIN) $(BINDIR) $(INSTALLBIN) $(USRBIN) $(USRBINDIR) - $(INSTALLDAT) $(USRLIB) $(USRLIBDIR) + $(INSTALLDAT) $(MOREHELP) $(MOREHELPDIR) $(INSTALLMAN) $(MAN1) $(MAN1DIR) .PHONY: clean distclean diff --git a/text-utils/col.c b/text-utils/col.c index f08f51ad8..81026bfd4 100644 --- a/text-utils/col.c +++ b/text-utils/col.c @@ -38,7 +38,9 @@ * Wed Sep 14 22:31:17 1994: patches from Carl Christofferson * (cchris@connected.com) * 1999-02-22 Arkadiusz Mi¶kiewicz - * - added Native Language Support + * added Native Language Support + * 1999-09-19 Bruno Haible + * modified to work correctly in multi-byte locales * */ @@ -50,7 +52,8 @@ #include #include #include "nls.h" -#include + +#include "widechar.h" #define BS '\b' /* backspace */ #define TAB '\t' /* tab */ @@ -75,7 +78,7 @@ typedef struct char_str { #define CS_ALTERNATE 2 short c_column; /* column character is in */ CSET c_set; /* character set (currently only 2) */ - char c_char; /* character in question */ + wchar_t c_char; /* character in question */ } CHAR; typedef struct line_str LINE; @@ -108,14 +111,14 @@ int nblank_lines; /* # blanks after last flushed line */ int no_backspaces; /* if not to output any backspaces */ #define PUTC(ch) \ - if (putchar(ch) == EOF) \ + if (putwchar(ch) == WEOF) \ wrerr(); int main(int argc, char **argv) { extern int optind; extern char *optarg; - register int ch; + register wint_t ch; CHAR *c; CSET cur_set; /* current character set */ LINE *l; /* current line */ @@ -170,8 +173,8 @@ int main(int argc, char **argv) cur_set = last_set = CS_NORMAL; lines = l = alloc_line(); - while ((ch = getchar()) != EOF) { - if (!isgraph(ch)) { + while ((ch = getwchar()) != WEOF) { + if (!iswgraph(ch)) { switch (ch) { case BS: /* can't go back further */ if (cur_col == 0) @@ -182,7 +185,7 @@ int main(int argc, char **argv) cur_col = 0; continue; case ESC: /* just ignore EOF */ - switch(getchar()) { + switch(getwchar()) { case RLF: cur_line -= 2; break; @@ -316,6 +319,8 @@ int main(int argc, char **argv) /* missing a \n on the last line? */ nblank_lines = 2; flush_blanks(); + if (ferror(stdout) || fclose(stdout)) + return 1; return 0; } diff --git a/text-utils/colcrt.c b/text-utils/colcrt.c index 1620c2737..55138f161 100644 --- a/text-utils/colcrt.c +++ b/text-utils/colcrt.c @@ -31,16 +31,21 @@ * SUCH DAMAGE. */ - /* 1999-02-22 Arkadiusz Mi¶kiewicz - * - added Native Language Support - */ +/* + * 1999-02-22 Arkadiusz Mi¶kiewicz + * added Native Language Support + * 1999-09-19 Bruno Haible + * modified to work correctly in multi-byte locales + */ #include #include /* for close() */ #include #include "nls.h" -int plus(char c, char d); +#include "widechar.h" + +int plus(wchar_t c, wchar_t d); void move(int l, int m); void pflush(int ol); @@ -58,7 +63,7 @@ void pflush(int ol); * Option -2 forces printing of all half lines. */ -char page[267][132]; +wchar_t page[267][132]; int outline = 1; int outcol; @@ -67,13 +72,13 @@ char suppresul; char printall; char *progname; -FILE *f; int main(int argc, char **argv) { - int c; - char *cp, *dp; + FILE *f; + wint_t c; + wchar_t *cp, *dp; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); @@ -97,9 +102,9 @@ main(int argc, char **argv) argc--; argv++; } + f = stdin; do { if (argc > 0) { - close(0); if (!(f = fopen(argv[0], "r"))) { fflush(stdout); perror(argv[0]); @@ -109,7 +114,7 @@ main(int argc, char **argv) argv++; } for (;;) { - c = getc(stdin); + c = getwc(f); if (c == -1) { pflush(outline); fflush(stdout); @@ -126,7 +131,7 @@ main(int argc, char **argv) case '\017': continue; case 033: - c = getc(stdin); + c = getwc(f); switch (c) { case '9': if (outline >= 266) @@ -180,12 +185,16 @@ main(int argc, char **argv) continue; } } + if (f != stdin) + fclose(f); } while (argc > 0); fflush(stdout); + if (ferror(stdout) || fclose(stdout)) + return 1; return 0; } -int plus(char c, char d) +int plus(wchar_t c, wchar_t d) { return (c == '|' && (d == '-' || d == '_')); @@ -196,7 +205,7 @@ int first; void pflush(int ol) { register int i; - register char *cp; + register wchar_t *cp; char lastomit; int l; @@ -217,10 +226,11 @@ void pflush(int ol) continue; } lastomit = 0; - printf("%s\n", cp); + fputws(cp, stdout); + putwchar('\n'); } - bcopy(page[ol], page, (267 - ol) * 132); - bzero(page[267- ol], ol * 132); + bcopy(page[ol], page, (267 - ol) * 132 * sizeof(wchar_t)); + bzero(page[267- ol], ol * 132 * sizeof(wchar_t)); outline -= ol; outcol = 0; first = 1; @@ -228,7 +238,7 @@ void pflush(int ol) void move(int l, int m) { - register char *cp, *dp; + register wchar_t *cp, *dp; for (cp = page[l], dp = page[m]; *cp; cp++, dp++) { switch (*cp) { diff --git a/text-utils/colrm.c b/text-utils/colrm.c index b17b8fb32..0297ccb53 100644 --- a/text-utils/colrm.c +++ b/text-utils/colrm.c @@ -31,35 +31,43 @@ * SUCH DAMAGE. */ - /* 1999-02-22 Arkadiusz Mi¶kiewicz - * - added Native Language Support - */ +/* + * 1999-02-22 Arkadiusz Mi¶kiewicz + * added Native Language Support + * 1999-09-19 Bruno Haible + * modified to work correctly in multi-byte locales + */ #include +#include +#include + +#include "widechar.h" /* COLRM removes unwanted columns from a file Jeff Schriebman UC Berkeley 11-74 */ -int getn(char *ap); - int main(int argc, char **argv) { - register int c, ct, first, last; + register int ct, first, last; + register wint_t c; + + setlocale(LC_ALL, ""); first = 0; last = 0; if (argc > 1) - first = getn(*++argv); + first = atoi(*++argv); if (argc > 2) - last = getn(*++argv); + last = atoi(*++argv); start: ct = 0; loop1: - c = getc(stdin); + c = getwc(stdin); if (feof(stdin)) goto fin; if (c == '\t') @@ -69,21 +77,21 @@ loop1: else ct++; if (c == '\n') { - putc(c, stdout); + putwc(c, stdout); goto start; } if (!first || ct < first) { - putc(c, stdout); + putwc(c, stdout); goto loop1; } /* Loop getting rid of characters */ while (!last || ct < last) { - c = getc(stdin); + c = getwc(stdin); if (feof(stdin)) goto fin; if (c == '\n') { - putc(c, stdout); + putwc(c, stdout); goto start; } if (c == '\t') @@ -96,26 +104,16 @@ loop1: /* Output last of the line */ for (;;) { - c = getc(stdin); + c = getwc(stdin); if (feof(stdin)) break; - putc(c, stdout); + putwc(c, stdout); if (c == '\n') goto start; } fin: fflush(stdout); + if (ferror(stdout) || fclose(stdout)) + return 1; return 0; } - -int getn(char *ap) -{ - register int n,c; - register char *p; - - p = ap; - n = 0; - while ((c = *p++) >= '0' && c <= '9') - n = n*10 + c - '0'; - return(n); -} diff --git a/text-utils/column.1 b/text-utils/column.1 index 05d6a0fd7..6c0230ae0 100644 --- a/text-utils/column.1 +++ b/text-utils/column.1 @@ -85,8 +85,8 @@ is used to determine the size of the screen if no other information is available. .El .Sh EXAMPLES -.Dl (printf \&"PERM LINKS OWNER SIZE MONTH DAY HH:MM/YEAR NAME\en\&"\ \&;\ \&\e -.Dl ls -l \&| sed 1d) \&| column -t +.Dl (printf \&"PERM LINKS OWNER GROUP SIZE MONTH DAY HH:MM/YEAR\ NAME\en\&"\ \&\e +.Dl \&; ls -l \&| sed 1d) \&| column -t .Sh SEE ALSO .Xr colrm 1 , .Xr ls 1 , diff --git a/text-utils/column.c b/text-utils/column.c index 21236b2c8..1ad7b8dd4 100644 --- a/text-utils/column.c +++ b/text-utils/column.c @@ -31,22 +31,37 @@ * SUCH DAMAGE. */ -/* 1999-02-22 Arkadiusz Mi¶kiewicz - * - added Native Language Support +/* + * 1999-02-22 Arkadiusz Mi¶kiewicz + * added Native Language Support + * 1999-09-19 Bruno Haible + * modified to work correctly in multi-byte locales */ #include #include #include -#include #include #include #include #include #include +#include "errs.h" #include "nls.h" +#include "widechar.h" + +#ifdef ENABLE_WIDECHAR +#define wcs_width(s) wcswidth(s,wcslen(s)) +static wchar_t *mbs_to_wcs(const char *); +#else +#define wcs_width(s) strlen(s) +#define mbs_to_wcs(s) strdup(s) +static char *mtsafe_strtok(char *, const char *, char **); +#define wcstok mtsafe_strtok +#endif + void c_columnate __P((void)); void *emalloc __P((int)); void input __P((FILE *)); @@ -60,8 +75,9 @@ int termwidth = 80; /* default terminal width */ int entries; /* number of records */ int eval; /* exit value */ int maxlength; /* longest record */ -char **list; /* array of pointers to records */ -char *separator = "\t "; /* field separator for table option */ +wchar_t **list; /* array of pointers to records */ +wchar_t default_separator[] = { '\t', ' ', 0 }; +wchar_t *separator = default_separator; /* field separator for table option */ int main(argc, argv) @@ -96,7 +112,7 @@ main(argc, argv) termwidth = atoi(optarg); break; case 's': - separator = optarg; + separator = mbs_to_wcs(optarg); break; case 't': tflag = 1; @@ -133,6 +149,8 @@ main(argc, argv) c_columnate(); else r_columnate(); + if (ferror(stdout) || fclose(stdout)) + eval = 1; exit(eval); } @@ -141,29 +159,30 @@ void c_columnate() { int chcnt, col, cnt, endcol, numcols; - char **lp; + wchar_t **lp; maxlength = (maxlength + TAB) & ~(TAB - 1); numcols = termwidth / maxlength; endcol = maxlength; for (chcnt = col = 0, lp = list;; ++lp) { - chcnt += printf("%s", *lp); + fputws(*lp, stdout); + chcnt += wcs_width(*lp); if (!--entries) break; if (++col == numcols) { chcnt = col = 0; endcol = maxlength; - putchar('\n'); + putwchar('\n'); } else { while ((cnt = ((chcnt + TAB) & ~(TAB - 1))) <= endcol) { - (void)putchar('\t'); + putwchar('\t'); chcnt = cnt; } endcol += maxlength; } } if (chcnt) - putchar('\n'); + putwchar('\n'); } void @@ -182,16 +201,17 @@ r_columnate() for (row = 0; row < numrows; ++row) { endcol = maxlength; for (base = row, chcnt = col = 0; col < numcols; ++col) { - chcnt += printf("%s", list[base]); + fputws(list[base], stdout); + chcnt += wcs_width(list[base]); if ((base += numrows) >= entries) break; while ((cnt = ((chcnt + TAB) & ~(TAB - 1))) <= endcol) { - (void)putchar('\t'); + putwchar('\t'); chcnt = cnt; } endcol += maxlength; } - putchar('\n'); + putwchar('\n'); } } @@ -199,14 +219,16 @@ void print() { int cnt; - char **lp; + wchar_t **lp; - for (cnt = entries, lp = list; cnt--; ++lp) - (void)printf("%s\n", *lp); + for (cnt = entries, lp = list; cnt--; ++lp) { + fputws(*lp, stdout); + putwchar('\n'); + } } typedef struct _tbl { - char **list; + wchar_t **list; int cols, *len; } TBL; #define DEFCOLS 25 @@ -215,43 +237,47 @@ void maketbl() { TBL *t; - int coloff, cnt; - char *p, **lp; + int coloff, cnt, i; + wchar_t *p, **lp; int *lens, maxcols; TBL *tbl; - char **cols; + wchar_t **cols; + wchar_t *wcstok_state; t = tbl = emalloc(entries * sizeof(TBL)); - cols = emalloc((maxcols = DEFCOLS) * sizeof(char *)); + cols = emalloc((maxcols = DEFCOLS) * sizeof(wchar_t *)); lens = emalloc(maxcols * sizeof(int)); for (cnt = 0, lp = list; cnt < entries; ++cnt, ++lp, ++t) { - for (coloff = 0, p = *lp; - (cols[coloff] = strtok(p, separator)) != NULL; - p = NULL) - if (++coloff == maxcols) { - if (!(cols = realloc(cols, (u_int)maxcols + - DEFCOLS * sizeof(char *))) || - !(lens = realloc(lens, - (u_int)maxcols + DEFCOLS * sizeof(int)))) - err(1, NULL); - memset((char *)lens + maxcols * sizeof(int), - 0, DEFCOLS * sizeof(int)); - maxcols += DEFCOLS; - } - t->list = emalloc(coloff * sizeof(char *)); - t->len = emalloc(coloff * sizeof(int)); - for (t->cols = coloff; --coloff >= 0;) { - t->list[coloff] = cols[coloff]; - t->len[coloff] = strlen(cols[coloff]); - if (t->len[coloff] > lens[coloff]) - lens[coloff] = t->len[coloff]; + for (coloff = 0, p = *lp; + (cols[coloff] = wcstok(p, separator, &wcstok_state)) != NULL; + p = NULL) + if (++coloff == maxcols) { + if (!(cols = realloc(cols, ((u_int)maxcols + DEFCOLS) + * sizeof(wchar_t *))) || + !(lens = realloc(lens, ((u_int)maxcols + DEFCOLS) + * sizeof(int)))) + err_nomsg(1); + memset((char *)lens + maxcols * sizeof(int), + 0, DEFCOLS * sizeof(int)); + maxcols += DEFCOLS; } + t->list = emalloc(coloff * sizeof(wchar_t *)); + t->len = emalloc(coloff * sizeof(int)); + for (t->cols = coloff; --coloff >= 0;) { + t->list[coloff] = cols[coloff]; + t->len[coloff] = wcs_width(cols[coloff]); + if (t->len[coloff] > lens[coloff]) + lens[coloff] = t->len[coloff]; + } } for (cnt = 0, t = tbl; cnt < entries; ++cnt, ++t) { - for (coloff = 0; coloff < t->cols - 1; ++coloff) - (void)printf("%s%*s", t->list[coloff], - lens[coloff] - t->len[coloff] + 2, " "); - (void)printf("%s\n", t->list[coloff]); + for (coloff = 0; coloff < t->cols - 1; ++coloff) { + fputws(t->list[coloff], stdout); + for (i = lens[coloff] - t->len[coloff] + 2; i > 0; i--) + putwchar(' '); + } + fputws(t->list[coloff], stdout); + putwchar('\n'); } } @@ -264,15 +290,15 @@ input(fp) { static int maxentry; int len; - char *p, buf[MAXLINELEN]; + wchar_t *p, buf[MAXLINELEN]; if (!list) - list = emalloc((maxentry = DEFNUM) * sizeof(char *)); - while (fgets(buf, MAXLINELEN, fp)) { - for (p = buf; *p && isspace(*p); ++p); + list = emalloc((maxentry = DEFNUM) * sizeof(wchar_t *)); + while (fgetws(buf, MAXLINELEN, fp)) { + for (p = buf; *p && iswspace(*p); ++p); if (!*p) continue; - if (!(p = strchr(p, '\n'))) { + if (!(p = wcschr(p, '\n'))) { warnx(_("line too long")); eval = 1; continue; @@ -284,13 +310,55 @@ input(fp) if (entries == maxentry) { maxentry += DEFNUM; if (!(list = realloc(list, - (u_int)maxentry * sizeof(char *)))) - err(1, NULL); + (u_int)maxentry * sizeof(wchar_t *)))) + err_nomsg(1); } - list[entries++] = strdup(buf); + list[entries++] = wcsdup(buf); } } +#ifdef ENABLE_WIDECHAR +static wchar_t *mbs_to_wcs(const char *s) +{ + size_t n; + wchar_t *wcs; + + n = mbstowcs((wchar_t *)0, s, 0); + if (n < 0) + return NULL; + wcs = malloc((n + 1) * sizeof(wchar_t)); + if (!wcs) + return NULL; + if (mbstowcs(wcs, s, n + 1) < 0) + return NULL; + return wcs; +} +#endif + +#ifndef ENABLE_WIDECHAR +static char *mtsafe_strtok(char *str, const char *delim, char **ptr) +{ + if (str == NULL) { + str = *ptr; + if (str == NULL) + return NULL; + } + str += strspn(str, delim); + if (*str == '\0') { + *ptr = NULL; + return NULL; + } else { + char *token_end = strpbrk(str, delim); + if (token_end) { + *token_end = '\0'; + *ptr = token_end + 1; + } else + *ptr = NULL; + return str; + } +} +#endif + void * emalloc(size) int size; @@ -298,7 +366,7 @@ emalloc(size) char *p; if (!(p = malloc(size))) - err(1, NULL); + err_nomsg(1); memset(p, 0, size); return (p); } diff --git a/text-utils/more.c b/text-utils/more.c index 4c2a179b6..771c8d2ae 100644 --- a/text-utils/more.c +++ b/text-utils/more.c @@ -32,9 +32,10 @@ - more nls translatable strings 1999-05-09 aeb - applied a RedHat patch (setjmp->sigsetjmp); without it a second ^Z would fail. - 1999-05-09 aeb - undone Kars' work, so that more works without libcurses - (and hence can be in /bin with libcurses being in /usr/lib which may not - be mounted). However, when termcap is not present curses can still be used. + 1999-05-09 aeb - undone Kars' work, so that more works without + libcurses (and hence can be in /bin with libcurses being in /usr/lib + which may not be mounted). However, when termcap is not present curses + can still be used. */ #include @@ -56,7 +57,7 @@ #include #include "nls.h" -#define HELPFILE "/usr/lib/more.help" +/* #define MOREHELPFILE "/usr/lib/more.help" */ #define VI "/usr/bin/vi" #define Fopen(s,m) (Currline = 0,file_pos=0,fopen(s,m)) @@ -1259,7 +1260,7 @@ int command (char *filename, register FILE *f) break; case '?': case 'h': - if ((helpf = fopen (HELPFILE, "r")) == NULL) + if ((helpf = fopen (MOREHELPFILE, "r")) == NULL) error (_("Can't open help file")); if (noscroll) doclear (); copy_file (helpf); diff --git a/text-utils/rev.c b/text-utils/rev.c index dbc25cd80..82b674f25 100644 --- a/text-utils/rev.c +++ b/text-utils/rev.c @@ -38,7 +38,9 @@ * 3-Jun-1998: Patched by Nicolai Langfeldt to work better on Linux: * Handle any-length-lines. Code copied from util-linux' setpwnam.c * 1999-02-22 Arkadiusz Mi¶kiewicz - * - added Native Language Support + * added Native Language Support + * 1999-09-19 Bruno Haible + * modified to work correctly in multi-byte locales * */ @@ -50,6 +52,8 @@ #include #include "nls.h" +#include "widechar.h" + void usage __P((void)); void warn __P((const char *, ...)); @@ -58,9 +62,10 @@ main(argc, argv) int argc; char *argv[]; { - register char *filename, *t; - size_t buflen=512; - char *p=malloc(buflen); + register char *filename; + register wchar_t *t; + size_t buflen = 512; + wchar_t *p = malloc(buflen*sizeof(wchar_t)); size_t len; FILE *fp; int ch, rval; @@ -93,9 +98,9 @@ main(argc, argv) filename = *argv++; } - while (fgets(p, buflen, fp)) { + while (fgetws(p, buflen, fp)) { - len = strlen(p); + len = wcslen(p); /* This is my hack from setpwnam.c -janl */ while (p[len-1] != '\n' && !feof(fp)) { @@ -104,32 +109,33 @@ main(argc, argv) /* So now we double the buffer size */ buflen *= 2; - p = realloc(p, buflen); + p = realloc(p, buflen*sizeof(wchar_t)); if (p == NULL) { fprintf(stderr,_("Unable to allocate bufferspace\n")); exit(1); } /* And fill the rest of the buffer */ - if (fgets(&p[len], buflen/2, fp) == NULL) break; + if (fgetws(&p[len], buflen/2, fp) == NULL) break; - len = strlen(p); + len = wcslen(p); /* That was a lot of work for nothing. Gimme perl! */ } - t = p + len - 1 - (*(p+len-1)=='\r' - || *(p+len-1)=='\n'); + t = p + len - 1 - (*(p+len-1)=='\r' || *(p+len-1)=='\n'); for ( ; t >= p; --t) - if(strcmp(t, "\0") != 0) - putchar(*t); - putchar('\n'); + if (*t != 0) + putwchar(*t); + putwchar('\n'); } + fflush(fp); if (ferror(fp)) { warn("%s: %s", filename, strerror(errno)); rval = 1; } - (void)fclose(fp); + if (fclose(fp)) + rval = 1; } while(*argv); exit(rval); } diff --git a/text-utils/ul.c b/text-utils/ul.c index a99de9d88..7745cce4d 100644 --- a/text-utils/ul.c +++ b/text-utils/ul.c @@ -32,12 +32,13 @@ */ /* -** modified by Kars de Jong to use terminfo instead -** of termcap. - 1999-02-22 Arkadiusz Mi¶kiewicz - - added Native Language Support - -*/ + * modified by Kars de Jong + * to use terminfo instead of termcap. + * 1999-02-22 Arkadiusz Mi¶kiewicz + * added Native Language Support + * 1999-09-19 Bruno Haible + * modified to work correctly in multi-byte locales + */ #include #include /* for getopt(), isatty() */ @@ -47,6 +48,21 @@ #include /* for INT_MAX */ #include "nls.h" +#include "widechar.h" + +#ifdef ENABLE_WIDECHAR +static int put1wc(int c) /* Output an ASCII character as a wide character */ +{ + if (putwchar(c) == WEOF) + return EOF; + else + return c; +} +#define putwp(s) tputs(s,1,put1wc) +#else +#define putwp(s) putp(s) +#endif + void filter(FILE *f); void flushln(void); void overstrike(void); @@ -55,7 +71,7 @@ void initbuf(void); void fwd(void); void reverse(void); void initinfo(void); -void outc(int c); +void outc(wint_t c); void setmode(int newmode); void setcol(int newcol); @@ -81,7 +97,7 @@ char *CURS_UP, *CURS_RIGHT, *CURS_LEFT, struct CHAR { char c_mode; - char c_char; + wchar_t c_char; } ; struct CHAR *obuf; @@ -92,7 +108,7 @@ int halfpos; int upln; int iflag; -#define PRINT(s) if (s == NULL) /* void */; else putp(s) +#define PRINT(s) if (s == NULL) /* void */; else putwp(s) int main(int argc, char **argv) { @@ -156,14 +172,16 @@ int main(int argc, char **argv) } else filter(f); } + if (ferror(stdout) || fclose(stdout)) + return 1; return 0; } void filter(FILE *f) { - int c; + wint_t c; - while ((c = getc(f)) != EOF) switch(c) { + while ((c = getwc(f)) != WEOF) switch(c) { case '\b': setcol(col - 1); @@ -186,7 +204,7 @@ void filter(FILE *f) continue; case IESC: - switch (c = getc(f)) { + switch (c = getwc(f)) { case HREV: if (halfpos == 0) { @@ -241,11 +259,11 @@ void filter(FILE *f) case '\f': flushln(); - putchar('\f'); + putwchar('\f'); continue; default: - if (c < ' ') /* non printing */ + if (!iswprint(c)) /* non printing */ continue; if (obuf[col].c_char == '\0') { obuf[col].c_char = c; @@ -290,7 +308,7 @@ void flushln() } if (must_overstrike && hadmodes) overstrike(); - putchar('\n'); + putwchar('\n'); if (iflag && hadmodes) iattr(); (void)fflush(stdout); @@ -306,8 +324,12 @@ void flushln() void overstrike() { register int i; - char lbuf[256]; - register char *cp = lbuf; +#ifdef __GNUC__ + register wchar_t *lbuf = __builtin_alloca((maxcol+1)*sizeof(wchar_t)); +#else + wchar_t lbuf[256]; +#endif + register wchar_t *cp = lbuf; int hadbold=0; /* Set up overstrike buffer */ @@ -325,25 +347,29 @@ void overstrike() hadbold=1; break; } - putchar('\r'); + putwchar('\r'); for (*cp=' '; *cp==' '; cp--) *cp = 0; for (cp=lbuf; *cp; cp++) - putchar(*cp); + putwchar(*cp); if (hadbold) { - putchar('\r'); + putwchar('\r'); for (cp=lbuf; *cp; cp++) - putchar(*cp=='_' ? ' ' : *cp); - putchar('\r'); + putwchar(*cp=='_' ? ' ' : *cp); + putwchar('\r'); for (cp=lbuf; *cp; cp++) - putchar(*cp=='_' ? ' ' : *cp); + putwchar(*cp=='_' ? ' ' : *cp); } } void iattr() { register int i; +#ifdef __GNUC__ + register char *lbuf = __builtin_alloca((maxcol+1)*sizeof(char)); +#else char lbuf[256]; +#endif register char *cp = lbuf; for (i=0; i