identifiers, base-36 digits. The number is converted to decimal and output as a
string.
+
.vitem &*${domain:*&<&'string'&>&*}*&
.cindex "domain" "extraction"
.cindex "expansion" "domain extraction"
when &%length%& is used as an operator.
-.vitem &*${local_part:*&<&'string'&>&*}*&
-.cindex "expansion" "local part extraction"
-.cindex "&%local_part%& expansion item"
-The string is interpreted as an RFC 2822 address and the local part is
-extracted from it. If the string does not parse successfully, the result is
-empty.
+.vitem &*${listcount:*&<&'string'&>&*}*&
+.cindex "expansion" "list item count"
+.cindex "list" "item count"
+.cindex "list" "count of items"
+.cindex "&%listcount%& expansion item"
+The string is interpreted as a list and the number of items is returned.
-.vitem &*${list:*&<&'name'&>&*}*&&~and&~&*${list_*&<&'type'&>&*name'&>&*}*&
+.vitem &*${listnamed:*&<&'name'&>&*}*&&~and&~&*${list_*&<&'type'&>&*name'&>&*}*&
.cindex "expansion" "named list"
-.cindex "&%list%& expansion item"
+.cindex "&%listnamed%& expansion item"
The name is interpreted as a named list and the content of the list is returned,
expanding any referenced lists, re-quoting as needed for colon-separation.
If the optional type if given it must be one of "a", "d", "h" or "l"
matching list is returned.
-.vitem &*${nlist:*&<&'string'&>&*}*&
-.cindex "expansion" "list item count"
-.cindex "list" "item count"
-.cindex "list" "count of items"
-.cindex "&%nlist%& expansion item"
-The string is interpreted as a list and the number of items is returned.
+.vitem &*${local_part:*&<&'string'&>&*}*&
+.cindex "expansion" "local part extraction"
+.cindex "&%local_part%& expansion item"
+The string is interpreted as an RFC 2822 address and the local part is
+extracted from it. If the string does not parse successfully, the result is
+empty.
.vitem &*${mask:*&<&'IP&~address'&>&*/*&<&'bit&~count'&>&*}*&
PP/08 Handle smtp transport tls_sni option forced-fail for OpenSSL.
-JH/03 Add expansion operators ${list:name} and ${nlist:string}
+JH/03 Add expansion operators ${listnamed:name} and ${listcount:string}
Exim version 4.80
Not yet supported: IGNOREQUOTA, SIZE, PIPELINING, AUTH.
- 8. New expansion operators ${list:name} to get the content of a named list
- and ${nlist:string} to count the items in a list.
+ 8. New expansion operators ${listnamed:name} to get the content of a named list
+ and ${listcount:string} to count the items in a list.
Version 4.80
------------
US"l",
US"lc",
US"length",
- US"list",
+ US"listcount",
+ US"listnamed",
US"mask",
US"md5",
US"nh",
US"nhash",
- US"nlist",
US"quote",
US"randint",
US"rfc2047",
EOP_L,
EOP_LC,
EOP_LENGTH,
- EOP_LIST,
+ EOP_LISTCOUNT,
+ EOP_LISTNAMED,
EOP_MASK,
EOP_MD5,
EOP_NH,
EOP_NHASH,
- EOP_NLIST,
EOP_QUOTE,
EOP_RANDINT,
EOP_RFC2047,
continue;
}
+ /* count the number of list elements */
+
+ case EOP_LISTCOUNT:
+ {
+ int cnt = 0;
+ int sep = 0;
+ uschar * cp;
+ uschar buffer[256];
+
+ while (string_nextinlist(&sub, &sep, buffer, sizeof(buffer)) != NULL) cnt++;
+ cp = string_sprintf("%d", cnt);
+ yield = string_cat(yield, &size, &ptr, cp, Ustrlen(cp));
+ continue;
+ }
+
/* expand a named list given the name */
- /* handles nested named lists but will confuse the separators in the result */
+ /* handles nested named lists; requotes as colon-sep list */
- case EOP_LIST:
+ case EOP_LISTNAMED:
{
tree_node *t = NULL;
uschar * list;
if (*item == '+') /* list item is itself a named list */
{
- uschar * sub = string_sprintf("${list%s:%s}", suffix, item);
+ uschar * sub = string_sprintf("${listnamed%s:%s}", suffix, item);
item = expand_string_internal(sub, FALSE, NULL, FALSE, TRUE);
}
else if (sep != ':') /* item from non-colon-sep list, re-quote for colon list-separator */
continue;
}
- /* count the number of list elements */
-
- case EOP_NLIST:
- {
- int cnt = 0;
- int sep = 0;
- uschar * cp;
- uschar buffer[256];
-
- while (string_nextinlist(&sub, &sep, buffer, sizeof(buffer)) != NULL) cnt++;
- cp = string_sprintf("%d", cnt);
- yield = string_cat(yield, &size, &ptr, cp, Ustrlen(cp));
- continue;
- }
-
/* mask applies a mask to an IP address; for example the result of
${mask:131.111.10.206/28} is 131.111.10.192/28. */
reduce: ${reduce {<, 1,2,3}{0}{${eval:$value+$item}}}
reduce: ${reduce {3:0:9:4:6}{0}{${if >{$item}{$value}{$item}{$value}}}}
-list: ${list:dlist}
-list: ${list:+dlist}
-list: ${list:hlist}
-list: ${list:elist}
-list: ${list:flist}
-list: ${list:nolist}
-list: ${list_d:dlist}
-list: ${list_d:hlist}
-list: ${list_z:dlist}
-
-nlist: ${nlist:a:b:c}
-nlist: ${nlist:}
-nlist: ${nlist:<;a;b;c}
-nlist: ${nlist:${list:dlist}}
+listnamed: ${listnamed:dlist}
+listnamed: ${listnamed:+dlist}
+listnamed: ${listnamed:hlist}
+listnamed: ${listnamed:elist}
+listnamed: ${listnamed:flist}
+listnamed: ${listnamed:nolist}
+listnamed: ${listnamed_d:dlist}
+listnamed: ${listnamed_d:hlist}
+listnamed: ${listnamed_z:dlist}
+
+listcount: ${listcount:a:b:c}
+listcount: ${listcount:}
+listcount: ${listcount:<;a;b;c}
+listcount: ${listcount:${listnamed:dlist}}
# Tests with iscntrl() and illegal separators
> reduce: 6
> reduce: 9
>
-> list: *.aa.bb : ^\Nxxx(.*)
-> list: *.aa.bb : ^\Nxxx(.*)
-> list: V4NET.11.12.13 : iplsearch;TESTSUITE/aux-fixed/0002.iplsearch
-> list: *.aa.bb : ^\Nxxx(.*) : ;;
-> list: a : b;c : *.aa.bb : ^\Nxxx(.*) : ;; : 2001::630::212::8::204::::b664
+> listnamed: *.aa.bb : ^\Nxxx(.*)
+> listnamed: *.aa.bb : ^\Nxxx(.*)
+> listnamed: V4NET.11.12.13 : iplsearch;TESTSUITE/aux-fixed/0002.iplsearch
+> listnamed: *.aa.bb : ^\Nxxx(.*) : ;;
+> listnamed: a : b;c : *.aa.bb : ^\Nxxx(.*) : ;; : 2001::630::212::8::204::::b664
> Failed: "nolist" is not a named list
-> list: *.aa.bb : ^\Nxxx(.*)
+> listnamed: *.aa.bb : ^\Nxxx(.*)
> Failed: "hlist" is not a domain named list
> Failed: bad suffix on "list" operator
>
-> nlist: 3
-> nlist: 0
-> nlist: 3
-> nlist: 2
+> listcount: 3
+> listcount: 0
+> listcount: 3
+> listcount: 2
>
> # Tests with iscntrl() and illegal separators
>