Merge branch '1.3'
authorPetri Lehtinen <petri@digip.org>
Sat, 14 Aug 2010 18:02:08 +0000 (21:02 +0300)
committerPetri Lehtinen <petri@digip.org>
Sat, 14 Aug 2010 18:02:08 +0000 (21:02 +0300)
Conflicts:
doc/apiref.rst
src/jansson_private.h

29 files changed:
.gitignore
configure.ac
doc/apiref.rst
doc/conf.py
doc/conformance.rst
doc/github_commits.c
doc/tutorial.rst
src/Makefile.am
src/dump.c
src/hashtable.c
src/hashtable.h
src/jansson.h [moved from src/jansson.h.in with 72% similarity]
src/jansson_config.h.in [new file with mode: 0644]
src/jansson_private.h
src/load.c
src/value.c
test/bin/json_process.c
test/suites/api/test_copy.c
test/suites/api/test_equal.c
test/suites/api/test_load.c
test/suites/api/test_simple.c
test/suites/invalid-strip/too-big-negative-integer/error
test/suites/invalid-strip/too-big-negative-integer/input
test/suites/invalid-strip/too-big-positive-integer/error
test/suites/invalid-strip/too-big-positive-integer/input
test/suites/invalid/too-big-negative-integer/error
test/suites/invalid/too-big-negative-integer/input
test/suites/invalid/too-big-positive-integer/error
test/suites/invalid/too-big-positive-integer/input

index db44e75..3b4bffe 100644 (file)
@@ -24,4 +24,4 @@ missing
 stamp-h1
 *.pyc
 *.pc
-/src/jansson.h
+/src/jansson_config.h
index a46fc27..cabc732 100644 (file)
@@ -1,5 +1,5 @@
 AC_PREREQ([2.60])
-AC_INIT([jansson], [1.3], [petri@digip.org])
+AC_INIT([jansson], [2.0pre], [petri@digip.org])
 
 AM_INIT_AUTOMAKE([1.10 foreign])
 
@@ -18,6 +18,13 @@ AM_CONDITIONAL([GCC], [test x$GCC = xyes])
 # 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;;
