base32d: 42 ${base32d:${base32:42}}
base32d error: ABC ${base32d:ABC}
-The base62 operator is actually a base36 operator in the Darwin and Cygwin
+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.
a.b.c: ${lookup{a.b.c}wildlsearch{DIR/aux-var/0002.wild}}
ab.c: ${lookup{ab.c}wildlsearch{DIR/aux-var/0002.wild}}
xyz: ${lookup{xyz}wildlsearch{DIR/aux-var/0002.wild}}
-Xyz: ${lookup{Xyz}wildlsearch{DIR/aux-var/0002.wild}}
-Zyz: ${lookup{Zyz}wildlsearch{DIR/aux-var/0002.wild}}
+.Xyz: ${lookup{Xyz}wildlsearch{DIR/aux-var/0002.wild}}
+.Zyz: ${lookup{Zyz}wildlsearch{DIR/aux-var/0002.wild}}
a b: ${lookup{a b}wildlsearch{DIR/aux-var/0002.wild}}
a b: ${lookup{a b}wildlsearch{DIR/aux-var/0002.wild}}
a:b: ${lookup{a:b}wildlsearch{DIR/aux-var/0002.wild}}
a.b.c: ${lookup{a.b.c}nwildlsearch{DIR/aux-var/0002.wild}}
ab.c: ${lookup{ab.c}nwildlsearch{DIR/aux-var/0002.wild}}
xyz: ${lookup{xyz}nwildlsearch{DIR/aux-var/0002.wild}}
-Xyz: ${lookup{Xyz}nwildlsearch{DIR/aux-var/0002.wild}}
-Zyz: ${lookup{Zyz}nwildlsearch{DIR/aux-var/0002.wild}}
+.Xyz: ${lookup{Xyz}nwildlsearch{DIR/aux-var/0002.wild}}
+.Zyz: ${lookup{Zyz}nwildlsearch{DIR/aux-var/0002.wild}}
a b: ${lookup{a b}nwildlsearch{DIR/aux-var/0002.wild}}
a b: ${lookup{a b}nwildlsearch{DIR/aux-var/0002.wild}}
a:b: ${lookup{a:b}nwildlsearch{DIR/aux-var/0002.wild}}
# Some tests of case-(in)dependence
-MiXeD-CD: ${lookup{MiXeD-CD}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
-MixeD-CD: ${lookup{MixeD-CD}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
-MiXeD-Ncd: ${lookup{MiXeD-Ncd}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
-MixeD-Ncd: ${lookup{MixeD-Ncd}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
+.MiXeD-CD: ${lookup{MiXeD-CD}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
+.MixeD-CD: ${lookup{MixeD-CD}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
+.MiXeD-Ncd: ${lookup{MiXeD-Ncd}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
+.MixeD-Ncd: ${lookup{MixeD-Ncd}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
# IP address (CIDR) lookups
${extract{ B }{A=1 B=2 C=3}{$value}{NOT FOUND}}
${extract{2}{:}{1:2:3}}
${extract{ 2 }{:}{1:2:3}{$value}{NOT FOUND}}
-Empty:<${extract{D}{A=1 B=2 C=3}}>
-Empty:<${extract{4}{:}{1:2:3}}>
+empty:<${extract{D}{A=1 B=2 C=3}}>
+empty:<${extract{4}{:}{1:2:3}}>
${extract{C}{A=1 B=2 C=3}{<$value>}}
${extract{3}{:}{1:2:3}{<$value>}}
-Empty:<${extract{Z}{A=1 B=2 C=3}{<$value>}}>
-Empty:<${extract{4}{:}{1:2:3}{<$value>}}>
+empty:<${extract{Z}{A=1 B=2 C=3}{<$value>}}>
+empty:<${extract{4}{:}{1:2:3}{<$value>}}>
${extract{Z}{A=1 B=2 C=3}{<$value>}{no Z}}
${extract{4}{:}{1:2:3}{<$value>}{no 4}}
${extract{Z}{A=1 B=2 C=3}{<$value>}fail}
abcd ${rfc2047:abcd}
<:abcd:> ${rfc2047:<:abcd:>}
<:ab cd:> ${rfc2047:<:ab cd:>}
-Long: ${rfc2047: here we go: a string that is going to be encoded: it will go over the 75-char limit}
-Long: ${rfc2047: here we go: a string that is going to be encoded: it will go over the 75-char limit by a long way; in fact this one will go over the 150 character limit}
+long: ${rfc2047: here we go: a string that is going to be encoded: it will go over the 75-char limit}
+long: ${rfc2047: here we go: a string that is going to be encoded: it will go over the 75-char limit by a long way; in fact this one will go over the 150 character limit}
# RFC 2047 decode
# Calling a command
${run{DIR/aux-fixed/0002.runfile 0}}
-RC=$runrc
+rc=$runrc
${run{DIR/aux-fixed/0002.runfile 0}{1}{2}}
-RC=$runrc
+rc=$runrc
${run{DIR/aux-fixed/0002.runfile 0}{$value}{2}}
-RC=$runrc
+rc=$runrc
${run{DIR/aux-fixed/0002.runfile 1}{$value}{2}}
-RC=$runrc
+rc=$runrc
${run{DIR/aux-fixed/0002.runfile 1}{$value}{$value}}
-RC=$runrc
+rc=$runrc
${run{DIR/test-nonexist}{Y}{N}}
-RC=$runrc
+rc=$runrc
>>${run{DIR/bin/iefbr14}}<<
-RC=$runrc
+rc=$runrc
${if eq{1}{2}{${run{/non/exist}}}{1!=2}}
-RC=$runrc
+rc=$runrc
# PRVS
${env {USER}}
${env {NO_SUCH_VARIABLE} {oops, success} {correct}}
+# JSON
+
+${extract json {Url} \
+ { \{ \"Url\": \"http://www.example.com/image/481989943\",\
+ \"Height\": 125,\
+ \"Width\": 100\
+ \} \
+ } \
+ }
+${extract json {Width} \
+ { \{ \"Url\": \"http://www.example.com/image/481989943\",\
+ \"Height\": 125,\
+ \"Width\": 100\
+ \} \
+ } \
+ }
+${extract json {2} {[116, 943, 234, 38793]} }
+${extract json {2} {${extract json{IDs} {\{"other":"foo", "IDs": [116, 943, 234]\} }}} }
+
+${extract json {2} {["red", "green", "blue", "black"]} }
+${extract jsons{2} {["red", "green", "blue", "black"]} }
+<${extract jsons{5} {["red", "green", "blue", "black"]} }>
+expect: <>
+
+${extract json {seconds} { \{"hours":0, "mins":0, "seconds":59\} }}
+${extract json {seconds} {${extract json {2} { ["irrelevant", \{"hours":0, "mins":0, "seconds":59\}] }}}}
+
+${extract json{IDs}{ \{"IDs": \{"1":116, "2":943, "3":234\}\} }}
+expect: {"1":116, "2":943, "3":234}
+
+${extract json{IDs}{ \{"id": \{"a":101, "b":102\}, "IDs": \{"1":116, "2":943, "3":234\}\} }}
+expect: {"1":116, "2":943, "3":234}
+
+<${extract json{nonexistent}{ \{"id": \{"a":101, "b":102\}, "IDs": \{"1":116, "2":943, "3":234\}\} }}>
+expect: <>
+<${extract jsons{nonexistent}{ \{"id": \{"a":101, "b":102\}, "IDs": \{"1":116, "2":943, "3":234\}\} }}>
+expect: <>
+
+${if forany_json {[1, 2, 3]}{={$item}{1}}{yes}{no}}
+${if forany_jsons{["A", "B", "C"]}{eq{$item}{B}}{yes}{no}}
+
****
# Test "escape" with print_topbitchars
exim -be -DPTBC=print_topbitchars
${if eq {1}{1}{yes}{${lookup{xx}lsearch{/non/exist}}}}
match_address: ${if match_address{a.b.c}{a.b.c}{yes}{no}}
****
+exim -d-all+expand+noutf8 -be
+primary_hostname: $primary_hostname
+match: ${if match{abcd}{\N^([ab]+)(\w+)$\N}{$2$1}fail}
+match: ${if match{wxyz}{\N^([ab]+)(\w+)$\N}{$2$1}fail}
+${if eq {1}{1}{yes}{${lookup{xx}lsearch{/non/exist}}}}
+match_address: ${if match_address{a.b.c}{a.b.c}{yes}{no}}
+****
# Sender host name and address etc, all unset
exim -be
-be Sender host name and address etc, all unset