Merge branch '1.0' into HEAD
authorPetri Lehtinen <petri@digip.org>
Tue, 8 Sep 2009 14:02:39 +0000 (17:02 +0300)
committerPetri Lehtinen <petri@digip.org>
Tue, 8 Sep 2009 14:02:39 +0000 (17:02 +0300)
Conflicts:
configure.ac
doc/conf.py

13 files changed:
configure.ac
doc/apiref.rst
doc/conf.py
src/Makefile.am
src/dump.c
src/jansson.h
src/load.c
src/value.c
test/.gitignore
test/testprogs/Makefile.am
test/testprogs/test_array.c
test/testprogs/test_object.c
test/testprogs/test_simple.c [new file with mode: 0644]

index 4a8c8e5..1ad73a9 100644 (file)
@@ -1,5 +1,5 @@
 AC_PREREQ([2.63])
-AC_INIT([jansson], [1.0.2], [petri@digip.org])
+AC_INIT([jansson], [1.0.2+], [petri@digip.org])
 
 AM_INIT_AUTOMAKE([1.10 foreign])
 
index 903b48c..dc82527 100644 (file)
@@ -41,6 +41,12 @@ Objects of :ctype:`json_t` are always used through a pointer. There
 are APIs for querying the type, manipulating the reference count, and
 for constructing and manipulating values of different types.
 
+Unless noted otherwise, all API functions return an error value if an
+error occurs. Depending on the function's signature, the error value
+is either *NULL* or -1. Invalid arguments or invalid input are
+apparent sources for errors. Memory allocation and I/O operations may
+also cause errors.
+
 
 Type
 ----
@@ -80,8 +86,8 @@ functions:
 .. cfunction:: int json_typeof(const json_t *json)
 
    Return the type of the JSON value (a :ctype:`json_type` cast to
-   :ctype:`int`). This function is actually implemented as a macro for
-   speed.
+   :ctype:`int`). *json* MUST NOT be *NULL*. This function is actually
+   implemented as a macro for speed.
 
 .. cfunction:: json_is_object(const json_t *json)
                json_is_array(const json_t *json)
@@ -93,17 +99,18 @@ functions:
                json_is_null(const json_t *json)
 
    These functions (actually macros) return true (non-zero) for values
-   of the given type, and false (zero) for values of other types.
+   of the given type, and false (zero) for values of other types and
+   for *NULL*.
 
 .. cfunction:: json_is_number(const json_t *json)
 
    Returns true for values of types :const:`JSON_INTEGER` and
-   :const:`JSON_REAL`, and false for other types.
+   :const:`JSON_REAL`, and false for other types and for *NULL*.
 
 .. cfunction:: json_is_boolean(const json_t *json)
 
    Returns true for types :const:`JSON_TRUE` and :const:`JSON_FALSE`,
-   and false for values of other types.
+   and false for values of other types and for *NULL*.
 
 
 Reference Count
@@ -121,7 +128,8 @@ The following functions are used to manipulate the reference count.
 
 .. cfunction:: json_t *json_incref(json_t *json)
 
-   Increment the reference count of *json*.
+   Increment the reference count of *json* if it's not non-*NULL*.
+   Returns *json*.
 
 .. cfunction:: void json_decref(json_t *json)
 
@@ -139,7 +147,7 @@ the value is no longer needed, :cfunc:`json_decref` should be called
 to release the reference.
 
 Normally, all functions accepting a JSON value as an argument will
-manage the reference, i.e. increase and decrease the reference count
+nmanage the reference, i.e. increase and decrease the reference count
 as needed. However, some functions **steal** the reference, i.e. they
 have the same result as if the user called :cfunc:`json_decref()` on
 the argument right after calling the function. These are usually
@@ -154,26 +162,26 @@ argument.
 True, False and Null
 ====================
 
+These values are implemented as singletons, so each of these functions
+returns the same value each time.
+
 .. cfunction:: json_t *json_true(void)
 
    .. refcounting:: new
 
-   Returns a value of the type :const:`JSON_TRUE`, or *NULL* on
-   error.
+   Returns the JSON true value.
 
 .. cfunction:: json_t *json_false(void)
 
    .. refcounting:: new
 
-   Returns a value of the type :const:`JSON_FALSE`, or *NULL* on
-   error.
+   Returns the JSON false value.
 
 .. cfunction:: json_t *json_null(void)
 
    .. refcounting:: new
 
-   Returns a value of the type :const:`JSON_NULL`, or *NULL* on
-   error.
+   Returns the JSON null value.
 
 
 String
@@ -183,13 +191,14 @@ String
 
    .. refcounting:: new
 
