Expansions: new ${escape8bit:<string>} operator. Bug 1863
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 14 Aug 2016 14:11:04 +0000 (15:11 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 14 Aug 2016 14:11:04 +0000 (15:11 +0100)
doc/doc-docbook/spec.xfpt
doc/doc-txt/NewStuff
src/src/expand.c
test/scripts/0000-Basic/0002
test/stdout/0002

index 7b5e3ccd57b3a05264cc335a4efa681fe0c65a57..3ab63e5ecbb66c924966ba43bf33ae7232ca55a9 100644 (file)
@@ -10158,6 +10158,15 @@ escape sequences starting with a backslash. Whether characters with the most
 significant bit set (so-called &"8-bit characters"&) count as printing or not
 is controlled by the &%print_topbitchars%& option.
 
+.new
+.vitem &*${escape8bit:*&<&'string'&>&*}*&
+.cindex "expansion" "escaping 8-bit characters"
+.cindex "&%escape8bit%& expansion item"
+If the string contains and characters with the most significant bit set,
+they are converted to escape sequences starting with a backslash.
+Backslashes and DEL characters are also converted.
+.wen
+
 
 .vitem &*${eval:*&<&'string'&>&*}*&&~and&~&*${eval10:*&<&'string'&>&*}*&
 .cindex "expansion" "expression evaluation"
index cf1cf6d56e9f9dd7b304f026cd518c4e353c459b..219c3c3fbc8063620e3c405d1d15f0f73589a746 100644 (file)
@@ -35,6 +35,8 @@ Version 4.88
 
  8. LMDB lookup support, as Experimental. Patch supplied by Andrew Colin Kissa.
 
+ 9. Expansion operator escape8bit, like escape but not touching newline etc..
+
 
 Version 4.87
 ------------
index c13284d8e78925c4053ef959ee62a700e2b8e209..fd55436a24a925df20ccdad83dab403e1b720247 100644 (file)
@@ -207,6 +207,7 @@ static uschar *op_table_main[] = {
   US"base64d",
   US"domain",
   US"escape",
+  US"escape8bit",
   US"eval",
   US"eval10",
   US"expand",
@@ -252,6 +253,7 @@ enum {
   EOP_BASE64D,
   EOP_DOMAIN,
   EOP_ESCAPE,
+  EOP_ESCAPE8BIT,
   EOP_EVAL,
   EOP_EVAL10,
   EOP_EXPAND,
@@ -7109,11 +7111,23 @@ while (*s != 0)
 
       case EOP_ESCAPE:
         {
-        const uschar *t = string_printing(sub);
+        const uschar * t = string_printing(sub);
         yield = string_cat(yield, &size, &ptr, t);
         continue;
         }
 
+      case EOP_ESCAPE8BIT:
+       {
+       const uschar * s = sub;
+       uschar c;
+
+       for (s = sub; c = *s; s++)
+         yield = c < 127 && c != '\\'
+           ? string_catn(yield, &size, &ptr, s, 1)
+           : string_catn(yield, &size, &ptr, string_sprintf("\\%03o", c), 4);
+       continue;
+       }
+
       /* Handle numeric expression evaluation */
 
       case EOP_EVAL:
index dafcba7f08154b9ecaf82b0b60d93fa3ece04af4..c2dcc40d9abc9b59b9d66da2eee73d7ef1995f56 100644 (file)
@@ -132,7 +132,9 @@ addresses: ${addresses:Exim Person <local-part@dom.ain> (that's me), \
            xyz@abc, nullgroupname:;, group: p@q, r@s; }
 addresses: ${addresses:local-part@dom.ain <local-part@dom.ain>}
 
-escape: ${escape:B7·F2ò}
+escape:     ${escape:B7·F2ò}
+excape8bit: ${escape8bit:undisturbed text\ttab\nnewline\ttab\\backslash \176tilde\177DEL\200\x81.}
+
 eval:   ${eval:1+1}
 eval:   ${eval:1+2*3}
 eval:   ${eval:(1+2)*3}
index a19cc526c85ff96673d3f5b07d44bc1fb4070be0..b6ca54d48363cbcba8446e2682e4bb25bbda2374 100644 (file)
 > addresses: local-part@dom.ain:xyz@abc:p@q:r@s
 > addresses: 
 > 
-> escape: B7\267F2\362
+> escape:     B7\267F2\362
+> excape8bit: undisturbed text tab
+newline        tab\134backslash ~tilde\177DEL\200\201.
+> 
 > eval:   2
 > eval:   7
 > eval:   9