aboutsummaryrefslogtreecommitdiff
path: root/toys/posix
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2020-12-03 16:38:26 -0800
committerRob Landley <rob@landley.net>2020-12-07 00:46:54 -0600
commit50d8ed89b1e02917e83a33b3d62f465192dd500f (patch)
treee4a6d1fccb19b58b8d4adf162e5450380e53ca12 /toys/posix
parented3d5eb0eaf74e6686bc2576b2c4d5a5343dfd57 (diff)
downloadtoybox-50d8ed89b1e02917e83a33b3d62f465192dd500f.tar.gz
sed: add 'x' flag to the 's' command.
The GNU tar manual, when talking about the `tar --transform` option that I need to implement, describes the 'x' flag by saying "regexp is an extended regular expression (see section 'Extended regular expressions' in GNU sed)". Only it turns out that even the latest GNU sed doesn't actually have that flag. It's unique to `tar --transform`. That link is just telling you that the sed manual will explain extended regular expressions, not that GNU sed also supports the 'x' flag. So I don't know whether we want this in toybox sed after all. (It made sense that sed would have such a flag, but no sed that I know of actually does.)
Diffstat (limited to 'toys/posix')
-rw-r--r--toys/posix/sed.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/toys/posix/sed.c b/toys/posix/sed.c
index 8fbef0cb..9bd05034 100644
--- a/toys/posix/sed.c
+++ b/toys/posix/sed.c
@@ -147,7 +147,7 @@ struct sedcmd {
int rmatch[2]; // offset of regex struct for prefix matches (/abc/,/def/p)
int arg1, arg2, w; // offset of two arguments per command, plus s//w filename
unsigned not, hit;
- unsigned sflags; // s///flag bits: i=1, g=2, p=4
+ unsigned sflags; // s///flag bits: i=1, g=2, p=4, x=8
char c; // action
};
@@ -441,7 +441,7 @@ static void sed_line(char **pline, long plen)
} else zmatch = 0;
// If we're replacing only a specific match, skip if this isn't it
- off = command->sflags>>3;
+ off = command->sflags>>4;
if (off && off != ++count) {
memcpy(l2+l2used, rline, match[0].rm_eo);
l2used += match[0].rm_eo;
@@ -793,6 +793,7 @@ static void parse_pattern(char **pline, long len)
if (!TT.nextlen--) break;
} else if (c == 's') {
char *end, delim = 0;
+ int flags;
// s/pattern/replacement/flags
@@ -845,19 +846,20 @@ resume_s:
if (isspace(*line) && *line != '\n') continue;
- if (0 <= (l = stridx("igp", *line))) command->sflags |= 1<<l;
+ if (0 <= (l = stridx("igpx", *line))) command->sflags |= 1<<l;
else if (*line == 'I') command->sflags |= 1<<0;
- else if (!(command->sflags>>3) && 0<(l = strtol(line, &line, 10))) {
- command->sflags |= l << 3;
+ else if (!(command->sflags>>4) && 0<(l = strtol(line, &line, 10))) {
+ command->sflags |= l << 4;
line--;
} else break;
}
+ flags = (FLAG(r) || (command->sflags&8)) ? REG_EXTENDED : 0;
+ if (command->sflags&1) flags |= REG_ICASE;
// We deferred actually parsing the regex until we had the s///i flag
// allocating the space was done by extend_string() above
if (!*TT.remember) command->arg1 = 0;
- else xregcomp((void *)(command->arg1 + (char *)command), TT.remember,
- (REG_EXTENDED*!!FLAG(r))|((command->sflags&1)*REG_ICASE));
+ else xregcomp((void *)(command->arg1+(char *)command),TT.remember,flags);
free(TT.remember);
TT.remember = 0;
if (*line == 'w') {