From 464c5de00d3dfb5f01e866f703d95bbb2bb9443c Mon Sep 17 00:00:00 2001 From: Mark Whitley Date: Fri, 14 Jul 2000 23:24:00 +0000 Subject: 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. --- editors/sed.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'editors') diff --git a/editors/sed.c b/editors/sed.c index 40400fe3a..1f1e9069c 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -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); } -- cgit v1.2.3