r38996 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r38995‎ | r38996 | r38997 >
Date:13:37, 9 August 2008
Author:river
Status:old
Tags:
Comment:
Unicode conversion, phase1: datum should be templated on char type.
added basic_datum<charT>, with typedefs datum and u32datum
Modified paths:
  • /trunk/extensions/AbuseFilter/parser_native/afstring.h (added) (history)
  • /trunk/extensions/AbuseFilter/parser_native/aftypes.cpp (modified) (history)
  • /trunk/extensions/AbuseFilter/parser_native/aftypes.h (modified) (history)
  • /trunk/extensions/AbuseFilter/parser_native/include (added) (history)
  • /trunk/extensions/AbuseFilter/parser_native/include/datum (added) (history)
  • /trunk/extensions/AbuseFilter/parser_native/include/datum/conversion.h (added) (history)
  • /trunk/extensions/AbuseFilter/parser_native/include/datum/create.h (added) (history)
  • /trunk/extensions/AbuseFilter/parser_native/include/datum/operators.h (added) (history)
  • /trunk/extensions/AbuseFilter/parser_native/include/datum/visitors.h (added) (history)
  • /trunk/extensions/AbuseFilter/parser_native/makefile (modified) (history)
  • /trunk/extensions/AbuseFilter/parser_native/parser.cpp (modified) (history)

Diff [purge]

