summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gnu.org>2012-04-13 10:39:09 +0200
committerPaolo Bonzini <bonzini@gnu.org>2012-04-13 10:42:53 +0200
commit8c7d0777642bc35fbda049250ca84e23112dde6b (patch)
tree041a85633ac16a906fe6154826fe57036592f12a
parente4536dbf6150557a817628429f61232959248723 (diff)
downloadsed-8c7d0777642bc35fbda049250ca84e23112dde6b.tar.gz
fix \x26 on RHS of s command
2012-04-13 Paolo Bonzini <bonzini@gnu.org> * sed/compile.c (convert_number): Remove default_char argument, expect buf to point to it. Remove maxdigits argument and compute it on the fly. (normalize_text): Unify calls to convert_number under the convert label. For TEXT_REPLACEMENT add a backslash to the output if convert_number returns ch == '&'.
-rw-r--r--ChangeLog9
-rw-r--r--sed/compile.c45
-rw-r--r--testsuite/Makefile.am3
-rw-r--r--testsuite/Makefile.tests2
4 files changed, 37 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 802f71e..3117430 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-04-13 Paolo Bonzini <bonzini@gnu.org>
+
+ * sed/compile.c (convert_number): Remove default_char argument,
+ expect buf to point to it. Remove maxdigits argument and compute
+ it on the fly.
+ (normalize_text): Unify calls to convert_number under the convert
+ label. For TEXT_REPLACEMENT add a backslash to the output if
+ convert_number returns ch == '&'.
+
2012-03-16 Paolo Bonzini <bonzini@gnu.org>
* basicdefs.h (P_): Remove.
diff --git a/sed/compile.c b/sed/compile.c
index 21b3464..513fac5 100644
--- a/sed/compile.c
+++ b/sed/compile.c
@@ -284,20 +284,19 @@ add_then_next(b, ch)
return inchar();
}
-static char * convert_number (char *, char *, const char *, int, int, int);
+static char * convert_number (char *, char *, const char *, int);
static char *
-convert_number(result, buf, bufend, base, maxdigits, default_char)
+convert_number(result, buf, bufend, base)
char *result;
char *buf;
const char *bufend;
int base;
- int maxdigits;
- int default_char;
{
int n = 0;
+ int max = 1;
char *p;
- for (p=buf; p < bufend && maxdigits-- > 0; ++p)
+ for (p=buf+1; p < bufend && max <= 255; ++p, max *= base)
{
int d = -1;
switch (*p)
@@ -323,8 +322,8 @@ convert_number(result, buf, bufend, base, maxdigits, default_char)
break;
n = n * base + d;
}
- if (p == buf)
- *result = default_char;
+ if (p == buf+1)
+ *result = *buf;
else
*result = n;
return p;
@@ -1399,6 +1398,8 @@ normalize_text(buf, len, buftype)
const char *bufend = buf + len;
char *p = buf;
char *q = buf;
+ char ch;
+ int base;
/* This variable prevents normalizing text within bracket
subexpressions when conforming to POSIX. If 0, we
@@ -1445,14 +1446,12 @@ normalize_text(buf, len, buftype)
case 'v': *q++ = '\v'; p++; continue;
case 'd': /* decimal byte */
- p = convert_number(q, p+1, bufend, 10, 3, 'd');
- q++;
- continue;
+ base = 10;
+ goto convert;
case 'x': /* hexadecimal byte */
- p = convert_number(q, p+1, bufend, 16, 2, 'x');
- q++;
- continue;
+ base = 16;
+ goto convert;
#ifdef REG_PERL
case '0': case '1': case '2': case '3':
@@ -1461,8 +1460,8 @@ normalize_text(buf, len, buftype)
&& p+1 < bufend
&& p[1] >= '0' && p[1] <= '9')
{
- p = convert_number(q, p, bufend, 8, 3, *p);
- q++;
+ base = 8;
+ goto convert;
}
else
{
@@ -1476,8 +1475,8 @@ normalize_text(buf, len, buftype)
case 'o': /* octal byte */
if (!(extended_regexp_flags & REG_PERL))
{
- p = convert_number(q, p+1, bufend, 8, 3, 'o');
- q++;
+ base = 8;
+ goto convert;
}
else
{
@@ -1489,10 +1488,16 @@ normalize_text(buf, len, buftype)
continue;
#else
case 'o': /* octal byte */
- p = convert_number(q, p+1, bufend, 8, 3, 'o');
- q++;
- continue;
+ base = 8;
#endif
+convert:
+ p = convert_number(&ch, p, bufend, base);
+
+ /* for an ampersand in a replacement, pass the \ up one level */
+ if (buftype == TEXT_REPLACEMENT && ch == '&')
+ *q++ = '\\';
+ *q++ = ch;
+ continue;
case 'c':
if (++p < bufend)
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 962a873..03b236e 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -15,7 +15,7 @@ SEDTESTS = \
fasts uniq manis khadafy linecnt eval distrib 8to7 y-bracket \
y-newline allsub cv-vars classes middle bsd stdin flipcase \
insens subwrite writeout readin insert \
- badenc inplace-hold brackets \
+ badenc inplace-hold brackets amp-escape \
help version file quiet \
factor binary3 binary2 binary dc
@@ -29,6 +29,7 @@ EXTRA_DIST = runtest Makefile.tests \
8bit.good 8bit.inp 8bit.sed \
8to7.good 8to7.inp 8to7.sed \
allsub.good allsub.inp allsub.sed \
+ amp-escape.good amp-escape.inp amp-escape.sed \
appquit.good appquit.inp appquit.sed \
binary.good binary.inp binary.sed binary2.sed binary3.sed \
bkslashes.good bkslashes.inp bkslashes.sed \
diff --git a/testsuite/Makefile.tests b/testsuite/Makefile.tests
index 1953903..861957f 100644
--- a/testsuite/Makefile.tests
+++ b/testsuite/Makefile.tests
@@ -19,7 +19,7 @@ RM=rm -f
enable sep inclib 8bit 8to7 newjis xabcx dollar noeol bkslashes \
numsub head madding mac-mf empty xbxcx xbxcx3 recall recall2 xemacs \
appquit fasts uniq manis linecnt khadafy allsub flipcase space modulo \
-y-bracket y-newline insert brackets::
+y-bracket y-newline insert brackets amp-escape::
$(SEDENV) $(SED) -f $(srcdir)/$@.sed \
< $(srcdir)/$@.inp | $(TR) -d \\r > $@.out
$(CMP) $(srcdir)/$@.good $@.out