11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 4. Neither the name of the University nor the names of its contributors 141590Srgrimes * may be used to endorse or promote products derived from this software 151590Srgrimes * without specific prior written permission. 161590Srgrimes * 171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271590Srgrimes * SUCH DAMAGE. 281590Srgrimes */ 291590Srgrimes 301590Srgrimes#ifndef lint 3127953Scharnierstatic const char copyright[] = 321590Srgrimes"@(#) Copyright (c) 1993\n\ 331590Srgrimes The Regents of the University of California. All rights reserved.\n"; 341590Srgrimes#endif /* not lint */ 351590Srgrimes 361590Srgrimes#ifndef lint 3795618Smarkmstatic const char sccsid[] = "@(#)rs.c 8.1 (Berkeley) 6/6/93"; 381590Srgrimes#endif /* not lint */ 391590Srgrimes 401590Srgrimes/* 411590Srgrimes * rs - reshape a data array 421590Srgrimes * Author: John Kunze, Office of Comp. Affairs, UCB 431590Srgrimes * BEWARE: lots of unfinished edges 441590Srgrimes */ 451590Srgrimes 4695618Smarkm#include <sys/cdefs.h> 4795618Smarkm__FBSDID("$FreeBSD$"); 4895618Smarkm 4927953Scharnier#include <err.h> 501590Srgrimes#include <ctype.h> 51218411Sjh#include <limits.h> 521590Srgrimes#include <stdio.h> 531590Srgrimes#include <stdlib.h> 5433648Sjb#include <string.h> 551590Srgrimes 56227177Sedstatic long flags; 571590Srgrimes#define TRANSPOSE 000001 581590Srgrimes#define MTRANSPOSE 000002 591590Srgrimes#define ONEPERLINE 000004 601590Srgrimes#define ONEISEPONLY 000010 611590Srgrimes#define ONEOSEPONLY 000020 621590Srgrimes#define NOTRIMENDCOL 000040 631590Srgrimes#define SQUEEZE 000100 641590Srgrimes#define SHAPEONLY 000200 651590Srgrimes#define DETAILSHAPE 000400 661590Srgrimes#define RIGHTADJUST 001000 671590Srgrimes#define NULLPAD 002000 681590Srgrimes#define RECYCLE 004000 691590Srgrimes#define SKIPPRINT 010000 701590Srgrimes#define ICOLBOUNDS 020000 711590Srgrimes#define OCOLBOUNDS 040000 721590Srgrimes#define ONEPERCHAR 0100000 731590Srgrimes#define NOARGS 0200000 741590Srgrimes 75227177Sedstatic short *colwidths; 76227177Sedstatic short *cord; 77227177Sedstatic short *icbd; 78227177Sedstatic short *ocbd; 79227177Sedstatic int nelem; 80227177Sedstatic char **elem; 81227177Sedstatic char **endelem; 82227177Sedstatic char *curline; 83227177Sedstatic int allocsize = BUFSIZ; 84227177Sedstatic int curlen; 85227177Sedstatic int irows, icols; 86227177Sedstatic int orows = 0, ocols = 0; 87227177Sedstatic int maxlen; 88227177Sedstatic int skip; 89227177Sedstatic int propgutter; 90227177Sedstatic char isep = ' ', osep = ' '; 91227177Sedstatic char blank[] = ""; 92227177Sedstatic int owidth = 80, gutter = 2; 931590Srgrimes 94227177Sedstatic void getargs(int, char *[]); 95227177Sedstatic void getfile(void); 96227177Sedstatic int getline(void); 97227177Sedstatic char *getlist(short **, char *); 98227177Sedstatic char *getnum(int *, char *, int); 99227177Sedstatic char **getptrs(char **); 100227177Sedstatic void prepfile(void); 101227177Sedstatic void prints(char *, int); 102227177Sedstatic void putfile(void); 10392921Simpstatic void usage(void); 1041590Srgrimes 10583303Sru#define INCR(ep) do { \ 10683303Sru if (++ep >= endelem) \ 10783303Sru ep = getptrs(ep); \ 10883303Sru} while(0) 10983303Sru 1101590Srgrimesint 11195618Smarkmmain(int argc, char *argv[]) 1121590Srgrimes{ 1131590Srgrimes getargs(argc, argv); 1141590Srgrimes getfile(); 1151590Srgrimes if (flags & SHAPEONLY) { 1161590Srgrimes printf("%d %d\n", irows, icols); 1171590Srgrimes exit(0); 1181590Srgrimes } 1191590Srgrimes prepfile(); 1201590Srgrimes putfile(); 1211590Srgrimes exit(0); 1221590Srgrimes} 1231590Srgrimes 124227177Sedstatic void 12595618Smarkmgetfile(void) 1261590Srgrimes{ 12795618Smarkm char *p; 12895618Smarkm char *endp; 12983303Sru char **ep; 130218410Sjh int c; 1311590Srgrimes int multisep = (flags & ONEISEPONLY ? 0 : 1); 1321590Srgrimes int nullpad = flags & NULLPAD; 1331590Srgrimes char **padto; 1341590Srgrimes 1351590Srgrimes while (skip--) { 136218410Sjh c = getline(); 1371590Srgrimes if (flags & SKIPPRINT) 1381590Srgrimes puts(curline); 139218410Sjh if (c == EOF) 140218410Sjh return; 1411590Srgrimes } 1421590Srgrimes getline(); 1431590Srgrimes if (flags & NOARGS && curlen < owidth) 1441590Srgrimes flags |= ONEPERLINE; 1451590Srgrimes if (flags & ONEPERLINE) 1461590Srgrimes icols = 1; 1471590Srgrimes else /* count cols on first line */ 1481590Srgrimes for (p = curline, endp = curline + curlen; p < endp; p++) { 1491590Srgrimes if (*p == isep && multisep) 1501590Srgrimes continue; 1511590Srgrimes icols++; 1521590Srgrimes while (*p && *p != isep) 1531590Srgrimes p++; 1541590Srgrimes } 1551590Srgrimes ep = getptrs(elem); 1561590Srgrimes do { 1571590Srgrimes if (flags & ONEPERLINE) { 15883303Sru *ep = curline; 15983303Sru INCR(ep); /* prepare for next entry */ 1601590Srgrimes if (maxlen < curlen) 1611590Srgrimes maxlen = curlen; 1621590Srgrimes irows++; 1631590Srgrimes continue; 1641590Srgrimes } 1651590Srgrimes for (p = curline, endp = curline + curlen; p < endp; p++) { 1661590Srgrimes if (*p == isep && multisep) 1671590Srgrimes continue; /* eat up column separators */ 1681590Srgrimes if (*p == isep) /* must be an empty column */ 16995618Smarkm *ep = blank; 1701590Srgrimes else /* store column entry */ 1711590Srgrimes *ep = p; 1721590Srgrimes while (p < endp && *p != isep) 1731590Srgrimes p++; /* find end of entry */ 1741590Srgrimes *p = '\0'; /* mark end of entry */ 1751590Srgrimes if (maxlen < p - *ep) /* update maxlen */ 1761590Srgrimes maxlen = p - *ep; 17783303Sru INCR(ep); /* prepare for next entry */ 1781590Srgrimes } 1791590Srgrimes irows++; /* update row count */ 1801590Srgrimes if (nullpad) { /* pad missing entries */ 1811590Srgrimes padto = elem + irows * icols; 18283303Sru while (ep < padto) { 18395618Smarkm *ep = blank; 18483303Sru INCR(ep); 18583303Sru } 1861590Srgrimes } 1871590Srgrimes } while (getline() != EOF); 1881590Srgrimes *ep = 0; /* mark end of pointers */ 1891590Srgrimes nelem = ep - elem; 1901590Srgrimes} 1911590Srgrimes 192227177Sedstatic void 19395618Smarkmputfile(void) 1941590Srgrimes{ 19595618Smarkm char **ep; 19695618Smarkm int i, j, k; 1971590Srgrimes 1981590Srgrimes ep = elem; 1991590Srgrimes if (flags & TRANSPOSE) 2001590Srgrimes for (i = 0; i < orows; i++) { 2011590Srgrimes for (j = i; j < nelem; j += orows) 2021590Srgrimes prints(ep[j], (j - i) / orows); 2031590Srgrimes putchar('\n'); 2041590Srgrimes } 2051590Srgrimes else 20615909Sjoerg for (i = k = 0; i < orows; i++) { 20715909Sjoerg for (j = 0; j < ocols; j++, k++) 20815909Sjoerg if (k < nelem) 20915909Sjoerg prints(ep[k], j); 2101590Srgrimes putchar('\n'); 2111590Srgrimes } 2121590Srgrimes} 2131590Srgrimes 214227177Sedstatic void 21595618Smarkmprints(char *s, int col) 2161590Srgrimes{ 21795618Smarkm int n; 21895618Smarkm char *p = s; 2191590Srgrimes 2201590Srgrimes while (*p) 2211590Srgrimes p++; 2221590Srgrimes n = (flags & ONEOSEPONLY ? 1 : colwidths[col] - (p - s)); 2231590Srgrimes if (flags & RIGHTADJUST) 2241590Srgrimes while (n-- > 0) 2251590Srgrimes putchar(osep); 2261590Srgrimes for (p = s; *p; p++) 2271590Srgrimes putchar(*p); 2281590Srgrimes while (n-- > 0) 2291590Srgrimes putchar(osep); 2301590Srgrimes} 2311590Srgrimes 23227953Scharnierstatic void 23395618Smarkmusage(void) 2341590Srgrimes{ 2351590Srgrimes fprintf(stderr, 23627953Scharnier "usage: rs [-[csCS][x][kKgGw][N]tTeEnyjhHmz] [rows [cols]]\n"); 2371590Srgrimes exit(1); 2381590Srgrimes} 2391590Srgrimes 240227177Sedstatic void 24195618Smarkmprepfile(void) 2421590Srgrimes{ 24395618Smarkm char **ep; 24495618Smarkm int i; 24595618Smarkm int j; 2461590Srgrimes char **lp; 2471590Srgrimes int colw; 24883296Sru int max; 2491590Srgrimes int n; 2501590Srgrimes 2511590Srgrimes if (!nelem) 2521590Srgrimes exit(0); 2531590Srgrimes gutter += maxlen * propgutter / 100.0; 2541590Srgrimes colw = maxlen + gutter; 2551590Srgrimes if (flags & MTRANSPOSE) { 2561590Srgrimes orows = icols; 2571590Srgrimes ocols = irows; 2581590Srgrimes } 2591590Srgrimes else if (orows == 0 && ocols == 0) { /* decide rows and cols */ 2601590Srgrimes ocols = owidth / colw; 26183298Sru if (ocols == 0) { 26227953Scharnier warnx("display width %d is less than column width %d", 26327953Scharnier owidth, colw); 26483298Sru ocols = 1; 26583298Sru } 2661590Srgrimes if (ocols > nelem) 2671590Srgrimes ocols = nelem; 2681590Srgrimes orows = nelem / ocols + (nelem % ocols ? 1 : 0); 2691590Srgrimes } 2701590Srgrimes else if (orows == 0) /* decide on rows */ 2711590Srgrimes orows = nelem / ocols + (nelem % ocols ? 1 : 0); 2721590Srgrimes else if (ocols == 0) /* decide on cols */ 2731590Srgrimes ocols = nelem / orows + (nelem % orows ? 1 : 0); 2741590Srgrimes lp = elem + orows * ocols; 2751590Srgrimes while (lp > endelem) { 2761590Srgrimes getptrs(elem + nelem); 2771590Srgrimes lp = elem + orows * ocols; 2781590Srgrimes } 2791590Srgrimes if (flags & RECYCLE) { 2801590Srgrimes for (ep = elem + nelem; ep < lp; ep++) 2811590Srgrimes *ep = *(ep - nelem); 2821590Srgrimes nelem = lp - elem; 2831590Srgrimes } 2841590Srgrimes if (!(colwidths = (short *) malloc(ocols * sizeof(short)))) 28527953Scharnier errx(1, "malloc"); 2861590Srgrimes if (flags & SQUEEZE) { 28783296Sru ep = elem; 2881590Srgrimes if (flags & TRANSPOSE) 28983296Sru for (i = 0; i < ocols; i++) { 29083296Sru max = 0; 29183296Sru for (j = 0; *ep != NULL && j < orows; j++) 2921590Srgrimes if ((n = strlen(*ep++)) > max) 2931590Srgrimes max = n; 2941590Srgrimes colwidths[i] = max + gutter; 2951590Srgrimes } 2961590Srgrimes else 2971590Srgrimes for (i = 0; i < ocols; i++) { 29883296Sru max = 0; 2991590Srgrimes for (j = i; j < nelem; j += ocols) 3001590Srgrimes if ((n = strlen(ep[j])) > max) 3011590Srgrimes max = n; 3021590Srgrimes colwidths[i] = max + gutter; 3031590Srgrimes } 3041590Srgrimes } 3051590Srgrimes /* for (i = 0; i < orows; i++) { 3061590Srgrimes for (j = i; j < nelem; j += orows) 3071590Srgrimes prints(ep[j], (j - i) / orows); 3081590Srgrimes putchar('\n'); 3091590Srgrimes } 3101590Srgrimes else 3111590Srgrimes for (i = 0; i < orows; i++) { 3121590Srgrimes for (j = 0; j < ocols; j++) 3131590Srgrimes prints(*ep++, j); 3141590Srgrimes putchar('\n'); 3151590Srgrimes }*/ 3161590Srgrimes else 3171590Srgrimes for (i = 0; i < ocols; i++) 3181590Srgrimes colwidths[i] = colw; 3191590Srgrimes if (!(flags & NOTRIMENDCOL)) { 3201590Srgrimes if (flags & RIGHTADJUST) 3211590Srgrimes colwidths[0] -= gutter; 3221590Srgrimes else 3231590Srgrimes colwidths[ocols - 1] = 0; 3241590Srgrimes } 3251590Srgrimes n = orows * ocols; 3261590Srgrimes if (n > nelem && (flags & RECYCLE)) 3271590Srgrimes nelem = n; 3281590Srgrimes /*for (i = 0; i < ocols; i++) 32927953Scharnier warnx("%d is colwidths, nelem %d", colwidths[i], nelem);*/ 3301590Srgrimes} 3311590Srgrimes 332218411Sjh#define BSIZE (LINE_MAX * 2) 333227177Sedstatic char ibuf[BSIZE]; 3341590Srgrimes 335227177Sedstatic int 33695618Smarkmgetline(void) /* get line; maintain curline, curlen; manage storage */ 3371590Srgrimes{ 3381590Srgrimes static int putlength; 3391590Srgrimes static char *endblock = ibuf + BSIZE; 34095618Smarkm char *p; 34195618Smarkm int c, i; 3421590Srgrimes 3431590Srgrimes if (!irows) { 3441590Srgrimes curline = ibuf; 3451590Srgrimes putlength = flags & DETAILSHAPE; 3461590Srgrimes } 3471590Srgrimes else if (skip <= 0) { /* don't waste storage */ 3481590Srgrimes curline += curlen + 1; 34998003Stjr if (putlength) { /* print length, recycle storage */ 3501590Srgrimes printf(" %d line %d\n", curlen, irows); 35198003Stjr curline = ibuf; 35298003Stjr } 3531590Srgrimes } 354218411Sjh if (!putlength && endblock - curline < LINE_MAX + 1) { /* need storage */ 3551590Srgrimes /*ww = endblock-curline; tt += ww;*/ 3561590Srgrimes /*printf("#wasted %d total %d\n",ww,tt);*/ 3571590Srgrimes if (!(curline = (char *) malloc(BSIZE))) 35827953Scharnier errx(1, "file too large"); 3591590Srgrimes endblock = curline + BSIZE; 3601590Srgrimes /*printf("#endb %d curline %d\n",endblock,curline);*/ 3611590Srgrimes } 362218411Sjh for (p = curline, i = 0;; *p++ = c, i++) { 363218411Sjh if ((c = getchar()) == EOF) 3641590Srgrimes break; 365218411Sjh if (i >= LINE_MAX) 366218411Sjh errx(1, "maximum line length (%d) exceeded", LINE_MAX); 367218411Sjh if (c == '\n') 368218411Sjh break; 369218411Sjh } 3701590Srgrimes *p = '\0'; 371218411Sjh curlen = i; 3721590Srgrimes return(c); 3731590Srgrimes} 3741590Srgrimes 375227177Sedstatic char ** 37695618Smarkmgetptrs(char **sp) 3771590Srgrimes{ 37883303Sru char **p; 3791590Srgrimes 38083303Sru allocsize += allocsize; 38183303Sru p = (char **)realloc(elem, allocsize * sizeof(char *)); 38283303Sru if (p == NULL) 38383303Sru err(1, "no memory"); 38483303Sru 38583303Sru sp += (p - elem); 38683303Sru endelem = (elem = p) + allocsize; 38783303Sru return(sp); 3881590Srgrimes} 3891590Srgrimes 390227177Sedstatic void 39195618Smarkmgetargs(int ac, char *av[]) 3921590Srgrimes{ 39395618Smarkm char *p; 3941590Srgrimes 3951590Srgrimes if (ac == 1) { 3961590Srgrimes flags |= NOARGS | TRANSPOSE; 3971590Srgrimes } 3981590Srgrimes while (--ac && **++av == '-') 3991590Srgrimes for (p = *av+1; *p; p++) 4001590Srgrimes switch (*p) { 4011590Srgrimes case 'T': 4021590Srgrimes flags |= MTRANSPOSE; 4031590Srgrimes case 't': 4041590Srgrimes flags |= TRANSPOSE; 4051590Srgrimes break; 4061590Srgrimes case 'c': /* input col. separator */ 4071590Srgrimes flags |= ONEISEPONLY; 4081590Srgrimes case 's': /* one or more allowed */ 4091590Srgrimes if (p[1]) 4101590Srgrimes isep = *++p; 4111590Srgrimes else 4121590Srgrimes isep = '\t'; /* default is ^I */ 4131590Srgrimes break; 4141590Srgrimes case 'C': 4151590Srgrimes flags |= ONEOSEPONLY; 4161590Srgrimes case 'S': 4171590Srgrimes if (p[1]) 4181590Srgrimes osep = *++p; 4191590Srgrimes else 4201590Srgrimes osep = '\t'; /* default is ^I */ 4211590Srgrimes break; 4221590Srgrimes case 'w': /* window width, default 80 */ 4231590Srgrimes p = getnum(&owidth, p, 0); 4241590Srgrimes if (owidth <= 0) 42527953Scharnier errx(1, "width must be a positive integer"); 4261590Srgrimes break; 4271590Srgrimes case 'K': /* skip N lines */ 4281590Srgrimes flags |= SKIPPRINT; 4291590Srgrimes case 'k': /* skip, do not print */ 4301590Srgrimes p = getnum(&skip, p, 0); 4311590Srgrimes if (!skip) 4321590Srgrimes skip = 1; 4331590Srgrimes break; 4341590Srgrimes case 'm': 4351590Srgrimes flags |= NOTRIMENDCOL; 4361590Srgrimes break; 4371590Srgrimes case 'g': /* gutter space */ 4381590Srgrimes p = getnum(&gutter, p, 0); 4391590Srgrimes break; 4401590Srgrimes case 'G': 4411590Srgrimes p = getnum(&propgutter, p, 0); 4421590Srgrimes break; 4431590Srgrimes case 'e': /* each line is an entry */ 4441590Srgrimes flags |= ONEPERLINE; 4451590Srgrimes break; 4461590Srgrimes case 'E': 4471590Srgrimes flags |= ONEPERCHAR; 4481590Srgrimes break; 4491590Srgrimes case 'j': /* right adjust */ 4501590Srgrimes flags |= RIGHTADJUST; 4511590Srgrimes break; 4521590Srgrimes case 'n': /* null padding for missing values */ 4531590Srgrimes flags |= NULLPAD; 4541590Srgrimes break; 4551590Srgrimes case 'y': 4561590Srgrimes flags |= RECYCLE; 4571590Srgrimes break; 4581590Srgrimes case 'H': /* print shape only */ 4591590Srgrimes flags |= DETAILSHAPE; 4601590Srgrimes case 'h': 4611590Srgrimes flags |= SHAPEONLY; 4621590Srgrimes break; 4631590Srgrimes case 'z': /* squeeze col width */ 4641590Srgrimes flags |= SQUEEZE; 4651590Srgrimes break; 4661590Srgrimes /*case 'p': 4671590Srgrimes ipagespace = atoi(++p); (default is 1) 4681590Srgrimes break;*/ 4691590Srgrimes case 'o': /* col order */ 4701590Srgrimes p = getlist(&cord, p); 4711590Srgrimes break; 4721590Srgrimes case 'b': 4731590Srgrimes flags |= ICOLBOUNDS; 4741590Srgrimes p = getlist(&icbd, p); 4751590Srgrimes break; 4761590Srgrimes case 'B': 4771590Srgrimes flags |= OCOLBOUNDS; 4781590Srgrimes p = getlist(&ocbd, p); 4791590Srgrimes break; 4801590Srgrimes default: 48127953Scharnier usage(); 4821590Srgrimes } 4831590Srgrimes /*if (!osep) 4841590Srgrimes osep = isep;*/ 4851590Srgrimes switch (ac) { 4861590Srgrimes /*case 3: 4871590Srgrimes opages = atoi(av[2]);*/ 4881590Srgrimes case 2: 489145617Srobert if ((ocols = atoi(av[1])) < 0) 490145617Srobert ocols = 0; 4911590Srgrimes case 1: 492145617Srobert if ((orows = atoi(av[0])) < 0) 493145617Srobert orows = 0; 4941590Srgrimes case 0: 4951590Srgrimes break; 4961590Srgrimes default: 49727953Scharnier errx(1, "too many arguments"); 4981590Srgrimes } 4991590Srgrimes} 5001590Srgrimes 501227177Sedstatic char * 50295618Smarkmgetlist(short **list, char *p) 5031590Srgrimes{ 50495618Smarkm int count = 1; 50595618Smarkm char *t; 5061590Srgrimes 5071590Srgrimes for (t = p + 1; *t; t++) { 508132205Stjr if (!isdigit((unsigned char)*t)) 50927953Scharnier errx(1, 51027953Scharnier "option %.1s requires a list of unsigned numbers separated by commas", t); 5111590Srgrimes count++; 512132205Stjr while (*t && isdigit((unsigned char)*t)) 5131590Srgrimes t++; 5141590Srgrimes if (*t != ',') 5151590Srgrimes break; 5161590Srgrimes } 5171590Srgrimes if (!(*list = (short *) malloc(count * sizeof(short)))) 51827953Scharnier errx(1, "no list space"); 5191590Srgrimes count = 0; 5201590Srgrimes for (t = p + 1; *t; t++) { 5211590Srgrimes (*list)[count++] = atoi(t); 5221590Srgrimes printf("++ %d ", (*list)[count-1]); 5231590Srgrimes fflush(stdout); 524132205Stjr while (*t && isdigit((unsigned char)*t)) 5251590Srgrimes t++; 5261590Srgrimes if (*t != ',') 5271590Srgrimes break; 5281590Srgrimes } 5291590Srgrimes (*list)[count] = 0; 5301590Srgrimes return(t - 1); 5311590Srgrimes} 5321590Srgrimes 53395618Smarkm/* 53495618Smarkm * num = number p points to; if (strict) complain 53595618Smarkm * returns pointer to end of num 53695618Smarkm */ 537227177Sedstatic char * 53895618Smarkmgetnum(int *num, char *p, int strict) 5391590Srgrimes{ 54095618Smarkm char *t = p; 5411590Srgrimes 542132205Stjr if (!isdigit((unsigned char)*++t)) { 5431590Srgrimes if (strict || *t == '-' || *t == '+') 54427953Scharnier errx(1, "option %.1s requires an unsigned integer", p); 5451590Srgrimes *num = 0; 5461590Srgrimes return(p); 5471590Srgrimes } 5481590Srgrimes *num = atoi(t); 5491590Srgrimes while (*++t) 550132205Stjr if (!isdigit((unsigned char)*t)) 5511590Srgrimes break; 5521590Srgrimes return(--t); 5531590Srgrimes} 554