Index: trunk/extensions/AbuseFilter/parser_native/include/datum/operators.h
@@ -0,0 +1,239 @@
 2+/*
 3+ * Copyright (c) 2008 Andrew Garrett.
 4+ * Copyright (c) 2008 River Tarnell <river@wikimedia.org>
 5+ * Derived from public domain code contributed by Victor Vasiliev.
 6+ *
 7+ * Permission is granted to anyone to use this software for any purpose,
 8+ * including commercial applications, and to alter it and redistribute it
 9+ * freely. This software is provided 'as-is', without any express or
 10+ * implied warranty.
 11+ */
 12+
 13+#ifndef DATUM_OPERATORS_H
 14+#define DATUM_OPERATORS_H
 15+
 16+#include "datum/visitors.h"
 17+
 18+namespace afp {
 19+
 20+namespace datum_impl {
 21+
 22+/*
 23+ * std::modulus doesn't work with double, so we provide our own.
 24+ */
 25+template<typename T>
 26+struct afpmodulus {
 27+ T operator() (T const &a, T const &b) const {
 28+ return a % b;
 29+ }
 30+};
 31+
 32+template<>
 33+struct afpmodulus<double> {
 34+ double operator() (double const &a, double const &b) const {
 35+ return std::fmod(a, b);
 36+ }
 37+};
 38+
 39+template<typename T>
 40+struct afppower {
 41+ T operator() (T const &a, T const &b) const {
 42+ return std::pow(a,b);
 43+ }
 44+};
 45+
 46+} // namespace datum_impl
 47+
 48+template<typename charT>
 49+basic_datum<charT> operator+(basic_datum<charT> const &a, basic_datum<charT> const &b);
 50+template<typename charT>
 51+basic_datum<charT> operator-(basic_datum<charT> const &a, basic_datum<charT> const &b);
 52+template<typename charT>
 53+basic_datum<charT> operator*(basic_datum<charT> const &a, basic_datum<charT> const &b);
 54+template<typename charT>
 55+basic_datum<charT> operator/(basic_datum<charT> const &a, basic_datum<charT> const &b);
 56+template<typename charT>
 57+basic_datum<charT> operator%(basic_datum<charT> const &a, basic_datum<charT> const &b);
 58+
 59+template<typename charT>
 60+bool operator==(basic_datum<charT> const &a, basic_datum<charT> const &b);
 61+template<typename charT>
 62+bool operator!=(basic_datum<charT> const &a, basic_datum<charT> const &b);
 63+template<typename charT>
 64+bool operator<(basic_datum<charT> const &a, basic_datum<charT> const &b);
 65+template<typename charT>
 66+bool operator>(basic_datum<charT> const &a, basic_datum<charT> const &b);
 67+template<typename charT>
 68+bool operator<=(basic_datum<charT> const &a, basic_datum<charT> const &b);
 69+template<typename charT>
 70+bool operator>=(basic_datum<charT> const &a, basic_datum<charT> const &b);
 71+
 72+template<typename charT>
 73+basic_datum<charT> pow(basic_datum<charT> const &a, basic_datum<charT> const &b);
 74+
 75+template<typename charT, typename char_type, typename traits>
 76+std::basic_ostream<char_type, traits> &
 77+operator<<(std::basic_ostream<char_type, traits> &s, basic_datum<charT> const &d) {
 78+ d.print_to(s);
 79+ return s;
 80+}
 81+
 82+template<typename charT>
 83+basic_datum<charT> &
 84+basic_datum<charT>::operator= (basic_datum<charT> const &other) {
 85+ value_ = other.value_;
 86+ return *this;
 87+}
 88+
 89+template<typename charT>
 90+basic_datum<charT> &
 91+basic_datum<charT>::operator+=(basic_datum<charT> const &other)
 92+{
 93+ /*
 94+ * If either argument is a string, convert both to string. After discussion
 95+ * on #mediawiki, this seems to be the least confusing option.
 96+ */
 97+ if (value_.which() == 0 || other.value_.which() == 0) {
 98+ value_ = toString() + other.toString();
 99+ return *this;
 100+ }
 101+
 102+ basic_datum<charT> result = boost::apply_visitor(datum_impl::arith_visitor<charT, std::plus>(), value_, other.value_);
 103+ *this = result;
 104+ return *this;
 105+}
 106+
 107+template<typename charT>
 108+basic_datum<charT> &
 109+basic_datum<charT>::operator-=(basic_datum<charT> const &other)
 110+{
 111+ basic_datum<charT> result = boost::apply_visitor(datum_impl::arith_visitor<charT, std::minus>(), value_, other.value_);
 112+ *this = result;
 113+ return *this;
 114+}
 115+
 116+template<typename charT>
 117+basic_datum<charT> &
 118+basic_datum<charT>::operator*=(basic_datum<charT> const &other)
 119+{
 120+ basic_datum<charT> result = boost::apply_visitor(datum_impl::arith_visitor<charT, std::multiplies>(), value_, other.value_);
 121+ *this = result;
 122+ return *this;
 123+}
 124+
 125+template<typename charT>
 126+basic_datum<charT>&
 127+basic_datum<charT>::operator/=(basic_datum<charT> const &other)
 128+{
 129+ basic_datum<charT> result = boost::apply_visitor(datum_impl::arith_visitor<charT, std::divides>(), value_, other.value_);
 130+ *this = result;
 131+ return *this;
 132+}
 133+
 134+template<typename charT>
 135+basic_datum<charT>&
 136+basic_datum<charT>::operator%=(basic_datum<charT> const &other)
 137+{
 138+ basic_datum<charT> result = boost::apply_visitor(
 139+ datum_impl::arith_visitor<charT, datum_impl::afpmodulus>(), value_, other.value_);
 140+ *this = result;
 141+ return *this;
 142+}
 143+
 144+template<typename charT>
 145+basic_datum<charT>
 146+basic_datum<charT>::operator+() const
 147+{
 148+ return *this;
 149+}
 150+
 151+template<typename charT>
 152+basic_datum<charT>
 153+basic_datum<charT>::operator-() const
 154+{
 155+ return boost::apply_visitor(datum_impl::arith_visitor<charT, std::negate>(), value_);
 156+}
 157+
 158+template<typename charT>
 159+basic_datum<charT>
 160+operator+(basic_datum<charT> const &a, basic_datum<charT> const &b) {
 161+ return basic_datum<charT>(a) += b;
 162+}
 163+
 164+template<typename charT>
 165+basic_datum<charT>
 166+operator-(basic_datum<charT> const &a, basic_datum<charT> const &b) {
 167+ return basic_datum<charT>(a) -= b;
 168+}
 169+
 170+template<typename charT>
 171+basic_datum<charT>
 172+operator*(basic_datum<charT> const &a, basic_datum<charT> const &b) {
 173+ return basic_datum<charT>(a) *= b;
 174+}
 175+
 176+template<typename charT>
 177+basic_datum<charT>
 178+operator/(basic_datum<charT> const &a, basic_datum<charT> const &b) {
 179+ return basic_datum<charT>(a) /= b;
 180+}
 181+
 182+template<typename charT>
 183+basic_datum<charT>
 184+operator%(basic_datum<charT> const &a, basic_datum<charT> const &b) {
 185+ return basic_datum<charT>(a) %= b;
 186+}
 187+
 188+template<typename charT>
 189+basic_datum<charT>
 190+pow(basic_datum<charT> const &a, basic_datum<charT> const &b) {
 191+ basic_datum<charT> result = basic_datum<charT>::from_double(std::pow(a.toFloat(),b.toFloat()));
 192+
 193+ return result;
 194+}
 195+
 196+template<typename charT>
 197+bool
 198+operator==(basic_datum<charT> const &a, basic_datum<charT> const &b) {
 199+ return a.compare(b);
 200+}
 201+
 202+template<typename charT>
 203+bool
 204+operator< (basic_datum<charT> const &a, basic_datum<charT> const &b) {
 205+ return a.less_than(b);
 206+}
 207+
 208+template<typename charT>
 209+bool
 210+operator<= (basic_datum<charT> const &a, basic_datum<charT> const &b) {
 211+ return a.less_than(b) || a == b;
 212+}
 213+
 214+template<typename charT>
 215+bool
 216+operator> (basic_datum<charT> const &a, basic_datum<charT> const &b) {
 217+ return !(a <= b);
 218+}
 219+
 220+template<typename charT>
 221+bool
 222+operator>= (basic_datum<charT> const &a, basic_datum<charT> const &b) {
 223+ return !(a < b);
 224+}
 225+
 226+template<typename charT>
 227+bool
 228+operator!= (basic_datum<charT> const &a, basic_datum<charT> const &b) {
 229+ return !(a == b);
 230+}
 231+
 232+template<typename charT>
 233+bool
 234+basic_datum<charT>::operator! () const {
 235+ return !toBool();
 236+}
 237+
 238+} // namespace afp
 239+
 240+#endif /* !DATUM_OPERATORS_H */