@@ -33,7 +40,7 @@ AC_CONFIG_FILES([
         Makefile
         doc/Makefile
         src/Makefile
-        src/jansson.h
+        src/jansson_config.h
         test/Makefile
         test/bin/Makefile
         test/suites/Makefile
index 2c6cf3b..c3a0554 100644 (file)
@@ -210,10 +210,10 @@ the user to avoid them.
 
 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
@@ -299,18 +299,57 @@ numbers, so for practical reasons Jansson also has distinct types for
 the two. They are called "integer" and "real", respectively. For more
 information, see :ref:`rfc-conformance`.
 
-.. cfunction:: json_t *json_integer(int 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 the full 64-bit range, you
+   should use ``json_int_t`` explicitly.
+
+``JSON_INTEGER_IS_LONG_LONG``
+
+   This is a preprocessor variable that holds the value 1 if
+   :ctype:`json_int_t` is ``long long``, and 0 if it's ``long``. It
+   can be used as follows::
+
+       #if JSON_INTEGER_IS_LONG_LONG
+       /* Code specific for long long */
+       #else
+       /* Code specific for long */
+       #endif
+
+``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:: int 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, int 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.
@@ -357,12 +396,12 @@ A JSON array is an ordered collection of other JSON values.
    Returns a new JSON array, or *NULL* on error. Initially, the array
    is empty.
 
-.. cfunction:: unsigned int json_array_size(const json_t *array)
+.. cfunction:: size_t json_array_size(const json_t *array)
 
    Returns the number of elements in *array*, or 0 if *array* is NULL
    or not a JSON array.
 
-.. cfunction:: json_t *json_array_get(const json_t *array, unsigned int index)
+.. cfunction:: json_t *json_array_get(const json_t *array, size_t index)
 
    .. refcounting:: borrow
 
@@ -372,14 +411,14 @@ A JSON array is an ordered collection of other JSON values.
    if *array* is *NULL*, or if *index* is out of range, *NULL* is
    returned.
 
-.. cfunction:: int json_array_set(json_t *array, unsigned int index, json_t *value)
+.. cfunction:: int json_array_set(json_t *array, size_t index, json_t *value)
 
    Replaces the element in *array* at position *index* with *value*.
    The valid range for *index* is from 0 to the return value of
    :cfunc:`json_array_size()` minus 1. Returns 0 on success and -1 on
    error.
 
-.. cfunction:: int json_array_set_new(json_t *array, unsigned int index, json_t *value)
+.. cfunction:: int json_array_set_new(json_t *array, size_t index, json_t *value)
 
    Like :cfunc:`json_array_set()` but steals the reference to *value*.
    This is useful when *value* is newly created and not used after
@@ -400,7 +439,7 @@ A JSON array is an ordered collection of other JSON values.
 
    .. versionadded:: 1.1
 
-.. cfunction:: int json_array_insert(json_t *array, unsigned int index, json_t *value)
+.. cfunction:: int json_array_insert(json_t *array, size_t index, json_t *value)
 
    Inserts *value* to *array* at position *index*, shifting the
    elements at *index* and after it one position towards the end of
@@ -408,7 +447,7 @@ A JSON array is an ordered collection of other JSON values.
 
    .. versionadded:: 1.1
 
-.. cfunction:: int json_array_insert_new(json_t *array, unsigned int index, json_t *value)
+.. cfunction:: int json_array_insert_new(json_t *array, size_t index, json_t *value)
 
    Like :cfunc:`json_array_insert()` but steals the reference to
    *value*. This is useful when *value* is newly created and not used
@@ -416,7 +455,7 @@ A JSON array is an ordered collection of other JSON values.
 
    .. versionadded:: 1.1
 
-.. cfunction:: int json_array_remove(json_t *array, unsigned int index)
+.. cfunction:: int json_array_remove(json_t *array, size_t index)
 
    Removes the element in *array* at position *index*, shifting the
    elements after *index* one position towards the start of the array.
@@ -452,7 +491,7 @@ Unicode string and the value is any JSON value.
    Returns a new JSON object, or *NULL* on error. Initially, the
    object is empty.
 
-.. cfunction:: unsigned int json_object_size(const json_t *object)
+.. cfunction:: size_t json_object_size(const json_t *object)
 
    Returns the number of elements in *object*, or 0 if *object* is not
    a JSON object.
@@ -603,7 +642,7 @@ can be ORed together to obtain *flags*.
 ``JSON_INDENT(n)``
    Pretty-print the result, using newlines between array and object
    items, and indenting with *n* spaces. The valid range for *n* is
-   between 0 and 255, other values result in an undefined output. If
+   between 0 and 32, other values result in an undefined output. If
    ``JSON_INDENT`` is not used or *n* is 0, no newlines are inserted
    between array and object items.
 
@@ -640,13 +679,13 @@ can be ORed together to obtain *flags*.
 The following functions perform the actual JSON encoding. The result
 is in UTF-8.
 
-.. cfunction:: char *json_dumps(const json_t *root, unsigned long flags)
+.. cfunction:: char *json_dumps(const json_t *root, size_t flags)
 
    Returns the JSON representation of *root* as a string, or *NULL* on
    error. *flags* is described above. The return value must be freed
    by the caller using :cfunc:`free()`.
 
-.. cfunction:: int json_dumpf(const json_t *root, FILE *output, unsigned long flags)
+.. cfunction:: int json_dumpf(const json_t *root, FILE *output, size_t flags)
 
    Write the JSON representation of *root* to the stream *output*.
    *flags* is described above. Returns 0 on success and -1 on error.
@@ -654,7 +693,7 @@ is in UTF-8.
    *output*. In this case, the output is undefined and most likely not
    valid JSON.
 
-.. cfunction:: int json_dump_file(const json_t *json, const char *path, unsigned long flags)
+.. cfunction:: int json_dump_file(const json_t *json, const char *path, size_t flags)
 
    Write the JSON representation of *root* to the file *path*. If
    *path* already exists, it is overwritten. *flags* is described
@@ -700,7 +739,7 @@ affect especially the behavior of the decoder.
           json_t *json;
           json_error_t error;
 
-          json = json_load_file("/path/to/file.json", &error);
+          json = json_load_file("/path/to/file.json", 0, &error);
           if(!json) {
               /* the error variable contains error information */
           }
@@ -716,32 +755,35 @@ affect especially the behavior of the decoder.
 
 The following functions perform the actual JSON decoding.
 
-.. cfunction:: json_t *json_loads(const char *input, json_error_t *error)
+.. cfunction:: json_t *json_loads(const char *input, size_t flags, json_error_t *error)
 
    .. refcounting:: new
 
    Decodes the JSON string *input* and returns the array or object it
    contains, or *NULL* on error, in which case *error* is filled with
    information about the error. See above for discussion on the
-   *error* parameter.
+   *error* parameter. *flags* is currently unused, and should be set
+   to 0.
 
-.. cfunction:: json_t *json_loadf(FILE *input, json_error_t *error)
+.. cfunction:: json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
 
    .. refcounting:: new
 
    Decodes the JSON text in stream *input* and returns the array or
    object it contains, or *NULL* on error, in which case *error* is
    filled with information about the error. See above for discussion
-   on the *error* parameter.
+   on the *error* parameter. *flags* is currently unused, and should
+   be set to 0.
 
-.. cfunction:: json_t *json_load_file(const char *path, json_error_t *error)
+.. cfunction:: json_t *json_load_file(const char *path, size_t flags, json_error_t *error)
 
    .. refcounting:: new
 
    Decodes the JSON text in file *path* and returns the array or
    object it contains, or *NULL* on error, in which case *error* is
    filled with information about the error. See above for discussion
-   on the *error* parameter.
+   on the *error* parameter. *flags* is currently unused, and should
+   be set to 0.
 
 
 Equality
index f0e8cc0..fd1f5ca 100644 (file)
@@ -50,9 +50,9 @@ copyright = u'2009, 2010 Petri Lehtinen'
 # built documents.
 #
 # The short X.Y version.
-version = '1.3'
+version = '2.0'
 # The full version, including alpha/beta/rc tags.
-release = '1.3'
+release = '2.0pre'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
index 3bfe51d..6359f22 100644 (file)
@@ -38,7 +38,9 @@ Real vs. Integer
 
 JSON makes no distinction between real and integer numbers; Jansson
 does. Real numbers are mapped to the ``double`` type and integers to
-the ``int`` 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
@@ -56,19 +58,19 @@ Overflow, Underflow & Precision
 -------------------------------
 
 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 ``int`` 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
@@ -96,9 +98,9 @@ Types
 -----
 
 No support is provided in Jansson for any C numeric types other than
-``int`` and ``double``. This excludes things such as unsigned types,
-``long``, ``long long``, ``long double``, etc. Obviously, shorter
-types like ``short`` 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.
index 8a362eb..707aac4 100644 (file)
@@ -96,7 +96,7 @@ static char *request(const char *url)
 
 int main(int argc, char *argv[])
 {
-    unsigned int i;
+    size_t i;
     char *text;
     char url[URL_SIZE];
 
@@ -117,7 +117,7 @@ int main(int argc, char *argv[])
     if(!text)
         return 1;
 
-    root = json_loads(text, &error);
+    root = json_loads(text, 0, &error);
     free(text);
 
     if(!root)
index aaeb554..eded745 100644 (file)
@@ -118,7 +118,7 @@ first newline in the commit message::
 The main function follows. In the beginning, we first declare a bunch
 of variables and check the command line parameters::
 
-    unsigned int i;
+    size_t i;
     char *text;
     char url[URL_SIZE];
 
@@ -152,7 +152,7 @@ function.
 Next we'll call :cfunc:`json_loads()` to decode the JSON text we got
 as a response::
 
-    root = json_loads(text, &error);
+    root = json_loads(text, 0, &error);
     free(text);
 
     if(!root)
index 52a2e57..907631d 100644 (file)
@@ -1,4 +1,4 @@
-include_HEADERS = jansson.h
+include_HEADERS = jansson.h jansson_config.h
 
 lib_LTLIBRARIES = libjansson.la
 libjansson_la_SOURCES = \
index dc27fbd..42eb256 100644 (file)
@@ -41,10 +41,10 @@ static int dump_to_file(const char *buffer, int size, void *data)
     return 0;
 }
 
-/* 256 spaces (the maximum indentation size) */
-static char whitespace[] = "                                                                                                                                                                                                                                                                ";
+/* 32 spaces (the maximum indentation size) */
+static char whitespace[] = "                                ";
 
-static int dump_indent(unsigned long flags, int depth, int space, dump_func dump, void *data)
+static int dump_indent(size_t flags, int depth, int space, dump_func dump, void *data)
 {
     if(JSON_INDENT(flags) > 0)
     {
@@ -165,7 +165,7 @@ static int object_key_compare_serials(const void *key1, const void *key2)
            (*(const object_key_t **)key2)->serial;
 }
 
-static int do_dump(const json_t *json, unsigned long flags, int depth,
+static int do_dump(const json_t *json, size_t flags, int depth,
                    dump_func dump, void *data)
 {
     int ascii = flags & JSON_ENSURE_ASCII ? 1 : 0;
@@ -185,7 +185,9 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
             char buffer[MAX_INTEGER_STR_LENGTH];
             int size;
 
-            size = snprintf(buffer, MAX_INTEGER_STR_LENGTH, "%d", 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;
 
@@ -307,8 +309,7 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
             if(flags & JSON_SORT_KEYS || flags & JSON_PRESERVE_ORDER)
             {
                 const object_key_t **keys;
-                unsigned int size;
-                unsigned int i;
+                size_t size, i;
                 int (*cmp_func)(const void *, const void *);
 
                 size = json_object_size(json);
@@ -415,7 +416,7 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
 }
 
 
-char *json_dumps(const json_t *json, unsigned long flags)
+char *json_dumps(const json_t *json, size_t flags)
 {
     strbuffer_t strbuff;
     char *result;
@@ -437,7 +438,7 @@ char *json_dumps(const json_t *json, unsigned long flags)
     return result;
 }
 
-int json_dumpf(const json_t *json, FILE *output, unsigned long flags)
+int json_dumpf(const json_t *json, FILE *output, size_t flags)
 {
     if(!json_is_array(json) && !json_is_object(json))
         return -1;
@@ -445,7 +446,7 @@ int json_dumpf(const json_t *json, FILE *output, unsigned long flags)
     return do_dump(json, flags, 0, dump_to_file, (void *)output);
 }
 
-int json_dump_file(const json_t *json, const char *path, unsigned long flags)
+int json_dump_file(const json_t *json, const char *path, size_t flags)
 {
     int result;
 
index a312047..dcba68a 100644 (file)
@@ -59,22 +59,22 @@ static void insert_to_bucket(hashtable_t *hashtable, bucket_t *bucket,
     }
 }
 
-static unsigned int primes[] = {
+static size_t primes[] = {
     5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
     49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469,
     12582917, 25165843, 50331653, 100663319, 201326611, 402653189,
     805306457, 1610612741
 };
-static const unsigned int num_primes = sizeof(primes) / sizeof(unsigned int);
+static const size_t num_primes = sizeof(primes) / sizeof(size_t);
 
-static inline unsigned int num_buckets(hashtable_t *hashtable)
+static inline size_t num_buckets(hashtable_t *hashtable)
 {
     return primes[hashtable->num_buckets];
 }
 
 
 static pair_t *hashtable_find_pair(hashtable_t *hashtable, bucket_t *bucket,
-                                   const void *key, unsigned int hash)
+                                   const void *key, size_t hash)
 {
     list_t *list;
     pair_t *pair;
@@ -100,11 +100,11 @@ static pair_t *hashtable_find_pair(hashtable_t *hashtable, bucket_t *bucket,
 
 /* returns 0 on success, -1 if key was not found */
 static int hashtable_do_del(hashtable_t *hashtable,
-                            const void *key, unsigned int hash)
+                            const void *key, size_t hash)
 {
     pair_t *pair;
     bucket_t *bucket;
-    unsigned int index;
+    size_t index;
 
     index = hash % num_buckets(hashtable);
     bucket = &hashtable->buckets[index];
@@ -156,7 +156,7 @@ static int hashtable_do_rehash(hashtable_t *hashtable)
 {
     list_t *list, *next;
     pair_t *pair;
-    unsigned int i, index, new_size;
+    size_t i, index, new_size;
 
     free(hashtable->buckets);
 
@@ -213,7 +213,7 @@ int hashtable_init(hashtable_t *hashtable,
                    key_hash_fn hash_key, key_cmp_fn cmp_keys,
                    free_fn free_key, free_fn free_value)
 {
-    unsigned int i;
+    size_t i;
 
     hashtable->size = 0;
     hashtable->num_buckets = 0;  /* index to primes[] */
@@ -247,7 +247,7 @@ int hashtable_set(hashtable_t *hashtable, void *key, void *value)
 {
     pair_t *pair;
     bucket_t *bucket;
-    unsigned int hash, index;
+    size_t hash, index;
 
     /* rehash if the load ratio exceeds 1 */
     if(hashtable->size >= num_buckets(hashtable))
@@ -288,7 +288,7 @@ int hashtable_set(hashtable_t *hashtable, void *key, void *value)
 void *hashtable_get(hashtable_t *hashtable, const void *key)
 {
     pair_t *pair;
-    unsigned int hash;
+    size_t hash;
     bucket_t *bucket;
 
     hash = hashtable->hash_key(key);
@@ -303,13 +303,13 @@ void *hashtable_get(hashtable_t *hashtable, const void *key)
 
 int hashtable_del(hashtable_t *hashtable, const void *key)
 {
-    unsigned int hash = hashtable->hash_key(key);
+    size_t hash = hashtable->hash_key(key);
     return hashtable_do_del(hashtable, key, hash);
 }
 
 void hashtable_clear(hashtable_t *hashtable)
 {
-    unsigned int i;
+    size_t i;
 
     hashtable_do_clear(hashtable);
 
@@ -331,7 +331,7 @@ void *hashtable_iter(hashtable_t *hashtable)
 void *hashtable_iter_at(hashtable_t *hashtable, const void *key)
 {
     pair_t *pair;
-    unsigned int hash;
+    size_t hash;
     bucket_t *bucket;
 
     hash = hashtable->hash_key(key);
index f03a769..aba5134 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef HASHTABLE_H
 #define HASHTABLE_H
 
-typedef unsigned int (*key_hash_fn)(const void *key);
+typedef size_t (*key_hash_fn)(const void *key);
 typedef int (*key_cmp_fn)(const void *key1, const void *key2);
 typedef void (*free_fn)(void *key);
 
@@ -20,7 +20,7 @@ struct hashtable_list {
 struct hashtable_pair {
     void *key;
     void *value;
-    unsigned int hash;
+    size_t hash;
     struct hashtable_list list;
 };
 
@@ -30,9 +30,9 @@ struct hashtable_bucket {
 };
 
 typedef struct hashtable {
-    unsigned int size;
+    size_t size;
     struct hashtable_bucket *buckets;
-    unsigned int num_buckets;  /* index to primes[] */
+    size_t num_buckets;  /* index to primes[] */
     struct hashtable_list list;
 
     key_hash_fn hash_key;
similarity index 72%
rename from src/jansson.h.in
rename to src/jansson.h
index 8032692..78a2222 100644 (file)
@@ -9,11 +9,10 @@
 #define JANSSON_H
 
 #include <stdio.h>
+#include <stdlib.h>  /* for size_t */
+#include <jansson_config.h>
 
-#ifndef __cplusplus
-#define JSON_INLINE @json_inline@
-#else
-#define JSON_INLINE inline
+#ifdef __cplusplus
 extern "C" {
 #endif
 
@@ -32,9 +31,17 @@ typedef enum {
 
 typedef struct {
     json_type type;
-    unsigned long refcount;
+    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)
@@ -53,7 +60,7 @@ json_t *json_object(void);
 json_t *json_array(void);
 json_t *json_string(const char *value);
 json_t *json_string_nocheck(const char *value);
-json_t *json_integer(int 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);
@@ -62,7 +69,7 @@ json_t *json_null(void);
 static JSON_INLINE
 json_t *json_incref(json_t *json)
 {
-    if(json && json->refcount != (unsigned int)-1)
+    if(json && json->refcount != (size_t)-1)
         ++json->refcount;
     return json;
 }
@@ -73,14 +80,14 @@ void json_delete(json_t *json);
 static JSON_INLINE
 void json_decref(json_t *json)
 {
-    if(json && json->refcount != (unsigned int)-1 && --json->refcount == 0)
+    if(json && json->refcount != (size_t)-1 && --json->refcount == 0)
         json_delete(json);
 }
 
 
 /* getters, setters, manipulation */
 
-unsigned int json_object_size(const json_t *object);
+size_t json_object_size(const json_t *object);
 json_t *json_object_get(const json_t *object, const char *key);
 int json_object_set_new(json_t *object, const char *key, json_t *value);
 int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value);
@@ -112,17 +119,17 @@ int json_object_iter_set(json_t *object, void *iter, json_t *value)
     return json_object_iter_set_new(object, iter, json_incref(value));
 }
 
-unsigned int json_array_size(const json_t *array);
-json_t *json_array_get(const json_t *array, unsigned int index);
-int json_array_set_new(json_t *array, unsigned int index, json_t *value);
+size_t json_array_size(const json_t *array);
+json_t *json_array_get(const json_t *array, size_t index);
+int json_array_set_new(json_t *array, size_t index, json_t *value);
 int json_array_append_new(json_t *array, json_t *value);
-int json_array_insert_new(json_t *array, unsigned int index, json_t *value);
-int json_array_remove(json_t *array, unsigned int index);
+int json_array_insert_new(json_t *array, size_t index, json_t *value);
+int json_array_remove(json_t *array, size_t index);
 int json_array_clear(json_t *array);
 int json_array_extend(json_t *array, json_t *other);
 
 static JSON_INLINE
-int json_array_set(json_t *array, unsigned int index, json_t *value)
+int json_array_set(json_t *array, size_t index, json_t *value)
 {
     return json_array_set_new(array, index, json_incref(value));
 }
@@ -134,19 +141,19 @@ int json_array_append(json_t *array, json_t *value)
 }
 
 static JSON_INLINE
-int json_array_insert(json_t *array, unsigned int index, json_t *value)
+int json_array_insert(json_t *array, size_t index, json_t *value)
 {
     return json_array_insert_new(array, index, json_incref(value));
 }
 
 const char *json_string_value(const json_t *string);
-int 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, int value);
+int json_integer_set(json_t *integer, json_int_t value);
 int json_real_set(json_t *real, double value);
 
 
@@ -170,19 +177,19 @@ typedef struct {
     int line;
 } json_error_t;
 
-json_t *json_loads(const char *input, json_error_t *error);
-json_t *json_loadf(FILE *input, json_error_t *error);
-json_t *json_load_file(const char *path, json_error_t *error);
+json_t *json_loads(const char *input, size_t flags, json_error_t *error);
+json_t *json_loadf(FILE *input, size_t flags, json_error_t *error);
+json_t *json_load_file(const char *path, size_t flags, json_error_t *error);
 
-#define JSON_INDENT(n)      (n & 0xFF)
-#define JSON_COMPACT        0x100
-#define JSON_ENSURE_ASCII   0x200
-#define JSON_SORT_KEYS      0x400
-#define JSON_PRESERVE_ORDER 0x800
+#define JSON_INDENT(n)      (n & 0x1F)
+#define JSON_COMPACT        0x20
+#define JSON_ENSURE_ASCII   0x40
+#define JSON_SORT_KEYS      0x80
+#define JSON_PRESERVE_ORDER 0x100
 
-char *json_dumps(const json_t *json, unsigned long flags);
-int json_dumpf(const json_t *json, FILE *output, unsigned long flags);
-int json_dump_file(const json_t *json, const char *path, unsigned long flags);
+char *json_dumps(const json_t *json, size_t flags);
+int json_dumpf(const json_t *json, FILE *output, size_t flags);
+int json_dump_file(const json_t *json, const char *path, size_t flags);
 
 #ifdef __cplusplus
 }
diff --git a/src/jansson_config.h.in b/src/jansson_config.h.in
new file mode 100644 (file)
index 0000000..d2a9392
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 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.
+ *
+ *
+ * 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 do the value substitution
+ * by hand.
+ */
+
+#ifndef JANSSON_CONFIG_H
+#define JANSSON_CONFIG_H
+
+/* If your compiler supports the inline keyword in C, JSON_INLINE is
+   defined to `inline', otherwise empty. In C++, the inline is always
+   supported. */
+#ifdef __cplusplus
+#define JSON_INLINE inline
+#else
+#define JSON_INLINE @json_inline@
+#endif
+
+/* If your compiler supports the `long long` type,
+   JSON_INTEGER_IS_LONG_LONG is defined to 1, otherwise to 0. */
+#define JSON_INTEGER_IS_LONG_LONG @json_have_long_long@
+
+#endif
index 55532eb..e9e0097 100644 (file)
 typedef struct {
     json_t json;
     hashtable_t hashtable;
-    unsigned long serial;
+    size_t serial;
     int visited;
 } json_object_t;
 
 typedef struct {
     json_t json;
-    unsigned int size;
-    unsigned int entries;
+    size_t size;
+    size_t entries;
     json_t **table;
     int visited;
 } json_array_t;
@@ -42,7 +42,7 @@ typedef struct {
 
 typedef struct {
     json_t json;
-    int value;
+    json_int_t value;
 } json_integer_t;
 
 #define json_to_object(json_)  container_of(json_, json_object_t, json)
@@ -52,7 +52,7 @@ typedef struct {
 #define json_to_integer(json_) container_of(json_, json_integer_t, json)
 
 typedef struct {
-    unsigned long serial;
+    size_t serial;
     char key[1];
 } object_key_t;
 
index d49a4da..17ebcb7 100644 (file)
@@ -52,7 +52,7 @@ typedef struct {
     int line, column;
     union {
         char *string;
-        int integer;
+        json_int_t integer;
         double real;
     } value;
 } lex_t;
@@ -401,6 +401,12 @@ out:
     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;
@@ -430,25 +436,26 @@ static int lex_scan_number(lex_t *lex, char c, json_error_t *error)
     }
 
     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;
     }
 
@@ -804,10 +811,11 @@ static int string_eof(void *data)
     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,
@@ -833,10 +841,11 @@ out:
     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;
@@ -857,7 +866,7 @@ out:
     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;
@@ -872,7 +881,7 @@ json_t *json_load_file(const char *path, json_error_t *error)
         return NULL;
     }
 
-    result = json_loadf(fp, error);
+    result = json_loadf(fp, flags, error);
 
     fclose(fp);
     return result;
index 8e0cfa2..3895882 100644 (file)
@@ -35,14 +35,14 @@ static inline void json_init(json_t *json, json_type type)
    an object_key_t instance. */
 #define string_to_key(string)  container_of(string, object_key_t, key)
 
-static unsigned int hash_key(const void *ptr)
+static size_t hash_key(const void *ptr)
 {
     const char *str = ((const object_key_t *)ptr)->key;
 
-    unsigned int hash = 5381;
-    unsigned int c;
+    size_t hash = 5381;
+    size_t c;
 
-    while((c = (unsigned int)*str))
+    while((c = (size_t)*str))
     {
         hash = ((hash << 5) + hash) + c;
         str++;
@@ -88,7 +88,7 @@ static void json_delete_object(json_object_t *object)
     free(object);
 }
 
-unsigned int json_object_size(const json_t *json)
+size_t json_object_size(const json_t *json)
 {
     json_object_t *object;
 
@@ -374,7 +374,7 @@ json_t *json_array(void)
 
 static void json_delete_array(json_array_t *array)
 {
-    unsigned int i;
+    size_t i;
 
     for(i = 0; i < array->entries; i++)
         json_decref(array->table[i]);
@@ -383,7 +383,7 @@ static void json_delete_array(json_array_t *array)
     free(array);
 }
 
-unsigned int json_array_size(const json_t *json)
+size_t json_array_size(const json_t *json)
 {
     if(!json_is_array(json))
         return 0;
@@ -391,7 +391,7 @@ unsigned int json_array_size(const json_t *json)
     return json_to_array(json)->entries;
 }
 
-json_t *json_array_get(const json_t *json, unsigned int index)
+json_t *json_array_get(const json_t *json, size_t index)
 {
     json_array_t *array;
     if(!json_is_array(json))
@@ -404,7 +404,7 @@ json_t *json_array_get(const json_t *json, unsigned int index)
     return array->table[index];
 }
 
-int json_array_set_new(json_t *json, unsigned int index, json_t *value)
+int json_array_set_new(json_t *json, size_t index, json_t *value)
 {
     json_array_t *array;
 
@@ -430,24 +430,24 @@ int json_array_set_new(json_t *json, unsigned int index, json_t *value)
     return 0;
 }
 
-static void array_move(json_array_t *array, unsigned int dest,
-                       unsigned int src, unsigned int count)
+static void array_move(json_array_t *array, size_t dest,
+                       size_t src, size_t count)
 {
     memmove(&array->table[dest], &array->table[src], count * sizeof(json_t *));
 }
 
-static void array_copy(json_t **dest, unsigned int dpos,
-                       json_t **src, unsigned int spos,
-                       unsigned int count)
+static void array_copy(json_t **dest, size_t dpos,
+                       json_t **src, size_t spos,
+                       size_t count)
 {
     memcpy(&dest[dpos], &src[spos], count * sizeof(json_t *));
 }
 
 static json_t **json_array_grow(json_array_t *array,
-                                unsigned int amount,
+                                size_t amount,
                                 int copy)
 {
-    unsigned int new_size;
+    size_t new_size;
     json_t **old_table, **new_table;
 
     if(array->entries + amount <= array->size)
@@ -497,7 +497,7 @@ int json_array_append_new(json_t *json, json_t *value)
     return 0;
 }
 
-int json_array_insert_new(json_t *json, unsigned int index, json_t *value)
+int json_array_insert_new(json_t *json, size_t index, json_t *value)
 {
     json_array_t *array;
     json_t **old_table;
@@ -537,7 +537,7 @@ int json_array_insert_new(json_t *json, unsigned int index, json_t *value)
     return 0;
 }
 
-int json_array_remove(json_t *json, unsigned int index)
+int json_array_remove(json_t *json, size_t index)
 {
     json_array_t *array;
 
@@ -559,7 +559,7 @@ int json_array_remove(json_t *json, unsigned int index)
 int json_array_clear(json_t *json)
 {
     json_array_t *array;
-    unsigned int i;
+    size_t i;
 
     if(!json_is_array(json))
         return -1;
@@ -575,7 +575,7 @@ int json_array_clear(json_t *json)
 int json_array_extend(json_t *json, json_t *other_json)
 {
     json_array_t *array, *other;
-    unsigned int i;
+    size_t i;
 
     if(!json_is_array(json) || !json_is_array(other_json))
         return -1;
@@ -596,7 +596,7 @@ int json_array_extend(json_t *json, json_t *other_json)
 
 static int json_array_equal(json_t *array1, json_t *array2)
 {
-    unsigned int i, size;
+    size_t i, size;
 
     size = json_array_size(array1);
     if(size != json_array_size(array2))
@@ -619,7 +619,7 @@ static int json_array_equal(json_t *array1, json_t *array2)
 static json_t *json_array_copy(json_t *array)
 {
     json_t *result;
-    unsigned int i;
+    size_t i;
 
     result = json_array();
     if(!result)
@@ -634,7 +634,7 @@ static json_t *json_array_copy(json_t *array)
 static json_t *json_array_deep_copy(json_t *array)
 {
     json_t *result;
-    unsigned int i;
+    size_t i;
 
     result = json_array();
     if(!result)
@@ -728,7 +728,7 @@ static json_t *json_string_copy(json_t *string)
 
 /*** integer ***/
 
-json_t *json_integer(int value)
+json_t *json_integer(json_int_t value)
 {
     json_integer_t *integer = malloc(sizeof(json_integer_t));
     if(!integer)
@@ -739,7 +739,7 @@ json_t *json_integer(int value)
     return &integer->json;
 }
 
-int json_integer_value(const json_t *json)
+json_int_t json_integer_value(const json_t *json)
 {
     if(!json_is_integer(json))
         return 0;
@@ -747,7 +747,7 @@ int json_integer_value(const json_t *json)
     return json_to_integer(json)->value;
 }
 
-int json_integer_set(json_t *json, int value)
+int json_integer_set(json_t *json, json_int_t value)
 {
     if(!json_is_integer(json))
         return -1;
@@ -839,7 +839,7 @@ json_t *json_true(void)
 {
     static json_t the_true = {
         .type = JSON_TRUE,
-        .refcount = (unsigned int)-1
+        .refcount = (size_t)-1
     };
     return &the_true;
 }
@@ -849,7 +849,7 @@ json_t *json_false(void)
 {
     static json_t the_false = {
         .type = JSON_FALSE,
-        .refcount = (unsigned int)-1
+        .refcount = (size_t)-1
     };
     return &the_false;
 }
@@ -859,7 +859,7 @@ json_t *json_null(void)
 {
     static json_t the_null = {
         .type = JSON_NULL,
-        .refcount = (unsigned int)-1
+        .refcount = (size_t)-1
     };
     return &the_null;
 }
index 77407e5..cff820b 100644 (file)
@@ -28,7 +28,7 @@ static int getenv_int(const char *name)
 int main(int argc, char *argv[])
 {
     int indent = 0;
-    unsigned int flags = 0;
+    size_t flags = 0;
 
     json_t *json;
     json_error_t error;
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
     if(getenv_int("JSON_SORT_KEYS"))
         flags |= JSON_SORT_KEYS;
 
-    json = json_loadf(stdin, &error);
+    json = json_loadf(stdin, 0, &error);
     if(!json) {
         fprintf(stderr, "%d\n%s\n", error.line, error.text);
         return 1;
index 54c1d28..1c8a066 100644 (file)
@@ -174,9 +174,9 @@ static void test_copy_array(void)
     const char *json_array_text = "[1, \"foo\", 3.141592, {\"foo\": \"bar\"}]";
 
     json_t *array, *copy;
-    unsigned int i;
+    size_t i;
 
-    array = json_loads(json_array_text, NULL);
+    array = json_loads(json_array_text, 0, NULL);
     if(!array)
         fail("unable to parse an array");
 
@@ -203,9 +203,9 @@ static void test_deep_copy_array(void)
     const char *json_array_text = "[1, \"foo\", 3.141592, {\"foo\": \"bar\"}]";
 
     json_t *array, *copy;
-    unsigned int i;
+    size_t i;
 
-    array = json_loads(json_array_text, NULL);
+    array = json_loads(json_array_text, 0, NULL);
     if(!array)
         fail("unable to parse an array");
 
@@ -235,7 +235,7 @@ static void test_copy_object(void)
     json_t *object, *copy;
     void *iter;
 
-    object = json_loads(json_object_text, NULL);
+    object = json_loads(json_object_text, 0, NULL);
     if(!object)
         fail("unable to parse an object");
 
@@ -275,7 +275,7 @@ static void test_deep_copy_object(void)
     json_t *object, *copy;
     void *iter;
 
-    object = json_loads(json_object_text, NULL);
+    object = json_loads(json_object_text, 0, NULL);
     if(!object)
         fail("unable to parse an object");
 
index 111ee26..3b4ec2a 100644 (file)
@@ -167,8 +167,8 @@ static void test_equal_complex()
 "    \"array\": [\"foo\", false, null, 1.234]"
 "}";
 
-    value1 = json_loads(complex_json, NULL);
-    value2 = json_loads(complex_json, NULL);
+    value1 = json_loads(complex_json, 0, NULL);
+    value2 = json_loads(complex_json, 0, NULL);
     if(!value1 || !value2)
         fail("unable to parse JSON");
     if(!json_equal(value1, value2))
index 0934ea8..b022a3a 100644 (file)
@@ -14,7 +14,7 @@ int main()
     json_t *json;
     json_error_t error;
 
-    json = json_load_file("/path/to/nonexistent/file.json", &error);
+    json = json_load_file("/path/to/nonexistent/file.json", 0, &error);
     if(error.line != -1)
         fail("json_load_file returned an invalid line number");
     if(strcmp(error.text, "unable to open /path/to/nonexistent/file.json: No such file or directory") != 0)
index 1769c65..9e1dba3 100644 (file)
@@ -152,33 +152,33 @@ int main()
 
     /* Test reference counting on singletons (true, false, null) */
     value = json_true();
-    if(value->refcount != (unsigned int)-1)
+    if(value->refcount != (size_t)-1)
       fail("refcounting true works incorrectly");
     json_decref(value);
-    if(value->refcount != (unsigned int)-1)
+    if(value->refcount != (size_t)-1)
       fail("refcounting true works incorrectly");
     json_incref(value);
-    if(value->refcount != (unsigned int)-1)
+    if(value->refcount != (size_t)-1)
       fail("refcounting true works incorrectly");
 
     value = json_false();
-    if(value->refcount != (unsigned int)-1)
+    if(value->refcount != (size_t)-1)
       fail("refcounting false works incorrectly");
     json_decref(value);
-    if(value->refcount != (unsigned int)-1)
+    if(value->refcount != (size_t)-1)
       fail("refcounting false works incorrectly");
     json_incref(value);
-    if(value->refcount != (unsigned int)-1)
+    if(value->refcount != (size_t)-1)
       fail("refcounting false works incorrectly");
 
     value = json_null();
-    if(value->refcount != (unsigned int)-1)
+    if(value->refcount != (size_t)-1)
       fail("refcounting null works incorrectly");
     json_decref(value);
-    if(value->refcount != (unsigned int)-1)
+    if(value->refcount != (size_t)-1)
       fail("refcounting null works incorrectly");
     json_incref(value);
-    if(value->refcount != (unsigned int)-1)
+    if(value->refcount != (size_t)-1)
       fail("refcounting null works incorrectly");
 
     return 0;
index f2366dc..dfa3846 100644 (file)
@@ -1 +1 @@
-[-123123123123123]
\ No newline at end of file
+[-123123123123123123123123123123]
\ No newline at end of file
index a787c2c..3156f10 100644 (file)
@@ -1 +1 @@
-[123123123123123]
\ No newline at end of file
+[123123123123123123123123123123]
\ No newline at end of file