=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/rs/rs.c,v retrieving revision 1.29 retrieving revision 1.30 diff -c -r1.29 -r1.30 *** src/usr.bin/rs/rs.c 2015/11/14 17:03:02 1.29 --- src/usr.bin/rs/rs.c 2015/12/03 12:23:15 1.30 *************** *** 1,4 **** ! /* $OpenBSD: rs.c,v 1.29 2015/11/14 17:03:02 schwarze Exp $ */ /*- * Copyright (c) 1993 --- 1,4 ---- ! /* $OpenBSD: rs.c,v 1.30 2015/12/03 12:23:15 schwarze Exp $ */ /*- * Copyright (c) 1993 *************** *** 39,49 **** --- 39,55 ---- #include #include #include + #include #include #include #include #include + struct entry { + int w; /* Display width. */ + char *s; /* Multibyte string. */ + }; + long flags; #define TRANSPOSE 000001 #define MTRANSPOSE 000002 *************** *** 63,88 **** short *colwidths; int nelem; ! char **elem; ! char **endelem; char *curline; int allocsize = BUFSIZ; - ssize_t curlen; int irows, icols; int orows, ocols; ! ssize_t maxlen; int skip; int propgutter; char isep = ' ', osep = ' '; int owidth = 80, gutter = 2; void usage(void); void getargs(int, char *[]); void getfile(void); int get_line(void); ! char **getptrs(char **); void prepfile(void); ! void prints(char *, int); void putfile(void); #define INCR(ep) do { \ --- 69,95 ---- short *colwidths; int nelem; ! struct entry *elem; ! struct entry *endelem; char *curline; int allocsize = BUFSIZ; int irows, icols; int orows, ocols; ! 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); ! struct entry *getptrs(struct entry *); void prepfile(void); ! void prints(struct entry *, int); void putfile(void); #define INCR(ep) do { \ *************** *** 93,98 **** --- 100,107 ---- int main(int argc, char *argv[]) { + setlocale(LC_CTYPE, ""); + if (pledge("stdio", NULL) == -1) err(1, "pledge"); *************** *** 110,122 **** void getfile(void) { char *p; ! char *endp; ! char **ep = NULL; int multisep = (flags & ONEISEPONLY ? 0 : 1); int nullpad = flags & NULLPAD; ! char **padto; while (skip--) { if (get_line() == EOF) return; --- 119,132 ---- void getfile(void) { + const char delim[2] = { isep, '\0' }; char *p; ! struct entry *ep; int multisep = (flags & ONEISEPONLY ? 0 : 1); int nullpad = flags & NULLPAD; ! struct entry *padto; + curline = NULL; while (skip--) { if (get_line() == EOF) return; *************** *** 125,191 **** } if (get_line() == EOF) return; ! if (flags & NOARGS && curlen < owidth) flags |= ONEPERLINE; if (flags & ONEPERLINE) icols = 1; else /* count cols on first line */ ! for (p = curline, endp = curline + curlen; p < endp; p++) { if (*p == isep && multisep) continue; icols++; while (*p && *p != isep) p++; } ! ep = getptrs(elem); p = curline; do { if (flags & ONEPERLINE) { ! *ep = curline; 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; INCR(ep); /* prepare for next entry */ } irows++; /* update row count */ if (nullpad) { /* pad missing entries */ padto = elem + irows * icols; while (ep < padto) { ! *ep = ""; INCR(ep); } } } while (get_line() != EOF); - *ep = NULL; /* mark end of pointers */ nelem = ep - elem; } void putfile(void) { ! char **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); putchar('\n'); } } else { --- 135,201 ---- } if (get_line() == EOF) return; ! if (flags & NOARGS && strlen(curline) < (size_t)owidth) flags |= ONEPERLINE; if (flags & ONEPERLINE) icols = 1; else /* count cols on first line */ ! for (p = curline; *p != '\0'; p++) { if (*p == isep && multisep) continue; icols++; while (*p && *p != isep) p++; } ! ep = getptrs(NULL); p = curline; do { if (flags & ONEPERLINE) { ! ep->w = mbsavis(&ep->s, curline); ! if (maxwidth < ep->w) ! maxwidth = ep->w; INCR(ep); /* prepare for next entry */ irows++; continue; } ! 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->s = ""; ! ep->w = 0; INCR(ep); } } } while (get_line() != EOF); nelem = ep - elem; } void putfile(void) { ! 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); putchar('\n'); } } else { *************** *** 193,199 **** for (j = 0; j < ocols; j++) { if (n++ >= nelem) break; ! prints(*ep++, j); } putchar('\n'); } --- 203,209 ---- for (j = 0; j < ocols; j++) { if (n++ >= nelem) break; ! prints(ep++, j); } putchar('\n'); } *************** *** 201,219 **** } void ! prints(char *s, int col) { int n; - char *p = s; ! while (*p) ! p++; ! n = (flags & ONEOSEPONLY ? 1 : colwidths[col] - (p - s)); if (flags & RIGHTADJUST) while (n-- > 0) putchar(osep); ! for (p = s; *p; p++) ! putchar(*p); while (n-- > 0) putchar(osep); } --- 211,225 ---- } void ! prints(struct entry *ep, int col) { int n; ! n = (flags & ONEOSEPONLY ? 1 : colwidths[col] - ep->w); if (flags & RIGHTADJUST) while (n-- > 0) putchar(osep); ! fputs(ep->s, stdout); while (n-- > 0) putchar(osep); } *************** *** 232,249 **** void prepfile(void) { ! char **ep; int i; int j; ! char **lp; int colw; int max = 0; int n; if (!nelem) exit(0); ! gutter += maxlen * propgutter / 100.0; ! colw = maxlen + gutter; if (flags & MTRANSPOSE) { orows = icols; ocols = irows; --- 238,255 ---- void prepfile(void) { ! struct entry *ep; int i; int j; ! struct entry *lp; int colw; int max = 0; int n; if (!nelem) exit(0); ! gutter += maxwidth * propgutter / 100.0; ! colw = maxwidth + gutter; if (flags & MTRANSPOSE) { orows = icols; ocols = irows; *************** *** 263,276 **** 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; ! } if (flags & RECYCLE) { for (ep = elem + nelem; ep < lp; ep++) ! *ep = *(ep - nelem); nelem = lp - elem; } if (!(colwidths = calloc(ocols, sizeof(short)))) --- 269,279 ---- orows = nelem / ocols + (nelem % ocols ? 1 : 0); else if (ocols == 0) /* decide on cols */ ocols = nelem / orows + (nelem % orows ? 1 : 0); ! while ((lp = elem + orows * ocols) > endelem) ! (void)getptrs(NULL); if (flags & RECYCLE) { for (ep = elem + nelem; ep < lp; ep++) ! memcpy(ep, ep - nelem, sizeof(*ep)); nelem = lp - elem; } if (!(colwidths = calloc(ocols, sizeof(short)))) *************** *** 279,291 **** for (ep = elem, i = 0; i < ocols; i++) { max = 0; if (flags & TRANSPOSE) { ! for (j = 0; j < orows; j++) ! if ((n = strlen(*ep++)) > max) ! max = n; } else { for (j = i; j < nelem; j += ocols) ! if ((n = strlen(ep[j])) > max) ! max = n; } colwidths[i] = max + gutter; } --- 282,294 ---- 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 (ep[j].w > max) ! max = ep[j].w; } colwidths[i] = max + gutter; } *************** *** 305,347 **** } int ! get_line(void) /* get line; maintain curline, curlen; manage storage */ { ! static char *ibuf = NULL; ! static size_t ibufsz = 0; if (irows > 0 && flags & DETAILSHAPE) printf(" %zd line %d\n", curlen, irows); ! if ((curlen = getline(&ibuf, &ibufsz, 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); - return 0; } ! char ** ! getptrs(char **sp) { ! char **p; int newsize; newsize = allocsize * 2; ! p = reallocarray(elem, newsize, sizeof(char *)); if (p == NULL) err(1, "no memory"); allocsize = newsize; ! sp += p - elem; elem = p; endelem = elem + allocsize; return(sp); --- 308,345 ---- } int ! get_line(void) { ! static size_t cursz; ! static ssize_t curlen; if (irows > 0 && flags & DETAILSHAPE) printf(" %zd line %d\n", curlen, irows); ! if ((curlen = getline(&curline, &cursz, stdin)) == EOF) { if (ferror(stdin)) err(1, NULL); return EOF; } ! if (curlen > 0 && curline[curlen - 1] == '\n') ! curline[--curlen] = '\0'; return 0; } ! struct entry * ! getptrs(struct entry *sp) { ! struct entry *p; int newsize; newsize = allocsize * 2; ! p = reallocarray(elem, newsize, sizeof(*p)); if (p == NULL) err(1, "no memory"); allocsize = newsize; ! sp = sp == NULL ? p : p + (sp - elem); elem = p; endelem = elem + allocsize; return(sp);