-   Returns a new value of the type :const:`JSON_STRING`, or *NULL* on
-   error. *value* must be a valid UTF-8 encoded Unicode string.
+   Returns a new JSON string, or *NULL* on error. *value* must be a
+   valid UTF-8 encoded Unicode string.
 
 .. cfunction:: const char *json_string_value(const json_t *json)
 
-   Returns the associated value of a :const:`JSON_STRING` value as a
-   null terminated UTF-8 encoded string.
+   Returns the associated value of the JSON string *json* as a null
+   terminated UTF-8 encoded string, or *NULL* if *json* is not a JSON
+   string.
 
 
 Number
@@ -199,33 +208,32 @@ Number
 
    .. refcounting:: new
 
-   Returns a new value of the type :const:`JSON_INTEGER`, or *NULL* on
-   error.
+   Returns a new JSON integer, or *NULL* on error.
 
 .. cfunction:: int json_integer_value(const json_t *json)
 
-   Returns the associated integer value of values of the type
-   :const:`JSON_INTEGER`, or 0 for values of other types.
+   Returns the associated value the JSON integer *json*. If *json* is
+   *NULL* or not a JSON integer, 0 is returned.
 
 .. cfunction:: json_t *json_real(double value)
 
    .. refcounting:: new
 
-   Returns a new value of the type :const:`JSON_REAL`, or *NULL* on
-   error.
+   Returns a new JSON real, or *NULL* on error.
 
 .. cfunction:: double json_real_value(const json_t *json)
 
-   Returns the associated real value of values of the type
-   :const:`JSON_INTEGER`, or 0 for values of other types.
+   Returns the associated value of the JSON real *json*. If *json* is
+   *NULL* or not a JSON real, 0.0 is returned.
 
 In addition to the functions above, there's a common query function
 for integers and reals:
 
 .. cfunction:: double json_number_value(const json_t *json)
 
-   Returns the value of either ``JSON_INTEGER`` or ``JSON_REAL``, cast
-   to double regardless of the actual type.
+   Returns the associated value of the JSON integer or JSON real
+   *json*, cast to double regardless of the actual type. If *json* is
+   neither JSON real nor JSON integer, 0.0 is returned.
 
 
 Array
@@ -237,33 +245,52 @@ A JSON array is an ordered collection of other JSON values.
 
    .. refcounting:: new
 
-   Returns a new value of the type :const:`JSON_ARRAY`, or *NULL* on
-   error. Initially, the array is empty.
+   Returns a new JSON array, or *NULL* on error. Initially, the array
+   is empty.
 
 .. cfunction:: unsigned int json_array_size(const json_t *array)
 
-   Returns the number of elements in *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)
 
    .. refcounting:: borrow
 
-   Returns the element in *array* at position *index*, or *NULL* if
-   *index* is out of range. The valid range for *index* is from 0 to
-   the return value of :cfunc:`json_array_size()` minus 1.
+   Returns the element in *array* at position *index*. The valid range
+   for *index* is from 0 to the return value of
+   :cfunc:`json_array_size()` minus 1. If *array* is not a JSON array,
+   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)
 
    Replaces the element in *array* at position *index* with *value*.
-   Returns 0 on success, or -1 if *index* is out of range. The valid
-   range for *index* is from 0 to the return value of
-   :cfunc:`json_array_size()` minus 1.
+   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)
+
+   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
 ======
@@ -275,8 +302,8 @@ Unicode string and the value is any JSON value.
 
    .. refcounting:: new
 
-   Returns a new value of the type :const:`JSON_OBJECT`, or *NULL* on
-   error. Initially, the object is empty.
+   Returns a new JSON object, or *NULL* on error. Initially, the
+   object is empty.
 
 .. cfunction:: json_t *json_object_get(const json_t *object, const char *key)
 
@@ -288,9 +315,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)
 
@@ -321,6 +356,20 @@ The following functions implement an iteration protocol for objects:
 
    Extract the associated value from *iter*.
 
+The iteration protocol can be used for example as follows::
+
+   /* obj is a JSON object */
+   const char *key;
+   json_t *value;
+   void *iter = json_object_iter(obj);
+   while(iter)
+   {
+       key = json_object_iter_key(iter);
+       value = json_object_iter_value(iter);
+       /* use key and value ... */
+       iter = json_object_iter_next(obj, iter);
+   }
+
 
 Encoding
 ========
index 0b0b6a9..911436a 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.2'
+release = '1.0.2+'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
index 528e50a..5165476 100644 (file)
@@ -15,4 +15,4 @@ libjansson_la_SOURCES = \
        value.c
 libjansson_la_LDFLAGS = -version-info 0:2:0
 
