diff options
author | Mark Whitley | 2000-07-14 23:24:00 +0000 |
---|---|---|
committer | Mark Whitley | 2000-07-14 23:24:00 +0000 |
commit | 464c5de00d3dfb5f01e866f703d95bbb2bb9443c (patch) | |
tree | c770d2ac4df0293c245dc246f93abf500545d865 /sed.c | |
parent | 70705d7c9681b4ea870ea11d0c569d81e5822169 (diff) | |
download | busybox-464c5de00d3dfb5f01e866f703d95bbb2bb9443c.zip busybox-464c5de00d3dfb5f01e866f703d95bbb2bb9443c.tar.gz |
Fixed a couple of buglets:
- add_cmd_str: segv's were being generated if there was a '# comment' line
(and probably other kinds of lines, too) that was not followed by a
semi-colon or whitespace
- parse_edit_cmd: was returning a wrong number (too low) for the index; it
was not accounting for backslashes eaten, for the fact that we start at the
3rd index in the string, or for the fact that we add an extra newline.
- parse_cmd_str: was returning a wrong number (again, too low) for the index
in the case of single-letter commands (p,d). There was some
over-compensation for this in the 'return' stmt at the end which also
needed some help.
- load_cmd_file: was not eating trailing newlines off the line read from the
command file. This had the deleterious effect of printing an extra newlines
after text displayed from edit (i,a,c) commands.
Diffstat (limited to 'sed.c')
-rw-r--r-- | sed.c | 35 |
1 files changed, 29 insertions, 6 deletions
@@ -307,6 +307,7 @@ out: static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr) { int idx = 0; + int slashes_eaten = 0; char *ptr; /* shorthand */ /* @@ -346,19 +347,32 @@ static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr) while (ptr[idx] != '\\' && (ptr[idx+1] != '\n' || ptr[idx+1] != '\r')) { idx++; if (!ptr[idx]) { - ptr[idx] = '\n'; - ptr[idx+1] = 0; - return idx; + goto out; } } /* move the newline over the '\' before it (effectively eats the '\') */ memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1])); ptr[strlen(ptr)-1] = 0; + slashes_eaten++; /* substitue \r for \n if needed */ if (ptr[idx] == '\r') ptr[idx] = '\n'; } +out: + ptr[idx] = '\n'; + ptr[idx+1] = 0; + + /* this accounts for discrepancies between the modified string and the + * original string passed in to this function */ + idx += slashes_eaten; + + /* this accounts for the fact that A) we started at index 3, not at index + * 0 and B) that we added an extra '\n' at the end (if you think the next + * line should read 'idx += 4' remember, arrays are zero-based) */ + + idx += 3; + return idx; } @@ -398,9 +412,13 @@ static char *parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) fatalError("only a beginning address can be specified for edit commands\n"); idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]); } + /* if it was a single-letter command (such as 'p' or 'd') we need to + * increment the index past that command */ + else + idx++; /* give back whatever's left over */ - return (char *)&cmdstr[++idx]; + return (char *)&cmdstr[idx]; } static void add_cmd_str(const char *cmdstr) @@ -412,7 +430,7 @@ static void add_cmd_str(const char *cmdstr) /* trim leading whitespace and semicolons */ memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr)); /* if we ate the whole thing, that means there was just trailing - * whitespace or a final semicolon. either way, get out */ + * whitespace or a final / no-op semicolon. either way, get out */ if (strlen(mystr) == 0) return; /* if this is a comment, jump past it and keep going */ @@ -427,7 +445,7 @@ static void add_cmd_str(const char *cmdstr) /* load command string into new array element, get remainder */ mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr); - } while (mystr); + } while (mystr && strlen(mystr)); } @@ -447,7 +465,12 @@ static void load_cmd_file(char *filename) (nextline = get_line_from_file(cmdfile)) != NULL) { line = realloc(line, strlen(line) + strlen(nextline) + 1); strcat(line, nextline); + free(nextline); } + /* eat trailing newline (if any) --if I don't do this, edit commands + * (aic) will print an extra newline */ + if (line[strlen(line)-1] == '\n') + line[strlen(line)-1] = 0; add_cmd_str(line); free(line); } |