|
|
1.1 ! root 1: /* Copyright (c) 1983 Regents of the University of California */ ! 2: ! 3: #ifndef lint ! 4: static char sccsid[] = "@(#)rs.c 4.3 (Berkeley) 4/5/86"; ! 5: #endif not lint ! 6: ! 7: /* ! 8: * rs - reshape a data array ! 9: * Author: John Kunze, Office of Comp. Affairs, UCB ! 10: * BEWARE: lots of unfinished edges ! 11: */ ! 12: ! 13: #include <stdio.h> ! 14: #include <ctype.h> ! 15: ! 16: long flags; ! 17: #define TRANSPOSE 000001 ! 18: #define MTRANSPOSE 000002 ! 19: #define ONEPERLINE 000004 ! 20: #define ONEISEPONLY 000010 ! 21: #define ONEOSEPONLY 000020 ! 22: #define NOTRIMENDCOL 000040 ! 23: #define SQUEEZE 000100 ! 24: #define SHAPEONLY 000200 ! 25: #define DETAILSHAPE 000400 ! 26: #define RIGHTADJUST 001000 ! 27: #define NULLPAD 002000 ! 28: #define RECYCLE 004000 ! 29: #define SKIPPRINT 010000 ! 30: #define ICOLBOUNDS 020000 ! 31: #define OCOLBOUNDS 040000 ! 32: #define ONEPERCHAR 0100000 ! 33: #define NOARGS 0200000 ! 34: ! 35: char buf[BUFSIZ]; ! 36: short *colwidths; ! 37: short *cord; ! 38: short *icbd; ! 39: short *ocbd; ! 40: int nelem; ! 41: char **elem; ! 42: char **endelem; ! 43: char *curline; ! 44: int allocsize = BUFSIZ; ! 45: int curlen; ! 46: int irows, icols; ! 47: int orows, ocols; ! 48: int maxlen; ! 49: int skip; ! 50: int propgutter; ! 51: char isep = ' ', osep = ' '; ! 52: int owidth = 80, gutter = 2; ! 53: ! 54: char **getptrs(); ! 55: ! 56: main(argc, argv) ! 57: int argc; ! 58: char **argv; ! 59: { ! 60: setbuf(stdout, buf); ! 61: getargs(argc, argv); ! 62: getfile(); ! 63: if (flags & SHAPEONLY) { ! 64: printf("%d %d\n", irows, icols); ! 65: exit(0); ! 66: } ! 67: prepfile(); ! 68: /*fprintf(stderr, "#irows %d icols %d orows %d ocols %d\n",irows,icols,orows,ocols);*/ ! 69: putfile(); ! 70: exit(0); ! 71: } ! 72: ! 73: getfile() ! 74: { ! 75: register char *p; ! 76: register char *endp; ! 77: register char **ep = 0; ! 78: int multisep = (flags & ONEISEPONLY ? 0 : 1); ! 79: int nullpad = flags & NULLPAD; ! 80: char **padto; ! 81: ! 82: while (skip--) { ! 83: getline(); ! 84: if (flags & SKIPPRINT) ! 85: puts(curline); ! 86: } ! 87: getline(); ! 88: if (flags & NOARGS && curlen < owidth) ! 89: flags |= ONEPERLINE; ! 90: if (flags & ONEPERLINE) ! 91: icols = 1; ! 92: else /* count cols on first line */ ! 93: for (p = curline, endp = curline + curlen; p < endp; p++) { ! 94: if (*p == isep && multisep) ! 95: continue; ! 96: icols++; ! 97: while (*p && *p != isep) ! 98: p++; ! 99: } ! 100: ep = getptrs(elem); ! 101: p = curline; ! 102: do { ! 103: if (flags & ONEPERLINE) { ! 104: *ep++ = curline; ! 105: if (maxlen < curlen) ! 106: maxlen = curlen; ! 107: irows++; ! 108: continue; ! 109: } ! 110: for (p = curline, endp = curline + curlen; p < endp; p++) { ! 111: if (*p == isep && multisep) ! 112: continue; /* eat up column separators */ ! 113: if (*p == isep) /* must be an empty column */ ! 114: *ep = ""; ! 115: else /* store column entry */ ! 116: *ep = p; ! 117: while (p < endp && *p != isep) ! 118: p++; /* find end of entry */ ! 119: *p = '\0'; /* mark end of entry */ ! 120: if (maxlen < p - *ep) /* update maxlen */ ! 121: maxlen = p - *ep; ! 122: ep++; /* prepare for next entry */ ! 123: } ! 124: irows++; /* update row count */ ! 125: if (nullpad) { /* pad missing entries */ ! 126: padto = elem + irows * icols; ! 127: while (ep < padto) ! 128: *ep++ = ""; ! 129: } ! 130: if (ep > endelem) /* if low on pointers */ ! 131: ep = getptrs(ep); /* get some more */ ! 132: } while (getline() != EOF); ! 133: *ep = 0; /* mark end of pointers */ ! 134: nelem = ep - elem; ! 135: } ! 136: ! 137: putfile() ! 138: { ! 139: register char **ep; ! 140: register int i; ! 141: register int j; ! 142: ! 143: ep = elem; ! 144: if (flags & TRANSPOSE) ! 145: for (i = 0; i < orows; i++) { ! 146: for (j = i; j < nelem; j += orows) ! 147: prints(ep[j], (j - i) / orows); ! 148: putchar('\n'); ! 149: } ! 150: else ! 151: for (i = 0; i < orows; i++) { ! 152: for (j = 0; j < ocols; j++) ! 153: prints(*ep++, j); ! 154: putchar('\n'); ! 155: } ! 156: } ! 157: ! 158: prints(s, col) ! 159: char *s; ! 160: int col; ! 161: { ! 162: register char *p = s; ! 163: register int n; ! 164: ! 165: while (*p) ! 166: p++; ! 167: n = (flags & ONEOSEPONLY ? 1 : colwidths[col] - (p - s)); ! 168: if (flags & RIGHTADJUST) ! 169: while (n-- > 0) ! 170: putchar(osep); ! 171: for (p = s; *p; p++) ! 172: putchar(*p); ! 173: while (n-- > 0) ! 174: putchar(osep); ! 175: } ! 176: ! 177: error(msg, s) ! 178: char *msg; ! 179: char *s; ! 180: { ! 181: fprintf(stderr, "rs: "); ! 182: fprintf(stderr, msg, s); ! 183: fprintf(stderr, "\nUsage: rs [ -[csCS][x][kKgGw][N]tTeEnyjhHm ] [ rows [ cols ] ]\n"); ! 184: exit(1); ! 185: } ! 186: ! 187: prepfile() ! 188: { ! 189: register char **ep; ! 190: register int i; ! 191: register int j; ! 192: char **lp; ! 193: int colw; ! 194: int max = 0; ! 195: int n; ! 196: ! 197: if (!nelem) ! 198: exit(0); ! 199: gutter += maxlen * propgutter / 100.0; ! 200: colw = maxlen + gutter; ! 201: if (flags & MTRANSPOSE) { ! 202: orows = icols; ! 203: ocols = irows; ! 204: } ! 205: else if (orows == 0 && ocols == 0) { /* decide rows and cols */ ! 206: ocols = owidth / colw; ! 207: if (ocols == 0) ! 208: fprintf(stderr, "Display width %d is less than column width %d\n", owidth, colw); ! 209: if (ocols > nelem) ! 210: ocols = nelem; ! 211: orows = nelem / ocols + (nelem % ocols ? 1 : 0); ! 212: } ! 213: else if (orows == 0) /* decide on rows */ ! 214: orows = nelem / ocols + (nelem % ocols ? 1 : 0); ! 215: else if (ocols == 0) /* decide on cols */ ! 216: ocols = nelem / orows + (nelem % orows ? 1 : 0); ! 217: lp = elem + orows * ocols; ! 218: while (lp > endelem) { ! 219: getptrs(elem + nelem); ! 220: lp = elem + orows * ocols; ! 221: } ! 222: if (flags & RECYCLE) { ! 223: for (ep = elem + nelem; ep < lp; ep++) ! 224: *ep = *(ep - nelem); ! 225: nelem = lp - elem; ! 226: } ! 227: if (!(colwidths = (short *) malloc(ocols * sizeof(short)))) ! 228: error("malloc: No gutter space", ""); ! 229: if (flags & SQUEEZE) { ! 230: if (flags & TRANSPOSE) ! 231: for (ep = elem, i = 0; i < ocols; i++) { ! 232: for (j = 0; j < orows; j++) ! 233: if ((n = strlen(*ep++)) > max) ! 234: max = n; ! 235: colwidths[i] = max + gutter; ! 236: } ! 237: else ! 238: for (i = 0; i < ocols; i++) { ! 239: for (j = i; j < nelem; j += ocols) ! 240: if ((n = strlen(ep[j])) > max) ! 241: max = n; ! 242: colwidths[i] = max + gutter; ! 243: } ! 244: } ! 245: /* for (i = 0; i < orows; i++) { ! 246: for (j = i; j < nelem; j += orows) ! 247: prints(ep[j], (j - i) / orows); ! 248: putchar('\n'); ! 249: } ! 250: else ! 251: for (i = 0; i < orows; i++) { ! 252: for (j = 0; j < ocols; j++) ! 253: prints(*ep++, j); ! 254: putchar('\n'); ! 255: }*/ ! 256: else ! 257: for (i = 0; i < ocols; i++) ! 258: colwidths[i] = colw; ! 259: if (!(flags & NOTRIMENDCOL)) { ! 260: if (flags & RIGHTADJUST) ! 261: colwidths[0] -= gutter; ! 262: else ! 263: colwidths[ocols - 1] = 0; ! 264: } ! 265: n = orows * ocols; ! 266: if (n > nelem && (flags & RECYCLE)) ! 267: nelem = n; ! 268: /*for (i = 0; i < ocols; i++) ! 269: fprintf(stderr, "%d ",colwidths[i]); ! 270: fprintf(stderr, "is colwidths, nelem %d\n", nelem);*/ ! 271: } ! 272: ! 273: #define BSIZE 2048 ! 274: char ibuf[BSIZE]; /* two screenfuls should do */ ! 275: ! 276: getline() /* get line; maintain curline, curlen; manage storage */ ! 277: { ! 278: register char *p; ! 279: register int c; ! 280: register int i; ! 281: static int putlength; ! 282: static char *endblock = ibuf + BSIZE; ! 283: ! 284: if (!irows) { ! 285: curline = ibuf; ! 286: putlength = flags & DETAILSHAPE; ! 287: } ! 288: else if (skip <= 0) { /* don't waste storage */ ! 289: curline += curlen + 1; ! 290: if (putlength) /* print length, recycle storage */ ! 291: printf(" %d line %d\n", curlen, irows); ! 292: } ! 293: if (!putlength && endblock - curline < BUFSIZ) { /* need storage */ ! 294: /*ww = endblock-curline; tt += ww;*/ ! 295: /*printf("#wasted %d total %d\n",ww,tt);*/ ! 296: if (!(curline = (char *) malloc(BSIZE))) ! 297: error("File too large", ""); ! 298: endblock = curline + BSIZE; ! 299: /*printf("#endb %d curline %d\n",endblock,curline);*/ ! 300: } ! 301: for (p = curline, i = 1; i < BUFSIZ; *p++ = c, i++) ! 302: if ((c = getchar()) == EOF || c == '\n') ! 303: break; ! 304: *p = '\0'; ! 305: curlen = i - 1; ! 306: return(c); ! 307: } ! 308: ! 309: char ** ! 310: getptrs(sp) ! 311: char **sp; ! 312: { ! 313: register char **p; ! 314: register char **ep; ! 315: ! 316: for (;;) { ! 317: allocsize += allocsize; ! 318: if (!(p = (char **) malloc(allocsize * sizeof(char *)))) { ! 319: perror("rs"); ! 320: exit(1); ! 321: } ! 322: if ((endelem = p + allocsize - icols) <= p) { ! 323: free(p); ! 324: continue; ! 325: } ! 326: if (elem != 0) ! 327: free(elem); ! 328: ep = elem; ! 329: elem = p; ! 330: while (ep < sp) ! 331: *p++ = *ep++; ! 332: return(p); ! 333: } ! 334: } ! 335: ! 336: getargs(ac, av) ! 337: int ac; ! 338: char **av; ! 339: { ! 340: register char *p; ! 341: char *getnum(), *getlist(); ! 342: ! 343: if (ac == 1) { ! 344: flags |= NOARGS | TRANSPOSE; ! 345: } ! 346: while (--ac && **++av == '-') ! 347: for (p = *av+1; *p; p++) ! 348: switch (*p) { ! 349: case 'T': ! 350: flags |= MTRANSPOSE; ! 351: case 't': ! 352: flags |= TRANSPOSE; ! 353: break; ! 354: case 'c': /* input col. separator */ ! 355: flags |= ONEISEPONLY; ! 356: case 's': /* one or more allowed */ ! 357: if (p[1]) ! 358: isep = *++p; ! 359: else ! 360: isep = '\t'; /* default is ^I */ ! 361: break; ! 362: case 'C': ! 363: flags |= ONEOSEPONLY; ! 364: case 'S': ! 365: if (p[1]) ! 366: osep = *++p; ! 367: else ! 368: osep = '\t'; /* default is ^I */ ! 369: break; ! 370: case 'w': /* window width, default 80 */ ! 371: p = getnum(&owidth, p, 0); ! 372: if (owidth <= 0) ! 373: error("Width must be a positive integer", ""); ! 374: break; ! 375: case 'K': /* skip N lines */ ! 376: flags |= SKIPPRINT; ! 377: case 'k': /* skip, do not print */ ! 378: p = getnum(&skip, p, 0); ! 379: if (!skip) ! 380: skip = 1; ! 381: break; ! 382: case 'm': ! 383: flags |= NOTRIMENDCOL; ! 384: break; ! 385: case 'g': /* gutter space */ ! 386: p = getnum(&gutter, p, 0); ! 387: break; ! 388: case 'G': ! 389: p = getnum(&propgutter, p, 0); ! 390: break; ! 391: case 'e': /* each line is an entry */ ! 392: flags |= ONEPERLINE; ! 393: break; ! 394: case 'E': ! 395: flags |= ONEPERCHAR; ! 396: break; ! 397: case 'j': /* right adjust */ ! 398: flags |= RIGHTADJUST; ! 399: break; ! 400: case 'n': /* null padding for missing values */ ! 401: flags |= NULLPAD; ! 402: break; ! 403: case 'y': ! 404: flags |= RECYCLE; ! 405: break; ! 406: case 'H': /* print shape only */ ! 407: flags |= DETAILSHAPE; ! 408: case 'h': ! 409: flags |= SHAPEONLY; ! 410: break; ! 411: case 'z': /* squeeze col width */ ! 412: flags |= SQUEEZE; ! 413: break; ! 414: /*case 'p': ! 415: ipagespace = atoi(++p); (default is 1) ! 416: break;*/ ! 417: case 'o': /* col order */ ! 418: p = getlist(&cord, p); ! 419: break; ! 420: case 'b': ! 421: flags |= ICOLBOUNDS; ! 422: p = getlist(&icbd, p); ! 423: break; ! 424: case 'B': ! 425: flags |= OCOLBOUNDS; ! 426: p = getlist(&ocbd, p); ! 427: break; ! 428: default: ! 429: error("Bad flag: %.1s", p); ! 430: } ! 431: /*if (!osep) ! 432: osep = isep;*/ ! 433: switch (ac) { ! 434: /*case 3: ! 435: opages = atoi(av[2]);*/ ! 436: case 2: ! 437: ocols = atoi(av[1]); ! 438: case 1: ! 439: orows = atoi(av[0]); ! 440: case 0: ! 441: break; ! 442: default: ! 443: error("Too many arguments. What do you mean by `%s'?", av[3]); ! 444: } ! 445: } ! 446: ! 447: char * ! 448: getlist(list, p) ! 449: short **list; ! 450: char *p; ! 451: { ! 452: register char *t; ! 453: register int count = 1; ! 454: ! 455: for (t = p + 1; *t; t++) { ! 456: if (!isdigit(*t)) ! 457: error("Option %.1s requires a list of unsigned numbers separated by commas", t); ! 458: count++; ! 459: while (*t && isdigit(*t)) ! 460: t++; ! 461: if (*t != ',') ! 462: break; ! 463: } ! 464: if (!(*list = (short *) malloc(count * sizeof(short)))) ! 465: error("No list space", ""); ! 466: count = 0; ! 467: for (t = p + 1; *t; t++) { ! 468: (*list)[count++] = atoi(t); ! 469: printf("++ %d ", (*list)[count-1]); ! 470: fflush(stdout); ! 471: while (*t && isdigit(*t)) ! 472: t++; ! 473: if (*t != ',') ! 474: break; ! 475: } ! 476: (*list)[count] = 0; ! 477: return(t - 1); ! 478: } ! 479: ! 480: char * ! 481: getnum(num, p, strict) /* num = number p points to; if (strict) complain */ ! 482: int *num; /* returns pointer to end of num */ ! 483: char *p; ! 484: int strict; ! 485: { ! 486: register char *t = p; ! 487: ! 488: if (!isdigit(*++t)) { ! 489: if (strict || *t == '-' || *t == '+') ! 490: error("Option %.1s requires an unsigned integer", p); ! 491: *num = 0; ! 492: return(p); ! 493: } ! 494: *num = atoi(t); ! 495: while (*++t) ! 496: if (!isdigit(*t)) ! 497: break; ! 498: return(--t); ! 499: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.