Index: trunk/extensions/AbuseFilter/parser_native/include/datum/visitors.h
@@ -0,0 +1,223 @@
 2+/*
 3+ * Copyright (c) 2008 Andrew Garrett.
 4+ * Copyright (c) 2008 River Tarnell <river@wikimedia.org>
 5+ * Derived from public domain code contributed by Victor Vasiliev.
 6+ *
 7+ * Permission is granted to anyone to use this software for any purpose,
 8+ * including commercial applications, and to alter it and redistribute it
 9+ * freely. This software is provided 'as-is', without any express or
 10+ * implied warranty.
 11+ */
 12+
 13+#ifndef DATUM_VISITORS_H
 14+#define DATUM_VISITORS_H
 15+
 16+#include "datum/create.h"
 17+
 18+namespace afp {
 19+namespace datum_impl {
 20+
 21+/* Given T and U, find the preferred type for maths (i.e. double, if present) */
 22+template<typename T, typename U>
 23+struct preferred_type {
 24+ typedef T type;
 25+};
 26+
 27+template<typename T>
 28+struct preferred_type<double, T> {
 29+ typedef double type;
 30+};
 31+
 32+template<typename T>
 33+struct preferred_type<T, double> {
 34+ typedef double type;
 35+};
 36+
 37+template<>
 38+struct preferred_type<double, double> {
 39+ typedef double type;
 40+};
 41+
 42+
 43+/*
 44+ * Convert a string to an integer value.
 45+ */
 46+template<typename charT, typename T>
 47+struct from_string_converter {
 48+ typedef T type;
 49+
 50+ static type convert(T const &v) {
 51+ return v;
 52+ }
 53+};
 54+
 55+template<typename charT>
 56+struct from_string_converter<charT, std::basic_string<charT> > {
 57+ typedef long int type;
 58+
 59+ template<typename T>
 60+ static type convert(T const &v) {
 61+ try {
 62+ return boost::lexical_cast<type>(v);
 63+ } catch (boost::bad_lexical_cast &e) {
 64+ return 0;
 65+ }
 66+ }
 67+};
 68+
 69+/*
 70+ * Conversions from datum to other types.
 71+ */
 72+template<typename charT>
 73+struct to_string_visitor : boost::static_visitor<std::basic_string<charT> > {
 74+ std::basic_string<charT> operator() (std::basic_string<charT> const &v) const {
 75+ return v;
 76+ }
 77+
 78+ template<typename T>
 79+ std::basic_string<charT> operator() (T const &v) const {
 80+ return boost::lexical_cast<std::basic_string<charT> >(v);
 81+ }
 82+};
 83+
 84+template<typename charT>
 85+struct to_int_visitor : boost::static_visitor<long int> {
 86+ long int operator() (std::basic_string<charT> const &v) const {
 87+ try {
 88+ return boost::lexical_cast<long int>(v);
 89+ } catch (boost::bad_lexical_cast &e) {
 90+ return 0;
 91+ }
 92+ }
 93+
 94+ long int operator() (double o) const {
 95+ return (long int) o;
 96+ }
 97+
 98+ template<typename T>
 99+ long int operator() (T const &v) const {
 100+ return v;
 101+ }
 102+};
 103+
 104+template<typename charT>
 105+struct to_double_visitor : boost::static_visitor<double> {
 106+ double operator() (std::basic_string<charT> const &v) const {
 107+ try {
 108+ return boost::lexical_cast<double>(v);
 109+ } catch (boost::bad_lexical_cast &e) {
 110+ return 0;
 111+ }
 112+ }
 113+
 114+ template<typename T>
 115+ double operator() (T const &v) const {
 116+ return v;
 117+ }
 118+};
 119+
 120+/*
 121+ * A visitor that performs an arithmetic operation on its arguments,
 122+ * after doing appropriate int->double promotion.
 123+ */
 124+template<typename charT, template<typename V> class Operator>
 125+struct arith_visitor : boost::static_visitor<basic_datum<charT> > {
 126+ /*
 127+ * Anything involving a double returns a double.
 128+ * Otherwise, int is returned.
 129+ */
 130+ template<typename T, typename U>
 131+ basic_datum<charT> operator() (T const &a, U const &b) const {
 132+ typedef typename from_string_converter<charT, T>::type a_type;
 133+ typedef typename from_string_converter<charT, U>::type b_type;
 134+ typedef typename preferred_type<a_type, b_type>::type preferred_type;
 135+
 136+ Operator<preferred_type> op;
 137+ return create_datum<charT, preferred_type>::create(op(
 138+ from_string_converter<charT, T>::convert(a),
 139+ from_string_converter<charT, U>::convert(b)));
 140+ }
 141+
 142+ /*
 143+ * Unary version.
 144+ */
 145+ template<typename T>
 146+ basic_datum<charT> operator() (T const &a) const {
 147+ typedef typename from_string_converter<charT, T>::type a_type;
 148+ typedef typename preferred_type<a_type, a_type>::type preferred_type;
 149+
 150+ Operator<preferred_type> op;
 151+ return create_datum<charT, preferred_type>::create(
 152+ op(from_string_converter<charT, T>::convert(a)));
 153+ }
 154+
 155+};
 156+
 157+/*
 158+ * Like arith_visitor, but for equality comparisons.
 159+ */
 160+template<
 161+ typename charT,
 162+ template<typename V> class Operator,
 163+ typename T,
 164+ typename U>
 165+struct compare_visitor_impl {
 166+ bool operator() (T const &a, U const &b) const {
 167+ typedef typename from_string_converter<charT, T>::type a_type;
 168+ typedef typename from_string_converter<charT, U>::type b_type;
 169+ typedef typename preferred_type<a_type, b_type>::type preferred_type;
 170+
 171+ Operator<preferred_type> op;
 172+ return op(
 173+ from_string_converter<charT, T>::convert(a),
 174+ from_string_converter<charT, U>::convert(b));
 175+ }
 176+};
 177+
 178+/*
 179+ * Specialise for string<>string comparisons
 180+ */
 181+template<typename charT, template<typename V> class Operator>
 182+struct compare_visitor_impl<
 183+ charT,
 184+ Operator,
 185+ std::basic_string<charT>,
 186+ std::basic_string<charT>
 187+ > : boost::static_visitor<bool> {
 188+
 189+ bool operator() (std::basic_string<charT> const &a, std::basic_string<charT> const &b) const {
 190+ Operator<std::basic_string<charT> > op;
 191+ return op(a, b);
 192+ }
 193+};
 194+
 195+template<typename charT, template<typename V> class Operator>
 196+struct compare_visitor : boost::static_visitor<bool> {
 197+ template<typename T, typename U>
 198+ bool operator() (T const &a, U const &b) const {
 199+ return compare_visitor_impl<charT, Operator, T, U>()(a, b);
 200+ }
 201+};
 202+
 203+/*
 204+ * For comparisons that only work on integers - strings will be converted.
 205+ */
 206+template<typename charT, template<typename V> class Operator>
 207+struct arith_compare_visitor : boost::static_visitor<bool> {
 208+ template<typename T, typename U>
 209+ bool operator() (T const &a, U const &b) const {
 210+ typedef typename from_string_converter<charT, T>::type a_type;
 211+ typedef typename from_string_converter<charT, U>::type b_type;
 212+ typedef typename preferred_type<a_type, b_type>::type preferred_type;
 213+
 214+ Operator<preferred_type> op;
 215+ return op(
 216+ from_string_converter<charT, T>::convert(a),
 217+ from_string_converter<charT, U>::convert(b));
 218+ }
 219+};
 220+
 221+} // namespace datum_impl
 222+} // namespace afp
 223+
 224+#endif /* !DATUM_VISITORS_H */
