xref: /original-bsd/usr.bin/rs/rs.c (revision 6e17b0ce)
1a9451f0dSbostic /*-
2*6e17b0ceSbostic  * Copyright (c) 1993
3*6e17b0ceSbostic  *	The Regents of the University of California.  All rights reserved.
4a9451f0dSbostic  *
5a9451f0dSbostic  * %sccs.include.redist.c%
6a9451f0dSbostic  */
7846a6e1dSsam 
8846a6e1dSsam #ifndef lint
9*6e17b0ceSbostic static char copyright[] =
10*6e17b0ceSbostic "@(#) Copyright (c) 1993\n\
11*6e17b0ceSbostic 	The Regents of the University of California.  All rights reserved.\n";
12a9451f0dSbostic #endif /* not lint */
13a9451f0dSbostic 
14a9451f0dSbostic #ifndef lint
15*6e17b0ceSbostic static char sccsid[] = "@(#)rs.c	8.1 (Berkeley) 06/06/93";
16a9451f0dSbostic #endif /* not lint */
17846a6e1dSsam 
18846a6e1dSsam /*
19846a6e1dSsam  *	rs - reshape a data array
20846a6e1dSsam  *	Author:  John Kunze, Office of Comp. Affairs, UCB
21846a6e1dSsam  *		BEWARE: lots of unfinished edges
22846a6e1dSsam  */
23846a6e1dSsam 
24846a6e1dSsam #include <ctype.h>
25a9451f0dSbostic #include <stdio.h>
26a9451f0dSbostic #include <stdlib.h>
27846a6e1dSsam 
28846a6e1dSsam long	flags;
29846a6e1dSsam #define	TRANSPOSE	000001
30846a6e1dSsam #define	MTRANSPOSE	000002
31846a6e1dSsam #define	ONEPERLINE	000004
32846a6e1dSsam #define	ONEISEPONLY	000010
33846a6e1dSsam #define	ONEOSEPONLY	000020
34846a6e1dSsam #define	NOTRIMENDCOL	000040
35846a6e1dSsam #define	SQUEEZE		000100
36846a6e1dSsam #define	SHAPEONLY	000200
37846a6e1dSsam #define	DETAILSHAPE	000400
38846a6e1dSsam #define	RIGHTADJUST	001000
39846a6e1dSsam #define	NULLPAD		002000
40846a6e1dSsam #define	RECYCLE		004000
41846a6e1dSsam #define	SKIPPRINT	010000
42846a6e1dSsam #define	ICOLBOUNDS	020000
43846a6e1dSsam #define	OCOLBOUNDS	040000
44846a6e1dSsam #define ONEPERCHAR	0100000
45ab6065d8Sjak #define NOARGS		0200000
46846a6e1dSsam 
47846a6e1dSsam short	*colwidths;
48846a6e1dSsam short	*cord;
49846a6e1dSsam short	*icbd;
50846a6e1dSsam short	*ocbd;
51846a6e1dSsam int	nelem;
52846a6e1dSsam char	**elem;
53846a6e1dSsam char	**endelem;
54846a6e1dSsam char	*curline;
55846a6e1dSsam int	allocsize = BUFSIZ;
56846a6e1dSsam int	curlen;
57846a6e1dSsam int	irows, icols;
58846a6e1dSsam int	orows, ocols;
59846a6e1dSsam int	maxlen;
60846a6e1dSsam int	skip;
61846a6e1dSsam int	propgutter;
62846a6e1dSsam char	isep = ' ', osep = ' ';
63846a6e1dSsam int	owidth = 80, gutter = 2;
64846a6e1dSsam 
65a9451f0dSbostic void	  error __P((char *, char *));
66a9451f0dSbostic void	  getargs __P((int, char *[]));
67a9451f0dSbostic void	  getfile __P((void));
68a9451f0dSbostic int	  getline __P((void));
69a9451f0dSbostic char	 *getlist __P((short **, char *));
70a9451f0dSbostic char	 *getnum __P((int *, char *, int));
71a9451f0dSbostic char	**getptrs __P((char **));
72a9451f0dSbostic void	  prepfile __P((void));
73a9451f0dSbostic void	  prints __P((char *, int));
74a9451f0dSbostic void	  putfile __P((void));
75846a6e1dSsam 
76a9451f0dSbostic int
main(argc,argv)77846a6e1dSsam main(argc, argv)
78846a6e1dSsam 	int argc;
79a9451f0dSbostic 	char *argv[];
80846a6e1dSsam {
81846a6e1dSsam 	getargs(argc, argv);
82846a6e1dSsam 	getfile();
83846a6e1dSsam 	if (flags & SHAPEONLY) {
84846a6e1dSsam 		printf("%d %d\n", irows, icols);
85846a6e1dSsam 		exit(0);
86846a6e1dSsam 	}
87846a6e1dSsam 	prepfile();
88846a6e1dSsam 	putfile();
89ab5850b8Slepreau 	exit(0);
90846a6e1dSsam }
91846a6e1dSsam 
92a9451f0dSbostic void
getfile()93846a6e1dSsam getfile()
94846a6e1dSsam {
95846a6e1dSsam 	register char *p;
96846a6e1dSsam 	register char *endp;
97846a6e1dSsam 	register char **ep = 0;
98846a6e1dSsam 	int multisep = (flags & ONEISEPONLY ? 0 : 1);
99846a6e1dSsam 	int nullpad = flags & NULLPAD;
100846a6e1dSsam 	char **padto;
101846a6e1dSsam 
102846a6e1dSsam 	while (skip--) {
103846a6e1dSsam 		getline();
104846a6e1dSsam 		if (flags & SKIPPRINT)
105846a6e1dSsam 			puts(curline);
106846a6e1dSsam 	}
107846a6e1dSsam 	getline();
108ab6065d8Sjak 	if (flags & NOARGS && curlen < owidth)
109ab6065d8Sjak 		flags |= ONEPERLINE;
110846a6e1dSsam 	if (flags & ONEPERLINE)
111846a6e1dSsam 		icols = 1;
112846a6e1dSsam 	else				/* count cols on first line */
113846a6e1dSsam 		for (p = curline, endp = curline + curlen; p < endp; p++) {
114846a6e1dSsam 			if (*p == isep && multisep)
115846a6e1dSsam 				continue;
116846a6e1dSsam 			icols++;
117846a6e1dSsam 			while (*p && *p != isep)
118846a6e1dSsam 				p++;
119846a6e1dSsam 		}
120846a6e1dSsam 	ep = getptrs(elem);
121846a6e1dSsam 	p = curline;
122846a6e1dSsam 	do {
123846a6e1dSsam 		if (flags & ONEPERLINE) {
124846a6e1dSsam 			*ep++ = curline;
125846a6e1dSsam 			if (maxlen < curlen)
126846a6e1dSsam 				maxlen = curlen;
127846a6e1dSsam 			irows++;
128846a6e1dSsam 			continue;
129846a6e1dSsam 		}
130846a6e1dSsam 		for (p = curline, endp = curline + curlen; p < endp; p++) {
131846a6e1dSsam 			if (*p == isep && multisep)
132846a6e1dSsam 				continue;	/* eat up column separators */
133846a6e1dSsam 			if (*p == isep)		/* must be an empty column */
134846a6e1dSsam 				*ep = "";
135846a6e1dSsam 			else			/* store column entry */
136846a6e1dSsam 				*ep = p;
137846a6e1dSsam 			while (p < endp && *p != isep)
138846a6e1dSsam 				p++;		/* find end of entry */
139846a6e1dSsam 			*p = '\0';		/* mark end of entry */
140846a6e1dSsam 			if (maxlen < p - *ep)	/* update maxlen */
141846a6e1dSsam 				maxlen = p - *ep;
142846a6e1dSsam 			ep++;			/* prepare for next entry */
143846a6e1dSsam 		}
144846a6e1dSsam 		irows++;			/* update row count */
145846a6e1dSsam 		if (nullpad) {			/* pad missing entries */
146846a6e1dSsam 			padto = elem + irows * icols;
147846a6e1dSsam 			while  (ep < padto)
148846a6e1dSsam 				*ep++ = "";
149846a6e1dSsam 		}
150846a6e1dSsam 	if (ep > endelem)			/* if low on pointers */
151846a6e1dSsam 		ep = getptrs(ep);		/* get some more */
152846a6e1dSsam 	} while (getline() != EOF);
153846a6e1dSsam 	*ep = 0;				/* mark end of pointers */
154846a6e1dSsam 	nelem = ep - elem;
155846a6e1dSsam }
156846a6e1dSsam 
157a9451f0dSbostic void
putfile()158846a6e1dSsam putfile()
159846a6e1dSsam {
160846a6e1dSsam 	register char **ep;
161a9451f0dSbostic 	register int i, j;
162846a6e1dSsam 
163846a6e1dSsam 	ep = elem;
164846a6e1dSsam 	if (flags & TRANSPOSE)
165846a6e1dSsam 		for (i = 0; i < orows; i++) {
166846a6e1dSsam 			for (j = i; j < nelem; j += orows)
167846a6e1dSsam 				prints(ep[j], (j - i) / orows);
168846a6e1dSsam 			putchar('\n');
169846a6e1dSsam 		}
170846a6e1dSsam 	else
171846a6e1dSsam 		for (i = 0; i < orows; i++) {
172846a6e1dSsam 			for (j = 0; j < ocols; j++)
173846a6e1dSsam 				prints(*ep++, j);
174846a6e1dSsam 			putchar('\n');
175846a6e1dSsam 		}
176846a6e1dSsam }
177846a6e1dSsam 
178a9451f0dSbostic void
prints(s,col)179846a6e1dSsam prints(s, col)
180846a6e1dSsam 	char *s;
181846a6e1dSsam 	int col;
182846a6e1dSsam {
183846a6e1dSsam 	register int n;
184a9451f0dSbostic 	register char *p = s;
185846a6e1dSsam 
186846a6e1dSsam 	while (*p)
187846a6e1dSsam 		p++;
188846a6e1dSsam 	n = (flags & ONEOSEPONLY ? 1 : colwidths[col] - (p - s));
189846a6e1dSsam 	if (flags & RIGHTADJUST)
190846a6e1dSsam 		while (n-- > 0)
191846a6e1dSsam 			putchar(osep);
192846a6e1dSsam 	for (p = s; *p; p++)
193846a6e1dSsam 		putchar(*p);
194846a6e1dSsam 	while (n-- > 0)
195846a6e1dSsam 		putchar(osep);
196846a6e1dSsam }
197846a6e1dSsam 
198a9451f0dSbostic void
error(msg,s)199846a6e1dSsam error(msg, s)
200a9451f0dSbostic 	char *msg, *s;
201846a6e1dSsam {
202846a6e1dSsam 	fprintf(stderr, "rs:  ");
203846a6e1dSsam 	fprintf(stderr, msg, s);
204a9451f0dSbostic 	fprintf(stderr,
205a9451f0dSbostic "\nUsage:  rs [ -[csCS][x][kKgGw][N]tTeEnyjhHm ] [ rows [ cols ] ]\n");
206846a6e1dSsam 	exit(1);
207846a6e1dSsam }
208846a6e1dSsam 
209a9451f0dSbostic void
prepfile()210846a6e1dSsam prepfile()
211846a6e1dSsam {
212846a6e1dSsam 	register char **ep;
213846a6e1dSsam 	register int  i;
214846a6e1dSsam 	register int  j;
215846a6e1dSsam 	char **lp;
216846a6e1dSsam 	int colw;
217846a6e1dSsam 	int max = 0;
218846a6e1dSsam 	int n;
219846a6e1dSsam 
220846a6e1dSsam 	if (!nelem)
221846a6e1dSsam 		exit(0);
222846a6e1dSsam 	gutter += maxlen * propgutter / 100.0;
223846a6e1dSsam 	colw = maxlen + gutter;
224846a6e1dSsam 	if (flags & MTRANSPOSE) {
225846a6e1dSsam 		orows = icols;
226846a6e1dSsam 		ocols = irows;
227846a6e1dSsam 	}
228846a6e1dSsam 	else if (orows == 0 && ocols == 0) {	/* decide rows and cols */
229ab6065d8Sjak 		ocols = owidth / colw;
230ab6065d8Sjak 		if (ocols == 0)
231ab6065d8Sjak 			fprintf(stderr, "Display width %d is less than column width %d\n", owidth, colw);
232846a6e1dSsam 		if (ocols > nelem)
233846a6e1dSsam 			ocols = nelem;
234846a6e1dSsam 		orows = nelem / ocols + (nelem % ocols ? 1 : 0);
235846a6e1dSsam 	}
236846a6e1dSsam 	else if (orows == 0)			/* decide on rows */
237846a6e1dSsam 		orows = nelem / ocols + (nelem % ocols ? 1 : 0);
238846a6e1dSsam 	else if (ocols == 0)			/* decide on cols */
239846a6e1dSsam 		ocols = nelem / orows + (nelem % orows ? 1 : 0);
240846a6e1dSsam 	lp = elem + orows * ocols;
241846a6e1dSsam 	while (lp > endelem) {
242846a6e1dSsam 		getptrs(elem + nelem);
243846a6e1dSsam 		lp = elem + orows * ocols;
244846a6e1dSsam 	}
245846a6e1dSsam 	if (flags & RECYCLE) {
246846a6e1dSsam 		for (ep = elem + nelem; ep < lp; ep++)
247846a6e1dSsam 			*ep = *(ep - nelem);
248846a6e1dSsam 		nelem = lp - elem;
249846a6e1dSsam 	}
250846a6e1dSsam 	if (!(colwidths = (short *) malloc(ocols * sizeof(short))))
251846a6e1dSsam 		error("malloc:  No gutter space", "");
252846a6e1dSsam 	if (flags & SQUEEZE) {
253846a6e1dSsam 		if (flags & TRANSPOSE)
254846a6e1dSsam 			for (ep = elem, i = 0; i < ocols; i++) {
255846a6e1dSsam 				for (j = 0; j < orows; j++)
256846a6e1dSsam 					if ((n = strlen(*ep++)) > max)
257846a6e1dSsam 						max = n;
258846a6e1dSsam 				colwidths[i] = max + gutter;
259846a6e1dSsam 			}
260846a6e1dSsam 		else
261846a6e1dSsam 			for (i = 0; i < ocols; i++) {
262846a6e1dSsam 				for (j = i; j < nelem; j += ocols)
263846a6e1dSsam 					if ((n = strlen(ep[j])) > max)
264846a6e1dSsam 						max = n;
265846a6e1dSsam 				colwidths[i] = max + gutter;
266846a6e1dSsam 			}
267846a6e1dSsam 	}
268846a6e1dSsam 	/*	for (i = 0; i < orows; i++) {
269846a6e1dSsam 			for (j = i; j < nelem; j += orows)
270846a6e1dSsam 				prints(ep[j], (j - i) / orows);
271846a6e1dSsam 			putchar('\n');
272846a6e1dSsam 		}
273846a6e1dSsam 	else
274846a6e1dSsam 		for (i = 0; i < orows; i++) {
275846a6e1dSsam 			for (j = 0; j < ocols; j++)
276846a6e1dSsam 				prints(*ep++, j);
277846a6e1dSsam 			putchar('\n');
278846a6e1dSsam 		}*/
279846a6e1dSsam 	else
280846a6e1dSsam 		for (i = 0; i < ocols; i++)
281846a6e1dSsam 			colwidths[i] = colw;
282846a6e1dSsam 	if (!(flags & NOTRIMENDCOL)) {
283846a6e1dSsam 		if (flags & RIGHTADJUST)
284846a6e1dSsam 			colwidths[0] -= gutter;
285846a6e1dSsam 		else
286846a6e1dSsam 			colwidths[ocols - 1] = 0;
287846a6e1dSsam 	}
288846a6e1dSsam 	n = orows * ocols;
289846a6e1dSsam 	if (n > nelem && (flags & RECYCLE))
290846a6e1dSsam 		nelem = n;
291846a6e1dSsam 	/*for (i = 0; i < ocols; i++)
292846a6e1dSsam 		fprintf(stderr, "%d ",colwidths[i]);
293846a6e1dSsam 	fprintf(stderr, "is colwidths, nelem %d\n", nelem);*/
294846a6e1dSsam }
295846a6e1dSsam 
296846a6e1dSsam #define	BSIZE	2048
297846a6e1dSsam char	ibuf[BSIZE];		/* two screenfuls should do */
298846a6e1dSsam 
299a9451f0dSbostic int
getline()300846a6e1dSsam getline()	/* get line; maintain curline, curlen; manage storage */
301846a6e1dSsam {
302846a6e1dSsam 	static	int putlength;
303846a6e1dSsam 	static	char *endblock = ibuf + BSIZE;
304a9451f0dSbostic 	register char *p;
305a9451f0dSbostic 	register int c, i;
306846a6e1dSsam 
307846a6e1dSsam 	if (!irows) {
308846a6e1dSsam 		curline = ibuf;
309846a6e1dSsam 		putlength = flags & DETAILSHAPE;
310846a6e1dSsam 	}
311846a6e1dSsam 	else if (skip <= 0) {			/* don't waste storage */
312846a6e1dSsam 		curline += curlen + 1;
313846a6e1dSsam 		if (putlength)		/* print length, recycle storage */
314846a6e1dSsam 			printf(" %d line %d\n", curlen, irows);
315846a6e1dSsam 	}
316846a6e1dSsam 	if (!putlength && endblock - curline < BUFSIZ) {   /* need storage */
317846a6e1dSsam 		/*ww = endblock-curline; tt += ww;*/
318846a6e1dSsam 		/*printf("#wasted %d total %d\n",ww,tt);*/
319846a6e1dSsam 		if (!(curline = (char *) malloc(BSIZE)))
320846a6e1dSsam 			error("File too large", "");
321846a6e1dSsam 		endblock = curline + BSIZE;
322846a6e1dSsam 		/*printf("#endb %d curline %d\n",endblock,curline);*/
323846a6e1dSsam 	}
324846a6e1dSsam 	for (p = curline, i = 1; i < BUFSIZ; *p++ = c, i++)
325846a6e1dSsam 		if ((c = getchar()) == EOF || c == '\n')
326846a6e1dSsam 			break;
327846a6e1dSsam 	*p = '\0';
328846a6e1dSsam 	curlen = i - 1;
329846a6e1dSsam 	return(c);
330846a6e1dSsam }
331846a6e1dSsam 
332846a6e1dSsam char **
getptrs(sp)333846a6e1dSsam getptrs(sp)
334846a6e1dSsam 	char **sp;
335846a6e1dSsam {
336a9451f0dSbostic 	register char **p, **ep;
337846a6e1dSsam 
338846a6e1dSsam 	for (;;) {
339846a6e1dSsam 		allocsize += allocsize;
340846a6e1dSsam 		if (!(p = (char **) malloc(allocsize * sizeof(char *)))) {
341846a6e1dSsam 			perror("rs");
342846a6e1dSsam 			exit(1);
343846a6e1dSsam 		}
344846a6e1dSsam 		if ((endelem = p + allocsize - icols) <= p) {
345846a6e1dSsam 			free(p);
346846a6e1dSsam 			continue;
347846a6e1dSsam 		}
348846a6e1dSsam 		if (elem != 0)
349846a6e1dSsam 			free(elem);
350846a6e1dSsam 		ep = elem;
351846a6e1dSsam 		elem = p;
352846a6e1dSsam 		while (ep < sp)
353846a6e1dSsam 			*p++ = *ep++;
354846a6e1dSsam 		return(p);
355846a6e1dSsam 	}
356846a6e1dSsam }
357846a6e1dSsam 
358a9451f0dSbostic void
getargs(ac,av)359846a6e1dSsam getargs(ac, av)
360846a6e1dSsam 	int ac;
361a9451f0dSbostic 	char *av[];
362846a6e1dSsam {
363846a6e1dSsam 	register char *p;
364846a6e1dSsam 
365846a6e1dSsam 	if (ac == 1) {
366ab6065d8Sjak 		flags |= NOARGS | TRANSPOSE;
367846a6e1dSsam 	}
368846a6e1dSsam 	while (--ac && **++av == '-')
369846a6e1dSsam 		for (p = *av+1; *p; p++)
370846a6e1dSsam 			switch (*p) {
371846a6e1dSsam 			case 'T':
372846a6e1dSsam 				flags |= MTRANSPOSE;
373846a6e1dSsam 			case 't':
374846a6e1dSsam 				flags |= TRANSPOSE;
375846a6e1dSsam 				break;
376846a6e1dSsam 			case 'c':		/* input col. separator */
377846a6e1dSsam 				flags |= ONEISEPONLY;
378846a6e1dSsam 			case 's':		/* one or more allowed */
379846a6e1dSsam 				if (p[1])
380846a6e1dSsam 					isep = *++p;
381846a6e1dSsam 				else
382846a6e1dSsam 					isep = '\t';	/* default is ^I */
383846a6e1dSsam 				break;
384846a6e1dSsam 			case 'C':
385846a6e1dSsam 				flags |= ONEOSEPONLY;
386846a6e1dSsam 			case 'S':
387846a6e1dSsam 				if (p[1])
388846a6e1dSsam 					osep = *++p;
389846a6e1dSsam 				else
390846a6e1dSsam 					osep = '\t';	/* default is ^I */
391846a6e1dSsam 				break;
392846a6e1dSsam 			case 'w':		/* window width, default 80 */
393846a6e1dSsam 				p = getnum(&owidth, p, 0);
394846a6e1dSsam 				if (owidth <= 0)
395846a6e1dSsam 				error("Width must be a positive integer", "");
396846a6e1dSsam 				break;
397846a6e1dSsam 			case 'K':			/* skip N lines */
398846a6e1dSsam 				flags |= SKIPPRINT;
399846a6e1dSsam 			case 'k':			/* skip, do not print */
400846a6e1dSsam 				p = getnum(&skip, p, 0);
401846a6e1dSsam 				if (!skip)
402846a6e1dSsam 					skip = 1;
403846a6e1dSsam 				break;
404846a6e1dSsam 			case 'm':
405846a6e1dSsam 				flags |= NOTRIMENDCOL;
406846a6e1dSsam 				break;
407846a6e1dSsam 			case 'g':		/* gutter space */
408846a6e1dSsam 				p = getnum(&gutter, p, 0);
409846a6e1dSsam 				break;
410846a6e1dSsam 			case 'G':
411846a6e1dSsam 				p = getnum(&propgutter, p, 0);
412846a6e1dSsam 				break;
413846a6e1dSsam 			case 'e':		/* each line is an entry */
414846a6e1dSsam 				flags |= ONEPERLINE;
415846a6e1dSsam 				break;
416846a6e1dSsam 			case 'E':
417846a6e1dSsam 				flags |= ONEPERCHAR;
418846a6e1dSsam 				break;
419846a6e1dSsam 			case 'j':			/* right adjust */
420846a6e1dSsam 				flags |= RIGHTADJUST;
421846a6e1dSsam 				break;
422846a6e1dSsam 			case 'n':	/* null padding for missing values */
423846a6e1dSsam 				flags |= NULLPAD;
424846a6e1dSsam 				break;
425846a6e1dSsam 			case 'y':
426846a6e1dSsam 				flags |= RECYCLE;
427846a6e1dSsam 				break;
428846a6e1dSsam 			case 'H':			/* print shape only */
429846a6e1dSsam 				flags |= DETAILSHAPE;
430846a6e1dSsam 			case 'h':
431846a6e1dSsam 				flags |= SHAPEONLY;
432846a6e1dSsam 				break;
433846a6e1dSsam 			case 'z':			/* squeeze col width */
434846a6e1dSsam 				flags |= SQUEEZE;
435846a6e1dSsam 				break;
436846a6e1dSsam 			/*case 'p':
437846a6e1dSsam 				ipagespace = atoi(++p);	(default is 1)
438846a6e1dSsam 				break;*/
439846a6e1dSsam 			case 'o':			/* col order */
440846a6e1dSsam 				p = getlist(&cord, p);
441846a6e1dSsam 				break;
442846a6e1dSsam 			case 'b':
443846a6e1dSsam 				flags |= ICOLBOUNDS;
444846a6e1dSsam 				p = getlist(&icbd, p);
445846a6e1dSsam 				break;
446846a6e1dSsam 			case 'B':
447846a6e1dSsam 				flags |= OCOLBOUNDS;
448846a6e1dSsam 				p = getlist(&ocbd, p);
449846a6e1dSsam 				break;
450846a6e1dSsam 			default:
451846a6e1dSsam 				error("Bad flag:  %.1s", p);
452846a6e1dSsam 			}
453846a6e1dSsam 	/*if (!osep)
454846a6e1dSsam 		osep = isep;*/
455846a6e1dSsam 	switch (ac) {
456846a6e1dSsam 	/*case 3:
457846a6e1dSsam 		opages = atoi(av[2]);*/
458846a6e1dSsam 	case 2:
459846a6e1dSsam 		ocols = atoi(av[1]);
460846a6e1dSsam 	case 1:
461846a6e1dSsam 		orows = atoi(av[0]);
462846a6e1dSsam 	case 0:
463846a6e1dSsam 		break;
464846a6e1dSsam 	default:
465846a6e1dSsam 		error("Too many arguments.  What do you mean by `%s'?", av[3]);
466846a6e1dSsam 	}
467846a6e1dSsam }
468846a6e1dSsam 
469846a6e1dSsam char *
getlist(list,p)470846a6e1dSsam getlist(list, p)
471846a6e1dSsam 	short **list;
472846a6e1dSsam 	char *p;
473846a6e1dSsam {
474846a6e1dSsam 	register int count = 1;
475a9451f0dSbostic 	register char *t;
476846a6e1dSsam 
477846a6e1dSsam 	for (t = p + 1; *t; t++) {
478846a6e1dSsam 		if (!isdigit(*t))
479846a6e1dSsam 			error("Option %.1s requires a list of unsigned numbers separated by commas", t);
480846a6e1dSsam 		count++;
481846a6e1dSsam 		while (*t && isdigit(*t))
482846a6e1dSsam 			t++;
483846a6e1dSsam 		if (*t != ',')
484846a6e1dSsam 			break;
485846a6e1dSsam 	}
486846a6e1dSsam 	if (!(*list = (short *) malloc(count * sizeof(short))))
487846a6e1dSsam 		error("No list space", "");
488846a6e1dSsam 	count = 0;
489846a6e1dSsam 	for (t = p + 1; *t; t++) {
490846a6e1dSsam 		(*list)[count++] = atoi(t);
491846a6e1dSsam 		printf("++ %d ", (*list)[count-1]);
492846a6e1dSsam 		fflush(stdout);
493846a6e1dSsam 		while (*t && isdigit(*t))
494846a6e1dSsam 			t++;
495846a6e1dSsam 		if (*t != ',')
496846a6e1dSsam 			break;
497846a6e1dSsam 	}
498846a6e1dSsam 	(*list)[count] = 0;
499846a6e1dSsam 	return(t - 1);
500846a6e1dSsam }
501846a6e1dSsam 
502846a6e1dSsam char *
getnum(num,p,strict)503846a6e1dSsam getnum(num, p, strict)	/* num = number p points to; if (strict) complain */
504a9451f0dSbostic 	int *num, strict;	/* returns pointer to end of num */
505846a6e1dSsam 	char *p;
506846a6e1dSsam {
507846a6e1dSsam 	register char *t = p;
508846a6e1dSsam 
509846a6e1dSsam 	if (!isdigit(*++t)) {
510846a6e1dSsam 		if (strict || *t == '-' || *t == '+')
511846a6e1dSsam 			error("Option %.1s requires an unsigned integer", p);
512846a6e1dSsam 		*num = 0;
513846a6e1dSsam 		return(p);
514846a6e1dSsam 	}
515846a6e1dSsam 	*num = atoi(t);
516846a6e1dSsam 	while (*++t)
517846a6e1dSsam 		if (!isdigit(*t))
518846a6e1dSsam 			break;
519846a6e1dSsam 	return(--t);
520846a6e1dSsam }
521