diff --git a/usr.bin/Makefile b/usr.bin/Makefile index e3d58a3524cf..3ccc626bdfc8 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -1,294 +1,294 @@ # From: @(#)Makefile 8.3 (Berkeley) 1/7/94 # $FreeBSD$ .include SUBDIR= alias \ apply \ asa \ awk \ backlight \ banner \ basename \ beep \ bintrans \ brandelf \ bsdcat \ bsddialog \ bsdiff \ bzip2 \ bzip2recover \ cap_mkdb \ chat \ chpass \ cksum \ cmp \ col \ colrm \ column \ comm \ compress \ cpuset \ csplit \ ctlstat \ cut \ diff \ dirname \ du \ elfctl \ elfdump \ enigma \ env \ etdump \ expand \ false \ fetch \ find \ fmt \ fold \ fstat \ fsync \ gcore \ gencat \ getaddrinfo \ getconf \ getent \ getopt \ grep \ gzip \ head \ hexdump \ id \ ident \ ipcrm \ ipcs \ join \ jot \ keylogin \ keylogout \ killall \ ktrace \ ktrdump \ lam \ ldd \ leave \ less \ lessecho \ lesskey \ limits \ locale \ localedef \ lock \ lockf \ logger \ login \ logins \ logname \ look \ lorder \ lsvfs \ lzmainfo \ m4 \ mandoc \ mesg \ ministat \ mkdep \ mkfifo \ mkimg \ mktemp \ mkuzip \ mt \ ncal \ ncurses \ netstat \ newgrp \ nfsstat \ nice \ nl \ nohup \ pagesize \ passwd \ paste \ patch \ pathchk \ perror \ posixshmcontrol \ pr \ printenv \ printf \ proccontrol \ procstat \ protect \ rctl \ renice \ resizewin \ rev \ revoke \ rpcinfo \ - rs \ rup \ ruptime \ rusers \ rwall \ rwho \ script \ sdiff \ sed \ seq \ shar \ showmount \ sockstat \ soelim \ sort \ split \ stat \ stdbuf \ strings \ su \ systat \ tail \ tar \ tcopy \ tee \ time \ timeout \ tip \ top \ touch \ tr \ true \ truncate \ tsort \ tty \ uname \ unexpand \ uniq \ unzip \ units \ unvis \ vis \ vmstat \ w \ wall \ wc \ wg \ what \ whereis \ which \ whois \ write \ xargs \ xinstall \ xo \ xz \ xzdec \ yes \ zstd # NB: keep these sorted by MK_* knobs SUBDIR.${MK_ACCT}+= lastcomm SUBDIR.${MK_AT}+= at SUBDIR.${MK_ATM}+= atm SUBDIR.${MK_BLUETOOTH}+= bluetooth SUBDIR.${MK_BSD_CPIO}+= cpio SUBDIR.${MK_CALENDAR}+= calendar .if ${MK_CLANG} != "no" || ${MK_LLVM_BINUTILS} != "no" || \ ${MK_LLD} != "no" || ${MK_LLDB} != "no" SUBDIR+= clang .endif SUBDIR.${MK_DIALOG}+= dpv SUBDIR.${MK_EE}+= ee SUBDIR.${MK_FILE}+= file SUBDIR.${MK_FINGER}+= finger SUBDIR.${MK_FTP}+= ftp SUBDIR.${MK_GAMES}+= caesar SUBDIR.${MK_GAMES}+= factor SUBDIR.${MK_GAMES}+= fortune SUBDIR.${MK_GAMES}+= grdc SUBDIR.${MK_GAMES}+= morse SUBDIR.${MK_GAMES}+= number SUBDIR.${MK_GAMES}+= pom SUBDIR.${MK_GAMES}+= primes SUBDIR.${MK_GAMES}+= random SUBDIR.${MK_CXX}+= dtc +SUBDIR.${MK_CXX}+= rs .if ${MK_GH_BC} == "yes" SUBDIR+= gh-bc .else SUBDIR.${MK_OPENSSL}+= bc SUBDIR.${MK_OPENSSL}+= dc .endif SUBDIR.${MK_HESIOD}+= hesinfo SUBDIR.${MK_ICONV}+= iconv SUBDIR.${MK_ICONV}+= mkcsmapper SUBDIR.${MK_ICONV}+= mkesdb SUBDIR.${MK_ISCSI}+= iscsictl SUBDIR.${MK_KDUMP}+= kdump SUBDIR.${MK_KDUMP}+= truss SUBDIR.${MK_KERBEROS_SUPPORT}+= compile_et SUBDIR.${MK_LDNS_UTILS}+= drill SUBDIR.${MK_LDNS_UTILS}+= host SUBDIR.${MK_LIB32}+= ldd32 SUBDIR.${MK_LOCATE}+= locate # XXX msgs? SUBDIR.${MK_MAIL}+= biff SUBDIR.${MK_MAIL}+= from SUBDIR.${MK_MAIL}+= mail SUBDIR.${MK_MAIL}+= msgs SUBDIR.${MK_MAKE}+= bmake SUBDIR.${MK_MAN_UTILS}+= man SUBDIR.${MK_NETCAT}+= nc SUBDIR.${MK_NIS}+= ypcat SUBDIR.${MK_NIS}+= ypmatch SUBDIR.${MK_NIS}+= ypwhich SUBDIR.${MK_OPENSSH}+= ssh-copy-id SUBDIR.${MK_OPENSSL}+= chkey SUBDIR.${MK_OPENSSL}+= newkey SUBDIR.${MK_QUOTAS}+= quota SUBDIR.${MK_SENDMAIL}+= vacation SUBDIR.${MK_TALK}+= talk SUBDIR.${MK_TELNET}+= telnet SUBDIR.${MK_TESTS_SUPPORT}.${MK_CXX}+= kyua SUBDIR.${MK_TESTS}+= tests SUBDIR.${MK_TEXTPROC}+= ul SUBDIR.${MK_TFTP}+= tftp .if ${MK_LLVM_BINUTILS} == "no" # Only build the elftoolchain tools if we aren't using the LLVM ones. SUBDIR.${MK_TOOLCHAIN}+= addr2line SUBDIR.${MK_TOOLCHAIN}+= ar SUBDIR.${MK_TOOLCHAIN}+= nm SUBDIR.${MK_TOOLCHAIN}+= objcopy SUBDIR.${MK_TOOLCHAIN}+= readelf SUBDIR.${MK_TOOLCHAIN}+= size .endif SUBDIR.${MK_TOOLCHAIN}+= c89 SUBDIR.${MK_TOOLCHAIN}+= c99 SUBDIR.${MK_TOOLCHAIN}+= ctags .if ${MK_LLVM_CXXFILT} == "no" SUBDIR.${MK_TOOLCHAIN}+= cxxfilt .endif SUBDIR.${MK_TOOLCHAIN}+= file2c SUBDIR.${MK_TOOLCHAIN}+= gprof SUBDIR.${MK_TOOLCHAIN}+= indent SUBDIR.${MK_TOOLCHAIN}+= lex SUBDIR.${MK_TOOLCHAIN}+= mkstr SUBDIR.${MK_TOOLCHAIN}+= rpcgen SUBDIR.${MK_TOOLCHAIN}+= unifdef SUBDIR.${MK_TOOLCHAIN}+= xstr SUBDIR.${MK_TOOLCHAIN}+= yacc SUBDIR.${MK_VI}+= vi SUBDIR.${MK_VT}+= vtfontcvt SUBDIR.${MK_USB}+= usbhidaction SUBDIR.${MK_USB}+= usbhidctl SUBDIR.${MK_UTMPX}+= last .if ${MK_CXX} != "no" SUBDIR.${MK_UTMPX}+= users .endif SUBDIR.${MK_UTMPX}+= who SUBDIR.${MK_OFED}+= ofed .include SUBDIR_PARALLEL= .include diff --git a/usr.bin/rs/Makefile b/usr.bin/rs/Makefile index 20da0d9dc9b6..b47899d0f80b 100644 --- a/usr.bin/rs/Makefile +++ b/usr.bin/rs/Makefile @@ -1,11 +1,11 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ .include -PROG= rs +PROG_CXX= rs HAS_TESTS= SUBDIR.${MK_TESTS}+= tests .include diff --git a/usr.bin/rs/rs.c b/usr.bin/rs/rs.cc similarity index 81% rename from usr.bin/rs/rs.c rename to usr.bin/rs/rs.cc index 046bdc125f00..c20956b3b5e1 100644 --- a/usr.bin/rs/rs.c +++ b/usr.bin/rs/rs.cc @@ -1,558 +1,513 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * rs - reshape a data array * Author: John Kunze, Office of Comp. Affairs, UCB * BEWARE: lots of unfinished edges */ #include #include #include -#include #include #include #include +#include static long flags; #define TRANSPOSE 000001 #define MTRANSPOSE 000002 #define ONEPERLINE 000004 #define ONEISEPONLY 000010 #define ONEOSEPONLY 000020 #define NOTRIMENDCOL 000040 #define SQUEEZE 000100 #define SHAPEONLY 000200 #define DETAILSHAPE 000400 #define RIGHTADJUST 001000 #define NULLPAD 002000 #define RECYCLE 004000 #define SKIPPRINT 010000 #define ICOLBOUNDS 020000 #define OCOLBOUNDS 040000 #define ONEPERCHAR 0100000 #define NOARGS 0200000 static short *colwidths; static short *cord; static short *icbd; static short *ocbd; -static int nelem; -static char **elem; -static char **endelem; +static std::vector elem; static char *curline; -static int allocsize = BUFSIZ; -static int curlen; -static int irows, icols; -static int orows = 0, ocols = 0; -static int maxlen; +static size_t curlen; +static size_t irows, icols; +static size_t orows = 0, ocols = 0; +static size_t maxlen; static int skip; static int propgutter; static char isep = ' ', osep = ' '; static char blank[] = ""; static int owidth = 80, gutter = 2; static void getargs(int, char *[]); static void getfile(void); static int get_line(void); static char *getlist(short **, char *); static char *getnum(int *, char *, int); -static char **getptrs(char **); static void prepfile(void); static void prints(char *, int); static void putfile(void); static void usage(void); -#define INCR(ep) do { \ - if (++ep >= endelem) \ - ep = getptrs(ep); \ -} while(0) - int main(int argc, char *argv[]) { getargs(argc, argv); getfile(); if (flags & SHAPEONLY) { - printf("%d %d\n", irows, icols); + printf("%zu %zu\n", irows, icols); exit(0); } prepfile(); putfile(); exit(0); } static void getfile(void) { char *p, *sp; char *endp; - char **ep; int c; - int len; int multisep = (flags & ONEISEPONLY ? 0 : 1); int nullpad = flags & NULLPAD; - char **padto; + size_t len, padto; while (skip--) { c = get_line(); if (flags & SKIPPRINT) puts(curline); if (c == EOF) return; } get_line(); - if (flags & NOARGS && curlen < owidth) + if (flags & NOARGS && curlen < (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++) { if (*p == isep && multisep) continue; icols++; while (*p && *p != isep) p++; } - ep = getptrs(elem); do { if (flags & ONEPERLINE) { - *ep = curline; - INCR(ep); /* prepare for next entry */ + elem.push_back(curline); 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 = blank; + elem.push_back(blank); else /* store column entry */ - *ep = p; + elem.push_back(p); sp = p; while (p < endp && *p != isep) p++; /* find end of entry */ *p = '\0'; /* mark end of entry */ len = p - sp; if (maxlen < len) /* update maxlen */ maxlen = len; - INCR(ep); /* prepare for next entry */ } irows++; /* update row count */ if (nullpad) { /* pad missing entries */ - padto = elem + irows * icols; - while (ep < padto) { - *ep = blank; - INCR(ep); - } + padto = irows * icols; + elem.resize(padto, blank); } } while (get_line() != EOF); - *ep = 0; /* mark end of pointers */ - nelem = ep - elem; } static void putfile(void) { - char **ep; - int i, j, k; + size_t i, j, k; - ep = elem; if (flags & TRANSPOSE) for (i = 0; i < orows; i++) { - for (j = i; j < nelem; j += orows) - prints(ep[j], (j - i) / orows); + for (j = i; j < elem.size(); j += orows) + prints(elem[j], (j - i) / orows); putchar('\n'); } else for (i = k = 0; i < orows; i++) { for (j = 0; j < ocols; j++, k++) - if (k < nelem) - prints(ep[k], j); + if (k < elem.size()) + prints(elem[k], j); putchar('\n'); } } static 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); } static void usage(void) { fprintf(stderr, "usage: rs [-[csCS][x][kKgGw][N]tTeEnyjhHmz] [rows [cols]]\n"); exit(1); } static void prepfile(void) { - char **ep; - int i; - int j; - char **lp; - int colw; - int max; - int n; + size_t i, j; + size_t colw, max, n, orig_size, padto; - if (!nelem) + if (elem.empty()) exit(0); gutter += maxlen * propgutter / 100.0; colw = maxlen + gutter; if (flags & MTRANSPOSE) { orows = icols; ocols = irows; } else if (orows == 0 && ocols == 0) { /* decide rows and cols */ ocols = owidth / colw; if (ocols == 0) { - warnx("display width %d is less than column width %d", + warnx("display width %d is less than column width %zu", owidth, colw); ocols = 1; } - if (ocols > nelem) - ocols = nelem; - orows = nelem / ocols + (nelem % ocols ? 1 : 0); + if (ocols > elem.size()) + ocols = elem.size(); + orows = elem.size() / ocols + (elem.size() % ocols ? 1 : 0); } else if (orows == 0) /* decide on rows */ - orows = nelem / ocols + (nelem % ocols ? 1 : 0); + orows = elem.size() / ocols + (elem.size() % 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; - } + ocols = elem.size() / orows + (elem.size() % orows ? 1 : 0); + padto = orows * ocols; + orig_size = elem.size(); if (flags & RECYCLE) { - for (ep = elem + nelem; ep < lp; ep++) - *ep = *(ep - nelem); - nelem = lp - elem; + for (i = 0; elem.size() < padto; i++) + elem.push_back(elem[i % orig_size]); } if (!(colwidths = (short *) malloc(ocols * sizeof(short)))) errx(1, "malloc"); if (flags & SQUEEZE) { - ep = elem; - if (flags & TRANSPOSE) + if (flags & TRANSPOSE) { + auto it = elem.begin(); for (i = 0; i < ocols; i++) { max = 0; - for (j = 0; *ep != NULL && j < orows; j++) - if ((n = strlen(*ep++)) > max) + for (j = 0; it != elem.end() && j < orows; j++) + if ((n = strlen(*it++)) > max) max = n; colwidths[i] = max + gutter; } - else + } else { for (i = 0; i < ocols; i++) { max = 0; - for (j = i; j < nelem; j += ocols) - if ((n = strlen(ep[j])) > max) + for (j = i; j < elem.size(); j += ocols) + if ((n = strlen(elem[j])) > max) max = n; colwidths[i] = max + gutter; } + } } /* for (i = 0; i < orows; i++) { - for (j = i; j < nelem; j += orows) - prints(ep[j], (j - i) / orows); + for (j = i; j < elem.size(); j += orows) + prints(elem[j], (j - i) / orows); putchar('\n'); } - else + else { + auto it = elem.begin(); for (i = 0; i < orows; i++) { for (j = 0; j < ocols; j++) - prints(*ep++, j); + prints(*it++, j); putchar('\n'); }*/ else for (i = 0; i < ocols; i++) colwidths[i] = colw; if (!(flags & NOTRIMENDCOL)) { if (flags & RIGHTADJUST) colwidths[0] -= gutter; else colwidths[ocols - 1] = 0; } - n = orows * ocols; - if (n > nelem && (flags & RECYCLE)) - nelem = n; /*for (i = 0; i < ocols; i++) - warnx("%d is colwidths, nelem %d", colwidths[i], nelem);*/ + warnx("%d is colwidths, nelem %zu", colwidths[i], elem.size());*/ } #define BSIZE (LINE_MAX * 2) static char ibuf[BSIZE]; static int get_line(void) /* get line; maintain curline, curlen; manage storage */ { static int putlength; static char *endblock = ibuf + BSIZE; char *p; int c, i; - if (!irows) { + if (irows == 0) { curline = ibuf; putlength = flags & DETAILSHAPE; } else if (skip <= 0) { /* don't waste storage */ curline += curlen + 1; if (putlength) { /* print length, recycle storage */ - printf(" %d line %d\n", curlen, irows); + printf(" %zu line %zu\n", curlen, irows); curline = ibuf; } } if (!putlength && endblock - curline < LINE_MAX + 1) { /* need storage */ /*ww = endblock-curline; tt += ww;*/ /*printf("#wasted %d total %d\n",ww,tt);*/ if (!(curline = (char *) malloc(BSIZE))) errx(1, "file too large"); endblock = curline + BSIZE; /*printf("#endb %d curline %d\n",endblock,curline);*/ } for (p = curline, i = 0;; *p++ = c, i++) { if ((c = getchar()) == EOF) break; if (i >= LINE_MAX) errx(1, "maximum line length (%d) exceeded", LINE_MAX); if (c == '\n') break; } *p = '\0'; curlen = i; return(c); } -static char ** -getptrs(char **sp) -{ - char **p; - ptrdiff_t offset; - - offset = sp - elem; - allocsize += allocsize; - p = (char **)realloc(elem, allocsize * sizeof(char *)); - if (p == NULL) - err(1, "no memory"); - - sp = p + offset; - endelem = (elem = p) + allocsize; - return(sp); -} - static void getargs(int ac, char *av[]) { + long val; char *p; if (ac == 1) { flags |= NOARGS | TRANSPOSE; } while (--ac && **++av == '-') for (p = *av+1; *p; p++) switch (*p) { case 'T': flags |= MTRANSPOSE; /* FALLTHROUGH */ case 't': flags |= TRANSPOSE; break; case 'c': /* input col. separator */ flags |= ONEISEPONLY; /* FALLTHROUGH */ case 's': /* one or more allowed */ if (p[1]) isep = *++p; else isep = '\t'; /* default is ^I */ break; case 'C': flags |= ONEOSEPONLY; /* FALLTHROUGH */ case 'S': if (p[1]) osep = *++p; else osep = '\t'; /* default is ^I */ break; case 'w': /* window width, default 80 */ p = getnum(&owidth, p, 0); if (owidth <= 0) errx(1, "width must be a positive integer"); break; case 'K': /* skip N lines */ flags |= SKIPPRINT; /* FALLTHROUGH */ case 'k': /* skip, do not print */ p = getnum(&skip, p, 0); if (!skip) skip = 1; break; case 'm': flags |= NOTRIMENDCOL; break; case 'g': /* gutter space */ p = getnum(&gutter, p, 0); break; case 'G': p = getnum(&propgutter, p, 0); break; case 'e': /* each line is an entry */ flags |= ONEPERLINE; break; case 'E': flags |= ONEPERCHAR; break; case 'j': /* right adjust */ flags |= RIGHTADJUST; break; case 'n': /* null padding for missing values */ flags |= NULLPAD; break; case 'y': flags |= RECYCLE; break; case 'H': /* print shape only */ flags |= DETAILSHAPE; /* FALLTHROUGH */ case 'h': flags |= SHAPEONLY; break; case 'z': /* squeeze col width */ flags |= SQUEEZE; break; /*case 'p': ipagespace = atoi(++p); (default is 1) break;*/ case 'o': /* col order */ p = getlist(&cord, p); break; case 'b': flags |= ICOLBOUNDS; p = getlist(&icbd, p); break; case 'B': flags |= OCOLBOUNDS; p = getlist(&ocbd, p); break; default: usage(); } /*if (!osep) osep = isep;*/ switch (ac) { #if 0 case 3: opages = atoi(av[2]); /* FALLTHROUGH */ #endif case 2: - if ((ocols = atoi(av[1])) < 0) - ocols = 0; + val = strtol(av[1], NULL, 10); + if (val >= 0) + ocols = val; /* FALLTHROUGH */ case 1: - if ((orows = atoi(av[0])) < 0) - orows = 0; + val = strtol(av[0], NULL, 10); + if (val >= 0) + orows = val; /* FALLTHROUGH */ case 0: break; default: errx(1, "too many arguments"); } } static char * getlist(short **list, char *p) { int count = 1; char *t; for (t = p + 1; *t; t++) { if (!isdigit((unsigned char)*t)) errx(1, "option %.1s requires a list of unsigned numbers separated by commas", t); count++; while (*t && isdigit((unsigned char)*t)) t++; if (*t != ',') break; } if (!(*list = (short *) malloc(count * sizeof(short)))) errx(1, "no list space"); count = 0; for (t = p + 1; *t; t++) { (*list)[count++] = atoi(t); printf("++ %d ", (*list)[count-1]); fflush(stdout); while (*t && isdigit((unsigned char)*t)) t++; if (*t != ',') break; } (*list)[count] = 0; return(t - 1); } /* * num = number p points to; if (strict) complain * returns pointer to end of num */ static char * getnum(int *num, char *p, int strict) { char *t = p; if (!isdigit((unsigned char)*++t)) { if (strict || *t == '-' || *t == '+') errx(1, "option %.1s requires an unsigned integer", p); *num = 0; return(p); } *num = atoi(t); while (*++t) if (!isdigit((unsigned char)*t)) break; return(--t); }