Mercurial > docs > cut
comparison code/cut.c__4.3bsd-reno.1990-06-25 @ 14:21ad1c1548c4
Code ausgewaehlter Implementierungen eingefuegt
Das Datum entspricht dem Dateiaenderungsdatum.
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Tue, 12 May 2015 06:46:59 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
13:bf5e41260f89 | 14:21ad1c1548c4 |
---|---|
1 /* | |
2 * Copyright (c) 1989 The Regents of the University of California. | |
3 * All rights reserved. | |
4 * | |
5 * This code is derived from software contributed to Berkeley by | |
6 * Adam S. Moskowitz of Menlo Consulting and Marciano Pitargue. | |
7 * | |
8 * Redistribution and use in source and binary forms are permitted provided | |
9 * that: (1) source distributions retain this entire copyright notice and | |
10 * comment, and (2) distributions including binaries display the following | |
11 * acknowledgement: ``This product includes software developed by the | |
12 * University of California, Berkeley and its contributors'' in the | |
13 * documentation or other materials provided with the distribution and in | |
14 * all advertising materials mentioning features or use of this software. | |
15 * Neither the name of the University nor the names of its contributors may | |
16 * be used to endorse or promote products derived from this software without | |
17 * specific prior written permission. | |
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED | |
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF | |
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
21 */ | |
22 | |
23 #ifndef lint | |
24 char copyright[] = | |
25 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ | |
26 All rights reserved.\n"; | |
27 #endif /* not lint */ | |
28 | |
29 #ifndef lint | |
30 static char sccsid[] = "@(#)cut.c 5.3 (Berkeley) 6/24/90"; | |
31 #endif /* not lint */ | |
32 | |
33 #include <limits.h> | |
34 #include <stdio.h> | |
35 #include <ctype.h> | |
36 | |
37 int cflag; | |
38 char dchar; | |
39 int dflag; | |
40 int fflag; | |
41 int sflag; | |
42 | |
43 main(argc, argv) | |
44 int argc; | |
45 char **argv; | |
46 { | |
47 extern char *optarg; | |
48 extern int errno, optind; | |
49 FILE *fp; | |
50 int ch, (*fcn)(), c_cut(), f_cut(); | |
51 char *strerror(); | |
52 | |
53 dchar = '\t'; /* default delimiter is \t */ | |
54 | |
55 while ((ch = getopt(argc, argv, "c:d:f:s")) != EOF) | |
56 switch(ch) { | |
57 case 'c': | |
58 fcn = c_cut; | |
59 get_list(optarg); | |
60 cflag = 1; | |
61 break; | |
62 case 'd': | |
63 dchar = *optarg; | |
64 dflag = 1; | |
65 break; | |
66 case 'f': | |
67 get_list(optarg); | |
68 fcn = f_cut; | |
69 fflag = 1; | |
70 break; | |
71 case 's': | |
72 sflag = 1; | |
73 break; | |
74 case '?': | |
75 default: | |
76 usage(); | |
77 } | |
78 argc -= optind; | |
79 argv += optind; | |
80 | |
81 if (fflag) { | |
82 if (cflag) | |
83 usage(); | |
84 } else if (!cflag || dflag || sflag) | |
85 usage(); | |
86 | |
87 if (*argv) | |
88 for (; *argv; ++argv) { | |
89 if (!(fp = fopen(*argv, "r"))) { | |
90 (void)fprintf(stderr, | |
91 "cut: %s: %s\n", *argv, strerror(errno)); | |
92 exit(1); | |
93 } | |
94 fcn(fp, *argv); | |
95 } | |
96 else | |
97 fcn(stdin, "stdin"); | |
98 exit(0); | |
99 } | |
100 | |
101 int autostart, autostop, maxval; | |
102 | |
103 char positions[_BSD_LINE_MAX + 1]; | |
104 | |
105 get_list(list) | |
106 char *list; | |
107 { | |
108 register char *pos; | |
109 register int setautostart, start, stop; | |
110 char *p, *strtok(); | |
111 | |
112 /* | |
113 * set a byte in the positions array to indicate if a field or | |
114 * column is to be selected; use +1, it's 1-based, not 0-based. | |
115 * This parser is less restrictive than the Draft 9 POSIX spec. | |
116 * POSIX doesn't allow lists that aren't in increasing order or | |
117 * overlapping lists. We also handle "-3-5" although there's no | |
118 * real reason too. | |
119 */ | |
120 for (; p = strtok(list, ", \t"); list = NULL) { | |
121 setautostart = start = stop = 0; | |
122 if (*p == '-') { | |
123 ++p; | |
124 setautostart = 1; | |
125 } | |
126 if (isdigit(*p)) { | |
127 start = stop = strtol(p, &p, 10); | |
128 if (setautostart && start > autostart) | |
129 autostart = start; | |
130 } | |
131 if (*p == '-') { | |
132 if (isdigit(p[1])) | |
133 stop = strtol(p + 1, &p, 10); | |
134 if (*p == '-') { | |
135 ++p; | |
136 if (!autostop || autostop > stop) | |
137 autostop = stop; | |
138 } | |
139 } | |
140 if (*p) | |
141 badlist("illegal list value"); | |
142 if (!stop || !start) | |
143 badlist("values may not include zero"); | |
144 if (stop > _BSD_LINE_MAX) { | |
145 /* positions used rather than allocate a new buffer */ | |
146 (void)sprintf(positions, "%d too large (max %d)", | |
147 stop, _BSD_LINE_MAX); | |
148 badlist(positions); | |
149 } | |
150 if (maxval < stop) | |
151 maxval = stop; | |
152 for (pos = positions + start; start++ <= stop; *pos++ = 1); | |
153 } | |
154 | |
155 /* overlapping ranges */ | |
156 if (autostop && maxval > autostop) | |
157 maxval = autostop; | |
158 | |
159 /* set autostart */ | |
160 if (autostart) | |
161 memset(positions + 1, '1', autostart); | |
162 } | |
163 | |
164 /* ARGSUSED */ | |
165 c_cut(fp, fname) | |
166 FILE *fp; | |
167 char *fname; | |
168 { | |
169 register int ch, col; | |
170 register char *pos; | |
171 | |
172 for (;;) { | |
173 pos = positions + 1; | |
174 for (col = maxval; col; --col) { | |
175 if ((ch = getc(fp)) == EOF) | |
176 return; | |
177 if (ch == '\n') | |
178 break; | |
179 if (*pos++) | |
180 putchar(ch); | |
181 } | |
182 if (ch != '\n') | |
183 if (autostop) | |
184 while ((ch = getc(fp)) != EOF && ch != '\n') | |
185 putchar(ch); | |
186 else | |
187 while ((ch = getc(fp)) != EOF && ch != '\n'); | |
188 putchar('\n'); | |
189 } | |
190 } | |
191 | |
192 f_cut(fp, fname) | |
193 FILE *fp; | |
194 char *fname; | |
195 { | |
196 register int ch, field, isdelim; | |
197 register char *pos, *p, sep; | |
198 int output; | |
199 char lbuf[_BSD_LINE_MAX + 1]; | |
200 | |
201 for (sep = dchar, output = 0; fgets(lbuf, sizeof(lbuf), fp);) { | |
202 for (isdelim = 0, p = lbuf;; ++p) { | |
203 if (!(ch = *p)) { | |
204 (void)fprintf(stderr, | |
205 "cut: %s: line too long.\n", fname); | |
206 exit(1); | |
207 } | |
208 /* this should work if newline is delimiter */ | |
209 if (ch == sep) | |
210 isdelim = 1; | |
211 if (ch == '\n') { | |
212 if (!isdelim && !sflag) | |
213 (void)printf("%s", lbuf); | |
214 break; | |
215 } | |
216 } | |
217 if (!isdelim) | |
218 continue; | |
219 | |
220 pos = positions + 1; | |
221 for (field = maxval, p = lbuf; field; --field, ++pos) { | |
222 if (*pos) { | |
223 if (output++) | |
224 putchar(sep); | |
225 while ((ch = *p++) != '\n' && ch != sep) | |
226 putchar(ch); | |
227 } else | |
228 while ((ch = *p++) != '\n' && ch != sep); | |
229 if (ch == '\n') | |
230 break; | |
231 } | |
232 if (ch != '\n') | |
233 if (autostop) { | |
234 if (output) | |
235 putchar(sep); | |
236 for (; (ch = *p) != '\n'; ++p) | |
237 putchar(ch); | |
238 } else | |
239 for (; (ch = *p) != '\n'; ++p); | |
240 putchar('\n'); | |
241 } | |
242 } | |
243 | |
244 badlist(msg) | |
245 char *msg; | |
246 { | |
247 (void)fprintf(stderr, "cut: [-cf] list: %s.\n", msg); | |
248 exit(1); | |
249 } | |
250 | |
251 usage() | |
252 { | |
253 (void)fprintf(stderr, | |
254 "usage:\tcut -c list [file1 ...]\n\tcut -f list [-s] [-d delim] [file ...]\n"); | |
255 exit(1); | |
256 } |