Index: trunk/extensions/AbuseFilter/parser_native/filter_evaluator.cpp |
— | — | @@ -31,7 +31,7 @@ |
32 | 32 | filter_evaluator::evaluate(std::string const &filter) const |
33 | 33 | { |
34 | 34 | try { |
35 | | - return (bool) e.evaluate(filter); |
| 35 | + return e.evaluate(filter).toBool(); |
36 | 36 | } catch (std::exception &e) { |
37 | 37 | std::cerr << "can't evaluate filter: " << e.what() << '\n'; |
38 | 38 | return false; |
Index: trunk/extensions/AbuseFilter/parser_native/aftypes.cpp |
— | — | @@ -22,59 +22,30 @@ |
23 | 23 | |
24 | 24 | namespace afp { |
25 | 25 | |
26 | | -datum::datum(std::string const &var) { |
27 | | - _init_from_string(var); |
| 26 | +datum::datum() { |
28 | 27 | } |
29 | 28 | |
30 | | -datum::datum(char const *var) |
| 29 | +datum::datum(datum const &other) |
| 30 | + : value_(other.value_) |
31 | 31 | { |
32 | | - _init_from_string(var); |
33 | 32 | } |
34 | 33 | |
35 | | -void |
36 | | -datum::_init_from_string(std::string const &var) |
| 34 | +datum |
| 35 | +datum::from_string_convert(std::string const &var) |
37 | 36 | { |
38 | 37 | // Try integer |
39 | 38 | try { |
40 | | - value_ = boost::lexical_cast<long int>(var); |
| 39 | + return from_int(boost::lexical_cast<long int>(var)); |
41 | 40 | } catch (boost::bad_lexical_cast &e) { |
42 | 41 | try { |
43 | | - value_ = boost::lexical_cast<double>(var); |
| 42 | + return from_double(boost::lexical_cast<double>(var)); |
44 | 43 | } catch (boost::bad_lexical_cast &e) { |
45 | 44 | /* If it's nothing else, it's a string */ |
46 | | - value_ = var; |
| 45 | + return from_string(var); |
47 | 46 | } |
48 | 47 | } |
49 | 48 | } |
50 | 49 | |
51 | | -datum::datum() { |
52 | | -} |
53 | | - |
54 | | -datum::datum(datum const &other) |
55 | | - : value_(other.value_) |
56 | | -{ |
57 | | -} |
58 | | - |
59 | | -datum::datum(long int var) |
60 | | - : value_(var) |
61 | | -{ |
62 | | -} |
63 | | - |
64 | | -datum::datum(double var) |
65 | | - : value_(var) |
66 | | -{ |
67 | | -} |
68 | | - |
69 | | -datum::datum(float var) |
70 | | - : value_(var) |
71 | | -{ |
72 | | -} |
73 | | - |
74 | | -datum::datum(bool var) |
75 | | - : value_((long int) var) |
76 | | -{ |
77 | | -} |
78 | | - |
79 | 50 | datum |
80 | 51 | datum::from_string(std::string const &v) |
81 | 52 | { |
— | — | @@ -99,6 +70,18 @@ |
100 | 71 | return d; |
101 | 72 | } |
102 | 73 | |
| 74 | +template<> datum datum::from<std::string>(std::string const &v) { |
| 75 | + return from_string(v); |
| 76 | +} |
| 77 | + |
| 78 | +template<> datum datum::from<long int>(long int const &v) { |
| 79 | + return from_int(v); |
| 80 | +} |
| 81 | + |
| 82 | +template<> datum datum::from<double>(double const &v) { |
| 83 | + return from_double(v); |
| 84 | +} |
| 85 | + |
103 | 86 | datum & datum::operator= (datum const &other) { |
104 | 87 | // Protect against self-assignment |
105 | 88 | if (this == &other) { |
— | — | @@ -259,9 +242,9 @@ |
260 | 243 | typedef typename from_string_converter<U>::type b_type; |
261 | 244 | |
262 | 245 | Operator<typename preferred_type<a_type, b_type>::type> op; |
263 | | - return op( |
| 246 | + return datum::from<typename preferred_type<a_type, b_type>::type>(op( |
264 | 247 | from_string_converter<T>::convert(a), |
265 | | - from_string_converter<U>::convert(b)); |
| 248 | + from_string_converter<U>::convert(b))); |
266 | 249 | } |
267 | 250 | |
268 | 251 | /* |
— | — | @@ -272,7 +255,8 @@ |
273 | 256 | typedef typename from_string_converter<T>::type a_type; |
274 | 257 | |
275 | 258 | Operator<typename preferred_type<a_type, a_type>::type> op; |
276 | | - return op(from_string_converter<T>::convert(a)); |
| 259 | + return datum::from<typename preferred_type<a_type, a_type>::type>( |
| 260 | + op(from_string_converter<T>::convert(a))); |
277 | 261 | } |
278 | 262 | |
279 | 263 | }; |
— | — | @@ -319,7 +303,7 @@ |
320 | 304 | * For comparisons that only work on integers - strings will be converted. |
321 | 305 | */ |
322 | 306 | template<template<typename V> class Operator> |
323 | | -struct arith_compare_visitor : boost::static_visitor<datum> { |
| 307 | +struct arith_compare_visitor : boost::static_visitor<bool> { |
324 | 308 | template<typename T, typename U> |
325 | 309 | bool operator() (T const &a, U const &b) const { |
326 | 310 | typedef typename from_string_converter<T>::type a_type; |
— | — | @@ -420,7 +404,7 @@ |
421 | 405 | |
422 | 406 | datum |
423 | 407 | pow(datum const &a, datum const &b) { |
424 | | - datum result = datum(std::pow(a.toFloat(),b.toFloat())); |
| 408 | + datum result = datum::from_double(std::pow(a.toFloat(),b.toFloat())); |
425 | 409 | |
426 | 410 | return result; |
427 | 411 | } |
— | — | @@ -475,7 +459,7 @@ |
476 | 460 | |
477 | 461 | bool |
478 | 462 | datum::operator! () const { |
479 | | - return !(int) *this; |
| 463 | + return !toBool(); |
480 | 464 | } |
481 | 465 | |
482 | 466 | } // namespace afp |
Index: trunk/extensions/AbuseFilter/parser_native/check.cpp |
— | — | @@ -19,7 +19,7 @@ |
20 | 20 | |
21 | 21 | for(int i=0;i<=100;i++) { |
22 | 22 | try { |
23 | | - f.add_variable("foo", afp::datum("love")); |
| 23 | + f.add_variable("foo", afp::datum::from_string("love")); |
24 | 24 | result = f.evaluate( "specialratio('foo;') == 0.25" ); |
25 | 25 | } catch (afp::exception* excep) { |
26 | 26 | printf( "Exception: %s\n", excep->what() ); |
Index: trunk/extensions/AbuseFilter/parser_native/affunctions.cpp |
— | — | @@ -83,7 +83,7 @@ |
84 | 84 | if (args.size() >= 2) |
85 | 85 | count--; |
86 | 86 | |
87 | | - return datum((long int)count); |
| 87 | + return datum::from_int((long int)count); |
88 | 88 | } |
89 | 89 | |
90 | 90 | datum |
— | — | @@ -108,7 +108,7 @@ |
109 | 109 | lastchr = chr; |
110 | 110 | } |
111 | 111 | |
112 | | - return datum(result); |
| 112 | + return datum::from_string(result); |
113 | 113 | } |
114 | 114 | |
115 | 115 | std::string |
— | — | @@ -144,13 +144,13 @@ |
145 | 145 | |
146 | 146 | double ratio = (float)specialcount / len; |
147 | 147 | |
148 | | - return datum(ratio); |
| 148 | + return datum::from_double(ratio); |
149 | 149 | } |
150 | 150 | |
151 | 151 | datum |
152 | 152 | af_rmspecials(std::vector<datum> const &args) { |
153 | 153 | check_args("rmspecials", args.size(), 1); |
154 | | - return datum(rmspecials(args[0].toString())); |
| 154 | + return datum::from_string(rmspecials(args[0].toString())); |
155 | 155 | } |
156 | 156 | |
157 | 157 | std::string |
— | — | @@ -169,25 +169,25 @@ |
170 | 170 | datum |
171 | 171 | af_ccnorm(std::vector<datum> const &args) { |
172 | 172 | check_args("ccnorm", args.size(), 1); |
173 | | - return datum( confusable_character_normalise( args[0].toString() ) ); |
| 173 | + return datum::from_string(confusable_character_normalise( args[0].toString())); |
174 | 174 | } |
175 | 175 | |
176 | 176 | datum |
177 | 177 | af_rmdoubles(std::vector<datum> const &args) { |
178 | 178 | check_args("ccnorm", args.size(), 1); |
179 | | - return datum(rmdoubles(args[0].toString())); |
| 179 | + return datum::from_string(rmdoubles(args[0].toString())); |
180 | 180 | } |
181 | 181 | |
182 | 182 | datum |
183 | 183 | af_length(std::vector<datum> const &args) { |
184 | 184 | check_args("ccnorm", args.size(), 1); |
185 | | - return datum( (long int)utf8::utf8_strlen(args[0].toString()) ); |
| 185 | + return datum::from_int((long int)utf8::utf8_strlen(args[0].toString())); |
186 | 186 | } |
187 | 187 | |
188 | 188 | datum |
189 | 189 | af_lcase(std::vector<datum> const &args) { |
190 | 190 | check_args("ccnorm", args.size(), 1); |
191 | | - return datum(utf8::utf8_tolower(args[0].toString())); |
| 191 | + return datum::from_string(utf8::utf8_tolower(args[0].toString())); |
192 | 192 | } |
193 | 193 | |
194 | 194 | std::string |
Index: trunk/extensions/AbuseFilter/parser_native/aftypes.h |
— | — | @@ -50,31 +50,22 @@ |
51 | 51 | class datum { |
52 | 52 | public: |
53 | 53 | datum(); |
54 | | - |
55 | | - /* |
56 | | - * Generic ctor tries to convert to an int. |
57 | | - */ |
58 | | - template<typename T> |
59 | | - datum(T const &v) |
60 | | - : value_(boost::lexical_cast<long int>(v)) |
61 | | - { |
62 | | - } |
63 | | - |
64 | | - // Specific type constructors |
65 | | - datum( std::string const &var ); |
66 | | - datum( char const *var ); |
67 | | - datum( long int var ); |
68 | | - datum( float var ); |
69 | | - datum( double var ); |
70 | | - datum( bool var ); |
71 | | - |
72 | | - datum( const datum & oldData ); |
| 54 | + datum(datum const &oldData); |
73 | 55 | |
74 | | - // Type forcing helpers |
| 56 | + // Type forcing construction functions |
75 | 57 | static datum from_string(std::string const &v); |
| 58 | + static datum from_string_convert(std::string const &v); |
76 | 59 | static datum from_int(long int v); |
77 | 60 | static datum from_double(double v); |
78 | 61 | |
| 62 | + /* |
| 63 | + * Template versions of the above. See below for the actual |
| 64 | + * implementations. |
| 65 | + */ |
| 66 | + template<typename T> static datum from(T const &v) { |
| 67 | + return from_int(0); |
| 68 | + } |
| 69 | + |
79 | 70 | // Assignment operator |
80 | 71 | datum &operator= (const datum & other); |
81 | 72 | |
— | — | @@ -98,22 +89,6 @@ |
99 | 90 | return (bool) toInt(); |
100 | 91 | } |
101 | 92 | |
102 | | - operator long int(void) const { |
103 | | - return toInt(); |
104 | | - } |
105 | | - |
106 | | - operator double(void) const { |
107 | | - return toFloat(); |
108 | | - } |
109 | | - |
110 | | - operator std::string(void) const { |
111 | | - return toString(); |
112 | | - } |
113 | | - |
114 | | - operator bool(void) const { |
115 | | - return (bool) toInt(); |
116 | | - } |
117 | | - |
118 | 93 | template<typename char_type, typename traits> |
119 | 94 | void |
120 | 95 | print_to(std::basic_ostream<char_type, traits> &s) const { |
— | — | @@ -141,6 +116,11 @@ |
142 | 117 | std::string what_; |
143 | 118 | }; |
144 | 119 | |
| 120 | + |
| 121 | +template<> datum datum::from<std::string>(std::string const &v); |
| 122 | +template<> datum datum::from<long int>(long int const &v); |
| 123 | +template<> datum datum::from<long int>(long int const &v); |
| 124 | + |
145 | 125 | datum operator+(datum const &a, datum const &b); |
146 | 126 | datum operator-(datum const &a, datum const &b); |
147 | 127 | datum operator*(datum const &a, datum const &b); |
Index: trunk/extensions/AbuseFilter/parser_native/request.cpp |
— | — | @@ -95,7 +95,7 @@ |
96 | 96 | return false; |
97 | 97 | value = *str; |
98 | 98 | |
99 | | - f.add_variable(key, datum(value)); |
| 99 | + f.add_variable(key, datum::from_string_convert(value)); |
100 | 100 | } |
101 | 101 | |
102 | 102 | return true; |
Index: trunk/extensions/AbuseFilter/parser_native/parser.cpp |
— | — | @@ -101,8 +101,8 @@ |
102 | 102 | datum |
103 | 103 | f_in(datum const &a, datum const &b) |
104 | 104 | { |
105 | | - std::string sa = a, sb = b; |
106 | | - return datum(std::search(sb.begin(), sb.end(), sa.begin(), sa.end()) != sb.end()); |
| 105 | + std::string sa = a.toString(), sb = b.toString(); |
| 106 | + return datum::from_int(std::search(sb.begin(), sb.end(), sa.begin(), sa.end()) != sb.end()); |
107 | 107 | } |
108 | 108 | |
109 | 109 | datum |
— | — | @@ -115,13 +115,13 @@ |
116 | 116 | f_regex(datum const &str, datum const &pattern) |
117 | 117 | { |
118 | 118 | boost::u32regex r = boost::make_u32regex(pattern.toString()); |
119 | | - return boost::u32regex_match(str.toString(), r); |
| 119 | + return datum::from_int(boost::u32regex_match(str.toString(), r)); |
120 | 120 | } |
121 | 121 | |
122 | 122 | datum |
123 | 123 | f_ternary(datum const &v, datum const &iftrue, datum const &iffalse) |
124 | 124 | { |
125 | | - return (bool)v ? iftrue : iffalse; |
| 125 | + return v.toInt() ? iftrue : iffalse; |
126 | 126 | } |
127 | 127 | |
128 | 128 | datum |
— | — | @@ -165,8 +165,32 @@ |
166 | 166 | return datum::from_string(s); |
167 | 167 | } |
168 | 168 | |
| 169 | +datum |
| 170 | +datum_and(datum const &a, datum const &b) |
| 171 | +{ |
| 172 | + return datum::from_int(a.toInt() && b.toInt()); |
169 | 173 | } |
170 | 174 | |
| 175 | +datum |
| 176 | +datum_or(datum const &a, datum const &b) |
| 177 | +{ |
| 178 | + return datum::from_int(a.toInt() || b.toInt()); |
| 179 | +} |
| 180 | + |
| 181 | +datum |
| 182 | +datum_xor(datum const &a, datum const &b) |
| 183 | +{ |
| 184 | + return datum::from_int((bool)a.toInt() ^ (bool)b.toInt()); |
| 185 | +} |
| 186 | + |
| 187 | +datum |
| 188 | +datum_negate(datum const &a) |
| 189 | +{ |
| 190 | + return datum::from_int(!(a.toBool())); |
| 191 | +} |
| 192 | + |
| 193 | +} |
| 194 | + |
171 | 195 | /* |
172 | 196 | * This is the closure types for functions. 'val' stores the final result of |
173 | 197 | * the function call; func and args store the function object and the parsed |
— | — | @@ -280,7 +304,7 @@ |
281 | 305 | * *(c_escape_ch_p[x]) into (*c_escape_ch_p)[x] |
282 | 306 | */ |
283 | 307 | | ( |
284 | | - ch_p('"')[value.val = ""] |
| 308 | + ch_p('"')[value.val = bind(&datum::from_string)("")] |
285 | 309 | >> *((c_escape_ch_p[value.val = bind(&f_append)(value.val, arg1)] - '"')) |
286 | 310 | >> ch_p('"')[value.val = bind(&f_strip_last)(value.val)] |
287 | 311 | ) |
— | — | @@ -295,7 +319,7 @@ |
296 | 320 | */ |
297 | 321 | variable = |
298 | 322 | self.variables[variable.val = arg1] |
299 | | - | (+ (upper_p | '_') )[variable.val = ""] |
| 323 | + | (+ (upper_p | '_') )[variable.val = bind(&datum::from_string)("")] |
300 | 324 | ; |
301 | 325 | |
302 | 326 | /* |
— | — | @@ -317,7 +341,7 @@ |
318 | 342 | */ |
319 | 343 | basic = |
320 | 344 | ( '(' >> tern_expr[basic.val = arg1] >> ')' ) |
321 | | - | ch_p('!') >> tern_expr[basic.val = !arg1] |
| 345 | + | ch_p('!') >> tern_expr[basic.val = bind(&datum_negate)(arg1)] |
322 | 346 | | ch_p('+') >> tern_expr[basic.val = arg1] |
323 | 347 | | ch_p('-') >> tern_expr[basic.val = -arg1] |
324 | 348 | | value[basic.val = arg1] |
— | — | @@ -381,10 +405,10 @@ |
382 | 406 | ord_expr = |
383 | 407 | plus_expr[ord_expr.val = arg1] |
384 | 408 | >> *( |
385 | | - "<" >> plus_expr[ord_expr.val = ord_expr.val < arg1] |
386 | | - | ">" >> plus_expr[ord_expr.val = ord_expr.val > arg1] |
387 | | - | "<=" >> plus_expr[ord_expr.val = ord_expr.val <= arg1] |
388 | | - | ">=" >> plus_expr[ord_expr.val = ord_expr.val >= arg1] |
| 409 | + "<" >> plus_expr[ord_expr.val = bind(&datum::from_int)(ord_expr.val < arg1)] |
| 410 | + | "<=" >> plus_expr[ord_expr.val = bind(&datum::from_int)(ord_expr.val <= arg1)] |
| 411 | + | ">" >> plus_expr[ord_expr.val = bind(&datum::from_int)(ord_expr.val > arg1)] |
| 412 | + | ">=" >> plus_expr[ord_expr.val = bind(&datum::from_int)(ord_expr.val >= arg1)] |
389 | 413 | ) |
390 | 414 | ; |
391 | 415 | |
— | — | @@ -394,14 +418,14 @@ |
395 | 419 | eq_expr = |
396 | 420 | ord_expr[eq_expr.val = arg1] |
397 | 421 | >> *( |
398 | | - "=" >> eq_expr[eq_expr.val = eq_expr.val == arg1] |
399 | | - | "==" >> eq_expr[eq_expr.val = eq_expr.val == arg1] |
400 | | - | "!=" >> eq_expr[eq_expr.val = eq_expr.val != arg1] |
401 | | - | "/=" >> eq_expr[eq_expr.val = eq_expr.val != arg1] |
| 422 | + "=" >> eq_expr[eq_expr.val = bind(&datum::from_int)(eq_expr.val == arg1)] |
| 423 | + | "==" >> eq_expr[eq_expr.val = bind(&datum::from_int)(eq_expr.val == arg1)] |
| 424 | + | "!=" >> eq_expr[eq_expr.val = bind(&datum::from_int)(eq_expr.val != arg1)] |
| 425 | + | "/=" >> eq_expr[eq_expr.val = bind(&datum::from_int)(eq_expr.val != arg1)] |
402 | 426 | | "===" >> eq_expr[eq_expr.val = |
403 | | - bind(&datum::compare_with_type)(eq_expr.val, arg1)] |
| 427 | + bind(&datum::from_int)(bind(&datum::compare_with_type)(eq_expr.val, arg1))] |
404 | 428 | | "!==" >> eq_expr[eq_expr.val = |
405 | | - !bind(&datum::compare_with_type)(eq_expr.val, arg1)] |
| 429 | + bind(&datum::from_int)(!bind(&datum::compare_with_type)(eq_expr.val, arg1))] |
406 | 430 | ) |
407 | 431 | ; |
408 | 432 | |
— | — | @@ -411,11 +435,9 @@ |
412 | 436 | bool_expr = |
413 | 437 | eq_expr[bool_expr.val = arg1] |
414 | 438 | >> *( |
415 | | - '&' >> eq_expr[bool_expr.val = bool_expr.val && arg1] |
416 | | - | '|' >> eq_expr[bool_expr.val = bool_expr.val || arg1] |
417 | | - | '^' >> eq_expr[bool_expr.val = |
418 | | - ((bool_expr.val || arg1) |
419 | | - && !(bool_expr.val && arg1)) ] |
| 439 | + '&' >> eq_expr[bool_expr.val = bind(datum_and)(bool_expr.val, arg1)] |
| 440 | + | '|' >> eq_expr[bool_expr.val = bind(datum_or)(bool_expr.val, arg1)] |
| 441 | + | '^' >> eq_expr[bool_expr.val = bind(datum_xor)(bool_expr.val, arg1)] |
420 | 442 | ) |
421 | 443 | ; |
422 | 444 | |
— | — | @@ -458,8 +480,8 @@ |
459 | 481 | /* |
460 | 482 | * We provide a couple of standard variables everyone wants. |
461 | 483 | */ |
462 | | - add_variable("true", afp::datum(true)); |
463 | | - add_variable("false", afp::datum(false)); |
| 484 | + add_variable("true", afp::datum::from_int(true)); |
| 485 | + add_variable("false", afp::datum::from_int(false)); |
464 | 486 | |
465 | 487 | /* |
466 | 488 | * The cast functions. |
— | — | @@ -672,9 +694,9 @@ |
673 | 695 | } |
674 | 696 | |
675 | 697 | afp::expressor e; |
676 | | - e.add_variable("ONE", 1); |
677 | | - e.add_variable("TWO", 2); |
678 | | - e.add_variable("THREE", 3); |
| 698 | + e.add_variable("ONE", afp::datum::from_int(1)); |
| 699 | + e.add_variable("TWO", afp::datum::from_int(2)); |
| 700 | + e.add_variable("THREE", afp::datum::from_int(3)); |
679 | 701 | e.add_function("add", f_add); |
680 | 702 | e.add_function("norm", f_norm); |
681 | 703 | |