-AM_CFLAGS = -Wall -Wextra -Werror -std=c99
+AM_CFLAGS = -Wall -Wextra -Werror
index 4831873..9505b7f 100644 (file)
@@ -9,7 +9,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 
 #include <jansson.h>
 #include "strbuffer.h"
@@ -36,22 +35,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..2e8582b 100644 (file)
@@ -54,7 +54,7 @@ json_t *json_null(void);
 
 static inline json_t *json_incref(json_t *json)
 {
-    if(json)
+    if(json && json->refcount != (unsigned int)-1)
         ++json->refcount;
     return json;
 }
@@ -64,7 +64,7 @@ void json_delete(json_t *json);
 
 static inline void json_decref(json_t *json)
 {
-    if(json && --json->refcount == 0)
+    if(json && json->refcount != (unsigned int)-1 && --json->refcount == 0)
         json_delete(json);
 }
 
@@ -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 fc3679d..d1366f8 100644 (file)
@@ -12,7 +12,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
-#include <unistd.h>
 #include <assert.h>
 
 #include <jansson.h>
@@ -541,6 +540,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);
@@ -584,7 +594,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..29f787c 100644 (file)
@@ -118,23 +118,43 @@ 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))
+    if(!key || !value)
         return -1;
 
+    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(json_t *json, const char *key, json_t *value)
+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_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 +255,57 @@ 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(!value)
+        return -1;
+
     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(!value)
+        return -1;
+
     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;
@@ -276,18 +316,28 @@ int json_array_append(json_t *json, json_t *value)
 
 json_t *json_string_nocheck(const char *value)
 {
-    json_string_t *string = malloc(sizeof(json_string_t));
+    json_string_t *string;
+
+    if(!value)
+        return NULL;
+
+    string = malloc(sizeof(json_string_t));
     if(!string)
        return NULL;
     json_init(&string->json, JSON_STRING);
 
     string->value = strdup(value);
+    if(!string->value) {
+        free(string);
+        return NULL;
+    }
+
     return &string->json;
 }
 
 json_t *json_string(const char *value)
 {
-    if(!utf8_check_string(value, -1))
+    if(!value || !utf8_check_string(value, -1))
         return NULL;
 
     return json_string_nocheck(value);
@@ -381,9 +431,9 @@ json_t *json_true(void)
 {
     static json_t the_true = {
         .type = JSON_TRUE,
-        .refcount = 1
+        .refcount = (unsigned int)1
     };
-    return json_incref(&the_true);
+    return &the_true;
 }
 
 
@@ -391,9 +441,9 @@ json_t *json_false(void)
 {
     static json_t the_false = {
         .type = JSON_FALSE,
-        .refcount = 1
+        .refcount = (unsigned int)1
     };
-    return json_incref(&the_false);
+    return &the_false;
 }
 
 
@@ -401,9 +451,9 @@ json_t *json_null(void)
 {
     static json_t the_null = {
         .type = JSON_NULL,
-        .refcount = 1
+        .refcount = (unsigned int)1
     };
-    return json_incref(&the_null);
+    return &the_null;
 }
 
 
index a31f16f..09dfb4d 100644 (file)
@@ -5,3 +5,4 @@ testlogs
 testprogs/test_array
 testprogs/test_number
 testprogs/test_object
+testprogs/test_simple
index b7b7e91..4360cb8 100644 (file)
@@ -1,6 +1,7 @@
-check_PROGRAMS = test_array test_number test_object
+check_PROGRAMS = test_array test_simple test_number test_object
 
 test_array_SOURCES = test_array.c util.h
+test_simple_SOURCES = test_simple.c util.h
 test_number_SOURCES = test_number.c util.h
 test_object_SOURCES = test_number.c util.h
 
index 0ebc3d5..b597afb 100644 (file)
@@ -27,6 +27,9 @@ int main()
     if(json_array_size(array) != 0)
         fail("empty array has nonzero size");
 
+    if(!json_array_append(array, NULL))
+        fail("able to append NULL");
+
     if(json_array_append(array, five))
         fail("unable to append");
 
@@ -54,6 +57,9 @@ int main()
     if(json_array_set(array, 0, seven))
         fail("unable to set value");
 
+    if(!json_array_set(array, 0, NULL))
+        fail("able to set NULL");
+
     if(json_array_size(array) != 2)
         fail("wrong array size");
 
@@ -85,6 +91,26 @@ int main()
             fail("got wrong value");
     }
 
+    if(json_array_set_new(array, 15, json_integer(123)))
+        fail("unable to set new value");
+
+    value = json_array_get(array, 15);
+    if(!json_is_integer(value) || json_integer_value(value) != 123)
+      fail("json_array_set_new works incorrectly");
+
+    if(!json_array_set_new(array, 15, NULL))
+        fail("able to set_new NULL value");
+
+    if(json_array_append_new(array, json_integer(321)))
+        fail("unable to append new value");
+
+    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");
+
+    if(!json_array_append_new(array, NULL))
+        fail("able to append_new NULL value");
+
     json_decref(five);
     json_decref(seven);
     json_decref(array);