Index: trunk/extensions/AbuseFilter/parser_native/include/datum/create.h
@@ -0,0 +1,43 @@
 2+/*
 3+ * Copyright (c) 2008 Andrew Garrett.
 4+ * Copyright (c) 2008 River Tarnell <river@wikimedia.org>
 5+ * Derived from public domain code contributed by Victor Vasiliev.
 6+ *
 7+ * Permission is granted to anyone to use this software for any purpose,
 8+ * including commercial applications, and to alter it and redistribute it
 9+ * freely. This software is provided 'as-is', without any express or
 10+ * implied warranty.
 11+ */
 12+
 13+#ifndef DATUM_CREATE_H
 14+#define DATUM_CREATE_H
 15+
 16+namespace afp {
 17+
 18+template<typename charT, typename T>
 19+struct create_datum;
 20+
 21+template<typename charT>
 22+struct create_datum<charT, long int> {
 23+ static basic_datum<charT> create(long int v) {
 24+ return basic_datum<charT>::from_int(v);
 25+ }
 26+};
 27+
 28+template<typename charT>
 29+struct create_datum<charT, double> {
 30+ static basic_datum<charT> create(double v) {
 31+ return basic_datum<charT>::from_double(v);
 32+ }
 33+};
 34+
 35+template<typename charT>
 36+struct create_datum<charT, std::string> {
 37+ static basic_datum<charT> create(std::basic_string<charT> const &v) {
 38+ return basic_datum<charT>::from_string(v);
 39+ }
 40+};
 41+
 42+}
 43+
 44+#endif /* !DATUM_CREATE_H */
Index: trunk/extensions/AbuseFilter/parser_native/include/datum/conversion.h
@@ -0,0 +1,83 @@
 2+/*
 3+ * Copyright (c) 2008 Andrew Garrett.
 4+ * Copyright (c) 2008 River Tarnell <river@wikimedia.org>
 5+ * Derived from public domain code contributed by Victor Vasiliev.
 6+ *
 7+ * Permission is granted to anyone to use this software for any purpose,
 8+ * including commercial applications, and to alter it and redistribute it
 9+ * freely. This software is provided 'as-is', without any express or
 10+ * implied warranty.
 11+ */
 12+
 13+#ifndef DATUM_CONVERSION_H
 14+#define DATUM_CONVERSION_H
 15+
 16+#include "datum/visitors.h"
 17+
 18+namespace afp {
 19+
 20+template<typename charT>
 21+basic_datum<charT>
 22+basic_datum<charT>::from_string_convert(basic_datum<charT>::string_t const &var)
 23+{
 24+ // Try integer
 25+ try {
 26+ return from_int(boost::lexical_cast<long int>(var));
 27+ } catch (boost::bad_lexical_cast &e) {
 28+ try {
 29+ return from_double(boost::lexical_cast<double>(var));
 30+ } catch (boost::bad_lexical_cast &e) {
 31+ /* If it's nothing else, it's a string */
 32+ return from_string(var);
 33+ }
 34+ }
 35+}
 36+
 37+template<typename charT>
 38+basic_datum<charT>
 39+basic_datum<charT>::from_string(basic_datum<charT>::string_t const &v)
 40+{
 41+ basic_datum<charT> d;
 42+ d.value_ = v;
 43+ return d;
 44+}
 45+
 46+template<typename charT>
 47+basic_datum<charT>
 48+basic_datum<charT>::from_int(long int v)
 49+{
 50+ basic_datum<charT> d;
 51+ d.value_ = v;
 52+ return d;
 53+}
 54+
 55+template<typename charT>
 56+basic_datum<charT>
 57+basic_datum<charT>::from_double(double v)
 58+{
 59+ basic_datum<charT> d;
 60+ d.value_ = v;
 61+ return d;
 62+}
 63+
 64+template<typename charT>
 65+std::basic_string<charT>
 66+basic_datum<charT>::toString() const {
 67+ return boost::apply_visitor(datum_impl::to_string_visitor<charT>(), value_);
 68+}
 69+
 70+template<typename charT>
 71+long int
 72+basic_datum<charT>::toInt() const {
 73+ return boost::apply_visitor(datum_impl::to_int_visitor<charT>(), value_);
 74+}
 75+
 76+template<typename charT>
 77+double
 78+basic_datum<charT>::toFloat() const {
 79+ return boost::apply_visitor(datum_impl::to_double_visitor<charT>(), value_);
 80+}
 81+
 82+} // namespace afp
 83+
 84+#endif /* !DATUM_CONVERSION_H */
