Use a linked list for sed commands in preparation for branching support
This commit is contained in:
parent
3a9b0bf0ba
commit
c949bfa555
@ -101,14 +101,17 @@ typedef struct sed_cmd_s {
|
|||||||
char cmd; /* p,d,s (add more at your leisure :-) */
|
char cmd; /* p,d,s (add more at your leisure :-) */
|
||||||
|
|
||||||
/* inversion flag */
|
/* inversion flag */
|
||||||
int invert; /* the '!' after the address */
|
int invert; /* the '!' after the address */
|
||||||
|
|
||||||
|
/* next command in list (sequential list of specified commands) */
|
||||||
|
struct sed_cmd_s *linear;
|
||||||
|
|
||||||
} sed_cmd_t;
|
} sed_cmd_t;
|
||||||
|
|
||||||
/* globals */
|
/* globals */
|
||||||
static sed_cmd_t **sed_cmds = NULL; /* growable arrary holding a sequence of sed cmds */
|
/* linked list of sed commands */
|
||||||
static int ncmds = 0; /* number of sed commands */
|
static sed_cmd_t sed_cmd_head;
|
||||||
|
static sed_cmd_t *sed_cmd_tail = &sed_cmd_head;
|
||||||
/*static char *cur_file = NULL;*/ /* file currently being processed XXX: do I need this? */
|
|
||||||
|
|
||||||
const char * const semicolon_whitespace = "; \n\r\t\v\0";
|
const char * const semicolon_whitespace = "; \n\r\t\v\0";
|
||||||
|
|
||||||
@ -485,19 +488,26 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
|
|||||||
|
|
||||||
if (sed_cmd->cmd == '{') {
|
if (sed_cmd->cmd == '{') {
|
||||||
do {
|
do {
|
||||||
|
sed_cmd_t *sed_cmd_new;
|
||||||
char *end_ptr = strpbrk(cmdstr, ";}");
|
char *end_ptr = strpbrk(cmdstr, ";}");
|
||||||
|
|
||||||
*end_ptr = '\0';
|
*end_ptr = '\0';
|
||||||
add_cmd(sed_cmd, cmdstr);
|
sed_cmd_new = xcalloc(1, sizeof(sed_cmd_t));
|
||||||
|
sed_cmd_new->beg_match = sed_cmd->beg_match;
|
||||||
|
sed_cmd_new->end_match = sed_cmd->end_match;
|
||||||
|
sed_cmd_new->beg_line = sed_cmd->beg_line;
|
||||||
|
sed_cmd_new->end_line = sed_cmd->end_line;
|
||||||
|
sed_cmd_new->invert = sed_cmd->invert;
|
||||||
|
|
||||||
|
add_cmd(sed_cmd_new, cmdstr);
|
||||||
cmdstr = end_ptr + 1;
|
cmdstr = end_ptr + 1;
|
||||||
} while (*cmdstr != '\0');
|
} while (*cmdstr != '\0');
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
cmdstr = parse_cmd_str(sed_cmd, cmdstr);
|
cmdstr = parse_cmd_str(sed_cmd, cmdstr);
|
||||||
|
|
||||||
/* Add the command to the command array */
|
/* Add the command to the command array */
|
||||||
sed_cmds = xrealloc(sed_cmds, sizeof(sed_cmd_t) * (++ncmds));
|
sed_cmd_tail->linear = sed_cmd;
|
||||||
sed_cmds[ncmds-1] = xmalloc(sizeof(sed_cmd_t));
|
sed_cmd_tail = sed_cmd_tail->linear;
|
||||||
memcpy(sed_cmds[ncmds-1], sed_cmd, sizeof(sed_cmd_t));
|
|
||||||
}
|
}
|
||||||
return(cmdstr);
|
return(cmdstr);
|
||||||
}
|
}
|
||||||
@ -677,7 +687,6 @@ static void process_file(FILE *file)
|
|||||||
static int linenum = 0; /* GNU sed does not restart counting lines at EOF */
|
static int linenum = 0; /* GNU sed does not restart counting lines at EOF */
|
||||||
unsigned int still_in_range = 0;
|
unsigned int still_in_range = 0;
|
||||||
int altered;
|
int altered;
|
||||||
int i;
|
|
||||||
|
|
||||||
line = bb_get_chomped_line_from_file(file);
|
line = bb_get_chomped_line_from_file(file);
|
||||||
if (line == NULL) {
|
if (line == NULL) {
|
||||||
@ -687,6 +696,7 @@ static void process_file(FILE *file)
|
|||||||
/* go through every line in the file */
|
/* go through every line in the file */
|
||||||
do {
|
do {
|
||||||
char *next_line;
|
char *next_line;
|
||||||
|
sed_cmd_t *sed_cmd;
|
||||||
|
|
||||||
/* Read one line in advance so we can act on the last line, the '$' address */
|
/* Read one line in advance so we can act on the last line, the '$' address */
|
||||||
next_line = bb_get_chomped_line_from_file(file);
|
next_line = bb_get_chomped_line_from_file(file);
|
||||||
@ -695,8 +705,7 @@ static void process_file(FILE *file)
|
|||||||
altered = 0;
|
altered = 0;
|
||||||
|
|
||||||
/* for every line, go through all the commands */
|
/* for every line, go through all the commands */
|
||||||
for (i = 0; i < ncmds; i++) {
|
for (sed_cmd = sed_cmd_head.linear; sed_cmd; sed_cmd = sed_cmd->linear) {
|
||||||
sed_cmd_t *sed_cmd = sed_cmds[i];
|
|
||||||
int deleted = 0;
|
int deleted = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -770,7 +779,7 @@ static void process_file(FILE *file)
|
|||||||
* (this is quite possibly the second printing) */
|
* (this is quite possibly the second printing) */
|
||||||
if (sed_cmd->sub_p)
|
if (sed_cmd->sub_p)
|
||||||
altered |= do_subst_command(sed_cmd, &line);
|
altered |= do_subst_command(sed_cmd, &line);
|
||||||
if (altered && (i+1 >= ncmds || sed_cmds[i+1]->cmd != 's'))
|
if (altered && ((sed_cmd->linear == NULL) || (sed_cmd->linear->cmd != 's')))
|
||||||
puts(line);
|
puts(line);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -900,7 +909,7 @@ extern int sed_main(int argc, char **argv)
|
|||||||
|
|
||||||
/* if we didn't get a pattern from a -e and no command file was specified,
|
/* if we didn't get a pattern from a -e and no command file was specified,
|
||||||
* argv[optind] should be the pattern. no pattern, no worky */
|
* argv[optind] should be the pattern. no pattern, no worky */
|
||||||
if (ncmds == 0) {
|
if (sed_cmd_head.linear == NULL) {
|
||||||
if (argv[optind] == NULL)
|
if (argv[optind] == NULL)
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
else {
|
else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user