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