|
7 | 7 | */
|
8 | 8 | #include "postgres_fe.h"
|
9 | 9 |
|
| 10 | +#include <math.h> |
| 11 | + |
10 | 12 | #include "common.h"
|
11 | 13 | #include "common/logging.h"
|
12 | 14 | #include "variables.h"
|
@@ -179,6 +181,74 @@ ParseVariableNum(const char *value, const char *name, int *result)
|
179 | 181 | }
|
180 | 182 | }
|
181 | 183 |
|
| 184 | +/* |
| 185 | + * Try to interpret "value" as a double value, and if successful store it in |
| 186 | + * *result. If unsuccessful, *result isn't clobbered. "name" is the variable |
| 187 | + * which is being assigned, the value of which is only used to produce a good |
| 188 | + * error message. Pass NULL as the name to suppress the error message. The |
| 189 | + * value must be within the range [min,max] in order to be considered valid. |
| 190 | + * |
| 191 | + * Returns true, with *result containing the interpreted value, if "value" is |
| 192 | + * syntactically valid, else false (with *result unchanged). |
| 193 | + */ |
| 194 | +bool |
| 195 | +ParseVariableDouble(const char *value, const char *name, double *result, double min, double max) |
| 196 | +{ |
| 197 | + char *end; |
| 198 | + double dblval; |
| 199 | + |
| 200 | + /* |
| 201 | + * Empty-string input has historically been treated differently by strtod |
| 202 | + * on various platforms, so handle that by specifically checking for it. |
| 203 | + */ |
| 204 | + if ((value == NULL) || (*value == '\0')) |
| 205 | + { |
| 206 | + if (name) |
| 207 | + pg_log_error("invalid input syntax for \"%s\"", name); |
| 208 | + return false; |
| 209 | + } |
| 210 | + |
| 211 | + errno = 0; |
| 212 | + dblval = strtod(value, &end); |
| 213 | + if (errno == 0 && *end == '\0' && end != value) |
| 214 | + { |
| 215 | + if (dblval < min) |
| 216 | + { |
| 217 | + if (name) |
| 218 | + pg_log_error("invalid value \"%s\" for \"%s\": must be greater than %.2f", |
| 219 | + value, name, min); |
| 220 | + return false; |
| 221 | + } |
| 222 | + else if (dblval > max) |
| 223 | + { |
| 224 | + if (name) |
| 225 | + pg_log_error("invalid value \"%s\" for \"%s\": must be less than %.2f", |
| 226 | + value, name, max); |
| 227 | + } |
| 228 | + *result = dblval; |
| 229 | + return true; |
| 230 | + } |
| 231 | + |
| 232 | + /* |
| 233 | + * Cater for platforms which treat values which aren't zero, but that are |
| 234 | + * too close to zero to have full precision, by checking for zero or real |
| 235 | + * out-of-range values. |
| 236 | + */ |
| 237 | + else if ((errno = ERANGE) && |
| 238 | + (dblval == 0.0 || dblval >= HUGE_VAL || dblval <= -HUGE_VAL)) |
| 239 | + { |
| 240 | + if (name) |
| 241 | + pg_log_error("\"%s\" is out of range for \"%s\"", value, name); |
| 242 | + return false; |
| 243 | + } |
| 244 | + else |
| 245 | + { |
| 246 | + if (name) |
| 247 | + pg_log_error("invalid value \"%s\" for \"%s\"", value, name); |
| 248 | + return false; |
| 249 | + } |
| 250 | +} |
| 251 | + |
182 | 252 | /*
|
183 | 253 | * Print values of all variables.
|
184 | 254 | */
|
|
0 commit comments