2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Adam S. Moskowitz of Menlo Consulting and Marciano Pitargue.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 static const char copyright
[] =
39 "@(#) Copyright (c) 1989, 1993\n\
40 The Regents of the University of California. All rights reserved.\n";
44 static const char sccsid
[] = "@(#)cut.c 8.3 (Berkeley) 5/4/95";
65 #include "bashgetopt.h"
72 #if !defined (_POSIX2_LINE_MAX)
73 # define _POSIX2_LINE_MAX 2048
82 static int autostart
, autostop
, maxval
;
83 static char positions
[_POSIX2_LINE_MAX
+ 1];
85 static int c_cut
__P((FILE *, char *));
86 static int f_cut
__P((FILE *, char *));
87 static int get_list
__P((char *));
88 static char *_cut_strsep
__P((char **, const char *));
95 int (*fcn
) __P((FILE *, char *)) = NULL
;
99 dchar
= '\t'; /* default delimiter is \t */
101 /* Since we don't support multi-byte characters, the -c and -b
102 options are equivalent, and the -n option is meaningless. */
103 reset_internal_getopt ();
104 while ((ch
= internal_getopt (list
, "b:c:d:f:sn")) != -1)
109 if (get_list(list_optarg
) < 0)
110 return (EXECUTION_FAILURE
);
114 dchar
= *list_optarg
;
119 if (get_list(list_optarg
) < 0)
120 return (EXECUTION_FAILURE
);
141 } else if (!cflag
|| dflag
|| sflag
) {
148 fp
= fopen(list
->word
->word
, "r");
150 builtin_error("%s", list
->word
->word
);
151 return (EXECUTION_FAILURE
);
153 ch
= (*fcn
)(fp
, list
->word
->word
);
156 return (EXECUTION_FAILURE
);
160 ch
= (*fcn
)(stdin
, "stdin");
162 return (EXECUTION_FAILURE
);
165 return (EXECUTION_SUCCESS
);
172 int setautostart
, start
, stop
;
177 * set a byte in the positions array to indicate if a field or
178 * column is to be selected; use +1, it's 1-based, not 0-based.
179 * This parser is less restrictive than the Draft 9 POSIX spec.
180 * POSIX doesn't allow lists that aren't in increasing order or
181 * overlapping lists. We also handle "-3-5" although there's no
184 for (; (p
= _cut_strsep(&list
, ", \t")) != NULL
;) {
185 setautostart
= start
= stop
= 0;
190 if (isdigit((unsigned char)*p
)) {
191 start
= stop
= strtol(p
, &p
, 10);
192 if (setautostart
&& start
> autostart
)
196 if (isdigit((unsigned char)p
[1]))
197 stop
= strtol(p
+ 1, &p
, 10);
200 if (!autostop
|| autostop
> stop
)
205 builtin_error("[-cf] list: illegal list value");
208 if (!stop
|| !start
) {
209 builtin_error("[-cf] list: values may not include zero");
212 if (stop
> _POSIX2_LINE_MAX
) {
213 builtin_error("[-cf] list: %d too large (max %d)",
214 stop
, _POSIX2_LINE_MAX
);
219 for (pos
= positions
+ start
; start
++ <= stop
; *pos
++ = 1);
222 /* overlapping ranges */
223 if (autostop
&& maxval
> autostop
)
228 memset(positions
+ 1, '1', autostart
);
245 for (col
= maxval
; col
; --col
) {
246 if ((ch
= getc(fp
)) == EOF
)
255 while ((ch
= getc(fp
)) != EOF
&& ch
!= '\n')
258 while ((ch
= getc(fp
)) != EOF
&& ch
!= '\n');
270 int ch
, field
, isdelim
;
273 char lbuf
[_POSIX2_LINE_MAX
+ 1];
275 for (sep
= dchar
; fgets(lbuf
, sizeof(lbuf
), fp
);) {
277 for (isdelim
= 0, p
= lbuf
;; ++p
) {
279 builtin_error("%s: line too long.", fname
);
282 /* this should work if newline is delimiter */
286 if (!isdelim
&& !sflag
)
287 (void)printf("%s", lbuf
);
295 for (field
= maxval
, p
= lbuf
; field
; --field
, ++pos
) {
299 while ((ch
= *p
++) != '\n' && ch
!= sep
)
302 while ((ch
= *p
++) != '\n' && ch
!= sep
)
312 for (; (ch
= *p
) != '\n'; ++p
)
315 for (; (ch
= *p
) != '\n'; ++p
);
323 * Get next token from string *stringp, where tokens are possibly-empty
324 * strings separated by characters from delim.
326 * Writes NULs into the string at *stringp to end tokens.
327 * delim need not remain constant from call to call.
328 * On return, *stringp points past the last NUL written (if there might
329 * be further tokens), or is NULL (if there are definitely no more tokens).
331 * If *stringp is NULL, strsep returns NULL.
334 _cut_strsep(stringp
, delim
)
335 register char **stringp
;
336 register const char *delim
;
339 register const char *spanp
;
343 if ((s
= *stringp
) == NULL
)
349 if ((sc
= *spanp
++) == c
) {
362 static char *cut_doc
[] = {
363 "Select portions of lines.",
365 "Select portions of each line (as specified by LIST) from each FILE",
366 "(by default, the standard input), and write them to the standard output.",
367 "Items specified by LIST are either column positions or fields delimited",
368 "by a special character. Column numbering starts at 1.",
372 struct builtin cut_struct
= {
377 "cut -b list [-n] [file ...] OR cut -c list [file ...] OR cut -f list [-s] [-d delim] [file ...]",