diff options
author | Christian Neukirchen <chneukirchen@gmail.com> | 2016-01-22 18:43:14 +0100 |
---|---|---|
committer | Christian Neukirchen <chneukirchen@gmail.com> | 2016-01-22 18:43:14 +0100 |
commit | 372fdabc1fcb5eda5a90a05da3d9f9b3b5857ba5 (patch) | |
tree | 6bb3109b362610f3024cff3e42a946d154737f20 /src/usr.bin/rs/rs.c | |
parent | 193f150ac3a87fad164b3911bb69280b0728f6f1 (diff) | |
download | outils-372fdabc1fcb5eda5a90a05da3d9f9b3b5857ba5.tar.gz outils-372fdabc1fcb5eda5a90a05da3d9f9b3b5857ba5.tar.xz outils-372fdabc1fcb5eda5a90a05da3d9f9b3b5857ba5.zip |
cvs update
Diffstat (limited to 'src/usr.bin/rs/rs.c')
-rw-r--r-- | src/usr.bin/rs/rs.c | 153 |
1 files changed, 75 insertions, 78 deletions
diff --git a/src/usr.bin/rs/rs.c b/src/usr.bin/rs/rs.c index 5d702cf..bb149ff 100644 --- a/src/usr.bin/rs/rs.c +++ b/src/usr.bin/rs/rs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rs.c,v 1.28 2015/11/10 14:42:41 schwarze Exp $ */ +/* $OpenBSD: rs.c,v 1.30 2015/12/03 12:23:15 schwarze Exp $ */ /*- * Copyright (c) 1993 @@ -39,11 +39,17 @@ #include <err.h> #include <errno.h> #include <limits.h> +#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> +struct entry { + int w; /* Display width. */ + char *s; /* Multibyte string. */ +}; + long flags; #define TRANSPOSE 000001 #define MTRANSPOSE 000002 @@ -63,26 +69,27 @@ long flags; short *colwidths; int nelem; -char **elem; -char **endelem; +struct entry *elem; +struct entry *endelem; char *curline; int allocsize = BUFSIZ; -ssize_t curlen; int irows, icols; int orows, ocols; -ssize_t maxlen; +int maxwidth; int skip; int propgutter; char isep = ' ', osep = ' '; int owidth = 80, gutter = 2; +int mbsavis(char **, const char *); + void usage(void); void getargs(int, char *[]); void getfile(void); int get_line(void); -char **getptrs(char **); +struct entry *getptrs(struct entry *); void prepfile(void); -void prints(char *, int); +void prints(struct entry *, int); void putfile(void); #define INCR(ep) do { \ @@ -93,6 +100,8 @@ void putfile(void); int main(int argc, char *argv[]) { + setlocale(LC_CTYPE, ""); + if (pledge("stdio", NULL) == -1) err(1, "pledge"); @@ -110,13 +119,14 @@ main(int argc, char *argv[]) void getfile(void) { + const char delim[2] = { isep, '\0' }; char *p; - char *endp; - char **ep = NULL; + struct entry *ep; int multisep = (flags & ONEISEPONLY ? 0 : 1); int nullpad = flags & NULLPAD; - char **padto; + struct entry *padto; + curline = NULL; while (skip--) { if (get_line() == EOF) return; @@ -125,67 +135,67 @@ getfile(void) } if (get_line() == EOF) return; - if (flags & NOARGS && curlen < owidth) + if (flags & NOARGS && strlen(curline) < (size_t)owidth) flags |= ONEPERLINE; if (flags & ONEPERLINE) icols = 1; else /* count cols on first line */ - for (p = curline, endp = curline + curlen; p < endp; p++) { + for (p = curline; *p != '\0'; p++) { if (*p == isep && multisep) continue; icols++; while (*p && *p != isep) p++; } - ep = getptrs(elem); + ep = getptrs(NULL); p = curline; do { if (flags & ONEPERLINE) { - *ep = curline; + ep->w = mbsavis(&ep->s, curline); + if (maxwidth < ep->w) + maxwidth = ep->w; INCR(ep); /* prepare for next entry */ - if (maxlen < curlen) - maxlen = curlen; irows++; continue; } - for (p = curline, endp = curline + curlen; p < endp; p++) { - if (*p == isep && multisep) - continue; /* eat up column separators */ - if (*p == isep) /* must be an empty column */ - *ep = ""; - else /* store column entry */ - *ep = p; - while (p < endp && *p != isep) - p++; /* find end of entry */ - *p = '\0'; /* mark end of entry */ - if (maxlen < p - *ep) /* update maxlen */ - maxlen = p - *ep; + p = curline; + while (p != NULL && *p != '\0') { + if (*p == isep) { + p++; + if (multisep) + continue; + ep->s = ""; /* empty column */ + ep->w = 0; + } else + ep->w = mbsavis(&ep->s, strsep(&p, delim)); + if (maxwidth < ep->w) + maxwidth = ep->w; INCR(ep); /* prepare for next entry */ } irows++; /* update row count */ if (nullpad) { /* pad missing entries */ padto = elem + irows * icols; while (ep < padto) { - *ep = ""; + ep->s = ""; + ep->w = 0; INCR(ep); } } } while (get_line() != EOF); - *ep = NULL; /* mark end of pointers */ nelem = ep - elem; } void putfile(void) { - char **ep; + struct entry *ep; int i, j, n; ep = elem; if (flags & TRANSPOSE) { for (i = 0; i < orows; i++) { for (j = i; j < nelem; j += orows) - prints(ep[j], (j - i) / orows); + prints(ep + j, (j - i) / orows); putchar('\n'); } } else { @@ -193,7 +203,7 @@ putfile(void) for (j = 0; j < ocols; j++) { if (n++ >= nelem) break; - prints(*ep++, j); + prints(ep++, j); } putchar('\n'); } @@ -201,19 +211,15 @@ putfile(void) } void -prints(char *s, int col) +prints(struct entry *ep, int col) { int n; - char *p = s; - while (*p) - p++; - n = (flags & ONEOSEPONLY ? 1 : colwidths[col] - (p - s)); + n = (flags & ONEOSEPONLY ? 1 : colwidths[col] - ep->w); if (flags & RIGHTADJUST) while (n-- > 0) putchar(osep); - for (p = s; *p; p++) - putchar(*p); + fputs(ep->s, stdout); while (n-- > 0) putchar(osep); } @@ -232,18 +238,18 @@ usage(void) void prepfile(void) { - char **ep; + struct entry *ep; int i; int j; - char **lp; + struct entry *lp; int colw; int max = 0; int n; if (!nelem) exit(0); - gutter += maxlen * propgutter / 100.0; - colw = maxlen + gutter; + gutter += maxwidth * propgutter / 100.0; + colw = maxwidth + gutter; if (flags & MTRANSPOSE) { orows = icols; ocols = irows; @@ -263,33 +269,29 @@ prepfile(void) orows = nelem / ocols + (nelem % ocols ? 1 : 0); else if (ocols == 0) /* decide on cols */ ocols = nelem / orows + (nelem % orows ? 1 : 0); - lp = elem + orows * ocols; - while (lp > endelem) { - getptrs(elem + nelem); - lp = elem + orows * ocols; - } + while ((lp = elem + orows * ocols) > endelem) + (void)getptrs(NULL); if (flags & RECYCLE) { for (ep = elem + nelem; ep < lp; ep++) - *ep = *(ep - nelem); + memcpy(ep, ep - nelem, sizeof(*ep)); nelem = lp - elem; } if (!(colwidths = calloc(ocols, sizeof(short)))) errx(1, "malloc: No gutter space"); if (flags & SQUEEZE) { - if (flags & TRANSPOSE) - for (ep = elem, i = 0; i < ocols; i++) { - for (j = 0; j < orows; j++) - if ((n = strlen(*ep++)) > max) - max = n; - colwidths[i] = max + gutter; - } - else - for (ep = elem, i = 0; i < ocols; i++) { + for (ep = elem, i = 0; i < ocols; i++) { + max = 0; + if (flags & TRANSPOSE) { + for (j = 0; j < orows; j++, ep++) + if (ep->w > max) + max = ep->w; + } else { for (j = i; j < nelem; j += ocols) - if ((n = strlen(ep[j])) > max) - max = n; - colwidths[i] = max + gutter; + if (ep[j].w > max) + max = ep[j].w; } + colwidths[i] = max + gutter; + } } else { for (i = 0; i < ocols; i++) colwidths[i] = colw; @@ -306,43 +308,38 @@ prepfile(void) } int -get_line(void) /* get line; maintain curline, curlen; manage storage */ +get_line(void) { - static char *ibuf = NULL; - static size_t ibufsz = 0; + static size_t cursz; + static ssize_t curlen; if (irows > 0 && flags & DETAILSHAPE) printf(" %zd line %d\n", curlen, irows); - if ((curlen = getline(&ibuf, &ibufsz, stdin)) == EOF) { + if ((curlen = getline(&curline, &cursz, stdin)) == EOF) { if (ferror(stdin)) err(1, NULL); return EOF; } - if (curlen > 0 && ibuf[curlen - 1] == '\n') - ibuf[--curlen] = '\0'; - - if (skip >= 0 || flags & SHAPEONLY) - curline = ibuf; - else if ((curline = strdup(ibuf)) == NULL) - err(1, NULL); + if (curlen > 0 && curline[curlen - 1] == '\n') + curline[--curlen] = '\0'; return 0; } -char ** -getptrs(char **sp) +struct entry * +getptrs(struct entry *sp) { - char **p; + struct entry *p; int newsize; newsize = allocsize * 2; - p = reallocarray(elem, newsize, sizeof(char *)); + p = reallocarray(elem, newsize, sizeof(*p)); if (p == NULL) err(1, "no memory"); allocsize = newsize; - sp += p - elem; + sp = sp == NULL ? p : p + (sp - elem); elem = p; endelem = elem + allocsize; return(sp); |