diff options
author | Erik Andersen <andersen@codepoet.org> | 2000-05-12 19:41:47 +0000 |
---|---|---|
committer | Erik Andersen <andersen@codepoet.org> | 2000-05-12 19:41:47 +0000 |
commit | 7ab9c7ee52db8759d457819f5480378fa3aa97cc (patch) | |
tree | 37ef0fb8b142a4925b866c7caa5207b71b4ecae6 /coreutils/cut.c | |
parent | 3d427ac5efd249dc25dd03deb30520335f68911a (diff) | |
download | busybox-w32-7ab9c7ee52db8759d457819f5480378fa3aa97cc.tar.gz busybox-w32-7ab9c7ee52db8759d457819f5480378fa3aa97cc.tar.bz2 busybox-w32-7ab9c7ee52db8759d457819f5480378fa3aa97cc.zip |
Lots of updates. Finished implementing BB_FEATURE_TRIVIAL_HELP
which lets you compile out most of the "--help" output, saving
up to 17k.
Renamed mnc to nc.
-Erik
Diffstat (limited to 'coreutils/cut.c')
-rw-r--r-- | coreutils/cut.c | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/coreutils/cut.c b/coreutils/cut.c new file mode 100644 index 000000000..89a934e76 --- /dev/null +++ b/coreutils/cut.c | |||
@@ -0,0 +1,372 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * cut implementation for busybox | ||
4 | * | ||
5 | * Copyright (c) Michael J. Holme | ||
6 | * | ||
7 | * This version of cut is adapted from Minix cut and was modified | ||
8 | * by Erik Andersen <andersee@debian.org> to be used in busybox. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
24 | * Original copyright notice is retained at the end of this file. | ||
25 | */ | ||
26 | |||
27 | #include "internal.h" | ||
28 | #include <sys/types.h> | ||
29 | #include <ctype.h> | ||
30 | #include <string.h> | ||
31 | #include <errno.h> | ||
32 | #include <stdlib.h> | ||
33 | #include <stdio.h> | ||
34 | #define BB_DECLARE_EXTERN | ||
35 | #define bb_need_help | ||
36 | #include "messages.c" | ||
37 | |||
38 | #define MAX_FIELD 80 /* Pointers to the beginning of each field | ||
39 | * are stored in columns[], if a line holds | ||
40 | * more than MAX_FIELD columns the array | ||
41 | * boundary is exceed. But unlikely at 80 */ | ||
42 | |||
43 | #define MAX_ARGS 32 /* Maximum number of fields following -f or | ||
44 | * -c switches */ | ||
45 | int args[MAX_ARGS * 2]; | ||
46 | int num_args; | ||
47 | |||
48 | /* Lots of new defines, should easen maintainance... */ | ||
49 | #define DUMP_STDIN 0 /* define for mode: no options */ | ||
50 | #define OPTIONF 1 /* define for mode: option -f */ | ||
51 | #define OPTIONC 2 /* define for mode: option -c */ | ||
52 | #define OPTIONB 3 /* define for mode: option -b */ | ||
53 | #define NOTSET 0 /* option not selected */ | ||
54 | #define SET 1 /* option selected */ | ||
55 | |||
56 | /* Defines for the warnings */ | ||
57 | #define DELIMITER_NOT_APPLICABLE 0 | ||
58 | #define OVERRIDING_PREVIOUS_MODE 1 | ||
59 | #define OPTION_NOT_APPLICABLE 2 | ||
60 | #define UNKNOWN_OPTION 3 | ||
61 | #define FILE_NOT_READABLE 4 | ||
62 | |||
63 | /* Defines for the fatal errors */ | ||
64 | #define SYNTAX_ERROR 101 | ||
65 | #define POSITION_ERROR 102 | ||
66 | #define LINE_TO_LONG_ERROR 103 | ||
67 | #define RANGE_ERROR 104 | ||
68 | #define MAX_FIELDS_EXEEDED_ERROR 105 | ||
69 | #define MAX_ARGS_EXEEDED_ERROR 106 | ||
70 | |||
71 | |||
72 | int mode; /* 0 = dump stdin to stdout, 1=-f, 2=-c */ | ||
73 | char delim = '\t'; /* default delimiting character */ | ||
74 | FILE *fd; | ||
75 | char *name; | ||
76 | char line[BUFSIZ]; | ||
77 | int exit_status; | ||
78 | |||
79 | int cut_main(int argc, char **argv); | ||
80 | void warn(int warn_number, char *option); | ||
81 | void cuterror(int err); | ||
82 | void get_args(void); | ||
83 | void cut(void); | ||
84 | |||
85 | void warn(int warn_number, char *option) | ||
86 | { | ||
87 | static char *warn_msg[] = { | ||
88 | "%s: Option -d allowed only with -f\n", | ||
89 | "%s: -%s overrides earlier option\n", | ||
90 | "%s: -%s not allowed in current mode\n", | ||
91 | "%s: Cannot open %s\n" | ||
92 | }; | ||
93 | |||
94 | fprintf(stderr, warn_msg[warn_number], name, option); | ||
95 | exit_status = warn_number + 1; | ||
96 | |||
97 | } | ||
98 | |||
99 | void cuterror(int err) | ||
100 | { | ||
101 | static char *err_mes[] = { | ||
102 | "%s: syntax error\n", | ||
103 | "%s: position must be >0\n", | ||
104 | "%s: line longer than BUFSIZ\n", | ||
105 | "%s: range must not decrease from left to right\n", | ||
106 | "%s: MAX_FIELD exceeded\n", | ||
107 | "%s: MAX_ARGS exceeded\n" | ||
108 | }; | ||
109 | |||
110 | fprintf(stderr, err_mes[err - 101], name); | ||
111 | exit(err); | ||
112 | } | ||
113 | |||
114 | |||
115 | void get_args() | ||
116 | { | ||
117 | int i = 0; | ||
118 | int arg_ptr = 0; | ||
119 | int flag; | ||
120 | |||
121 | num_args = 0; | ||
122 | do { | ||
123 | if (num_args == MAX_ARGS) | ||
124 | cuterror(MAX_ARGS_EXEEDED_ERROR); | ||
125 | if (!isdigit(line[i]) && line[i] != '-') | ||
126 | cuterror(SYNTAX_ERROR); | ||
127 | |||
128 | args[arg_ptr] = 1; | ||
129 | args[arg_ptr + 1] = BUFSIZ; | ||
130 | flag = 1; | ||
131 | |||
132 | while (line[i] != ',' && line[i] != 0) { | ||
133 | if (isdigit(line[i])) { | ||
134 | args[arg_ptr] = 0; | ||
135 | while (isdigit(line[i])) | ||
136 | args[arg_ptr] = 10 * args[arg_ptr] + line[i++] - '0'; | ||
137 | if (!args[arg_ptr]) | ||
138 | cuterror(POSITION_ERROR); | ||
139 | arg_ptr++; | ||
140 | } | ||
141 | if (line[i] == '-') { | ||
142 | arg_ptr |= 1; | ||
143 | i++; | ||
144 | flag = 0; | ||
145 | } | ||
146 | } | ||
147 | if (flag && arg_ptr & 1) | ||
148 | args[arg_ptr] = args[arg_ptr - 1]; | ||
149 | if (args[num_args * 2] > args[num_args * 2 + 1]) | ||
150 | cuterror(RANGE_ERROR); | ||
151 | num_args++; | ||
152 | arg_ptr = num_args * 2; | ||
153 | } | ||
154 | while (line[i++]); | ||
155 | } | ||
156 | |||
157 | |||
158 | void cut() | ||
159 | { | ||
160 | int i, j, length, maxcol=0; | ||
161 | char *columns[MAX_FIELD]; | ||
162 | |||
163 | while (fgets(line, BUFSIZ, fd)) { | ||
164 | length = strlen(line) - 1; | ||
165 | *(line + length) = 0; | ||
166 | switch (mode) { | ||
167 | case DUMP_STDIN: | ||
168 | printf("%s", line); | ||
169 | break; | ||
170 | case OPTIONF: | ||
171 | columns[maxcol++] = line; | ||
172 | for (i = 0; i < length; i++) { | ||
173 | if (*(line + i) == delim) { | ||
174 | *(line + i) = 0; | ||
175 | if (maxcol == MAX_FIELD) | ||
176 | cuterror(MAX_FIELDS_EXEEDED_ERROR); | ||
177 | columns[maxcol] = line + i + 1; | ||
178 | maxcol++; | ||
179 | } | ||
180 | } | ||
181 | if (maxcol != 1) { | ||
182 | for (i = 0; i < num_args; i++) { | ||
183 | for (j = args[i * 2]; j <= args[i * 2 + 1]; j++) | ||
184 | if (j <= maxcol) { | ||
185 | printf("%s", columns[j - 1]); | ||
186 | if (i != num_args - 1 || j != args[i * 2 + 1]) | ||
187 | putchar(delim); | ||
188 | } | ||
189 | } | ||
190 | } | ||
191 | break; | ||
192 | case OPTIONC: | ||
193 | for (i = 0; i < num_args; i++) { | ||
194 | for (j = args[i * 2]; | ||
195 | j <= (args[i * 2 + 1] > | ||
196 | length ? length : args[i * 2 + 1]); j++) | ||
197 | putchar(*(line + j - 1)); | ||
198 | } | ||
199 | } | ||
200 | if (maxcol != 1) | ||
201 | putchar('\n'); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | |||
206 | int cut_main(int argc, char **argv) | ||
207 | { | ||
208 | int i = 1; | ||
209 | int numberFilenames = 0; | ||
210 | |||
211 | name = argv[0]; | ||
212 | |||
213 | if (argc == 1 || strcmp(argv[1], dash_dash_help)==0) | ||
214 | usage( "cut [OPTION]... [FILE]...\n" | ||
215 | #ifndef BB_FEATURE_TRIVIAL_HELP | ||
216 | "\nPrints selected fields from each input FILE to standard output.\n\n" | ||
217 | "Options:\n" | ||
218 | "\t-b LIST\tOutput only bytes from LIST\n" | ||
219 | "\t-c LIST\tOutput only characters from LIST\n" | ||
220 | "\t-d DELIM\tUse DELIM instead of tab as the field delimiter\n" | ||
221 | "\t-f N\tPrint only these fields\n" | ||
222 | "\t-n\tIgnored\n" | ||
223 | #endif | ||
224 | ); | ||
225 | |||
226 | while (i < argc) { | ||
227 | if (argv[i][0] == '-') { | ||
228 | switch (argv[i++][1]) { | ||
229 | case 'd': | ||
230 | if (mode == OPTIONC || mode == OPTIONB) | ||
231 | warn(DELIMITER_NOT_APPLICABLE, "d"); | ||
232 | delim = argv[i++][0]; | ||
233 | break; | ||
234 | case 'f': | ||
235 | sprintf(line, "%s", argv[i++]); | ||
236 | if (mode == OPTIONC || mode == OPTIONB) | ||
237 | warn(OVERRIDING_PREVIOUS_MODE, "f"); | ||
238 | mode = OPTIONF; | ||
239 | break; | ||
240 | case 'b': | ||
241 | sprintf(line, "%s", argv[i++]); | ||
242 | if (mode == OPTIONF || mode == OPTIONC) | ||
243 | warn(OVERRIDING_PREVIOUS_MODE, "b"); | ||
244 | mode = OPTIONB; | ||
245 | break; | ||
246 | case 'c': | ||
247 | sprintf(line, "%s", argv[i++]); | ||
248 | if (mode == OPTIONF || mode == OPTIONB) | ||
249 | warn(OVERRIDING_PREVIOUS_MODE, "c"); | ||
250 | mode = OPTIONC; | ||
251 | break; | ||
252 | case '\0': /* - means: read from stdin */ | ||
253 | numberFilenames++; | ||
254 | break; | ||
255 | case 'n': /* needed for Posix, but no effect here */ | ||
256 | if (mode != OPTIONB) | ||
257 | warn(OPTION_NOT_APPLICABLE, "n"); | ||
258 | break; | ||
259 | default: | ||
260 | warn(UNKNOWN_OPTION, &(argv[i - 1][1])); | ||
261 | } | ||
262 | } else { | ||
263 | i++; | ||
264 | numberFilenames++; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | /* Here follow the checks, if the selected options are reasonable. */ | ||
269 | if (mode == OPTIONB) /* since in Minix char := byte */ | ||
270 | mode = OPTIONC; | ||
271 | get_args(); | ||
272 | if (numberFilenames != 0) { | ||
273 | i = 1; | ||
274 | while (i < argc) { | ||
275 | if (argv[i][0] == '-') { | ||
276 | switch (argv[i][1]) { | ||
277 | case 'f': | ||
278 | case 'c': | ||
279 | case 'b': | ||
280 | case 'd': | ||
281 | i += 2; | ||
282 | break; | ||
283 | case 'n': | ||
284 | case 'i': | ||
285 | case 's': | ||
286 | i++; | ||
287 | break; | ||
288 | case '\0': | ||
289 | fd = stdin; | ||
290 | i++; | ||
291 | cut(); | ||
292 | break; | ||
293 | default: | ||
294 | i++; | ||
295 | } | ||
296 | } else { | ||
297 | if ((fd = fopen(argv[i++], "r")) == NULL) { | ||
298 | warn(FILE_NOT_READABLE, argv[i - 1]); | ||
299 | } else { | ||
300 | cut(); | ||
301 | fclose(fd); | ||
302 | } | ||
303 | } | ||
304 | } | ||
305 | } else { | ||
306 | fd = stdin; | ||
307 | cut(); | ||
308 | } | ||
309 | |||
310 | exit(exit_status); | ||
311 | } | ||
312 | |||
313 | /* cut - extract columns from a file or stdin. Author: Michael J. Holme | ||
314 | * | ||
315 | * Copyright 1989, Michael John Holme, All rights reserved. | ||
316 | * This code may be freely distributed, provided that this notice | ||
317 | * remains intact. | ||
318 | * | ||
319 | * V1.1: 6th September 1989 | ||
320 | * | ||
321 | * Bugs, criticisms, etc, | ||
322 | * c/o Mark Powell | ||
323 | * JANET sq79@uk.ac.liv | ||
324 | * ARPA sq79%liv.ac.uk@nsfnet-relay.ac.uk | ||
325 | * UUCP ...!mcvax!ukc!liv.ac.uk!sq79 | ||
326 | *------------------------------------------------------------------------- | ||
327 | * Changed for POSIX1003.2/Draft10 conformance | ||
328 | * Thomas Brupbacher (tobr@mw.lpc.ethz.ch), September 1990. | ||
329 | * Changes: | ||
330 | * - separation of error messages ( stderr) and output (stdout). | ||
331 | * - support for -b and -n (no effect, -b acts as -c) | ||
332 | * - support for -s | ||
333 | *------------------------------------------------------------------------- | ||
334 | */ | ||
335 | |||
336 | /* | ||
337 | * Copyright (c) 1987,1997, Prentice Hall | ||
338 | * All rights reserved. | ||
339 | * | ||
340 | * Redistribution and use of the MINIX operating system in source and | ||
341 | * binary forms, with or without modification, are permitted provided | ||
342 | * that the following conditions are met: | ||
343 | * | ||
344 | * Redistributions of source code must retain the above copyright | ||
345 | * notice, this list of conditions and the following disclaimer. | ||
346 | * | ||
347 | * Redistributions in binary form must reproduce the above | ||
348 | * copyright notice, this list of conditions and the following | ||
349 | * disclaimer in the documentation and/or other materials provided | ||
350 | * with the distribution. | ||
351 | * | ||
352 | * Neither the name of Prentice Hall nor the names of the software | ||
353 | * authors or contributors may be used to endorse or promote | ||
354 | * products derived from this software without specific prior | ||
355 | * written permission. | ||
356 | * | ||
357 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND | ||
358 | * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
359 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
360 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
361 | * IN NO EVENT SHALL PRENTICE HALL OR ANY AUTHORS OR CONTRIBUTORS BE | ||
362 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
363 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
364 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
365 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
366 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
367 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||
368 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
369 | * | ||
370 | */ | ||
371 | |||
372 | |||