Merge branch '1.0'
authorPetri Lehtinen <petri@digip.org>
Sun, 6 Sep 2009 09:53:38 +0000 (12:53 +0300)
committerPetri Lehtinen <petri@digip.org>
Sun, 6 Sep 2009 09:53:38 +0000 (12:53 +0300)
Conflicts:
configure.ac
doc/conf.py

configure.ac
doc/apiref.rst
doc/conf.py
src/Makefile.am
src/dump.c
src/jansson.h
src/load.c
src/value.c
test/testprogs/test_array.c
test/testprogs/test_object.c

index 44535ff..f7fe011 100644 (file)
@@ -1,5 +1,5 @@
 AC_PREREQ([2.63])
-AC_INIT([jansson], [1.0.1], [petri@digip.org])
+AC_INIT([jansson], [1.0.1+], [petri@digip.org])
 
 AM_INIT_AUTOMAKE([1.10 foreign])
 
index 903b48c..57b5e31 100644 (file)
@@ -259,11 +259,27 @@ A JSON array is an ordered collection of other JSON values.
    range for *index* is from 0 to the return value of
    :cfunc:`json_array_size()` minus 1.
 
+.. cfunction:: int json_array_set_new(json_t *array, unsigned int 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
+   the call.
+
+   .. versionadded:: 1.1
+
 .. cfunction:: int json_array_append(json_t *array, json_t *value)
 
    Appends *value* to the end of *array*, growing the size of *array*
    by 1. Returns 0 on success and -1 on error.
 
+.. cfunction:: int json_array_append_new(json_t *array, json_t *value)
+
+   Like :cfunc:`json_array_append()` but steals the reference to
+   *value*. This is useful when *value* is newly created and not used
+   after the call.
+
+   .. versionadded:: 1.1
+
 
 Object
 ======
@@ -288,9 +304,17 @@ Unicode string and the value is any JSON value.
 .. cfunction:: int json_object_set(json_t *object, const char *key, json_t *value)
 
    Set the value of *key* to *value* in *object*. *key* must be a
-   valid terminated UTF-8 encoded Unicode string. If there already is
-   a value for *key*, it is replaced by the new value. Returns 0 on
-   success and -1 on error.
+   valid null terminated UTF-8 encoded Unicode string. If there
+   already is a value for *key*, it is replaced by the new value.
+   Returns 0 on success and -1 on error.
+
+.. cfunction:: int json_object_set_new(json_t *object, const char *key, json_t *value)
+
+   Like :cfunc:`json_object_set()` but steals the reference to
+   *value*. This is useful when *value* is newly created and not used
+   after the call.
+
+   .. versionadded:: 1.1
 
 .. cfunction:: int json_object_del(json_t *object, const char *key)
 
index 0aaee33..bd88c6b 100644 (file)
@@ -52,7 +52,7 @@ copyright = u'2009, Petri Lehtinen'
 # The short X.Y version.
 version = '1.0'
 # The full version, including alpha/beta/rc tags.
-release = '1.0.1'
+release = '1.0.1+'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
index e6264d5..50b1e69 100644 (file)
@@ -15,4 +15,4 @@ libjansson_la_SOURCES = \
        value.c
 libjansson_la_LDFLAGS = -version-info 0:1:0
 
-AM_CFLAGS = -Wall -Wextra -Werror -std=c99
+AM_CFLAGS = -Wall -Wextra -Werror
index 4831873..24e206f 100644 (file)
@@ -36,22 +36,23 @@ static int dump_to_file(const char *buffer, int size, void *data)
     return 0;
 }
 
+/* 256 spaces (the maximum indentation size) */
+static char whitespace[] = "                                                                                                                                                                                                                                                                ";
+
 static int dump_indent(uint32_t flags, int depth, dump_func dump, void *data)
 {
     if(JSON_INDENT(flags) > 0)
     {
-        char *ws_buffer;
-        int ws_count = JSON_INDENT(flags) * depth;
+        int i, ws_count = JSON_INDENT(flags);
 
         if(dump("\n", 1, data))
             return -1;
 
-        if(ws_count == 0)
-            return 0;
-
-        ws_buffer = alloca(ws_count);
-        memset(ws_buffer, ' ', ws_count);
-        return dump(ws_buffer, ws_count, data);
+        for(i = 0; i < depth; i++)
+        {
+            if(dump(whitespace, ws_count, data))
+                return -1;
+        }
     }
     return 0;
 }
index 02b20f5..3aa10de 100644 (file)
@@ -72,17 +72,36 @@ static inline void json_decref(json_t *json)
 /* getters, setters, manipulation */
 
 json_t *json_object_get(const json_t *object, const char *key);
-int json_object_set(json_t *object, const char *key, json_t *value);
+int json_object_set_new(json_t *object, const char *key, json_t *value);
 int json_object_del(json_t *object, const char *key);
 void *json_object_iter(json_t *object);
 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);
 
