aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--busybox.def.h3
-rw-r--r--editors/sed.c48
-rw-r--r--sed.c48
3 files changed, 81 insertions, 18 deletions
diff --git a/busybox.def.h b/busybox.def.h
index d9477d41c..fd4302a84 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -217,6 +217,9 @@
// Enable support for "--exclude" for excluding files
#define BB_FEATURE_TAR_EXCLUDE
//
+// Enable support for s///p pattern matching
+#define BB_FEATURE_SED_PATTERN_SPACE
+//
//// Enable reverse sort
#define BB_FEATURE_SORT_REVERSE
//
diff --git a/editors/sed.c b/editors/sed.c
index 60b1e8d2e..f3c3262e4 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -63,6 +63,11 @@ extern char *optarg; /* ditto */
/* options */
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 {
/* address storage */
@@ -80,7 +85,11 @@ struct sed_cmd {
unsigned int num_backrefs:4; /* how many back references (\1..\9) */
/* Note: GNU/POSIX sed does not save more than nine backrefs, so
* 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 */
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:
- * s/match/replace/gI
- * || | ||
+ * s/match/replace/gIp
+ * || | |||
* mandatory optional
*
* (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]) {
switch (substr[idx]) {
case 'g':
- sed_cmd->sub_g = 1;
+ sed_cmd->sub_flags = SUB_G;
break;
case 'I':
cflags |= REG_ICASE;
break;
+#ifdef BB_FEATURE_SED_PATTERN_SPACE
+ case 'p':
+ sed_cmd->sub_flags = SUB_P;
+ break;
+#endif
default:
/* any whitespace or semicolon trailing after a s/// is ok */
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 (regexec(sed_cmd->sub_match, ptr, sed_cmd->num_backrefs+1, regmatch, 0) == 0) {
/* 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);
+ }
/* 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);
/* then advance past the match */
@@ -548,7 +569,7 @@ static int do_subst_command(const struct sed_cmd *sed_cmd, const char *line)
altered++;
/* if we're not doing this globally... */
- if (!sed_cmd->sub_g)
+ if (!sed_cmd->sub_flags & SUB_G)
break;
}
/* 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? */
+#ifdef BB_FEATURE_SED_PATTERN_SPACE
+ if (*ptr && (!be_quiet || sed_cmds->sub_flags & SUB_P))
+#else
if (*ptr)
+#endif
fputs(ptr, stdout);
/* 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
- * line was altered (via a 'd'elete or 's'ubstitution) */
- if (!be_quiet && !line_altered)
+ /* 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) */
+#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);
free(line);
diff --git a/sed.c b/sed.c
index 60b1e8d2e..f3c3262e4 100644
--- a/sed.c
+++ b/sed.c
@@ -63,6 +63,11 @@ extern char *optarg; /* ditto */
/* options */
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 {
/* address storage */
@@ -80,7 +85,11 @@ struct sed_cmd {
unsigned int num_backrefs:4; /* how many back references (\1..\9) */
/* Note: GNU/POSIX sed does not save more than nine backrefs, so
* 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 */
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:
- * s/match/replace/gI
- * || | ||
+ * s/match/replace/gIp
+ * || | |||
* mandatory optional
*
* (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]) {
switch (substr[idx]) {
case 'g':
- sed_cmd->sub_g = 1;
+ sed_cmd->sub_flags = SUB_G;
break;
case 'I':
cflags |= REG_ICASE;
break;
+#ifdef BB_FEATURE_SED_PATTERN_SPACE
+ case 'p':
+ sed_cmd->sub_flags = SUB_P;
+ break;
+#endif
default:
/* any whitespace or semicolon trailing after a s/// is ok */
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 (regexec(sed_cmd->sub_match, ptr, sed_cmd->num_backrefs+1, regmatch, 0) == 0) {
/* 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);
+ }
/* 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);
/* then advance past the match */
@@ -548,7 +569,7 @@ static int do_subst_command(const struct sed_cmd *sed_cmd, const char *line)
altered++;
/* if we're not doing this globally... */
- if (!sed_cmd->sub_g)
+ if (!sed_cmd->sub_flags & SUB_G)
break;
}
/* 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? */
+#ifdef BB_FEATURE_SED_PATTERN_SPACE
+ if (*ptr && (!be_quiet || sed_cmds->sub_flags & SUB_P))
+#else
if (*ptr)
+#endif
fputs(ptr, stdout);
/* 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
- * line was altered (via a 'd'elete or 's'ubstitution) */
- if (!be_quiet && !line_altered)
+ /* 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) */
+#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);
free(line);