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