diff options
Diffstat (limited to 'editors/sed.c')
-rw-r--r-- | editors/sed.c | 687 |
1 files changed, 354 insertions, 333 deletions
diff --git a/editors/sed.c b/editors/sed.c index e261415..3e33529 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -131,7 +131,7 @@ void sed_free_and_close_stuff(void) while (sed_cmd) { sed_cmd_t *sed_cmd_next = sed_cmd->next; - if(sed_cmd->file) + if (sed_cmd->file) xprint_and_close_file(sed_cmd->file); if (sed_cmd->beg_match) { @@ -151,9 +151,9 @@ void sed_free_and_close_stuff(void) sed_cmd = sed_cmd_next; } - if(bbg.hold_space) free(bbg.hold_space); + if (bbg.hold_space) free(bbg.hold_space); - while(bbg.current_input_file<bbg.input_file_count) + while (bbg.current_input_file < bbg.input_file_count) fclose(bbg.input_file_list[bbg.current_input_file++]); } #endif @@ -162,31 +162,31 @@ void sed_free_and_close_stuff(void) static void cleanup_outname(void) { - if(bbg.outname) unlink(bbg.outname); + if (bbg.outname) unlink(bbg.outname); } /* strdup, replacing "\n" with '\n', and "\delimiter" with 'delimiter' */ static void parse_escapes(char *dest, char *string, int len, char from, char to) { - int i=0; + int i = 0; - while(i<len) { - if(string[i] == '\\') { - if(!to || string[i+1] == from) { + while (i < len) { + if (string[i] == '\\') { + if (!to || string[i+1] == from) { *(dest++) = to ? to : string[i+1]; - i+=2; + i += 2; continue; - } else *(dest++)=string[i++]; + } else *(dest++) = string[i++]; } *(dest++) = string[i++]; } - *dest=0; + *dest = 0; } static char *copy_parsing_escapes(char *string, int len) { - char *dest=xmalloc(len+1); + char *dest = xmalloc(len+1); parse_escapes(dest,string,len,'n','\n'); return dest; @@ -243,7 +243,7 @@ static int parse_regex_delim(char *cmdstr, char **match, char **replace) * (typically a 'slash') is now our regexp delimiter... */ if (*cmdstr == '\0') bb_error_msg_and_die("bad format in substitution expression"); - delimiter = *(cmdstr_ptr++); + delimiter = *cmdstr_ptr++; /* save the match string */ idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr); @@ -275,11 +275,11 @@ static int get_address(char *my_str, int *linenum, regex_t ** regex) char delimiter; char *temp; - if (*my_str == '\\') delimiter = *(++pos); - else delimiter = '/'; + delimiter = '/'; + if (*my_str == '\\') delimiter = *++pos; next = index_of_next_unescaped_regexp_delim(delimiter, ++pos); temp = copy_parsing_escapes(pos,next); - *regex = (regex_t *) xmalloc(sizeof(regex_t)); + *regex = xmalloc(sizeof(regex_t)); xregcomp(*regex, temp, bbg.regex_type|REG_NEWLINE); free(temp); /* Move position to next character after last delimiter */ @@ -291,17 +291,19 @@ static int get_address(char *my_str, int *linenum, regex_t ** regex) /* Grab a filename. Whitespace at start is skipped, then goes to EOL. */ static int parse_file_cmd(sed_cmd_t *sed_cmd, char *filecmdstr, char **retval) { - int start = 0, idx, hack=0; + int start = 0, idx, hack = 0; /* Skip whitespace, then grab filename to end of line */ while (isspace(filecmdstr[start])) start++; - idx=start; - while(filecmdstr[idx] && filecmdstr[idx]!='\n') idx++; + idx = start; + while (filecmdstr[idx] && filecmdstr[idx] != '\n') idx++; + /* If lines glued together, put backslash back. */ - if(filecmdstr[idx]=='\n') hack=1; - if(idx==start) bb_error_msg_and_die("Empty filename"); + if (filecmdstr[idx] == '\n') hack = 1; + if (idx == start) + bb_error_msg_and_die("empty filename"); *retval = xstrndup(filecmdstr+start, idx-start+hack+1); - if(hack) *(idx+*retval)='\\'; + if (hack) (*retval)[idx] = '\\'; return idx; } @@ -327,20 +329,20 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, char *substr) /* process the flags */ - sed_cmd->which_match=1; + sed_cmd->which_match = 1; while (substr[++idx]) { /* Parse match number */ - if(isdigit(substr[idx])) { - if(match[0]!='^') { + if (isdigit(substr[idx])) { + if (match[0] != '^') { /* Match 0 treated as all, multiple matches we take the last one. */ - char *pos=substr+idx; - sed_cmd->which_match=(unsigned short)strtol(substr+idx,&pos,10); - idx=pos-substr; + char *pos = substr+idx; + sed_cmd->which_match = (unsigned short)strtol(substr+idx,&pos,10); + idx = pos-substr; } continue; } /* Skip spaces */ - if(isspace(substr[idx])) continue; + if (isspace(substr[idx])) continue; switch (substr[idx]) { /* Replace all occurrences */ @@ -355,7 +357,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, char *substr) case 'w': { char *temp; - idx+=parse_file_cmd(sed_cmd,substr+idx,&temp); + idx += parse_file_cmd(sed_cmd,substr+idx,&temp); break; } @@ -365,7 +367,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, char *substr) break; /* Comment */ case '#': - while(substr[++idx]); + while (substr[++idx]) /*skip all*/; /* Fall through */ /* End of command */ case ';': @@ -393,29 +395,32 @@ out: static char *parse_cmd_args(sed_cmd_t *sed_cmd, char *cmdstr) { /* handle (s)ubstitution command */ - if (sed_cmd->cmd == 's') cmdstr += parse_subst_cmd(sed_cmd, cmdstr); + if (sed_cmd->cmd == 's') + cmdstr += parse_subst_cmd(sed_cmd, cmdstr); /* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */ else if (strchr("aic", sed_cmd->cmd)) { if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c') bb_error_msg_and_die ("only a beginning address can be specified for edit commands"); - for(;;) { - if(*cmdstr=='\n' || *cmdstr=='\\') { + for (;;) { + if (*cmdstr == '\n' || *cmdstr == '\\') { + cmdstr++; + break; + } else if (isspace(*cmdstr)) cmdstr++; + else break; - } else if(isspace(*cmdstr)) cmdstr++; - else break; } sed_cmd->string = xstrdup(cmdstr); parse_escapes(sed_cmd->string,sed_cmd->string,strlen(cmdstr),0,0); cmdstr += strlen(cmdstr); /* handle file cmds: (r)ead */ - } else if(strchr("rw", sed_cmd->cmd)) { + } else if (strchr("rw", sed_cmd->cmd)) { if (sed_cmd->end_line || sed_cmd->end_match) - bb_error_msg_and_die("Command only uses one address"); + bb_error_msg_and_die("command only uses one address"); cmdstr += parse_file_cmd(sed_cmd, cmdstr, &sed_cmd->string); - if(sed_cmd->cmd=='w') - sed_cmd->file=xfopen(sed_cmd->string,"w"); + if (sed_cmd->cmd == 'w') + sed_cmd->file = xfopen(sed_cmd->string,"w"); /* handle branch commands */ } else if (strchr(":btT", sed_cmd->cmd)) { int length; @@ -430,17 +435,17 @@ static char *parse_cmd_args(sed_cmd_t *sed_cmd, char *cmdstr) /* translation command */ else if (sed_cmd->cmd == 'y') { char *match, *replace; - int i=cmdstr[0]; + int i = cmdstr[0]; - cmdstr+=parse_regex_delim(cmdstr, &match, &replace)+1; + cmdstr += parse_regex_delim(cmdstr, &match, &replace)+1; /* \n already parsed, but \delimiter needs unescaping. */ parse_escapes(match,match,strlen(match),i,i); parse_escapes(replace,replace,strlen(replace),i,i); sed_cmd->string = xzalloc((strlen(match) + 1) * 2); for (i = 0; match[i] && replace[i]; i++) { - sed_cmd->string[i * 2] = match[i]; - sed_cmd->string[(i * 2) + 1] = replace[i]; + sed_cmd->string[i*2] = match[i]; + sed_cmd->string[i*2+1] = replace[i]; } free(match); free(replace); @@ -449,11 +454,11 @@ static char *parse_cmd_args(sed_cmd_t *sed_cmd, char *cmdstr) * then it must be an invalid command. */ else if (strchr("dDgGhHlnNpPqx={}", sed_cmd->cmd) == 0) { - bb_error_msg_and_die("Unsupported command %c", sed_cmd->cmd); + bb_error_msg_and_die("unsupported command %c", sed_cmd->cmd); } /* give back whatever's left over */ - return (cmdstr); + return cmdstr; } @@ -472,26 +477,29 @@ static void add_cmd(char *cmdstr) } /* If this line ends with backslash, request next line. */ - temp=strlen(cmdstr); - if(temp && cmdstr[temp-1]=='\\') { - if (!bbg.add_cmd_line) bbg.add_cmd_line = xstrdup(cmdstr); + temp = strlen(cmdstr); + if (temp && cmdstr[temp-1] == '\\') { + if (!bbg.add_cmd_line) + bbg.add_cmd_line = xstrdup(cmdstr); bbg.add_cmd_line[temp-1] = 0; return; } /* Loop parsing all commands in this line. */ - while(*cmdstr) { + while (*cmdstr) { /* Skip leading whitespace and semicolons */ cmdstr += strspn(cmdstr, semicolon_whitespace); /* If no more commands, exit. */ - if(!*cmdstr) break; + if (!*cmdstr) break; /* if this is a comment, jump past it and keep going */ if (*cmdstr == '#') { /* "#n" is the same as using -n on the command line */ - if (cmdstr[1] == 'n') bbg.be_quiet++; - if(!(cmdstr=strpbrk(cmdstr, "\n\r"))) break; + if (cmdstr[1] == 'n') + bbg.be_quiet++; + cmdstr = strpbrk(cmdstr, "\n\r"); + if (!cmdstr) break; continue; } @@ -512,7 +520,8 @@ static void add_cmd(char *cmdstr) cmdstr++; idx = get_address(cmdstr, &sed_cmd->end_line, &sed_cmd->end_match); - if (!idx) bb_error_msg_and_die("no address after comma"); + if (!idx) + bb_error_msg_and_die("no address after comma"); cmdstr += idx; } @@ -529,7 +538,8 @@ static void add_cmd(char *cmdstr) } /* last part (mandatory) will be a command */ - if (!*cmdstr) bb_error_msg_and_die("missing command"); + if (!*cmdstr) + bb_error_msg_and_die("missing command"); sed_cmd->cmd = *(cmdstr++); cmdstr = parse_cmd_args(sed_cmd, cmdstr); @@ -549,10 +559,10 @@ static void add_cmd(char *cmdstr) static void pipe_putc(char c) { - if(bbg.pipeline.idx==bbg.pipeline.len) { + if (bbg.pipeline.idx == bbg.pipeline.len) { bbg.pipeline.buf = xrealloc(bbg.pipeline.buf, - bbg.pipeline.len + PIPE_GROW); - bbg.pipeline.len+=PIPE_GROW; + bbg.pipeline.len + PIPE_GROW); + bbg.pipeline.len += PIPE_GROW; } bbg.pipeline.buf[bbg.pipeline.idx++] = c; } @@ -564,22 +574,26 @@ static void do_subst_w_backrefs(char *line, char *replace) /* go through the replacement string */ for (i = 0; replace[i]; i++) { /* if we find a backreference (\1, \2, etc.) print the backref'ed * text */ - if (replace[i] == '\\' && replace[i+1]>='0' && replace[i+1]<='9') { - int backref=replace[++i]-'0'; + if (replace[i] == '\\' && replace[i+1] >= '0' && replace[i+1] <= '9') { + int backref = replace[++i]-'0'; /* print out the text held in bbg.regmatch[backref] */ - if(bbg.regmatch[backref].rm_so != -1) - for (j = bbg.regmatch[backref].rm_so; - j < bbg.regmatch[backref].rm_eo; j++) pipe_putc(line[j]); + if (bbg.regmatch[backref].rm_so != -1) { + j = bbg.regmatch[backref].rm_so; + while (j < bbg.regmatch[backref].rm_eo) + pipe_putc(line[j++]); + } } /* if we find a backslash escaped character, print the character */ else if (replace[i] == '\\') pipe_putc(replace[++i]); /* if we find an unescaped '&' print out the whole matched text. */ - else if (replace[i] == '&') - for (j = bbg.regmatch[0].rm_so; j < bbg.regmatch[0].rm_eo; j++) - pipe_putc(line[j]); + else if (replace[i] == '&') { + j = bbg.regmatch[0].rm_so; + while (j < bbg.regmatch[0].rm_eo) + pipe_putc(line[j++]); + } /* Otherwise just output the character. */ else pipe_putc(replace[i]); } @@ -589,24 +603,25 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line) { char *oldline = *line; int altered = 0; - int match_count=0; + int match_count = 0; regex_t *current_regex; /* Handle empty regex. */ if (sed_cmd->sub_match == NULL) { current_regex = bbg.previous_regex_ptr; - if(!current_regex) + if (!current_regex) bb_error_msg_and_die("No previous regexp."); - } else bbg.previous_regex_ptr = current_regex = sed_cmd->sub_match; + } else + bbg.previous_regex_ptr = current_regex = sed_cmd->sub_match; /* Find the first match */ - if(REG_NOMATCH==regexec(current_regex, oldline, 10, bbg.regmatch, 0)) + if (REG_NOMATCH == regexec(current_regex, oldline, 10, bbg.regmatch, 0)) return 0; /* Initialize temporary output buffer. */ - bbg.pipeline.buf=xmalloc(PIPE_GROW); - bbg.pipeline.len=PIPE_GROW; - bbg.pipeline.idx=0; + bbg.pipeline.buf = xmalloc(PIPE_GROW); + bbg.pipeline.len = PIPE_GROW; + bbg.pipeline.idx = 0; /* Now loop through, substituting for matches */ do { @@ -616,8 +631,8 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line) echo " a.b" | busybox sed 's [^ .]* x g' The match_count check is so not to break echo "hi" | busybox sed 's/^/!/g' */ - if(!bbg.regmatch[0].rm_so && !bbg.regmatch[0].rm_eo && match_count) { - pipe_putc(*(oldline++)); + if (!bbg.regmatch[0].rm_so && !bbg.regmatch[0].rm_eo && match_count) { + pipe_putc(*oldline++); continue; } @@ -625,14 +640,15 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line) /* If we aren't interested in this match, output old line to end of match and continue */ - if(sed_cmd->which_match && sed_cmd->which_match!=match_count) { - for(i=0;i<bbg.regmatch[0].rm_eo;i++) - pipe_putc(*(oldline++)); + if (sed_cmd->which_match && sed_cmd->which_match!=match_count) { + for (i = 0; i < bbg.regmatch[0].rm_eo; i++) + pipe_putc(*oldline++); continue; } /* print everything before the match */ - for (i = 0; i < bbg.regmatch[0].rm_so; i++) pipe_putc(oldline[i]); + for (i = 0; i < bbg.regmatch[0].rm_so; i++) + pipe_putc(oldline[i]); /* then print the substitution string */ do_subst_w_backrefs(oldline, sed_cmd->string); @@ -648,7 +664,8 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line) /* Copy rest of string into output pipeline */ - while(*oldline) pipe_putc(*(oldline++)); + while (*oldline) + pipe_putc(*oldline++); pipe_putc(0); free(*line); @@ -662,11 +679,11 @@ static sed_cmd_t *branch_to(char *label) sed_cmd_t *sed_cmd; for (sed_cmd = bbg.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { - if ((sed_cmd->cmd == ':') && (sed_cmd->string) && (strcmp(sed_cmd->string, label) == 0)) { - return (sed_cmd); + if (sed_cmd->cmd == ':' && sed_cmd->string && !strcmp(sed_cmd->string, label)) { + return sed_cmd; } } - bb_error_msg_and_die("Can't find label for jump to `%s'", label); + bb_error_msg_and_die("can't find label for jump to '%s'", label); } static void append(char *s) @@ -679,7 +696,7 @@ static void flush_append(void) char *data; /* Output appended lines. */ - while((data = (char *)llist_pop(&bbg.append_head))) { + while ((data = (char *)llist_pop(&bbg.append_head))) { fprintf(bbg.nonstdout,"%s\n",data); free(data); } @@ -687,7 +704,7 @@ static void flush_append(void) static void add_input_file(FILE *file) { - bbg.input_file_list=xrealloc(bbg.input_file_list, + bbg.input_file_list = xrealloc(bbg.input_file_list, (bbg.input_file_count + 1) * sizeof(FILE *)); bbg.input_file_list[bbg.input_file_count++] = file; } @@ -697,18 +714,19 @@ static void add_input_file(FILE *file) */ static char *get_next_line(int *no_newline) { - char *temp=NULL; + char *temp = NULL; int len; flush_append(); - while (bbg.current_input_file<bbg.input_file_count) { + while (bbg.current_input_file < bbg.input_file_count) { temp = bb_get_chunk_from_file(bbg.input_file_list[bbg.current_input_file],&len); if (temp) { - *no_newline = !(len && temp[len-1]=='\n'); + *no_newline = !(len && temp[len-1] == '\n'); if (!*no_newline) temp[len-1] = 0; break; // Close this file and advance to next one - } else fclose(bbg.input_file_list[bbg.current_input_file++]); + } else + fclose(bbg.input_file_list[bbg.current_input_file++]); } return temp; @@ -720,11 +738,11 @@ static char *get_next_line(int *no_newline) static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int no_newline) { - if(missing_newline) fputc('\n',file); + if (missing_newline) fputc('\n',file); fputs(s,file); - if(!no_newline) fputc('\n',file); + if (!no_newline) fputc('\n',file); - if(ferror(file)) { + if (ferror(file)) { xfunc_error_retval = 4; /* It's what gnu sed exits with... */ bb_error_msg_and_die(bb_msg_write_error); } @@ -739,20 +757,21 @@ static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int no_n static void process_files(void) { char *pattern_space, *next_line; - int linenum = 0, missing_newline=0; - int no_newline,next_no_newline=0; + int linenum = 0, missing_newline = 0; + int no_newline,next_no_newline = 0; /* Prime the pump */ next_line = get_next_line(&next_no_newline); /* go through every line in each file */ - for(;;) { + for (;;) { sed_cmd_t *sed_cmd; - int substituted=0; + int substituted = 0; /* Advance to next line. Stop if out of lines. */ - if(!(pattern_space=next_line)) break; - no_newline=next_no_newline; + pattern_space = next_line; + if (!pattern_space) break; + no_newline = next_no_newline; /* Read one line in advance so we can act on the last line, * the '$' address */ @@ -760,8 +779,7 @@ static void process_files(void) linenum++; restart: /* for every line, go through all the commands */ - for (sed_cmd = bbg.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) - { + for (sed_cmd = bbg.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { int old_matched, matched; old_matched = sed_cmd->in_match; @@ -769,21 +787,16 @@ restart: /* Determine if this command matches this line: */ /* Are we continuing a previous multi-line match? */ - sed_cmd->in_match = sed_cmd->in_match - - /* Or is no range necessary? */ + /* Or is no range necessary? */ || (!sed_cmd->beg_line && !sed_cmd->end_line && !sed_cmd->beg_match && !sed_cmd->end_match) - - /* Or did we match the start of a numerical range? */ + /* Or did we match the start of a numerical range? */ || (sed_cmd->beg_line > 0 && (sed_cmd->beg_line == linenum)) - - /* Or does this line match our begin address regex? */ + /* Or does this line match our begin address regex? */ || (sed_cmd->beg_match && !regexec(sed_cmd->beg_match, pattern_space, 0, NULL, 0)) - - /* Or did we match last line of input? */ + /* Or did we match last line of input? */ || (sed_cmd->beg_line == -1 && next_line == NULL); /* Snapshot the value */ @@ -792,7 +805,7 @@ restart: /* Is this line the end of the current match? */ - if(matched) { + if (matched) { sed_cmd->in_match = !( /* has the ending line come, or is this a single address command? */ (sed_cmd->end_line ? @@ -807,9 +820,10 @@ restart: /* Skip blocks of commands we didn't match. */ if (sed_cmd->cmd == '{') { - if(sed_cmd->invert ? matched : !matched) - while(sed_cmd && sed_cmd->cmd!='}') sed_cmd=sed_cmd->next; - if(!sed_cmd) bb_error_msg_and_die("Unterminated {"); + if (sed_cmd->invert ? matched : !matched) + while (sed_cmd && sed_cmd->cmd != '}') + sed_cmd = sed_cmd->next; + if (!sed_cmd) bb_error_msg_and_die("unterminated {"); continue; } @@ -823,230 +837,234 @@ restart: /* actual sedding */ switch (sed_cmd->cmd) { - /* Print line number */ - case '=': - fprintf(bbg.nonstdout,"%d\n", linenum); - break; - - /* Write the current pattern space up to the first newline */ - case 'P': - { - char *tmp = strchr(pattern_space, '\n'); + /* Print line number */ + case '=': + fprintf(bbg.nonstdout, "%d\n", linenum); + break; - if (tmp) { - *tmp = '\0'; - sed_puts(pattern_space,1); - *tmp = '\n'; - break; - } - /* Fall Through */ - } + /* Write the current pattern space up to the first newline */ + case 'P': + { + char *tmp = strchr(pattern_space, '\n'); - /* Write the current pattern space to output */ - case 'p': - sed_puts(pattern_space,no_newline); + if (tmp) { + *tmp = '\0'; + sed_puts(pattern_space,1); + *tmp = '\n'; break; - /* Delete up through first newline */ - case 'D': - { - char *tmp = strchr(pattern_space,'\n'); - - if(tmp) { - tmp=xstrdup(tmp+1); - free(pattern_space); - pattern_space=tmp; - goto restart; - } } - /* discard this line. */ - case 'd': - goto discard_line; + /* Fall Through */ + } - /* Substitute with regex */ - case 's': - if(do_subst_command(sed_cmd, &pattern_space)) { - substituted|=1; + /* Write the current pattern space to output */ + case 'p': + sed_puts(pattern_space,no_newline); + break; + /* Delete up through first newline */ + case 'D': + { + char *tmp = strchr(pattern_space,'\n'); + + if (tmp) { + tmp = xstrdup(tmp+1); + free(pattern_space); + pattern_space = tmp; + goto restart; + } + } + /* discard this line. */ + case 'd': + goto discard_line; - /* handle p option */ - if(sed_cmd->sub_p) - sed_puts(pattern_space,no_newline); - /* handle w option */ - if(sed_cmd->file) - sed_cmd->no_newline=puts_maybe_newline(pattern_space, sed_cmd->file, sed_cmd->no_newline, no_newline); + /* Substitute with regex */ + case 's': + if (do_subst_command(sed_cmd, &pattern_space)) { + substituted |= 1; - } - break; + /* handle p option */ + if (sed_cmd->sub_p) + sed_puts(pattern_space,no_newline); + /* handle w option */ + if (sed_cmd->file) + sed_cmd->no_newline = puts_maybe_newline(pattern_space, sed_cmd->file, sed_cmd->no_newline, no_newline); - /* Append line to linked list to be printed later */ - case 'a': - { - append(sed_cmd->string); - break; } + break; - /* Insert text before this line */ - case 'i': - sed_puts(sed_cmd->string,1); - break; + /* Append line to linked list to be printed later */ + case 'a': + { + append(sed_cmd->string); + break; + } - /* Cut and paste text (replace) */ - case 'c': - /* Only triggers on last line of a matching range. */ - if (!sed_cmd->in_match) sed_puts(sed_cmd->string,0); - goto discard_line; + /* Insert text before this line */ + case 'i': + sed_puts(sed_cmd->string,1); + break; + + /* Cut and paste text (replace) */ + case 'c': + /* Only triggers on last line of a matching range. */ + if (!sed_cmd->in_match) + sed_puts(sed_cmd->string,0); + goto discard_line; + + /* Read file, append contents to output */ + case 'r': + { + FILE *rfile; + + rfile = fopen(sed_cmd->string, "r"); + if (rfile) { + char *line; + + while ((line = xmalloc_getline(rfile)) + != NULL) + append(line); + xprint_and_close_file(rfile); + } - /* Read file, append contents to output */ - case 'r': - { - FILE *rfile; + break; + } - rfile = fopen(sed_cmd->string, "r"); - if (rfile) { - char *line; - - while ((line = xmalloc_getline(rfile)) - != NULL) - append(line); - xprint_and_close_file(rfile); - } + /* Write pattern space to file. */ + case 'w': + sed_cmd->no_newline = puts_maybe_newline(pattern_space,sed_cmd->file, sed_cmd->no_newline,no_newline); + break; + /* Read next line from input */ + case 'n': + if (!bbg.be_quiet) + sed_puts(pattern_space,no_newline); + if (next_line) { + free(pattern_space); + pattern_space = next_line; + no_newline = next_no_newline; + next_line = get_next_line(&next_no_newline); + linenum++; break; } - - /* Write pattern space to file. */ - case 'w': - sed_cmd->no_newline=puts_maybe_newline(pattern_space,sed_cmd->file, sed_cmd->no_newline,no_newline); - break; - - /* Read next line from input */ - case 'n': - if (!bbg.be_quiet) - sed_puts(pattern_space,no_newline); - if (next_line) { - free(pattern_space); - pattern_space = next_line; - no_newline=next_no_newline; - next_line = get_next_line(&next_no_newline); - linenum++; - break; - } - /* fall through */ - - /* Quit. End of script, end of input. */ - case 'q': - /* Exit the outer while loop */ + /* fall through */ + + /* Quit. End of script, end of input. */ + case 'q': + /* Exit the outer while loop */ + free(next_line); + next_line = NULL; + goto discard_commands; + + /* Append the next line to the current line */ + case 'N': + { + /* If no next line, jump to end of script and exit. */ + if (next_line == NULL) { + /* Jump to end of script and exit */ free(next_line); next_line = NULL; - goto discard_commands; - - /* Append the next line to the current line */ - case 'N': - { - /* If no next line, jump to end of script and exit. */ - if (next_line == NULL) { - /* Jump to end of script and exit */ - free(next_line); - next_line = NULL; - goto discard_line; - /* append next_line, read new next_line. */ - } else { - int len=strlen(pattern_space); - - pattern_space = realloc(pattern_space, len + strlen(next_line) + 2); - pattern_space[len]='\n'; - strcpy(pattern_space+len+1, next_line); - no_newline=next_no_newline; - next_line = get_next_line(&next_no_newline); - linenum++; - } - break; + goto discard_line; + /* append next_line, read new next_line. */ + } else { + int len = strlen(pattern_space); + + pattern_space = realloc(pattern_space, len + strlen(next_line) + 2); + pattern_space[len] = '\n'; + strcpy(pattern_space + len+1, next_line); + no_newline = next_no_newline; + next_line = get_next_line(&next_no_newline); + linenum++; } + break; + } - /* Test/branch if substitution occurred */ - case 't': - if(!substituted) break; - substituted=0; - /* Fall through */ - /* Test/branch if substitution didn't occur */ - case 'T': - if (substituted) break; - /* Fall through */ - /* Branch to label */ - case 'b': - if (!sed_cmd->string) goto discard_commands; - else sed_cmd = branch_to(sed_cmd->string); - break; - /* Transliterate characters */ - case 'y': - { - int i; - - for (i = 0; pattern_space[i]; i++) { - int j; - - for (j = 0; sed_cmd->string[j]; j += 2) { - if (pattern_space[i] == sed_cmd->string[j]) { - pattern_space[i] = sed_cmd->string[j + 1]; - break; - } + /* Test/branch if substitution occurred */ + case 't': + if (!substituted) break; + substituted = 0; + /* Fall through */ + /* Test/branch if substitution didn't occur */ + case 'T': + if (substituted) break; + /* Fall through */ + /* Branch to label */ + case 'b': + if (!sed_cmd->string) goto discard_commands; + else sed_cmd = branch_to(sed_cmd->string); + break; + /* Transliterate characters */ + case 'y': + { + int i; + + for (i = 0; pattern_space[i]; i++) { + int j; + + for (j = 0; sed_cmd->string[j]; j += 2) { + if (pattern_space[i] == sed_cmd->string[j]) { + pattern_space[i] = sed_cmd->string[j + 1]; + break; } } - - break; } - case 'g': /* Replace pattern space with hold space */ - free(pattern_space); - pattern_space = xstrdup(bbg.hold_space ? bbg.hold_space : ""); - break; - case 'G': /* Append newline and hold space to pattern space */ - { - int pattern_space_size = 2; - int hold_space_size = 0; - - if (pattern_space) - pattern_space_size += strlen(pattern_space); - if (bbg.hold_space) - hold_space_size = strlen(bbg.hold_space); - pattern_space = xrealloc(pattern_space, - pattern_space_size + hold_space_size); - if (pattern_space_size == 2) pattern_space[0]=0; - strcat(pattern_space, "\n"); - if (bbg.hold_space) - strcat(pattern_space, bbg.hold_space); - no_newline=0; - - break; - } - case 'h': /* Replace hold space with pattern space */ - free(bbg.hold_space); - bbg.hold_space = xstrdup(pattern_space); - break; - case 'H': /* Append newline and pattern space to hold space */ - { - int hold_space_size = 2; - int pattern_space_size = 0; - - if (bbg.hold_space) - hold_space_size += strlen(bbg.hold_space); - if (pattern_space) - pattern_space_size = strlen(pattern_space); - bbg.hold_space = xrealloc(bbg.hold_space, - hold_space_size + pattern_space_size); - - if (hold_space_size == 2) *bbg.hold_space=0; - strcat(bbg.hold_space, "\n"); - if (pattern_space) strcat(bbg.hold_space, pattern_space); - break; - } - case 'x': /* Exchange hold and pattern space */ - { - char *tmp = pattern_space; - pattern_space = bbg.hold_space ? : xzalloc(1); - no_newline=0; - bbg.hold_space = tmp; - break; - } + break; + } + case 'g': /* Replace pattern space with hold space */ + free(pattern_space); + pattern_space = xstrdup(bbg.hold_space ? bbg.hold_space : ""); + break; + case 'G': /* Append newline and hold space to pattern space */ + { + int pattern_space_size = 2; + int hold_space_size = 0; + + if (pattern_space) + pattern_space_size += strlen(pattern_space); + if (bbg.hold_space) + hold_space_size = strlen(bbg.hold_space); + pattern_space = xrealloc(pattern_space, + pattern_space_size + hold_space_size); + if (pattern_space_size == 2) + pattern_space[0] = 0; + strcat(pattern_space, "\n"); + if (bbg.hold_space) + strcat(pattern_space, bbg.hold_space); + no_newline = 0; + + break; + } + case 'h': /* Replace hold space with pattern space */ + free(bbg.hold_space); + bbg.hold_space = xstrdup(pattern_space); + break; + case 'H': /* Append newline and pattern space to hold space */ + { + int hold_space_size = 2; + int pattern_space_size = 0; + + if (bbg.hold_space) + hold_space_size += strlen(bbg.hold_space); + if (pattern_space) + pattern_space_size = strlen(pattern_space); + bbg.hold_space = xrealloc(bbg.hold_space, + hold_space_size + pattern_space_size); + + if (hold_space_size == 2) + *bbg.hold_space = 0; + strcat(bbg.hold_space, "\n"); + if (pattern_space) + strcat(bbg.hold_space, pattern_space); + + break; + } + case 'x': /* Exchange hold and pattern space */ + { + char *tmp = pattern_space; + pattern_space = bbg.hold_space ? : xzalloc(1); + no_newline = 0; + bbg.hold_space = tmp; + break; + } } } } @@ -1071,15 +1089,15 @@ discard_line: static void add_cmd_block(char *cmdstr) { - int go=1; - char *temp=xstrdup(cmdstr),*temp2=temp; + int go = 1; + char *temp = xstrdup(cmdstr), *temp2 = temp; - while(go) { - int len=strcspn(temp2,"\n"); - if(!temp2[len]) go=0; - else temp2[len]=0; + while (go) { + int len = strcspn(temp2,"\n"); + if (!temp2[len]) go = 0; + else temp2[len] = 0; add_cmd(temp2); - temp2+=len+1; + temp2 += len+1; } free(temp); } @@ -1119,7 +1137,7 @@ int sed_main(int argc, char **argv) if (ENABLE_FEATURE_CLEAN_UP) atexit(sed_free_and_close_stuff); /* Lie to autoconf when it starts asking stupid questions. */ - if(argc==2 && !strcmp(argv[1],"--version")) { + if (argc==2 && !strcmp(argv[1],"--version")) { printf("This is not GNU sed version 4.0\n"); exit(0); } @@ -1143,7 +1161,7 @@ int sed_main(int argc, char **argv) add_files_link(opt_f); } /* if we didn't get a pattern from -e or -f, use argv[optind] */ - if(!(opt & 0x18)) { + if (!(opt & 0x18)) { if (argv[optind] == NULL) bb_show_usage(); else @@ -1159,7 +1177,8 @@ int sed_main(int argc, char **argv) * files were specified or '-' was specified, take input from stdin. * Otherwise, we process all the files specified. */ if (argv[optind] == NULL) { - if(bbg.in_place) bb_error_msg_and_die(bb_msg_requires_arg, "-i"); + if (bbg.in_place) + bb_error_msg_and_die(bb_msg_requires_arg, "-i"); add_input_file(stdin); process_files(); } else { @@ -1170,7 +1189,7 @@ int sed_main(int argc, char **argv) struct stat statbuf; int nonstdoutfd; - if(!strcmp(argv[i], "-") && !bbg.in_place) { + if (!strcmp(argv[i], "-") && !bbg.in_place) { add_input_file(stdin); process_files(); continue; @@ -1180,16 +1199,16 @@ int sed_main(int argc, char **argv) status = EXIT_FAILURE; continue; } - if(!bbg.in_place) { + if (!bbg.in_place) { add_input_file(file); continue; } - bbg.outname=xstrndup(argv[i],strlen(argv[i])+6); - strcat(bbg.outname,"XXXXXX"); - if(-1==(nonstdoutfd=mkstemp(bbg.outname))) + bbg.outname = xasprintf("%sXXXXXX", argv[i]); + nonstdoutfd = mkstemp(bbg.outname); + if (-1 == nonstdoutfd) bb_error_msg_and_die("no temp file"); - bbg.nonstdout=fdopen(nonstdoutfd,"w"); + bbg.nonstdout = fdopen(nonstdoutfd,"w"); /* Set permissions of output file */ @@ -1199,13 +1218,15 @@ int sed_main(int argc, char **argv) process_files(); fclose(bbg.nonstdout); - bbg.nonstdout=stdout; - unlink(argv[i]); + bbg.nonstdout = stdout; + /* unlink(argv[i]); */ + // FIXME: error check / message? rename(bbg.outname,argv[i]); free(bbg.outname); - bbg.outname=0; + bbg.outname = 0; } - if(bbg.input_file_count>bbg.current_input_file) process_files(); + if (bbg.input_file_count > bbg.current_input_file) + process_files(); } return status; |