Index: trunk/extensions/AbuseFilter/parser_native/affunctions.cpp |
— | — | @@ -15,18 +15,51 @@ |
16 | 16 | #include <ios> |
17 | 17 | #include <iostream> |
18 | 18 | |
| 19 | +#include <unicode/uchar.h> |
| 20 | + |
| 21 | +#include <boost/format.hpp> |
| 22 | + |
19 | 23 | #include "utf8.h" |
20 | 24 | #include "equiv.h" |
21 | 25 | #include "affunctions.h" |
22 | 26 | |
23 | | -#include <unicode/uchar.h> |
| 27 | +namespace { |
24 | 28 | |
| 29 | +struct too_many_arguments_exception : afp::exception { |
| 30 | + too_many_arguments_exception(char const *what) |
| 31 | + : afp::exception(what) {} |
| 32 | +}; |
| 33 | + |
| 34 | +struct too_few_arguments_exception : afp::exception { |
| 35 | + too_few_arguments_exception(char const *what) |
| 36 | + : afp::exception(what) {} |
| 37 | +}; |
| 38 | + |
| 39 | +void |
| 40 | +check_args(std::string const &fname, int args, int min, int max = 0) |
| 41 | +{ |
| 42 | + if (max == 0) |
| 43 | + max = min; |
| 44 | + if (args < min) { |
| 45 | + std::string s = str(boost::format( |
| 46 | + "too few arguments for function %s (got %d, expected %d)") |
| 47 | + % fname % args % min); |
| 48 | + throw too_few_arguments_exception(s.c_str()); |
| 49 | + } else if (args > max) { |
| 50 | + std::string s = str(boost::format( |
| 51 | + "too many arguments for function %s (got %d, expected %d)") |
| 52 | + % fname % args % min); |
| 53 | + throw too_many_arguments_exception(s.c_str()); |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +} // anonymous namespace |
| 58 | + |
25 | 59 | namespace afp { |
26 | 60 | |
27 | 61 | datum |
28 | 62 | af_count(std::vector<datum> const &args) { |
29 | | - if (args.empty()) |
30 | | - throw exception( "Not enough arguments to count" ); |
| 63 | + check_args("count", args.size(), 1, 2); |
31 | 64 | |
32 | 65 | std::string needle, haystack; |
33 | 66 | |
— | — | @@ -55,8 +88,7 @@ |
56 | 89 | |
57 | 90 | datum |
58 | 91 | af_norm(std::vector<datum> const &args) { |
59 | | - if (args.empty()) |
60 | | - throw exception( "Not enough arguments to norm" ); |
| 92 | + check_args("norm", args.size(), 1); |
61 | 93 | |
62 | 94 | std::string orig = args[0].toString(); |
63 | 95 | |
— | — | @@ -97,8 +129,7 @@ |
98 | 130 | |
99 | 131 | datum |
100 | 132 | af_specialratio(std::vector<datum> const &args) { |
101 | | - if (args.empty()) |
102 | | - throw exception( "Not enough arguments to specialratio" ); |
| 133 | + check_args("specialratio", args.size(), 1); |
103 | 134 | |
104 | 135 | std::string orig = args[0].toString(); |
105 | 136 | int len = 0; |
— | — | @@ -118,9 +149,7 @@ |
119 | 150 | |
120 | 151 | datum |
121 | 152 | af_rmspecials(std::vector<datum> const &args) { |
122 | | - if (args.empty()) |
123 | | - throw exception( "Not enough arguments to rmspecials" ); |
124 | | - |
| 153 | + check_args("rmspecials", args.size(), 1); |
125 | 154 | return datum(rmspecials(args[0].toString())); |
126 | 155 | } |
127 | 156 | |
— | — | @@ -139,33 +168,25 @@ |
140 | 169 | |
141 | 170 | datum |
142 | 171 | af_ccnorm(std::vector<datum> const &args) { |
143 | | - if (args.empty()) |
144 | | - throw exception( "Not enough arguments to ccnorm" ); |
145 | | - |
| 172 | + check_args("ccnorm", args.size(), 1); |
146 | 173 | return datum( confusable_character_normalise( args[0].toString() ) ); |
147 | 174 | } |
148 | 175 | |
149 | 176 | datum |
150 | 177 | af_rmdoubles(std::vector<datum> const &args) { |
151 | | - if (args.empty()) |
152 | | - throw exception( "Not enough arguments to rmdoubles" ); |
153 | | - |
| 178 | + check_args("ccnorm", args.size(), 1); |
154 | 179 | return datum(rmdoubles(args[0].toString())); |
155 | 180 | } |
156 | 181 | |
157 | 182 | datum |
158 | 183 | af_length(std::vector<datum> const &args) { |
159 | | - if (args.empty()) |
160 | | - throw exception( "Not enough arguments to lcase" ); |
161 | | - |
| 184 | + check_args("ccnorm", args.size(), 1); |
162 | 185 | return datum( (long int)utf8::utf8_strlen(args[0].toString()) ); |
163 | 186 | } |
164 | 187 | |
165 | 188 | datum |
166 | 189 | af_lcase(std::vector<datum> const &args) { |
167 | | - if (args.empty()) |
168 | | - throw exception( "Not enough arguments to lcase" ); |
169 | | - |
| 190 | + check_args("ccnorm", args.size(), 1); |
170 | 191 | return datum(utf8::utf8_tolower(args[0].toString())); |
171 | 192 | } |
172 | 193 | |