Merge branch '1.2'
authorPetri Lehtinen <petri@digip.org>
Sun, 28 Mar 2010 18:44:41 +0000 (21:44 +0300)
committerPetri Lehtinen <petri@digip.org>
Sun, 28 Mar 2010 18:44:41 +0000 (21:44 +0300)
Conflicts:
configure.ac

1  2 
.gitignore
configure.ac
src/hashtable.c
src/jansson.h.in
src/value.c

diff --combined .gitignore
@@@ -1,4 -1,3 +1,4 @@@
 +*~
  *.o
  *.a
  .libs
@@@ -24,3 -23,4 +24,4 @@@ missin
  stamp-h1
  *.pyc
  *.pc
+ /src/jansson.h
diff --combined configure.ac
@@@ -1,5 -1,5 +1,5 @@@
- AC_PREREQ([2.59])
+ AC_PREREQ([2.60])
 -AC_INIT([jansson], [1.2], [petri@digip.org])
 +AC_INIT([jansson], [1.2+], [petri@digip.org])
  
  AM_INIT_AUTOMAKE([1.10 foreign])
  
@@@ -8,7 -8,6 +8,7 @@@ AC_CONFIG_HEADERS([config.h]
  
  # Checks for programs.
  AC_PROG_CC
 +AC_PROG_CXX
  AC_PROG_LIBTOOL
  
  # Checks for libraries.
  # Checks for typedefs, structures, and compiler characteristics.
  AC_TYPE_INT32_T
  
+ AC_C_INLINE
+ case $ac_cv_c_inline in
+     yes) json_inline=inline;;
+     no) json_inline=;;
+     *) json_inline=$ac_cv_c_inline;;
+ esac
+ AC_SUBST([json_inline])
  # Checks for library functions.
  
  AC_CONFIG_FILES([
@@@ -25,6 -32,7 +33,7 @@@
          Makefile
          doc/Makefile
          src/Makefile
+         src/jansson.h
          test/Makefile
          test/bin/Makefile
          test/suites/Makefile
diff --combined src/hashtable.c
@@@ -5,6 -5,8 +5,8 @@@
   * it under the terms of the MIT license. See LICENSE for details.
   */
  
+ #include <config.h>
  #include <stdlib.h>
  #include "hashtable.h"
  
@@@ -247,39 -249,31 +249,39 @@@ int hashtable_set(hashtable_t *hashtabl
      bucket_t *bucket;
      unsigned int hash, index;
  
 -    hash = hashtable->hash_key(key);
 -
 -    /* if the key already exists, delete it */
 -    hashtable_do_del(hashtable, key, hash);
 -
      /* rehash if the load ratio exceeds 1 */
      if(hashtable->size >= num_buckets(hashtable))
          if(hashtable_do_rehash(hashtable))
              return -1;
  
 -    pair = malloc(sizeof(pair_t));
 -    if(!pair)
 -        return -1;
 -
 -    pair->key = key;
 -    pair->value = value;
 -    pair->hash = hash;
 -    list_init(&pair->list);
 -
 +    hash = hashtable->hash_key(key);
      index = hash % num_buckets(hashtable);
      bucket = &hashtable->buckets[index];
 +    pair = hashtable_find_pair(hashtable, bucket, key, hash);
 +
 +    if(pair)
 +    {
 +        if(hashtable->free_key)
 +            hashtable->free_key(key);
 +        if(hashtable->free_value)
 +            hashtable->free_value(pair->value);
 +        pair->value = value;
 +    }
 +    else
 +    {
 +        pair = malloc(sizeof(pair_t));
 +        if(!pair)
 +            return -1;
 +
 +        pair->key = key;
 +        pair->value = value;
 +        pair->hash = hash;
 +        list_init(&pair->list);
  
 -    insert_to_bucket(hashtable, bucket, &pair->list);
 +        insert_to_bucket(hashtable, bucket, &pair->list);
  
 -    hashtable->size++;
 +        hashtable->size++;
 +    }
      return 0;
  }
  
@@@ -326,22 -320,6 +328,22 @@@ void *hashtable_iter(hashtable_t *hasht
      return hashtable_iter_next(hashtable, &hashtable->list);
  }
  
 +void *hashtable_iter_at(hashtable_t *hashtable, const void *key)
 +{
 +    pair_t *pair;
 +    unsigned int hash;
 +    bucket_t *bucket;
 +
 +    hash = hashtable->hash_key(key);
 +    bucket = &hashtable->buckets[hash % num_buckets(hashtable)];
 +
 +    pair = hashtable_find_pair(hashtable, bucket, key, hash);
 +    if(!pair)
 +        return NULL;
 +
 +    return &pair->list;
 +}
 +
  void *hashtable_iter_next(hashtable_t *hashtable, void *iter)
  {
      list_t *list = (list_t *)iter;
@@@ -361,13 -339,3 +363,13 @@@ void *hashtable_iter_value(void *iter
      pair_t *pair = list_to_pair((list_t *)iter);
      return pair->value;
  }
 +
 +void hashtable_iter_set(hashtable_t *hashtable, void *iter, void *value)
 +{
 +    pair_t *pair = list_to_pair((list_t *)iter);
 +
 +    if(hashtable->free_value)
 +        hashtable->free_value(pair->value);
 +
 +    pair->value = value;
 +}
diff --combined src/jansson.h.in
  
  #include <stdio.h>
  
- #ifdef __cplusplus
+ #ifndef __cplusplus
+ #define JSON_INLINE @json_inline@
+ #else
+ #define JSON_INLINE inline
  extern "C" {
  #endif
  
@@@ -56,7 -59,8 +59,8 @@@ json_t *json_true(void)
  json_t *json_false(void);
  json_t *json_null(void);
  
- static inline json_t *json_incref(json_t *json)
+ static JSON_INLINE
+ json_t *json_incref(json_t *json)
  {
      if(json && json->refcount != (unsigned int)-1)
          ++json->refcount;
@@@ -66,7 -70,8 +70,8 @@@
  /* do not call json_delete directly */
  void json_delete(json_t *json);
  
- static inline void json_decref(json_t *json)
+ static JSON_INLINE
+ void json_decref(json_t *json)
  {
      if(json && json->refcount != (unsigned int)-1 && --json->refcount == 0)
          json_delete(json);
@@@ -83,30 -88,22 +88,30 @@@ int json_object_del(json_t *object, con
  int json_object_clear(json_t *object);
  int json_object_update(json_t *object, json_t *other);
  void *json_object_iter(json_t *object);
 +void *json_object_iter_at(json_t *object, const char *key);
  void *json_object_iter_next(json_t *object, void *iter);
  const char *json_object_iter_key(void *iter);
  json_t *json_object_iter_value(void *iter);
 +int json_object_iter_set_new(json_t *object, void *iter, json_t *value);
  
- static inline
+ static JSON_INLINE
  int json_object_set(json_t *object, const char *key, json_t *value)
  {
      return json_object_set_new(object, key, json_incref(value));
  }
  
- static inline
+ static JSON_INLINE
  int json_object_set_nocheck(json_t *object, const char *key, json_t *value)
  {
      return json_object_set_new_nocheck(object, key, json_incref(value));
  }
  
 +static 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);
@@@ -116,19 -113,19 +121,19 @@@ int json_array_remove(json_t *array, un
  int json_array_clear(json_t *array);
  int json_array_extend(json_t *array, json_t *other);
  
- static inline
+ static JSON_INLINE
  int json_array_set(json_t *array, unsigned int index, json_t *value)
  {
      return json_array_set_new(array, index, json_incref(value));
  }
  
- static inline
+ static JSON_INLINE
  int json_array_append(json_t *array, json_t *value)
  {
      return json_array_append_new(array, json_incref(value));
  }
  
- static inline
+ static JSON_INLINE
  int json_array_insert(json_t *array, unsigned int index, json_t *value)
  {
      return json_array_insert_new(array, index, json_incref(value));
@@@ -173,7 -170,6 +178,7 @@@ json_t *json_load_file(const char *path
  #define JSON_COMPACT        0x100
  #define JSON_ENSURE_ASCII   0x200
  #define JSON_SORT_KEYS      0x400
 +#define JSON_PRESERVE_ORDER 0x800
  
  char *json_dumps(const json_t *json, unsigned long flags);
  int json_dumpf(const json_t *json, FILE *output, unsigned long flags);
diff --combined src/value.c
@@@ -6,6 -6,9 +6,9 @@@
   */
  
  #define _GNU_SOURCE
+ #include <config.h>
  #include <stdlib.h>
  #include <string.h>
  
@@@ -25,16 -28,9 +28,16 @@@ static inline void json_init(json_t *js
  
  /*** object ***/
  
 -static unsigned int hash_string(const void *key)
 +/* This macro just returns a pointer that's a few bytes backwards from
 +   string. This makes it possible to pass a pointer to object_key_t
 +   when only the string inside it is used, without actually creating
 +   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)
  {
 -    const char *str = (const char *)key;
 +    const char *str = ((const object_key_t *)ptr)->key;
 +
      unsigned int hash = 5381;
      unsigned int c;
  
      return hash;
  }
  
 -static int string_equal(const void *key1, const void *key2)
 +static int key_equal(const void *ptr1, const void *ptr2)
  {
 -    return strcmp((const char *)key1, (const char *)key2) == 0;
 +    return strcmp(((const object_key_t *)ptr1)->key,
 +                  ((const object_key_t *)ptr2)->key) == 0;
  }
  
  static void value_decref(void *value)
@@@ -65,14 -60,13 +68,14 @@@ json_t *json_object(void
          return NULL;
      json_init(&object->json, JSON_OBJECT);
  
 -    if(hashtable_init(&object->hashtable, hash_string, string_equal,
 +    if(hashtable_init(&object->hashtable, hash_key, key_equal,
                        free, value_decref))
      {
          free(object);
          return NULL;
      }
  
 +    object->serial = 0;
      object->visited = 0;
  
      return &object->json;
@@@ -103,13 -97,12 +106,13 @@@ json_t *json_object_get(const json_t *j
          return NULL;
  
      object = json_to_object(json);
 -    return hashtable_get(&object->hashtable, key);
 +    return hashtable_get(&object->hashtable, string_to_key(key));
  }
  
  int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
  {
      json_object_t *object;
 +    object_key_t *k;
  
      if(!key || !value)
          return -1;
      }
      object = json_to_object(json);
  
 -    if(hashtable_set(&object->hashtable, strdup(key), value))
 +    k = malloc(sizeof(object_key_t) + strlen(key) + 1);
 +    if(!k)
 +        return -1;
 +
 +    k->serial = object->serial++;
 +    strcpy(k->key, key);
 +
 +    if(hashtable_set(&object->hashtable, k, value))
      {
          json_decref(value);
          return -1;
@@@ -156,7 -142,7 +159,7 @@@ int json_object_del(json_t *json, cons
          return -1;
  
      object = json_to_object(json);
 -    return hashtable_del(&object->hashtable, key);
 +    return hashtable_del(&object->hashtable, string_to_key(key));
  }
  
  int json_object_clear(json_t *json)
@@@ -207,17 -193,6 +210,17 @@@ void *json_object_iter(json_t *json
      return hashtable_iter(&object->hashtable);
  }
  
 +void *json_object_iter_at(json_t *json, const char *key)
 +{
 +    json_object_t *object;
 +
 +    if(!key || !json_is_object(json))
 +        return NULL;
 +
 +    object = json_to_object(json);
 +    return hashtable_iter_at(&object->hashtable, string_to_key(key));
 +}
 +
  void *json_object_iter_next(json_t *json, void *iter)
  {
      json_object_t *object;
      return hashtable_iter_next(&object->hashtable, iter);
  }
  
 +const object_key_t *jsonp_object_iter_fullkey(void *iter)
 +{
 +    if(!iter)
 +        return NULL;
 +
 +    return hashtable_iter_key(iter);
 +}
 +
  const char *json_object_iter_key(void *iter)
  {
      if(!iter)
          return NULL;
  
 -    return (const char *)hashtable_iter_key(iter);
 +    return jsonp_object_iter_fullkey(iter)->key;
  }
  
  json_t *json_object_iter_value(void *iter)
      return (json_t *)hashtable_iter_value(iter);
  }
  
 +int json_object_iter_set_new(json_t *json, void *iter, json_t *value)
 +{
 +    json_object_t *object;
 +
 +    if(!json_is_object(json) || !iter || !value)
 +        return -1;
 +
 +    object = json_to_object(json);
 +    hashtable_iter_set(&object->hashtable, iter, value);
 +
 +    return 0;
 +}
 +
  static int json_object_equal(json_t *object1, json_t *object2)
  {
      void *iter;