Follow POSIX (IEEE Std 1003.1, 2004 Edition) in the implementation

of the y (translate) command.

"If a backslash character is immediately followed by a backslash
character in string1 or string2, the two backslash characters shall
be counted as a single literal backslash character"

Pointed by:	Marius Strobl
Obtained from:	Mac OS X
This commit is contained in:
dds 2009-09-20 15:17:40 +00:00
parent cc9cdb30b3
commit 668711df00
3 changed files with 17 additions and 9 deletions

View File

@ -445,6 +445,10 @@ u2/g' lines1
# set specification (both with --posix and without).
mark '8.19' ; sed 's/l/[/' lines1 | $SED -e 's[\[.[X['
mark '8.20' ; sed 's/l/[/' lines1 | $SED -e 's[\[.[X\[['
COMMENT='\ in y command'
mark '8.21'
echo 'a\b(c' |
$SED 'y%ABCDEFGHIJKLMNOPQRSTUVWXYZ, /\\()"%abcdefghijklmnopqrstuvwxyz,------%'
}
test_error()

View File

@ -0,0 +1 @@
a-b-c

View File

@ -66,7 +66,7 @@ static struct labhash {
static char *compile_addr(char *, struct s_addr *);
static char *compile_ccl(char **, char *);
static char *compile_delimited(char *, char *);
static char *compile_delimited(char *, char *, int);
static char *compile_flags(char *, struct s_subst *);
static regex_t *compile_re(char *, int);
static char *compile_subst(char *, struct s_subst *);
@ -320,7 +320,7 @@ semicolon: EATSPACE();
linenum, fname);
if ((cmd->u.s = calloc(1, sizeof(struct s_subst))) == NULL)
err(1, "malloc");
p = compile_delimited(p, re);
p = compile_delimited(p, re, 0);
if (p == NULL)
errx(1,
"%lu: %s: unterminated substitute pattern", linenum, fname);
@ -373,7 +373,7 @@ semicolon: EATSPACE();
* with the processed string.
*/
static char *
compile_delimited(char *p, char *d)
compile_delimited(char *p, char *d, int is_tr)
{
char c;
@ -399,9 +399,12 @@ compile_delimited(char *p, char *d)
*d++ = '\n';
p += 2;
continue;
} else if (*p == '\\' && p[1] == '\\')
*d++ = *p++;
else if (*p == c) {
} else if (*p == '\\' && p[1] == '\\') {
if (is_tr)
p++;
else
*d++ = *p++;
} else if (*p == c) {
*d = '\0';
return (p + 1);
}
@ -654,11 +657,11 @@ compile_tr(char *p, struct s_tr **py)
errx(1,
"%lu: %s: transform pattern can not be delimited by newline or backslash",
linenum, fname);
p = compile_delimited(p, old);
p = compile_delimited(p, old, 1);
if (p == NULL)
errx(1, "%lu: %s: unterminated transform source string",
linenum, fname);
p = compile_delimited(p - 1, new);
p = compile_delimited(p - 1, new, 1);
if (p == NULL)
errx(1, "%lu: %s: unterminated transform target string",
linenum, fname);
@ -781,7 +784,7 @@ compile_addr(char *p, struct s_addr *a)
++p;
/* FALLTHROUGH */
case '/': /* Context address */
p = compile_delimited(p, re);
p = compile_delimited(p, re, 0);
if (p == NULL)
errx(1, "%lu: %s: unterminated regular expression", linenum, fname);
/* Check for case insensitive regexp flag */