19b50d902SRodney W. Grimes /* 29b50d902SRodney W. Grimes * Copyright (c) 1989, 1993 39b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * This code is derived from software contributed to Berkeley by 69b50d902SRodney W. Grimes * Adam S. Moskowitz of Menlo Consulting and Marciano Pitargue. 79b50d902SRodney W. Grimes * 89b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 99b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 109b50d902SRodney W. Grimes * are met: 119b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 129b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 139b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 149b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 159b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 169b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 179b50d902SRodney W. Grimes * must display the following acknowledgement: 189b50d902SRodney W. Grimes * This product includes software developed by the University of 199b50d902SRodney W. Grimes * California, Berkeley and its contributors. 209b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 219b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 229b50d902SRodney W. Grimes * without specific prior written permission. 239b50d902SRodney W. Grimes * 249b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 259b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 269b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 279b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 289b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 299b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 309b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 319b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 329b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 339b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 349b50d902SRodney W. Grimes * SUCH DAMAGE. 359b50d902SRodney W. Grimes */ 369b50d902SRodney W. Grimes 379b50d902SRodney W. Grimes #ifndef lint 38fa146c53SArchie Cobbs static const char copyright[] = 399b50d902SRodney W. Grimes "@(#) Copyright (c) 1989, 1993\n\ 409b50d902SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 41fa146c53SArchie Cobbs static const char sccsid[] = "@(#)cut.c 8.3 (Berkeley) 5/4/95"; 429b50d902SRodney W. Grimes #endif /* not lint */ 4377c8bf7cSDavid E. O'Brien #include <sys/cdefs.h> 4477c8bf7cSDavid E. O'Brien __FBSDID("$FreeBSD$"); 459b50d902SRodney W. Grimes 469b50d902SRodney W. Grimes #include <ctype.h> 47812bff99SPhilippe Charnier #include <err.h> 489b50d902SRodney W. Grimes #include <limits.h> 49d51c6625SEivind Eklund #include <locale.h> 509b50d902SRodney W. Grimes #include <stdio.h> 519b50d902SRodney W. Grimes #include <stdlib.h> 529b50d902SRodney W. Grimes #include <string.h> 53df3f5d9dSPeter Wemm #include <unistd.h> 54d900c384STim J. Robbins #include <wchar.h> 559b50d902SRodney W. Grimes 56393cf508STim J. Robbins int bflag; 579b50d902SRodney W. Grimes int cflag; 589b50d902SRodney W. Grimes char dchar; 599b50d902SRodney W. Grimes int dflag; 609b50d902SRodney W. Grimes int fflag; 61393cf508STim J. Robbins int nflag; 629b50d902SRodney W. Grimes int sflag; 639b50d902SRodney W. Grimes 64364d0a91STim J. Robbins int b_cut(FILE *, const char *); 65364d0a91STim J. Robbins int b_n_cut(FILE *, const char *); 66364d0a91STim J. Robbins int c_cut(FILE *, const char *); 67364d0a91STim J. Robbins int f_cut(FILE *, const char *); 6899557a79SWill Andrews void get_list(char *); 69a8522a9bSTim J. Robbins void needpos(size_t); 7099557a79SWill Andrews static void usage(void); 719b50d902SRodney W. Grimes 729b50d902SRodney W. Grimes int 73f4ac32deSDavid Malone main(int argc, char *argv[]) 749b50d902SRodney W. Grimes { 759b50d902SRodney W. Grimes FILE *fp; 76364d0a91STim J. Robbins int (*fcn)(FILE *, const char *); 77a6ea32c3STim J. Robbins int ch, rval; 789b50d902SRodney W. Grimes 79d51c6625SEivind Eklund setlocale(LC_ALL, ""); 80d51c6625SEivind Eklund 8193738f50STim J. Robbins fcn = NULL; 829b50d902SRodney W. Grimes dchar = '\t'; /* default delimiter is \t */ 839b50d902SRodney W. Grimes 845183fb53SEivind Eklund while ((ch = getopt(argc, argv, "b:c:d:f:sn")) != -1) 859b50d902SRodney W. Grimes switch(ch) { 86d51c6625SEivind Eklund case 'b': 87393cf508STim J. Robbins get_list(optarg); 88393cf508STim J. Robbins bflag = 1; 89393cf508STim J. Robbins break; 909b50d902SRodney W. Grimes case 'c': 919b50d902SRodney W. Grimes get_list(optarg); 929b50d902SRodney W. Grimes cflag = 1; 939b50d902SRodney W. Grimes break; 949b50d902SRodney W. Grimes case 'd': 959b50d902SRodney W. Grimes dchar = *optarg; 969b50d902SRodney W. Grimes dflag = 1; 979b50d902SRodney W. Grimes break; 989b50d902SRodney W. Grimes case 'f': 999b50d902SRodney W. Grimes get_list(optarg); 1009b50d902SRodney W. Grimes fflag = 1; 1019b50d902SRodney W. Grimes break; 1029b50d902SRodney W. Grimes case 's': 1039b50d902SRodney W. Grimes sflag = 1; 1049b50d902SRodney W. Grimes break; 105d51c6625SEivind Eklund case 'n': 106393cf508STim J. Robbins nflag = 1; 107d51c6625SEivind Eklund break; 1089b50d902SRodney W. Grimes case '?': 1099b50d902SRodney W. Grimes default: 1109b50d902SRodney W. Grimes usage(); 1119b50d902SRodney W. Grimes } 1129b50d902SRodney W. Grimes argc -= optind; 1139b50d902SRodney W. Grimes argv += optind; 1149b50d902SRodney W. Grimes 1159b50d902SRodney W. Grimes if (fflag) { 116393cf508STim J. Robbins if (bflag || cflag || nflag) 1179b50d902SRodney W. Grimes usage(); 118393cf508STim J. Robbins } else if (!(bflag || cflag) || dflag || sflag) 1199b50d902SRodney W. Grimes usage(); 120393cf508STim J. Robbins else if (!bflag && nflag) 121393cf508STim J. Robbins usage(); 122393cf508STim J. Robbins 123364d0a91STim J. Robbins if (fflag) 124364d0a91STim J. Robbins fcn = f_cut; 125364d0a91STim J. Robbins else if (cflag) 126364d0a91STim J. Robbins fcn = MB_CUR_MAX > 1 ? c_cut : b_cut; 127364d0a91STim J. Robbins else if (bflag) 128364d0a91STim J. Robbins fcn = nflag && MB_CUR_MAX > 1 ? b_n_cut : b_cut; 1299b50d902SRodney W. Grimes 130a6ea32c3STim J. Robbins rval = 0; 1319b50d902SRodney W. Grimes if (*argv) 1329b50d902SRodney W. Grimes for (; *argv; ++argv) { 133204c78a1STim J. Robbins if (strcmp(*argv, "-") == 0) 134364d0a91STim J. Robbins rval |= fcn(stdin, "stdin"); 135204c78a1STim J. Robbins else { 136a6ea32c3STim J. Robbins if (!(fp = fopen(*argv, "r"))) { 137a6ea32c3STim J. Robbins warn("%s", *argv); 138a6ea32c3STim J. Robbins rval = 1; 139a6ea32c3STim J. Robbins continue; 140a6ea32c3STim J. Robbins } 1419b50d902SRodney W. Grimes fcn(fp, *argv); 1429b50d902SRodney W. Grimes (void)fclose(fp); 1439b50d902SRodney W. Grimes } 144204c78a1STim J. Robbins } 1459b50d902SRodney W. Grimes else 146364d0a91STim J. Robbins rval = fcn(stdin, "stdin"); 147a6ea32c3STim J. Robbins exit(rval); 1489b50d902SRodney W. Grimes } 1499b50d902SRodney W. Grimes 150d8a3fbd5SWill Andrews size_t autostart, autostop, maxval; 1519b50d902SRodney W. Grimes 152a8522a9bSTim J. Robbins char *positions; 1539b50d902SRodney W. Grimes 1549b50d902SRodney W. Grimes void 155f4ac32deSDavid Malone get_list(char *list) 1569b50d902SRodney W. Grimes { 157d8a3fbd5SWill Andrews size_t setautostart, start, stop; 1582c39ae65SEivind Eklund char *pos; 1599b50d902SRodney W. Grimes char *p; 1609b50d902SRodney W. Grimes 1619b50d902SRodney W. Grimes /* 1629b50d902SRodney W. Grimes * set a byte in the positions array to indicate if a field or 1639b50d902SRodney W. Grimes * column is to be selected; use +1, it's 1-based, not 0-based. 1640dcb7b75STim J. Robbins * Numbers and number ranges may be overlapping, repeated, and in 1650dcb7b75STim J. Robbins * any order. We handle "-3-5" although there's no real reason too. 1669b50d902SRodney W. Grimes */ 1672c39ae65SEivind Eklund for (; (p = strsep(&list, ", \t")) != NULL;) { 1689b50d902SRodney W. Grimes setautostart = start = stop = 0; 1699b50d902SRodney W. Grimes if (*p == '-') { 1709b50d902SRodney W. Grimes ++p; 1719b50d902SRodney W. Grimes setautostart = 1; 1729b50d902SRodney W. Grimes } 1732c39ae65SEivind Eklund if (isdigit((unsigned char)*p)) { 1749b50d902SRodney W. Grimes start = stop = strtol(p, &p, 10); 1759b50d902SRodney W. Grimes if (setautostart && start > autostart) 1769b50d902SRodney W. Grimes autostart = start; 1779b50d902SRodney W. Grimes } 1789b50d902SRodney W. Grimes if (*p == '-') { 1792c39ae65SEivind Eklund if (isdigit((unsigned char)p[1])) 1809b50d902SRodney W. Grimes stop = strtol(p + 1, &p, 10); 1819b50d902SRodney W. Grimes if (*p == '-') { 1829b50d902SRodney W. Grimes ++p; 1839b50d902SRodney W. Grimes if (!autostop || autostop > stop) 1849b50d902SRodney W. Grimes autostop = stop; 1859b50d902SRodney W. Grimes } 1869b50d902SRodney W. Grimes } 1879b50d902SRodney W. Grimes if (*p) 188812bff99SPhilippe Charnier errx(1, "[-cf] list: illegal list value"); 1899b50d902SRodney W. Grimes if (!stop || !start) 190812bff99SPhilippe Charnier errx(1, "[-cf] list: values may not include zero"); 191a8522a9bSTim J. Robbins if (maxval < stop) { 1929b50d902SRodney W. Grimes maxval = stop; 193a8522a9bSTim J. Robbins needpos(maxval + 1); 194a8522a9bSTim J. Robbins } 1959b50d902SRodney W. Grimes for (pos = positions + start; start++ <= stop; *pos++ = 1); 1969b50d902SRodney W. Grimes } 1979b50d902SRodney W. Grimes 1989b50d902SRodney W. Grimes /* overlapping ranges */ 199a8522a9bSTim J. Robbins if (autostop && maxval > autostop) { 2009b50d902SRodney W. Grimes maxval = autostop; 201a8522a9bSTim J. Robbins needpos(maxval + 1); 202a8522a9bSTim J. Robbins } 2039b50d902SRodney W. Grimes 2049b50d902SRodney W. Grimes /* set autostart */ 2059b50d902SRodney W. Grimes if (autostart) 2069b50d902SRodney W. Grimes memset(positions + 1, '1', autostart); 2079b50d902SRodney W. Grimes } 2089b50d902SRodney W. Grimes 209a8522a9bSTim J. Robbins void 210a8522a9bSTim J. Robbins needpos(size_t n) 211a8522a9bSTim J. Robbins { 212a8522a9bSTim J. Robbins static size_t npos; 213f457179aSTim J. Robbins size_t oldnpos; 214a8522a9bSTim J. Robbins 215a8522a9bSTim J. Robbins /* Grow the positions array to at least the specified size. */ 216a8522a9bSTim J. Robbins if (n > npos) { 217f457179aSTim J. Robbins oldnpos = npos; 218a8522a9bSTim J. Robbins if (npos == 0) 219a8522a9bSTim J. Robbins npos = n; 220a8522a9bSTim J. Robbins while (n > npos) 221a8522a9bSTim J. Robbins npos *= 2; 222a8522a9bSTim J. Robbins if ((positions = realloc(positions, npos)) == NULL) 223a8522a9bSTim J. Robbins err(1, "realloc"); 224f457179aSTim J. Robbins memset((char *)positions + oldnpos, 0, npos - oldnpos); 225a8522a9bSTim J. Robbins } 226a8522a9bSTim J. Robbins } 227a8522a9bSTim J. Robbins 228364d0a91STim J. Robbins int 229364d0a91STim J. Robbins b_cut(FILE *fp, const char *fname) 230364d0a91STim J. Robbins { 231364d0a91STim J. Robbins int ch, col; 232364d0a91STim J. Robbins char *pos; 233364d0a91STim J. Robbins 234364d0a91STim J. Robbins ch = 0; 235364d0a91STim J. Robbins for (;;) { 236364d0a91STim J. Robbins pos = positions + 1; 237364d0a91STim J. Robbins for (col = maxval; col; --col) { 238364d0a91STim J. Robbins if ((ch = getc(fp)) == EOF) 239364d0a91STim J. Robbins return (0); 240364d0a91STim J. Robbins if (ch == '\n') 241364d0a91STim J. Robbins break; 242364d0a91STim J. Robbins if (*pos++) 243364d0a91STim J. Robbins (void)putchar(ch); 244364d0a91STim J. Robbins } 245364d0a91STim J. Robbins if (ch != '\n') { 246364d0a91STim J. Robbins if (autostop) 247364d0a91STim J. Robbins while ((ch = getc(fp)) != EOF && ch != '\n') 248364d0a91STim J. Robbins (void)putchar(ch); 249364d0a91STim J. Robbins else 250364d0a91STim J. Robbins while ((ch = getc(fp)) != EOF && ch != '\n'); 251364d0a91STim J. Robbins } 252364d0a91STim J. Robbins (void)putchar('\n'); 253364d0a91STim J. Robbins } 254364d0a91STim J. Robbins return (0); 255364d0a91STim J. Robbins } 256364d0a91STim J. Robbins 257393cf508STim J. Robbins /* 258393cf508STim J. Robbins * Cut based on byte positions, taking care not to split multibyte characters. 259393cf508STim J. Robbins * Although this function also handles the case where -n is not specified, 260364d0a91STim J. Robbins * b_cut() ought to be much faster. 261393cf508STim J. Robbins */ 262364d0a91STim J. Robbins int 263f4ac32deSDavid Malone b_n_cut(FILE *fp, const char *fname) 264393cf508STim J. Robbins { 265393cf508STim J. Robbins size_t col, i, lbuflen; 266393cf508STim J. Robbins char *lbuf; 267393cf508STim J. Robbins int canwrite, clen, warned; 268d900c384STim J. Robbins mbstate_t mbs; 269393cf508STim J. Robbins 270d900c384STim J. Robbins memset(&mbs, 0, sizeof(mbs)); 271393cf508STim J. Robbins warned = 0; 272393cf508STim J. Robbins while ((lbuf = fgetln(fp, &lbuflen)) != NULL) { 273393cf508STim J. Robbins for (col = 0; lbuflen > 0; col += clen) { 274d900c384STim J. Robbins if ((clen = mbrlen(lbuf, lbuflen, &mbs)) < 0) { 275393cf508STim J. Robbins if (!warned) { 276393cf508STim J. Robbins warn("%s", fname); 277393cf508STim J. Robbins warned = 1; 278393cf508STim J. Robbins } 279d900c384STim J. Robbins memset(&mbs, 0, sizeof(mbs)); 280393cf508STim J. Robbins clen = 1; 281393cf508STim J. Robbins } 282393cf508STim J. Robbins if (clen == 0 || *lbuf == '\n') 283393cf508STim J. Robbins break; 284393cf508STim J. Robbins if (col < maxval && !positions[1 + col]) { 285393cf508STim J. Robbins /* 286393cf508STim J. Robbins * Print the character if (1) after an initial 287393cf508STim J. Robbins * segment of un-selected bytes, the rest of 288393cf508STim J. Robbins * it is selected, and (2) the last byte is 289393cf508STim J. Robbins * selected. 290393cf508STim J. Robbins */ 291393cf508STim J. Robbins i = col; 292393cf508STim J. Robbins while (i < col + clen && i < maxval && 293393cf508STim J. Robbins !positions[1 + i]) 294393cf508STim J. Robbins i++; 295393cf508STim J. Robbins canwrite = i < col + clen; 296393cf508STim J. Robbins for (; i < col + clen && i < maxval; i++) 297393cf508STim J. Robbins canwrite &= positions[1 + i]; 298393cf508STim J. Robbins if (canwrite) 299393cf508STim J. Robbins fwrite(lbuf, 1, clen, stdout); 300393cf508STim J. Robbins } else { 301393cf508STim J. Robbins /* 302393cf508STim J. Robbins * Print the character if all of it has 303393cf508STim J. Robbins * been selected. 304393cf508STim J. Robbins */ 305393cf508STim J. Robbins canwrite = 1; 306393cf508STim J. Robbins for (i = col; i < col + clen; i++) 307393cf508STim J. Robbins if ((i >= maxval && !autostop) || 308393cf508STim J. Robbins (i < maxval && !positions[1 + i])) { 309393cf508STim J. Robbins canwrite = 0; 310393cf508STim J. Robbins break; 311393cf508STim J. Robbins } 312393cf508STim J. Robbins if (canwrite) 313393cf508STim J. Robbins fwrite(lbuf, 1, clen, stdout); 314393cf508STim J. Robbins } 315393cf508STim J. Robbins lbuf += clen; 316393cf508STim J. Robbins lbuflen -= clen; 317393cf508STim J. Robbins } 318393cf508STim J. Robbins if (lbuflen > 0) 319393cf508STim J. Robbins putchar('\n'); 320393cf508STim J. Robbins } 321364d0a91STim J. Robbins return (warned); 322393cf508STim J. Robbins } 323393cf508STim J. Robbins 324364d0a91STim J. Robbins int 325364d0a91STim J. Robbins c_cut(FILE *fp, const char *fname) 3269b50d902SRodney W. Grimes { 327364d0a91STim J. Robbins wint_t ch; 328364d0a91STim J. Robbins int col; 3292c39ae65SEivind Eklund char *pos; 3309b50d902SRodney W. Grimes 3312c39ae65SEivind Eklund ch = 0; 3329b50d902SRodney W. Grimes for (;;) { 3339b50d902SRodney W. Grimes pos = positions + 1; 3349b50d902SRodney W. Grimes for (col = maxval; col; --col) { 335364d0a91STim J. Robbins if ((ch = getwc(fp)) == WEOF) 336364d0a91STim J. Robbins goto out; 3379b50d902SRodney W. Grimes if (ch == '\n') 3389b50d902SRodney W. Grimes break; 3399b50d902SRodney W. Grimes if (*pos++) 340364d0a91STim J. Robbins (void)putwchar(ch); 3419b50d902SRodney W. Grimes } 3422c39ae65SEivind Eklund if (ch != '\n') { 3439b50d902SRodney W. Grimes if (autostop) 344364d0a91STim J. Robbins while ((ch = getwc(fp)) != WEOF && ch != '\n') 345364d0a91STim J. Robbins (void)putwchar(ch); 3469b50d902SRodney W. Grimes else 347364d0a91STim J. Robbins while ((ch = getwc(fp)) != WEOF && ch != '\n'); 3482c39ae65SEivind Eklund } 349364d0a91STim J. Robbins (void)putwchar('\n'); 3509b50d902SRodney W. Grimes } 351364d0a91STim J. Robbins out: 352364d0a91STim J. Robbins if (ferror(fp)) { 353364d0a91STim J. Robbins warn("%s", fname); 354364d0a91STim J. Robbins return (1); 355364d0a91STim J. Robbins } 356364d0a91STim J. Robbins return (0); 3579b50d902SRodney W. Grimes } 3589b50d902SRodney W. Grimes 359364d0a91STim J. Robbins int 360f4ac32deSDavid Malone f_cut(FILE *fp, const char *fname __unused) 3619b50d902SRodney W. Grimes { 3622c39ae65SEivind Eklund int ch, field, isdelim; 3632c39ae65SEivind Eklund char *pos, *p, sep; 3649b50d902SRodney W. Grimes int output; 36593738f50STim J. Robbins char *lbuf, *mlbuf; 3661928e20eSDima Dorfman size_t lbuflen; 3679b50d902SRodney W. Grimes 36893738f50STim J. Robbins mlbuf = NULL; 3691928e20eSDima Dorfman for (sep = dchar; (lbuf = fgetln(fp, &lbuflen)) != NULL;) { 3701928e20eSDima Dorfman /* Assert EOL has a newline. */ 3711928e20eSDima Dorfman if (*(lbuf + lbuflen - 1) != '\n') { 3721928e20eSDima Dorfman /* Can't have > 1 line with no trailing newline. */ 3731928e20eSDima Dorfman mlbuf = malloc(lbuflen + 1); 3741928e20eSDima Dorfman if (mlbuf == NULL) 3751928e20eSDima Dorfman err(1, "malloc"); 3761928e20eSDima Dorfman memcpy(mlbuf, lbuf, lbuflen); 3771928e20eSDima Dorfman *(mlbuf + lbuflen) = '\n'; 3781928e20eSDima Dorfman lbuf = mlbuf; 3791928e20eSDima Dorfman } 380eaf92380SAndrey A. Chernov output = 0; 3819b50d902SRodney W. Grimes for (isdelim = 0, p = lbuf;; ++p) { 3821928e20eSDima Dorfman ch = *p; 3839b50d902SRodney W. Grimes /* this should work if newline is delimiter */ 3849b50d902SRodney W. Grimes if (ch == sep) 3859b50d902SRodney W. Grimes isdelim = 1; 3869b50d902SRodney W. Grimes if (ch == '\n') { 3879b50d902SRodney W. Grimes if (!isdelim && !sflag) 3881928e20eSDima Dorfman (void)fwrite(lbuf, lbuflen, 1, stdout); 3899b50d902SRodney W. Grimes break; 3909b50d902SRodney W. Grimes } 3919b50d902SRodney W. Grimes } 3929b50d902SRodney W. Grimes if (!isdelim) 3939b50d902SRodney W. Grimes continue; 3949b50d902SRodney W. Grimes 3959b50d902SRodney W. Grimes pos = positions + 1; 3969b50d902SRodney W. Grimes for (field = maxval, p = lbuf; field; --field, ++pos) { 3979b50d902SRodney W. Grimes if (*pos) { 3989b50d902SRodney W. Grimes if (output++) 3999b50d902SRodney W. Grimes (void)putchar(sep); 4009b50d902SRodney W. Grimes while ((ch = *p++) != '\n' && ch != sep) 4019b50d902SRodney W. Grimes (void)putchar(ch); 4022c39ae65SEivind Eklund } else { 4032c39ae65SEivind Eklund while ((ch = *p++) != '\n' && ch != sep) 4042c39ae65SEivind Eklund continue; 4052c39ae65SEivind Eklund } 4069b50d902SRodney W. Grimes if (ch == '\n') 4079b50d902SRodney W. Grimes break; 4089b50d902SRodney W. Grimes } 4092c39ae65SEivind Eklund if (ch != '\n') { 4109b50d902SRodney W. Grimes if (autostop) { 4119b50d902SRodney W. Grimes if (output) 4129b50d902SRodney W. Grimes (void)putchar(sep); 4139b50d902SRodney W. Grimes for (; (ch = *p) != '\n'; ++p) 4149b50d902SRodney W. Grimes (void)putchar(ch); 4159b50d902SRodney W. Grimes } else 4169b50d902SRodney W. Grimes for (; (ch = *p) != '\n'; ++p); 4172c39ae65SEivind Eklund } 4189b50d902SRodney W. Grimes (void)putchar('\n'); 4199b50d902SRodney W. Grimes } 4201928e20eSDima Dorfman if (mlbuf != NULL) 4211928e20eSDima Dorfman free(mlbuf); 422364d0a91STim J. Robbins return (0); 4239b50d902SRodney W. Grimes } 4249b50d902SRodney W. Grimes 425812bff99SPhilippe Charnier static void 426f4ac32deSDavid Malone usage(void) 4279b50d902SRodney W. Grimes { 428d51c6625SEivind Eklund (void)fprintf(stderr, "%s\n%s\n%s\n", 429d51c6625SEivind Eklund "usage: cut -b list [-n] [file ...]", 430d51c6625SEivind Eklund " cut -c list [file ...]", 431812bff99SPhilippe Charnier " cut -f list [-s] [-d delim] [file ...]"); 4329b50d902SRodney W. Grimes exit(1); 4339b50d902SRodney W. Grimes } 434