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: }

Defined functions

error defined in line 177; used 8 times
getargs defined in line 336; used 1 times
  • in line 61
getfile defined in line 73; used 1 times
  • in line 62
getline defined in line 276; used 3 times
getlist defined in line 447; used 4 times
getnum defined in line 480; used 5 times
getptrs defined in line 309; used 4 times
main defined in line 56; never used
prepfile defined in line 187; used 1 times
  • in line 67
prints defined in line 158; used 2 times
putfile defined in line 137; used 1 times
  • in line 69

Defined variables

allocsize defined in line 44; used 4 times
buf defined in line 35; used 1 times
  • in line 60
colwidths defined in line 36; used 7 times
cord defined in line 37; used 1 times
curlen defined in line 45; used 8 times
curline defined in line 43; used 13 times
elem defined in line 41; used 14 times
endelem defined in line 42; used 3 times
flags defined in line 16; used 36 times
ibuf defined in line 274; used 2 times
icbd defined in line 38; used 1 times
icols defined in line 46; used 6 times
irows defined in line 46; used 7 times
isep defined in line 51; used 7 times
maxlen defined in line 48; used 6 times
nelem defined in line 40; used 18 times
ocbd defined in line 39; used 1 times
ocols defined in line 47; used 23 times
orows defined in line 47; used 16 times
owidth defined in line 52; used 5 times
propgutter defined in line 50; used 2 times
sccsid defined in line 4; never used
skip defined in line 49; used 5 times

Defined macros

BSIZE defined in line 273; used 4 times
DETAILSHAPE defined in line 25; used 2 times
ICOLBOUNDS defined in line 30; used 1 times
MTRANSPOSE defined in line 18; used 2 times
NOARGS defined in line 33; used 2 times
NOTRIMENDCOL defined in line 22; used 2 times
NULLPAD defined in line 27; used 2 times
OCOLBOUNDS defined in line 31; used 1 times
ONEISEPONLY defined in line 20; used 2 times
ONEOSEPONLY defined in line 21; used 2 times
ONEPERCHAR defined in line 32; used 1 times
ONEPERLINE defined in line 19; used 4 times
RECYCLE defined in line 28; used 3 times
RIGHTADJUST defined in line 26; used 3 times
SHAPEONLY defined in line 24; used 2 times
SKIPPRINT defined in line 29; used 2 times
SQUEEZE defined in line 23; used 2 times
TRANSPOSE defined in line 17; used 4 times
Last modified: 1986-04-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1646
Valid CSS Valid XHTML 1.0 Strict