aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2016-09-06 00:14:24 -0500
committerRob Landley <rob@landley.net>2016-09-06 00:14:24 -0500
commit337c072ac09a94a4a47d81cb214b3b8e55eee621 (patch)
treec6dc6584a3f12dc81dfbdcacc4d3330b0fa3cfb9 /toys
parenteed9ed41aa73023af8f79cd5353b96b80585490f (diff)
downloadtoybox-337c072ac09a94a4a47d81cb214b3b8e55eee621.tar.gz
Teach sed s/// how to handle [:space:] type sequences.
Or more accurately, s@[[:space:]@]@replace@ which can't treat the @ in [] as a delimiter but has to know about nested [[]] to make that decision.
Diffstat (limited to 'toys')
-rw-r--r--toys/posix/sed.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/toys/posix/sed.c b/toys/posix/sed.c
index 744edf7b..31268ece 100644
--- a/toys/posix/sed.c
+++ b/toys/posix/sed.c
@@ -657,6 +657,7 @@ static char *unescape_delimited_string(char **pstr, char *delim)
{
char *to, *from, mode = 0, d;
+ // Grab leading delimiter (if necessary), allocate space for new string
from = *pstr;
if (!delim || !*delim) {
if (!(d = *(from++))) return 0;
@@ -670,13 +671,23 @@ static char *unescape_delimited_string(char **pstr, char *delim)
if (!*from) return 0;
// delimiter in regex character range doesn't count
- if (!mode && *from == '[') {
- mode = '[';
- if (from[1]=='-' || from[1]==']') *(to++) = *(from++);
- } else if (mode && *from == ']') mode = 0;
+ if (*from == '[') {
+ if (!mode) {
+ mode = ']';
+ if (from[1]=='-' || from[1]==']') *(to++) = *(from++);
+ } else if (mode == ']' && strchr(".=:", from[1])) {
+ *(to++) = *(from++);
+ mode = *from;
+ }
+ } else if (*from == mode) {
+ if (mode == ']') mode = 0;
+ else {
+ *(to++) = *(from++);
+ mode = ']';
+ }
// Length 1 range (X-X with same X) is "undefined" and makes regcomp err,
// but the perl build does it, so we need to filter it out.
- else if (mode && *from == '-' && from[-1] == from[1]) {
+ } else if (mode && *from == '-' && from[-1] == from[1]) {
from+=2;
continue;
} else if (*from == '\\') {