Пример #1
0
static json_t *parse_integer(stream_t *stream, size_t flags,
                             json_error_t *error)
{
    json_int_t value;
    char *endptr;
    ssize_t end;

    (void) flags;

    end = search(stream, 'e');
    if (end < 0) {
        error_set(error, stream, "unterminated integer");
        return NULL;
    }

    if (validate_number(stream, error))
        return NULL;

    errno = 0;
    value = json_strtoint(&stream->buffer[stream->pos], &endptr, 10);
    if (endptr != &stream->buffer[end]) {
        error_set(error, stream, "invalid integer");
        return NULL;
    }
    if(errno == ERANGE) {
        if(value < 0)
            error_set(error, stream, "too big negative integer");
        else
            error_set(error, stream, "too big integer");
        return NULL;
    }
    stream->pos = end + 1;

    return json_integer(value);
}
Пример #2
0
static int lex_scan_number(lex_t *lex, int c, json_error_t *error)
{
    const char *saved_text;
    char *end;
    double value;

    lex->token = TOKEN_INVALID;

    if(c == '-')
        c = lex_get_save(lex, error);

    if(c == '0') {
        c = lex_get_save(lex, error);
        if(l_isdigit(c)) {
            lex_unget_unsave(lex, c);
            goto out;
        }
    }
    else if(l_isdigit(c)) {
        c = lex_get_save(lex, error);
        while(l_isdigit(c))
            c = lex_get_save(lex, error);
    }
    else {
        lex_unget_unsave(lex, c);
        goto out;
    }

    if(c != '.' && c != 'E' && c != 'e') {
        json_int_t value;

        lex_unget_unsave(lex, c);

        saved_text = strbuffer_value(&lex->saved_text);

        errno = 0;
        value = json_strtoint(saved_text, &end, 10);
        if(errno == ERANGE) {
            if(value < 0)
                error_set(error, lex, "too big negative integer");
            else
                error_set(error, lex, "too big integer");
            goto out;
        }

        assert(end == saved_text + lex->saved_text.length);

        lex->token = TOKEN_INTEGER;
        lex->value.integer = value;
        return 0;
    }

    if(c == '.') {
        c = lex_get(lex, error);
        if(!l_isdigit(c)) {
            lex_unget(lex, c);
            goto out;
        }
        lex_save(lex, c);

        c = lex_get_save(lex, error);
        while(l_isdigit(c))
            c = lex_get_save(lex, error);
    }

    if(c == 'E' || c == 'e') {
        c = lex_get_save(lex, error);
        if(c == '+' || c == '-')
            c = lex_get_save(lex, error);

        if(!l_isdigit(c)) {
            lex_unget_unsave(lex, c);
            goto out;
        }

        c = lex_get_save(lex, error);
        while(l_isdigit(c))
            c = lex_get_save(lex, error);
    }

    lex_unget_unsave(lex, c);

    if(jsonp_strtod(&lex->saved_text, &value)) {
        error_set(error, lex, "real number overflow");
        goto out;
    }

    lex->token = TOKEN_REAL;
    lex->value.real = value;
    return 0;

out:
    return -1;
}