index 9f72374..540109e 100644 (file)
@@ -29,6 +29,23 @@ int main()
     if(json_object_set(object, "a", string))
         fail("unable to set value");
 
+    if(!json_object_set(object, NULL, string))
+        fail("able to set NULL key");
+
+    if(!json_object_set(object, "a", NULL))
+        fail("able to set NULL value");
+
+    iter = json_object_iter(object);
+    if(!iter)
+        fail("unable to get iterator");
+
+    if(strcmp(json_object_iter_key(iter), "a"))
+        fail("iterating failed: wrong key");
+    if(json_object_iter_value(iter) != string)
+        fail("iterating failed: wrong value");
+    if(json_object_iter_next(object, iter) != NULL)
+        fail("able to iterate over the end");
+
     /* invalid UTF-8 in key */
     if(!json_object_set(object, "a\xefz", string))
         fail("able to set invalid unicode key");
@@ -39,7 +56,7 @@ int main()
     if(value != string)
         fail("got different value than what was added");
 
-    /* "a", "lp" and "px" collide with a five-bucket hashtable */
+    /* "a", "lp" and "px" collide in a five-bucket hashtable */
     if(json_object_set(object, "b", string) ||
        json_object_set(object, "lp", string) ||
        json_object_set(object, "px", string))
@@ -73,7 +90,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 +110,20 @@ int main()
     if(json_object_set(object, "e", string))
         fail("unable to set value");
 
+
+    if(json_object_set_new(object, "foo", json_integer(123)))
+        fail("unable to set new value");
+
+    value = json_object_get(object, "foo");
+    if(!json_is_integer(value) || json_integer_value(value) != 123)
+      fail("json_object_set_new works incorrectly");
+
+    if(!json_object_set_new(object, NULL, json_integer(432)))
+        fail("able to set_new NULL key");
+
+    if(!json_object_set_new(object, "foo", NULL))
+        fail("able to set_new NULL value");
+
     json_decref(string);
     json_decref(other_string);
     json_decref(object);
diff --git a/test/testprogs/test_simple.c b/test/testprogs/test_simple.c
new file mode 100644 (file)
index 0000000..4491ed2
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2009 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.
+ */
+
+#include <string.h>
+#include <jansson.h>
+#include "util.h"
+
+/* Call the simple functions not covered by other tests of the public API */
+int main()
+{
+    json_t *value;
+
+    value = json_integer(1);
+    if(json_typeof(value) != JSON_INTEGER)
+        fail("json_typeof failed");
+
+    if(json_is_object(value))
+        fail("json_is_object failed");
+
+    if(json_is_array(value))
+        fail("json_is_array failed");
+
+    if(json_is_string(value))
+        fail("json_is_string failed");
+
+    if(!json_is_integer(value))
+        fail("json_is_integer failed");
+
+    if(json_is_real(value))
+        fail("json_is_real failed");
+
+    if(!json_is_number(value))
+        fail("json_is_number failed");
+
+    if(json_is_true(value))
+        fail("json_is_true failed");
+
+    if(json_is_false(value))
+        fail("json_is_false failed");
+
+    if(json_is_boolean(value))
+        fail("json_is_boolean failed");
+
+    if(json_is_null(value))
+        fail("json_is_null failed");
+
+    json_decref(value);
+
+
+    value = json_string("foo");
+    if(!value)
+        fail("json_string failed");
+    if(strcmp(json_string_value(value), "foo"))
+        fail("invalid string value");
+    json_decref(value);
+
+    value = json_string(NULL);
+    if(value)
+        fail("json_string(NULL) failed");
+
+    value = json_integer(123);
+    if(!value)
+        fail("json_integer failed");
+    if(json_integer_value(value) != 123)
+        fail("invalid integer value");
+    if(json_number_value(value) != 123.0)
+        fail("invalid number value");
+    json_decref(value);
+
+    value = json_real(123.123);
+    if(!value)
+        fail("json_real failed");
+    if(json_real_value(value) != 123.123)
+        fail("invalid integer value");
+    if(json_number_value(value) != 123.123)
+        fail("invalid number value");
+    json_decref(value);
+
+    value = json_true();
+    if(!value)
+        fail("json_true failed");
+    json_decref(value);
+
+    value = json_false();
+    if(!value)
+        fail("json_false failed");
+    json_decref(value);
+
+    value = json_null();
+    if(!value)
+        fail("json_null failed");
+    json_decref(value);
+
+    return 0;
+}