aboutsummaryrefslogtreecommitdiff
path: root/sed.c
diff options
context:
space:
mode:
authorErik Andersen <andersen@codepoet.org>2000-02-08 19:58:47 +0000
committerErik Andersen <andersen@codepoet.org>2000-02-08 19:58:47 +0000
commite49d5ecbbe51718fa925b6890a735e5937cc2aa2 (patch)
treec90bda10731ad9333ce3b404f993354c9fc104b8 /sed.c
parentc0bf817bbc5c7867fbe8fb76d5c39f8ee802692f (diff)
downloadbusybox-w32-e49d5ecbbe51718fa925b6890a735e5937cc2aa2.tar.gz
busybox-w32-e49d5ecbbe51718fa925b6890a735e5937cc2aa2.tar.bz2
busybox-w32-e49d5ecbbe51718fa925b6890a735e5937cc2aa2.zip
Some formatting updates (ran the code through indent)
-Erik
Diffstat (limited to 'sed.c')
-rw-r--r--sed.c522
1 files changed, 262 insertions, 260 deletions
diff --git a/sed.c b/sed.c
index 25777243d..3a7737e2f 100644
--- a/sed.c
+++ b/sed.c
@@ -1,3 +1,4 @@
1/* vi: set sw=4 ts=4: */
1/* 2/*
2 * Mini sed implementation for busybox 3 * Mini sed implementation for busybox
3 * 4 *
@@ -37,27 +38,27 @@
37#include <ctype.h> 38#include <ctype.h>
38 39
39static const char sed_usage[] = 40static const char sed_usage[] =
40 "sed [-n] -e script [file...]\n\n" 41 "sed [-n] -e script [file...]\n\n"
41 "Allowed sed scripts come in the following form:\n" 42 "Allowed sed scripts come in the following form:\n"
42 "\t'ADDR [!] COMMAND'\n\n" 43 "\t'ADDR [!] COMMAND'\n\n"
43 "\twhere address ADDR can be:\n" 44 "\twhere address ADDR can be:\n"
44 "\t NUMBER Match specified line number\n" 45 "\t NUMBER Match specified line number\n"
45 "\t $ Match last line\n" 46 "\t $ Match last line\n"
46 "\t /REGEXP/ Match specified regexp\n" 47 "\t /REGEXP/ Match specified regexp\n"
47 "\t (! inverts the meaning of the match)\n\n" 48 "\t (! inverts the meaning of the match)\n\n"
48 "\tand COMMAND can be:\n" 49 "\tand COMMAND can be:\n"
49 "\t s/regexp/replacement/[igp]\n" 50 "\t s/regexp/replacement/[igp]\n"
50 "\t which attempt to match regexp against the pattern space\n" 51 "\t which attempt to match regexp against the pattern space\n"
51 "\t and if successful replaces the matched portion with replacement.\n\n" 52 "\t and if successful replaces the matched portion with replacement.\n\n"
52 "\t aTEXT\n" 53 "\t aTEXT\n"
53 "\t which appends TEXT after the pattern space\n" 54 "\t which appends TEXT after the pattern space\n"
54 "Options:\n" 55 "Options:\n"
55 "-e\tadd the script to the commands to be executed\n" 56 "-e\tadd the script to the commands to be executed\n"
56 "-n\tsuppress automatic printing of pattern space\n\n" 57 "-n\tsuppress automatic printing of pattern space\n\n"
57#if defined BB_REGEXP 58#if defined BB_REGEXP
58 "This version of sed matches full regular expresions.\n"; 59 "This version of sed matches full regular expresions.\n";
59#else 60#else
60 "This version of sed matches strings (not full regular expresions).\n"; 61 "This version of sed matches strings (not full regular expresions).\n";
61#endif 62#endif
62 63
63/* Flags & variables */ 64/* Flags & variables */
@@ -76,276 +77,277 @@ static int negated = 0;
76 77
77static inline int at_last(FILE * fp) 78static inline int at_last(FILE * fp)
78{ 79{
79 int res = 0; 80 int res = 0;
80 81
81 if (feof(fp)) 82 if (feof(fp))
82 return 1; 83 return 1;
83 else { 84 else {
84 char ch; 85 char ch;
85 if ((ch = fgetc(fp)) == EOF) 86
86 res++; 87 if ((ch = fgetc(fp)) == EOF)
87 ungetc(ch, fp); 88 res++;
88 } 89 ungetc(ch, fp);
89 return res; 90 }
91 return res;
90} 92}
91 93
92static void do_sed_repl(FILE * fp, char *needle, char *newNeedle, 94static void do_sed_repl(FILE * fp, char *needle, char *newNeedle,
93 int ignoreCase, int printFlag, int quietFlag) 95 int ignoreCase, int printFlag, int quietFlag)
94{ 96{
95 int foundOne = FALSE; 97 int foundOne = FALSE;
96 char haystack[BUFSIZE]; 98 char haystack[BUFSIZE];
97 int line = 1, doit; 99 int line = 1, doit;
98 100
99 while (fgets(haystack, BUFSIZE - 1, fp)) { 101 while (fgets(haystack, BUFSIZE - 1, fp)) {
100 doit = 0; 102 doit = 0;
101 if (addr_pattern) { 103 if (addr_pattern) {
102 doit = !find_match(haystack, addr_pattern, FALSE); 104 doit = !find_match(haystack, addr_pattern, FALSE);
103 } else if (addr_line == NO_LINE) 105 } else if (addr_line == NO_LINE)
104 doit = 1; 106 doit = 1;
105 else if (addr_line == LAST_LINE) { 107 else if (addr_line == LAST_LINE) {
106 if (at_last(fp)) 108 if (at_last(fp))
107 doit = 1; 109 doit = 1;
108 } else { 110 } else {
109 if (line == addr_line) 111 if (line == addr_line)
110 doit = 1; 112 doit = 1;
111 } 113 }
112 if (negated) 114 if (negated)
113 doit = 1 - doit; 115 doit = 1 - doit;
114 if (doit) { 116 if (doit) {
115 foundOne = 117 foundOne =
116 replace_match(haystack, needle, newNeedle, ignoreCase); 118 replace_match(haystack, needle, newNeedle, ignoreCase);
117 119
118 if (foundOne == TRUE && printFlag == TRUE) { 120 if (foundOne == TRUE && printFlag == TRUE) {
119 fprintf(stdout, haystack); 121 fprintf(stdout, haystack);
120 } 122 }
121 } 123 }
122 124
123 if (quietFlag == FALSE) { 125 if (quietFlag == FALSE) {
124 fprintf(stdout, haystack); 126 fprintf(stdout, haystack);
125 } 127 }
126 128
127 line++; 129 line++;
128 } 130 }
129} 131}
130 132
131static void do_sed_append(FILE * fp, char *appendline, int quietFlag) 133static void do_sed_append(FILE * fp, char *appendline, int quietFlag)
132{ 134{
133 char buffer[BUFSIZE]; 135 char buffer[BUFSIZE];
134 int line = 1, doit; 136 int line = 1, doit;
135 137
136 while (fgets(buffer, BUFSIZE - 1, fp)) { 138 while (fgets(buffer, BUFSIZE - 1, fp)) {
137 doit = 0; 139 doit = 0;
138 if (addr_pattern) { 140 if (addr_pattern) {
139 doit = !find_match(buffer, addr_pattern, FALSE); 141 doit = !find_match(buffer, addr_pattern, FALSE);
140 } else if (addr_line == NO_LINE) 142 } else if (addr_line == NO_LINE)
141 doit = 1; 143 doit = 1;
142 else if (addr_line == LAST_LINE) { 144 else if (addr_line == LAST_LINE) {
143 if (at_last(fp)) 145 if (at_last(fp))
144 doit = 1; 146 doit = 1;
145 } else { 147 } else {
146 if (line == addr_line) 148 if (line == addr_line)
147 doit = 1; 149 doit = 1;
148 } 150 }
149 if (negated) 151 if (negated)
150 doit = 1 - doit; 152 doit = 1 - doit;
151 if (quietFlag == FALSE) { 153 if (quietFlag == FALSE) {
152 fprintf(stdout, buffer); 154 fprintf(stdout, buffer);
153 } 155 }
154 if (doit) { 156 if (doit) {
155 fputs(appendline, stdout); 157 fputs(appendline, stdout);
156 fputc('\n', stdout); 158 fputc('\n', stdout);
157 } 159 }
158 160
159 line++; 161 line++;
160 } 162 }
161} 163}
162 164
163extern int sed_main(int argc, char **argv) 165extern int sed_main(int argc, char **argv)
164{ 166{
165 FILE *fp; 167 FILE *fp;
166 char *needle = NULL, *newNeedle = NULL; 168 char *needle = NULL, *newNeedle = NULL;
167 char *name; 169 char *name;
168 char *cp; 170 char *cp;
169 int ignoreCase = FALSE; 171 int ignoreCase = FALSE;
170 int printFlag = FALSE; 172 int printFlag = FALSE;
171 int quietFlag = FALSE; 173 int quietFlag = FALSE;
172 int stopNow; 174 int stopNow;
173 char *line_s = NULL, saved; 175 char *line_s = NULL, saved;
174 char *appendline = NULL; 176 char *appendline = NULL;
175 char *pos; 177 char *pos;
176 sed_function sed_f = f_none; 178 sed_function sed_f = f_none;
177
178 argc--;
179 argv++;
180 if (argc < 1) {
181 usage(sed_usage);
182 }
183
184 if (**argv == '-') {
185 argc--;
186 cp = *argv++;
187 stopNow = FALSE;
188
189 while (*++cp && stopNow == FALSE) {
190 switch (*cp) {
191 case 'n':
192 quietFlag = TRUE;
193 break;
194 case 'e':
195 if (*(cp + 1) == 0 && --argc < 0) {
196 usage(sed_usage);
197 }
198 if (*++cp != 's')
199 cp = *argv++;
200
201 /* Read address if present */
202 SKIPSPACES(cp);
203 if (*cp == '$') {
204 addr_line = LAST_LINE;
205 cp++;
206 } else {
207 if (isdigit(*cp)) { /* LINE ADDRESS */
208 line_s = cp;
209 while (isdigit(*cp))
210 cp++;
211 if (cp > line_s) {
212 /* numeric line */
213 saved = *cp;
214 *cp = '\0';
215 addr_line = atoi(line_s);
216 *cp = saved;
217 }
218 } else if (*cp == '/') { /* PATTERN ADDRESS */
219 pos = addr_pattern = cp + 1;
220 pos = strchr(pos, '/');
221 if (!pos)
222 usage(sed_usage);
223 *pos = '\0';
224 cp = pos + 1;
225 }
226 }
227
228 SKIPSPACES(cp);
229 if (*cp == '!') {
230 negated++;
231 cp++;
232 }
233 179
234 /* Read command */ 180 argc--;
181 argv++;
182 if (argc < 1) {
183 usage(sed_usage);
184 }
235 185
236 SKIPSPACES(cp); 186 if (**argv == '-') {
237 switch (*cp) { 187 argc--;
238 case 's': /* REPLACE */ 188 cp = *argv++;
239 if (strlen(cp) <= 3 || *(cp + 1) != '/') 189 stopNow = FALSE;
240 break;
241 sed_f = f_replace;
242 190
243 pos = needle = cp + 2; 191 while (*++cp && stopNow == FALSE) {
192 switch (*cp) {
193 case 'n':
194 quietFlag = TRUE;
195 break;
196 case 'e':
197 if (*(cp + 1) == 0 && --argc < 0) {
198 usage(sed_usage);
199 }
200 if (*++cp != 's')
201 cp = *argv++;
202
203 /* Read address if present */
204 SKIPSPACES(cp);
205 if (*cp == '$') {
206 addr_line = LAST_LINE;
207 cp++;
208 } else {
209 if (isdigit(*cp)) { /* LINE ADDRESS */
210 line_s = cp;
211 while (isdigit(*cp))
212 cp++;
213 if (cp > line_s) {
214 /* numeric line */
215 saved = *cp;
216 *cp = '\0';
217 addr_line = atoi(line_s);
218 *cp = saved;
219 }
220 } else if (*cp == '/') { /* PATTERN ADDRESS */
221 pos = addr_pattern = cp + 1;
222 pos = strchr(pos, '/');
223 if (!pos)
224 usage(sed_usage);
225 *pos = '\0';
226 cp = pos + 1;
227 }
228 }
229
230 SKIPSPACES(cp);
231 if (*cp == '!') {
232 negated++;
233 cp++;
234 }
235
236 /* Read command */
237
238 SKIPSPACES(cp);
239 switch (*cp) {
240 case 's': /* REPLACE */
241 if (strlen(cp) <= 3 || *(cp + 1) != '/')
242 break;
243 sed_f = f_replace;
244
245 pos = needle = cp + 2;
246
247 for (;;) {
248 pos = strchr(pos, '/');
249 if (pos == NULL) {
250 usage(sed_usage);
251 }
252 if (*(pos - 1) == '\\') {
253 pos++;
254 continue;
255 }
256 break;
257 }
258 *pos = 0;
259 newNeedle = ++pos;
260 for (;;) {
261 pos = strchr(pos, '/');
262 if (pos == NULL) {
263 usage(sed_usage);
264 }
265 if (*(pos - 1) == '\\') {
266 pos++;
267 continue;
268 }
269 break;
270 }
271 *pos = 0;
272 if (pos + 2 != 0) {
273 while (*++pos) {
274 switch (*pos) {
275 case 'i':
276 ignoreCase = TRUE;
277 break;
278 case 'p':
279 printFlag = TRUE;
280 break;
281 case 'g':
282 break;
283 default:
284 usage(sed_usage);
285 }
286 }
287 }
288 cp = pos;
289 /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */
290 break;
291
292 case 'a': /* APPEND */
293 if (strlen(cp) < 2)
294 break;
295 sed_f = f_append;
296 appendline = ++cp;
297 /* fprintf(stderr, "append '%s'\n", appendline); */
298 break;
299 }
300
301 stopNow = TRUE;
302 break;
244 303
245 for (;;) { 304 default:
246 pos = strchr(pos, '/'); 305 usage(sed_usage);
247 if (pos == NULL) {
248 usage(sed_usage);
249 }
250 if (*(pos - 1) == '\\') {
251 pos++;
252 continue;
253 } 306 }
307 }
308 }
309
310 if (argc == 0) {
311 switch (sed_f) {
312 case f_none:
254 break; 313 break;
255 } 314 case f_replace:
256 *pos = 0; 315 do_sed_repl(stdin, needle, newNeedle, ignoreCase, printFlag,
257 newNeedle = ++pos; 316 quietFlag);
258 for (;;) {
259 pos = strchr(pos, '/');
260 if (pos == NULL) {
261 usage(sed_usage);
262 }
263 if (*(pos - 1) == '\\') {
264 pos++;
265 continue;
266 }
267 break; 317 break;
268 } 318 case f_append:
269 *pos = 0; 319 do_sed_append(stdin, appendline, quietFlag);
270 if (pos + 2 != 0) { 320 break;
271 while (*++pos) { 321 }
272 switch (*pos) { 322 } else {
273 case 'i': 323 while (argc-- > 0) {
274 ignoreCase = TRUE; 324 name = *argv++;
325
326 fp = fopen(name, "r");
327 if (fp == NULL) {
328 perror(name);
329 continue;
330 }
331
332 switch (sed_f) {
333 case f_none:
275 break; 334 break;
276 case 'p': 335 case f_replace:
277 printFlag = TRUE; 336 do_sed_repl(fp, needle, newNeedle, ignoreCase, printFlag,
337 quietFlag);
278 break; 338 break;
279 case 'g': 339 case f_append:
340 do_sed_append(fp, appendline, quietFlag);
280 break; 341 break;
281 default:
282 usage(sed_usage);
283 }
284 } 342 }
285 }
286 cp = pos;
287 /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */
288 break;
289 343
290 case 'a': /* APPEND */ 344 if (ferror(fp))
291 if (strlen(cp) < 2) 345 perror(name);
292 break;
293 sed_f = f_append;
294 appendline = ++cp;
295 /* fprintf(stderr, "append '%s'\n", appendline); */
296 break;
297 }
298 346
299 stopNow = TRUE; 347 fclose(fp);
300 break; 348 }
301
302 default:
303 usage(sed_usage);
304 }
305 }
306 }
307
308 if (argc == 0) {
309 switch (sed_f) {
310 case f_none:
311 break;
312 case f_replace:
313 do_sed_repl(stdin, needle, newNeedle, ignoreCase, printFlag,
314 quietFlag);
315 break;
316 case f_append:
317 do_sed_append(stdin, appendline, quietFlag);
318 break;
319 }
320 } else {
321 while (argc-- > 0) {
322 name = *argv++;
323
324 fp = fopen(name, "r");
325 if (fp == NULL) {
326 perror(name);
327 continue;
328 }
329
330 switch (sed_f) {
331 case f_none:
332 break;
333 case f_replace:
334 do_sed_repl(fp, needle, newNeedle, ignoreCase, printFlag,
335 quietFlag);
336 break;
337 case f_append:
338 do_sed_append(fp, appendline, quietFlag);
339 break;
340 }
341
342 if (ferror(fp))
343 perror(name);
344
345 fclose(fp);
346 } 349 }
347 } 350 exit(TRUE);
348 exit(TRUE);
349} 351}
350 352
351 353