rev |
line source |
meillo@14
|
1 /*
|
meillo@14
|
2 * Copyright (c) 1989, 1993
|
meillo@14
|
3 * The Regents of the University of California. All rights reserved.
|
meillo@14
|
4 *
|
meillo@14
|
5 * This code is derived from software contributed to Berkeley by
|
meillo@14
|
6 * Adam S. Moskowitz of Menlo Consulting and Marciano Pitargue.
|
meillo@14
|
7 *
|
meillo@14
|
8 * Redistribution and use in source and binary forms, with or without
|
meillo@14
|
9 * modification, are permitted provided that the following conditions
|
meillo@14
|
10 * are met:
|
meillo@14
|
11 * 1. Redistributions of source code must retain the above copyright
|
meillo@14
|
12 * notice, this list of conditions and the following disclaimer.
|
meillo@14
|
13 * 2. Redistributions in binary form must reproduce the above copyright
|
meillo@14
|
14 * notice, this list of conditions and the following disclaimer in the
|
meillo@14
|
15 * documentation and/or other materials provided with the distribution.
|
meillo@14
|
16 * 4. Neither the name of the University nor the names of its contributors
|
meillo@14
|
17 * may be used to endorse or promote products derived from this software
|
meillo@14
|
18 * without specific prior written permission.
|
meillo@14
|
19 *
|
meillo@14
|
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
meillo@14
|
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
meillo@14
|
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
meillo@14
|
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
meillo@14
|
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
meillo@14
|
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
meillo@14
|
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
meillo@14
|
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
meillo@14
|
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
meillo@14
|
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
meillo@14
|
30 * SUCH DAMAGE.
|
meillo@14
|
31 */
|
meillo@14
|
32
|
meillo@14
|
33 #ifndef lint
|
meillo@14
|
34 static const char copyright[] =
|
meillo@14
|
35 "@(#) Copyright (c) 1989, 1993\n\
|
meillo@14
|
36 The Regents of the University of California. All rights reserved.\n";
|
meillo@14
|
37 static const char sccsid[] = "@(#)cut.c 8.3 (Berkeley) 5/4/95";
|
meillo@14
|
38 #endif /* not lint */
|
meillo@14
|
39 #include <sys/cdefs.h>
|
meillo@14
|
40 __FBSDID("$FreeBSD$");
|
meillo@14
|
41
|
meillo@14
|
42 #include <ctype.h>
|
meillo@14
|
43 #include <err.h>
|
meillo@14
|
44 #include <errno.h>
|
meillo@14
|
45 #include <limits.h>
|
meillo@14
|
46 #include <locale.h>
|
meillo@14
|
47 #include <stdio.h>
|
meillo@14
|
48 #include <stdlib.h>
|
meillo@14
|
49 #include <string.h>
|
meillo@14
|
50 #include <unistd.h>
|
meillo@14
|
51 #include <wchar.h>
|
meillo@14
|
52
|
meillo@14
|
53 static int bflag;
|
meillo@14
|
54 static int cflag;
|
meillo@14
|
55 static wchar_t dchar;
|
meillo@14
|
56 static char dcharmb[MB_LEN_MAX + 1];
|
meillo@14
|
57 static int dflag;
|
meillo@14
|
58 static int fflag;
|
meillo@14
|
59 static int nflag;
|
meillo@14
|
60 static int sflag;
|
meillo@14
|
61 static int wflag;
|
meillo@14
|
62
|
meillo@14
|
63 static size_t autostart, autostop, maxval;
|
meillo@14
|
64 static char * positions;
|
meillo@14
|
65
|
meillo@14
|
66 static int b_cut(FILE *, const char *);
|
meillo@14
|
67 static int b_n_cut(FILE *, const char *);
|
meillo@14
|
68 static int c_cut(FILE *, const char *);
|
meillo@14
|
69 static int f_cut(FILE *, const char *);
|
meillo@14
|
70 static void get_list(char *);
|
meillo@14
|
71 static int is_delim(wchar_t);
|
meillo@14
|
72 static void needpos(size_t);
|
meillo@14
|
73 static void usage(void);
|
meillo@14
|
74
|
meillo@14
|
75 int
|
meillo@14
|
76 main(int argc, char *argv[])
|
meillo@14
|
77 {
|
meillo@14
|
78 FILE *fp;
|
meillo@14
|
79 int (*fcn)(FILE *, const char *);
|
meillo@14
|
80 int ch, rval;
|
meillo@14
|
81 size_t n;
|
meillo@14
|
82
|
meillo@14
|
83 setlocale(LC_ALL, "");
|
meillo@14
|
84
|
meillo@14
|
85 fcn = NULL;
|
meillo@14
|
86 dchar = '\t'; /* default delimiter is \t */
|
meillo@14
|
87 strcpy(dcharmb, "\t");
|
meillo@14
|
88
|
meillo@14
|
89 while ((ch = getopt(argc, argv, "b:c:d:f:snw")) != -1)
|
meillo@14
|
90 switch(ch) {
|
meillo@14
|
91 case 'b':
|
meillo@14
|
92 get_list(optarg);
|
meillo@14
|
93 bflag = 1;
|
meillo@14
|
94 break;
|
meillo@14
|
95 case 'c':
|
meillo@14
|
96 get_list(optarg);
|
meillo@14
|
97 cflag = 1;
|
meillo@14
|
98 break;
|
meillo@14
|
99 case 'd':
|
meillo@14
|
100 n = mbrtowc(&dchar, optarg, MB_LEN_MAX, NULL);
|
meillo@14
|
101 if (dchar == '\0' || n != strlen(optarg))
|
meillo@14
|
102 errx(1, "bad delimiter");
|
meillo@14
|
103 strcpy(dcharmb, optarg);
|
meillo@14
|
104 dflag = 1;
|
meillo@14
|
105 break;
|
meillo@14
|
106 case 'f':
|
meillo@14
|
107 get_list(optarg);
|
meillo@14
|
108 fflag = 1;
|
meillo@14
|
109 break;
|
meillo@14
|
110 case 's':
|
meillo@14
|
111 sflag = 1;
|
meillo@14
|
112 break;
|
meillo@14
|
113 case 'n':
|
meillo@14
|
114 nflag = 1;
|
meillo@14
|
115 break;
|
meillo@14
|
116 case 'w':
|
meillo@14
|
117 wflag = 1;
|
meillo@14
|
118 break;
|
meillo@14
|
119 case '?':
|
meillo@14
|
120 default:
|
meillo@14
|
121 usage();
|
meillo@14
|
122 }
|
meillo@14
|
123 argc -= optind;
|
meillo@14
|
124 argv += optind;
|
meillo@14
|
125
|
meillo@14
|
126 if (fflag) {
|
meillo@14
|
127 if (bflag || cflag || nflag || (wflag && dflag))
|
meillo@14
|
128 usage();
|
meillo@14
|
129 } else if (!(bflag || cflag) || dflag || sflag || wflag)
|
meillo@14
|
130 usage();
|
meillo@14
|
131 else if (!bflag && nflag)
|
meillo@14
|
132 usage();
|
meillo@14
|
133
|
meillo@14
|
134 if (fflag)
|
meillo@14
|
135 fcn = f_cut;
|
meillo@14
|
136 else if (cflag)
|
meillo@14
|
137 fcn = MB_CUR_MAX > 1 ? c_cut : b_cut;
|
meillo@14
|
138 else if (bflag)
|
meillo@14
|
139 fcn = nflag && MB_CUR_MAX > 1 ? b_n_cut : b_cut;
|
meillo@14
|
140
|
meillo@14
|
141 rval = 0;
|
meillo@14
|
142 if (*argv)
|
meillo@14
|
143 for (; *argv; ++argv) {
|
meillo@14
|
144 if (strcmp(*argv, "-") == 0)
|
meillo@14
|
145 rval |= fcn(stdin, "stdin");
|
meillo@14
|
146 else {
|
meillo@14
|
147 if (!(fp = fopen(*argv, "r"))) {
|
meillo@14
|
148 warn("%s", *argv);
|
meillo@14
|
149 rval = 1;
|
meillo@14
|
150 continue;
|
meillo@14
|
151 }
|
meillo@14
|
152 fcn(fp, *argv);
|
meillo@14
|
153 (void)fclose(fp);
|
meillo@14
|
154 }
|
meillo@14
|
155 }
|
meillo@14
|
156 else
|
meillo@14
|
157 rval = fcn(stdin, "stdin");
|
meillo@14
|
158 exit(rval);
|
meillo@14
|
159 }
|
meillo@14
|
160
|
meillo@14
|
161 static void
|
meillo@14
|
162 get_list(char *list)
|
meillo@14
|
163 {
|
meillo@14
|
164 size_t setautostart, start, stop;
|
meillo@14
|
165 char *pos;
|
meillo@14
|
166 char *p;
|
meillo@14
|
167
|
meillo@14
|
168 /*
|
meillo@14
|
169 * set a byte in the positions array to indicate if a field or
|
meillo@14
|
170 * column is to be selected; use +1, it's 1-based, not 0-based.
|
meillo@14
|
171 * Numbers and number ranges may be overlapping, repeated, and in
|
meillo@14
|
172 * any order. We handle "-3-5" although there's no real reason to.
|
meillo@14
|
173 */
|
meillo@14
|
174 for (; (p = strsep(&list, ", \t")) != NULL;) {
|
meillo@14
|
175 setautostart = start = stop = 0;
|
meillo@14
|
176 if (*p == '-') {
|
meillo@14
|
177 ++p;
|
meillo@14
|
178 setautostart = 1;
|
meillo@14
|
179 }
|
meillo@14
|
180 if (isdigit((unsigned char)*p)) {
|
meillo@14
|
181 start = stop = strtol(p, &p, 10);
|
meillo@14
|
182 if (setautostart && start > autostart)
|
meillo@14
|
183 autostart = start;
|
meillo@14
|
184 }
|
meillo@14
|
185 if (*p == '-') {
|
meillo@14
|
186 if (isdigit((unsigned char)p[1]))
|
meillo@14
|
187 stop = strtol(p + 1, &p, 10);
|
meillo@14
|
188 if (*p == '-') {
|
meillo@14
|
189 ++p;
|
meillo@14
|
190 if (!autostop || autostop > stop)
|
meillo@14
|
191 autostop = stop;
|
meillo@14
|
192 }
|
meillo@14
|
193 }
|
meillo@14
|
194 if (*p)
|
meillo@14
|
195 errx(1, "[-bcf] list: illegal list value");
|
meillo@14
|
196 if (!stop || !start)
|
meillo@14
|
197 errx(1, "[-bcf] list: values may not include zero");
|
meillo@14
|
198 if (maxval < stop) {
|
meillo@14
|
199 maxval = stop;
|
meillo@14
|
200 needpos(maxval + 1);
|
meillo@14
|
201 }
|
meillo@14
|
202 for (pos = positions + start; start++ <= stop; *pos++ = 1);
|
meillo@14
|
203 }
|
meillo@14
|
204
|
meillo@14
|
205 /* overlapping ranges */
|
meillo@14
|
206 if (autostop && maxval > autostop) {
|
meillo@14
|
207 maxval = autostop;
|
meillo@14
|
208 needpos(maxval + 1);
|
meillo@14
|
209 }
|
meillo@14
|
210
|
meillo@14
|
211 /* set autostart */
|
meillo@14
|
212 if (autostart)
|
meillo@14
|
213 memset(positions + 1, '1', autostart);
|
meillo@14
|
214 }
|
meillo@14
|
215
|
meillo@14
|
216 static void
|
meillo@14
|
217 needpos(size_t n)
|
meillo@14
|
218 {
|
meillo@14
|
219 static size_t npos;
|
meillo@14
|
220 size_t oldnpos;
|
meillo@14
|
221
|
meillo@14
|
222 /* Grow the positions array to at least the specified size. */
|
meillo@14
|
223 if (n > npos) {
|
meillo@14
|
224 oldnpos = npos;
|
meillo@14
|
225 if (npos == 0)
|
meillo@14
|
226 npos = n;
|
meillo@14
|
227 while (n > npos)
|
meillo@14
|
228 npos *= 2;
|
meillo@14
|
229 if ((positions = realloc(positions, npos)) == NULL)
|
meillo@14
|
230 err(1, "realloc");
|
meillo@14
|
231 memset((char *)positions + oldnpos, 0, npos - oldnpos);
|
meillo@14
|
232 }
|
meillo@14
|
233 }
|
meillo@14
|
234
|
meillo@14
|
235 static int
|
meillo@14
|
236 b_cut(FILE *fp, const char *fname __unused)
|
meillo@14
|
237 {
|
meillo@14
|
238 int ch, col;
|
meillo@14
|
239 char *pos;
|
meillo@14
|
240
|
meillo@14
|
241 ch = 0;
|
meillo@14
|
242 for (;;) {
|
meillo@14
|
243 pos = positions + 1;
|
meillo@14
|
244 for (col = maxval; col; --col) {
|
meillo@14
|
245 if ((ch = getc(fp)) == EOF)
|
meillo@14
|
246 return (0);
|
meillo@14
|
247 if (ch == '\n')
|
meillo@14
|
248 break;
|
meillo@14
|
249 if (*pos++)
|
meillo@14
|
250 (void)putchar(ch);
|
meillo@14
|
251 }
|
meillo@14
|
252 if (ch != '\n') {
|
meillo@14
|
253 if (autostop)
|
meillo@14
|
254 while ((ch = getc(fp)) != EOF && ch != '\n')
|
meillo@14
|
255 (void)putchar(ch);
|
meillo@14
|
256 else
|
meillo@14
|
257 while ((ch = getc(fp)) != EOF && ch != '\n');
|
meillo@14
|
258 }
|
meillo@14
|
259 (void)putchar('\n');
|
meillo@14
|
260 }
|
meillo@14
|
261 return (0);
|
meillo@14
|
262 }
|
meillo@14
|
263
|
meillo@14
|
264 /*
|
meillo@14
|
265 * Cut based on byte positions, taking care not to split multibyte characters.
|
meillo@14
|
266 * Although this function also handles the case where -n is not specified,
|
meillo@14
|
267 * b_cut() ought to be much faster.
|
meillo@14
|
268 */
|
meillo@14
|
269 static int
|
meillo@14
|
270 b_n_cut(FILE *fp, const char *fname)
|
meillo@14
|
271 {
|
meillo@14
|
272 size_t col, i, lbuflen;
|
meillo@14
|
273 char *lbuf;
|
meillo@14
|
274 int canwrite, clen, warned;
|
meillo@14
|
275 mbstate_t mbs;
|
meillo@14
|
276
|
meillo@14
|
277 memset(&mbs, 0, sizeof(mbs));
|
meillo@14
|
278 warned = 0;
|
meillo@14
|
279 while ((lbuf = fgetln(fp, &lbuflen)) != NULL) {
|
meillo@14
|
280 for (col = 0; lbuflen > 0; col += clen) {
|
meillo@14
|
281 if ((clen = mbrlen(lbuf, lbuflen, &mbs)) < 0) {
|
meillo@14
|
282 if (!warned) {
|
meillo@14
|
283 warn("%s", fname);
|
meillo@14
|
284 warned = 1;
|
meillo@14
|
285 }
|
meillo@14
|
286 memset(&mbs, 0, sizeof(mbs));
|
meillo@14
|
287 clen = 1;
|
meillo@14
|
288 }
|
meillo@14
|
289 if (clen == 0 || *lbuf == '\n')
|
meillo@14
|
290 break;
|
meillo@14
|
291 if (col < maxval && !positions[1 + col]) {
|
meillo@14
|
292 /*
|
meillo@14
|
293 * Print the character if (1) after an initial
|
meillo@14
|
294 * segment of un-selected bytes, the rest of
|
meillo@14
|
295 * it is selected, and (2) the last byte is
|
meillo@14
|
296 * selected.
|
meillo@14
|
297 */
|
meillo@14
|
298 i = col;
|
meillo@14
|
299 while (i < col + clen && i < maxval &&
|
meillo@14
|
300 !positions[1 + i])
|
meillo@14
|
301 i++;
|
meillo@14
|
302 canwrite = i < col + clen;
|
meillo@14
|
303 for (; i < col + clen && i < maxval; i++)
|
meillo@14
|
304 canwrite &= positions[1 + i];
|
meillo@14
|
305 if (canwrite)
|
meillo@14
|
306 fwrite(lbuf, 1, clen, stdout);
|
meillo@14
|
307 } else {
|
meillo@14
|
308 /*
|
meillo@14
|
309 * Print the character if all of it has
|
meillo@14
|
310 * been selected.
|
meillo@14
|
311 */
|
meillo@14
|
312 canwrite = 1;
|
meillo@14
|
313 for (i = col; i < col + clen; i++)
|
meillo@14
|
314 if ((i >= maxval && !autostop) ||
|
meillo@14
|
315 (i < maxval && !positions[1 + i])) {
|
meillo@14
|
316 canwrite = 0;
|
meillo@14
|
317 break;
|
meillo@14
|
318 }
|
meillo@14
|
319 if (canwrite)
|
meillo@14
|
320 fwrite(lbuf, 1, clen, stdout);
|
meillo@14
|
321 }
|
meillo@14
|
322 lbuf += clen;
|
meillo@14
|
323 lbuflen -= clen;
|
meillo@14
|
324 }
|
meillo@14
|
325 if (lbuflen > 0)
|
meillo@14
|
326 putchar('\n');
|
meillo@14
|
327 }
|
meillo@14
|
328 return (warned);
|
meillo@14
|
329 }
|
meillo@14
|
330
|
meillo@14
|
331 static int
|
meillo@14
|
332 c_cut(FILE *fp, const char *fname)
|
meillo@14
|
333 {
|
meillo@14
|
334 wint_t ch;
|
meillo@14
|
335 int col;
|
meillo@14
|
336 char *pos;
|
meillo@14
|
337
|
meillo@14
|
338 ch = 0;
|
meillo@14
|
339 for (;;) {
|
meillo@14
|
340 pos = positions + 1;
|
meillo@14
|
341 for (col = maxval; col; --col) {
|
meillo@14
|
342 if ((ch = getwc(fp)) == WEOF)
|
meillo@14
|
343 goto out;
|
meillo@14
|
344 if (ch == '\n')
|
meillo@14
|
345 break;
|
meillo@14
|
346 if (*pos++)
|
meillo@14
|
347 (void)putwchar(ch);
|
meillo@14
|
348 }
|
meillo@14
|
349 if (ch != '\n') {
|
meillo@14
|
350 if (autostop)
|
meillo@14
|
351 while ((ch = getwc(fp)) != WEOF && ch != '\n')
|
meillo@14
|
352 (void)putwchar(ch);
|
meillo@14
|
353 else
|
meillo@14
|
354 while ((ch = getwc(fp)) != WEOF && ch != '\n');
|
meillo@14
|
355 }
|
meillo@14
|
356 (void)putwchar('\n');
|
meillo@14
|
357 }
|
meillo@14
|
358 out:
|
meillo@14
|
359 if (ferror(fp)) {
|
meillo@14
|
360 warn("%s", fname);
|
meillo@14
|
361 return (1);
|
meillo@14
|
362 }
|
meillo@14
|
363 return (0);
|
meillo@14
|
364 }
|
meillo@14
|
365
|
meillo@14
|
366 static int
|
meillo@14
|
367 is_delim(wchar_t ch)
|
meillo@14
|
368 {
|
meillo@14
|
369 if (wflag) {
|
meillo@14
|
370 if (ch == ' ' || ch == '\t')
|
meillo@14
|
371 return 1;
|
meillo@14
|
372 } else {
|
meillo@14
|
373 if (ch == dchar)
|
meillo@14
|
374 return 1;
|
meillo@14
|
375 }
|
meillo@14
|
376 return 0;
|
meillo@14
|
377 }
|
meillo@14
|
378
|
meillo@14
|
379 static int
|
meillo@14
|
380 f_cut(FILE *fp, const char *fname)
|
meillo@14
|
381 {
|
meillo@14
|
382 wchar_t ch;
|
meillo@14
|
383 int field, i, isdelim;
|
meillo@14
|
384 char *pos, *p;
|
meillo@14
|
385 int output;
|
meillo@14
|
386 char *lbuf, *mlbuf;
|
meillo@14
|
387 size_t clen, lbuflen, reallen;
|
meillo@14
|
388
|
meillo@14
|
389 mlbuf = NULL;
|
meillo@14
|
390 while ((lbuf = fgetln(fp, &lbuflen)) != NULL) {
|
meillo@14
|
391 reallen = lbuflen;
|
meillo@14
|
392 /* Assert EOL has a newline. */
|
meillo@14
|
393 if (*(lbuf + lbuflen - 1) != '\n') {
|
meillo@14
|
394 /* Can't have > 1 line with no trailing newline. */
|
meillo@14
|
395 mlbuf = malloc(lbuflen + 1);
|
meillo@14
|
396 if (mlbuf == NULL)
|
meillo@14
|
397 err(1, "malloc");
|
meillo@14
|
398 memcpy(mlbuf, lbuf, lbuflen);
|
meillo@14
|
399 *(mlbuf + lbuflen) = '\n';
|
meillo@14
|
400 lbuf = mlbuf;
|
meillo@14
|
401 reallen++;
|
meillo@14
|
402 }
|
meillo@14
|
403 output = 0;
|
meillo@14
|
404 for (isdelim = 0, p = lbuf;; p += clen) {
|
meillo@14
|
405 clen = mbrtowc(&ch, p, lbuf + reallen - p, NULL);
|
meillo@14
|
406 if (clen == (size_t)-1 || clen == (size_t)-2) {
|
meillo@14
|
407 warnc(EILSEQ, "%s", fname);
|
meillo@14
|
408 free(mlbuf);
|
meillo@14
|
409 return (1);
|
meillo@14
|
410 }
|
meillo@14
|
411 if (clen == 0)
|
meillo@14
|
412 clen = 1;
|
meillo@14
|
413 /* this should work if newline is delimiter */
|
meillo@14
|
414 if (is_delim(ch))
|
meillo@14
|
415 isdelim = 1;
|
meillo@14
|
416 if (ch == '\n') {
|
meillo@14
|
417 if (!isdelim && !sflag)
|
meillo@14
|
418 (void)fwrite(lbuf, lbuflen, 1, stdout);
|
meillo@14
|
419 break;
|
meillo@14
|
420 }
|
meillo@14
|
421 }
|
meillo@14
|
422 if (!isdelim)
|
meillo@14
|
423 continue;
|
meillo@14
|
424
|
meillo@14
|
425 pos = positions + 1;
|
meillo@14
|
426 for (field = maxval, p = lbuf; field; --field, ++pos) {
|
meillo@14
|
427 if (*pos && output++)
|
meillo@14
|
428 for (i = 0; dcharmb[i] != '\0'; i++)
|
meillo@14
|
429 putchar(dcharmb[i]);
|
meillo@14
|
430 for (;;) {
|
meillo@14
|
431 clen = mbrtowc(&ch, p, lbuf + reallen - p,
|
meillo@14
|
432 NULL);
|
meillo@14
|
433 if (clen == (size_t)-1 || clen == (size_t)-2) {
|
meillo@14
|
434 warnc(EILSEQ, "%s", fname);
|
meillo@14
|
435 free(mlbuf);
|
meillo@14
|
436 return (1);
|
meillo@14
|
437 }
|
meillo@14
|
438 if (clen == 0)
|
meillo@14
|
439 clen = 1;
|
meillo@14
|
440 p += clen;
|
meillo@14
|
441 if (ch == '\n' || is_delim(ch)) {
|
meillo@14
|
442 /* compress whitespace */
|
meillo@14
|
443 if (wflag && ch != '\n')
|
meillo@14
|
444 while (is_delim(*p))
|
meillo@14
|
445 p++;
|
meillo@14
|
446 break;
|
meillo@14
|
447 }
|
meillo@14
|
448 if (*pos)
|
meillo@14
|
449 for (i = 0; i < (int)clen; i++)
|
meillo@14
|
450 putchar(p[i - clen]);
|
meillo@14
|
451 }
|
meillo@14
|
452 if (ch == '\n')
|
meillo@14
|
453 break;
|
meillo@14
|
454 }
|
meillo@14
|
455 if (ch != '\n') {
|
meillo@14
|
456 if (autostop) {
|
meillo@14
|
457 if (output)
|
meillo@14
|
458 for (i = 0; dcharmb[i] != '\0'; i++)
|
meillo@14
|
459 putchar(dcharmb[i]);
|
meillo@14
|
460 for (; (ch = *p) != '\n'; ++p)
|
meillo@14
|
461 (void)putchar(ch);
|
meillo@14
|
462 } else
|
meillo@14
|
463 for (; (ch = *p) != '\n'; ++p);
|
meillo@14
|
464 }
|
meillo@14
|
465 (void)putchar('\n');
|
meillo@14
|
466 }
|
meillo@14
|
467 free(mlbuf);
|
meillo@14
|
468 return (0);
|
meillo@14
|
469 }
|
meillo@14
|
470
|
meillo@14
|
471 static void
|
meillo@14
|
472 usage(void)
|
meillo@14
|
473 {
|
meillo@14
|
474 (void)fprintf(stderr, "%s\n%s\n%s\n",
|
meillo@14
|
475 "usage: cut -b list [-n] [file ...]",
|
meillo@14
|
476 " cut -c list [file ...]",
|
meillo@14
|
477 " cut -f list [-s] [-w | -d delim] [file ...]");
|
meillo@14
|
478 exit(1);
|
meillo@14
|
479 }
|