On 08.07.2018 16:23, Yann Ylavic wrote:
>> +
>> + if (treat_as_float) {
>> + retval->type = APR_JSON_DOUBLE;
>> + retval->value.dnumber = strtod(self->p, NULL);
>> + }
>> + else {
>> + retval->type = APR_JSON_LONG;
>> + retval->value.lnumber = strtol(self->p, NULL, 10);
>> + }
> Can't we simply try strtol() and then strtod() if the former failed?
Not unless there's extra checking. strtol() will happily convert "3.14"
to 3 and only testing the end pointer (which is ignored here) can tell
you if the whole string was converted.
Something like this (untested, pseudocode only):
char *endptr;
const long lnumber = strtol(self->p, &endptr, 10);
if (*endptr == '\0') {
retval->type = APR_JSON_LONG;
retval->value.lnumber = lnumber;
}
else {
const double dnumber = strtod(self->p, &endptr);
if (*endptr == '\0') {
retval->type = APR_JSON_DOUBLE;
retval->value.dnumber = dnumber;
}
else {
oops;
}
}
One could check if the *endptr returned from strtol() pointed at a
decimal separator before invoking strtod(), but that would require
querying the locale; it's probably better just to call strtod(). Also,
the strings would have to be at least right-trimmed for whitespace for
the (*endptr == '\0') test to be valid.
-- Brane