Run through indent
This commit is contained in:
237
editors/sed.c
237
editors/sed.c
@@ -59,13 +59,14 @@
|
|||||||
#define SED_LABEL_LENGTH 8
|
#define SED_LABEL_LENGTH 8
|
||||||
|
|
||||||
/* externs */
|
/* externs */
|
||||||
extern void xregcomp(regex_t *preg, const char *regex, int cflags);
|
extern void xregcomp(regex_t * preg, const char *regex, int cflags);
|
||||||
extern int optind; /* in unistd.h */
|
extern int optind; /* in unistd.h */
|
||||||
extern char *optarg; /* ditto */
|
extern char *optarg; /* ditto */
|
||||||
|
|
||||||
/* options */
|
/* options */
|
||||||
static int be_quiet = 0;
|
static int be_quiet = 0;
|
||||||
static const char bad_format_in_subst[] = "bad format in substitution expression";
|
static const char bad_format_in_subst[] =
|
||||||
|
"bad format in substitution expression";
|
||||||
|
|
||||||
typedef struct sed_cmd_s {
|
typedef struct sed_cmd_s {
|
||||||
/* Order by alignment requirements */
|
/* Order by alignment requirements */
|
||||||
@@ -122,7 +123,7 @@ static sed_cmd_t *sed_cmd_tail = &sed_cmd_head;
|
|||||||
static sed_cmd_t *block_cmd;
|
static sed_cmd_t *block_cmd;
|
||||||
|
|
||||||
static int in_block = 0;
|
static int in_block = 0;
|
||||||
const char * const semicolon_whitespace = "; \n\r\t\v\0";
|
const char *const semicolon_whitespace = "; \n\r\t\v\0";
|
||||||
static regex_t *previous_regex_ptr = NULL;
|
static regex_t *previous_regex_ptr = NULL;
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_CLEAN_UP
|
#ifdef CONFIG_FEATURE_CLEAN_UP
|
||||||
@@ -158,17 +159,18 @@ static void destroy_cmd_strs(void)
|
|||||||
* expression delimiter (typically a forward * slash ('/')) not preceeded by
|
* expression delimiter (typically a forward * slash ('/')) not preceeded by
|
||||||
* a backslash ('\').
|
* a backslash ('\').
|
||||||
*/
|
*/
|
||||||
static int index_of_next_unescaped_regexp_delim(const char delimiter, const char *str)
|
static int index_of_next_unescaped_regexp_delim(const char delimiter,
|
||||||
|
const char *str)
|
||||||
{
|
{
|
||||||
int bracket = -1;
|
int bracket = -1;
|
||||||
int escaped = 0;
|
int escaped = 0;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
for ( ; (ch = str[idx]); idx++) {
|
for (; (ch = str[idx]); idx++) {
|
||||||
if (bracket != -1) {
|
if (bracket != -1) {
|
||||||
if (ch == ']' && !(bracket == idx - 1 ||
|
if (ch == ']' && !(bracket == idx - 1 ||
|
||||||
(bracket == idx - 2 && str[idx-1] == '^')))
|
(bracket == idx - 2 && str[idx - 1] == '^')))
|
||||||
bracket = -1;
|
bracket = -1;
|
||||||
} else if (escaped)
|
} else if (escaped)
|
||||||
escaped = 0;
|
escaped = 0;
|
||||||
@@ -214,26 +216,26 @@ static int parse_regex_delim(const char *cmdstr, char **match, char **replace)
|
|||||||
}
|
}
|
||||||
*replace = bb_xstrndup(cmdstr_ptr, idx);
|
*replace = bb_xstrndup(cmdstr_ptr, idx);
|
||||||
|
|
||||||
return((cmdstr_ptr - cmdstr) + idx);
|
return ((cmdstr_ptr - cmdstr) + idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns the index in the string just past where the address ends.
|
* returns the index in the string just past where the address ends.
|
||||||
*/
|
*/
|
||||||
static int get_address(char *my_str, int *linenum, regex_t **regex)
|
static int get_address(char *my_str, int *linenum, regex_t ** regex)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
if (isdigit(my_str[idx])) {
|
if (isdigit(my_str[idx])) {
|
||||||
char *endstr;
|
char *endstr;
|
||||||
|
|
||||||
*linenum = strtol(my_str, &endstr, 10);
|
*linenum = strtol(my_str, &endstr, 10);
|
||||||
/* endstr shouldnt ever equal NULL */
|
/* endstr shouldnt ever equal NULL */
|
||||||
idx = endstr - my_str;
|
idx = endstr - my_str;
|
||||||
}
|
} else if (my_str[idx] == '$') {
|
||||||
else if (my_str[idx] == '$') {
|
|
||||||
*linenum = -1;
|
*linenum = -1;
|
||||||
idx++;
|
idx++;
|
||||||
}
|
} else if (my_str[idx] == '/' || my_str[idx] == '\\') {
|
||||||
else if (my_str[idx] == '/' || my_str[idx] == '\\') {
|
|
||||||
int idx_start = 1;
|
int idx_start = 1;
|
||||||
char delimiter;
|
char delimiter;
|
||||||
|
|
||||||
@@ -249,8 +251,8 @@ static int get_address(char *my_str, int *linenum, regex_t **regex)
|
|||||||
}
|
}
|
||||||
my_str[idx] = '\0';
|
my_str[idx] = '\0';
|
||||||
|
|
||||||
*regex = (regex_t *)xmalloc(sizeof(regex_t));
|
*regex = (regex_t *) xmalloc(sizeof(regex_t));
|
||||||
xregcomp(*regex, my_str+idx_start, REG_NEWLINE);
|
xregcomp(*regex, my_str + idx_start, REG_NEWLINE);
|
||||||
idx++; /* so it points to the next character after the last '/' */
|
idx++; /* so it points to the next character after the last '/' */
|
||||||
}
|
}
|
||||||
return idx;
|
return idx;
|
||||||
@@ -278,10 +280,11 @@ static int parse_subst_cmd(sed_cmd_t * const sed_cmd, const char *substr)
|
|||||||
* function to save processor time, at the expense of a little more memory
|
* function to save processor time, at the expense of a little more memory
|
||||||
* (4 bits) per sed_cmd */
|
* (4 bits) per sed_cmd */
|
||||||
|
|
||||||
/* sed_cmd->num_backrefs = 0; */ /* XXX: not needed? --apparently not */
|
/* sed_cmd->num_backrefs = 0; *//* XXX: not needed? --apparently not */
|
||||||
for (j = 0; match[j]; j++) {
|
for (j = 0; match[j]; j++) {
|
||||||
/* GNU/POSIX sed does not save more than nine backrefs */
|
/* GNU/POSIX sed does not save more than nine backrefs */
|
||||||
if (match[j] == '\\' && match[j+1] == '(' && sed_cmd->num_backrefs <= 9)
|
if (match[j] == '\\' && match[j + 1] == '('
|
||||||
|
&& sed_cmd->num_backrefs <= 9)
|
||||||
sed_cmd->num_backrefs++;
|
sed_cmd->num_backrefs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,11 +310,11 @@ static int parse_subst_cmd(sed_cmd_t * const sed_cmd, const char *substr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
/* compile the match string into a regex */
|
/* compile the match string into a regex */
|
||||||
if (*match != '\0') {
|
if (*match != '\0') {
|
||||||
/* If match is empty, we use last regex used at runtime */
|
/* If match is empty, we use last regex used at runtime */
|
||||||
sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t));
|
sed_cmd->sub_match = (regex_t *) xmalloc(sizeof(regex_t));
|
||||||
xregcomp(sed_cmd->sub_match, match, cflags);
|
xregcomp(sed_cmd->sub_match, match, cflags);
|
||||||
}
|
}
|
||||||
free(match);
|
free(match);
|
||||||
@@ -349,10 +352,10 @@ static int parse_translate_cmd(sed_cmd_t * const sed_cmd, const char *cmdstr)
|
|||||||
sed_cmd->translate[i * 2] = match[i];
|
sed_cmd->translate[i * 2] = match[i];
|
||||||
sed_cmd->translate[(i * 2) + 1] = replace[i];
|
sed_cmd->translate[(i * 2) + 1] = replace[i];
|
||||||
}
|
}
|
||||||
return(idx + 1);
|
return (idx + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_edit_cmd(sed_cmd_t *sed_cmd, const char *editstr)
|
static int parse_edit_cmd(sed_cmd_t * sed_cmd, const char *editstr)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
@@ -383,9 +386,9 @@ static int parse_edit_cmd(sed_cmd_t *sed_cmd, const char *editstr)
|
|||||||
|
|
||||||
/* store the edit line text */
|
/* store the edit line text */
|
||||||
sed_cmd->editline = xmalloc(strlen(&editstr[2]) + 2);
|
sed_cmd->editline = xmalloc(strlen(&editstr[2]) + 2);
|
||||||
for (i = 2, j = 0; editstr[i] != '\0' && strchr("\r\n", editstr[i]) == NULL;
|
for (i = 2, j = 0;
|
||||||
i++, j++) {
|
editstr[i] != '\0' && strchr("\r\n", editstr[i]) == NULL; i++, j++) {
|
||||||
if ((editstr[i] == '\\') && strchr("\n\r", editstr[i+1]) != NULL) {
|
if ((editstr[i] == '\\') && strchr("\n\r", editstr[i + 1]) != NULL) {
|
||||||
sed_cmd->editline[j] = '\n';
|
sed_cmd->editline[j] = '\n';
|
||||||
i++;
|
i++;
|
||||||
} else
|
} else
|
||||||
@@ -393,7 +396,7 @@ static int parse_edit_cmd(sed_cmd_t *sed_cmd, const char *editstr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* figure out if we need to add a newline */
|
/* figure out if we need to add a newline */
|
||||||
if (sed_cmd->editline[j-1] != '\n')
|
if (sed_cmd->editline[j - 1] != '\n')
|
||||||
sed_cmd->editline[j++] = '\n';
|
sed_cmd->editline[j++] = '\n';
|
||||||
|
|
||||||
/* terminate string */
|
/* terminate string */
|
||||||
@@ -403,7 +406,7 @@ static int parse_edit_cmd(sed_cmd_t *sed_cmd, const char *editstr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int parse_file_cmd(sed_cmd_t *sed_cmd, const char *filecmdstr)
|
static int parse_file_cmd(sed_cmd_t * sed_cmd, const char *filecmdstr)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
int filenamelen = 0;
|
int filenamelen = 0;
|
||||||
@@ -427,8 +430,8 @@ static int parse_file_cmd(sed_cmd_t *sed_cmd, const char *filecmdstr)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* the file command may be followed by whitespace; move past it. */
|
/* the file command may be followed by whitespace; move past it. */
|
||||||
while (isspace(filecmdstr[++idx]))
|
while (isspace(filecmdstr[++idx])) {;
|
||||||
{ ; }
|
}
|
||||||
|
|
||||||
/* the first non-whitespace we get is a filename. the filename ends when we
|
/* the first non-whitespace we get is a filename. the filename ends when we
|
||||||
* hit a normal sed command terminator or end of string */
|
* hit a normal sed command terminator or end of string */
|
||||||
@@ -451,7 +454,8 @@ static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr)
|
|||||||
/* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */
|
/* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */
|
||||||
else if (strchr("aic", sed_cmd->cmd)) {
|
else if (strchr("aic", sed_cmd->cmd)) {
|
||||||
if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c')
|
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");
|
bb_error_msg_and_die
|
||||||
|
("only a beginning address can be specified for edit commands");
|
||||||
cmdstr += parse_edit_cmd(sed_cmd, cmdstr);
|
cmdstr += parse_edit_cmd(sed_cmd, cmdstr);
|
||||||
}
|
}
|
||||||
/* handle file cmds: (r)ead */
|
/* handle file cmds: (r)ead */
|
||||||
@@ -484,10 +488,10 @@ static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* give back whatever's left over */
|
/* give back whatever's left over */
|
||||||
return(cmdstr);
|
return (cmdstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
|
static char *add_cmd(sed_cmd_t * sed_cmd, char *cmdstr)
|
||||||
{
|
{
|
||||||
/* Skip over leading whitespace and semicolons */
|
/* Skip over leading whitespace and semicolons */
|
||||||
cmdstr += strspn(cmdstr, semicolon_whitespace);
|
cmdstr += strspn(cmdstr, semicolon_whitespace);
|
||||||
@@ -495,7 +499,7 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
|
|||||||
/* 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 / no-op semicolon. either way, get out */
|
* whitespace or a final / no-op semicolon. either way, get out */
|
||||||
if (*cmdstr == '\0') {
|
if (*cmdstr == '\0') {
|
||||||
return(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if this is a comment, jump past it and keep going */
|
/* if this is a comment, jump past it and keep going */
|
||||||
@@ -504,14 +508,14 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
|
|||||||
if (cmdstr[1] == 'n') {
|
if (cmdstr[1] == 'n') {
|
||||||
be_quiet++;
|
be_quiet++;
|
||||||
}
|
}
|
||||||
return(strpbrk(cmdstr, "\n\r"));
|
return (strpbrk(cmdstr, "\n\r"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test for end of block */
|
/* Test for end of block */
|
||||||
if (*cmdstr == '}') {
|
if (*cmdstr == '}') {
|
||||||
in_block = 0;
|
in_block = 0;
|
||||||
cmdstr++;
|
cmdstr++;
|
||||||
return(cmdstr);
|
return (cmdstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse the command
|
/* parse the command
|
||||||
@@ -526,6 +530,7 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
|
|||||||
/* second part (if present) will begin with a comma */
|
/* second part (if present) will begin with a comma */
|
||||||
if (*cmdstr == ',') {
|
if (*cmdstr == ',') {
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
cmdstr++;
|
cmdstr++;
|
||||||
idx = get_address(cmdstr, &sed_cmd->end_line, &sed_cmd->end_match);
|
idx = get_address(cmdstr, &sed_cmd->end_line, &sed_cmd->end_match);
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
@@ -552,8 +557,7 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
|
|||||||
* with <blank>s.
|
* with <blank>s.
|
||||||
*/
|
*/
|
||||||
if (isblank(cmdstr[idx]) {
|
if (isblank(cmdstr[idx]) {
|
||||||
bb_error_msg_and_die("blank follows '!'");
|
bb_error_msg_and_die("blank follows '!'");}
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
/* skip whitespace before the command */
|
/* skip whitespace before the command */
|
||||||
while (isspace(*cmdstr)) {
|
while (isspace(*cmdstr)) {
|
||||||
@@ -574,7 +578,7 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
|
|||||||
in_block = 1;
|
in_block = 1;
|
||||||
block_cmd = sed_cmd;
|
block_cmd = sed_cmd;
|
||||||
|
|
||||||
return(cmdstr + 1);
|
return (cmdstr + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
sed_cmd->cmd = *cmdstr;
|
sed_cmd->cmd = *cmdstr;
|
||||||
@@ -594,7 +598,7 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
|
|||||||
sed_cmd_tail->linear = sed_cmd;
|
sed_cmd_tail->linear = sed_cmd;
|
||||||
sed_cmd_tail = sed_cmd_tail->linear;
|
sed_cmd_tail = sed_cmd_tail->linear;
|
||||||
|
|
||||||
return(cmdstr);
|
return (cmdstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_cmd_str(char *cmdstr)
|
static void add_cmd_str(char *cmdstr)
|
||||||
@@ -603,7 +607,7 @@ static void add_cmd_str(char *cmdstr)
|
|||||||
char *cmdstr_ptr = cmdstr;
|
char *cmdstr_ptr = cmdstr;
|
||||||
|
|
||||||
/* HACK: convert "\n" to match tranlated '\n' string */
|
/* HACK: convert "\n" to match tranlated '\n' string */
|
||||||
while((cmdstr_ptr = strstr(cmdstr_ptr, "\\n")) != NULL) {
|
while ((cmdstr_ptr = strstr(cmdstr_ptr, "\\n")) != NULL) {
|
||||||
cmdstr = xrealloc(cmdstr, strlen(cmdstr) + 2);
|
cmdstr = xrealloc(cmdstr, strlen(cmdstr) + 2);
|
||||||
cmdstr_ptr = strstr(cmdstr, "\\n");
|
cmdstr_ptr = strstr(cmdstr, "\\n");
|
||||||
memmove(cmdstr_ptr + 1, cmdstr_ptr, strlen(cmdstr_ptr) + 1);
|
memmove(cmdstr_ptr + 1, cmdstr_ptr, strlen(cmdstr_ptr) + 1);
|
||||||
@@ -613,6 +617,7 @@ static void add_cmd_str(char *cmdstr)
|
|||||||
#endif
|
#endif
|
||||||
do {
|
do {
|
||||||
sed_cmd_t *sed_cmd;
|
sed_cmd_t *sed_cmd;
|
||||||
|
|
||||||
sed_cmd = xcalloc(1, sizeof(sed_cmd_t));
|
sed_cmd = xcalloc(1, sizeof(sed_cmd_t));
|
||||||
cmdstr = add_cmd(sed_cmd, cmdstr);
|
cmdstr = add_cmd(sed_cmd, cmdstr);
|
||||||
} while (cmdstr && strlen(cmdstr));
|
} while (cmdstr && strlen(cmdstr));
|
||||||
@@ -657,8 +662,7 @@ struct pipeline {
|
|||||||
void pipe_putc(struct pipeline *const pipeline, char c)
|
void pipe_putc(struct pipeline *const pipeline, char c)
|
||||||
{
|
{
|
||||||
if (pipeline->buf[pipeline->idx] == PIPE_MAGIC) {
|
if (pipeline->buf[pipeline->idx] == PIPE_MAGIC) {
|
||||||
pipeline->buf =
|
pipeline->buf = xrealloc(pipeline->buf, pipeline->len + PIPE_GROW);
|
||||||
xrealloc(pipeline->buf, pipeline->len + PIPE_GROW);
|
|
||||||
memset(pipeline->buf + pipeline->len, 0, PIPE_GROW);
|
memset(pipeline->buf + pipeline->len, 0, PIPE_GROW);
|
||||||
pipeline->len += PIPE_GROW;
|
pipeline->len += PIPE_GROW;
|
||||||
pipeline->buf[pipeline->len - 1] = PIPE_MAGIC;
|
pipeline->buf[pipeline->len - 1] = PIPE_MAGIC;
|
||||||
@@ -669,33 +673,40 @@ void pipe_putc(struct pipeline *const pipeline, char c)
|
|||||||
#define pipeputc(c) pipe_putc(pipeline, c)
|
#define pipeputc(c) pipe_putc(pipeline, c)
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
{ if (pipeline[pipeline_idx] == PIPE_MAGIC) { \
|
{
|
||||||
pipeline = xrealloc(pipeline, pipeline_len+PIPE_GROW); \
|
if (pipeline[pipeline_idx] == PIPE_MAGIC) {
|
||||||
memset(pipeline+pipeline_len, 0, PIPE_GROW); \
|
pipeline = xrealloc(pipeline, pipeline_len + PIPE_GROW);
|
||||||
pipeline_len += PIPE_GROW; \
|
memset(pipeline + pipeline_len, 0, PIPE_GROW);
|
||||||
pipeline[pipeline_len-1] = PIPE_MAGIC; } \
|
pipeline_len += PIPE_GROW;
|
||||||
pipeline[pipeline_idx++] = (c); }
|
pipeline[pipeline_len - 1] = PIPE_MAGIC;
|
||||||
|
}
|
||||||
|
pipeline[pipeline_idx++] = (c);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void print_subst_w_backrefs(const char *line, const char *replace,
|
static void print_subst_w_backrefs(const char *line, const char *replace,
|
||||||
regmatch_t *regmatch, struct pipeline *const pipeline, int matches)
|
regmatch_t * regmatch,
|
||||||
|
struct pipeline *const pipeline,
|
||||||
|
int matches)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* go through the replacement string */
|
/* go through the replacement string */
|
||||||
for (i = 0; replace[i]; i++) {
|
for (i = 0; replace[i]; i++) {
|
||||||
/* if we find a backreference (\1, \2, etc.) print the backref'ed * text */
|
/* if we find a backreference (\1, \2, etc.) print the backref'ed * text */
|
||||||
if (replace[i] == '\\' && isdigit(replace[i+1])) {
|
if (replace[i] == '\\' && isdigit(replace[i + 1])) {
|
||||||
int j;
|
int j;
|
||||||
char tmpstr[2];
|
char tmpstr[2];
|
||||||
int backref;
|
int backref;
|
||||||
|
|
||||||
++i; /* i now indexes the backref number, instead of the leading slash */
|
++i; /* i now indexes the backref number, instead of the leading slash */
|
||||||
tmpstr[0] = replace[i];
|
tmpstr[0] = replace[i];
|
||||||
tmpstr[1] = 0;
|
tmpstr[1] = 0;
|
||||||
backref = atoi(tmpstr);
|
backref = atoi(tmpstr);
|
||||||
/* print out the text held in regmatch[backref] */
|
/* print out the text held in regmatch[backref] */
|
||||||
if (backref <= matches && regmatch[backref].rm_so != -1)
|
if (backref <= matches && regmatch[backref].rm_so != -1)
|
||||||
for (j = regmatch[backref].rm_so; j < regmatch[backref].rm_eo; j++)
|
for (j = regmatch[backref].rm_so; j < regmatch[backref].rm_eo;
|
||||||
|
j++)
|
||||||
pipeputc(line[j]);
|
pipeputc(line[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,8 +720,9 @@ static void print_subst_w_backrefs(const char *line, const char *replace,
|
|||||||
* fortunately, regmatch[0] contains the indicies to the whole matched
|
* fortunately, regmatch[0] contains the indicies to the whole matched
|
||||||
* expression (kinda seems like it was designed for just such a
|
* expression (kinda seems like it was designed for just such a
|
||||||
* purpose...) */
|
* purpose...) */
|
||||||
else if (replace[i] == '&' && replace[i-1] != '\\') {
|
else if (replace[i] == '&' && replace[i - 1] != '\\') {
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = regmatch[0].rm_so; j < regmatch[0].rm_eo; j++)
|
for (j = regmatch[0].rm_so; j < regmatch[0].rm_eo; j++)
|
||||||
pipeputc(line[j]);
|
pipeputc(line[j]);
|
||||||
}
|
}
|
||||||
@@ -720,10 +732,10 @@ static void print_subst_w_backrefs(const char *line, const char *replace,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_subst_command(sed_cmd_t *sed_cmd, char **line)
|
static int do_subst_command(sed_cmd_t * sed_cmd, char **line)
|
||||||
{
|
{
|
||||||
char *hackline = *line;
|
char *hackline = *line;
|
||||||
struct pipeline thepipe = { NULL, 0 , 0};
|
struct pipeline thepipe = { NULL, 0, 0 };
|
||||||
struct pipeline *const pipeline = &thepipe;
|
struct pipeline *const pipeline = &thepipe;
|
||||||
int altered = 0;
|
int altered = 0;
|
||||||
int result;
|
int result;
|
||||||
@@ -743,19 +755,20 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* whaddaya know, it matched. get the number of back references */
|
/* whaddaya know, it matched. get the number of back references */
|
||||||
regmatch = xmalloc(sizeof(regmatch_t) * (sed_cmd->num_backrefs+1));
|
regmatch = xmalloc(sizeof(regmatch_t) * (sed_cmd->num_backrefs + 1));
|
||||||
|
|
||||||
/* allocate more PIPE_GROW bytes
|
/* allocate more PIPE_GROW bytes
|
||||||
if replaced string is larger than original */
|
if replaced string is larger than original */
|
||||||
thepipe.len = strlen(hackline)+PIPE_GROW;
|
thepipe.len = strlen(hackline) + PIPE_GROW;
|
||||||
thepipe.buf = xcalloc(1, thepipe.len);
|
thepipe.buf = xcalloc(1, thepipe.len);
|
||||||
/* buffer magic */
|
/* buffer magic */
|
||||||
thepipe.buf[thepipe.len-1] = PIPE_MAGIC;
|
thepipe.buf[thepipe.len - 1] = PIPE_MAGIC;
|
||||||
|
|
||||||
/* and now, as long as we've got a line to try matching and if we can match
|
/* and now, as long as we've got a line to try matching and if we can match
|
||||||
* the search string, we make substitutions */
|
* the search string, we make substitutions */
|
||||||
while ((*hackline || !altered) && (regexec(current_regex, hackline,
|
while ((*hackline || !altered) && (regexec(current_regex, hackline,
|
||||||
sed_cmd->num_backrefs+1, regmatch, 0) != REG_NOMATCH) ) {
|
sed_cmd->num_backrefs + 1,
|
||||||
|
regmatch, 0) != REG_NOMATCH)) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* print everything before the match */
|
/* print everything before the match */
|
||||||
@@ -776,8 +789,10 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (; *hackline; hackline++) pipeputc(*hackline);
|
for (; *hackline; hackline++)
|
||||||
if (thepipe.buf[thepipe.idx] == PIPE_MAGIC) thepipe.buf[thepipe.idx] = 0;
|
pipeputc(*hackline);
|
||||||
|
if (thepipe.buf[thepipe.idx] == PIPE_MAGIC)
|
||||||
|
thepipe.buf[thepipe.idx] = 0;
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
free(regmatch);
|
free(regmatch);
|
||||||
@@ -790,17 +805,18 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line)
|
|||||||
static sed_cmd_t *branch_to(const char *label)
|
static sed_cmd_t *branch_to(const char *label)
|
||||||
{
|
{
|
||||||
sed_cmd_t *sed_cmd;
|
sed_cmd_t *sed_cmd;
|
||||||
for(sed_cmd = sed_cmd_head.linear; sed_cmd; sed_cmd = sed_cmd->linear) {
|
|
||||||
|
for (sed_cmd = sed_cmd_head.linear; sed_cmd; sed_cmd = sed_cmd->linear) {
|
||||||
if (strcmp(sed_cmd->label, label) == 0) {
|
if (strcmp(sed_cmd->label, label) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If no match returns last command */
|
/* If no match returns last command */
|
||||||
return(sed_cmd);
|
return (sed_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_file(FILE *file)
|
static void process_file(FILE * file)
|
||||||
{
|
{
|
||||||
char *pattern_space; /* Posix requires it be able to hold at least 8192 bytes */
|
char *pattern_space; /* Posix requires it be able to hold at least 8192 bytes */
|
||||||
char *hold_space = NULL; /* Posix requires it be able to hold at least 8192 bytes */
|
char *hold_space = NULL; /* Posix requires it be able to hold at least 8192 bytes */
|
||||||
@@ -828,7 +844,8 @@ static void process_file(FILE *file)
|
|||||||
force_print = 0;
|
force_print = 0;
|
||||||
|
|
||||||
/* for every line, go through all the commands */
|
/* for every line, go through all the commands */
|
||||||
for (sed_cmd = sed_cmd_head.linear; sed_cmd; sed_cmd = sed_cmd->linear) {
|
for (sed_cmd = sed_cmd_head.linear; sed_cmd;
|
||||||
|
sed_cmd = sed_cmd->linear) {
|
||||||
int deleted = 0;
|
int deleted = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -836,15 +853,22 @@ static void process_file(FILE *file)
|
|||||||
*/
|
*/
|
||||||
int matched = (
|
int matched = (
|
||||||
/* no range necessary */
|
/* no range necessary */
|
||||||
(sed_cmd->beg_line == 0 && sed_cmd->end_line == 0 &&
|
(sed_cmd->beg_line == 0
|
||||||
sed_cmd->beg_match == NULL &&
|
&& sed_cmd->end_line == 0
|
||||||
sed_cmd->end_match == NULL) ||
|
&& sed_cmd->beg_match == NULL
|
||||||
|
&& sed_cmd->end_match == NULL) ||
|
||||||
/* this line number is the first address we're looking for */
|
/* this line number is the first address we're looking for */
|
||||||
(sed_cmd->beg_line && (sed_cmd->beg_line == linenum)) ||
|
(sed_cmd->beg_line
|
||||||
|
&& (sed_cmd->beg_line == linenum)) ||
|
||||||
/* this line matches our first address regex */
|
/* this line matches our first address regex */
|
||||||
(sed_cmd->beg_match && (regexec(sed_cmd->beg_match, pattern_space, 0, NULL, 0) == 0)) ||
|
(sed_cmd->beg_match
|
||||||
|
&&
|
||||||
|
(regexec
|
||||||
|
(sed_cmd->beg_match, pattern_space, 0, NULL,
|
||||||
|
0) == 0)) ||
|
||||||
/* we are currently within the beginning & ending address range */
|
/* we are currently within the beginning & ending address range */
|
||||||
still_in_range || ((sed_cmd->beg_line == -1) && (next_line == NULL))
|
still_in_range || ((sed_cmd->beg_line == -1)
|
||||||
|
&& (next_line == NULL))
|
||||||
);
|
);
|
||||||
|
|
||||||
if (sed_cmd->invert ^ matched) {
|
if (sed_cmd->invert ^ matched) {
|
||||||
@@ -860,8 +884,10 @@ static void process_file(FILE *file)
|
|||||||
case '=':
|
case '=':
|
||||||
printf("%d\n", linenum);
|
printf("%d\n", linenum);
|
||||||
break;
|
break;
|
||||||
case 'P': { /* Write the current pattern space upto the first newline */
|
case 'P':{
|
||||||
|
/* Write the current pattern space upto the first newline */
|
||||||
char *tmp = strchr(pattern_space, '\n');
|
char *tmp = strchr(pattern_space, '\n');
|
||||||
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
*tmp = '\0';
|
*tmp = '\0';
|
||||||
}
|
}
|
||||||
@@ -896,9 +922,13 @@ static void process_file(FILE *file)
|
|||||||
/* HACK: escape newlines twice so regex can match them */
|
/* HACK: escape newlines twice so regex can match them */
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
while(strchr(pattern_space + offset, '\n') != NULL) {
|
|
||||||
|
while (strchr(pattern_space + offset, '\n') != NULL) {
|
||||||
char *tmp;
|
char *tmp;
|
||||||
pattern_space = xrealloc(pattern_space, strlen(pattern_space) + 2);
|
|
||||||
|
pattern_space =
|
||||||
|
xrealloc(pattern_space,
|
||||||
|
strlen(pattern_space) + 2);
|
||||||
tmp = strchr(pattern_space + offset, '\n');
|
tmp = strchr(pattern_space + offset, '\n');
|
||||||
memmove(tmp + 1, tmp, strlen(tmp) + 1);
|
memmove(tmp + 1, tmp, strlen(tmp) + 1);
|
||||||
tmp[0] = '\\';
|
tmp[0] = '\\';
|
||||||
@@ -915,14 +945,16 @@ static void process_file(FILE *file)
|
|||||||
{
|
{
|
||||||
char *tmp = pattern_space;
|
char *tmp = pattern_space;
|
||||||
|
|
||||||
while((tmp = strstr(tmp, "\\n")) != NULL) {
|
while ((tmp = strstr(tmp, "\\n")) != NULL) {
|
||||||
memmove(tmp, tmp + 1, strlen(tmp + 1) + 1);
|
memmove(tmp, tmp + 1, strlen(tmp + 1) + 1);
|
||||||
tmp[0] = '\n';
|
tmp[0] = '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
altered |= substituted;
|
altered |= substituted;
|
||||||
if (!be_quiet && altered && ((sed_cmd->linear == NULL) || (sed_cmd->linear->cmd != 's'))) {
|
if (!be_quiet && altered && ((sed_cmd->linear == NULL)
|
||||||
|
|| (sed_cmd->linear->cmd !=
|
||||||
|
's'))) {
|
||||||
force_print = 1;
|
force_print = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -947,18 +979,23 @@ static void process_file(FILE *file)
|
|||||||
if ((sed_cmd->end_match == NULL && sed_cmd->end_line == 0)
|
if ((sed_cmd->end_match == NULL && sed_cmd->end_line == 0)
|
||||||
/* multi-address case */
|
/* multi-address case */
|
||||||
/* - matching text */
|
/* - matching text */
|
||||||
|| (sed_cmd->end_match && (regexec(sed_cmd->end_match, pattern_space, 0, NULL, 0) == 0))
|
|| (sed_cmd->end_match
|
||||||
|
&&
|
||||||
|
(regexec
|
||||||
|
(sed_cmd->end_match, pattern_space, 0, NULL,
|
||||||
|
0) == 0))
|
||||||
/* - matching line numbers */
|
/* - matching line numbers */
|
||||||
|| (sed_cmd->end_line > 0 && sed_cmd->end_line == linenum))
|
|| (sed_cmd->end_line > 0
|
||||||
{
|
&& sed_cmd->end_line == linenum)) {
|
||||||
fputs(sed_cmd->editline, stdout);
|
fputs(sed_cmd->editline, stdout);
|
||||||
}
|
}
|
||||||
altered++;
|
altered++;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r': {
|
case 'r':{
|
||||||
FILE *outfile;
|
FILE *outfile;
|
||||||
|
|
||||||
puts(pattern_space);
|
puts(pattern_space);
|
||||||
outfile = fopen(sed_cmd->filename, "r");
|
outfile = fopen(sed_cmd->filename, "r");
|
||||||
if (outfile)
|
if (outfile)
|
||||||
@@ -982,7 +1019,10 @@ static void process_file(FILE *file)
|
|||||||
break;
|
break;
|
||||||
case 'N': /* Append the next line to the current line */
|
case 'N': /* Append the next line to the current line */
|
||||||
if (next_line) {
|
if (next_line) {
|
||||||
pattern_space = realloc(pattern_space, strlen(pattern_space) + strlen(next_line) + 2);
|
pattern_space =
|
||||||
|
realloc(pattern_space,
|
||||||
|
strlen(pattern_space) +
|
||||||
|
strlen(next_line) + 2);
|
||||||
strcat(pattern_space, "\n");
|
strcat(pattern_space, "\n");
|
||||||
strcat(pattern_space, next_line);
|
strcat(pattern_space, next_line);
|
||||||
next_line = bb_get_chomped_line_from_file(file);
|
next_line = bb_get_chomped_line_from_file(file);
|
||||||
@@ -997,11 +1037,13 @@ static void process_file(FILE *file)
|
|||||||
sed_cmd = branch_to(sed_cmd->label);
|
sed_cmd = branch_to(sed_cmd->label);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'y': {
|
case 'y':{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; pattern_space[i] != 0; i++) {
|
for (i = 0; pattern_space[i] != 0; i++) {
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; sed_cmd->translate[j] ;j += 2) {
|
|
||||||
|
for (j = 0; sed_cmd->translate[j]; j += 2) {
|
||||||
if (pattern_space[i] == sed_cmd->translate[j]) {
|
if (pattern_space[i] == sed_cmd->translate[j]) {
|
||||||
pattern_space[i] = sed_cmd->translate[j + 1];
|
pattern_space[i] = sed_cmd->translate[j + 1];
|
||||||
}
|
}
|
||||||
@@ -1017,8 +1059,10 @@ static void process_file(FILE *file)
|
|||||||
free(hold_space);
|
free(hold_space);
|
||||||
hold_space = strdup(pattern_space);
|
hold_space = strdup(pattern_space);
|
||||||
break;
|
break;
|
||||||
case 'x': { /* Swap hold and pattern space */
|
case 'x':{
|
||||||
|
/* Swap hold and pattern space */
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
tmp = pattern_space;
|
tmp = pattern_space;
|
||||||
pattern_space = hold_space;
|
pattern_space = hold_space;
|
||||||
hold_space = tmp;
|
hold_space = tmp;
|
||||||
@@ -1032,16 +1076,29 @@ static void process_file(FILE *file)
|
|||||||
if (matched) {
|
if (matched) {
|
||||||
if (
|
if (
|
||||||
/* this is a single-address command or... */
|
/* this is a single-address command or... */
|
||||||
(sed_cmd->end_line == 0 && sed_cmd->end_match == NULL) || (
|
(sed_cmd->end_line == 0 && sed_cmd->end_match == NULL)
|
||||||
|
|| (
|
||||||
/* If only one address */
|
/* If only one address */
|
||||||
|
|
||||||
/* we were in the middle of our address range (this
|
/* we were in the middle of our address range (this
|
||||||
* isn't the first time through) and.. */
|
* isn't the first time through) and.. */
|
||||||
(still_in_range == 1) && (
|
(still_in_range == 1) && (
|
||||||
/* this line number is the last address we're looking for or... */
|
/* this line number is the last address we're looking for or... */
|
||||||
(sed_cmd->end_line && (sed_cmd->end_line == linenum)) ||
|
(sed_cmd->
|
||||||
|
end_line
|
||||||
|
&& (sed_cmd->
|
||||||
|
end_line ==
|
||||||
|
linenum))
|
||||||
|
||
|
||||||
/* this line matches our last address regex */
|
/* this line matches our last address regex */
|
||||||
(sed_cmd->end_match && (regexec(sed_cmd->end_match, pattern_space, 0, NULL, 0) == 0))
|
(sed_cmd->
|
||||||
|
end_match
|
||||||
|
&&
|
||||||
|
(regexec
|
||||||
|
(sed_cmd->
|
||||||
|
end_match,
|
||||||
|
pattern_space,
|
||||||
|
0, NULL,
|
||||||
|
0) == 0))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@@ -1062,7 +1119,7 @@ static void process_file(FILE *file)
|
|||||||
/* we will print the line unless we were told to be quiet or if the
|
/* we will print the line unless we were told to be quiet or if the
|
||||||
* line was altered (via a 'd'elete or 's'ubstitution), in which case
|
* line was altered (via a 'd'elete or 's'ubstitution), in which case
|
||||||
* the altered line was already printed */
|
* the altered line was already printed */
|
||||||
if ((!be_quiet && !altered) || force_print){
|
if ((!be_quiet && !altered) || force_print) {
|
||||||
puts(pattern_space);
|
puts(pattern_space);
|
||||||
}
|
}
|
||||||
free(pattern_space);
|
free(pattern_space);
|
||||||
@@ -1086,8 +1143,9 @@ extern int sed_main(int argc, char **argv)
|
|||||||
case 'n':
|
case 'n':
|
||||||
be_quiet++;
|
be_quiet++;
|
||||||
break;
|
break;
|
||||||
case 'e': {
|
case 'e':{
|
||||||
char *str_cmd = strdup(optarg);
|
char *str_cmd = strdup(optarg);
|
||||||
|
|
||||||
add_cmd_str(str_cmd);
|
add_cmd_str(str_cmd);
|
||||||
free(str_cmd);
|
free(str_cmd);
|
||||||
break;
|
break;
|
||||||
@@ -1107,6 +1165,7 @@ extern int sed_main(int argc, char **argv)
|
|||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
else {
|
else {
|
||||||
char *str_cmd = strdup(argv[optind]);
|
char *str_cmd = strdup(argv[optind]);
|
||||||
|
|
||||||
add_cmd_str(strdup(str_cmd));
|
add_cmd_str(strdup(str_cmd));
|
||||||
free(str_cmd);
|
free(str_cmd);
|
||||||
optind++;
|
optind++;
|
||||||
@@ -1118,10 +1177,10 @@ extern int sed_main(int argc, char **argv)
|
|||||||
* Otherwise, we process all the files specified. */
|
* Otherwise, we process all the files specified. */
|
||||||
if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
|
if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
|
||||||
process_file(stdin);
|
process_file(stdin);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
int i;
|
int i;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
for (i = optind; i < argc; i++) {
|
for (i = optind; i < argc; i++) {
|
||||||
file = bb_wfopen(argv[i], "r");
|
file = bb_wfopen(argv[i], "r");
|
||||||
if (file) {
|
if (file) {
|
||||||
|
Reference in New Issue
Block a user