xref: /freebsd/usr.bin/rs/rs.cc (revision afb4998dd4de03c2d635faf7db89f3d3f6c3a6ff)
142d10b1bSJohn Baldwin /*-
242d10b1bSJohn Baldwin  * SPDX-License-Identifier: BSD-3-Clause
342d10b1bSJohn Baldwin  *
442d10b1bSJohn Baldwin  * Copyright (c) 1993
542d10b1bSJohn Baldwin  *	The Regents of the University of California.  All rights reserved.
642d10b1bSJohn Baldwin  *
742d10b1bSJohn Baldwin  * Redistribution and use in source and binary forms, with or without
842d10b1bSJohn Baldwin  * modification, are permitted provided that the following conditions
942d10b1bSJohn Baldwin  * are met:
1042d10b1bSJohn Baldwin  * 1. Redistributions of source code must retain the above copyright
1142d10b1bSJohn Baldwin  *    notice, this list of conditions and the following disclaimer.
1242d10b1bSJohn Baldwin  * 2. Redistributions in binary form must reproduce the above copyright
1342d10b1bSJohn Baldwin  *    notice, this list of conditions and the following disclaimer in the
1442d10b1bSJohn Baldwin  *    documentation and/or other materials provided with the distribution.
1542d10b1bSJohn Baldwin  * 3. Neither the name of the University nor the names of its contributors
1642d10b1bSJohn Baldwin  *    may be used to endorse or promote products derived from this software
1742d10b1bSJohn Baldwin  *    without specific prior written permission.
1842d10b1bSJohn Baldwin  *
1942d10b1bSJohn Baldwin  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2042d10b1bSJohn Baldwin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2142d10b1bSJohn Baldwin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2242d10b1bSJohn Baldwin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2342d10b1bSJohn Baldwin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2442d10b1bSJohn Baldwin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2542d10b1bSJohn Baldwin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2642d10b1bSJohn Baldwin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2742d10b1bSJohn Baldwin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2842d10b1bSJohn Baldwin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2942d10b1bSJohn Baldwin  * SUCH DAMAGE.
3042d10b1bSJohn Baldwin  */
3142d10b1bSJohn Baldwin 
3242d10b1bSJohn Baldwin /*
3342d10b1bSJohn Baldwin  *	rs - reshape a data array
3442d10b1bSJohn Baldwin  *	Author:  John Kunze, Office of Comp. Affairs, UCB
3542d10b1bSJohn Baldwin  *		BEWARE: lots of unfinished edges
3642d10b1bSJohn Baldwin  */
3742d10b1bSJohn Baldwin 
3842d10b1bSJohn Baldwin #include <err.h>
3942d10b1bSJohn Baldwin #include <ctype.h>
4042d10b1bSJohn Baldwin #include <limits.h>
4142d10b1bSJohn Baldwin #include <stdio.h>
4242d10b1bSJohn Baldwin #include <stdlib.h>
4342d10b1bSJohn Baldwin #include <string.h>
44*afb4998dSJohn Baldwin #include <unistd.h>
4542d10b1bSJohn Baldwin #include <vector>
4642d10b1bSJohn Baldwin 
4742d10b1bSJohn Baldwin static long	flags;
4842d10b1bSJohn Baldwin #define	TRANSPOSE	000001
4942d10b1bSJohn Baldwin #define	MTRANSPOSE	000002
5042d10b1bSJohn Baldwin #define	ONEPERLINE	000004
5142d10b1bSJohn Baldwin #define	ONEISEPONLY	000010
5242d10b1bSJohn Baldwin #define	ONEOSEPONLY	000020
5342d10b1bSJohn Baldwin #define	NOTRIMENDCOL	000040
5442d10b1bSJohn Baldwin #define	SQUEEZE		000100
5542d10b1bSJohn Baldwin #define	SHAPEONLY	000200
5642d10b1bSJohn Baldwin #define	DETAILSHAPE	000400
5742d10b1bSJohn Baldwin #define	RIGHTADJUST	001000
5842d10b1bSJohn Baldwin #define	NULLPAD		002000
5942d10b1bSJohn Baldwin #define	RECYCLE		004000
6042d10b1bSJohn Baldwin #define	SKIPPRINT	010000
6142d10b1bSJohn Baldwin #define	ICOLBOUNDS	020000
6242d10b1bSJohn Baldwin #define	OCOLBOUNDS	040000
6342d10b1bSJohn Baldwin #define ONEPERCHAR	0100000
6442d10b1bSJohn Baldwin #define NOARGS		0200000
6542d10b1bSJohn Baldwin 
6642d10b1bSJohn Baldwin static short	*colwidths;
6742d10b1bSJohn Baldwin static std::vector<char *> elem;
6842d10b1bSJohn Baldwin static char	*curline;
6942d10b1bSJohn Baldwin static size_t	curlen;
7042d10b1bSJohn Baldwin static size_t	irows, icols;
7142d10b1bSJohn Baldwin static size_t	orows = 0, ocols = 0;
7242d10b1bSJohn Baldwin static size_t	maxlen;
7342d10b1bSJohn Baldwin static int	skip;
7442d10b1bSJohn Baldwin static int	propgutter;
7542d10b1bSJohn Baldwin static char	isep = ' ', osep = ' ';
7642d10b1bSJohn Baldwin static char	blank[] = "";
77*afb4998dSJohn Baldwin static size_t	owidth = 80, gutter = 2;
7842d10b1bSJohn Baldwin 
7942d10b1bSJohn Baldwin static void	  getargs(int, char *[]);
8042d10b1bSJohn Baldwin static void	  getfile(void);
8142d10b1bSJohn Baldwin static int	  get_line(void);
82*afb4998dSJohn Baldwin static long	  getnum(const char *);
8342d10b1bSJohn Baldwin static void	  prepfile(void);
8442d10b1bSJohn Baldwin static void	  prints(char *, int);
8542d10b1bSJohn Baldwin static void	  putfile(void);
8642d10b1bSJohn Baldwin static void usage(void);
8742d10b1bSJohn Baldwin 
8842d10b1bSJohn Baldwin int
main(int argc,char * argv[])8942d10b1bSJohn Baldwin main(int argc, char *argv[])
9042d10b1bSJohn Baldwin {
9142d10b1bSJohn Baldwin 	getargs(argc, argv);
9242d10b1bSJohn Baldwin 	getfile();
9342d10b1bSJohn Baldwin 	if (flags & SHAPEONLY) {
9442d10b1bSJohn Baldwin 		printf("%zu %zu\n", irows, icols);
9542d10b1bSJohn Baldwin 		exit(0);
9642d10b1bSJohn Baldwin 	}
9742d10b1bSJohn Baldwin 	prepfile();
9842d10b1bSJohn Baldwin 	putfile();
9942d10b1bSJohn Baldwin 	exit(0);
10042d10b1bSJohn Baldwin }
10142d10b1bSJohn Baldwin 
10242d10b1bSJohn Baldwin static void
getfile(void)10342d10b1bSJohn Baldwin getfile(void)
10442d10b1bSJohn Baldwin {
10542d10b1bSJohn Baldwin 	char *p, *sp;
10642d10b1bSJohn Baldwin 	char *endp;
10742d10b1bSJohn Baldwin 	int c;
10842d10b1bSJohn Baldwin 	int multisep = (flags & ONEISEPONLY ? 0 : 1);
10942d10b1bSJohn Baldwin 	int nullpad = flags & NULLPAD;
11042d10b1bSJohn Baldwin 	size_t len, padto;
11142d10b1bSJohn Baldwin 
11242d10b1bSJohn Baldwin 	while (skip--) {
11342d10b1bSJohn Baldwin 		c = get_line();
11442d10b1bSJohn Baldwin 		if (flags & SKIPPRINT)
11542d10b1bSJohn Baldwin 			puts(curline);
11642d10b1bSJohn Baldwin 		if (c == EOF)
11742d10b1bSJohn Baldwin 			return;
11842d10b1bSJohn Baldwin 	}
11942d10b1bSJohn Baldwin 	get_line();
120*afb4998dSJohn Baldwin 	if (flags & NOARGS && curlen < owidth)
12142d10b1bSJohn Baldwin 		flags |= ONEPERLINE;
12242d10b1bSJohn Baldwin 	if (flags & ONEPERLINE)
12342d10b1bSJohn Baldwin 		icols = 1;
12442d10b1bSJohn Baldwin 	else				/* count cols on first line */
12542d10b1bSJohn Baldwin 		for (p = curline, endp = curline + curlen; p < endp; p++) {
12642d10b1bSJohn Baldwin 			if (*p == isep && multisep)
12742d10b1bSJohn Baldwin 				continue;
12842d10b1bSJohn Baldwin 			icols++;
12942d10b1bSJohn Baldwin 			while (*p && *p != isep)
13042d10b1bSJohn Baldwin 				p++;
13142d10b1bSJohn Baldwin 		}
13242d10b1bSJohn Baldwin 	do {
13342d10b1bSJohn Baldwin 		if (flags & ONEPERLINE) {
13442d10b1bSJohn Baldwin 			elem.push_back(curline);
13542d10b1bSJohn Baldwin 			if (maxlen < curlen)
13642d10b1bSJohn Baldwin 				maxlen = curlen;
13742d10b1bSJohn Baldwin 			irows++;
13842d10b1bSJohn Baldwin 			continue;
13942d10b1bSJohn Baldwin 		}
14042d10b1bSJohn Baldwin 		for (p = curline, endp = curline + curlen; p < endp; p++) {
14142d10b1bSJohn Baldwin 			if (*p == isep && multisep)
14242d10b1bSJohn Baldwin 				continue;	/* eat up column separators */
14342d10b1bSJohn Baldwin 			if (*p == isep)		/* must be an empty column */
14442d10b1bSJohn Baldwin 				elem.push_back(blank);
14542d10b1bSJohn Baldwin 			else			/* store column entry */
14642d10b1bSJohn Baldwin 				elem.push_back(p);
14742d10b1bSJohn Baldwin 			sp = p;
14842d10b1bSJohn Baldwin 			while (p < endp && *p != isep)
14942d10b1bSJohn Baldwin 				p++;		/* find end of entry */
15042d10b1bSJohn Baldwin 			*p = '\0';		/* mark end of entry */
15142d10b1bSJohn Baldwin 			len = p - sp;
15242d10b1bSJohn Baldwin 			if (maxlen < len)	/* update maxlen */
15342d10b1bSJohn Baldwin 				maxlen = len;
15442d10b1bSJohn Baldwin 		}
15542d10b1bSJohn Baldwin 		irows++;			/* update row count */
15642d10b1bSJohn Baldwin 		if (nullpad) {			/* pad missing entries */
15742d10b1bSJohn Baldwin 			padto = irows * icols;
15842d10b1bSJohn Baldwin 			elem.resize(padto, blank);
15942d10b1bSJohn Baldwin 		}
16042d10b1bSJohn Baldwin 	} while (get_line() != EOF);
16142d10b1bSJohn Baldwin }
16242d10b1bSJohn Baldwin 
16342d10b1bSJohn Baldwin static void
putfile(void)16442d10b1bSJohn Baldwin putfile(void)
16542d10b1bSJohn Baldwin {
16642d10b1bSJohn Baldwin 	size_t i, j, k;
16742d10b1bSJohn Baldwin 
16842d10b1bSJohn Baldwin 	if (flags & TRANSPOSE)
16942d10b1bSJohn Baldwin 		for (i = 0; i < orows; i++) {
17042d10b1bSJohn Baldwin 			for (j = i; j < elem.size(); j += orows)
17142d10b1bSJohn Baldwin 				prints(elem[j], (j - i) / orows);
17242d10b1bSJohn Baldwin 			putchar('\n');
17342d10b1bSJohn Baldwin 		}
17442d10b1bSJohn Baldwin 	else
17542d10b1bSJohn Baldwin 		for (i = k = 0; i < orows; i++) {
17642d10b1bSJohn Baldwin 			for (j = 0; j < ocols; j++, k++)
17742d10b1bSJohn Baldwin 				if (k < elem.size())
17842d10b1bSJohn Baldwin 					prints(elem[k], j);
17942d10b1bSJohn Baldwin 			putchar('\n');
18042d10b1bSJohn Baldwin 		}
18142d10b1bSJohn Baldwin }
18242d10b1bSJohn Baldwin 
18342d10b1bSJohn Baldwin static void
prints(char * s,int col)18442d10b1bSJohn Baldwin prints(char *s, int col)
18542d10b1bSJohn Baldwin {
18642d10b1bSJohn Baldwin 	int n;
18742d10b1bSJohn Baldwin 	char *p = s;
18842d10b1bSJohn Baldwin 
18942d10b1bSJohn Baldwin 	while (*p)
19042d10b1bSJohn Baldwin 		p++;
19142d10b1bSJohn Baldwin 	n = (flags & ONEOSEPONLY ? 1 : colwidths[col] - (p - s));
19242d10b1bSJohn Baldwin 	if (flags & RIGHTADJUST)
19342d10b1bSJohn Baldwin 		while (n-- > 0)
19442d10b1bSJohn Baldwin 			putchar(osep);
19542d10b1bSJohn Baldwin 	for (p = s; *p; p++)
19642d10b1bSJohn Baldwin 		putchar(*p);
19742d10b1bSJohn Baldwin 	while (n-- > 0)
19842d10b1bSJohn Baldwin 		putchar(osep);
19942d10b1bSJohn Baldwin }
20042d10b1bSJohn Baldwin 
20142d10b1bSJohn Baldwin static void
usage(void)20242d10b1bSJohn Baldwin usage(void)
20342d10b1bSJohn Baldwin {
20442d10b1bSJohn Baldwin 	fprintf(stderr,
20542d10b1bSJohn Baldwin 		"usage: rs [-[csCS][x][kKgGw][N]tTeEnyjhHmz] [rows [cols]]\n");
20642d10b1bSJohn Baldwin 	exit(1);
20742d10b1bSJohn Baldwin }
20842d10b1bSJohn Baldwin 
20942d10b1bSJohn Baldwin static void
prepfile(void)21042d10b1bSJohn Baldwin prepfile(void)
21142d10b1bSJohn Baldwin {
21242d10b1bSJohn Baldwin 	size_t i, j;
21342d10b1bSJohn Baldwin 	size_t colw, max, n, orig_size, padto;
21442d10b1bSJohn Baldwin 
21542d10b1bSJohn Baldwin 	if (elem.empty())
21642d10b1bSJohn Baldwin 		exit(0);
21742d10b1bSJohn Baldwin 	gutter += maxlen * propgutter / 100.0;
21842d10b1bSJohn Baldwin 	colw = maxlen + gutter;
21942d10b1bSJohn Baldwin 	if (flags & MTRANSPOSE) {
22042d10b1bSJohn Baldwin 		orows = icols;
22142d10b1bSJohn Baldwin 		ocols = irows;
22242d10b1bSJohn Baldwin 	}
22342d10b1bSJohn Baldwin 	else if (orows == 0 && ocols == 0) {	/* decide rows and cols */
22442d10b1bSJohn Baldwin 		ocols = owidth / colw;
22542d10b1bSJohn Baldwin 		if (ocols == 0) {
226*afb4998dSJohn Baldwin 			warnx("display width %zu is less than column width %zu",
22742d10b1bSJohn Baldwin 					owidth, colw);
22842d10b1bSJohn Baldwin 			ocols = 1;
22942d10b1bSJohn Baldwin 		}
23042d10b1bSJohn Baldwin 		if (ocols > elem.size())
23142d10b1bSJohn Baldwin 			ocols = elem.size();
23242d10b1bSJohn Baldwin 		orows = elem.size() / ocols + (elem.size() % ocols ? 1 : 0);
23342d10b1bSJohn Baldwin 	}
23442d10b1bSJohn Baldwin 	else if (orows == 0)			/* decide on rows */
23542d10b1bSJohn Baldwin 		orows = elem.size() / ocols + (elem.size() % ocols ? 1 : 0);
23642d10b1bSJohn Baldwin 	else if (ocols == 0)			/* decide on cols */
23742d10b1bSJohn Baldwin 		ocols = elem.size() / orows + (elem.size() % orows ? 1 : 0);
23842d10b1bSJohn Baldwin 	padto = orows * ocols;
23942d10b1bSJohn Baldwin 	orig_size = elem.size();
24042d10b1bSJohn Baldwin 	if (flags & RECYCLE) {
24142d10b1bSJohn Baldwin 		for (i = 0; elem.size() < padto; i++)
24242d10b1bSJohn Baldwin 			elem.push_back(elem[i % orig_size]);
24342d10b1bSJohn Baldwin 	}
24442d10b1bSJohn Baldwin 	if (!(colwidths = (short *) malloc(ocols * sizeof(short))))
24542d10b1bSJohn Baldwin 		errx(1, "malloc");
24642d10b1bSJohn Baldwin 	if (flags & SQUEEZE) {
24742d10b1bSJohn Baldwin 		if (flags & TRANSPOSE) {
24842d10b1bSJohn Baldwin 			auto it = elem.begin();
24942d10b1bSJohn Baldwin 			for (i = 0; i < ocols; i++) {
25042d10b1bSJohn Baldwin 				max = 0;
25142d10b1bSJohn Baldwin 				for (j = 0; it != elem.end() && j < orows; j++)
25242d10b1bSJohn Baldwin 					if ((n = strlen(*it++)) > max)
25342d10b1bSJohn Baldwin 						max = n;
25442d10b1bSJohn Baldwin 				colwidths[i] = max + gutter;
25542d10b1bSJohn Baldwin 			}
25642d10b1bSJohn Baldwin 		} else {
25742d10b1bSJohn Baldwin 			for (i = 0; i < ocols; i++) {
25842d10b1bSJohn Baldwin 				max = 0;
25942d10b1bSJohn Baldwin 				for (j = i; j < elem.size(); j += ocols)
26042d10b1bSJohn Baldwin 					if ((n = strlen(elem[j])) > max)
26142d10b1bSJohn Baldwin 						max = n;
26242d10b1bSJohn Baldwin 				colwidths[i] = max + gutter;
26342d10b1bSJohn Baldwin 			}
26442d10b1bSJohn Baldwin 		}
26542d10b1bSJohn Baldwin 	}
26642d10b1bSJohn Baldwin 	/*	for (i = 0; i < orows; i++) {
26742d10b1bSJohn Baldwin 			for (j = i; j < elem.size(); j += orows)
26842d10b1bSJohn Baldwin 				prints(elem[j], (j - i) / orows);
26942d10b1bSJohn Baldwin 			putchar('\n');
27042d10b1bSJohn Baldwin 		}
27142d10b1bSJohn Baldwin 	else {
27242d10b1bSJohn Baldwin 		auto it = elem.begin();
27342d10b1bSJohn Baldwin 		for (i = 0; i < orows; i++) {
27442d10b1bSJohn Baldwin 			for (j = 0; j < ocols; j++)
27542d10b1bSJohn Baldwin 				prints(*it++, j);
27642d10b1bSJohn Baldwin 			putchar('\n');
27742d10b1bSJohn Baldwin 		}*/
27842d10b1bSJohn Baldwin 	else
27942d10b1bSJohn Baldwin 		for (i = 0; i < ocols; i++)
28042d10b1bSJohn Baldwin 			colwidths[i] = colw;
28142d10b1bSJohn Baldwin 	if (!(flags & NOTRIMENDCOL)) {
28242d10b1bSJohn Baldwin 		if (flags & RIGHTADJUST)
28342d10b1bSJohn Baldwin 			colwidths[0] -= gutter;
28442d10b1bSJohn Baldwin 		else
28542d10b1bSJohn Baldwin 			colwidths[ocols - 1] = 0;
28642d10b1bSJohn Baldwin 	}
28742d10b1bSJohn Baldwin 	/*for (i = 0; i < ocols; i++)
28842d10b1bSJohn Baldwin 		warnx("%d is colwidths, nelem %zu", colwidths[i], elem.size());*/
28942d10b1bSJohn Baldwin }
29042d10b1bSJohn Baldwin 
29142d10b1bSJohn Baldwin #define	BSIZE	(LINE_MAX * 2)
29242d10b1bSJohn Baldwin static char	ibuf[BSIZE];
29342d10b1bSJohn Baldwin 
29442d10b1bSJohn Baldwin static int
get_line(void)29542d10b1bSJohn Baldwin get_line(void)	/* get line; maintain curline, curlen; manage storage */
29642d10b1bSJohn Baldwin {
29742d10b1bSJohn Baldwin 	static	int putlength;
29842d10b1bSJohn Baldwin 	static	char *endblock = ibuf + BSIZE;
29942d10b1bSJohn Baldwin 	char *p;
30042d10b1bSJohn Baldwin 	int c, i;
30142d10b1bSJohn Baldwin 
30242d10b1bSJohn Baldwin 	if (irows == 0) {
30342d10b1bSJohn Baldwin 		curline = ibuf;
30442d10b1bSJohn Baldwin 		putlength = flags & DETAILSHAPE;
30542d10b1bSJohn Baldwin 	}
30642d10b1bSJohn Baldwin 	else if (skip <= 0) {			/* don't waste storage */
30742d10b1bSJohn Baldwin 		curline += curlen + 1;
30842d10b1bSJohn Baldwin 		if (putlength) {	/* print length, recycle storage */
30942d10b1bSJohn Baldwin 			printf(" %zu line %zu\n", curlen, irows);
31042d10b1bSJohn Baldwin 			curline = ibuf;
31142d10b1bSJohn Baldwin 		}
31242d10b1bSJohn Baldwin 	}
31342d10b1bSJohn Baldwin 	if (!putlength && endblock - curline < LINE_MAX + 1) { /* need storage */
31442d10b1bSJohn Baldwin 		/*ww = endblock-curline; tt += ww;*/
31542d10b1bSJohn Baldwin 		/*printf("#wasted %d total %d\n",ww,tt);*/
31642d10b1bSJohn Baldwin 		if (!(curline = (char *) malloc(BSIZE)))
31742d10b1bSJohn Baldwin 			errx(1, "file too large");
31842d10b1bSJohn Baldwin 		endblock = curline + BSIZE;
31942d10b1bSJohn Baldwin 		/*printf("#endb %d curline %d\n",endblock,curline);*/
32042d10b1bSJohn Baldwin 	}
32142d10b1bSJohn Baldwin 	for (p = curline, i = 0;; *p++ = c, i++) {
32242d10b1bSJohn Baldwin 		if ((c = getchar()) == EOF)
32342d10b1bSJohn Baldwin 			break;
32442d10b1bSJohn Baldwin 		if (i >= LINE_MAX)
32542d10b1bSJohn Baldwin 			errx(1, "maximum line length (%d) exceeded", LINE_MAX);
32642d10b1bSJohn Baldwin 		if (c == '\n')
32742d10b1bSJohn Baldwin 			break;
32842d10b1bSJohn Baldwin 	}
32942d10b1bSJohn Baldwin 	*p = '\0';
33042d10b1bSJohn Baldwin 	curlen = i;
33142d10b1bSJohn Baldwin 	return(c);
33242d10b1bSJohn Baldwin }
33342d10b1bSJohn Baldwin 
33442d10b1bSJohn Baldwin static void
getargs(int ac,char * av[])33542d10b1bSJohn Baldwin getargs(int ac, char *av[])
33642d10b1bSJohn Baldwin {
33742d10b1bSJohn Baldwin 	long val;
338*afb4998dSJohn Baldwin 	int ch;
33942d10b1bSJohn Baldwin 
34042d10b1bSJohn Baldwin 	if (ac == 1) {
34142d10b1bSJohn Baldwin 		flags |= NOARGS | TRANSPOSE;
34242d10b1bSJohn Baldwin 	}
343*afb4998dSJohn Baldwin 
344*afb4998dSJohn Baldwin 	while ((ch = getopt(ac, av, "C::EG:HK:S::Tc::eg:hjk:mns::tw:yz")) != -1)
345*afb4998dSJohn Baldwin 		switch (ch) {
34642d10b1bSJohn Baldwin 		case 'T':
34742d10b1bSJohn Baldwin 			flags |= MTRANSPOSE;
34842d10b1bSJohn Baldwin 			/* FALLTHROUGH */
34942d10b1bSJohn Baldwin 		case 't':
35042d10b1bSJohn Baldwin 			flags |= TRANSPOSE;
35142d10b1bSJohn Baldwin 			break;
35242d10b1bSJohn Baldwin 		case 'c':		/* input col. separator */
35342d10b1bSJohn Baldwin 			flags |= ONEISEPONLY;
35442d10b1bSJohn Baldwin 			/* FALLTHROUGH */
35542d10b1bSJohn Baldwin 		case 's':		/* one or more allowed */
356*afb4998dSJohn Baldwin 			if (optarg != NULL)
357*afb4998dSJohn Baldwin 				isep = *optarg;
35842d10b1bSJohn Baldwin 			else
35942d10b1bSJohn Baldwin 				isep = '\t';	/* default is ^I */
36042d10b1bSJohn Baldwin 			break;
36142d10b1bSJohn Baldwin 		case 'C':
36242d10b1bSJohn Baldwin 			flags |= ONEOSEPONLY;
36342d10b1bSJohn Baldwin 			/* FALLTHROUGH */
36442d10b1bSJohn Baldwin 		case 'S':
365*afb4998dSJohn Baldwin 			if (optarg != NULL)
366*afb4998dSJohn Baldwin 				osep = *optarg;
36742d10b1bSJohn Baldwin 			else
36842d10b1bSJohn Baldwin 				osep = '\t';	/* default is ^I */
36942d10b1bSJohn Baldwin 			break;
37042d10b1bSJohn Baldwin 		case 'w':		/* window width, default 80 */
371*afb4998dSJohn Baldwin 			val = getnum(optarg);
372*afb4998dSJohn Baldwin 			if (val <= 0)
37342d10b1bSJohn Baldwin 				errx(1, "width must be a positive integer");
374*afb4998dSJohn Baldwin 			owidth = val;
37542d10b1bSJohn Baldwin 			break;
37642d10b1bSJohn Baldwin 		case 'K':			/* skip N lines */
37742d10b1bSJohn Baldwin 			flags |= SKIPPRINT;
37842d10b1bSJohn Baldwin 			/* FALLTHROUGH */
37942d10b1bSJohn Baldwin 		case 'k':			/* skip, do not print */
380*afb4998dSJohn Baldwin 			skip = getnum(optarg);
381*afb4998dSJohn Baldwin 			if (skip < 1)
38242d10b1bSJohn Baldwin 				skip = 1;
38342d10b1bSJohn Baldwin 			break;
38442d10b1bSJohn Baldwin 		case 'm':
38542d10b1bSJohn Baldwin 			flags |= NOTRIMENDCOL;
38642d10b1bSJohn Baldwin 			break;
38742d10b1bSJohn Baldwin 		case 'g':		/* gutter space */
388*afb4998dSJohn Baldwin 			gutter = getnum(optarg);
38942d10b1bSJohn Baldwin 			break;
39042d10b1bSJohn Baldwin 		case 'G':
391*afb4998dSJohn Baldwin 			propgutter = getnum(optarg);
39242d10b1bSJohn Baldwin 			break;
39342d10b1bSJohn Baldwin 		case 'e':		/* each line is an entry */
39442d10b1bSJohn Baldwin 			flags |= ONEPERLINE;
39542d10b1bSJohn Baldwin 			break;
39642d10b1bSJohn Baldwin 		case 'E':
39742d10b1bSJohn Baldwin 			flags |= ONEPERCHAR;
39842d10b1bSJohn Baldwin 			break;
39942d10b1bSJohn Baldwin 		case 'j':			/* right adjust */
40042d10b1bSJohn Baldwin 			flags |= RIGHTADJUST;
40142d10b1bSJohn Baldwin 			break;
40242d10b1bSJohn Baldwin 		case 'n':	/* null padding for missing values */
40342d10b1bSJohn Baldwin 			flags |= NULLPAD;
40442d10b1bSJohn Baldwin 			break;
40542d10b1bSJohn Baldwin 		case 'y':
40642d10b1bSJohn Baldwin 			flags |= RECYCLE;
40742d10b1bSJohn Baldwin 			break;
40842d10b1bSJohn Baldwin 		case 'H':			/* print shape only */
40942d10b1bSJohn Baldwin 			flags |= DETAILSHAPE;
41042d10b1bSJohn Baldwin 			/* FALLTHROUGH */
41142d10b1bSJohn Baldwin 		case 'h':
41242d10b1bSJohn Baldwin 			flags |= SHAPEONLY;
41342d10b1bSJohn Baldwin 			break;
41442d10b1bSJohn Baldwin 		case 'z':			/* squeeze col width */
41542d10b1bSJohn Baldwin 			flags |= SQUEEZE;
41642d10b1bSJohn Baldwin 			break;
41742d10b1bSJohn Baldwin 		/*case 'p':
418*afb4998dSJohn Baldwin 			ipagespace = atoi(optarg);	(default is 1)
41942d10b1bSJohn Baldwin 			break;*/
42042d10b1bSJohn Baldwin 		default:
42142d10b1bSJohn Baldwin 			usage();
42242d10b1bSJohn Baldwin 		}
423*afb4998dSJohn Baldwin 
424*afb4998dSJohn Baldwin 	av += optind;
425*afb4998dSJohn Baldwin 	ac -= optind;
426*afb4998dSJohn Baldwin 
42742d10b1bSJohn Baldwin 	/*if (!osep)
42842d10b1bSJohn Baldwin 		osep = isep;*/
42942d10b1bSJohn Baldwin 	switch (ac) {
43042d10b1bSJohn Baldwin #if 0
43142d10b1bSJohn Baldwin 	case 3:
43242d10b1bSJohn Baldwin 		opages = atoi(av[2]);
43342d10b1bSJohn Baldwin 		/* FALLTHROUGH */
43442d10b1bSJohn Baldwin #endif
43542d10b1bSJohn Baldwin 	case 2:
43642d10b1bSJohn Baldwin 		val = strtol(av[1], NULL, 10);
43742d10b1bSJohn Baldwin 		if (val >= 0)
43842d10b1bSJohn Baldwin 			ocols = val;
43942d10b1bSJohn Baldwin 		/* FALLTHROUGH */
44042d10b1bSJohn Baldwin 	case 1:
44142d10b1bSJohn Baldwin 		val = strtol(av[0], NULL, 10);
44242d10b1bSJohn Baldwin 		if (val >= 0)
44342d10b1bSJohn Baldwin 			orows = val;
44442d10b1bSJohn Baldwin 		/* FALLTHROUGH */
44542d10b1bSJohn Baldwin 	case 0:
44642d10b1bSJohn Baldwin 		break;
44742d10b1bSJohn Baldwin 	default:
44842d10b1bSJohn Baldwin 		errx(1, "too many arguments");
44942d10b1bSJohn Baldwin 	}
45042d10b1bSJohn Baldwin }
45142d10b1bSJohn Baldwin 
452*afb4998dSJohn Baldwin static long
getnum(const char * p)453*afb4998dSJohn Baldwin getnum(const char *p)
45442d10b1bSJohn Baldwin {
455*afb4998dSJohn Baldwin 	char *ep;
456*afb4998dSJohn Baldwin 	long val;
45742d10b1bSJohn Baldwin 
458*afb4998dSJohn Baldwin 	val = strtol(p, &ep, 10);
459*afb4998dSJohn Baldwin 	if (*ep != '\0')
460*afb4998dSJohn Baldwin 		errx(1, "invalid integer %s", p);
461*afb4998dSJohn Baldwin 	return (val);
46242d10b1bSJohn Baldwin }
463