git: 42d10b1b56f2 - main - rs: Convert to C++ to convert elem to a std::vector<char *>.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Wed, 16 Nov 2022 05:19:08 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=42d10b1b56f2f7739081487814f90a22b81792ee

commit 42d10b1b56f2f7739081487814f90a22b81792ee
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2022-11-16 05:03:12 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2022-11-16 05:03:12 +0000

    rs: Convert to C++ to convert elem to a std::vector<char *>.
    
    This also updates various indices and counters from int to size_t to
    pacify resulting -Wsign-compare warnings.
    
    Reviewed by:    brooks
    Differential Revision:  https://reviews.freebsd.org/D36833
---
 usr.bin/Makefile           |   2 +-
 usr.bin/rs/Makefile        |   2 +-
 usr.bin/rs/{rs.c => rs.cc} | 155 ++++++++++++++++-----------------------------
 3 files changed, 57 insertions(+), 102 deletions(-)

diff --git a/usr.bin/Makefile b/usr.bin/Makefile
index e3d58a3524cf..3ccc626bdfc8 100644
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -125,7 +125,6 @@ SUBDIR=	alias \
 	rev \
 	revoke \
 	rpcinfo \
-	rs \
 	rup \
 	ruptime \
 	rusers \
@@ -212,6 +211,7 @@ 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
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
@@ -3,7 +3,7 @@
 
 .include <src.opts.mk>
 
-PROG=	rs
+PROG_CXX=	rs
 
 HAS_TESTS=
 SUBDIR.${MK_TESTS}+= tests
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
@@ -38,10 +38,10 @@
 #include <err.h>
 #include <ctype.h>
 #include <limits.h>
-#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <vector>
 
 static long	flags;
 #define	TRANSPOSE	000001
@@ -66,15 +66,12 @@ static short	*colwidths;
 static short	*cord;
 static short	*icbd;
 static short	*ocbd;
-static int	nelem;
-static char	**elem;
-static char	**endelem;
+static std::vector<char *> 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 = ' ';
@@ -86,24 +83,18 @@ 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();
@@ -116,12 +107,10 @@ 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();
@@ -131,7 +120,7 @@ getfile(void)
 			return;
 	}
 	get_line();
-	if (flags & NOARGS && curlen < owidth)
+	if (flags & NOARGS && curlen < (size_t)owidth)
 		flags |= ONEPERLINE;
 	if (flags & ONEPERLINE)
 		icols = 1;
@@ -143,11 +132,9 @@ getfile(void)
 			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++;
@@ -157,9 +144,9 @@ getfile(void)
 			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 */
@@ -167,39 +154,31 @@ getfile(void)
 			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');
 		}
 }
@@ -233,15 +212,10 @@ usage(void)
 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;
@@ -252,58 +226,56 @@ prepfile(void)
 	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
@@ -315,11 +287,8 @@ prepfile(void)
 		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)
@@ -333,14 +302,14 @@ get_line(void)	/* get line; maintain curline, curlen; manage storage */
 	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;
 		}
 	}
@@ -365,26 +334,10 @@ get_line(void)	/* get line; maintain curline, curlen; manage storage */
 	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) {
@@ -489,12 +442,14 @@ getargs(int ac, char *av[])
 		/* 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;