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