Annotation of coherent/d/usr/bin/cutpaste/cut.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1989 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * This code is derived from software contributed to Berkeley by
        !             6:  * Adam S. Moskowitz of Menlo Consulting and Marciano Pitargue.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms are permitted provided
        !             9:  * that: (1) source distributions retain this entire copyright notice and
        !            10:  * comment, and (2) distributions including binaries display the following
        !            11:  * acknowledgement:  ``This product includes software developed by the
        !            12:  * University of California, Berkeley and its contributors'' in the
        !            13:  * documentation or other materials provided with the distribution and in
        !            14:  * all advertising materials mentioning features or use of this software.
        !            15:  * Neither the name of the University nor the names of its contributors may
        !            16:  * be used to endorse or promote products derived from this software without
        !            17:  * specific prior written permission.
        !            18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            19:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            20:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            21:  */
        !            22: 
        !            23: #ifndef lint
        !            24: char copyright[] =
        !            25: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
        !            26:  All rights reserved.\n";
        !            27: static char sccsid[] = "@(#)cut.c      5.3 (Berkeley) 6/24/90";
        !            28: #endif /* not lint */
        !            29: 
        !            30: #include <stdio.h>
        !            31: #include <ctype.h>
        !            32: #if COHERENT
        !            33: #include <string.h>
        !            34: #define        _BSD_LINE_MAX   BUFSIZ                  /* compatibility */
        !            35: #else
        !            36: #include <limits.h>
        !            37: #endif
        !            38: 
        !            39: int    cflag;
        !            40: char   dchar;
        !            41: int    dflag;
        !            42: int    fflag;
        !            43: int    sflag;
        !            44: long   strtol();
        !            45: 
        !            46: main(argc, argv)
        !            47:        int argc;
        !            48:        char **argv;
        !            49: {
        !            50:        extern char *optarg;
        !            51:        extern int errno, optind;
        !            52:        FILE *fp;
        !            53:        int ch, (*fcn)(), c_cut(), f_cut();
        !            54:        char *strerror();
        !            55: 
        !            56:        dchar = '\t';                   /* default delimiter is \t */
        !            57: 
        !            58:        while ((ch = getopt(argc, argv, "c:d:f:s")) != EOF)
        !            59:                switch(ch) {
        !            60:                case 'c':
        !            61:                        fcn = c_cut;
        !            62:                        get_list(optarg);
        !            63:                        cflag = 1;
        !            64:                        break;
        !            65:                case 'd':
        !            66:                        dchar = *optarg;
        !            67:                        dflag = 1;
        !            68:                        break;
        !            69:                case 'f':
        !            70:                        get_list(optarg);
        !            71:                        fcn = f_cut;
        !            72:                        fflag = 1;
        !            73:                        break;
        !            74:                case 's':
        !            75:                        sflag = 1;
        !            76:                        break;
        !            77:                case '?':
        !            78:                default:
        !            79:                        usage();
        !            80:                }
        !            81:        argc -= optind;
        !            82:        argv += optind;
        !            83: 
        !            84:        if (fflag) {
        !            85:                if (cflag)
        !            86:                        usage();
        !            87:        } else if (!cflag || dflag || sflag)
        !            88:                usage();
        !            89: 
        !            90:        if (*argv)
        !            91:                for (; *argv; ++argv) {
        !            92:                        if (!(fp = fopen(*argv, "r"))) {
        !            93:                                (void)fprintf(stderr,
        !            94:                                    "cut: %s: %s\n", *argv, strerror(errno));
        !            95:                                exit(1);
        !            96:                        }
        !            97:                        (*fcn)(fp, *argv);
        !            98:                }
        !            99:        else
        !           100:                (*fcn)(stdin, "stdin");
        !           101:        exit(0);
        !           102: }
        !           103: 
        !           104: int autostart, autostop, maxval;
        !           105: 
        !           106: char positions[_BSD_LINE_MAX + 1];
        !           107: 
        !           108: get_list(list)
        !           109:        char *list;
        !           110: {
        !           111:        register char *pos;
        !           112:        register int setautostart, start, stop;
        !           113:        char *p, *strtok();
        !           114: 
        !           115:        /*
        !           116:         * set a byte in the positions array to indicate if a field or
        !           117:         * column is to be selected; use +1, it's 1-based, not 0-based.
        !           118:         * This parser is less restrictive than the Draft 9 POSIX spec.
        !           119:         * POSIX doesn't allow lists that aren't in increasing order or
        !           120:         * overlapping lists.  We also handle "-3-5" although there's no
        !           121:         * real reason too.
        !           122:         */
        !           123:        for (; p = strtok(list, ", \t"); list = NULL) {
        !           124:                setautostart = start = stop = 0;
        !           125:                if (*p == '-') {
        !           126:                        ++p;
        !           127:                        setautostart = 1;
        !           128:                }
        !           129:                if (isdigit(*p)) {
        !           130:                        start = stop = strtol(p, &p, 10);
        !           131:                        if (setautostart && start > autostart)
        !           132:                                autostart = start;
        !           133:                }
        !           134:                if (*p == '-') {
        !           135:                        if (isdigit(p[1]))
        !           136:                                stop = strtol(p + 1, &p, 10);
        !           137:                        if (*p == '-') {
        !           138:                                ++p;
        !           139:                                if (!autostop || autostop > stop)
        !           140:                                        autostop = stop;
        !           141:                        }
        !           142:                }
        !           143:                if (*p)
        !           144:                        badlist("illegal list value");
        !           145:                if (!stop || !start)
        !           146:                        badlist("values may not include zero");
        !           147:                if (stop > _BSD_LINE_MAX) {
        !           148:                        /* positions used rather than allocate a new buffer */
        !           149:                        (void)sprintf(positions, "%d too large (max %d)",
        !           150:                            stop, _BSD_LINE_MAX);
        !           151:                        badlist(positions);
        !           152:                }
        !           153:                if (maxval < stop)
        !           154:                        maxval = stop;
        !           155:                for (pos = positions + start; start++ <= stop; *pos++ = 1);
        !           156:        }
        !           157: 
        !           158:        /* overlapping ranges */
        !           159:        if (autostop && maxval > autostop)
        !           160:                maxval = autostop;
        !           161: 
        !           162:        /* set autostart */
        !           163:        if (autostart)
        !           164:                memset(positions + 1, '1', autostart);
        !           165: }
        !           166: 
        !           167: /* ARGSUSED */
        !           168: c_cut(fp, fname)
        !           169:        FILE *fp;
        !           170:        char *fname;
        !           171: {
        !           172:        register int ch, col;
        !           173:        register char *pos;
        !           174: 
        !           175:        for (;;) {
        !           176:                pos = positions + 1;
        !           177:                for (col = maxval; col; --col) {
        !           178:                        if ((ch = getc(fp)) == EOF)
        !           179:                                return;
        !           180:                        if (ch == '\n')
        !           181:                                break;
        !           182:                        if (*pos++)
        !           183:                                putchar(ch);
        !           184:                }
        !           185:                if (ch != '\n')
        !           186:                        if (autostop)
        !           187:                                while ((ch = getc(fp)) != EOF && ch != '\n')
        !           188:                                        putchar(ch);
        !           189:                        else
        !           190:                                while ((ch = getc(fp)) != EOF && ch != '\n');
        !           191:                putchar('\n');
        !           192:        }
        !           193: }
        !           194: 
        !           195: f_cut(fp, fname)
        !           196:        FILE *fp;
        !           197:        char *fname;
        !           198: {
        !           199:        register int ch, field, isdelim;
        !           200:        register char *pos, *p, sep;
        !           201:        int output;
        !           202:        char lbuf[_BSD_LINE_MAX + 1];
        !           203: 
        !           204:        for (sep = dchar, output = 0; fgets(lbuf, sizeof(lbuf), fp);) {
        !           205:                for (isdelim = 0, p = lbuf;; ++p) {
        !           206:                        if (!(ch = *p)) {
        !           207:                                (void)fprintf(stderr,
        !           208:                                    "cut: %s: line too long.\n", fname);
        !           209:                                exit(1);
        !           210:                        }
        !           211:                        /* this should work if newline is delimiter */
        !           212:                        if (ch == sep)
        !           213:                                isdelim = 1;
        !           214:                        if (ch == '\n') {
        !           215:                                if (!isdelim && !sflag)
        !           216:                                        (void)printf("%s", lbuf);
        !           217:                                break;
        !           218:                        }
        !           219:                }
        !           220:                if (!isdelim)
        !           221:                        continue;
        !           222: 
        !           223:                pos = positions + 1;
        !           224:                for (field = maxval, p = lbuf; field; --field, ++pos) {
        !           225:                        if (*pos) {
        !           226:                                if (output++)
        !           227:                                        putchar(sep);
        !           228:                                while ((ch = *p++) != '\n' && ch != sep)
        !           229:                                        putchar(ch);
        !           230:                        } else
        !           231:                                while ((ch = *p++) != '\n' && ch != sep);
        !           232:                        if (ch == '\n')
        !           233:                                break;
        !           234:                }
        !           235:                if (ch != '\n')
        !           236:                        if (autostop) {
        !           237:                                if (output)
        !           238:                                        putchar(sep);
        !           239:                                for (; (ch = *p) != '\n'; ++p)
        !           240:                                        putchar(ch);
        !           241:                        } else
        !           242:                                for (; (ch = *p) != '\n'; ++p);
        !           243:                putchar('\n');
        !           244:        }
        !           245: }
        !           246: 
        !           247: badlist(msg)
        !           248:        char *msg;
        !           249: {
        !           250:        (void)fprintf(stderr, "cut: [-cf] list: %s.\n", msg);
        !           251:        exit(1);
        !           252: }
        !           253: 
        !           254: usage()
        !           255: {
        !           256:        (void)fprintf(stderr,
        !           257: "usage:\tcut -c list [file1 ...]\n\tcut -f list [-s] [-d delim] [file ...]\n");
        !           258:        exit(1);
        !           259: }

unix.superglobalmegacorp.com

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