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

1  2 
configure.ac
doc/apiref.rst
doc/conformance.rst
src/Makefile.am
src/jansson.h
src/jansson_private.h
src/value.c

diff --combined configure.ac
@@@ -1,5 -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])
  
@@@ -8,8 -8,8 +8,8 @@@ AC_CONFIG_HEADERS([config.h]
  
  # Checks for programs.
  AC_PROG_CC
- AC_PROG_CXX
  AC_PROG_LIBTOOL
+ AM_CONDITIONAL([GCC], [test x$GCC = xyes])
  
  # Checks for libraries.
  
  # 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;;
@@@ -40,7 -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
diff --combined doc/apiref.rst
@@@ -210,10 -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
@@@ -244,6 -244,12 +244,12 @@@ returns the same value each time
  String
  ======
  
+ Jansson uses UTF-8 as the character encoding. All JSON strings must be
+ valid UTF-8 (or ASCII, as it's a subset of UTF-8). Normal null
+ terminated C strings are used, so JSON strings may not contain
+ embedded null characters. All other Unicode codepoints U+0001 through
+ U+10FFFF are allowed.
  .. cfunction:: json_t *json_string(const char *value)
  
     .. refcounting:: new
  Number
  ======
  
 -.. cfunction:: json_t *json_integer(int value)
+ The JSON specification only contains one numeric type, "number". The C
+ programming language has distinct types for integer and floating-point
+ 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`.
 +.. 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.
@@@ -384,12 -357,12 +396,12 @@@ A JSON array is an ordered collection o
     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
  
     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
  
     .. 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
  
     .. 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
  
     .. 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.
@@@ -479,7 -452,7 +491,7 @@@ Unicode string and the value is any JSO
     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.
@@@ -630,7 -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.
  
  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.
     *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
@@@ -695,10 -668,12 +707,12 @@@ This sections describes the functions t
  text to the Jansson representation of JSON data. The JSON
  specification requires that a JSON text is either a serialized array
  or object, and this requirement is also enforced with the following
- functions.
+ functions. In other words, the top level value in the JSON text being
+ decoded must be either array or object.
  
- The only supported character encoding is UTF-8 (which ASCII is a
- subset of).
+ See :ref:`rfc-conformance` for a discussion on Jansson's conformance
+ to the JSON specification. It explains many design decisions that
+ affect especially the behavior of the decoder.
  
  .. ctype:: json_error_t
  
            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 */
            }
  
  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
@@@ -786,7 -758,8 +800,8 @@@ only if they are exactly the same value
    values are equal. An integer value is never equal to a real value,
    though.
  
- * Two strings are equal if their contained UTF-8 strings are equal.
+ * Two strings are equal if their contained UTF-8 strings are equal,
+   byte by byte. Unicode comparison algorithms are not implemented.
  
  * Two arrays are equal if they have the same number of elements and
    each element in the first array is equal to the corresponding
diff --combined doc/conformance.rst
@@@ -1,3 -1,5 +1,5 @@@
+ .. _rfc-conformance:
  ***************
  RFC Conformance
  ***************
@@@ -36,9 -38,7 +38,9 @@@ Real vs. Intege
  
  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 -56,19 +58,19 @@@ Overflow, Underflow & Precisio
  -------------------------------
  
  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 -96,9 +98,9 @@@ Type
  -----
  
  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.
diff --combined src/Makefile.am
@@@ -1,4 -1,4 +1,4 @@@
 -include_HEADERS = jansson.h
 +include_HEADERS = jansson.h jansson_config.h
  
  lib_LTLIBRARIES = libjansson.la
  libjansson_la_SOURCES = \
@@@ -17,4 -17,7 +17,7 @@@ libjansson_la_LDFLAGS = 
        -export-symbols-regex '^json_' \
        -version-info 3:0:3
  
+ if GCC
+ # These flags are gcc specific
  AM_CFLAGS = -Wall -Wextra -Werror
+ endif
diff --combined src/jansson.h
@@@ -9,10 -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
  
@@@ -31,17 -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)
@@@ -60,7 -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);
@@@ -69,7 -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;
  }
@@@ -80,14 -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);
@@@ -113,23 -106,23 +113,23 @@@ int json_object_set_nocheck(json_t *obj
      return json_object_set_new_nocheck(object, key, json_incref(value));
  }
  
- static inline
+ static JSON_INLINE
  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));
  }
@@@ -141,19 -134,19 +141,19 @@@ int json_array_append(json_t *array, js
  }
  
  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);
  
  
@@@ -177,19 -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 --combined src/jansson_private.h
@@@ -8,23 -8,24 +8,24 @@@
  #ifndef JANSSON_PRIVATE_H
  #define JANSSON_PRIVATE_H
  
+ #include <stddef.h>
  #include "jansson.h"
  #include "hashtable.h"
  
  #define container_of(ptr_, type_, member_)  \
-     ((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_))
+     ((type_ *)((char *)ptr_ - offsetof(type_, member_)))
  
  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;
@@@ -41,7 -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)
@@@ -51,8 -52,8 +52,8 @@@
  #define json_to_integer(json_) container_of(json_, json_integer_t, json)
  
  typedef struct {
 -    unsigned long serial;
 +    size_t serial;
-     char key[];
+     char key[1];
  } object_key_t;
  
  const object_key_t *jsonp_object_iter_fullkey(void *iter);
diff --combined src/value.c
@@@ -9,6 -9,7 +9,7 @@@
  
  #include <config.h>
  
+ #include <stddef.h>
  #include <stdlib.h>
  #include <string.h>
  
@@@ -34,14 -35,14 +35,14 @@@ static inline void json_init(json_t *js
     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++;
@@@ -87,7 -88,7 +88,7 @@@ static void json_delete_object(json_obj
      free(object);
  }
  
 -unsigned int json_object_size(const json_t *json)
 +size_t json_object_size(const json_t *json)
  {
      json_object_t *object;
  
@@@ -124,9 -125,11 +125,11 @@@ int json_object_set_new_nocheck(json_t 
      }
      object = json_to_object(json);
  
-     k = malloc(sizeof(object_key_t) + strlen(key) + 1);
-     if(!k)
-         return -1;
+     /* offsetof(...) returns the size of object_key_t without the
+        last, flexible member. This way, the correct amount is
+        allocated. */
+     k = malloc(offsetof(object_key_t, key) +
+     strlen(key) + 1); if(!k) return -1;
  
      k->serial = object->serial++;
      strcpy(k->key, key);
@@@ -371,7 -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]);
      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;
      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))
      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;
  
      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)
@@@ -494,7 -497,7 +497,7 @@@ int json_array_append_new(json_t *json
      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;
      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;
  
  int json_array_clear(json_t *json)
  {
      json_array_t *array;
 -    unsigned int i;
 +    size_t i;
  
      if(!json_is_array(json))
          return -1;
  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;
  
  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))
  static json_t *json_array_copy(json_t *array)
  {
      json_t *result;
 -    unsigned int i;
 +    size_t i;
  
      result = json_array();
      if(!result)
  static json_t *json_array_deep_copy(json_t *array)
  {
      json_t *result;
 -    unsigned int i;
 +    size_t i;
  
      result = json_array();
      if(!result)
@@@ -725,7 -728,7 +728,7 @@@ static json_t *json_string_copy(json_t 
  
  /*** 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)
      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;
      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;
@@@ -836,7 -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;
  }
@@@ -846,7 -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;
  }
@@@ -856,7 -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;
  }