/*
- * Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
#include <string.h>
#include <stdarg.h>
#include <assert.h>
-#include <stdint.h>
#include <jansson.h>
#include "jansson_private.h"
int line, column;
union {
char *string;
- int integer;
+ json_int_t integer;
double real;
} value;
} lex_t;
/*** lexical analyzer ***/
-void stream_init(stream_t *stream, get_func get, eof_func eof, void *data)
+static void
+stream_init(stream_t *stream, get_func get, eof_func eof, void *data)
{
stream->get = get;
stream->eof = eof;
free(lex->value.string);
}
+#if JSON_INTEGER_IS_LONG_LONG
+#define json_strtoint strtoll
+#else
+#define json_strtoint strtol
+#endif
+
static int lex_scan_number(lex_t *lex, char c, json_error_t *error)
{
const char *saved_text;
}
if(c != '.' && c != 'E' && c != 'e') {
- long value;
+ json_int_t value;
lex_unget_unsave(lex, c);
saved_text = strbuffer_value(&lex->saved_text);
- value = strtol(saved_text, &end, 10);
- assert(end == saved_text + lex->saved_text.length);
- if((value == LONG_MAX && errno == ERANGE) || value > INT_MAX) {
- error_set(error, lex, "too big integer");
- goto out;
- }
- else if((value == LONG_MIN && errno == ERANGE) || value < INT_MIN) {
- error_set(error, lex, "too big negative integer");
+ 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 = (int)value;
+ lex->value.integer = value;
return 0;
}
value = strtod(saved_text, &end);
assert(end == saved_text + lex->saved_text.length);
- if(value == 0 && errno == ERANGE) {
- error_set(error, lex, "real number underflow");
- goto out;
- }
-
- /* Cannot test for +/-HUGE_VAL because the HUGE_VAL constant is
- only defined in C99 mode. So let's trust in sole errno. */
- else if(errno == ERANGE) {
+ if(errno == ERANGE && value != 0) {
error_set(error, lex, "real number overflow");
goto out;
}
return json;
}
-json_t *parse_json(lex_t *lex, json_error_t *error)
+static json_t *parse_json(lex_t *lex, json_error_t *error)
{
error_init(error);
return (stream->data[stream->pos] == '\0');
}
-json_t *json_loads(const char *string, json_error_t *error)
+json_t *json_loads(const char *string, size_t flags, json_error_t *error)
{
lex_t lex;
json_t *result;
+ (void)flags; /* unused */
- string_data_t stream_data = {
- .data = string,
- .pos = 0
- };
+ string_data_t stream_data = {string, 0};
if(lex_init(&lex, string_get, string_eof, (void *)&stream_data))
return NULL;
return result;
}
-json_t *json_loadf(FILE *input, json_error_t *error)
+json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
{
lex_t lex;
json_t *result;
+ (void)flags; /* unused */
if(lex_init(&lex, (get_func)fgetc, (eof_func)feof, input))
return NULL;
return result;
}
-json_t *json_load_file(const char *path, json_error_t *error)
+json_t *json_load_file(const char *path, size_t flags, json_error_t *error)
{
json_t *result;
FILE *fp;
return NULL;
}
- result = json_loadf(fp, error);
+ result = json_loadf(fp, flags, error);
fclose(fp);
return result;