On 9/7/2011 2:40 PM, Tom Hendrikx wrote:
The above snippet poses some other issue that I cannot easily solve: the ascii-numeric comparator only handles integer values.
All 0.xxxx header values are truncated to 0 by the comparator, just like the sieve script value "0.95". After comparision, this results in true for all cases.
I don't really see a way to interact with floats in sieve, other than using regular expressions. However this gets clumsy/hairy quite fast when you're matching a hypothetical header value>=0.73 in stead of>=0.99.
Any ideas?
Yes. This can be a problem. However, the usual application for this is matching against a spam header. If it is, you can use the spamtest extension instead. Then you can configure the gory details in the background (http://wiki2.dovecot.org/Pigeonhole/Sieve/Extensions/SpamtestVirustest).
Otherwise, things indeed tend to get hairy. I've puzzled a bit and came up with the following:
==== require "variables"; require "relational"; require "comparator-i;ascii-numeric"; require "regex";
# Extract integer and fractional part separately: set "val_int" "0"; set "val_frac" "0"; if header :regex "X-Header-Name" "([0-9]+)\\.([0-9]+)" { set "val_int" "${1}"; set "val_frac" "${2}"; }
if allof ( /* Compare the integer part */ string :comparator "i;ascii-numeric" :value "ge" "${val_int}" "5", /* Compare the fractional part */ string :value "ge" "${val_frac}" "34" ) { discard; }
As you can see, the integer and fractional parts of the fractional number are extracted separately using a :regex match. Then the comparison is performed. The integer part is compared using i;ascii-numeric. Quite counter-intuitively, the fractional part is compared using a normal string comparison. The earlier regex match made sure that the ${val_frac} variable only contains digits. The string comparison makes sure that the length of the fractional part does not matter (much) and that the comparison works as expected. A length difference will only have an effect when there are spurious trailing zeros and all the preceeding digits are equal, thereby causing the longer string to have higher value, which is not strictly correct.
The above certainly does not deserve an award for beauty, it does not
handle negative numbers (can be added), and it is not tested very well.
So, use this with caution. Unfortunately, there is no i;ascii-fractional
(or whatever) collation and afaik nothing like that is in the works at
the IETF.
Regards,
Stephan.