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.
This commit is contained in:
parent
70705d7c96
commit
464c5de00d
@ -307,6 +307,7 @@ out:
|
|||||||
static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
|
static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
int slashes_eaten = 0;
|
||||||
char *ptr; /* shorthand */
|
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')) {
|
while (ptr[idx] != '\\' && (ptr[idx+1] != '\n' || ptr[idx+1] != '\r')) {
|
||||||
idx++;
|
idx++;
|
||||||
if (!ptr[idx]) {
|
if (!ptr[idx]) {
|
||||||
ptr[idx] = '\n';
|
goto out;
|
||||||
ptr[idx+1] = 0;
|
|
||||||
return idx;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* move the newline over the '\' before it (effectively eats the '\') */
|
/* move the newline over the '\' before it (effectively eats the '\') */
|
||||||
memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1]));
|
memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1]));
|
||||||
ptr[strlen(ptr)-1] = 0;
|
ptr[strlen(ptr)-1] = 0;
|
||||||
|
slashes_eaten++;
|
||||||
/* substitue \r for \n if needed */
|
/* substitue \r for \n if needed */
|
||||||
if (ptr[idx] == '\r')
|
if (ptr[idx] == '\r')
|
||||||
ptr[idx] = '\n';
|
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;
|
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");
|
fatalError("only a beginning address can be specified for edit commands\n");
|
||||||
idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]);
|
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 */
|
/* give back whatever's left over */
|
||||||
return (char *)&cmdstr[++idx];
|
return (char *)&cmdstr[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_cmd_str(const char *cmdstr)
|
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 */
|
/* trim leading whitespace and semicolons */
|
||||||
memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr));
|
memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr));
|
||||||
/* if we ate the whole thing, that means there was just trailing
|
/* 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)
|
if (strlen(mystr) == 0)
|
||||||
return;
|
return;
|
||||||
/* if this is a comment, jump past it and keep going */
|
/* 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 */
|
/* load command string into new array element, get remainder */
|
||||||
mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr);
|
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) {
|
(nextline = get_line_from_file(cmdfile)) != NULL) {
|
||||||
line = realloc(line, strlen(line) + strlen(nextline) + 1);
|
line = realloc(line, strlen(line) + strlen(nextline) + 1);
|
||||||
strcat(line, nextline);
|
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);
|
add_cmd_str(line);
|
||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
|
35
sed.c
35
sed.c
@ -307,6 +307,7 @@ out:
|
|||||||
static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
|
static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
int slashes_eaten = 0;
|
||||||
char *ptr; /* shorthand */
|
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')) {
|
while (ptr[idx] != '\\' && (ptr[idx+1] != '\n' || ptr[idx+1] != '\r')) {
|
||||||
idx++;
|
idx++;
|
||||||
if (!ptr[idx]) {
|
if (!ptr[idx]) {
|
||||||
ptr[idx] = '\n';
|
goto out;
|
||||||
ptr[idx+1] = 0;
|
|
||||||
return idx;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* move the newline over the '\' before it (effectively eats the '\') */
|
/* move the newline over the '\' before it (effectively eats the '\') */
|
||||||
memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1]));
|
memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1]));
|
||||||
ptr[strlen(ptr)-1] = 0;
|
ptr[strlen(ptr)-1] = 0;
|
||||||
|
slashes_eaten++;
|
||||||
/* substitue \r for \n if needed */
|
/* substitue \r for \n if needed */
|
||||||
if (ptr[idx] == '\r')
|
if (ptr[idx] == '\r')
|
||||||
ptr[idx] = '\n';
|
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;
|
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");
|
fatalError("only a beginning address can be specified for edit commands\n");
|
||||||
idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]);
|
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 */
|
/* give back whatever's left over */
|
||||||
return (char *)&cmdstr[++idx];
|
return (char *)&cmdstr[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_cmd_str(const char *cmdstr)
|
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 */
|
/* trim leading whitespace and semicolons */
|
||||||
memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr));
|
memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr));
|
||||||
/* if we ate the whole thing, that means there was just trailing
|
/* 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)
|
if (strlen(mystr) == 0)
|
||||||
return;
|
return;
|
||||||
/* if this is a comment, jump past it and keep going */
|
/* 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 */
|
/* load command string into new array element, get remainder */
|
||||||
mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr);
|
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) {
|
(nextline = get_line_from_file(cmdfile)) != NULL) {
|
||||||
line = realloc(line, strlen(line) + strlen(nextline) + 1);
|
line = realloc(line, strlen(line) + strlen(nextline) + 1);
|
||||||
strcat(line, nextline);
|
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);
|
add_cmd_str(line);
|
||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user