Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Rename library. Addresses issues 5 & 17 #18

Merged
merged 16 commits into from

2 participants

@kdopen
Collaborator

Also adds a couple of files to the .gitignore list

hawicz added some commits
@hawicz hawicz Perform better error checking in json_tokener_parse_verbose and rewri…
…te json_tokener_parse to use that instead of json_tokener_parse_ex.

Fix a typo in the string represenations of the json_tokener_error_depth error (s/to deep/too deep/)
9885b30
@hawicz hawicz Ignore several more files, include .o's, .lo's, etc... d7db7e8
@hawicz hawicz Adjust json_object_is_type and json_object_get_type so they return js…
…on_type_null for NULL objects.
e6668b1
@hawicz hawicz Define a LH_LOAD_FACTOR constant and note the range that it can be se…
…t to.

Change the resize check from "count > size" to "count >= size" to avoid a
potential infinite loop with high load factors and a full hash table.
7c4a964
@hawicz hawicz Mention json_type_to_name() in the docs for json_object_get_type(). 23d0da5
@hawicz hawicz For the prototype for json_tokener_error_desc(). bb7978c
@hawicz hawicz Split the json_tokener_parse tests off from test1 into their own test…
… and add several more cases to check various incremental parsing situations.
30c6c4a
@hawicz hawicz Fix a bug in json_tokener_parse_ex when re-using the same tokener to …
…parse multiple objects. Now, json_tokener_reset() does not need to be called after a valid object is parsed.
f30a9ac
@hawicz hawicz Remove a few more things in the distclean target to get rid of *all* …
…generated files.
a7bd85c
@hawicz hawicz Direct people to send bug reports to the json-c google group. 2b5929b
@kdopen
Collaborator

Per the release checklist, this commit will require an additional change to Makefile.am to bump the --version-info value to '2 0 0' as the library name change will require changes to make files and relinking at a minimum, possibly source code changes if includes in the source are of the form '<json/...>'.

I have left that to be done by the maintainer as part of the release.

