aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-04-08 11:56:11 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-04-08 11:56:11 +0000
commit8d6395d41a4784352cbba5b61e73bfc8afec3f31 (patch)
tree9e1cae748c71f2a8e1c7b7247905f9acf42b4bf2
parentc1d95076f0b775977ff12c3a55fc78fee437ba45 (diff)
downloadbusybox-w32-8d6395d41a4784352cbba5b61e73bfc8afec3f31.tar.gz
busybox-w32-8d6395d41a4784352cbba5b61e73bfc8afec3f31.tar.bz2
busybox-w32-8d6395d41a4784352cbba5b61e73bfc8afec3f31.zip
Run through indent
-rw-r--r--editors/sed.c661
1 files changed, 360 insertions, 301 deletions
diff --git a/editors/sed.c b/editors/sed.c
index 1e2191864..a616c992c 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -47,11 +47,11 @@
47*/ 47*/
48 48
49#include <stdio.h> 49#include <stdio.h>
50#include <unistd.h> /* for getopt() */ 50#include <unistd.h> /* for getopt() */
51#include <regex.h> 51#include <regex.h>
52#include <string.h> /* for strdup() */ 52#include <string.h> /* for strdup() */
53#include <errno.h> 53#include <errno.h>
54#include <ctype.h> /* for isspace() */ 54#include <ctype.h> /* for isspace() */
55#include <stdlib.h> 55#include <stdlib.h>
56#include "busybox.h" 56#include "busybox.h"
57 57
@@ -59,20 +59,21 @@
59#define SED_LABEL_LENGTH 8 59#define SED_LABEL_LENGTH 8
60 60
61/* externs */ 61/* externs */
62extern void xregcomp(regex_t *preg, const char *regex, int cflags); 62extern void xregcomp(regex_t * preg, const char *regex, int cflags);
63extern int optind; /* in unistd.h */ 63extern int optind; /* in unistd.h */
64extern char *optarg; /* ditto */ 64extern char *optarg; /* ditto */
65 65
66/* options */ 66/* options */
67static int be_quiet = 0; 67static int be_quiet = 0;
68static const char bad_format_in_subst[] = "bad format in substitution expression"; 68static const char bad_format_in_subst[] =
69 "bad format in substitution expression";
69 70
70typedef struct sed_cmd_s { 71typedef struct sed_cmd_s {
71 /* Order by alignment requirements */ 72 /* Order by alignment requirements */
72 73
73 /* address storage */ 74 /* address storage */
74 regex_t *beg_match; /* sed -e '/match/cmd' */ 75 regex_t *beg_match; /* sed -e '/match/cmd' */
75 regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */ 76 regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */
76 77
77 /* SUBSTITUTION COMMAND SPECIFIC FIELDS */ 78 /* SUBSTITUTION COMMAND SPECIFIC FIELDS */
78 79
@@ -87,25 +88,25 @@ typedef struct sed_cmd_s {
87 char *filename; 88 char *filename;
88 89
89 /* address storage */ 90 /* address storage */
90 int beg_line; /* 'sed 1p' 0 == no begining line, apply commands to all lines */ 91 int beg_line; /* 'sed 1p' 0 == no begining line, apply commands to all lines */
91 int end_line; /* 'sed 1,3p' 0 == no end line, use only beginning. -1 == $ */ 92 int end_line; /* 'sed 1,3p' 0 == no end line, use only beginning. -1 == $ */
92 /* SUBSTITUTION COMMAND SPECIFIC FIELDS */ 93 /* SUBSTITUTION COMMAND SPECIFIC FIELDS */
93 94
94 unsigned int num_backrefs:4; /* how many back references (\1..\9) */ 95 unsigned int num_backrefs:4; /* how many back references (\1..\9) */
95 /* Note: GNU/POSIX sed does not save more than nine backrefs, so 96 /* Note: GNU/POSIX sed does not save more than nine backrefs, so
96 * we only use 4 bits to hold the number */ 97 * we only use 4 bits to hold the number */
97 unsigned int sub_g:1; /* sed -e 's/foo/bar/g' (global) */ 98 unsigned int sub_g:1; /* sed -e 's/foo/bar/g' (global) */
98 unsigned int sub_p:1; /* sed -e 's/foo/bar/p' (print substitution) */ 99 unsigned int sub_p:1; /* sed -e 's/foo/bar/p' (print substitution) */
99 100
100 /* TRANSLATE COMMAND */ 101 /* TRANSLATE COMMAND */
101 char *translate; 102 char *translate;
102 103
103 /* GENERAL FIELDS */ 104 /* GENERAL FIELDS */
104 /* the command */ 105 /* the command */
105 char cmd; /* p,d,s (add more at your leisure :-) */ 106 char cmd; /* p,d,s (add more at your leisure :-) */
106 107
107 /* inversion flag */ 108 /* inversion flag */
108 int invert; /* the '!' after the address */ 109 int invert; /* the '!' after the address */
109 110
110 /* Branch commands */ 111 /* Branch commands */
111 char label[SED_LABEL_LENGTH + 1]; 112 char label[SED_LABEL_LENGTH + 1];
@@ -122,7 +123,7 @@ static sed_cmd_t *sed_cmd_tail = &sed_cmd_head;
122static sed_cmd_t *block_cmd; 123static sed_cmd_t *block_cmd;
123 124
124static int in_block = 0; 125static int in_block = 0;
125const char * const semicolon_whitespace = "; \n\r\t\v\0"; 126const char *const semicolon_whitespace = "; \n\r\t\v\0";
126static regex_t *previous_regex_ptr = NULL; 127static regex_t *previous_regex_ptr = NULL;
127 128
128#ifdef CONFIG_FEATURE_CLEAN_UP 129#ifdef CONFIG_FEATURE_CLEAN_UP
@@ -158,17 +159,18 @@ static void destroy_cmd_strs(void)
158 * expression delimiter (typically a forward * slash ('/')) not preceeded by 159 * expression delimiter (typically a forward * slash ('/')) not preceeded by
159 * a backslash ('\'). 160 * a backslash ('\').
160 */ 161 */
161static int index_of_next_unescaped_regexp_delim(const char delimiter, const char *str) 162static int index_of_next_unescaped_regexp_delim(const char delimiter,
163 const char *str)
162{ 164{
163 int bracket = -1; 165 int bracket = -1;
164 int escaped = 0; 166 int escaped = 0;
165 int idx = 0; 167 int idx = 0;
166 char ch; 168 char ch;
167 169
168 for ( ; (ch = str[idx]); idx++) { 170 for (; (ch = str[idx]); idx++) {
169 if (bracket != -1) { 171 if (bracket != -1) {
170 if (ch == ']' && !(bracket == idx - 1 || 172 if (ch == ']' && !(bracket == idx - 1 ||
171 (bracket == idx - 2 && str[idx-1] == '^'))) 173 (bracket == idx - 2 && str[idx - 1] == '^')))
172 bracket = -1; 174 bracket = -1;
173 } else if (escaped) 175 } else if (escaped)
174 escaped = 0; 176 escaped = 0;
@@ -214,26 +216,26 @@ static int parse_regex_delim(const char *cmdstr, char **match, char **replace)
214 } 216 }
215 *replace = bb_xstrndup(cmdstr_ptr, idx); 217 *replace = bb_xstrndup(cmdstr_ptr, idx);
216 218
217 return((cmdstr_ptr - cmdstr) + idx); 219 return ((cmdstr_ptr - cmdstr) + idx);
218} 220}
219 221
220/* 222/*
221 * returns the index in the string just past where the address ends. 223 * returns the index in the string just past where the address ends.
222 */ 224 */
223static int get_address(char *my_str, int *linenum, regex_t **regex) 225static int get_address(char *my_str, int *linenum, regex_t ** regex)
224{ 226{
225 int idx = 0; 227 int idx = 0;
228
226 if (isdigit(my_str[idx])) { 229 if (isdigit(my_str[idx])) {
227 char *endstr; 230 char *endstr;
231
228 *linenum = strtol(my_str, &endstr, 10); 232 *linenum = strtol(my_str, &endstr, 10);
229 /* endstr shouldnt ever equal NULL */ 233 /* endstr shouldnt ever equal NULL */
230 idx = endstr - my_str; 234 idx = endstr - my_str;
231 } 235 } else if (my_str[idx] == '$') {
232 else if (my_str[idx] == '$') {
233 *linenum = -1; 236 *linenum = -1;
234 idx++; 237 idx++;
235 } 238 } else if (my_str[idx] == '/' || my_str[idx] == '\\') {
236 else if (my_str[idx] == '/' || my_str[idx] == '\\') {
237 int idx_start = 1; 239 int idx_start = 1;
238 char delimiter; 240 char delimiter;
239 241
@@ -248,10 +250,10 @@ static int get_address(char *my_str, int *linenum, regex_t **regex)
248 bb_error_msg_and_die("unterminated match expression"); 250 bb_error_msg_and_die("unterminated match expression");
249 } 251 }
250 my_str[idx] = '\0'; 252 my_str[idx] = '\0';
251 253
252 *regex = (regex_t *)xmalloc(sizeof(regex_t)); 254 *regex = (regex_t *) xmalloc(sizeof(regex_t));
253 xregcomp(*regex, my_str+idx_start, REG_NEWLINE); 255 xregcomp(*regex, my_str + idx_start, REG_NEWLINE);
254 idx++; /* so it points to the next character after the last '/' */ 256 idx++; /* so it points to the next character after the last '/' */
255 } 257 }
256 return idx; 258 return idx;
257} 259}
@@ -277,41 +279,42 @@ static int parse_subst_cmd(sed_cmd_t * const sed_cmd, const char *substr)
277 /* Note: we compute this here rather than in the do_subst_command() 279 /* Note: we compute this here rather than in the do_subst_command()
278 * function to save processor time, at the expense of a little more memory 280 * function to save processor time, at the expense of a little more memory
279 * (4 bits) per sed_cmd */ 281 * (4 bits) per sed_cmd */
280 282
281 /* sed_cmd->num_backrefs = 0; */ /* XXX: not needed? --apparently not */ 283 /* sed_cmd->num_backrefs = 0; *//* XXX: not needed? --apparently not */
282 for (j = 0; match[j]; j++) { 284 for (j = 0; match[j]; j++) {
283 /* GNU/POSIX sed does not save more than nine backrefs */ 285 /* GNU/POSIX sed does not save more than nine backrefs */
284 if (match[j] == '\\' && match[j+1] == '(' && sed_cmd->num_backrefs <= 9) 286 if (match[j] == '\\' && match[j + 1] == '('
287 && sed_cmd->num_backrefs <= 9)
285 sed_cmd->num_backrefs++; 288 sed_cmd->num_backrefs++;
286 } 289 }
287 290
288 /* process the flags */ 291 /* process the flags */
289 while (substr[++idx]) { 292 while (substr[++idx]) {
290 switch (substr[idx]) { 293 switch (substr[idx]) {
291 case 'g': 294 case 'g':
292 sed_cmd->sub_g = 1; 295 sed_cmd->sub_g = 1;
293 break; 296 break;
294 /* Hmm, i dont see the I option mentioned in the standard */ 297 /* Hmm, i dont see the I option mentioned in the standard */
295 case 'I': 298 case 'I':
296 cflags |= REG_ICASE; 299 cflags |= REG_ICASE;
297 break; 300 break;
298 case 'p': 301 case 'p':
299 sed_cmd->sub_p = 1; 302 sed_cmd->sub_p = 1;
300 break; 303 break;
301 default: 304 default:
302 /* any whitespace or semicolon trailing after a s/// is ok */ 305 /* any whitespace or semicolon trailing after a s/// is ok */
303 if (strchr(semicolon_whitespace, substr[idx])) 306 if (strchr(semicolon_whitespace, substr[idx]))
304 goto out; 307 goto out;
305 /* else */ 308 /* else */
306 bb_error_msg_and_die("bad option in substitution expression"); 309 bb_error_msg_and_die("bad option in substitution expression");
307 } 310 }
308 } 311 }
309 312
310out: 313 out:
311 /* compile the match string into a regex */ 314 /* compile the match string into a regex */
312 if (*match != '\0') { 315 if (*match != '\0') {
313 /* If match is empty, we use last regex used at runtime */ 316 /* If match is empty, we use last regex used at runtime */
314 sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t)); 317 sed_cmd->sub_match = (regex_t *) xmalloc(sizeof(regex_t));
315 xregcomp(sed_cmd->sub_match, match, cflags); 318 xregcomp(sed_cmd->sub_match, match, cflags);
316 } 319 }
317 free(match); 320 free(match);
@@ -349,10 +352,10 @@ static int parse_translate_cmd(sed_cmd_t * const sed_cmd, const char *cmdstr)
349 sed_cmd->translate[i * 2] = match[i]; 352 sed_cmd->translate[i * 2] = match[i];
350 sed_cmd->translate[(i * 2) + 1] = replace[i]; 353 sed_cmd->translate[(i * 2) + 1] = replace[i];
351 } 354 }
352 return(idx + 1); 355 return (idx + 1);
353} 356}
354 357
355static int parse_edit_cmd(sed_cmd_t *sed_cmd, const char *editstr) 358static int parse_edit_cmd(sed_cmd_t * sed_cmd, const char *editstr)
356{ 359{
357 int i, j; 360 int i, j;
358 361
@@ -383,9 +386,9 @@ static int parse_edit_cmd(sed_cmd_t *sed_cmd, const char *editstr)
383 386
384 /* store the edit line text */ 387 /* store the edit line text */
385 sed_cmd->editline = xmalloc(strlen(&editstr[2]) + 2); 388 sed_cmd->editline = xmalloc(strlen(&editstr[2]) + 2);
386 for (i = 2, j = 0; editstr[i] != '\0' && strchr("\r\n", editstr[i]) == NULL; 389 for (i = 2, j = 0;
387 i++, j++) { 390 editstr[i] != '\0' && strchr("\r\n", editstr[i]) == NULL; i++, j++) {
388 if ((editstr[i] == '\\') && strchr("\n\r", editstr[i+1]) != NULL) { 391 if ((editstr[i] == '\\') && strchr("\n\r", editstr[i + 1]) != NULL) {
389 sed_cmd->editline[j] = '\n'; 392 sed_cmd->editline[j] = '\n';
390 i++; 393 i++;
391 } else 394 } else
@@ -393,7 +396,7 @@ static int parse_edit_cmd(sed_cmd_t *sed_cmd, const char *editstr)
393 } 396 }
394 397
395 /* figure out if we need to add a newline */ 398 /* figure out if we need to add a newline */
396 if (sed_cmd->editline[j-1] != '\n') 399 if (sed_cmd->editline[j - 1] != '\n')
397 sed_cmd->editline[j++] = '\n'; 400 sed_cmd->editline[j++] = '\n';
398 401
399 /* terminate string */ 402 /* terminate string */
@@ -403,7 +406,7 @@ static int parse_edit_cmd(sed_cmd_t *sed_cmd, const char *editstr)
403} 406}
404 407
405 408
406static int parse_file_cmd(sed_cmd_t *sed_cmd, const char *filecmdstr) 409static int parse_file_cmd(sed_cmd_t * sed_cmd, const char *filecmdstr)
407{ 410{
408 int idx = 0; 411 int idx = 0;
409 int filenamelen = 0; 412 int filenamelen = 0;
@@ -427,9 +430,9 @@ static int parse_file_cmd(sed_cmd_t *sed_cmd, const char *filecmdstr)
427 */ 430 */
428 431
429 /* the file command may be followed by whitespace; move past it. */ 432 /* the file command may be followed by whitespace; move past it. */
430 while (isspace(filecmdstr[++idx])) 433 while (isspace(filecmdstr[++idx])) {;
431 { ; } 434 }
432 435
433 /* the first non-whitespace we get is a filename. the filename ends when we 436 /* the first non-whitespace we get is a filename. the filename ends when we
434 * hit a normal sed command terminator or end of string */ 437 * hit a normal sed command terminator or end of string */
435 filenamelen = strcspn(&filecmdstr[idx], semicolon_whitespace); 438 filenamelen = strcspn(&filecmdstr[idx], semicolon_whitespace);
@@ -451,7 +454,8 @@ static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr)
451 /* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */ 454 /* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */
452 else if (strchr("aic", sed_cmd->cmd)) { 455 else if (strchr("aic", sed_cmd->cmd)) {
453 if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c') 456 if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c')
454 bb_error_msg_and_die("only a beginning address can be specified for edit commands"); 457 bb_error_msg_and_die
458 ("only a beginning address can be specified for edit commands");
455 cmdstr += parse_edit_cmd(sed_cmd, cmdstr); 459 cmdstr += parse_edit_cmd(sed_cmd, cmdstr);
456 } 460 }
457 /* handle file cmds: (r)ead */ 461 /* handle file cmds: (r)ead */
@@ -470,7 +474,7 @@ static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr)
470 length = SED_LABEL_LENGTH; 474 length = SED_LABEL_LENGTH;
471 } 475 }
472 strncpy(sed_cmd->label, cmdstr, length); 476 strncpy(sed_cmd->label, cmdstr, length);
473 cmdstr += length; 477 cmdstr += length;
474 } 478 }
475 /* translation command */ 479 /* translation command */
476 else if (sed_cmd->cmd == 'y') { 480 else if (sed_cmd->cmd == 'y') {
@@ -484,10 +488,10 @@ static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr)
484 } 488 }
485 489
486 /* give back whatever's left over */ 490 /* give back whatever's left over */
487 return(cmdstr); 491 return (cmdstr);
488} 492}
489 493
490static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr) 494static char *add_cmd(sed_cmd_t * sed_cmd, char *cmdstr)
491{ 495{
492 /* Skip over leading whitespace and semicolons */ 496 /* Skip over leading whitespace and semicolons */
493 cmdstr += strspn(cmdstr, semicolon_whitespace); 497 cmdstr += strspn(cmdstr, semicolon_whitespace);
@@ -495,7 +499,7 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
495 /* if we ate the whole thing, that means there was just trailing 499 /* if we ate the whole thing, that means there was just trailing
496 * whitespace or a final / no-op semicolon. either way, get out */ 500 * whitespace or a final / no-op semicolon. either way, get out */
497 if (*cmdstr == '\0') { 501 if (*cmdstr == '\0') {
498 return(NULL); 502 return (NULL);
499 } 503 }
500 504
501 /* if this is a comment, jump past it and keep going */ 505 /* if this is a comment, jump past it and keep going */
@@ -504,14 +508,14 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
504 if (cmdstr[1] == 'n') { 508 if (cmdstr[1] == 'n') {
505 be_quiet++; 509 be_quiet++;
506 } 510 }
507 return(strpbrk(cmdstr, "\n\r")); 511 return (strpbrk(cmdstr, "\n\r"));
508 } 512 }
509 513
510 /* Test for end of block */ 514 /* Test for end of block */
511 if (*cmdstr == '}') { 515 if (*cmdstr == '}') {
512 in_block = 0; 516 in_block = 0;
513 cmdstr++; 517 cmdstr++;
514 return(cmdstr); 518 return (cmdstr);
515 } 519 }
516 520
517 /* parse the command 521 /* parse the command
@@ -526,11 +530,12 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
526 /* second part (if present) will begin with a comma */ 530 /* second part (if present) will begin with a comma */
527 if (*cmdstr == ',') { 531 if (*cmdstr == ',') {
528 int idx; 532 int idx;
533
529 cmdstr++; 534 cmdstr++;
530 idx = get_address(cmdstr, &sed_cmd->end_line, &sed_cmd->end_match); 535 idx = get_address(cmdstr, &sed_cmd->end_line, &sed_cmd->end_match);
531 if (idx == 0) { 536 if (idx == 0) {
532 bb_error_msg_and_die("get_address: no address found in string\n" 537 bb_error_msg_and_die("get_address: no address found in string\n"
533 "\t(you probably didn't check the string you passed me)"); 538 "\t(you probably didn't check the string you passed me)");
534 } 539 }
535 cmdstr += idx; 540 cmdstr += idx;
536 } 541 }
@@ -552,9 +557,8 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
552 * with <blank>s. 557 * with <blank>s.
553 */ 558 */
554 if (isblank(cmdstr[idx]) { 559 if (isblank(cmdstr[idx]) {
555 bb_error_msg_and_die("blank follows '!'"); 560 bb_error_msg_and_die("blank follows '!'");}
556 } 561#else
557#else
558 /* skip whitespace before the command */ 562 /* skip whitespace before the command */
559 while (isspace(*cmdstr)) { 563 while (isspace(*cmdstr)) {
560 cmdstr++; 564 cmdstr++;
@@ -573,8 +577,8 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
573 } 577 }
574 in_block = 1; 578 in_block = 1;
575 block_cmd = sed_cmd; 579 block_cmd = sed_cmd;
576 580
577 return(cmdstr + 1); 581 return (cmdstr + 1);
578 } 582 }
579 583
580 sed_cmd->cmd = *cmdstr; 584 sed_cmd->cmd = *cmdstr;
@@ -594,7 +598,7 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
594 sed_cmd_tail->linear = sed_cmd; 598 sed_cmd_tail->linear = sed_cmd;
595 sed_cmd_tail = sed_cmd_tail->linear; 599 sed_cmd_tail = sed_cmd_tail->linear;
596 600
597 return(cmdstr); 601 return (cmdstr);
598} 602}
599 603
600static void add_cmd_str(char *cmdstr) 604static void add_cmd_str(char *cmdstr)
@@ -603,7 +607,7 @@ static void add_cmd_str(char *cmdstr)
603 char *cmdstr_ptr = cmdstr; 607 char *cmdstr_ptr = cmdstr;
604 608
605 /* HACK: convert "\n" to match tranlated '\n' string */ 609 /* HACK: convert "\n" to match tranlated '\n' string */
606 while((cmdstr_ptr = strstr(cmdstr_ptr, "\\n")) != NULL) { 610 while ((cmdstr_ptr = strstr(cmdstr_ptr, "\\n")) != NULL) {
607 cmdstr = xrealloc(cmdstr, strlen(cmdstr) + 2); 611 cmdstr = xrealloc(cmdstr, strlen(cmdstr) + 2);
608 cmdstr_ptr = strstr(cmdstr, "\\n"); 612 cmdstr_ptr = strstr(cmdstr, "\\n");
609 memmove(cmdstr_ptr + 1, cmdstr_ptr, strlen(cmdstr_ptr) + 1); 613 memmove(cmdstr_ptr + 1, cmdstr_ptr, strlen(cmdstr_ptr) + 1);
@@ -613,6 +617,7 @@ static void add_cmd_str(char *cmdstr)
613#endif 617#endif
614 do { 618 do {
615 sed_cmd_t *sed_cmd; 619 sed_cmd_t *sed_cmd;
620
616 sed_cmd = xcalloc(1, sizeof(sed_cmd_t)); 621 sed_cmd = xcalloc(1, sizeof(sed_cmd_t));
617 cmdstr = add_cmd(sed_cmd, cmdstr); 622 cmdstr = add_cmd(sed_cmd, cmdstr);
618 } while (cmdstr && strlen(cmdstr)); 623 } while (cmdstr && strlen(cmdstr));
@@ -652,13 +657,12 @@ struct pipeline {
652}; 657};
653 658
654#define PIPE_MAGIC 0x7f 659#define PIPE_MAGIC 0x7f
655#define PIPE_GROW 64 660#define PIPE_GROW 64
656 661
657void pipe_putc(struct pipeline *const pipeline, char c) 662void pipe_putc(struct pipeline *const pipeline, char c)
658{ 663{
659 if (pipeline->buf[pipeline->idx] == PIPE_MAGIC) { 664 if (pipeline->buf[pipeline->idx] == PIPE_MAGIC) {
660 pipeline->buf = 665 pipeline->buf = xrealloc(pipeline->buf, pipeline->len + PIPE_GROW);
661 xrealloc(pipeline->buf, pipeline->len + PIPE_GROW);
662 memset(pipeline->buf + pipeline->len, 0, PIPE_GROW); 666 memset(pipeline->buf + pipeline->len, 0, PIPE_GROW);
663 pipeline->len += PIPE_GROW; 667 pipeline->len += PIPE_GROW;
664 pipeline->buf[pipeline->len - 1] = PIPE_MAGIC; 668 pipeline->buf[pipeline->len - 1] = PIPE_MAGIC;
@@ -669,33 +673,40 @@ void pipe_putc(struct pipeline *const pipeline, char c)
669#define pipeputc(c) pipe_putc(pipeline, c) 673#define pipeputc(c) pipe_putc(pipeline, c)
670 674
671#if 0 675#if 0
672{ if (pipeline[pipeline_idx] == PIPE_MAGIC) { \ 676{
673 pipeline = xrealloc(pipeline, pipeline_len+PIPE_GROW); \ 677 if (pipeline[pipeline_idx] == PIPE_MAGIC) {
674 memset(pipeline+pipeline_len, 0, PIPE_GROW); \ 678 pipeline = xrealloc(pipeline, pipeline_len + PIPE_GROW);
675 pipeline_len += PIPE_GROW; \ 679 memset(pipeline + pipeline_len, 0, PIPE_GROW);
676 pipeline[pipeline_len-1] = PIPE_MAGIC; } \ 680 pipeline_len += PIPE_GROW;
677 pipeline[pipeline_idx++] = (c); } 681 pipeline[pipeline_len - 1] = PIPE_MAGIC;
682 }
683 pipeline[pipeline_idx++] = (c);
684}
678#endif 685#endif
679 686
680static void print_subst_w_backrefs(const char *line, const char *replace, 687static void print_subst_w_backrefs(const char *line, const char *replace,
681 regmatch_t *regmatch, struct pipeline *const pipeline, int matches) 688 regmatch_t * regmatch,
689 struct pipeline *const pipeline,
690 int matches)
682{ 691{
683 int i; 692 int i;
684 693
685 /* go through the replacement string */ 694 /* go through the replacement string */
686 for (i = 0; replace[i]; i++) { 695 for (i = 0; replace[i]; i++) {
687 /* if we find a backreference (\1, \2, etc.) print the backref'ed * text */ 696 /* if we find a backreference (\1, \2, etc.) print the backref'ed * text */
688 if (replace[i] == '\\' && isdigit(replace[i+1])) { 697 if (replace[i] == '\\' && isdigit(replace[i + 1])) {
689 int j; 698 int j;
690 char tmpstr[2]; 699 char tmpstr[2];
691 int backref; 700 int backref;
692 ++i; /* i now indexes the backref number, instead of the leading slash */ 701
702 ++i; /* i now indexes the backref number, instead of the leading slash */
693 tmpstr[0] = replace[i]; 703 tmpstr[0] = replace[i];
694 tmpstr[1] = 0; 704 tmpstr[1] = 0;
695 backref = atoi(tmpstr); 705 backref = atoi(tmpstr);
696 /* print out the text held in regmatch[backref] */ 706 /* print out the text held in regmatch[backref] */
697 if (backref <= matches && regmatch[backref].rm_so != -1) 707 if (backref <= matches && regmatch[backref].rm_so != -1)
698 for (j = regmatch[backref].rm_so; j < regmatch[backref].rm_eo; j++) 708 for (j = regmatch[backref].rm_so; j < regmatch[backref].rm_eo;
709 j++)
699 pipeputc(line[j]); 710 pipeputc(line[j]);
700 } 711 }
701 712
@@ -709,8 +720,9 @@ static void print_subst_w_backrefs(const char *line, const char *replace,
709 * fortunately, regmatch[0] contains the indicies to the whole matched 720 * fortunately, regmatch[0] contains the indicies to the whole matched
710 * expression (kinda seems like it was designed for just such a 721 * expression (kinda seems like it was designed for just such a
711 * purpose...) */ 722 * purpose...) */
712 else if (replace[i] == '&' && replace[i-1] != '\\') { 723 else if (replace[i] == '&' && replace[i - 1] != '\\') {
713 int j; 724 int j;
725
714 for (j = regmatch[0].rm_so; j < regmatch[0].rm_eo; j++) 726 for (j = regmatch[0].rm_so; j < regmatch[0].rm_eo; j++)
715 pipeputc(line[j]); 727 pipeputc(line[j]);
716 } 728 }
@@ -720,10 +732,10 @@ static void print_subst_w_backrefs(const char *line, const char *replace,
720 } 732 }
721} 733}
722 734
723static int do_subst_command(sed_cmd_t *sed_cmd, char **line) 735static int do_subst_command(sed_cmd_t * sed_cmd, char **line)
724{ 736{
725 char *hackline = *line; 737 char *hackline = *line;
726 struct pipeline thepipe = { NULL, 0 , 0}; 738 struct pipeline thepipe = { NULL, 0, 0 };
727 struct pipeline *const pipeline = &thepipe; 739 struct pipeline *const pipeline = &thepipe;
728 int altered = 0; 740 int altered = 0;
729 int result; 741 int result;
@@ -743,19 +755,20 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line)
743 } 755 }
744 756
745 /* whaddaya know, it matched. get the number of back references */ 757 /* whaddaya know, it matched. get the number of back references */
746 regmatch = xmalloc(sizeof(regmatch_t) * (sed_cmd->num_backrefs+1)); 758 regmatch = xmalloc(sizeof(regmatch_t) * (sed_cmd->num_backrefs + 1));
747 759
748 /* allocate more PIPE_GROW bytes 760 /* allocate more PIPE_GROW bytes
749 if replaced string is larger than original */ 761 if replaced string is larger than original */
750 thepipe.len = strlen(hackline)+PIPE_GROW; 762 thepipe.len = strlen(hackline) + PIPE_GROW;
751 thepipe.buf = xcalloc(1, thepipe.len); 763 thepipe.buf = xcalloc(1, thepipe.len);
752 /* buffer magic */ 764 /* buffer magic */
753 thepipe.buf[thepipe.len-1] = PIPE_MAGIC; 765 thepipe.buf[thepipe.len - 1] = PIPE_MAGIC;
754 766
755 /* and now, as long as we've got a line to try matching and if we can match 767 /* and now, as long as we've got a line to try matching and if we can match
756 * the search string, we make substitutions */ 768 * the search string, we make substitutions */
757 while ((*hackline || !altered) && (regexec(current_regex, hackline, 769 while ((*hackline || !altered) && (regexec(current_regex, hackline,
758 sed_cmd->num_backrefs+1, regmatch, 0) != REG_NOMATCH) ) { 770 sed_cmd->num_backrefs + 1,
771 regmatch, 0) != REG_NOMATCH)) {
759 int i; 772 int i;
760 773
761 /* print everything before the match */ 774 /* print everything before the match */
@@ -763,8 +776,8 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line)
763 pipeputc(hackline[i]); 776 pipeputc(hackline[i]);
764 777
765 /* then print the substitution string */ 778 /* then print the substitution string */
766 print_subst_w_backrefs(hackline, sed_cmd->replace, regmatch, 779 print_subst_w_backrefs(hackline, sed_cmd->replace, regmatch,
767 pipeline, sed_cmd->num_backrefs); 780 pipeline, sed_cmd->num_backrefs);
768 781
769 /* advance past the match */ 782 /* advance past the match */
770 hackline += regmatch[0].rm_eo; 783 hackline += regmatch[0].rm_eo;
@@ -776,8 +789,10 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line)
776 break; 789 break;
777 } 790 }
778 } 791 }
779 for (; *hackline; hackline++) pipeputc(*hackline); 792 for (; *hackline; hackline++)
780 if (thepipe.buf[thepipe.idx] == PIPE_MAGIC) thepipe.buf[thepipe.idx] = 0; 793 pipeputc(*hackline);
794 if (thepipe.buf[thepipe.idx] == PIPE_MAGIC)
795 thepipe.buf[thepipe.idx] = 0;
781 796
782 /* cleanup */ 797 /* cleanup */
783 free(regmatch); 798 free(regmatch);
@@ -790,21 +805,22 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line)
790static sed_cmd_t *branch_to(const char *label) 805static sed_cmd_t *branch_to(const char *label)
791{ 806{
792 sed_cmd_t *sed_cmd; 807 sed_cmd_t *sed_cmd;
793 for(sed_cmd = sed_cmd_head.linear; sed_cmd; sed_cmd = sed_cmd->linear) { 808
809 for (sed_cmd = sed_cmd_head.linear; sed_cmd; sed_cmd = sed_cmd->linear) {
794 if (strcmp(sed_cmd->label, label) == 0) { 810 if (strcmp(sed_cmd->label, label) == 0) {
795 break; 811 break;
796 } 812 }
797 } 813 }
798 814
799 /* If no match returns last command */ 815 /* If no match returns last command */
800 return(sed_cmd); 816 return (sed_cmd);
801} 817}
802 818
803static void process_file(FILE *file) 819static void process_file(FILE * file)
804{ 820{
805 char *pattern_space; /* Posix requires it be able to hold at least 8192 bytes */ 821 char *pattern_space; /* Posix requires it be able to hold at least 8192 bytes */
806 char *hold_space = NULL; /* Posix requires it be able to hold at least 8192 bytes */ 822 char *hold_space = NULL; /* Posix requires it be able to hold at least 8192 bytes */
807 static int linenum = 0; /* GNU sed does not restart counting lines at EOF */ 823 static int linenum = 0; /* GNU sed does not restart counting lines at EOF */
808 unsigned int still_in_range = 0; 824 unsigned int still_in_range = 0;
809 int altered; 825 int altered;
810 int force_print; 826 int force_print;
@@ -828,24 +844,32 @@ static void process_file(FILE *file)
828 force_print = 0; 844 force_print = 0;
829 845
830 /* for every line, go through all the commands */ 846 /* for every line, go through all the commands */
831 for (sed_cmd = sed_cmd_head.linear; sed_cmd; sed_cmd = sed_cmd->linear) { 847 for (sed_cmd = sed_cmd_head.linear; sed_cmd;
848 sed_cmd = sed_cmd->linear) {
832 int deleted = 0; 849 int deleted = 0;
833 850
834 /* 851 /*
835 * entry point into sedding... 852 * entry point into sedding...
836 */ 853 */
837 int matched = ( 854 int matched = (
838 /* no range necessary */ 855 /* no range necessary */
839 (sed_cmd->beg_line == 0 && sed_cmd->end_line == 0 && 856 (sed_cmd->beg_line == 0
840 sed_cmd->beg_match == NULL && 857 && sed_cmd->end_line == 0
841 sed_cmd->end_match == NULL) || 858 && sed_cmd->beg_match == NULL
842 /* this line number is the first address we're looking for */ 859 && sed_cmd->end_match == NULL) ||
843 (sed_cmd->beg_line && (sed_cmd->beg_line == linenum)) || 860 /* this line number is the first address we're looking for */
844 /* this line matches our first address regex */ 861 (sed_cmd->beg_line
845 (sed_cmd->beg_match && (regexec(sed_cmd->beg_match, pattern_space, 0, NULL, 0) == 0)) || 862 && (sed_cmd->beg_line == linenum)) ||
846 /* we are currently within the beginning & ending address range */ 863 /* this line matches our first address regex */
847 still_in_range || ((sed_cmd->beg_line == -1) && (next_line == NULL)) 864 (sed_cmd->beg_match
848 ); 865 &&
866 (regexec
867 (sed_cmd->beg_match, pattern_space, 0, NULL,
868 0) == 0)) ||
869 /* we are currently within the beginning & ending address range */
870 still_in_range || ((sed_cmd->beg_line == -1)
871 && (next_line == NULL))
872 );
849 873
850 if (sed_cmd->invert ^ matched) { 874 if (sed_cmd->invert ^ matched) {
851 /* Update last used regex incase a blank substitute BRE is found */ 875 /* Update last used regex incase a blank substitute BRE is found */
@@ -857,172 +881,192 @@ static void process_file(FILE *file)
857 * actual sedding 881 * actual sedding
858 */ 882 */
859 switch (sed_cmd->cmd) { 883 switch (sed_cmd->cmd) {
860 case '=': 884 case '=':
861 printf("%d\n", linenum); 885 printf("%d\n", linenum);
862 break; 886 break;
863 case 'P': { /* Write the current pattern space upto the first newline */ 887 case 'P':{
864 char *tmp = strchr(pattern_space, '\n'); 888 /* Write the current pattern space upto the first newline */
865 if (tmp) { 889 char *tmp = strchr(pattern_space, '\n');
866 *tmp = '\0'; 890
867 } 891 if (tmp) {
868 } 892 *tmp = '\0';
869 case 'p': /* Write the current pattern space to output */ 893 }
870 puts(pattern_space); 894 }
871 break; 895 case 'p': /* Write the current pattern space to output */
872 case 'd': 896 puts(pattern_space);
873 altered++; 897 break;
874 deleted = 1; 898 case 'd':
875 break; 899 altered++;
876 900 deleted = 1;
877 case 's': 901 break;
878 902
879 /* 903 case 's':
880 * Some special cases for 's' printing to make it compliant with 904
881 * GNU sed printing behavior (aka "The -n | s///p Matrix"): 905 /*
882 * 906 * Some special cases for 's' printing to make it compliant with
883 * -n ONLY = never print anything regardless of any successful 907 * GNU sed printing behavior (aka "The -n | s///p Matrix"):
884 * substitution 908 *
885 * 909 * -n ONLY = never print anything regardless of any successful
886 * s///p ONLY = always print successful substitutions, even if 910 * substitution
887 * the pattern_space is going to be printed anyway (pattern_space 911 *
888 * will be printed twice). 912 * s///p ONLY = always print successful substitutions, even if
889 * 913 * the pattern_space is going to be printed anyway (pattern_space
890 * -n AND s///p = print ONLY a successful substitution ONE TIME; 914 * will be printed twice).
891 * no other lines are printed - this is the reason why the 'p' 915 *
892 * flag exists in the first place. 916 * -n AND s///p = print ONLY a successful substitution ONE TIME;
893 */ 917 * no other lines are printed - this is the reason why the 'p'
918 * flag exists in the first place.
919 */
894 920
895#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE 921#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE
896 /* HACK: escape newlines twice so regex can match them */ 922 /* HACK: escape newlines twice so regex can match them */
897 { 923 {
898 int offset = 0; 924 int offset = 0;
899 while(strchr(pattern_space + offset, '\n') != NULL) { 925
900 char *tmp; 926 while (strchr(pattern_space + offset, '\n') != NULL) {
901 pattern_space = xrealloc(pattern_space, strlen(pattern_space) + 2); 927 char *tmp;
902 tmp = strchr(pattern_space + offset, '\n'); 928
903 memmove(tmp + 1, tmp, strlen(tmp) + 1); 929 pattern_space =
904 tmp[0] = '\\'; 930 xrealloc(pattern_space,
905 tmp[1] = 'n'; 931 strlen(pattern_space) + 2);
906 offset = tmp - pattern_space + 2; 932 tmp = strchr(pattern_space + offset, '\n');
907 } 933 memmove(tmp + 1, tmp, strlen(tmp) + 1);
908 } 934 tmp[0] = '\\';
935 tmp[1] = 'n';
936 offset = tmp - pattern_space + 2;
937 }
938 }
909#endif 939#endif
910 /* we print the pattern_space once, unless we were told to be quiet */ 940 /* we print the pattern_space once, unless we were told to be quiet */
911 substituted = do_subst_command(sed_cmd, &pattern_space); 941 substituted = do_subst_command(sed_cmd, &pattern_space);
912 942
913#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE 943#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE
914 /* undo HACK: escape newlines twice so regex can match them */ 944 /* undo HACK: escape newlines twice so regex can match them */
915 { 945 {
916 char *tmp = pattern_space; 946 char *tmp = pattern_space;
917 947
918 while((tmp = strstr(tmp, "\\n")) != NULL) { 948 while ((tmp = strstr(tmp, "\\n")) != NULL) {
919 memmove(tmp, tmp + 1, strlen(tmp + 1) + 1); 949 memmove(tmp, tmp + 1, strlen(tmp + 1) + 1);
920 tmp[0] = '\n'; 950 tmp[0] = '\n';
921 }
922 } 951 }
952 }
923#endif 953#endif
924 altered |= substituted; 954 altered |= substituted;
925 if (!be_quiet && altered && ((sed_cmd->linear == NULL) || (sed_cmd->linear->cmd != 's'))) { 955 if (!be_quiet && altered && ((sed_cmd->linear == NULL)
926 force_print = 1; 956 || (sed_cmd->linear->cmd !=
927 } 957 's'))) {
928 958 force_print = 1;
929 /* we also print the line if we were given the 'p' flag 959 }
930 * (this is quite possibly the second printing) */ 960
931 if ((sed_cmd->sub_p) && altered) { 961 /* we also print the line if we were given the 'p' flag
932 puts(pattern_space); 962 * (this is quite possibly the second printing) */
933 } 963 if ((sed_cmd->sub_p) && altered) {
934 break;
935 case 'a':
936 puts(pattern_space); 964 puts(pattern_space);
937 fputs(sed_cmd->editline, stdout); 965 }
938 altered++; 966 break;
939 break; 967 case 'a':
940 968 puts(pattern_space);
941 case 'i': 969 fputs(sed_cmd->editline, stdout);
942 fputs(sed_cmd->editline, stdout); 970 altered++;
943 break; 971 break;
944 972
945 case 'c': 973 case 'i':
946 /* single-address case */ 974 fputs(sed_cmd->editline, stdout);
947 if ((sed_cmd->end_match == NULL && sed_cmd->end_line == 0) 975 break;
976
977 case 'c':
978 /* single-address case */
979 if ((sed_cmd->end_match == NULL && sed_cmd->end_line == 0)
948 /* multi-address case */ 980 /* multi-address case */
949 /* - matching text */ 981 /* - matching text */
950 || (sed_cmd->end_match && (regexec(sed_cmd->end_match, pattern_space, 0, NULL, 0) == 0)) 982 || (sed_cmd->end_match
983 &&
984 (regexec
985 (sed_cmd->end_match, pattern_space, 0, NULL,
986 0) == 0))
951 /* - matching line numbers */ 987 /* - matching line numbers */
952 || (sed_cmd->end_line > 0 && sed_cmd->end_line == linenum)) 988 || (sed_cmd->end_line > 0
953 { 989 && sed_cmd->end_line == linenum)) {
954 fputs(sed_cmd->editline, stdout); 990 fputs(sed_cmd->editline, stdout);
955 } 991 }
956 altered++; 992 altered++;
957 993
958 break; 994 break;
959 995
960 case 'r': { 996 case 'r':{
961 FILE *outfile; 997 FILE *outfile;
962 puts(pattern_space); 998
963 outfile = fopen(sed_cmd->filename, "r"); 999 puts(pattern_space);
964 if (outfile) 1000 outfile = fopen(sed_cmd->filename, "r");
965 bb_xprint_and_close_file(outfile); 1001 if (outfile)
966 /* else if we couldn't open the output file, 1002 bb_xprint_and_close_file(outfile);
967 * no biggie, just don't print anything */ 1003 /* else if we couldn't open the output file,
968 altered++; 1004 * no biggie, just don't print anything */
969 } 1005 altered++;
970 break; 1006 }
971 case 'q': /* Branch to end of script and quit */ 1007 break;
972 deleted = 1; 1008 case 'q': /* Branch to end of script and quit */
973 /* Exit the outer while loop */ 1009 deleted = 1;
974 free(next_line); 1010 /* Exit the outer while loop */
975 next_line = NULL; 1011 free(next_line);
976 break; 1012 next_line = NULL;
977 case 'n': /* Read next line from input */ 1013 break;
978 free(pattern_space); 1014 case 'n': /* Read next line from input */
979 pattern_space = next_line; 1015 free(pattern_space);
1016 pattern_space = next_line;
1017 next_line = bb_get_chomped_line_from_file(file);
1018 linenum++;
1019 break;
1020 case 'N': /* Append the next line to the current line */
1021 if (next_line) {
1022 pattern_space =
1023 realloc(pattern_space,
1024 strlen(pattern_space) +
1025 strlen(next_line) + 2);
1026 strcat(pattern_space, "\n");
1027 strcat(pattern_space, next_line);
980 next_line = bb_get_chomped_line_from_file(file); 1028 next_line = bb_get_chomped_line_from_file(file);
981 linenum++; 1029 linenum++;
982 break; 1030 }
983 case 'N': /* Append the next line to the current line */ 1031 break;
984 if (next_line) { 1032 case 'b':
985 pattern_space = realloc(pattern_space, strlen(pattern_space) + strlen(next_line) + 2); 1033 sed_cmd = branch_to(sed_cmd->label);
986 strcat(pattern_space, "\n"); 1034 break;
987 strcat(pattern_space, next_line); 1035 case 't':
988 next_line = bb_get_chomped_line_from_file(file); 1036 if (substituted) {
989 linenum++;
990 }
991 break;
992 case 'b':
993 sed_cmd = branch_to(sed_cmd->label); 1037 sed_cmd = branch_to(sed_cmd->label);
994 break; 1038 }
995 case 't': 1039 break;
996 if (substituted) { 1040 case 'y':{
997 sed_cmd = branch_to(sed_cmd->label); 1041 int i;
998 } 1042
999 break; 1043 for (i = 0; pattern_space[i] != 0; i++) {
1000 case 'y': { 1044 int j;
1001 int i; 1045
1002 for (i = 0; pattern_space[i] != 0; i++) { 1046 for (j = 0; sed_cmd->translate[j]; j += 2) {
1003 int j; 1047 if (pattern_space[i] == sed_cmd->translate[j]) {
1004 for (j = 0; sed_cmd->translate[j] ;j += 2) { 1048 pattern_space[i] = sed_cmd->translate[j + 1];
1005 if (pattern_space[i] == sed_cmd->translate[j]) {
1006 pattern_space[i] = sed_cmd->translate[j + 1];
1007 }
1008 }
1009 } 1049 }
1010 } 1050 }
1011 break; 1051 }
1012 case 'g': /* Replace pattern space with hold space */ 1052 }
1013 free(pattern_space); 1053 break;
1014 pattern_space = strdup(hold_space); 1054 case 'g': /* Replace pattern space with hold space */
1015 break; 1055 free(pattern_space);
1016 case 'h': /* Replace hold space with pattern space */ 1056 pattern_space = strdup(hold_space);
1017 free(hold_space); 1057 break;
1018 hold_space = strdup(pattern_space); 1058 case 'h': /* Replace hold space with pattern space */
1019 break; 1059 free(hold_space);
1020 case 'x': { /* Swap hold and pattern space */ 1060 hold_space = strdup(pattern_space);
1021 char *tmp; 1061 break;
1022 tmp = pattern_space; 1062 case 'x':{
1023 pattern_space = hold_space; 1063 /* Swap hold and pattern space */
1024 hold_space = tmp; 1064 char *tmp;
1025 } 1065
1066 tmp = pattern_space;
1067 pattern_space = hold_space;
1068 hold_space = tmp;
1069 }
1026 } 1070 }
1027 } 1071 }
1028 1072
@@ -1031,20 +1075,33 @@ static void process_file(FILE *file)
1031 */ 1075 */
1032 if (matched) { 1076 if (matched) {
1033 if ( 1077 if (
1034 /* this is a single-address command or... */ 1078 /* this is a single-address command or... */
1035 (sed_cmd->end_line == 0 && sed_cmd->end_match == NULL) || ( 1079 (sed_cmd->end_line == 0 && sed_cmd->end_match == NULL)
1036 /* If only one address */ 1080 || (
1037 1081 /* If only one address */
1038 /* we were in the middle of our address range (this 1082 /* we were in the middle of our address range (this
1039 * isn't the first time through) and.. */ 1083 * isn't the first time through) and.. */
1040 (still_in_range == 1) && ( 1084 (still_in_range == 1) && (
1041 /* this line number is the last address we're looking for or... */ 1085 /* this line number is the last address we're looking for or... */
1042 (sed_cmd->end_line && (sed_cmd->end_line == linenum)) || 1086 (sed_cmd->
1043 /* this line matches our last address regex */ 1087 end_line
1044 (sed_cmd->end_match && (regexec(sed_cmd->end_match, pattern_space, 0, NULL, 0) == 0)) 1088 && (sed_cmd->
1045 ) 1089 end_line ==
1046 ) 1090 linenum))
1047 ) { 1091 ||
1092 /* this line matches our last address regex */
1093 (sed_cmd->
1094 end_match
1095 &&
1096 (regexec
1097 (sed_cmd->
1098 end_match,
1099 pattern_space,
1100 0, NULL,
1101 0) == 0))
1102 )
1103 )
1104 ) {
1048 /* we're out of our address range */ 1105 /* we're out of our address range */
1049 still_in_range = 0; 1106 still_in_range = 0;
1050 } 1107 }
@@ -1056,13 +1113,13 @@ static void process_file(FILE *file)
1056 } 1113 }
1057 1114
1058 if (deleted) 1115 if (deleted)
1059 break; 1116 break;
1060 } 1117 }
1061 1118
1062 /* we will print the line unless we were told to be quiet or if the 1119 /* we will print the line unless we were told to be quiet or if the
1063 * line was altered (via a 'd'elete or 's'ubstitution), in which case 1120 * line was altered (via a 'd'elete or 's'ubstitution), in which case
1064 * the altered line was already printed */ 1121 * the altered line was already printed */
1065 if ((!be_quiet && !altered) || force_print){ 1122 if ((!be_quiet && !altered) || force_print) {
1066 puts(pattern_space); 1123 puts(pattern_space);
1067 } 1124 }
1068 free(pattern_space); 1125 free(pattern_space);
@@ -1083,20 +1140,21 @@ extern int sed_main(int argc, char **argv)
1083 /* do normal option parsing */ 1140 /* do normal option parsing */
1084 while ((opt = getopt(argc, argv, "ne:f:")) > 0) { 1141 while ((opt = getopt(argc, argv, "ne:f:")) > 0) {
1085 switch (opt) { 1142 switch (opt) {
1086 case 'n': 1143 case 'n':
1087 be_quiet++; 1144 be_quiet++;
1088 break; 1145 break;
1089 case 'e': { 1146 case 'e':{
1090 char *str_cmd = strdup(optarg); 1147 char *str_cmd = strdup(optarg);
1091 add_cmd_str(str_cmd); 1148
1092 free(str_cmd); 1149 add_cmd_str(str_cmd);
1093 break; 1150 free(str_cmd);
1094 } 1151 break;
1095 case 'f': 1152 }
1096 load_cmd_file(optarg); 1153 case 'f':
1097 break; 1154 load_cmd_file(optarg);
1098 default: 1155 break;
1099 bb_show_usage(); 1156 default:
1157 bb_show_usage();
1100 } 1158 }
1101 } 1159 }
1102 1160
@@ -1107,6 +1165,7 @@ extern int sed_main(int argc, char **argv)
1107 bb_show_usage(); 1165 bb_show_usage();
1108 else { 1166 else {
1109 char *str_cmd = strdup(argv[optind]); 1167 char *str_cmd = strdup(argv[optind]);
1168
1110 add_cmd_str(strdup(str_cmd)); 1169 add_cmd_str(strdup(str_cmd));
1111 free(str_cmd); 1170 free(str_cmd);
1112 optind++; 1171 optind++;
@@ -1118,10 +1177,10 @@ extern int sed_main(int argc, char **argv)
1118 * Otherwise, we process all the files specified. */ 1177 * Otherwise, we process all the files specified. */
1119 if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) { 1178 if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
1120 process_file(stdin); 1179 process_file(stdin);
1121 } 1180 } else {
1122 else {
1123 int i; 1181 int i;
1124 FILE *file; 1182 FILE *file;
1183
1125 for (i = optind; i < argc; i++) { 1184 for (i = optind; i < argc; i++) {
1126 file = bb_wfopen(argv[i], "r"); 1185 file = bb_wfopen(argv[i], "r");
1127 if (file) { 1186 if (file) {
@@ -1131,6 +1190,6 @@ extern int sed_main(int argc, char **argv)
1131 status = EXIT_FAILURE; 1190 status = EXIT_FAILURE;
1132 } 1191 }
1133 } 1192 }
1134 1193
1135 return status; 1194 return status;
1136} 1195}