Annotation of coherent/d/bin/c.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * c.c
                      3:  * 9/23/91
                      4:  * Usage: c [ -lN ] [ -wN ] [ -012 ]
                      5:  * Columnize from stdin to stdout.
                      6:  */
                      7: 
                      8: #include       <stdio.h>
                      9: 
                     10: #define        VERSION "1.3"
                     11: 
                     12: extern char    *getenv();
                     13: 
                     14: #define        NAV     6                       /* max # environmental args */
                     15: 
                     16: typedef        struct line {
                     17:        struct line     *l_next;
                     18:        char            *l_line;
                     19: } LINE;
                     20: 
                     21: /* Forward. */
                     22: char   *item();
                     23: char   *sel0();
                     24: char   *sel1();
                     25: char   *sel2();
                     26: void   nomem();
                     27: void   fatal();
                     28: 
                     29: /* Globals. */
                     30: int    fieldmax;                       /* # columns of widest field    */
                     31: int    length;                         /* # lines down page            */
                     32: LINE   *lhead;                         /* head of LINE list            */
                     33: LINE   *ltail;                         /* tail of LINE list            */
                     34: int    nacross;                        /* # fields across page         */
                     35: int    ndown;                          /* # fields down page           */
                     36: int    nfields;                        /* # fields read from input     */
                     37: int    npp;                            /* # fields per page            */
                     38: char   *(*select)() = sel1;            /* selector function            */
                     39: char   *usage = "\nUsage: c [ -lN ] [ -wN ] [ -012 ]";
                     40: int    width = 80;                     /* # columns across page        */
                     41: 
                     42: main(argc, argv) int argc; char *argv[];
                     43: {
                     44:        char obuf[BUFSIZ], av[NAV];
                     45: 
                     46:        envargs(av);
                     47:        setflags(av);
                     48:        setflags(&argv[1]);
                     49:        setbuf(stdout, obuf);
                     50:        input();
                     51:        output();
                     52:        exit(0);
                     53: }
                     54: 
                     55: setflags(av) register char **av;
                     56: {
                     57: 
                     58:        for (; *av; ++av) {
                     59:                if (av[0][0] != '-')
                     60:                        fatal("%s is not an option%s", av[0], usage);
                     61:                switch (av[0][1]) {
                     62:                case '0':
                     63:                        select = sel0;
                     64:                        break;
                     65:                case '1':
                     66:                        select = sel1;
                     67:                        break;
                     68:                case '2':
                     69:                        select = sel2;
                     70:                        break;
                     71:                case 'w':
                     72:                        width = atoi(&av[0][2]);
                     73:                        break;
                     74:                case 'l':
                     75:                        length = atoi(&av[0][2]);
                     76:                        break;
                     77:                case 'V':
                     78:                        fprintf(stderr, "c: V%s\n", VERSION);
                     79:                        break;
                     80:                default:
                     81:                        fatal("bad option %s%s", av[0], usage);
                     82:                }
                     83:        }
                     84: }
                     85: 
                     86: input()
                     87: {
                     88:        register LINE   *lp;
                     89:        register        i;
                     90:        char            lbuf[BUFSIZ];
                     91: 
                     92:        while ((i=getline(lbuf)) >= 0) {
                     93:                lp = malloc(sizeof *lp);
                     94:                if (lp == NULL)
                     95:                        nomem();
                     96:                if (lhead)
                     97:                        ltail->l_next = lp;
                     98:                else
                     99:                        lhead = lp;
                    100:                ltail = lp;
                    101:                lp->l_next = NULL;
                    102:                if (i) {
                    103:                        lp->l_line = malloc(i+1);
                    104:                        if (lp->l_line == NULL)
                    105:                                nomem();
                    106:                        strcpy(lp->l_line, lbuf);
                    107:                }
                    108:                else
                    109:                        lp->l_line = NULL;
                    110:                ++nfields;
                    111:        }
                    112: 
                    113:        ++fieldmax;
                    114: }
                    115: 
                    116: output()
                    117: {
                    118:        register int i, j;
                    119: 
                    120:        nacross = (width+1) / fieldmax;
                    121:        if (nacross <= 0)
                    122:                nacross = 1;
                    123:        if (length != 0)
                    124:                npp = length * nacross;
                    125:        ndown = (nfields + nacross - 1) / nacross;
                    126:        for (i = 0; i < ndown; ++i) {
                    127:                for (j = 0; j < nacross; ++j)
                    128:                        putline((*select)(i, j));
                    129:                putline((char *)0);
                    130:        }
                    131: 
                    132:        fclose(stdout);
                    133: }
                    134: 
                    135: 
                    136: getline(lbuf) char lbuf[];
                    137: {
                    138:        register char   *p;
                    139:        register int    col, xcol;
                    140:        int             c;
                    141: 
                    142:        p = lbuf;
                    143:        col = 0;
                    144:        xcol = 0;
                    145: 
                    146:        for (; ;) {
                    147:                switch (c = getchar()) {
                    148:                case EOF:
                    149:                        return (-1);
                    150:                case '\n':
                    151:                        break;
                    152:                case ' ':
                    153:                        ++xcol;
                    154:                        continue;
                    155:                case '\t':
                    156:                        xcol = (xcol|7) + 1;
                    157:                        continue;
                    158:                case '\b':
                    159:                        if (xcol > col)
                    160:                                --xcol;
                    161:                        else if (col) {
                    162:                                --col;
                    163:                                --xcol;
                    164:                                *p++ = c;
                    165:                        }
                    166:                        continue;
                    167:                default:
                    168:                        while (col < xcol) {
                    169:                                *p++ = ' ';
                    170:                                ++col;
                    171:                        }
                    172:                        *p++ = c;
                    173:                        ++col;
                    174:                        ++xcol;
                    175:                        continue;
                    176:                }
                    177:                break;
                    178:        }
                    179: 
                    180:        if (col > fieldmax)
                    181:                fieldmax = col;
                    182:        *p = '\0';
                    183:        return (p - lbuf);
                    184: }
                    185: 
                    186: putline(lbuf) char *lbuf;
                    187: {
                    188:        register        c;
                    189:        register char   *p;
                    190:        static          col,
                    191:                        xcol;
                    192: 
                    193:        p = lbuf;
                    194:        if (p == NULL) {
                    195:                col = 0;
                    196:                xcol = 0;
                    197:                putchar('\n');
                    198:                return;
                    199:        }
                    200: 
                    201:        while (c = *p++)
                    202:                switch (c) {
                    203:                case ' ':
                    204:                        ++xcol;
                    205:                        break;
                    206:                case '\b':
                    207:                        --col;
                    208:                        --xcol;
                    209:                        putchar(c);
                    210:                        break;
                    211:                default:
                    212:                        while ((col|7)+1 <= xcol) {
                    213:                                putchar('\t');
                    214:                                col = (col|7) + 1;
                    215:                        }
                    216:                        while (col < xcol) {
                    217:                                putchar(' ');
                    218:                                ++col;
                    219:                        }
                    220:                        putchar(c);
                    221:                        ++col;
                    222:                        ++xcol;
                    223:                        break;
                    224:                }
                    225: 
                    226:        xcol += fieldmax - xcol%fieldmax;
                    227: }
                    228: 
                    229: char *
                    230: item(n) int n;
                    231: {
                    232:        register LINE *lp;
                    233:        register int m;
                    234: 
                    235:        for (m = 0, lp = lhead; lp; lp = lp->l_next)
                    236:                if (++m > n)
                    237:                        return (lp->l_line ? lp->l_line : "");
                    238:        return "";
                    239: }
                    240: 
                    241: /*
                    242:  * Across each row, then on to next row.
                    243:  */
                    244: char *
                    245: sel0(i, j) int i, j;
                    246: {
                    247:        return item(i*nacross + j);
                    248: }
                    249: 
                    250: /*
                    251:  * Down each column, then on to next column.
                    252:  * Leave spaces in last column.
                    253:  */
                    254: char *
                    255: sel1(i, j) int i, j;
                    256: {
                    257:        register int page, rows, line;
                    258: 
                    259:        if (length == 0)
                    260:                return item(i + j*ndown);
                    261:        page = i / length;                      /* page number */
                    262:        line = i % length;                      /* line on page */
                    263:        if (page == (ndown-1)/length)
                    264:                rows = ((ndown-1)%length) + 1;  /* rows on last page */
                    265:        else
                    266:                rows = length;                  /* rows on full page */
                    267:        return item(page * npp + line + j * rows);
                    268: }
                    269: 
                    270: /*
                    271:  * Down each column, then on to next column.
                    272:  * Leave spaces in last row.
                    273:  */
                    274: char *
                    275: sel2(i, j) int i, j;
                    276: {
                    277:        register int ncols, page, line, adjust;
                    278: 
                    279:        if (i * nacross + j >= nfields)
                    280:                return "";
                    281:        ncols = nfields % nacross;              /* columns in incomplete last line */
                    282:        adjust = (j > ncols) ? ncols : j;       /* last line adjust */
                    283:        if (length == 0)
                    284:                return item(i                   /* n on prev. lines this col. */
                    285:                           + j*(ndown-1)        /* n on prev. cols. */
                    286:                           + adjust);           /* n on last line */
                    287:        page = i / length;                      /* page number */
                    288:        line = i % length;                      /* line on page */
                    289:        if (page != (ndown-1)/length)           /* not last page */
                    290:                return item(page * npp + line + j * length);
                    291:        else                                    /* last page */
                    292:                return item(page * npp          /* n on prev. pages. */
                    293:                           + line               /* n on prev. lines this col. */
                    294:                           + j*((ndown-1)%length)       /* n on prev. cols. */
                    295:                           + adjust);           /* n on last line */
                    296: }
                    297: 
                    298: envargs(av) char **av;
                    299: {
                    300:        register        fl;
                    301:        register char   *p;
                    302:        register char   **ap;
                    303: 
                    304:        ap = av;
                    305:        *ap = NULL;
                    306:        if ((p=getenv("C")) == NULL)
                    307:                return;
                    308: 
                    309:        fl = 0;
                    310:        while (*p)
                    311:                switch (*p++) {
                    312:                case '\t':
                    313:                case '\n':
                    314:                case ' ':
                    315:                        fl = 0;
                    316:                        p[-1] = '\0';
                    317:                        break;
                    318:                default:
                    319:                        if (fl)
                    320:                                break;
                    321:                        if (ap >= &av[NAV-1])
                    322:                                fatal("too many environmental arguments");
                    323:                        *ap++ = &p[-1];
                    324:                        ++fl;
                    325:                        break;
                    326:                }
                    327: 
                    328:        *ap = NULL;
                    329: }
                    330: 
                    331: void
                    332: nomem()
                    333: {
                    334: 
                    335:        fatal("out of memory");
                    336: }
                    337: 
                    338: void
                    339: fatal(arg0)
                    340: char   *arg0;
                    341: {
                    342: 
                    343:        fflush(stdout);
                    344:        fprintf(stderr, "c: %r\n", &arg0);
                    345:        exit(1);
                    346: }
                    347: 
                    348: /* end of c.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.