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"
71 #if !defined (_POSIX2_LINE_MAX)
72 # define _POSIX2_LINE_MAX 2048
81 static int autostart
, autostop
, maxval
;
82 static char positions
[_POSIX2_LINE_MAX
+ 1];
84 static int c_cut
__P((FILE *, char *));
85 static int f_cut
__P((FILE *, char *));
86 static int get_list
__P((char *));
87 static char *_cut_strsep
__P((char **, const char *));
94 int (*fcn
) __P((FILE *, char *)) = NULL
;
98 dchar
= '\t'; /* default delimiter is \t */
100 /* Since we don't support multi-byte characters, the -c and -b
101 options are equivalent, and the -n option is meaningless. */
102 reset_internal_getopt ();
103 while ((ch
= internal_getopt (list
, "b:c:d:f:sn")) != -1)
108 if (get_list(list_optarg
) < 0)
109 return (EXECUTION_FAILURE
);
113 dchar
= *list_optarg
;
118 if (get_list(list_optarg
) < 0)
119 return (EXECUTION_FAILURE
);
140 } else if (!cflag
|| dflag
|| sflag
) {
147 fp
= fopen(list
->word
->word
, "r");
149 builtin_error("%s", list
->word
->word
);
150 return (EXECUTION_FAILURE
);
152 ch
= (*fcn
)(fp
, list
->word
->word
);
155 return (EXECUTION_FAILURE
);
159 ch
= (*fcn
)(stdin
, "stdin");
161 return (EXECUTION_FAILURE
);
164 return (EXECUTION_SUCCESS
);
171 int setautostart
, start
, stop
;
176 * set a byte in the positions array to indicate if a field or
177 * column is to be selected; use +1, it's 1-based, not 0-based.
178 * This parser is less restrictive than the Draft 9 POSIX spec.
179 * POSIX doesn't allow lists that aren't in increasing order or
180 * overlapping lists. We also handle "-3-5" although there's no
183 for (; (p
= _cut_strsep(&list
, ", \t")) != NULL
;) {
184 setautostart
= start
= stop
= 0;
189 if (isdigit((unsigned char)*p
)) {
190 start
= stop
= strtol(p
, &p
, 10);
191 if (setautostart
&& start
> autostart
)
195 if (isdigit((unsigned char)p
[1]))
196 stop
= strtol(p
+ 1, &p
, 10);
199 if (!autostop
|| autostop
> stop
)
204 builtin_error("[-cf] list: illegal list value");
207 if (!stop
|| !start
) {
208 builtin_error("[-cf] list: values may not include zero");
211 if (stop
> _POSIX2_LINE_MAX
) {
212 builtin_error("[-cf] list: %d too large (max %d)",
213 stop
, _POSIX2_LINE_MAX
);
218 for (pos
= positions
+ start
; start
++ <= stop
; *pos
++ = 1);
221 /* overlapping ranges */
222 if (autostop
&& maxval
> autostop
)
227 memset(positions
+ 1, '1', autostart
);
244 for (col
= maxval
; col
; --col
) {
245 if ((ch
= getc(fp
)) == EOF
)
254 while ((ch
= getc(fp
)) != EOF
&& ch
!= '\n')
257 while ((ch
= getc(fp
)) != EOF
&& ch
!= '\n');
269 int ch
, field
, isdelim
;
272 char lbuf
[_POSIX2_LINE_MAX
+ 1];
274 for (sep
= dchar
; fgets(lbuf
, sizeof(lbuf
), fp
);) {
276 for (isdelim
= 0, p
= lbuf
;; ++p
) {
278 builtin_error("%s: line too long.", fname
);
281 /* this should work if newline is delimiter */
285 if (!isdelim
&& !sflag
)
286 (void)printf("%s", lbuf
);
294 for (field
= maxval
, p
= lbuf
; field
; --field
, ++pos
) {
298 while ((ch
= *p
++) != '\n' && ch
!= sep
)
301 while ((ch
= *p
++) != '\n' && ch
!= sep
)
311 for (; (ch
= *p
) != '\n'; ++p
)
314 for (; (ch
= *p
) != '\n'; ++p
);
322 * Get next token from string *stringp, where tokens are possibly-empty
323 * strings separated by characters from delim.
325 * Writes NULs into the string at *stringp to end tokens.
326 * delim need not remain constant from call to call.
327 * On return, *stringp points past the last NUL written (if there might
328 * be further tokens), or is NULL (if there are definitely no more tokens).
330 * If *stringp is NULL, strsep returns NULL.
333 _cut_strsep(stringp
, delim
)
334 register char **stringp
;
335 register const char *delim
;
338 register const char *spanp
;
342 if ((s
= *stringp
) == NULL
)
348 if ((sc
= *spanp
++) == c
) {
361 static char *cut_doc
[] = {
362 "Select portions of each line (as specified by LIST) from each FILE",
363 "(by default, the standard input), and write them to the standard output.",
364 "Items specified by LIST are either column positions or fields delimited",
365 "by a special character. Column numbering starts at 1.",
369 struct builtin cut_struct
= {
374 "cut -b list [-n] [file ...] OR cut -c list [file ...] OR cut -f list [-s] [-d delim] [file ...]",