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

Reply via email to