Martin Briza c37bd4a
Upstream 0f968ceb7bc1a65773979ef419872ce43677c790
Martin Briza c37bd4a
Original by Paolo Bonzini  <bonzini@gnu.org> - 2012-04-13
Martin Briza c37bd4a
Modified by Martin Briza (original patch didn't apply clearly)
Martin Briza c37bd4a
Martin Briza c37bd4a
* sed/compile.c (convert_number): Remove default_char argument,
Martin Briza c37bd4a
 expect buf to point to it.  Remove maxdigits argument and compute
Martin Briza c37bd4a
 it on the fly.
Martin Briza c37bd4a
 (normalize_text): Unify calls to convert_number under the convert
Martin Briza c37bd4a
 label.  For TEXT_REPLACEMENT add a backslash to the output if
Martin Briza c37bd4a
 convert_number returns ch == '&'.
Martin Briza c37bd4a
--
Martin Briza c37bd4a
diff -rpu sed-4.2.1/sed/compile.c sed-4.2.1-modified/sed/compile.c
Martin Briza c37bd4a
--- sed-4.2.1/sed/compile.c	2009-06-17 14:54:43.000000000 +0200
Martin Briza c37bd4a
+++ sed-4.2.1-modified/sed/compile.c	2012-06-12 16:46:19.310301149 +0200
Martin Briza c37bd4a
@@ -300,20 +300,19 @@ add_then_next(b, ch)
Martin Briza c37bd4a
   return inchar();
Martin Briza c37bd4a
 }
Martin Briza c37bd4a
 
Martin Briza c37bd4a
-static char * convert_number P_((char *, char *, const char *, int, int, int));
Martin Briza c37bd4a
+static char * convert_number P_((char *, char *, const char *, int));
Martin Briza c37bd4a
 static char *
Martin Briza c37bd4a
-convert_number(result, buf, bufend, base, maxdigits, default_char)
Martin Briza c37bd4a
+convert_number(result, buf, bufend, base)
Martin Briza c37bd4a
   char *result;
Martin Briza c37bd4a
   char *buf;
Martin Briza c37bd4a
   const char *bufend;
Martin Briza c37bd4a
   int base;