hawicz and others added some commits
@hawicz hawicz Add a printbuf_memset() function to provide an effecient way to set a…
…nd append things like whitespace indentation.
8310d36
@hawicz hawicz Remove the "#undef PRINTBUF_DEBUG" from printbuf.h so it can be more …
…easily turned on in the Makefile.
7f3298d
@hawicz hawicz Fix some bugs with how buffer sizes were being calcuated in printbuf_…
…memset and an off-by-one error in printbuf_memappend.
e0fa94b
Keith Derrick Added explanatory notes to documentation. 21d3706
Keith Derrick Modify install names for library and include files
Changing root name of library to json-c, and also the
directory where header files are installed to .../jsdon-c/*.

This avoids clashes with other implementations of JSON libraries.
30dd367
Keith Derrick Ignoring additional build products 65f649b
@hawicz
Owner

Fyi, I have (finally!) started applying these changes. The basic change to use the new libjson-c.so library name is present on the kdopen-rename_library branch, and I have it creating a compatibility library with the original libjson.so name, but I still need to figure out what to do about the headers.

@kdopen
Collaborator

great timing. This rename has been blocking us on moving to json-c.

@kdopen
Collaborator

Keep the header file with the same name, but move it to a subdirectory (json-c) under /usr/include. Then set the c-flags to point to the new subdirectory. Should suffice for most people using it. Optionally (via a command line option on configure) install a link to the old name and location to help people with the transition?

@hawicz
Owner

I'd like to keep existing builds against json-c working as-is as much as possible, so I was going to have the link from include/json -> include/json-c happen by default, at least for one release.

@kdopen
Collaborator

Could it be configurable NOT to install the link then? So that the only directory created is json-c? i.e something like

./configure -DNO_COMPATIBILITY_LINK

or whatever the syntax is for passing an option to configure 8)

@hawicz
Owner

Oh, sure. It didn't occur to me to add the option until we switch it off by default, but having something like ./configure --no-oldname-compat right away sounds like a great idea.

@hawicz
Owner

Ok, I think I've got all the necessary changes in place on the kdopen-rename_library branch. If you could try it out from there, I'd appreciate it. To omit the library with the old name, run "./configure --disable-oldname-compat"

@kdopen
Collaborator

Looks good. Did a make install with prefix overidden to check the result. Here's a "tree" of the install directory. Doesn't look quite right here, but the headers are under include/json-c and the libs and .pc fie where they should be as well 8)

.
├── include
|    └── json-c
 |  ├── arraylist.h
│   ├── bits.h
│   ├── debug.h
│   ├── json_config.h
│   ├── json.h
│   ├── json_inttypes.h
│   ├── json_object.h
│   ├── json_object_iterator.h
│   ├── json_object_private.h
│   ├── json_tokener.h
│   ├── json_util.h
│   ├── linkhash.h
│   └── printbuf.h
└── lib
├── libjson-c.a
├── libjson-c.la
├── libjson-c.so -> libjson-c.so.2.0.0
├── libjson-c.so.2 -> libjson-c.so.2.0.0
├── libjson-c.so.2.0.0
└── pkgconfig
└── json-c.pc

@hawicz hawicz merged commit 65f649b into json-c:master
@kdopen kdopen deleted the kdopen:rename_library branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 2, 2012
  1. @hawicz

    Perform better error checking in json_tokener_parse_verbose and rewri…

    hawicz authored Keith Derrick committed
    …te json_tokener_parse to use that instead of json_tokener_parse_ex.
    
    Fix a typo in the string represenations of the json_tokener_error_depth error (s/to deep/too deep/)
  2. @hawicz

    Ignore several more files, include .o's, .lo's, etc...

    hawicz authored Keith Derrick committed
  3. @hawicz

    Adjust json_object_is_type and json_object_get_type so they return js…

    hawicz authored Keith Derrick committed
    …on_type_null for NULL objects.
  4. @hawicz

    Define a LH_LOAD_FACTOR constant and note the range that it can be se…

    hawicz authored Keith Derrick committed
    …t to.
    
    Change the resize check from "count > size" to "count >= size" to avoid a
    potential infinite loop with high load factors and a full hash table.
  5. @hawicz

    Mention json_type_to_name() in the docs for json_object_get_type().

    hawicz authored Keith Derrick committed
  6. @hawicz

    For the prototype for json_tokener_error_desc().

    hawicz authored Keith Derrick committed
  7. @hawicz

    Split the json_tokener_parse tests off from test1 into their own test…

    hawicz authored Keith Derrick committed
    … and add several more cases to check various incremental parsing situations.
  8. @hawicz

    Fix a bug in json_tokener_parse_ex when re-using the same tokener to …

    hawicz authored Keith Derrick committed
    …parse multiple objects. Now, json_tokener_reset() does not need to be called after a valid object is parsed.
  9. @hawicz

    Remove a few more things in the distclean target to get rid of *all* …

    hawicz authored Keith Derrick committed
    …generated files.
  10. @hawicz

    Direct people to send bug reports to the json-c google group.

    hawicz authored Keith Derrick committed
Commits on Apr 5, 2012
  1. @hawicz

    Add a printbuf_memset() function to provide an effecient way to set a…

    hawicz authored Keith Derrick committed
    …nd append things like whitespace indentation.
  2. @hawicz

    Remove the "#undef PRINTBUF_DEBUG" from printbuf.h so it can be more …

    hawicz authored Keith Derrick committed
    …easily turned on in the Makefile.
  3. @hawicz

    Fix some bugs with how buffer sizes were being calcuated in printbuf_…

    hawicz authored Keith Derrick committed
    …memset and an off-by-one error in printbuf_memappend.
Commits on Apr 6, 2012
  1. Added explanatory notes to documentation.

    Keith Derrick authored
  2. Modify install names for library and include files

    Keith Derrick authored
    Changing root name of library to json-c, and also the
    directory where header files are installed to .../jsdon-c/*.
    
    This avoids clashes with other implementations of JSON libraries.
  3. Ignoring additional build products

    Keith Derrick authored
This page is out of date. Refresh to see the latest.
View
9 .gitignore
@@ -17,10 +17,19 @@ Makefile
Makefile.in
missing
stamp-h1
+stamp-h2
test1
test2
test4
testSubDir
test_parse_int64
+test_parse
+test_cast
+test_null
Debug
Release
+*.lo
+*.o
+libjson.la
+json-c.pc
+json_config.h
View
18 Makefile.am
@@ -2,12 +2,12 @@ AM_CFLAGS = -Wall -Wwrite-strings -Werror -std=gnu99 -D_GNU_SOURCE -D_REENTRANT
EXTRA_DIST = README.html README-WIN32.html config.h.win32 doc json-c.vcproj
-lib_LTLIBRARIES = libjson.la
+lib_LTLIBRARIES = libjson-c.la
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = json.pc
+pkgconfig_DATA = json-c.pc
-libjsonincludedir = $(includedir)/json
+libjsonincludedir = $(includedir)/json-c
libjsoninclude_HEADERS = \
arraylist.h \
bits.h \
@@ -27,9 +27,9 @@ libjsoninclude_HEADERS = \
#libjsonx_include_HEADERS = \
# json_config.h
-libjson_la_LDFLAGS = -version-info 1:0:1 -no-undefined
+libjson_c_la_LDFLAGS = -version-info 1:0:1 -no-undefined
-libjson_la_SOURCES = \
+libjson_c_la_SOURCES = \
arraylist.c \
debug.c \
json_object.c \
@@ -38,7 +38,7 @@ libjson_la_SOURCES = \
linkhash.c \
printbuf.c
-check_PROGRAMS = test1 test2 test4 test_parse_int64 test_null test_cast
+check_PROGRAMS = test1 test2 test4 test_parse_int64 test_null test_cast test_parse
test1_SOURCES = test1.c
test1_LDADD = $(lib_LTLIBRARIES)
@@ -58,11 +58,15 @@ test_null_LDADD = $(lib_LTLIBRARIES)
test_cast_SOURCES = test_cast.c
test_cast_LDADD = $(lib_LTLIBRARIES)
-TESTS = test1.test test2.test test4.test parse_int64.test test_null.test test_cast.test
+test_parse_SOURCES = test_parse.c
+test_parse_LDADD = $(lib_LTLIBRARIES)
+
+TESTS = test1.test test2.test test4.test parse_int64.test test_null.test test_cast.test test_parse.test
EXTRA_DIST += $(TESTS)
testsubdir=testSubDir
TESTS_ENVIRONMENT = top_builddir=$(top_builddir)
distclean-local:
-rm -rf $(testsubdir)
+ -rm -rf config.h.in~ Makefile.in aclocal.m4 autom4te.cache/ config.guess config.sub configure depcomp install-sh ltmain.sh missing
View
2  config.h.win32
@@ -12,7 +12,7 @@
/* config.h.win32 Generated by configure. */
#define PACKAGE_STRING "JSON C Library 0.2"
-#define PACKAGE_BUGREPORT "michael@metaparadigm.com"
+#define PACKAGE_BUGREPORT "json-c@googlegroups.com"
#define PACKAGE_NAME "JSON C Library"
#define PACKAGE_TARNAME "json-c"
#define PACKAGE_VERSION "0.2"
View
4 configure.in
@@ -1,7 +1,7 @@
AC_PREREQ(2.52)
# Process this file with autoconf to produce a configure script.
-AC_INIT([json-c], 0.10, [michael@metaparadigm.com])
+AC_INIT([json-c], 0.10, [json-c@googlegroups.com])
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
@@ -31,5 +31,5 @@ AM_PROG_LIBTOOL
AC_OUTPUT([
Makefile
-json.pc
+json-c.pc
])
View
6 json.pc.in → json-c.pc.in
@@ -3,9 +3,9 @@ exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-Name: json
+Name: json-c
Description: JSON implementation in C
Version: @VERSION@
Requires:
-Libs: -L${libdir} -ljson
-Cflags: -I${includedir}/json
+Libs: -L${libdir} -ljson-c
+Cflags: -I${includedir}/json-c
View
4 json_object.c
@@ -166,11 +166,15 @@ static struct json_object* json_object_new(enum json_type o_type)
int json_object_is_type(struct json_object *jso, enum json_type type)
{
+ if (!jso)
+ return (type == json_type_null);
return (jso->o_type == type);
}
enum json_type json_object_get_type(struct json_object *jso)
{
+ if (!jso)
+ return json_type_null;
return jso->o_type;
}
View
70 json_object.h
@@ -79,6 +79,7 @@ extern void json_object_put(struct json_object *obj);
* Check if the json_object is of a given type
* @param obj the json_object instance
* @param type one of:
+ json_type_null (i.e. obj == NULL),
json_type_boolean,
json_type_double,
json_type_int,
@@ -89,9 +90,12 @@ extern void json_object_put(struct json_object *obj);
extern int json_object_is_type(struct json_object *obj, enum json_type type);
/**
- * Get the type of the json_object
+ * Get the type of the json_object. See also json_type_to_name() to turn this
+ * into a string suitable, for instance, for logging.
+ *
* @param obj the json_object instance
* @returns type being one of:
+ json_type_null (i.e. obj == NULL),
json_type_boolean,
json_type_double,
json_type_int,
@@ -111,7 +115,14 @@ extern const char* json_object_to_json_string(struct json_object *obj);
/* object type methods */
-/** Create a new empty object
+/** Create a new empty object with a reference count of 1. The caller of
+ * this object initially has sole ownership. Remember, when using
+ * json_object_object_add or json_object_array_put_idx, ownership will
+ * transfer to the object/array. Call json_object_get if you want to maintain
+ * shared ownership or also add this object as a child of multiple objects or
+ * arrays. Any ownerships you acquired but did not transfer must be released
+ * through json_object_put.
+ *
* @returns a json_object of type json_type_object
*/
extern struct json_object* json_object_new_object(void);
@@ -126,7 +137,13 @@ extern struct lh_table* json_object_get_object(struct json_object *obj);
*
* The reference count will *not* be incremented. This is to make adding
* fields to objects in code more compact. If you want to retain a reference
- * to an added object you must wrap the passed object with json_object_get
+ * to an added object, independent of the lifetime of obj, you must wrap the
+ * passed object with json_object_get.
+ *
+ * Upon calling this, the ownership of val transfers to obj. Thus you must
+ * make sure that you do in fact have ownership over this object. For instance,
+ * json_object_new_object will give you ownership until you transfer it,
+ * whereas json_object_object_get does not.
*
* @param obj the json_object instance
* @param key the object field name (a private copy will be duplicated)
@@ -136,6 +153,17 @@ extern void json_object_object_add(struct json_object* obj, const char *key,
struct json_object *val);
/** Get the json_object associate with a given object field
+ *
+ * *No* reference counts will be changed. There is no need to manually adjust
+ * reference counts through the json_object_put/json_object_get methods unless
+ * you need to have the child (value) reference maintain a different lifetime
+ * than the owning parent (obj). Ownership of the returned value is retained
+ * by obj (do not do json_object_put unless you have done a json_object_get).
+ * If you delete the value from obj (json_object_object_del) and wish to access
+ * the returned reference afterwards, make sure you have first gotten shared
+ * ownership through json_object_get (& don't forget to do a json_object_put
+ * or transfer ownership to prevent a memory leak).
+ *
* @param obj the json_object instance
* @param key the object field name
* @returns the json_object associated with the given field name
@@ -145,7 +173,9 @@ extern struct json_object* json_object_object_get(struct json_object* obj,
/** Delete the given json_object field
*
- * The reference count will be decremented for the deleted object
+ * The reference count will be decremented for the deleted object. If there
+ * are no more owners of the value represented by this key, then the value is
+ * freed. Otherwise, the reference to the value will remain in memory.
*
* @param obj the json_object instance
* @param key the object field name
@@ -155,7 +185,8 @@ extern void json_object_object_del(struct json_object* obj, const char *key);
/** Iterate through all keys and values of an object
* @param obj the json_object instance
* @param key the local name for the char* key variable defined in the body
- * @param val the local name for the json_object* object variable defined in the body
+ * @param val the local name for the json_object* object variable defined in
+ * the body
*/
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
@@ -289,7 +320,8 @@ extern struct json_object* json_object_new_int64(int64_t i);
*
* The type is coerced to a int if the passed object is not a int.
* double objects will return their integer conversion. Strings will be
- * parsed as an integer. If no conversion exists then 0 is returned.
+ * parsed as an integer. If no conversion exists then 0 is returned
+ * and errno is set to EINVAL. null is equivalent to 0 (no error values set)
*
* Note that integers are stored internally as 64-bit values.
* If the value of too big or too small to fit into 32-bit, INT32_MAX or
@@ -306,6 +338,10 @@ extern int32_t json_object_get_int(struct json_object *obj);
* double objects will return their int64 conversion. Strings will be
* parsed as an int64. If no conversion exists then 0 is returned.
*
+ * NOTE: Set errno to 0 directly before a call to this function to determine
+ * whether or not conversion was successful (it does not clear the value for
+ * you).
+ *
* @param obj the json_object instance
* @returns an int64
*/
@@ -320,14 +356,28 @@ extern int64_t json_object_get_int64(struct json_object *obj);
*/
extern struct json_object* json_object_new_double(double d);
-/** Get the double value of a json_object
+/** Get the double floating point value of a json_object
*
* The type is coerced to a double if the passed object is not a double.
- * integer objects will return their dboule conversion. Strings will be
- * parsed as a double. If no conversion exists then 0.0 is returned.
+ * integer objects will return their double conversion. Strings will be
+ * parsed as a double. If no conversion exists then 0.0 is returned and
+ * errno is set to EINVAL. null is equivalent to 0 (no error values set)
+ *
+ * If the value is too big to fit in a double, then the value is set to
+ * the closest infinity with errno set to ERANGE. If strings cannot be
+ * converted to their double value, then EINVAL is set & NaN is returned.
+ *
+ * Arrays of length 0 are interpreted as 0 (with no error flags set).
+ * Arrays of length 1 are effectively cast to the equivalent object and
+ * converted using the above rules. All other arrays set the error to
+ * EINVAL & return NaN.
+ *
+ * NOTE: Set errno to 0 directly before a call to this function to
+ * determine whether or not conversion was successful (it does not clear
+ * the value for you).
*
* @param obj the json_object instance
- * @returns an double
+ * @returns a double floating point number
*/
extern double json_object_get_double(struct json_object *obj);
View
33 json_tokener.c
@@ -47,7 +47,7 @@ static const char* json_false_str = "false";
const char* json_tokener_errors[] = {
"success",
"continue",
- "nesting to deep",
+ "nesting too deep",
"unexpected end of data",
"unexpected character",
"null expected",
@@ -122,17 +122,10 @@ void json_tokener_reset(struct json_tokener *tok)
struct json_object* json_tokener_parse(const char *str)
{
- struct json_tokener* tok;
- struct json_object* obj;
-
- tok = json_tokener_new();
- if (!tok)
- return NULL;
- obj = json_tokener_parse_ex(tok, str, -1);
- if(tok->err != json_tokener_success)
- obj = NULL;
- json_tokener_free(tok);
- return obj;
+ enum json_tokener_error jerr_ignored;
+ struct json_object* obj;
+ obj = json_tokener_parse_verbose(str, &jerr_ignored);
+ return obj;
}
struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
@@ -141,9 +134,13 @@ struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokene
struct json_object* obj;
tok = json_tokener_new();
+ if (!tok)
+ return NULL;
obj = json_tokener_parse_ex(tok, str, -1);
*error = tok->err;
if(tok->err != json_tokener_success) {
+ if (obj != NULL)
+ json_object_put(obj);
obj = NULL;
}
@@ -718,7 +715,17 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
tok->err = json_tokener_error_parse_eof;
}
- if(tok->err == json_tokener_success) return json_object_get(current);
+ if (tok->err == json_tokener_success)
+ {
+ json_object *ret = json_object_get(current);
+ int ii;
+
+ /* Partially reset, so we parse additional objects on subsequent calls. */
+ for(ii = tok->depth; ii >= 0; ii--)
+ json_tokener_reset_level(tok, ii);
+ return ret;
+ }
+
MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n",
json_tokener_errors[tok->err], tok->char_offset);
return NULL;
View
6 json_tokener.h
@@ -88,13 +88,13 @@ struct json_tokener
*
* @return a generic error message is returned if an invalid error value is provided.
*/
-const char *json_tokeners_errors(enum json_tokener_error jerr);
+const char *json_tokener_error_desc(enum json_tokener_error jerr);
/**
* @b XXX do not use json_tokener_errors directly.
* After v0.10 this will be removed.
*
- * See json_tokeners_errors() instead.
+ * See json_tokener_error_desc() instead.
*/
extern const char* json_tokener_errors[];
@@ -162,7 +162,7 @@ do {
} while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
if (jerr != json_tokener_success)
{
- fprintf(stderr, "Error: %s\n", json_tokener_errors[jerr]);
+ fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
// Handle errors, as appropriate for your application.
}
if (tok->char_offset < stringlen) // XXX shouldn't access internal fields
View
2  linkhash.c
@@ -125,7 +125,7 @@ int lh_table_insert(struct lh_table *t, void *k, const void *v)
unsigned long h, n;
t->inserts++;
- if(t->count > t->size * 0.66) lh_table_resize(t, t->size * 2);
+ if(t->count >= t->size * LH_LOAD_FACTOR) lh_table_resize(t, t->size * 2);
h = t->hash_fn(k);
n = h % t->size;
View
7 linkhash.h
@@ -22,6 +22,13 @@ extern "C" {
#define LH_PRIME 0x9e370001UL
/**
+ * The fraction of filled hash buckets until an insert will cause the table
+ * to be resized.
+ * This can range from just above 0 up to 1.0.
+ */
+#define LH_LOAD_FACTOR 0.66
+
+/**
* sentinel pointer value for empty slots
*/
#define LH_EMPTY (void*)-1
View
63 printbuf.c
@@ -29,6 +29,8 @@
#include "debug.h"
#include "printbuf.h"
+static int printbuf_extend(struct printbuf *p, int min_size);
+
struct printbuf* printbuf_new(void)
{
struct printbuf *p;
@@ -45,19 +47,40 @@ struct printbuf* printbuf_new(void)
}
-int printbuf_memappend(struct printbuf *p, const char *buf, int size)
+/**
+ * Extend the buffer p so it has a size of at least min_size.
+ *
+ * If the current size is large enough, nothing is changed.
+ *
+ * Note: this does not check the available space! The caller
+ * is responsible for performing those calculations.
+ */
+static int printbuf_extend(struct printbuf *p, int min_size)
{
- char *t;
- if(p->size - p->bpos <= size) {
- int new_size = json_max(p->size * 2, p->bpos + size + 8);
+ char *t;
+ int new_size;
+
+ if (p->size >= min_size)
+ return 0;
+
+ new_size = json_max(p->size * 2, min_size + 8);
#ifdef PRINTBUF_DEBUG
- MC_DEBUG("printbuf_memappend: realloc "
- "bpos=%d wrsize=%d old_size=%d new_size=%d\n",
- p->bpos, size, p->size, new_size);
+ MC_DEBUG("printbuf_memappend: realloc "
+ "bpos=%d min_size=%d old_size=%d new_size=%d\n",
+ p->bpos, min_size, p->size, new_size);
#endif /* PRINTBUF_DEBUG */
- if(!(t = (char*)realloc(p->buf, new_size))) return -1;
- p->size = new_size;
- p->buf = t;
+ if(!(t = (char*)realloc(p->buf, new_size)))
+ return -1;
+ p->size = new_size;
+ p->buf = t;
+ return 0;
+}
+
+int printbuf_memappend(struct printbuf *p, const char *buf, int size)
+{
+ if (p->size <= p->bpos + size + 1) {
+ if (printbuf_extend(p, p->bpos + size + 1) < 0)
+ return -1;
}
memcpy(p->buf + p->bpos, buf, size);
p->bpos += size;
@@ -65,6 +88,26 @@ int printbuf_memappend(struct printbuf *p, const char *buf, int size)
return size;
}
+int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
+{
+ int size_needed;
+
+ if (offset == -1)
+ offset = pb->bpos;
+ size_needed = offset + len;
+ if (pb->size < size_needed)
+ {
+ if (printbuf_extend(pb, size_needed) < 0)
+ return -1;
+ }
+
+ memset(pb->buf + offset, charvalue, len);
+ if (pb->bpos < size_needed)
+ pb->bpos = size_needed;
+
+ return 0;
+}
+
#if !HAVE_VSNPRINTF && defined(_MSC_VER)
# define vsnprintf _vsnprintf
#elif !HAVE_VSNPRINTF /* !HAVE_VSNPRINTF */
View
15 printbuf.h
@@ -20,8 +20,6 @@
extern "C" {
#endif
-#undef PRINTBUF_DEBUG
-
struct printbuf {
char *buf;
int bpos;
@@ -50,6 +48,19 @@ do { \
} else { printbuf_memappend(p, (bufptr), bufsize); } \
} while (0)
+#define printbuf_length(p) ((p)->bpos)
+
+/**
+ * Set len bytes of the buffer to charvalue, starting at offset offset.
+ * Similar to calling memset(x, charvalue, len);
+ *
+ * The memory allocated for the buffer is extended as necessary.
+ *
+ * If offset is -1, this starts at the end of the current data in the buffer.
+ */
+extern int
+printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len);
+
extern int
sprintbuf(struct printbuf *p, const char *msg, ...);
View
108 test1.c
@@ -31,9 +31,7 @@ static int sort_fn (const void *j1, const void *j2)
int main(int argc, char **argv)
{
- json_tokener *tok;
json_object *my_string, *my_int, *my_object, *my_array;
- json_object *new_obj;
int i;
MC_SET_DEBUG(1);
@@ -104,112 +102,6 @@ int main(int argc, char **argv)
}
printf("my_object.to_string()=%s\n", json_object_to_json_string(my_object));
- new_obj = json_tokener_parse("\"\003\"");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("/* hello */\"foo\"");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("// hello\n\"foo\"");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("\"\\u0041\\u0042\\u0043\"");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("null");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("True");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("12");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("12.3");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("[\"\\n\"]");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("[\"\\nabc\\n\"]");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("[null]");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("[]");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("[false]");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("[\"abc\",null,\"def\",12]");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("{}");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("{ \"foo\": \"bar\" }");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("{ \"foo\": [null, \"foo\"] }");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- new_obj = json_tokener_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }");
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
-
- enum json_tokener_error error = json_tokener_success;
- new_obj = json_tokener_parse_verbose("{ foo }", &error);
- assert (error == json_tokener_error_parse_object_key_name);
- assert (new_obj == NULL);
-
- new_obj = json_tokener_parse("{ foo }");
- assert (new_obj == NULL);
-
- // if(is_error(new_obj)) printf("got error as expected\n");
-
- new_obj = json_tokener_parse("foo");
- assert (new_obj == NULL);
- new_obj = json_tokener_parse_verbose("foo", &error);
- assert (new_obj == NULL);
- assert (error == json_tokener_error_parse_boolean);
-
- new_obj = json_tokener_parse("{ \"foo");
- if(is_error(new_obj)) printf("got error as expected\n");
-
- /* test incremental parsing */
- tok = json_tokener_new();
- new_obj = json_tokener_parse_ex(tok, "{ \"foo", 6);
- if(is_error(new_obj)) printf("got error as expected\n");
- new_obj = json_tokener_parse_ex(tok, "\": {\"bar", 8);
- if(is_error(new_obj)) printf("got error as expected\n");
- new_obj = json_tokener_parse_ex(tok, "\":13}}", 6);
- printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
- json_object_put(new_obj);
- json_tokener_free(tok);
-
json_object_put(my_string);
json_object_put(my_int);
json_object_put(my_object);
View
23 test1.expected
@@ -33,26 +33,3 @@ my_object=
bool0: false
bool1: true
my_object.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true }
-new_obj.to_string()="\u0003"
-new_obj.to_string()="foo"
-new_obj.to_string()="foo"
-new_obj.to_string()="ABC"
-new_obj.to_string()=null
-new_obj.to_string()=true
-new_obj.to_string()=12
-new_obj.to_string()=12.300000
-new_obj.to_string()=[ "\n" ]
-new_obj.to_string()=[ "\nabc\n" ]
-new_obj.to_string()=[ null ]
-new_obj.to_string()=[ ]
-new_obj.to_string()=[ false ]
-new_obj.to_string()=[ "abc", null, "def", 12 ]
-new_obj.to_string()={ }
-new_obj.to_string()={ "foo": "bar" }
-new_obj.to_string()={ "foo": "bar", "baz": null, "bool0": true }
-new_obj.to_string()={ "foo": [ null, "foo" ] }
-new_obj.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "arr": [ 1, 2, 3, null, 5 ] }
-got error as expected
-got error as expected
-got error as expected
-new_obj.to_string()={ "foo": { "bar": 13 } }
View
42 test_cast.c
@@ -1,5 +1,6 @@
/*
* Tests if casting within the json_object_get_* functions work correctly.
+ * Also checks the json_object_get_type and json_object_is_type functions.
*/
#include <stdio.h>
@@ -13,6 +14,8 @@
#include "json_util.h"
static void getit(struct json_object *new_obj, const char *field);
+static void checktype_header(void);
+static void checktype(struct json_object *new_obj, const char *field);
int main(int argc, char **argv)
{
@@ -23,6 +26,7 @@ int main(int argc, char **argv)
\"boolean_true\": true,\n\
\"boolean_false\": false,\n\
\"big_number\": 2147483649,\n\
+ \"a_null\": null,\n\
}";
/* Note: 2147483649 = INT_MAX + 2 */
@@ -40,6 +44,19 @@ int main(int argc, char **argv)
getit(new_obj, "boolean_true");
getit(new_obj, "boolean_false");
getit(new_obj, "big_number");
+ getit(new_obj, "a_null");
+
+ // Now check the behaviour of the json_object_is_type() function.
+ printf("\n================================\n");
+ checktype_header();
+ checktype(new_obj, NULL);
+ checktype(new_obj, "string_of_digits");
+ checktype(new_obj, "regular_number");
+ checktype(new_obj, "decimal_number");
+ checktype(new_obj, "boolean_true");
+ checktype(new_obj, "boolean_false");
+ checktype(new_obj, "big_number");
+ checktype(new_obj, "a_null");
json_object_put(new_obj);
@@ -62,3 +79,28 @@ static void getit(struct json_object *new_obj, const char *field)
printf("new_obj.%s json_object_get_double()=%f\n", field,
json_object_get_double(o));
}
+
+static void checktype_header()
+{
+ printf("json_object_is_type: %s,%s,%s,%s,%s,%s,%s\n",
+ json_type_to_name(json_type_null),
+ json_type_to_name(json_type_boolean),
+ json_type_to_name(json_type_double),
+ json_type_to_name(json_type_int),
+ json_type_to_name(json_type_object),
+ json_type_to_name(json_type_array),
+ json_type_to_name(json_type_string));
+}
+static void checktype(struct json_object *new_obj, const char *field)
+{
+ struct json_object *o = field ? json_object_object_get(new_obj, field) : new_obj;
+ printf("new_obj%s%-18s: %d,%d,%d,%d,%d,%d,%d\n",
+ field ? "." : " ", field ? field : "",
+ json_object_is_type(o, json_type_null),
+ json_object_is_type(o, json_type_boolean),
+ json_object_is_type(o, json_type_double),
+ json_object_is_type(o, json_type_int),
+ json_object_is_type(o, json_type_object),
+ json_object_is_type(o, json_type_array),
+ json_object_is_type(o, json_type_string));
+}
View
17 test_cast.expected
@@ -5,6 +5,7 @@ Parsed input: {
"boolean_true": true,
"boolean_false": false,
"big_number": 2147483649,
+ "a_null": null,
}
Result is not NULL
new_obj.string_of_digits json_object_get_type()=string
@@ -37,3 +38,19 @@ new_obj.big_number json_object_get_int()=2147483647
new_obj.big_number json_object_get_int64()=2147483649
new_obj.big_number json_object_get_boolean()=1
new_obj.big_number json_object_get_double()=2147483649.000000
+new_obj.a_null json_object_get_type()=null
+new_obj.a_null json_object_get_int()=0
+new_obj.a_null json_object_get_int64()=0
+new_obj.a_null json_object_get_boolean()=0
+new_obj.a_null json_object_get_double()=0.000000
+
+================================
+json_object_is_type: null,boolean,double,int,object,array,string
+new_obj : 0,0,0,0,1,0,0
+new_obj.string_of_digits : 0,0,0,0,0,0,1
+new_obj.regular_number : 0,0,0,1,0,0,0
+new_obj.decimal_number : 0,0,1,0,0,0,0
+new_obj.boolean_true : 0,1,0,0,0,0,0
+new_obj.boolean_false : 0,1,0,0,0,0,0
+new_obj.big_number : 0,0,0,1,0,0,0
+new_obj.a_null : 1,0,0,0,0,0,0
View
270 test_parse.c
@@ -0,0 +1,270 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+
+#include "json.h"
+#include "json_tokener.h"
+
+static void test_basic_parse(void);
+static void test_verbose_parse(void);
+static void test_incremental_parse(void);
+
+int main(int argc, char **argv)
+{
+ MC_SET_DEBUG(1);
+
+ test_basic_parse();
+ printf("==================================\n");
+ test_verbose_parse();
+ printf("==================================\n");
+ test_incremental_parse();
+ printf("==================================\n");
+}
+
+static void test_basic_parse()
+{
+ json_object *new_obj;
+
+ new_obj = json_tokener_parse("\"\003\"");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("/* hello */\"foo\"");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("// hello\n\"foo\"");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("\"\\u0041\\u0042\\u0043\"");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("null");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("True");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("12");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("12.3");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[\"\\n\"]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[\"\\nabc\\n\"]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[null]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[false]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[\"abc\",null,\"def\",12]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{}");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{ \"foo\": \"bar\" }");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{ \"foo\": [null, \"foo\"] }");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+}
+
+static void test_verbose_parse()
+{
+ json_object *new_obj;
+ enum json_tokener_error error = json_tokener_success;
+
+ new_obj = json_tokener_parse_verbose("{ foo }", &error);
+ assert (error == json_tokener_error_parse_object_key_name);
+ assert (new_obj == NULL);
+
+ new_obj = json_tokener_parse("{ foo }");
+ assert (new_obj == NULL);
+
+ new_obj = json_tokener_parse("foo");
+ assert (new_obj == NULL);
+ new_obj = json_tokener_parse_verbose("foo", &error);
+ assert (new_obj == NULL);
+
+ /* b/c the string starts with 'f' parsing return a boolean error */
+ assert (error == json_tokener_error_parse_boolean);
+
+ printf("json_tokener_parse_versbose() OK\n");
+}
+
+struct incremental_step {
+ const char *string_to_parse;
+ int length;
+ int char_offset;
+ enum json_tokener_error expected_error;
+ int reset_tokener;
+} incremental_steps[] = {
+
+ /* Check that full json messages can be parsed, both w/ and w/o a reset */
+ { "{ \"foo\": 123 }", -1, -1, json_tokener_success, 0 },
+ { "{ \"foo\": 456 }", -1, -1, json_tokener_success, 1 },
+ { "{ \"foo\": 789 }", -1, -1, json_tokener_success, 1 },
+
+ /* Check a basic incremental parse */
+ { "{ \"foo", -1, -1, json_tokener_continue, 0 },
+ { "\": {\"bar", -1, -1, json_tokener_continue, 0 },
+ { "\":13}}", -1, -1, json_tokener_success, 1 },
+
+ /* Check that json_tokener_reset actually resets */
+ { "{ \"foo", -1, -1, json_tokener_continue, 1 },
+ { ": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1 },
+
+ /* Check incremental parsing with trailing characters */
+ { "{ \"foo", -1, -1, json_tokener_continue, 0 },
+ { "\": {\"bar", -1, -1, json_tokener_continue, 0 },
+ { "\":13}}XXXX", 10, 6, json_tokener_success, 0 },
+ { "XXXX", 4, 0, json_tokener_error_parse_unexpected, 1 },
+
+ /* Check that trailing characters can change w/o a reset */
+ { "{\"x\": 123 }\"X\"", -1, 11, json_tokener_success, 0 },
+ { "\"Y\"", -1, -1, json_tokener_success, 1 },
+
+ /* To stop parsing a number we need to reach a non-digit, e.g. a \0 */
+ { "1", 1, 1, json_tokener_continue, 0 },
+ { "2", 2, 1, json_tokener_success, 0 },
+
+ /* Strings have a well defined end point, so we can stop at the quote */
+ { "\"blue\"", -1, -1, json_tokener_success, 0 },
+
+ { "[1,2,3]", -1, -1, json_tokener_success, 0 },
+
+ /* This behaviour doesn't entirely follow the json spec, but until we have
+ a way to specify how strict to be we follow Postel's Law and be liberal
+ in what we accept (up to a point). */
+ { "[1,2,3,]", -1, -1, json_tokener_success, 0 },
+ { "[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0 },
+
+ { NULL, json_tokener_success },
+};
+
+static void test_incremental_parse()
+{
+ json_object *new_obj;
+ enum json_tokener_error jerr;
+ json_tokener *tok;
+ const char *string_to_parse;
+ int ii;
+ int num_ok, num_error;
+
+ num_ok = 0;
+ num_error = 0;
+
+ printf("Starting incremental tests.\n");
+
+ string_to_parse = "{ \"foo"; /* } */
+ printf("json_tokener_parse(%s) ... ", string_to_parse);
+ new_obj = json_tokener_parse(string_to_parse);
+ if (new_obj == NULL) printf("got error as expected\n");
+
+ /* test incremental parsing in various forms */
+ tok = json_tokener_new();
+ for (ii = 0; incremental_steps[ii].string_to_parse != NULL; ii++)
+ {
+ int this_step_ok = 0;
+ struct incremental_step *step = &incremental_steps[ii];
+ int length = step->length;
+ int expected_char_offset = step->char_offset;
+ if (length == -1)
+ length = strlen(step->string_to_parse);
+ if (expected_char_offset == -1)
+ expected_char_offset = length;
+
+ printf("json_tokener_parse_ex(tok, %-12s, %3d) ... ",
+ step->string_to_parse, length);
+ new_obj = json_tokener_parse_ex(tok, step->string_to_parse, length);
+
+ jerr = json_tokener_get_error(tok);
+ if (step->expected_error != json_tokener_success)
+ {
+ if (new_obj != NULL)
+ printf("ERROR: invalid object returned: %s\n",
+ json_object_to_json_string(new_obj));
+ else if (jerr != step->expected_error)
+ printf("ERROR: got wrong error: %s\n",
+ json_tokener_error_desc(jerr));
+ else if (tok->char_offset != expected_char_offset)
+ printf("ERROR: wrong char_offset %d != expected %d\n",
+ tok->char_offset,
+ expected_char_offset);
+ else
+ {
+ printf("OK: got correct error: %s\n", json_tokener_error_desc(jerr));
+ this_step_ok = 1;
+ }
+ }
+ else
+ {
+ if (new_obj == NULL)
+ printf("ERROR: expected valid object, instead: %s\n",
+ json_tokener_error_desc(jerr));
+ else if (tok->char_offset != expected_char_offset)
+ printf("ERROR: wrong char_offset %d != expected %d\n",
+ tok->char_offset,
+ expected_char_offset);
+ else
+ {
+ printf("OK: got object of type [%s]: %s\n",
+ json_type_to_name(json_object_get_type(new_obj)),
+ json_object_to_json_string(new_obj));
+ this_step_ok = 1;
+ }
+ }
+
+ if (new_obj)
+ json_object_put(new_obj);
+
+ if (step->reset_tokener)
+ json_tokener_reset(tok);
+
+ if (this_step_ok)
+ num_ok++;
+ else
+ num_error++;
+ }
+
+ json_tokener_free(tok);
+
+ printf("End Incremental Tests OK=%d ERROR=%d\n", num_ok, num_error);
+
+ return;
+}
View
46 test_parse.expected
@@ -0,0 +1,46 @@
+new_obj.to_string()="\u0003"
+new_obj.to_string()="foo"
+new_obj.to_string()="foo"
+new_obj.to_string()="ABC"
+new_obj.to_string()=null
+new_obj.to_string()=true
+new_obj.to_string()=12
+new_obj.to_string()=12.300000
+new_obj.to_string()=[ "\n" ]
+new_obj.to_string()=[ "\nabc\n" ]
+new_obj.to_string()=[ null ]
+new_obj.to_string()=[ ]
+new_obj.to_string()=[ false ]
+new_obj.to_string()=[ "abc", null, "def", 12 ]
+new_obj.to_string()={ }
+new_obj.to_string()={ "foo": "bar" }
+new_obj.to_string()={ "foo": "bar", "baz": null, "bool0": true }
+new_obj.to_string()={ "foo": [ null, "foo" ] }
+new_obj.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "arr": [ 1, 2, 3, null, 5 ] }
+==================================
+json_tokener_parse_versbose() OK
+==================================
+Starting incremental tests.
+json_tokener_parse({ "foo) ... got error as expected
+json_tokener_parse_ex(tok, { "foo": 123 }, 14) ... OK: got object of type [object]: { "foo": 123 }
+json_tokener_parse_ex(tok, { "foo": 456 }, 14) ... OK: got object of type [object]: { "foo": 456 }
+json_tokener_parse_ex(tok, { "foo": 789 }, 14) ... OK: got object of type [object]: { "foo": 789 }
+json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, ": {"bar , 8) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, ":13}} , 6) ... OK: got object of type [object]: { "foo": { "bar": 13 } }
+json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, : "bar"} , 8) ... OK: got correct error: unexpected character
+json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, ": {"bar , 8) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, ":13}}XXXX , 10) ... OK: got object of type [object]: { "foo": { "bar": 13 } }
+json_tokener_parse_ex(tok, XXXX , 4) ... OK: got correct error: unexpected character
+json_tokener_parse_ex(tok, {"x": 123 }"X", 14) ... OK: got object of type [object]: { "x": 123 }
+json_tokener_parse_ex(tok, "Y" , 3) ... OK: got object of type [string]: "Y"
+json_tokener_parse_ex(tok, 1 , 1) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, 2 , 2) ... OK: got object of type [int]: 12
+json_tokener_parse_ex(tok, "blue" , 6) ... OK: got object of type [string]: "blue"
+json_tokener_parse_ex(tok, [1,2,3] , 7) ... OK: got object of type [array]: [ 1, 2, 3 ]
+json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got object of type [array]: [ 1, 2, 3 ]
+json_tokener_parse_ex(tok, [1,2,,3,] , 9) ... OK: got correct error: unexpected character
+End Incremental Tests OK=20 ERROR=0
+==================================
View
12 test_parse.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test_parse
+exit $?
Something went wrong with that request. Please try again.