Applied patch from Mark Ferrell <mferrell@mvista.com> to use the 'p' option in
substitution expressions.
This commit is contained in:
@@ -217,6 +217,9 @@
|
|||||||
// Enable support for "--exclude" for excluding files
|
// Enable support for "--exclude" for excluding files
|
||||||
#define BB_FEATURE_TAR_EXCLUDE
|
#define BB_FEATURE_TAR_EXCLUDE
|
||||||
//
|
//
|
||||||
|
// Enable support for s///p pattern matching
|
||||||
|
#define BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
//
|
||||||
//// Enable reverse sort
|
//// Enable reverse sort
|
||||||
#define BB_FEATURE_SORT_REVERSE
|
#define BB_FEATURE_SORT_REVERSE
|
||||||
//
|
//
|
||||||
|
@@ -63,6 +63,11 @@ extern char *optarg; /* ditto */
|
|||||||
/* options */
|
/* options */
|
||||||
static int be_quiet = 0;
|
static int be_quiet = 0;
|
||||||
|
|
||||||
|
static const int SUB_G = 1 << 0;
|
||||||
|
#ifdef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
static const int SUB_P = 1 << 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct sed_cmd {
|
struct sed_cmd {
|
||||||
|
|
||||||
/* address storage */
|
/* address storage */
|
||||||
@@ -80,7 +85,11 @@ struct sed_cmd {
|
|||||||
unsigned int num_backrefs:4; /* how many back references (\1..\9) */
|
unsigned int num_backrefs:4; /* how many back references (\1..\9) */
|
||||||
/* Note: GNU/POSIX sed does not save more than nine backrefs, so
|
/* Note: GNU/POSIX sed does not save more than nine backrefs, so
|
||||||
* we only use 4 bits to hold the number */
|
* we only use 4 bits to hold the number */
|
||||||
unsigned int sub_g:1; /* sed -e 's/foo/bar/g' (global) */
|
#ifndef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
unsigned int sub_flags:1; /* sed -e 's/foo/bar/g' (global) */
|
||||||
|
#else
|
||||||
|
unsigned int sub_flags:2; /* sed -e 's/foo/bar/gp' (global/pattern) */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* edit command (a,i,c) speicific field */
|
/* edit command (a,i,c) speicific field */
|
||||||
char *editline;
|
char *editline;
|
||||||
@@ -244,8 +253,8 @@ static int parse_subst_cmd(struct sed_cmd *sed_cmd, const char *substr)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* the string that gets passed to this function should look like this:
|
* the string that gets passed to this function should look like this:
|
||||||
* s/match/replace/gI
|
* s/match/replace/gIp
|
||||||
* || | ||
|
* || | |||
|
||||||
* mandatory optional
|
* mandatory optional
|
||||||
*
|
*
|
||||||
* (all three of the '/' slashes are mandatory)
|
* (all three of the '/' slashes are mandatory)
|
||||||
@@ -285,11 +294,16 @@ static int parse_subst_cmd(struct sed_cmd *sed_cmd, const char *substr)
|
|||||||
while (substr[++idx]) {
|
while (substr[++idx]) {
|
||||||
switch (substr[idx]) {
|
switch (substr[idx]) {
|
||||||
case 'g':
|
case 'g':
|
||||||
sed_cmd->sub_g = 1;
|
sed_cmd->sub_flags = SUB_G;
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
cflags |= REG_ICASE;
|
cflags |= REG_ICASE;
|
||||||
break;
|
break;
|
||||||
|
#ifdef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
case 'p':
|
||||||
|
sed_cmd->sub_flags = SUB_P;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
/* any whitespace or semicolon trailing after a s/// is ok */
|
/* any whitespace or semicolon trailing after a s/// is ok */
|
||||||
if (strchr("; \t\v\n\r", substr[idx]))
|
if (strchr("; \t\v\n\r", substr[idx]))
|
||||||
@@ -535,10 +549,17 @@ static int do_subst_command(const struct sed_cmd *sed_cmd, const char *line)
|
|||||||
/* if we can match the search string... */
|
/* if we can match the search string... */
|
||||||
if (regexec(sed_cmd->sub_match, ptr, sed_cmd->num_backrefs+1, regmatch, 0) == 0) {
|
if (regexec(sed_cmd->sub_match, ptr, sed_cmd->num_backrefs+1, regmatch, 0) == 0) {
|
||||||
/* print everything before the match, */
|
/* print everything before the match, */
|
||||||
for (i = 0; i < regmatch[0].rm_so; i++)
|
for (i = 0; i < regmatch[0].rm_so; i++) {
|
||||||
|
#ifdef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
if(!be_quiet || (sed_cmd->sub_flags & SUB_P))
|
||||||
|
#endif
|
||||||
fputc(ptr[i], stdout);
|
fputc(ptr[i], stdout);
|
||||||
|
}
|
||||||
|
|
||||||
/* then print the substitution in its place */
|
/* then print the substitution in its place */
|
||||||
|
#ifdef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
if(!be_quiet || (sed_cmd->sub_flags & SUB_P))
|
||||||
|
#endif
|
||||||
print_subst_w_backrefs(ptr, sed_cmd->replace, regmatch);
|
print_subst_w_backrefs(ptr, sed_cmd->replace, regmatch);
|
||||||
|
|
||||||
/* then advance past the match */
|
/* then advance past the match */
|
||||||
@@ -548,7 +569,7 @@ static int do_subst_command(const struct sed_cmd *sed_cmd, const char *line)
|
|||||||
altered++;
|
altered++;
|
||||||
|
|
||||||
/* if we're not doing this globally... */
|
/* if we're not doing this globally... */
|
||||||
if (!sed_cmd->sub_g)
|
if (!sed_cmd->sub_flags & SUB_G)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* if we COULD NOT match the search string (meaning we've gone past
|
/* if we COULD NOT match the search string (meaning we've gone past
|
||||||
@@ -558,7 +579,11 @@ static int do_subst_command(const struct sed_cmd *sed_cmd, const char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* is there anything left to print? */
|
/* is there anything left to print? */
|
||||||
|
#ifdef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
if (*ptr && (!be_quiet || sed_cmds->sub_flags & SUB_P))
|
||||||
|
#else
|
||||||
if (*ptr)
|
if (*ptr)
|
||||||
|
#endif
|
||||||
fputs(ptr, stdout);
|
fputs(ptr, stdout);
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
@@ -656,9 +681,14 @@ 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
|
||||||
* line was altered (via a 'd'elete or 's'ubstitution) */
|
* the line was altered (via a 'd'elete or 's'ubstitution) */
|
||||||
if (!be_quiet && !line_altered)
|
#ifndef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
if (!be_quiet &&!line_altered)
|
||||||
|
#else
|
||||||
|
/* we where specificly requested to print the output */
|
||||||
|
if ((!be_quiet || (sed_cmds[i].sub_flags & SUB_P)) && !line_altered)
|
||||||
|
#endif
|
||||||
fputs(line, stdout);
|
fputs(line, stdout);
|
||||||
|
|
||||||
free(line);
|
free(line);
|
||||||
|
48
sed.c
48
sed.c
@@ -63,6 +63,11 @@ extern char *optarg; /* ditto */
|
|||||||
/* options */
|
/* options */
|
||||||
static int be_quiet = 0;
|
static int be_quiet = 0;
|
||||||
|
|
||||||
|
static const int SUB_G = 1 << 0;
|
||||||
|
#ifdef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
static const int SUB_P = 1 << 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct sed_cmd {
|
struct sed_cmd {
|
||||||
|
|
||||||
/* address storage */
|
/* address storage */
|
||||||
@@ -80,7 +85,11 @@ struct sed_cmd {
|
|||||||
unsigned int num_backrefs:4; /* how many back references (\1..\9) */
|
unsigned int num_backrefs:4; /* how many back references (\1..\9) */
|
||||||
/* Note: GNU/POSIX sed does not save more than nine backrefs, so
|
/* Note: GNU/POSIX sed does not save more than nine backrefs, so
|
||||||
* we only use 4 bits to hold the number */
|
* we only use 4 bits to hold the number */
|
||||||
unsigned int sub_g:1; /* sed -e 's/foo/bar/g' (global) */
|
#ifndef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
unsigned int sub_flags:1; /* sed -e 's/foo/bar/g' (global) */
|
||||||
|
#else
|
||||||
|
unsigned int sub_flags:2; /* sed -e 's/foo/bar/gp' (global/pattern) */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* edit command (a,i,c) speicific field */
|
/* edit command (a,i,c) speicific field */
|
||||||
char *editline;
|
char *editline;
|
||||||
@@ -244,8 +253,8 @@ static int parse_subst_cmd(struct sed_cmd *sed_cmd, const char *substr)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* the string that gets passed to this function should look like this:
|
* the string that gets passed to this function should look like this:
|
||||||
* s/match/replace/gI
|
* s/match/replace/gIp
|
||||||
* || | ||
|
* || | |||
|
||||||
* mandatory optional
|
* mandatory optional
|
||||||
*
|
*
|
||||||
* (all three of the '/' slashes are mandatory)
|
* (all three of the '/' slashes are mandatory)
|
||||||
@@ -285,11 +294,16 @@ static int parse_subst_cmd(struct sed_cmd *sed_cmd, const char *substr)
|
|||||||
while (substr[++idx]) {
|
while (substr[++idx]) {
|
||||||
switch (substr[idx]) {
|
switch (substr[idx]) {
|
||||||
case 'g':
|
case 'g':
|
||||||
sed_cmd->sub_g = 1;
|
sed_cmd->sub_flags = SUB_G;
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
cflags |= REG_ICASE;
|
cflags |= REG_ICASE;
|
||||||
break;
|
break;
|
||||||
|
#ifdef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
case 'p':
|
||||||
|
sed_cmd->sub_flags = SUB_P;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
/* any whitespace or semicolon trailing after a s/// is ok */
|
/* any whitespace or semicolon trailing after a s/// is ok */
|
||||||
if (strchr("; \t\v\n\r", substr[idx]))
|
if (strchr("; \t\v\n\r", substr[idx]))
|
||||||
@@ -535,10 +549,17 @@ static int do_subst_command(const struct sed_cmd *sed_cmd, const char *line)
|
|||||||
/* if we can match the search string... */
|
/* if we can match the search string... */
|
||||||
if (regexec(sed_cmd->sub_match, ptr, sed_cmd->num_backrefs+1, regmatch, 0) == 0) {
|
if (regexec(sed_cmd->sub_match, ptr, sed_cmd->num_backrefs+1, regmatch, 0) == 0) {
|
||||||
/* print everything before the match, */
|
/* print everything before the match, */
|
||||||
for (i = 0; i < regmatch[0].rm_so; i++)
|
for (i = 0; i < regmatch[0].rm_so; i++) {
|
||||||
|
#ifdef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
if(!be_quiet || (sed_cmd->sub_flags & SUB_P))
|
||||||
|
#endif
|
||||||
fputc(ptr[i], stdout);
|
fputc(ptr[i], stdout);
|
||||||
|
}
|
||||||
|
|
||||||
/* then print the substitution in its place */
|
/* then print the substitution in its place */
|
||||||
|
#ifdef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
if(!be_quiet || (sed_cmd->sub_flags & SUB_P))
|
||||||
|
#endif
|
||||||
print_subst_w_backrefs(ptr, sed_cmd->replace, regmatch);
|
print_subst_w_backrefs(ptr, sed_cmd->replace, regmatch);
|
||||||
|
|
||||||
/* then advance past the match */
|
/* then advance past the match */
|
||||||
@@ -548,7 +569,7 @@ static int do_subst_command(const struct sed_cmd *sed_cmd, const char *line)
|
|||||||
altered++;
|
altered++;
|
||||||
|
|
||||||
/* if we're not doing this globally... */
|
/* if we're not doing this globally... */
|
||||||
if (!sed_cmd->sub_g)
|
if (!sed_cmd->sub_flags & SUB_G)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* if we COULD NOT match the search string (meaning we've gone past
|
/* if we COULD NOT match the search string (meaning we've gone past
|
||||||
@@ -558,7 +579,11 @@ static int do_subst_command(const struct sed_cmd *sed_cmd, const char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* is there anything left to print? */
|
/* is there anything left to print? */
|
||||||
|
#ifdef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
if (*ptr && (!be_quiet || sed_cmds->sub_flags & SUB_P))
|
||||||
|
#else
|
||||||
if (*ptr)
|
if (*ptr)
|
||||||
|
#endif
|
||||||
fputs(ptr, stdout);
|
fputs(ptr, stdout);
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
@@ -656,9 +681,14 @@ 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
|
||||||
* line was altered (via a 'd'elete or 's'ubstitution) */
|
* the line was altered (via a 'd'elete or 's'ubstitution) */
|
||||||
if (!be_quiet && !line_altered)
|
#ifndef BB_FEATURE_SED_PATTERN_SPACE
|
||||||
|
if (!be_quiet &&!line_altered)
|
||||||
|
#else
|
||||||
|
/* we where specificly requested to print the output */
|
||||||
|
if ((!be_quiet || (sed_cmds[i].sub_flags & SUB_P)) && !line_altered)
|
||||||
|
#endif
|
||||||
fputs(line, stdout);
|
fputs(line, stdout);
|
||||||
|
|
||||||
free(line);
|
free(line);
|
||||||
|
Reference in New Issue
Block a user