Martin Briza c37bd4a
-  int maxdigits;
Martin Briza c37bd4a
-  int default_char;
Martin Briza c37bd4a
 {
Martin Briza c37bd4a
   int n = 0;
Martin Briza c37bd4a
+  int max = 1;
Martin Briza c37bd4a
   char *p;
Martin Briza c37bd4a
 
Martin Briza c37bd4a
-  for (p=buf; p < bufend && maxdigits-- > 0; ++p)
Martin Briza c37bd4a
+  for (p=buf+1; p < bufend && max <= 255; ++p, max *= base)
Martin Briza c37bd4a
     {
Martin Briza c37bd4a
       int d = -1;
Martin Briza c37bd4a
       switch (*p)
Martin Briza c37bd4a
@@ -339,8 +338,8 @@ convert_number(result, buf, bufend, base
Martin Briza c37bd4a
 	break;
Martin Briza c37bd4a
       n = n * base + d;
Martin Briza c37bd4a
     }
Martin Briza c37bd4a
-  if (p == buf)
Martin Briza c37bd4a
-    *result = default_char;
Martin Briza c37bd4a
+  if (p == buf+1)
Martin Briza c37bd4a
+    *result = *buf;
Martin Briza c37bd4a
   else
Martin Briza c37bd4a
     *result = n;
Martin Briza c37bd4a
   return p;
Martin Briza c37bd4a
@@ -1417,6 +1416,8 @@ normalize_text(buf, len, buftype)
Martin Briza c37bd4a
   const char *bufend = buf + len;
Martin Briza c37bd4a
   char *p = buf;
Martin Briza c37bd4a
   char *q = buf;
Martin Briza c37bd4a
+  char ch;
Martin Briza c37bd4a
+  int base;
Martin Briza c37bd4a
 
Martin Briza c37bd4a
   /* This variable prevents normalizing text within bracket
Martin Briza c37bd4a
      subexpressions when conforming to POSIX.  If 0, we
Martin Briza c37bd4a
@@ -1464,14 +1465,12 @@ normalize_text(buf, len, buftype)
Martin Briza c37bd4a
 	  case 'v': *q++ = '\v'; p++; continue;
Martin Briza c37bd4a
 
Martin Briza c37bd4a
 	  case 'd': /* decimal byte */
Martin Briza c37bd4a
-	    p = convert_number(q, p+1, bufend, 10, 3, 'd');
Martin Briza c37bd4a
-	    q++;
Martin Briza c37bd4a
-	    continue;
Martin Briza c37bd4a
+            base = 10;
Martin Briza c37bd4a
+            goto convert;
Martin Briza c37bd4a
 
Martin Briza c37bd4a
 	  case 'x': /* hexadecimal byte */
Martin Briza c37bd4a
-	    p = convert_number(q, p+1, bufend, 16, 2, 'x');
Martin Briza c37bd4a
-	    q++;
Martin Briza c37bd4a
-	    continue;
Martin Briza c37bd4a
+            base = 16;
Martin Briza c37bd4a
+            goto convert;
Martin Briza c37bd4a
 
Martin Briza c37bd4a
 #ifdef REG_PERL
Martin Briza c37bd4a
 	  case '0': case '1': case '2': case '3':
Martin Briza c37bd4a
@@ -1480,8 +1479,8 @@ normalize_text(buf, len, buftype)
Martin Briza c37bd4a
 		&& p+1 < bufend
Martin Briza c37bd4a
 		&& p[1] >= '0' && p[1] <= '9')
Martin Briza c37bd4a
 	      {
Martin Briza c37bd4a
-		p = convert_number(q, p, bufend, 8, 3, *p);
Martin Briza c37bd4a
-		q++;
Martin Briza c37bd4a
+                base = 8;
Martin Briza c37bd4a
+                goto convert;
Martin Briza c37bd4a
 	      }
Martin Briza c37bd4a
 	    else
Martin Briza c37bd4a
 	      {
Martin Briza c37bd4a
@@ -1495,8 +1494,8 @@ normalize_text(buf, len, buftype)
Martin Briza c37bd4a
 	  case 'o': /* octal byte */
Martin Briza c37bd4a
 	    if (!(extended_regexp_flags & REG_PERL))
Martin Briza c37bd4a
 	      {
Martin Briza c37bd4a
-	        p = convert_number(q, p+1, bufend,  8, 3, 'o');
Martin Briza c37bd4a
-		q++;
Martin Briza c37bd4a
+                base = 8;
Martin Briza c37bd4a
+                goto convert;
Martin Briza c37bd4a
 	      }
Martin Briza c37bd4a
 	    else
Martin Briza c37bd4a
 	      {
Martin Briza c37bd4a
@@ -1508,10 +1507,16 @@ normalize_text(buf, len, buftype)
Martin Briza c37bd4a
 	    continue;
Martin Briza c37bd4a
 #else
Martin Briza c37bd4a
 	  case 'o': /* octal byte */
Martin Briza c37bd4a
-	    p = convert_number(q, p+1, bufend,  8, 3, 'o');
Martin Briza c37bd4a
-	    q++;
Martin Briza c37bd4a
-	    continue;
Martin Briza c37bd4a
+            base = 8;
Martin Briza c37bd4a
 #endif
Martin Briza c37bd4a
+convert:
Martin Briza c37bd4a
+            p = convert_number(&ch, p, bufend, base);
Martin Briza c37bd4a
+
Martin Briza c37bd4a
+            /* for an ampersand in a replacement, pass the \ up one level */
Martin Briza c37bd4a
+            if (buftype == TEXT_REPLACEMENT && ch == '&')
Martin Briza c37bd4a
+              *q++ = '\\';
Martin Briza c37bd4a
+            *q++ = ch;
Martin Briza c37bd4a
+            continue;
Martin Briza c37bd4a
 
Martin Briza c37bd4a
 	  case 'c':
Martin Briza c37bd4a
 	    if (++p < bufend)
Martin Briza c37bd4a
diff -rpu sed-4.2.1/testsuite/Makefile.am sed-4.2.1-modified/testsuite/Makefile.am
Martin Briza c37bd4a
--- sed-4.2.1/testsuite/Makefile.am	2009-06-25 20:55:35.000000000 +0200
Martin Briza c37bd4a
+++ sed-4.2.1-modified/testsuite/Makefile.am	2012-06-12 16:45:56.875331158 +0200
Martin Briza c37bd4a
@@ -24,7 +24,7 @@ SEDTESTS += \
Martin Briza c37bd4a
 	fasts uniq manis khadafy linecnt eval distrib 8to7 y-bracket \
Martin Briza c37bd4a
 	y-newline allsub cv-vars classes middle bsd stdin flipcase \
Martin Briza c37bd4a
 	insens subwrite writeout readin insert utf8-1 utf8-2 utf8-3 utf8-4 \
Martin Briza c37bd4a
-	badenc inplace-hold brackets \
Martin Briza c37bd4a
+	badenc inplace-hold brackets amp-escape\
Martin Briza c37bd4a
 	help version file quiet \
Martin Briza c37bd4a
 	factor binary3 binary2 binary dc
Martin Briza c37bd4a
 
Martin Briza c37bd4a
@@ -39,6 +39,7 @@ EXTRA_DIST = \
Martin Briza c37bd4a
 	8bit.good 8bit.inp 8bit.sed \
Martin Briza c37bd4a
 	8to7.good 8to7.inp 8to7.sed \
Martin Briza c37bd4a
 	allsub.good allsub.inp allsub.sed \
Martin Briza c37bd4a
+	amp-escape.good amp-escape.inp amp-escape.sed \
Martin Briza c37bd4a
 	appquit.good appquit.inp appquit.sed \
Martin Briza c37bd4a
 	binary.good binary.inp binary.sed binary2.sed binary3.sed \
Martin Briza c37bd4a
 	bkslashes.good bkslashes.inp bkslashes.sed \
Martin Briza c37bd4a
diff -rpu sed-4.2.1/testsuite/Makefile.tests sed-4.2.1-modified/testsuite/Makefile.tests
Martin Briza c37bd4a
--- sed-4.2.1/testsuite/Makefile.tests	2009-06-25 20:55:35.000000000 +0200
Martin Briza c37bd4a
+++ sed-4.2.1-modified/testsuite/Makefile.tests	2012-06-12 16:46:17.195303978 +0200
Martin Briza c37bd4a
@@ -21,7 +21,7 @@ SKIP = :>$@.skip; exit 77
Martin Briza c37bd4a
 enable sep inclib 8bit 8to7 newjis xabcx dollar noeol bkslashes \
Martin Briza c37bd4a
 numsub head madding mac-mf empty xbxcx xbxcx3 recall recall2 xemacs \
Martin Briza c37bd4a
 appquit fasts uniq manis linecnt khadafy allsub flipcase space modulo \
Martin Briza c37bd4a
-y-bracket y-newline insert brackets::
Martin Briza c37bd4a
+y-bracket y-newline insert brackets amp-escape::
Martin Briza c37bd4a
 	$(SEDENV) $(SED) -f $(srcdir)/$@.sed \
Martin Briza c37bd4a
 		< $(srcdir)/$@.inp | $(TR) -d \\r > $@.out 
Martin Briza c37bd4a
 	$(CMP) $(srcdir)/$@.good $@.out