Annotation of 43BSDReno/usr.bin/cut/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: #endif /* not lint */
        !            28: 
        !            29: #ifndef lint
        !            30: static char sccsid[] = "@(#)cut.c      5.3 (Berkeley) 6/24/90";
        !            31: #endif /* not lint */
        !            32: 
        !            33: #include <limits.h>
        !            34: #include <stdio.h>
        !            35: #include <ctype.h>
        !            36: 
        !            37: int    cflag;
        !            38: char   dchar;
        !            39: int    dflag;
        !            40: int    fflag;
        !            41: int    sflag;
        !            42: 
        !            43: main(argc, argv)
        !            44:        int argc;
        !            45:        char **argv;
        !            46: {
        !            47:        extern char *optarg;
        !            48:        extern int errno, optind;
        !            49:        FILE *fp;
        !            50:        int ch, (*fcn)(), c_cut(), f_cut();
        !            51:        char *strerror();
        !            52: 
        !            53:        dchar = '\t';                   /* default delimiter is \t */
        !            54: 
        !            55:        while ((ch = getopt(argc, argv, "c:d:f:s")) != EOF)
        !            56:                switch(ch) {
        !            57:                case 'c':
        !            58:                        fcn = c_cut;
        !            59:                        get_list(optarg);
        !            60:                        cflag = 1;
        !            61:                        break;
        !            62:                case 'd':
        !            63:                        dchar = *optarg;
        !            64:                        dflag = 1;
        !            65:                        break;
        !            66:                case 'f':
        !            67:                        get_list(optarg);
        !            68:                        fcn = f_cut;
        !            69:                        fflag = 1;
        !            70:                        break;
        !            71:                case 's':
        !            72:                        sflag = 1;
        !            73:                        break;
        !            74:                case '?':
        !            75:                default:
        !            76:                        usage();
        !            77:                }
        !            78:        argc -= optind;
        !            79:        argv += optind;
        !            80: 
        !            81:        if (fflag) {
        !            82:                if (cflag)
        !            83:                        usage();
        !            84:        } else if (!cflag || dflag || sflag)
        !            85:                usage();
        !            86: 
        !            87:        if (*argv)
        !            88:                for (; *argv; ++argv) {
        !            89:                        if (!(fp = fopen(*argv, "r"))) {
        !            90:                                (void)fprintf(stderr,
        !            91:                                    "cut: %s: %s\n", *argv, strerror(errno));
        !            92:                                exit(1);
        !            93:                        }
        !            94:                        fcn(fp, *argv);
        !            95:                }
        !            96:        else
        !            97:                fcn(stdin, "stdin");
        !            98:        exit(0);
        !            99: }
        !           100: 
        !           101: int autostart, autostop, maxval;
        !           102: 
        !           103: char positions[_BSD_LINE_MAX + 1];
        !           104: 
        !           105: get_list(list)
        !           106:        char *list;
        !           107: {
        !           108:        register char *pos;
        !           109:        register int setautostart, start, stop;
        !           110:        char *p, *strtok();
        !           111: 
        !           112:        /*
        !           113:         * set a byte in the positions array to indicate if a field or
        !           114:         * column is to be selected; use +1, it's 1-based, not 0-based.
        !           115:         * This parser is less restrictive than the Draft 9 POSIX spec.
        !           116:         * POSIX doesn't allow lists that aren't in increasing order or
        !           117:         * overlapping lists.  We also handle "-3-5" although there's no
        !           118:         * real reason too.
        !           119:         */
        !           120:        for (; p = strtok(list, ", \t"); list = NULL) {
        !           121:                setautostart = start = stop = 0;
        !           122:                if (*p == '-') {
        !           123:                        ++p;
        !           124:                        setautostart = 1;
        !           125:                }
        !           126:                if (isdigit(*p)) {
        !           127:                        start = stop = strtol(p, &p, 10);
        !           128:                        if (setautostart && start > autostart)
        !           129:                                autostart = start;
        !           130:                }
        !           131:                if (*p == '-') {
        !           132:                        if (isdigit(p[1]))
        !           133:                                stop = strtol(p + 1, &p, 10);
        !           134:                        if (*p == '-') {
        !           135:                                ++p;
        !           136:                                if (!autostop || autostop > stop)
        !           137:                                        autostop = stop;
        !           138:                        }
        !           139:                }
        !           140:                if (*p)
        !           141:                        badlist("illegal list value");
        !           142:                if (!stop || !start)
        !           143:                        badlist("values may not include zero");
        !           144:                if (stop > _BSD_LINE_MAX) {
        !           145:                        /* positions used rather than allocate a new buffer */
        !           146:                        (void)sprintf(positions, "%d too large (max %d)",
        !           147:                            stop, _BSD_LINE_MAX);
        !           148:                        badlist(positions);
        !           149:                }
        !           150:                if (maxval < stop)
        !           151:                        maxval = stop;
        !           152:                for (pos = positions + start; start++ <= stop; *pos++ = 1);
        !           153:        }
        !           154: 
        !           155:        /* overlapping ranges */
        !           156:        if (autostop && maxval > autostop)
        !           157:                maxval = autostop;
        !           158: 
        !           159:        /* set autostart */
        !           160:        if (autostart)
        !           161:                memset(positions + 1, '1', autostart);
        !           162: }
        !           163: 
        !           164: /* ARGSUSED */
        !           165: c_cut(fp, fname)
        !           166:        FILE *fp;
        !           167:        char *fname;
        !           168: {
        !           169:        register int ch, col;
        !           170:        register char *pos;
        !           171: 
        !           172:        for (;;) {
        !           173:                pos = positions + 1;
        !           174:                for (col = maxval; col; --col) {
        !           175:                        if ((ch = getc(fp)) == EOF)
        !           176:                                return;
        !           177:                        if (ch == '\n')
        !           178:                                break;
        !           179:                        if (*pos++)
        !           180:                                putchar(ch);
        !           181:                }
        !           182:                if (ch != '\n')
        !           183:                        if (autostop)
        !           184:                                while ((ch = getc(fp)) != EOF && ch != '\n')
        !           185:                                        putchar(ch);
        !           186:                        else
        !           187:                                while ((ch = getc(fp)) != EOF && ch != '\n');
        !           188:                putchar('\n');
        !           189:        }
        !           190: }
        !           191: 
        !           192: f_cut(fp, fname)
        !           193:        FILE *fp;
        !           194:        char *fname;
        !           195: {
        !           196:        register int ch, field, isdelim;
        !           197:        register char *pos, *p, sep;
        !           198:        int output;
        !           199:        char lbuf[_BSD_LINE_MAX + 1];
        !           200: 
        !           201:        for (sep = dchar, output = 0; fgets(lbuf, sizeof(lbuf), fp);) {
        !           202:                for (isdelim = 0, p = lbuf;; ++p) {
        !           203:                        if (!(ch = *p)) {
        !           204:                                (void)fprintf(stderr,
        !           205:                                    "cut: %s: line too long.\n", fname);
        !           206:                                exit(1);
        !           207:                        }
        !           208:                        /* this should work if newline is delimiter */
        !           209:                        if (ch == sep)
        !           210:                                isdelim = 1;
        !           211:                        if (ch == '\n') {
        !           212:                                if (!isdelim && !sflag)
        !           213:                                        (void)printf("%s", lbuf);
        !           214:                                break;
        !           215:                        }
        !           216:                }
        !           217:                if (!isdelim)
        !           218:                        continue;
        !           219: 
        !           220:                pos = positions + 1;
        !           221:                for (field = maxval, p = lbuf; field; --field, ++pos) {
        !           222:                        if (*pos) {
        !           223:                                if (output++)
        !           224:                                        putchar(sep);
        !           225:                                while ((ch = *p++) != '\n' && ch != sep)
        !           226:                                        putchar(ch);
        !           227:                        } else
        !           228:                                while ((ch = *p++) != '\n' && ch != sep);
        !           229:                        if (ch == '\n')
        !           230:                                break;
        !           231:                }
        !           232:                if (ch != '\n')
        !           233:                        if (autostop) {
        !           234:                                if (output)
        !           235:                                        putchar(sep);
        !           236:                                for (; (ch = *p) != '\n'; ++p)
        !           237:                                        putchar(ch);
        !           238:                        } else
        !           239:                                for (; (ch = *p) != '\n'; ++p);
        !           240:                putchar('\n');
        !           241:        }
        !           242: }
        !           243: 
        !           244: badlist(msg)
        !           245:        char *msg;
        !           246: {
        !           247:        (void)fprintf(stderr, "cut: [-cf] list: %s.\n", msg);
        !           248:        exit(1);
        !           249: }
        !           250: 
        !           251: usage()
        !           252: {
        !           253:        (void)fprintf(stderr,
        !           254: "usage:\tcut -c list [file1 ...]\n\tcut -f list [-s] [-d delim] [file ...]\n");
        !           255:        exit(1);
        !           256: }

unix.superglobalmegacorp.com

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