+static inline
+int json_object_set(json_t *object, const char *key, json_t *value)
+{
+    return json_object_set_new(object, key, 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(json_t *array, unsigned int index, json_t *value);
-int json_array_append(json_t *array, json_t *value);
+int json_array_set_new(json_t *array, unsigned int index, json_t *value);
+int json_array_append_new(json_t *array, json_t *value);
+
+static 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
+int json_array_append(json_t *array, json_t *value)
+{
+    return json_array_append_new(array, json_incref(value));
+}
+
 
 const char *json_string_value(const json_t *json);
 int json_integer_value(const json_t *json);
index 25df182..1e2ad2a 100644 (file)
@@ -544,6 +544,17 @@ out:
     return lex->token;
 }
 
+static char *lex_steal_string(lex_t *lex)
+{
+    char *result = NULL;
+    if(lex->token == TOKEN_STRING)
+    {
+        result = lex->value.string;
+        lex->value.string = NULL;
+    }
+    return result;
+}
+
 static int lex_init(lex_t *lex, get_func get, eof_func eof, void *data)
 {
     stream_init(&lex->stream, get, eof, data);
@@ -587,7 +598,7 @@ static json_t *parse_object(lex_t *lex, json_error_t *error)
             goto error;
         }
 
-        key = strdup(lex->value.string);
+        key = lex_steal_string(lex);
         if(!key)
             return NULL;
 
index fda0b03..d83d575 100644 (file)
@@ -118,23 +118,40 @@ json_t *json_object_get(const json_t *json, const char *key)
     return hashtable_get(&object->hashtable, key);
 }
 
-int json_object_set_nocheck(json_t *json, const char *key, json_t *value)
+int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
 {
     json_object_t *object;
 
     if(!json_is_object(json))
+    {
+        json_decref(value);
         return -1;
-
+    }
     object = json_to_object(json);
-    return hashtable_set(&object->hashtable, strdup(key), json_incref(value));
+
+    if(hashtable_set(&object->hashtable, strdup(key), value))
+    {
+        json_decref(value);
+        return -1;
+    }
+
+    return 0;
+}
+
+int json_object_set_nocheck(json_t *json, const char *key, json_t *value)
+{
+    return json_object_set_new_nocheck(json, key, json_incref(value));
 }
 
-int json_object_set(json_t *json, const char *key, json_t *value)
+int json_object_set_new(json_t *json, const char *key, json_t *value)
 {
     if(!utf8_check_string(key, -1))
+    {
+        json_decref(value);
         return -1;
+    }
 
-    return json_object_set_nocheck(json, key, value);
+    return json_object_set_new_nocheck(json, key, value);
 }
 
 int json_object_del(json_t *json, const char *key)
@@ -235,37 +252,49 @@ json_t *json_array_get(const json_t *json, unsigned int index)
     return array->table[index];
 }
 
-int json_array_set(json_t *json, unsigned int index, json_t *value)
+int json_array_set_new(json_t *json, unsigned int index, json_t *value)
 {
     json_array_t *array;
     if(!json_is_array(json))
+    {
+        json_decref(value);
         return -1;
+    }
     array = json_to_array(json);
 
     if(index >= array->entries)
+    {
+        json_decref(value);
         return -1;
+    }
 
     json_decref(array->table[index]);
-    array->table[index] = json_incref(value);
+    array->table[index] = value;
 
     return 0;
 }
 
-int json_array_append(json_t *json, json_t *value)
+int json_array_append_new(json_t *json, json_t *value)
 {
     json_array_t *array;
     if(!json_is_array(json))
+    {
+        json_decref(value);
         return -1;
+    }
     array = json_to_array(json);
 
     if(array->entries == array->size) {
         array->size = max(8, array->size * 2);
         array->table = realloc(array->table, array->size * sizeof(json_t *));
         if(!array->table)
+        {
+            json_decref(value);
             return -1;
+        }
     }
 
-    array->table[array->entries] = json_incref(value);
+    array->table[array->entries] = value;
     array->entries++;
 
     return 0;
index 0ebc3d5..97a8513 100644 (file)
@@ -85,6 +85,16 @@ int main()
             fail("got wrong value");
     }
 
+    json_array_set_new(array, 15, json_integer(123));
+    value = json_array_get(array, 15);
+    if(!json_is_integer(value) || json_integer_value(value) != 123)
+      fail("json_array_set_new works incorrectly");
+
+    json_array_append_new(array, json_integer(321));
+    value = json_array_get(array, json_array_size(array) - 1);
+    if(!json_is_integer(value) || json_integer_value(value) != 321)
+      fail("json_array_append_new works incorrectly");
+
     json_decref(five);
     json_decref(seven);
     json_decref(array);
index 9f72374..1b42c02 100644 (file)
@@ -73,7 +73,7 @@ int main()
         fail("unable to delete an existing key");
 
 
-    /* add many keys to  rehashing */
+    /* add many keys to initiate rehashing */
 
     if(json_object_set(object, "a", string))
         fail("unable to set value");
@@ -93,6 +93,12 @@ int main()
     if(json_object_set(object, "e", string))
         fail("unable to set value");
 
+
+    json_object_set_new(object, "foo", json_integer(123));
+    value = json_object_get(object, "foo");
+    if(!json_is_integer(value) || json_integer_value(value) != 123)
+      fail("json_object_set_new works incorrectly");
+
     json_decref(string);
     json_decref(other_string);
     json_decref(object);