|
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