# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_INT32_T
+AC_TYPE_LONG_LONG_INT
+case $ac_cv_type_long_long_int in
+ yes) json_have_long_long=1;;
+ *) json_have_long_long=0;;
+esac
+AC_SUBST([json_have_long_long])
+
AC_C_INLINE
case $ac_cv_c_inline in
yes) json_inline=inline;;
If a circular reference is created, the memory consumed by the values
cannot be freed by :cfunc:`json_decref()`. The reference counts never
-drops to zero because the values are keeping the circular reference to
-themselves. Moreover, trying to encode the values with any of the
-encoding functions will fail. The encoder detects circular references
-and returns an error status.
+drops to zero because the values are keeping the references to each
+other. Moreover, trying to encode the values with any of the encoding
+functions will fail. The encoder detects circular references and
+returns an error status.
True, False and Null
Number
======
-.. cfunction:: json_t *json_integer(long value)
+.. ctype:: json_int_t
+
+ This is the C type that is used to store JSON integer values. It
+ represents the widest integer type available on your system. In
+ practice it's just a typedef of ``long long`` if your compiler
+ supports it, otherwise ``long``.
+
+ Usually, you can safely use plain ``int`` in place of
+ ``json_int_t``, and the implicit C integer conversion handles the
+ rest. Only when you know that you need a full 64-bit range, you
+ should use ``json_int_t`` explicitly.
+
+``JSON_INTEGER_FORMAT``
+
+ This is a macro that expands to a :cfunc:`printf()` conversion
+ specifier that corresponds to :ctype:`json_int_t`, without the
+ leading ``%`` sign, i.e. either ``"lld"`` or ``"ld"``. This macro
+ is required because the actual type of :ctype:`json_int_t` can be
+ either ``long`` or ``long long``, and :cfunc:`printf()` reuiqres
+ different length modifiers for the two.
+
+ Example::
+
+ json_int_t x = 123123123;
+ printf("x is %" JSON_INTEGER_FORMAT "\n", x);
+
+
+.. cfunction:: json_t *json_integer(json_int_t value)
.. refcounting:: new
Returns a new JSON integer, or *NULL* on error.
-.. cfunction:: long json_integer_value(const json_t *integer)
+.. cfunction:: json_int_t json_integer_value(const json_t *integer)
Returns the associated value of *integer*, or 0 if *json* is not a
JSON integer.
-.. cfunction:: int json_integer_set(const json_t *integer, long value)
+.. cfunction:: int json_integer_set(const json_t *integer, json_int_t value)
Sets the associated value of *integer* to *value*. Returns 0 on
success and -1 if *integer* is not a JSON integer.
JSON makes no distinction between real and integer numbers; Jansson
does. Real numbers are mapped to the ``double`` type and integers to
-the ``long`` type.
+the ``json_int_t`` type, which is a typedef of ``long long`` or
+``long``, depending on whether ``long long`` is supported by your
+compiler or not.
A JSON number is considered to be a real number if its lexical
representation includes one of ``e``, ``E``, or ``.``; regardless if
-------------------------------
Real numbers whose absolute values are too small to be represented in
-a C double will be silently estimated with 0.0. Thus, depending on
+a C ``double`` will be silently estimated with 0.0. Thus, depending on
platform, JSON numbers very close to zero such as 1E-999 may result in
0.0.
Real numbers whose absolute values are too large to be represented in
-a C ``double`` type will result in an overflow error (a JSON decoding
+a C ``double`` will result in an overflow error (a JSON decoding
error). Thus, depending on platform, JSON numbers like 1E+999 or
-1E+999 may result in a parsing error.
Likewise, integer numbers whose absolute values are too large to be
-represented in the ``long`` type will result in an overflow error (a
-JSON decoding error). Thus, depending on platform, JSON numbers like
-1000000000000000 may result in parsing error.
+represented in the ``json_int_t`` type (see above) will result in an
+overflow error (a JSON decoding error). Thus, depending on platform,
+JSON numbers like 1000000000000000 may result in parsing error.
Parsing JSON real numbers may result in a loss of precision. As long
as overflow does not occur (i.e. a total loss of precision), the
-----
No support is provided in Jansson for any C numeric types other than
-``long`` and ``double``. This excludes things such as unsigned types,
-``long long``, ``long double``, etc. Obviously, shorter types like
-``short``, ``int`` and ``float`` are implicitly handled via the
-ordinary C type coercion rules (subject to overflow semantics). Also,
-no support or hooks are provided for any supplemental "bignum" type
-add-on packages.
+``json_int_t`` and ``double``. This excludes things such as unsigned
+types, ``long double``, etc. Obviously, shorter types like ``short``,
+``int``, ``long`` (if ``json_int_t`` is ``long long``) and ``float``
+are implicitly handled via the ordinary C type coercion rules (subject
+to overflow semantics). Also, no support or hooks are provided for any
+supplemental "bignum" type add-on packages.
char buffer[MAX_INTEGER_STR_LENGTH];
int size;
- size = snprintf(buffer, MAX_INTEGER_STR_LENGTH, "%li", json_integer_value(json));
+ size = snprintf(buffer, MAX_INTEGER_STR_LENGTH,
+ "%" JSON_INTEGER_FORMAT,
+ json_integer_value(json));
if(size >= MAX_INTEGER_STR_LENGTH)
return -1;
size_t refcount;
} json_t;
+#if JSON_INTEGER_IS_LONG_LONG
+#define JSON_INTEGER_FORMAT "lld"
+typedef long long json_int_t;
+#else
+#define JSON_INTEGER_FORMAT "ld"
+typedef long json_int_t;
+#endif /* JSON_INTEGER_IS_LONG_LONG */
+
#define json_typeof(json) ((json)->type)
#define json_is_object(json) (json && json_typeof(json) == JSON_OBJECT)
#define json_is_array(json) (json && json_typeof(json) == JSON_ARRAY)
json_t *json_array(void);
json_t *json_string(const char *value);
json_t *json_string_nocheck(const char *value);
-json_t *json_integer(long value);
+json_t *json_integer(json_int_t value);
json_t *json_real(double value);
json_t *json_true(void);
json_t *json_false(void);
}
const char *json_string_value(const json_t *string);
-long json_integer_value(const json_t *integer);
+json_int_t json_integer_value(const json_t *integer);
double json_real_value(const json_t *real);
double json_number_value(const json_t *json);
int json_string_set(json_t *string, const char *value);
int json_string_set_nocheck(json_t *string, const char *value);
-int json_integer_set(json_t *integer, long value);
+int json_integer_set(json_t *integer, json_int_t value);
int json_real_set(json_t *real, double value);
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
+ *
+ *
+ * This file specifies a part of the site-specific configuration for
+ * Jansson, namely those things that affect the public API in
+ * jansson.h.
+ *
+ * The configure script copies this file to jansson_config.h and
+ * replaces @var@ substitutions by values that fit your system. If you
+ * cannot run the configure script, you can copy the file and do the
+ * value substitution by hand.
+ *
+ * See below for explanations of each substitution variable.
*/
#ifndef JANSSON_CONFIG_H
#ifdef __cplusplus
#define JSON_INLINE inline
#else
+/* If your compiler supports the inline keyword, @json_inline@ is
+ replaced with `inline', otherwise empty. */
#define JSON_INLINE @json_inline@
#endif
+/* If your compiler supports the `long long` type,
+ @json_have_long_long@ is replaced with 1, otherwise with 0. */
+#if @json_have_long_long@
+#define JSON_INTEGER_IS_LONG_LONG 1
+#else
+#define JSON_INTEGER_IS_LONG 1
+#endif
+
#endif
typedef struct {
json_t json;
- long value;
+ json_int_t value;
} json_integer_t;
#define json_to_object(json_) container_of(json_, json_object_t, json)
int line, column;
union {
char *string;
- long integer;
+ json_int_t integer;
double real;
} value;
} lex_t;
free(lex->value.string);
}
+#ifdef 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) {
- error_set(error, lex, "too big integer");
- goto out;
- }
- else if(value == LONG_MIN && errno == ERANGE) {
- 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 = value;
return 0;
/*** integer ***/
-json_t *json_integer(long value)
+json_t *json_integer(json_int_t value)
{
json_integer_t *integer = malloc(sizeof(json_integer_t));
if(!integer)
return &integer->json;
}
-long json_integer_value(const json_t *json)
+json_int_t json_integer_value(const json_t *json)
{
if(!json_is_integer(json))
return 0;
return json_to_integer(json)->value;
}
-int json_integer_set(json_t *json, long value)
+int json_integer_set(json_t *json, json_int_t value)
{
if(!json_is_integer(json))
return -1;
1
-too big negative integer near '-123123123123123'
+too big negative integer
-[-123123123123123]
\ No newline at end of file
+[-123123123123123123123123123123]
\ No newline at end of file
1
-too big integer near '123123123123123'
+too big integer
-[123123123123123]
\ No newline at end of file
+[123123123123123123123123123123]
\ No newline at end of file
1
-too big negative integer near '-123123123123123'
+too big negative integer
-[-123123123123123]
+[-123123123123123123123123123123]
1
-too big integer near '123123123123123'
+too big integer
-[123123123123123]
+[123123123123123123123123123123]