Expansions: add operators base32, base32d
authorJeremy Harris <jgh146exb@wizmail.org>
Mon, 15 Feb 2016 15:42:21 +0000 (15:42 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 30 Jul 2016 14:15:30 +0000 (15:15 +0100)
doc/doc-docbook/spec.xfpt
doc/doc-txt/NewStuff
src/src/expand.c
test/scripts/0000-Basic/0002
test/stdout/0002

index d3307eacd88c41e091956395018b13b595c8da6b..d08a7a040e77c28a6c2b53acb2b00b31deb14a08 100644 (file)
@@ -10090,6 +10090,21 @@ Last:user@example.com
 user@example.com
 .endd
 
+.new
+.vitem &*${base32:*&<&'digits'&>&*}*&
+.cindex "&%base32%& expansion item"
+.cindex "expansion" "conversion to base 32"
+The string must consist entirely of decimal digits. The number is converted to
+base 32 and output as a (empty, for zero) string of characters.
+Only lowercase letters are used.
+
+.vitem &*${base32d:*&<&'base-32&~digits'&>&*}*&
+.cindex "&%base32d%& expansion item"
+.cindex "expansion" "conversion to base 32"
+The string must consist entirely of base-32 digits.
+The number is converted to decimal and output as a string.
+.wen
+
 .vitem &*${base62:*&<&'digits'&>&*}*&
 .cindex "&%base62%& expansion item"
 .cindex "expansion" "conversion to base 62"
index 2a776b7305bccde69e4d1c67a11d894695de1cd6..587dc65084331b8370a9e7a75e97493a2b33f8b3 100644 (file)
@@ -26,6 +26,8 @@ Version 4.88
     the queue to be used for a message.  A $queue_name variable gives
     visibility.
 
+ 6. New expansion operators base32/base32d.
+
 
 Version 4.87
 ------------
index 2c23f13e4af8b0c2ae00d6d67bdf0b425c708be0..10874add3e50e92f6140668140cdd79b82bb0d68 100644 (file)
@@ -199,6 +199,8 @@ enum {
 static uschar *op_table_main[] = {
   US"address",
   US"addresses",
+  US"base32",
+  US"base32d",
   US"base62",
   US"base62d",
   US"base64",
@@ -242,6 +244,8 @@ static uschar *op_table_main[] = {
 enum {
   EOP_ADDRESS =  nelem(op_table_underscore),
   EOP_ADDRESSES,
+  EOP_BASE32,
+  EOP_BASE32D,
   EOP_BASE62,
   EOP_BASE62D,
   EOP_BASE64,
@@ -838,6 +842,9 @@ static int utf8_table2[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
     }
 
 
+
+static uschar * base32_chars = US"abcdefghijklmnopqrstuvwxyz234567";
+
 /*************************************************
 *           Binary chop search on a table        *
 *************************************************/
@@ -6257,6 +6264,47 @@ while (*s != 0)
 
     switch(c)
       {
+      case EOP_BASE32:
+       {
+        uschar *t;
+        unsigned long int n = Ustrtoul(sub, &t, 10);
+       uschar * s = NULL;
+       int sz = 0, i = 0;
+
+        if (*t != 0)
+          {
+          expand_string_message = string_sprintf("argument for base32 "
+            "operator is \"%s\", which is not a decimal number", sub);
+          goto EXPAND_FAILED;
+          }
+       for ( ; n; n >>= 5)
+         s = string_catn(s, &sz, &i, &base32_chars[n & 0x1f], 1);
+
+       while (i > 0) yield = string_catn(yield, &size, &ptr, &s[--i], 1);
+       continue;
+       }
+
+      case EOP_BASE32D:
+        {
+        uschar *tt = sub;
+        unsigned long int n = 0;
+       uschar * s;
+        while (*tt)
+          {
+          uschar * t = Ustrchr(base32_chars, *tt++);
+          if (t == NULL)
+            {
+            expand_string_message = string_sprintf("argument for base32d "
+              "operator is \"%s\", which is not a base 32 number", sub);
+            goto EXPAND_FAILED;
+            }
+          n = n * 32 + (t - base32_chars);
+          }
+        s = string_sprintf("%ld", n);
+        yield = string_cat(yield, &size, &ptr, s);
+        continue;
+        }
+
       case EOP_BASE62:
         {
         uschar *t;
index 278a38660519afadefd1ae19eef06594dae3d9aa..dafcba7f08154b9ecaf82b0b60d93fa3ece04af4 100644 (file)
@@ -179,6 +179,20 @@ hex2b64:${hex2b64:1a2b3c4d5e6g}
 hex2b64:${hex2b64:${md5:the quick brown fox}}
 hex2b64:${hex2b64:${sha1:the quick brown fox}}
 
+base32: 0  <${base32:0}>
+base32: 1  <${base32:1}>
+base32: 31 <${base32:31}>
+base32: 32 <${base32:32}>
+base32: 42 <${base32:42}>
+base32 error: 0x1 ${base32:0x1}
+
+base32d: 0  ${base32d:${base32:0}}
+base32d: 1  ${base32d:${base32:1}}
+base32d: 31 ${base32d:${base32:31}}
+base32d: 32 ${base32d:${base32:32}}
+base32d: 42 ${base32d:${base32:42}}
+base32d error: ABC ${base32d:ABC}
+
 The base62 operator is actually a base36 operator in the Darwin and Cygwin
 environments. Write cunning tests that produce the same output in both cases,
 while doing a reasonable check.
index 0bbd4c75497e8fb385d05e58de88f18bd0919a12..a19cc526c85ff96673d3f5b07d44bc1fb4070be0 100644 (file)
 > hex2b64:MPPJPkZDbetYunCBao7BJA==
 > hex2b64:ztcfpyNSMb7Tg/rP3EHE3cwi7PE=
 > 
+> base32: 0  <>
+> base32: 1  <b>
+> base32: 31 <7>
+> base32: 32 <ba>
+> base32: 42 <bk>
+> Failed: argument for base32 operator is "0x1", which is not a decimal number
+> 
+> base32d: 0  0
+> base32d: 1  1
+> base32d: 31 31
+> base32d: 32 32
+> base32d: 42 42
+> Failed: argument for base32d operator is "ABC", which is not a base 32 number
+> 
 > The base62 operator is actually a base36 operator in the Darwin and Cygwin
 > environments. Write cunning tests that produce the same output in both cases,
 > while doing a reasonable check.