Index: trunk/extensions/AbuseFilter/parser_native/aftypes.cpp
@@ -22,432 +22,8 @@
2323
2424 namespace afp {
2525
26 -datum::datum() {
27 -}
2826
29 -datum::datum(datum const &other)
30 - : value_(other.value_)
31 -{
32 -}
33 -
34 -datum
35 -datum::from_string_convert(std::string const &var)
36 -{
37 - // Try integer
38 - try {
39 - return from_int(boost::lexical_cast<long int>(var));
40 - } catch (boost::bad_lexical_cast &e) {
41 - try {
42 - return from_double(boost::lexical_cast<double>(var));
43 - } catch (boost::bad_lexical_cast &e) {
44 - /* If it's nothing else, it's a string */
45 - return from_string(var);
46 - }
47 - }
48 -}
49 -
50 -datum
51 -datum::from_string(std::string const &v)
52 -{
53 - datum d;
54 - d.value_ = v;
55 - return d;
56 -}
57 -
58 -datum
59 -datum::from_int(long int v)
60 -{
61 - datum d;
62 - d.value_ = v;
63 - return d;
64 -}
65 -
66 -datum
67 -datum::from_double(double v)
68 -{
69 - datum d;
70 - d.value_ = v;
71 - return d;
72 -}
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 -
86 -datum & datum::operator= (datum const &other) {
87 - // Protect against self-assignment
88 - if (this == &other) {
89 - return *this;
90 - }
91 -
92 - value_ = other.value_;
93 - return *this;
94 -}
95 -
96 -/*
97 - * Convert a string to an integer value.
98 - */
99 -template<typename T>
100 -struct from_string_converter {
101 - typedef T type;
102 -
103 - static type convert(T const &v) {
104 - return v;
105 - }
106 -};
107 -
108 -template<>
109 -struct from_string_converter<std::string> {
110 - typedef long int type;
111 -
112 - template<typename T>
113 - static type convert(T const &v) {
114 - try {
115 - return boost::lexical_cast<type>(v);
116 - } catch (boost::bad_lexical_cast &e) {
117 - return 0;
118 - }
119 - }
120 -};
121 -
122 -/*
123 - * Conversions from datum to other types.
124 - */
125 -struct to_string_visitor : boost::static_visitor<std::string> {
126 - std::string operator() (std::string const &v) const {
127 - return v;
128 - }
129 -
130 - template<typename T>
131 - std::string operator() (T const &v) const {
132 - return boost::lexical_cast<std::string>(v);
133 - }
134 -};
135 -
136 -struct to_int_visitor : boost::static_visitor<long int> {
137 - long int operator() (std::string const &v) const {
138 - try {
139 - return boost::lexical_cast<long int>(v);
140 - } catch (boost::bad_lexical_cast &e) {
141 - return 0;
142 - }
143 - }
144 -
145 - long int operator() (double o) const {
146 - return (long int) o;
147 - }
148 -
149 - template<typename T>
150 - long int operator() (T const &v) const {
151 - return v;
152 - }
153 -};
154 -
155 -struct to_double_visitor : boost::static_visitor<double> {
156 - double operator() (std::string const &v) const {
157 - try {
158 - return boost::lexical_cast<double>(v);
159 - } catch (boost::bad_lexical_cast &e) {
160 - return 0;
161 - }
162 - }
163 -
164 - template<typename T>
165 - double operator() (T const &v) const {
166 - return v;
167 - }
168 -};
169 -
170 -std::string
171 -datum::toString() const {
172 - return boost::apply_visitor(to_string_visitor(), value_);
173 -}
174 -
175 -long int
176 -datum::toInt() const {
177 - return boost::apply_visitor(to_int_visitor(), value_);
178 -}
179 -
180 -double
181 -datum::toFloat() const {
182 - return boost::apply_visitor(to_double_visitor(), value_);
183 -}
184 -
185 -/* Given T and U, find the preferred type for maths (i.e. double, if present) */
186 -template<typename T, typename U>
187 -struct preferred_type {
188 - typedef T type;
189 -};
190 -
191 -template<typename T>
192 -struct preferred_type<double, T> {
193 - typedef double type;
194 -};
195 -
196 -template<typename T>
197 -struct preferred_type<T, double> {
198 - typedef double type;
199 -};
200 -
201 -template<>
202 -struct preferred_type<double, double> {
203 - typedef double type;
204 -};
205 -
206 -/*
207 - * std::modulus doesn't work with double, so we provide our own.
208 - */
209 -template<typename T>
210 -struct afpmodulus {
211 - T operator() (T const &a, T const &b) const {
212 - return a % b;
213 - }
214 -};
215 -
216 -template<>
217 -struct afpmodulus<double> {
218 - double operator() (double const &a, double const &b) const {
219 - return std::fmod(a, b);
220 - }
221 -};
222 -
223 -template<typename T>
224 -struct afppower {
225 - T operator() (T const &a, T const &b) const {
226 - return std::pow(a,b);
227 - }
228 -};
229 -
230 -/*
231 - * A visitor that performs an arithmetic operation on its arguments,
232 - * after doing appropriate int->double promotion.
233 - */
234 -template<template<typename V> class Operator>
235 -struct arith_visitor : boost::static_visitor<datum> {
236 - /*
237 - * Anything involving a double returns a double.
238 - * Otherwise, int is returned.
239 - */
240 - template<typename T, typename U>
241 - datum operator() (T const &a, U const &b) const {
242 - typedef typename from_string_converter<T>::type a_type;
243 - typedef typename from_string_converter<U>::type b_type;
244 -
245 - Operator<typename preferred_type<a_type, b_type>::type> op;
246 - return datum::from<typename preferred_type<a_type, b_type>::type>(op(
247 - from_string_converter<T>::convert(a),
248 - from_string_converter<U>::convert(b)));
249 - }
250 -
251 - /*
252 - * Unary version.
253 - */
254 - template<typename T>
255 - datum operator() (T const &a) const {
256 - typedef typename from_string_converter<T>::type a_type;
257 -
258 - Operator<typename preferred_type<a_type, a_type>::type> op;
259 - return datum::from<typename preferred_type<a_type, a_type>::type>(
260 - op(from_string_converter<T>::convert(a)));
261 - }
262 -
263 -};
264 -
265 -/*
266 - * Like arith_visitor, but for equality comparisons.
267 - */
268 -template<
269 - template<typename V> class Operator,
270 - typename T,
271 - typename U>
272 -struct compare_visitor_impl {
273 - bool operator() (T const &a, U const &b) const {
274 - typedef typename from_string_converter<T>::type a_type;
275 - typedef typename from_string_converter<U>::type b_type;
276 -
277 - Operator<typename preferred_type<a_type, b_type>::type> op;
278 - return op(
279 - from_string_converter<T>::convert(a),
280 - from_string_converter<U>::convert(b));
281 - }
282 -};
283 -
284 -/*
285 - * Specialise for string<>string comparisons
286 - */
287 -template<template<typename V> class Operator>
288 -struct compare_visitor_impl<Operator, std::string, std::string> : boost::static_visitor<bool> {
289 - bool operator() (std::string const &a, std::string const &b) const {
290 - Operator<std::string> op;
291 - return op(a, b);
292 - }
293 -};
294 -
295 -template<template<typename V> class Operator>
296 -struct compare_visitor : boost::static_visitor<bool> {
297 - template<typename T, typename U>
298 - bool operator() (T const &a, U const &b) const {
299 - return compare_visitor_impl<Operator, T, U>()(a, b);
300 - }
301 -};
302 -
303 -/*
304 - * For comparisons that only work on integers - strings will be converted.
305 - */
306 -template<template<typename V> class Operator>
307 -struct arith_compare_visitor : boost::static_visitor<bool> {
308 - template<typename T, typename U>
309 - bool operator() (T const &a, U const &b) const {
310 - typedef typename from_string_converter<T>::type a_type;
311 - typedef typename from_string_converter<U>::type b_type;
312 -
313 - Operator<typename preferred_type<a_type, b_type>::type> op;
314 - return op(
315 - from_string_converter<T>::convert(a),
316 - from_string_converter<U>::convert(b));
317 - }
318 -};
319 -
320 -datum &
321 -datum::operator+=(datum const &other)
322 -{
323 - /*
324 - * If either argument is a string, convert both to string. After discussion
325 - * on #mediawiki, this seems to be the least confusing option.
326 - */
327 - if (value_.which() == 0 || other.value_.which() == 0) {
328 - value_ = toString() + other.toString();
329 - return *this;
330 - }
331 -
332 - datum result = boost::apply_visitor(arith_visitor<std::plus>(), value_, other.value_);
333 - *this = result;
334 - return *this;
335 -}
336 -
337 -datum &
338 -datum::operator-=(datum const &other)
339 -{
340 - datum result = boost::apply_visitor(arith_visitor<std::minus>(), value_, other.value_);
341 - *this = result;
342 - return *this;
343 -}
344 -
345 -datum &
346 -datum::operator*=(datum const &other)
347 -{
348 - datum result = boost::apply_visitor(arith_visitor<std::multiplies>(), value_, other.value_);
349 - *this = result;
350 - return *this;
351 -}
352 -
353 -datum&
354 -datum::operator/=(datum const &other)
355 -{
356 - datum result = boost::apply_visitor(arith_visitor<std::divides>(), value_, other.value_);
357 - *this = result;
358 - return *this;
359 -}
360 -
361 -datum&
362 -datum::operator%=(datum const &other)
363 -{
364 - datum result = boost::apply_visitor(arith_visitor<afpmodulus>(), value_, other.value_);
365 - *this = result;
366 - return *this;
367 -}
368 -
369 -datum
370 -datum::operator+() const
371 -{
372 - return *this;
373 -}
374 -
375 -datum
376 -datum::operator-() const
377 -{
378 - return boost::apply_visitor(arith_visitor<std::negate>(), value_);
379 -}
380 -
381 -datum
382 -operator+(datum const &a, datum const &b) {
383 - return datum(a) += b;
384 -}
385 -
386 -datum
387 -operator-(datum const &a, datum const &b) {
388 - return datum(a) -= b;
389 -}
390 -
391 -datum
392 -operator*(datum const &a, datum const &b) {
393 - return datum(a) *= b;
394 -}
395 -
396 -datum
397 -operator/(datum const &a, datum const &b) {
398 - return datum(a) /= b;
399 -}
400 -
401 -datum
402 -operator%(datum const &a, datum const &b) {
403 - return datum(a) %= b;
404 -}
405 -
406 -datum
407 -pow(datum const &a, datum const &b) {
408 - datum result = datum::from_double(std::pow(a.toFloat(),b.toFloat()));
409 -
410 - return result;
411 -}
412 -
41327 bool
414 -operator==(datum const &a, datum const &b) {
415 - return a.compare(b);
416 -}
417 -
418 -bool
419 -datum::compare(datum const &other) const {
420 - return boost::apply_visitor(compare_visitor<std::equal_to>(), value_, other.value_);
421 -}
422 -
423 -bool
424 -datum::compare_with_type(datum const &other) const {
425 - if (value_.which() != other.value_.which())
426 - return false;
427 -
428 - return boost::apply_visitor(compare_visitor<std::equal_to>(), value_, other.value_);
429 -}
430 -
431 -bool
432 -datum::less_than(datum const &other) const {
433 - return boost::apply_visitor(arith_compare_visitor<std::less>(), value_, other.value_);
434 -}
435 -
436 -bool
437 -operator< (datum const &a, datum const &b) {
438 - return a.less_than(b);
439 -}
440 -
441 -bool
442 -operator<= (datum const &a, datum const &b) {
443 - return a.less_than(b) || a == b;
444 -}
445 -
446 -bool
447 -operator> (datum const &a, datum const &b) {
448 - return !(a <= b);
449 -}
450 -
451 -bool
45228 operator>= (datum const &a, datum const &b) {
45329 return !(a < b);
45430 }
Index: trunk/extensions/AbuseFilter/parser_native/aftypes.h
@@ -12,13 +12,21 @@
1313 #ifndef AFTYPES_H
1414 #define AFTYPES_H
1515
16 -#include <string>
17 -#include <vector>
18 -#include <iostream>
 16+#include <string>
 17+#include <vector>
 18+#include <iostream>
 19+#include <sstream>
 20+#include <ios>
 21+#include <iostream>
 22+#include <cassert>
 23+#include <algorithm>
 24+#include <cmath>
1925
20 -#include <boost/variant.hpp>
21 -#include <boost/lexical_cast.hpp>
 26+#include <boost/lexical_cast.hpp>
 27+#include <boost/variant.hpp>
2228
 29+#include <unicode/uchar.h>
 30+
2331 namespace afp {
2432
2533 /*
@@ -47,58 +55,53 @@
4856 * entirely stack-based, avoiding memory allocation overhead when manipulating
4957 * datum objects.
5058 */
51 -class datum {
52 -public:
53 - datum();
54 - datum(datum const &oldData);
 59+
 60+template<typename charT>
 61+struct basic_datum {
 62+ typedef std::basic_string<charT> string_t;
 63+
 64+ basic_datum();
 65+ basic_datum(basic_datum<charT> const &oldData);
5566
5667 // Type forcing construction functions
57 - static datum from_string(std::string const &v);
58 - static datum from_string_convert(std::string const &v);
59 - static datum from_int(long int v);
60 - static datum from_double(double v);
 68+ static basic_datum<charT> from_string(string_t const &v);
 69+ static basic_datum<charT> from_string_convert(std::basic_string<charT> const &v);
 70+ static basic_datum<charT> from_int(long int v);
 71+ static basic_datum<charT> from_double(double v);
6172
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 -
7073 // Assignment operator
71 - datum &operator= (const datum & other);
 74+ basic_datum<charT> &operator= (const basic_datum<charT> & other);
7275
73 - datum &operator+=(datum const &other);
74 - datum &operator-=(datum const &other);
75 - datum &operator*=(datum const &other);
76 - datum &operator/=(datum const &other);
77 - datum &operator%=(datum const &other);
 76+ basic_datum<charT> &operator+=(basic_datum<charT> const &other);
 77+ basic_datum<charT> &operator-=(basic_datum<charT> const &other);
 78+ basic_datum<charT> &operator*=(basic_datum<charT> const &other);
 79+ basic_datum<charT> &operator/=(basic_datum<charT> const &other);
 80+ basic_datum<charT> &operator%=(basic_datum<charT> const &other);
7881 bool operator!() const;
79 - datum operator+() const;
80 - datum operator-() const;
 82+ basic_datum<charT> operator+() const;
 83+ basic_datum<charT> operator-() const;
8184
82 - bool compare(datum const &other) const;
83 - bool compare_with_type(datum const &other) const;
84 - bool less_than(datum const &other) const;
 85+ bool compare(basic_datum<charT> const &other) const;
 86+ bool compare_with_type(basic_datum<charT> const &other) const;
 87+ bool less_than(basic_datum<charT> const &other) const;
8588
86 - std::string toString() const;
 89+ string_t toString() const;
8790 long int toInt() const;
8891 double toFloat() const;
8992 bool toBool() const {
9093 return (bool) toInt();
9194 }
9295
93 - template<typename char_type, typename traits>
 96+ template<typename traits>
9497 void
95 - print_to(std::basic_ostream<char_type, traits> &s) const {
 98+ print_to(std::basic_ostream<charT, traits> &s) const {
9699 s << value_;
97100 }
98101
99102 protected:
100 - void _init_from_string(std::string const &);
 103+ void _init_from_string(string_t const &);
101104
102 - typedef boost::variant<std::string, long int, double> valuetype;
 105+ typedef boost::variant<string_t, long int, double> valuetype;
103106 valuetype value_;
104107 };
105108
@@ -116,33 +119,48 @@
117120 std::string what_;
118121 };
119122
 123+}
120124
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);
 125+#include "datum/create.h"
 126+#include "datum/conversion.h"
 127+#include "datum/operators.h"
124128
125 -datum operator+(datum const &a, datum const &b);
126 -datum operator-(datum const &a, datum const &b);
127 -datum operator*(datum const &a, datum const &b);
128 -datum operator/(datum const &a, datum const &b);
129 -datum operator%(datum const &a, datum const &b);
 129+namespace afp {
130130
131 -bool operator==(datum const &a, datum const &b);
132 -bool operator!=(datum const &a, datum const &b);
133 -bool operator<(datum const &a, datum const &b);
134 -bool operator>(datum const &a, datum const &b);
135 -bool operator<=(datum const &a, datum const &b);
136 -bool operator>=(datum const &a, datum const &b);
 131+template<typename charT>
 132+basic_datum<charT>::basic_datum() {
 133+}
137134
138 -datum pow(datum const &a, datum const &b);
 135+template<typename charT>
 136+basic_datum<charT>::basic_datum(basic_datum<charT> const &other)
 137+ : value_(other.value_)
 138+{
 139+}
139140
140 -template<typename char_type, typename traits>
141 -std::basic_ostream<char_type, traits> &
142 -operator<<(std::basic_ostream<char_type, traits> &s, datum const &d) {
143 - d.print_to(s);
144 - return s;
 141+template<typename charT>
 142+bool
 143+basic_datum<charT>::compare(basic_datum<charT> const &other) const {
 144+ return boost::apply_visitor(datum_impl::compare_visitor<charT, std::equal_to>(), value_, other.value_);
145145 }
146146
 147+template<typename charT>
 148+bool
 149+basic_datum<charT>::compare_with_type(basic_datum<charT> const &other) const {
 150+ if (value_.which() != other.value_.which())
 151+ return false;
 152+
 153+ return boost::apply_visitor(datum_impl::compare_visitor<charT, std::equal_to>(), value_, other.value_);
 154+}
 155+
 156+template<typename charT>
 157+bool
 158+basic_datum<charT>::less_than(basic_datum<charT> const &other) const {
 159+ return boost::apply_visitor(datum_impl::arith_compare_visitor<charT, std::less>(), value_, other.value_);
 160+}
 161+
 162+typedef basic_datum<char> datum;
 163+typedef basic_datum<UChar> u32datum;
 164+
147165 } // namespace afp
148166
149167 #endif /* !AFTYPES_H */
Index: trunk/extensions/AbuseFilter/parser_native/afstring.h
@@ -0,0 +1,26 @@
 2+/*
 3+ * Copyright (c) 2008 Andrew Garrett.
 4+ * Copyright (c) 2008 River Tarnell <river@wikimedia.org>
 5+ * Derived from public domain code contributed by Victor Vasiliev.
 6+ *
 7+ * Permission is granted to anyone to use this software for any purpose,
 8+ * including commercial applications, and to alter it and redistribute it
 9+ * freely. This software is provided 'as-is', without any express or
 10+ * implied warranty.
 11+ */
 12+#ifndef AFSTRING_H
 13+#define AFSTRING_H
 14+
 15+#include <string>
 16+
 17+#include <unicode/uchar.h>
 18+
 19+typedef std::basic_string<UChar> u32string;
 20+typedef std::basic_istream<UChar> u32istream;
 21+typedef std::basic_ostream<UChar> u32ostream;
 22+typedef std::basic_iostream<UChar> u32iostream;
 23+typedef std::basic_istringstream<UChar> u32istringstream;
 24+typedef std::basic_ostringstream<UChar> u32ostringstream;
 25+typedef std::basic_stringstream<UChar> u32stringstream;
 26+
 27+#endif /* !AFSTRING_H */
Index: trunk/extensions/AbuseFilter/parser_native/makefile
@@ -9,7 +9,7 @@
1010
1111 include makefile.config
1212
13 -CPPFLAGS = $(EXTRA_CPPFLAGS)
 13+CPPFLAGS = -Iinclude $(EXTRA_CPPFLAGS)
1414 LDFLAGS = $(EXTRA_LDFLAGS)
1515
1616 LIBS = -lboost_regex$(BOOST_TAG) -licuuc -licui18n -licudata
@@ -18,7 +18,6 @@
1919
2020 af_expr_objs = \
2121 af_expr-affunctions.o \
22 - af_expr-aftypes.o \
2322 af_expr-parser.o \
2423 af_expr-filter_evaluator.o \
2524 af_expr-eval.o \
@@ -28,7 +27,6 @@
2928
3029 af_parser_objs = \
3130 af_parser-affunctions.o \
32 - af_parser-aftypes.o \
3331 af_parser-main.o \
3432 af_parser-parser.o \
3533 af_parser-request.o \
@@ -38,7 +36,6 @@
3937
4038 check_objs = \
4139 check-affunctions.o \
42 - check-aftypes.o \
4340 check-check.o \
4441 check-parser.o \
4542 check-utf8.o \
@@ -47,7 +44,6 @@
4845
4946 syntax_check_objs = \
5047 syntax_check-affunctions.o \
51 - syntax_check-aftypes.o \
5248 syntax_check-filter_evaluator.o \
5349 syntax_check-parser.o \
5450 syntax_check-utf8.o \
@@ -55,7 +51,6 @@
5652 syntax_check-syntax_check.o
5753
5854 expr_objs = \
59 - expr-aftypes.o \
6055 expr-parser.o
6156
6257 progs = check af_parser syntax_check af_expr expr
Index: trunk/extensions/AbuseFilter/parser_native/parser.cpp
@@ -370,7 +370,7 @@
371371 pow_expr =
372372 in_expr[pow_expr.val = arg1]
373373 >> !(
374 - "**" >> pow_expr[pow_expr.val = bind(&afp::pow)(pow_expr.val, arg1)]
 374+ "**" >> pow_expr[pow_expr.val = bind(&afp::pow<char>)(pow_expr.val, arg1)]
375375 )
376376 ;
377377

Status & tagging log