1 1.17 mrg /* $NetBSD: rs.c,v 1.17 2023/08/10 20:36:29 mrg Exp $ */ 2 1.5 ad 3 1.1 tls /*- 4 1.1 tls * Copyright (c) 1993 5 1.1 tls * The Regents of the University of California. All rights reserved. 6 1.1 tls * 7 1.1 tls * Redistribution and use in source and binary forms, with or without 8 1.1 tls * modification, are permitted provided that the following conditions 9 1.1 tls * are met: 10 1.1 tls * 1. Redistributions of source code must retain the above copyright 11 1.1 tls * notice, this list of conditions and the following disclaimer. 12 1.1 tls * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 tls * notice, this list of conditions and the following disclaimer in the 14 1.1 tls * documentation and/or other materials provided with the distribution. 15 1.9 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 tls * may be used to endorse or promote products derived from this software 17 1.1 tls * without specific prior written permission. 18 1.1 tls * 19 1.1 tls * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 tls * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 tls * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 tls * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 tls * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 tls * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 tls * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 tls * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 tls * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 tls * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 tls * SUCH DAMAGE. 30 1.1 tls */ 31 1.1 tls 32 1.4 lukem #include <sys/cdefs.h> 33 1.1 tls #ifndef lint 34 1.12 lukem __COPYRIGHT("@(#) Copyright (c) 1993\ 35 1.12 lukem The Regents of the University of California. All rights reserved."); 36 1.1 tls #endif /* not lint */ 37 1.1 tls 38 1.1 tls #ifndef lint 39 1.4 lukem #if 0 40 1.1 tls static char sccsid[] = "@(#)rs.c 8.1 (Berkeley) 6/6/93"; 41 1.4 lukem #else 42 1.17 mrg __RCSID("$NetBSD: rs.c,v 1.17 2023/08/10 20:36:29 mrg Exp $"); 43 1.4 lukem #endif 44 1.1 tls #endif /* not lint */ 45 1.1 tls 46 1.1 tls /* 47 1.1 tls * rs - reshape a data array 48 1.1 tls * Author: John Kunze, Office of Comp. Affairs, UCB 49 1.1 tls * BEWARE: lots of unfinished edges 50 1.1 tls */ 51 1.1 tls 52 1.1 tls #include <ctype.h> 53 1.4 lukem #include <err.h> 54 1.1 tls #include <stdio.h> 55 1.1 tls #include <stdlib.h> 56 1.2 cgd #include <string.h> 57 1.6 is #include <stdarg.h> 58 1.1 tls 59 1.15 joerg static long flags; 60 1.1 tls #define TRANSPOSE 000001 61 1.1 tls #define MTRANSPOSE 000002 62 1.1 tls #define ONEPERLINE 000004 63 1.1 tls #define ONEISEPONLY 000010 64 1.1 tls #define ONEOSEPONLY 000020 65 1.1 tls #define NOTRIMENDCOL 000040 66 1.1 tls #define SQUEEZE 000100 67 1.1 tls #define SHAPEONLY 000200 68 1.1 tls #define DETAILSHAPE 000400 69 1.1 tls #define RIGHTADJUST 001000 70 1.1 tls #define NULLPAD 002000 71 1.1 tls #define RECYCLE 004000 72 1.1 tls #define SKIPPRINT 010000 73 1.1 tls #define ICOLBOUNDS 020000 74 1.1 tls #define OCOLBOUNDS 040000 75 1.1 tls #define ONEPERCHAR 0100000 76 1.1 tls #define NOARGS 0200000 77 1.1 tls 78 1.15 joerg static short *colwidths; 79 1.15 joerg static short *cord; 80 1.15 joerg static short *icbd; 81 1.15 joerg static short *ocbd; 82 1.15 joerg static int nelem; 83 1.15 joerg static char **elem; 84 1.15 joerg static char **endelem; 85 1.15 joerg static char *curline; 86 1.15 joerg static int allocsize = BUFSIZ; 87 1.15 joerg static int curlen; 88 1.15 joerg static int irows, icols; 89 1.15 joerg static int orows, ocols; 90 1.15 joerg static int maxlen; 91 1.15 joerg static int skip; 92 1.15 joerg static int propgutter; 93 1.15 joerg static char isep = ' ', osep = ' '; 94 1.15 joerg static int owidth = 80, gutter = 2; 95 1.15 joerg 96 1.15 joerg static void usage(const char *, ...) __dead __printflike(1, 2); 97 1.15 joerg static void getargs(int, char *[]); 98 1.15 joerg static void getfile(void); 99 1.15 joerg static int get_line(void); 100 1.15 joerg static char *getlist(short **, char *); 101 1.15 joerg static char *getnum(int *, char *, int); 102 1.15 joerg static char **getptrs(char **); 103 1.15 joerg static void prepfile(void); 104 1.15 joerg static void prints(char *, int); 105 1.15 joerg static void putfile(void); 106 1.1 tls 107 1.3 pk #define INCR(ep) do { \ 108 1.3 pk if (++ep >= endelem) \ 109 1.3 pk ep = getptrs(ep); \ 110 1.3 pk } while(0) 111 1.3 pk 112 1.1 tls int 113 1.15 joerg main(int argc, char *argv[]) 114 1.1 tls { 115 1.1 tls getargs(argc, argv); 116 1.1 tls getfile(); 117 1.1 tls if (flags & SHAPEONLY) { 118 1.1 tls printf("%d %d\n", irows, icols); 119 1.1 tls exit(0); 120 1.1 tls } 121 1.1 tls prepfile(); 122 1.1 tls putfile(); 123 1.1 tls exit(0); 124 1.1 tls } 125 1.1 tls 126 1.15 joerg static void 127 1.15 joerg getfile(void) 128 1.1 tls { 129 1.13 lukem char empty[1] = { '\0' }; 130 1.4 lukem char *p; 131 1.4 lukem char *endp; 132 1.4 lukem char **ep = 0; 133 1.1 tls int multisep = (flags & ONEISEPONLY ? 0 : 1); 134 1.1 tls int nullpad = flags & NULLPAD; 135 1.1 tls char **padto; 136 1.1 tls 137 1.1 tls while (skip--) { 138 1.14 roy get_line(); 139 1.1 tls if (flags & SKIPPRINT) 140 1.1 tls puts(curline); 141 1.1 tls } 142 1.14 roy get_line(); 143 1.1 tls if (flags & NOARGS && curlen < owidth) 144 1.1 tls flags |= ONEPERLINE; 145 1.1 tls if (flags & ONEPERLINE) 146 1.1 tls icols = 1; 147 1.1 tls else /* count cols on first line */ 148 1.1 tls for (p = curline, endp = curline + curlen; p < endp; p++) { 149 1.1 tls if (*p == isep && multisep) 150 1.1 tls continue; 151 1.1 tls icols++; 152 1.1 tls while (*p && *p != isep) 153 1.1 tls p++; 154 1.1 tls } 155 1.1 tls ep = getptrs(elem); 156 1.1 tls p = curline; 157 1.1 tls do { 158 1.1 tls if (flags & ONEPERLINE) { 159 1.3 pk *ep = curline; 160 1.3 pk INCR(ep); /* prepare for next entry */ 161 1.1 tls if (maxlen < curlen) 162 1.1 tls maxlen = curlen; 163 1.1 tls irows++; 164 1.1 tls continue; 165 1.1 tls } 166 1.1 tls for (p = curline, endp = curline + curlen; p < endp; p++) { 167 1.1 tls if (*p == isep && multisep) 168 1.1 tls continue; /* eat up column separators */ 169 1.1 tls if (*p == isep) /* must be an empty column */ 170 1.13 lukem *ep = empty; 171 1.1 tls else /* store column entry */ 172 1.1 tls *ep = p; 173 1.1 tls while (p < endp && *p != isep) 174 1.1 tls p++; /* find end of entry */ 175 1.1 tls *p = '\0'; /* mark end of entry */ 176 1.1 tls if (maxlen < p - *ep) /* update maxlen */ 177 1.1 tls maxlen = p - *ep; 178 1.3 pk INCR(ep); /* prepare for next entry */ 179 1.1 tls } 180 1.1 tls irows++; /* update row count */ 181 1.1 tls if (nullpad) { /* pad missing entries */ 182 1.1 tls padto = elem + irows * icols; 183 1.3 pk while (ep < padto) { 184 1.13 lukem *ep = empty; 185 1.3 pk INCR(ep); 186 1.3 pk } 187 1.1 tls } 188 1.14 roy } while (get_line() != EOF); 189 1.1 tls *ep = 0; /* mark end of pointers */ 190 1.1 tls nelem = ep - elem; 191 1.1 tls } 192 1.1 tls 193 1.15 joerg static void 194 1.15 joerg putfile(void) 195 1.1 tls { 196 1.4 lukem char **ep; 197 1.4 lukem int i, j, n; 198 1.1 tls 199 1.1 tls ep = elem; 200 1.3 pk if (flags & TRANSPOSE) { 201 1.1 tls for (i = 0; i < orows; i++) { 202 1.1 tls for (j = i; j < nelem; j += orows) 203 1.1 tls prints(ep[j], (j - i) / orows); 204 1.1 tls putchar('\n'); 205 1.1 tls } 206 1.3 pk } else { 207 1.3 pk for (n = 0, i = 0; i < orows && n < nelem; i++) { 208 1.3 pk for (j = 0; j < ocols; j++) { 209 1.3 pk if (n++ >= nelem) 210 1.3 pk break; 211 1.1 tls prints(*ep++, j); 212 1.3 pk } 213 1.1 tls putchar('\n'); 214 1.1 tls } 215 1.3 pk } 216 1.1 tls } 217 1.1 tls 218 1.15 joerg static void 219 1.15 joerg prints(char *s, int col) 220 1.1 tls { 221 1.4 lukem int n; 222 1.4 lukem char *p = s; 223 1.1 tls 224 1.1 tls while (*p) 225 1.1 tls p++; 226 1.1 tls n = (flags & ONEOSEPONLY ? 1 : colwidths[col] - (p - s)); 227 1.1 tls if (flags & RIGHTADJUST) 228 1.1 tls while (n-- > 0) 229 1.1 tls putchar(osep); 230 1.1 tls for (p = s; *p; p++) 231 1.1 tls putchar(*p); 232 1.1 tls while (n-- > 0) 233 1.1 tls putchar(osep); 234 1.1 tls } 235 1.1 tls 236 1.15 joerg static void 237 1.13 lukem usage(const char *msg, ...) 238 1.1 tls { 239 1.6 is va_list ap; 240 1.6 is 241 1.6 is va_start(ap, msg); 242 1.6 is vwarnx(msg, ap); 243 1.6 is va_end(ap); 244 1.1 tls fprintf(stderr, 245 1.10 jmmv "usage: rs [ -[csCS][x][kKgGw][N]tTeEnyjhHm ] [ rows [ cols ] ]\n"); 246 1.1 tls exit(1); 247 1.1 tls } 248 1.1 tls 249 1.15 joerg static void 250 1.15 joerg prepfile(void) 251 1.1 tls { 252 1.4 lukem char **ep; 253 1.4 lukem int i; 254 1.4 lukem int j; 255 1.1 tls char **lp; 256 1.1 tls int colw; 257 1.1 tls int max = 0; 258 1.1 tls int n; 259 1.1 tls 260 1.4 lukem ep = NULL; 261 1.1 tls if (!nelem) 262 1.1 tls exit(0); 263 1.1 tls gutter += maxlen * propgutter / 100.0; 264 1.1 tls colw = maxlen + gutter; 265 1.1 tls if (flags & MTRANSPOSE) { 266 1.1 tls orows = icols; 267 1.1 tls ocols = irows; 268 1.1 tls } 269 1.1 tls else if (orows == 0 && ocols == 0) { /* decide rows and cols */ 270 1.1 tls ocols = owidth / colw; 271 1.3 pk if (ocols == 0) { 272 1.8 itojun warnx("Display width %d is less than column width %d", owidth, colw); 273 1.3 pk ocols = 1; 274 1.3 pk } 275 1.1 tls if (ocols > nelem) 276 1.1 tls ocols = nelem; 277 1.1 tls orows = nelem / ocols + (nelem % ocols ? 1 : 0); 278 1.1 tls } 279 1.1 tls else if (orows == 0) /* decide on rows */ 280 1.1 tls orows = nelem / ocols + (nelem % ocols ? 1 : 0); 281 1.1 tls else if (ocols == 0) /* decide on cols */ 282 1.1 tls ocols = nelem / orows + (nelem % orows ? 1 : 0); 283 1.1 tls lp = elem + orows * ocols; 284 1.1 tls while (lp > endelem) { 285 1.1 tls getptrs(elem + nelem); 286 1.1 tls lp = elem + orows * ocols; 287 1.1 tls } 288 1.1 tls if (flags & RECYCLE) { 289 1.1 tls for (ep = elem + nelem; ep < lp; ep++) 290 1.1 tls *ep = *(ep - nelem); 291 1.1 tls nelem = lp - elem; 292 1.1 tls } 293 1.1 tls if (!(colwidths = (short *) malloc(ocols * sizeof(short)))) 294 1.3 pk errx(1, "malloc: No gutter space"); 295 1.1 tls if (flags & SQUEEZE) { 296 1.1 tls if (flags & TRANSPOSE) 297 1.1 tls for (ep = elem, i = 0; i < ocols; i++) { 298 1.1 tls for (j = 0; j < orows; j++) 299 1.1 tls if ((n = strlen(*ep++)) > max) 300 1.1 tls max = n; 301 1.1 tls colwidths[i] = max + gutter; 302 1.1 tls } 303 1.1 tls else 304 1.7 tron for (ep = elem, i = 0; i < ocols; i++) { 305 1.1 tls for (j = i; j < nelem; j += ocols) 306 1.1 tls if ((n = strlen(ep[j])) > max) 307 1.1 tls max = n; 308 1.1 tls colwidths[i] = max + gutter; 309 1.1 tls } 310 1.1 tls } 311 1.1 tls /* for (i = 0; i < orows; i++) { 312 1.1 tls for (j = i; j < nelem; j += orows) 313 1.1 tls prints(ep[j], (j - i) / orows); 314 1.1 tls putchar('\n'); 315 1.1 tls } 316 1.1 tls else 317 1.1 tls for (i = 0; i < orows; i++) { 318 1.1 tls for (j = 0; j < ocols; j++) 319 1.1 tls prints(*ep++, j); 320 1.1 tls putchar('\n'); 321 1.1 tls }*/ 322 1.1 tls else 323 1.1 tls for (i = 0; i < ocols; i++) 324 1.1 tls colwidths[i] = colw; 325 1.1 tls if (!(flags & NOTRIMENDCOL)) { 326 1.1 tls if (flags & RIGHTADJUST) 327 1.1 tls colwidths[0] -= gutter; 328 1.1 tls else 329 1.1 tls colwidths[ocols - 1] = 0; 330 1.1 tls } 331 1.1 tls n = orows * ocols; 332 1.1 tls if (n > nelem && (flags & RECYCLE)) 333 1.1 tls nelem = n; 334 1.1 tls /*for (i = 0; i < ocols; i++) 335 1.1 tls fprintf(stderr, "%d ",colwidths[i]); 336 1.1 tls fprintf(stderr, "is colwidths, nelem %d\n", nelem);*/ 337 1.1 tls } 338 1.1 tls 339 1.1 tls #define BSIZE 2048 340 1.1 tls char ibuf[BSIZE]; /* two screenfuls should do */ 341 1.1 tls 342 1.15 joerg static int 343 1.15 joerg get_line(void) /* get line; maintain curline, curlen; manage storage */ 344 1.1 tls { 345 1.1 tls static int putlength; 346 1.1 tls static char *endblock = ibuf + BSIZE; 347 1.4 lukem char *p; 348 1.4 lukem int c, i; 349 1.1 tls 350 1.1 tls if (!irows) { 351 1.1 tls curline = ibuf; 352 1.1 tls putlength = flags & DETAILSHAPE; 353 1.1 tls } 354 1.1 tls else if (skip <= 0) { /* don't waste storage */ 355 1.1 tls curline += curlen + 1; 356 1.1 tls if (putlength) /* print length, recycle storage */ 357 1.1 tls printf(" %d line %d\n", curlen, irows); 358 1.1 tls } 359 1.1 tls if (!putlength && endblock - curline < BUFSIZ) { /* need storage */ 360 1.1 tls /*ww = endblock-curline; tt += ww;*/ 361 1.1 tls /*printf("#wasted %d total %d\n",ww,tt);*/ 362 1.1 tls if (!(curline = (char *) malloc(BSIZE))) 363 1.3 pk errx(1, "File too large"); 364 1.1 tls endblock = curline + BSIZE; 365 1.1 tls /*printf("#endb %d curline %d\n",endblock,curline);*/ 366 1.1 tls } 367 1.1 tls for (p = curline, i = 1; i < BUFSIZ; *p++ = c, i++) 368 1.1 tls if ((c = getchar()) == EOF || c == '\n') 369 1.1 tls break; 370 1.1 tls *p = '\0'; 371 1.1 tls curlen = i - 1; 372 1.1 tls return(c); 373 1.1 tls } 374 1.1 tls 375 1.15 joerg static char ** 376 1.15 joerg getptrs(char **sp) 377 1.1 tls { 378 1.4 lukem char **p; 379 1.17 mrg ptrdiff_t off; 380 1.1 tls 381 1.3 pk allocsize += allocsize; 382 1.17 mrg off = sp - elem; 383 1.3 pk p = (char **)realloc(elem, allocsize * sizeof(char *)); 384 1.3 pk if (p == (char **)0) 385 1.3 pk err(1, "no memory"); 386 1.3 pk 387 1.17 mrg sp = p + off; 388 1.3 pk endelem = (elem = p) + allocsize; 389 1.3 pk return(sp); 390 1.1 tls } 391 1.1 tls 392 1.15 joerg static void 393 1.15 joerg getargs(int ac, char *av[]) 394 1.1 tls { 395 1.4 lukem char *p; 396 1.1 tls 397 1.1 tls if (ac == 1) { 398 1.1 tls flags |= NOARGS | TRANSPOSE; 399 1.1 tls } 400 1.1 tls while (--ac && **++av == '-') 401 1.1 tls for (p = *av+1; *p; p++) 402 1.1 tls switch (*p) { 403 1.1 tls case 'T': 404 1.1 tls flags |= MTRANSPOSE; 405 1.16 mrg /* FALLTHROUGH */ 406 1.1 tls case 't': 407 1.1 tls flags |= TRANSPOSE; 408 1.1 tls break; 409 1.1 tls case 'c': /* input col. separator */ 410 1.1 tls flags |= ONEISEPONLY; 411 1.16 mrg /* FALLTHROUGH */ 412 1.1 tls case 's': /* one or more allowed */ 413 1.1 tls if (p[1]) 414 1.1 tls isep = *++p; 415 1.1 tls else 416 1.1 tls isep = '\t'; /* default is ^I */ 417 1.1 tls break; 418 1.1 tls case 'C': 419 1.1 tls flags |= ONEOSEPONLY; 420 1.16 mrg /* FALLTHROUGH */ 421 1.1 tls case 'S': 422 1.1 tls if (p[1]) 423 1.1 tls osep = *++p; 424 1.1 tls else 425 1.1 tls osep = '\t'; /* default is ^I */ 426 1.1 tls break; 427 1.1 tls case 'w': /* window width, default 80 */ 428 1.1 tls p = getnum(&owidth, p, 0); 429 1.1 tls if (owidth <= 0) 430 1.6 is usage("Width must be a positive integer"); 431 1.1 tls break; 432 1.1 tls case 'K': /* skip N lines */ 433 1.1 tls flags |= SKIPPRINT; 434 1.16 mrg /* FALLTHROUGH */ 435 1.1 tls case 'k': /* skip, do not print */ 436 1.1 tls p = getnum(&skip, p, 0); 437 1.1 tls if (!skip) 438 1.1 tls skip = 1; 439 1.1 tls break; 440 1.1 tls case 'm': 441 1.1 tls flags |= NOTRIMENDCOL; 442 1.1 tls break; 443 1.1 tls case 'g': /* gutter space */ 444 1.1 tls p = getnum(&gutter, p, 0); 445 1.1 tls break; 446 1.1 tls case 'G': 447 1.1 tls p = getnum(&propgutter, p, 0); 448 1.1 tls break; 449 1.1 tls case 'e': /* each line is an entry */ 450 1.1 tls flags |= ONEPERLINE; 451 1.1 tls break; 452 1.1 tls case 'E': 453 1.1 tls flags |= ONEPERCHAR; 454 1.1 tls break; 455 1.1 tls case 'j': /* right adjust */ 456 1.1 tls flags |= RIGHTADJUST; 457 1.1 tls break; 458 1.1 tls case 'n': /* null padding for missing values */ 459 1.1 tls flags |= NULLPAD; 460 1.1 tls break; 461 1.1 tls case 'y': 462 1.1 tls flags |= RECYCLE; 463 1.1 tls break; 464 1.1 tls case 'H': /* print shape only */ 465 1.1 tls flags |= DETAILSHAPE; 466 1.16 mrg /* FALLTHROUGH */ 467 1.1 tls case 'h': 468 1.1 tls flags |= SHAPEONLY; 469 1.1 tls break; 470 1.1 tls case 'z': /* squeeze col width */ 471 1.1 tls flags |= SQUEEZE; 472 1.1 tls break; 473 1.1 tls /*case 'p': 474 1.1 tls ipagespace = atoi(++p); (default is 1) 475 1.1 tls break;*/ 476 1.1 tls case 'o': /* col order */ 477 1.1 tls p = getlist(&cord, p); 478 1.1 tls break; 479 1.1 tls case 'b': 480 1.1 tls flags |= ICOLBOUNDS; 481 1.1 tls p = getlist(&icbd, p); 482 1.1 tls break; 483 1.1 tls case 'B': 484 1.1 tls flags |= OCOLBOUNDS; 485 1.1 tls p = getlist(&ocbd, p); 486 1.1 tls break; 487 1.1 tls default: 488 1.3 pk usage("Bad flag: %.1s", p); 489 1.1 tls } 490 1.1 tls /*if (!osep) 491 1.1 tls osep = isep;*/ 492 1.1 tls switch (ac) { 493 1.1 tls /*case 3: 494 1.1 tls opages = atoi(av[2]);*/ 495 1.16 mrg /* FALLTHROUGH */ 496 1.1 tls case 2: 497 1.1 tls ocols = atoi(av[1]); 498 1.16 mrg /* FALLTHROUGH */ 499 1.1 tls case 1: 500 1.1 tls orows = atoi(av[0]); 501 1.16 mrg /* FALLTHROUGH */ 502 1.1 tls case 0: 503 1.1 tls break; 504 1.1 tls default: 505 1.6 is usage("Too many arguments."); 506 1.1 tls } 507 1.1 tls } 508 1.1 tls 509 1.15 joerg static char * 510 1.15 joerg getlist(short **list, char *p) 511 1.1 tls { 512 1.4 lukem int count = 1; 513 1.4 lukem char *t; 514 1.1 tls 515 1.1 tls for (t = p + 1; *t; t++) { 516 1.11 dsl if (!isdigit((unsigned char)*t)) 517 1.3 pk usage("Option %.1s requires a list of unsigned numbers separated by commas", t); 518 1.1 tls count++; 519 1.11 dsl while (*t && isdigit((unsigned char)*t)) 520 1.1 tls t++; 521 1.1 tls if (*t != ',') 522 1.1 tls break; 523 1.1 tls } 524 1.1 tls if (!(*list = (short *) malloc(count * sizeof(short)))) 525 1.3 pk errx(1, "No list space"); 526 1.1 tls count = 0; 527 1.1 tls for (t = p + 1; *t; t++) { 528 1.1 tls (*list)[count++] = atoi(t); 529 1.1 tls printf("++ %d ", (*list)[count-1]); 530 1.1 tls fflush(stdout); 531 1.11 dsl while (*t && isdigit((unsigned char)*t)) 532 1.1 tls t++; 533 1.1 tls if (*t != ',') 534 1.1 tls break; 535 1.1 tls } 536 1.1 tls (*list)[count] = 0; 537 1.1 tls return(t - 1); 538 1.1 tls } 539 1.1 tls 540 1.15 joerg static char * 541 1.15 joerg getnum(int *num, char *p, int strict) /* num = number p points to; if (strict) complain */ 542 1.15 joerg /* returns pointer to end of num */ 543 1.1 tls { 544 1.4 lukem char *t = p; 545 1.1 tls 546 1.11 dsl if (!isdigit((unsigned char)*++t)) { 547 1.1 tls if (strict || *t == '-' || *t == '+') 548 1.3 pk usage("Option %.1s requires an unsigned integer", p); 549 1.1 tls *num = 0; 550 1.1 tls return(p); 551 1.1 tls } 552 1.1 tls *num = atoi(t); 553 1.1 tls while (*++t) 554 1.11 dsl if (!isdigit((unsigned char)*t)) 555 1.1 tls break; 556 1.1 tls return(--t); 557 1.1 tls } 558