diff --git a/3party/jansson/CHANGES b/3party/jansson/CHANGES index 73d149c482..d68018b20d 100644 --- a/3party/jansson/CHANGES +++ b/3party/jansson/CHANGES @@ -1,8 +1,76 @@ +Version 2.0 +=========== + +Released 2011-02-28 + +This release is backwards incompatible with the 1.x release series. +See the chapter "Upgrading from older versions" in documentation for +details. + +* Backwards incompatible changes: + + - Unify unsigned integer usage in the API: All occurences of + unsigned int and unsigned long have been replaced with size_t. + + - Change JSON integer's underlying type to the widest signed integer + type available, i.e. long long if it's supported, otherwise long. + Add a typedef json_int_t that defines the type. + + - Change the maximum indentation depth to 31 spaces in encoder. This + frees up bits from the flags parameter of encoding functions + `json_dumpf()`, `json_dumps()` and `json_dump_file()`. + + - For future needs, add a flags parameter to all decoding functions + `json_loadf()`, `json_loads()` and `json_load_file()`. + +* New features + + - `json_pack()`, `json_pack_ex()`, `json_vpack_ex()`: Create JSON + values based on a format string. + + - `json_unpack()`, `json_unpack_ex()`, `json_vunpack_ex()`: Simple + value extraction and validation functionality based on a format + string. + + - Add column, position and source fields to the ``json_error_t`` + struct. + + - Enhance error reporting in the decoder. + + - ``JANSSON_VERSION`` et al.: Preprocessor constants that define the + library version. + + - `json_set_alloc_funcs()`: Set custom memory allocation functions. + +* Fix many portability issues, especially on Windows. + +* Configuration + + - Add file ``jansson_config.h`` that contains site specific + configuration. It's created automatically by the configure script, + or can be created by hand if the configure script cannot be used. + The file ``jansson_config.h.win32`` can be used without + modifications on Windows systems. + + - Add a section to documentation describing how to build Jansson on + Windows. + + - Documentation now requires Sphinx 1.0 or newer. + + Version 1.3 =========== Released 2010-06-13 +* New functions: + + - `json_object_iter_set()`, `json_object_iter_set_new()`: Change + object contents while iterating over it. + + - `json_object_iter_at()`: Return an iterator that points to a + specific object item. + * New encoding flags: - ``JSON_PRESERVE_ORDER``: Preserve the insertion order of object diff --git a/3party/jansson/LICENSE b/3party/jansson/LICENSE index 552b3498b0..6d70a1b350 100644 --- a/3party/jansson/LICENSE +++ b/3party/jansson/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009, 2010 Petri Lehtinen +Copyright (c) 2009-2011 Petri Lehtinen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/3party/jansson/README.rst b/3party/jansson/README.rst index 27706dd5a7..cbb171f56c 100644 --- a/3party/jansson/README.rst +++ b/3party/jansson/README.rst @@ -24,7 +24,13 @@ Compilation and Installation If you obtained a source tarball, just use the standard autotools commands:: - $ ./configure && make && make install + $ ./configure + $ make + $ make install + +To run the test suite, invoke:: + + $ make check If the source has been checked out from a Git repository, the ./configure script has to be generated fist. The easiest way is to use @@ -32,28 +38,22 @@ autoreconf:: $ autoreconf -i -To run the test suite, invoke:: - - $ make check - Documentation ------------- -Documentation is in the ``doc/`` subdirectory. It's written in -reStructuredText_ with Sphinx_ annotations, so reading it in plain may -be inconvenient. For this reason, prebuilt HTML documentation is -available at http://www.digip.org/jansson/doc/. +Prebuilt HTML documentation is available at +http://www.digip.org/jansson/doc/. -To generate HTML documentation yourself, invoke:: +The documentation source is in the ``doc/`` subdirectory. To generate +HTML documentation, invoke:: - make html + $ make html -and point your browser to ``doc/_build/html/index.html``. Sphinx_ is -required to generate the documentation. +Then, point your browser to ``doc/_build/html/index.html``. Sphinx_ +1.0 or newer is required to generate the documentation. .. _Jansson: http://www.digip.org/jansson/ .. _`MIT license`: http://www.opensource.org/licenses/mit-license.php -.. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _Sphinx: http://sphinx.pocoo.org/ diff --git a/3party/jansson/jansson.pro b/3party/jansson/jansson.pro index 563aa63be2..b2a89a859e 100644 --- a/3party/jansson/jansson.pro +++ b/3party/jansson/jansson.pro @@ -5,18 +5,20 @@ include($$ROOT_DIR/common.pri) TEMPLATE = lib CONFIG += staticlib SOURCES += \ - src/dump.c \ - src/hashtable.c \ - src/load.c \ - src/strbuffer.c \ - src/utf.c \ - src/value.c \ + src/dump.c \ + src/hashtable.c \ + src/load.c \ + src/strbuffer.c \ + src/utf.c \ + src/value.c \ + src/memory.c \ + src/error.c \ HEADERS += \ - myjansson.hpp \ - src/jansson.h \ - src/jansson_private.h \ - src/hashtable.h \ - src/strbuffer.h \ - src/utf.h \ - src/util.h \ + myjansson.hpp \ + src/jansson.h \ + src/jansson_private.h \ + src/hashtable.h \ + src/strbuffer.h \ + src/utf.h \ + src/util.h \ diff --git a/3party/jansson/myjansson.hpp b/3party/jansson/myjansson.hpp index 4c040266b3..8640211024 100644 --- a/3party/jansson/myjansson.hpp +++ b/3party/jansson/myjansson.hpp @@ -17,7 +17,7 @@ public: explicit Json(char const * s) { json_error_t jsonError; - m_pJson = json_loads(s, &jsonError); + m_pJson = json_loads(s, 0, &jsonError); if (!m_pJson) MYTHROW(Exception, (jsonError.line, jsonError.text)); } diff --git a/3party/jansson/src/dump.c b/3party/jansson/src/dump.c index a2bc10b446..850a708190 100644 --- a/3party/jansson/src/dump.c +++ b/3party/jansson/src/dump.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * Jansson is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. @@ -46,10 +46,10 @@ static int dump_to_file(const char *buffer, int size, void *data) return 0; } -/* 256 spaces (the maximum indentation size) */ -static char whitespace[] = " "; +/* 32 spaces (the maximum indentation size) */ +static char whitespace[] = " "; -static int dump_indent(unsigned long flags, int depth, int space, dump_func dump, void *data) +static int dump_indent(size_t flags, int depth, int space, dump_func dump, void *data) { if(JSON_INDENT(flags) > 0) { @@ -170,7 +170,7 @@ static int object_key_compare_serials(const void *key1, const void *key2) (*(const object_key_t **)key2)->serial; } -static int do_dump(const json_t *json, unsigned long flags, int depth, +static int do_dump(const json_t *json, size_t flags, int depth, dump_func dump, void *data) { int ascii = flags & JSON_ENSURE_ASCII ? 1 : 0; @@ -190,7 +190,9 @@ static int do_dump(const json_t *json, unsigned long flags, int depth, char buffer[MAX_INTEGER_STR_LENGTH]; int size; - size = snprintf(buffer, MAX_INTEGER_STR_LENGTH, "%d", json_integer_value(json)); + size = snprintf(buffer, MAX_INTEGER_STR_LENGTH, + "%" JSON_INTEGER_FORMAT, + json_integer_value(json)); if(size >= MAX_INTEGER_STR_LENGTH) return -1; @@ -312,12 +314,11 @@ static int do_dump(const json_t *json, unsigned long flags, int depth, if(flags & JSON_SORT_KEYS || flags & JSON_PRESERVE_ORDER) { object_key_t **keys; - unsigned int size; - unsigned int i; + size_t size, i; int (*cmp_func)(const void *, const void *); size = json_object_size(json); - keys = malloc(size * sizeof(object_key_t *)); + keys = jsonp_malloc(size * sizeof(object_key_t *)); if(!keys) goto object_error; @@ -350,7 +351,7 @@ static int do_dump(const json_t *json, unsigned long flags, int depth, if(dump(separator, separator_length, data) || do_dump(value, flags, depth + 1, dump, data)) { - free(keys); + jsonp_free(keys); goto object_error; } @@ -359,7 +360,7 @@ static int do_dump(const json_t *json, unsigned long flags, int depth, if(dump(",", 1, data) || dump_indent(flags, depth + 1, 1, dump, data)) { - free(keys); + jsonp_free(keys); goto object_error; } } @@ -367,13 +368,13 @@ static int do_dump(const json_t *json, unsigned long flags, int depth, { if(dump_indent(flags, depth, 0, dump, data)) { - free(keys); + jsonp_free(keys); goto object_error; } } } - free(keys); + jsonp_free(keys); } else { @@ -420,7 +421,7 @@ static int do_dump(const json_t *json, unsigned long flags, int depth, } -char *json_dumps(const json_t *json, unsigned long flags) +char *json_dumps(const json_t *json, size_t flags) { strbuffer_t strbuff; char *result; @@ -436,13 +437,13 @@ char *json_dumps(const json_t *json, unsigned long flags) return NULL; } - result = strdup(strbuffer_value(&strbuff)); + result = jsonp_strdup(strbuffer_value(&strbuff)); strbuffer_close(&strbuff); return result; } -int json_dumpf(const json_t *json, FILE *output, unsigned long flags) +int json_dumpf(const json_t *json, FILE *output, size_t flags) { if(!json_is_array(json) && !json_is_object(json)) return -1; @@ -450,7 +451,7 @@ int json_dumpf(const json_t *json, FILE *output, unsigned long flags) return do_dump(json, flags, 0, dump_to_file, (void *)output); } -int json_dump_file(const json_t *json, const char *path, unsigned long flags) +int json_dump_file(const json_t *json, const char *path, size_t flags) { int result; diff --git a/3party/jansson/src/error.c b/3party/jansson/src/error.c new file mode 100644 index 0000000000..074a68e098 --- /dev/null +++ b/3party/jansson/src/error.c @@ -0,0 +1,60 @@ +#include +#include "jansson_private.h" + +void jsonp_error_init(json_error_t *error, const char *source) +{ + if(error) + { + error->text[0] = '\0'; + error->line = -1; + error->column = -1; + error->position = 0; + if(source) + jsonp_error_set_source(error, source); + else + error->source[0] = '\0'; + } +} + +void jsonp_error_set_source(json_error_t *error, const char *source) +{ + if(!error || !source) + return; + + size_t length = strlen(source); + if(length < JSON_ERROR_SOURCE_LENGTH) + strcpy(error->source, source); + else { + size_t extra = length - JSON_ERROR_SOURCE_LENGTH + 4; + strcpy(error->source, "..."); + strcpy(error->source + 3, source + extra); + } +} + +void jsonp_error_set(json_error_t *error, int line, int column, + size_t position, const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + jsonp_error_vset(error, line, column, position, msg, ap); + va_end(ap); +} + +void jsonp_error_vset(json_error_t *error, int line, int column, + size_t position, const char *msg, va_list ap) +{ + if(!error) + return; + + if(error->text[0] != '\0') { + /* error already set */ + return; + } + + error->line = line; + error->column = column; + error->position = position; + + vsnprintf(error->text, JSON_ERROR_TEXT_LENGTH, msg, ap); +} diff --git a/3party/jansson/src/hashtable.c b/3party/jansson/src/hashtable.c index 44d2ccea4d..4f0bf8b641 100644 --- a/3party/jansson/src/hashtable.c +++ b/3party/jansson/src/hashtable.c @@ -1,31 +1,28 @@ /* - * Copyright (c) 2009, 2010 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * This library is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. */ -#include "config.h" - #include +//#include /* for inline */ +#include "jansson_private.h" /* for container_of() */ #include "hashtable.h" typedef struct hashtable_list list_t; typedef struct hashtable_pair pair_t; typedef struct hashtable_bucket bucket_t; -#define container_of(ptr_, type_, member_) \ - ((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_)) - #define list_to_pair(list_) container_of(list_, pair_t, list) -static JSON_INLINE void list_init(list_t *list) +static inline void list_init(list_t *list) { list->next = list; list->prev = list; } -static JSON_INLINE void list_insert(list_t *list, list_t *node) +static inline void list_insert(list_t *list, list_t *node) { node->next = list; node->prev = list->prev; @@ -33,13 +30,13 @@ static JSON_INLINE void list_insert(list_t *list, list_t *node) list->prev = node; } -static JSON_INLINE void list_remove(list_t *list) +static inline void list_remove(list_t *list) { list->prev->next = list->next; list->next->prev = list->prev; } -static JSON_INLINE int bucket_is_empty(hashtable_t *hashtable, bucket_t *bucket) +static inline int bucket_is_empty(hashtable_t *hashtable, bucket_t *bucket) { return bucket->first == &hashtable->list && bucket->first == bucket->last; } @@ -59,22 +56,22 @@ static void insert_to_bucket(hashtable_t *hashtable, bucket_t *bucket, } } -static unsigned int primes[] = { +static size_t primes[] = { 5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741 }; -static const unsigned int num_primes = sizeof(primes) / sizeof(unsigned int); +static const size_t num_primes = sizeof(primes) / sizeof(size_t); -static JSON_INLINE unsigned int num_buckets(hashtable_t *hashtable) +static inline size_t num_buckets(hashtable_t *hashtable) { return primes[hashtable->num_buckets]; } static pair_t *hashtable_find_pair(hashtable_t *hashtable, bucket_t *bucket, - const void *key, unsigned int hash) + const void *key, size_t hash) { list_t *list; pair_t *pair; @@ -100,11 +97,11 @@ static pair_t *hashtable_find_pair(hashtable_t *hashtable, bucket_t *bucket, /* returns 0 on success, -1 if key was not found */ static int hashtable_do_del(hashtable_t *hashtable, - const void *key, unsigned int hash) + const void *key, size_t hash) { pair_t *pair; bucket_t *bucket; - unsigned int index; + size_t index; index = hash % num_buckets(hashtable); bucket = &hashtable->buckets[index]; @@ -148,7 +145,7 @@ static void hashtable_do_clear(hashtable_t *hashtable) hashtable->free_key(pair->key); if(hashtable->free_value) hashtable->free_value(pair->value); - free(pair); + jsonp_free(pair); } } @@ -156,14 +153,14 @@ static int hashtable_do_rehash(hashtable_t *hashtable) { list_t *list, *next; pair_t *pair; - unsigned int i, index, new_size; + size_t i, index, new_size; - free(hashtable->buckets); + jsonp_free(hashtable->buckets); hashtable->num_buckets++; new_size = num_buckets(hashtable); - hashtable->buckets = malloc(new_size * sizeof(bucket_t)); + hashtable->buckets = jsonp_malloc(new_size * sizeof(bucket_t)); if(!hashtable->buckets) return -1; @@ -190,13 +187,13 @@ static int hashtable_do_rehash(hashtable_t *hashtable) hashtable_t *hashtable_create(key_hash_fn hash_key, key_cmp_fn cmp_keys, free_fn free_key, free_fn free_value) { - hashtable_t *hashtable = malloc(sizeof(hashtable_t)); + hashtable_t *hashtable = jsonp_malloc(sizeof(hashtable_t)); if(!hashtable) return NULL; if(hashtable_init(hashtable, hash_key, cmp_keys, free_key, free_value)) { - free(hashtable); + jsonp_free(hashtable); return NULL; } @@ -206,18 +203,18 @@ hashtable_t *hashtable_create(key_hash_fn hash_key, key_cmp_fn cmp_keys, void hashtable_destroy(hashtable_t *hashtable) { hashtable_close(hashtable); - free(hashtable); + jsonp_free(hashtable); } int hashtable_init(hashtable_t *hashtable, key_hash_fn hash_key, key_cmp_fn cmp_keys, free_fn free_key, free_fn free_value) { - unsigned int i; + size_t i; hashtable->size = 0; hashtable->num_buckets = 0; /* index to primes[] */ - hashtable->buckets = malloc(num_buckets(hashtable) * sizeof(bucket_t)); + hashtable->buckets = jsonp_malloc(num_buckets(hashtable) * sizeof(bucket_t)); if(!hashtable->buckets) return -1; @@ -240,14 +237,14 @@ int hashtable_init(hashtable_t *hashtable, void hashtable_close(hashtable_t *hashtable) { hashtable_do_clear(hashtable); - free(hashtable->buckets); + jsonp_free(hashtable->buckets); } int hashtable_set(hashtable_t *hashtable, void *key, void *value) { pair_t *pair; bucket_t *bucket; - unsigned int hash, index; + size_t hash, index; /* rehash if the load ratio exceeds 1 */ if(hashtable->size >= num_buckets(hashtable)) @@ -269,7 +266,7 @@ int hashtable_set(hashtable_t *hashtable, void *key, void *value) } else { - pair = malloc(sizeof(pair_t)); + pair = jsonp_malloc(sizeof(pair_t)); if(!pair) return -1; @@ -288,7 +285,7 @@ int hashtable_set(hashtable_t *hashtable, void *key, void *value) void *hashtable_get(hashtable_t *hashtable, const void *key) { pair_t *pair; - unsigned int hash; + size_t hash; bucket_t *bucket; hash = hashtable->hash_key(key); @@ -303,13 +300,13 @@ void *hashtable_get(hashtable_t *hashtable, const void *key) int hashtable_del(hashtable_t *hashtable, const void *key) { - unsigned int hash = hashtable->hash_key(key); + size_t hash = hashtable->hash_key(key); return hashtable_do_del(hashtable, key, hash); } void hashtable_clear(hashtable_t *hashtable) { - unsigned int i; + size_t i; hashtable_do_clear(hashtable); @@ -331,7 +328,7 @@ void *hashtable_iter(hashtable_t *hashtable) void *hashtable_iter_at(hashtable_t *hashtable, const void *key) { pair_t *pair; - unsigned int hash; + size_t hash; bucket_t *bucket; hash = hashtable->hash_key(key); diff --git a/3party/jansson/src/hashtable.h b/3party/jansson/src/hashtable.h index f03a7690b0..5aed14f2ef 100644 --- a/3party/jansson/src/hashtable.h +++ b/3party/jansson/src/hashtable.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * This library is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. @@ -8,7 +8,7 @@ #ifndef HASHTABLE_H #define HASHTABLE_H -typedef unsigned int (*key_hash_fn)(const void *key); +typedef size_t (*key_hash_fn)(const void *key); typedef int (*key_cmp_fn)(const void *key1, const void *key2); typedef void (*free_fn)(void *key); @@ -20,7 +20,7 @@ struct hashtable_list { struct hashtable_pair { void *key; void *value; - unsigned int hash; + size_t hash; struct hashtable_list list; }; @@ -30,9 +30,9 @@ struct hashtable_bucket { }; typedef struct hashtable { - unsigned int size; + size_t size; struct hashtable_bucket *buckets; - unsigned int num_buckets; /* index to primes[] */ + size_t num_buckets; /* index to primes[] */ struct hashtable_list list; key_hash_fn hash_key; diff --git a/3party/jansson/src/jansson.h b/3party/jansson/src/jansson.h index 2a6f8eeef1..5cecdf474c 100644 --- a/3party/jansson/src/jansson.h +++ b/3party/jansson/src/jansson.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * Jansson is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. @@ -8,14 +8,32 @@ #ifndef JANSSON_H #define JANSSON_H -#include "config.h" - #include +#include /* for size_t */ +#include + +//#include #ifdef __cplusplus extern "C" { #endif +/* version */ + +#define JANSSON_MAJOR_VERSION 2 +#define JANSSON_MINOR_VERSION 0 +#define JANSSON_MICRO_VERSION 0 + +/* Micro version is omitted if it's 0 */ +#define JANSSON_VERSION "2.0" + +/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this + for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */ +#define JANSSON_VERSION_HEX ((JANSSON_MAJOR_VERSION << 16) | \ + (JANSSON_MINOR_VERSION << 8) | \ + (JANSSON_MICRO_VERSION << 0))) + + /* types */ typedef enum { @@ -31,9 +49,17 @@ typedef enum { typedef struct { json_type type; - unsigned long refcount; + size_t refcount; } json_t; +#if JSON_INTEGER_IS_LONG_LONG +#define JSON_INTEGER_FORMAT "lld" +typedef long long json_int_t; +#else +#define JSON_INTEGER_FORMAT "ld" +typedef long json_int_t; +#endif /* JSON_INTEGER_IS_LONG_LONG */ + #define json_typeof(json) ((json)->type) #define json_is_object(json) (json && json_typeof(json) == JSON_OBJECT) #define json_is_array(json) (json && json_typeof(json) == JSON_ARRAY) @@ -52,16 +78,16 @@ json_t *json_object(void); json_t *json_array(void); json_t *json_string(const char *value); json_t *json_string_nocheck(const char *value); -json_t *json_integer(int value); +json_t *json_integer(json_int_t value); json_t *json_real(double value); json_t *json_true(void); json_t *json_false(void); json_t *json_null(void); -static JSON_INLINE +static inline json_t *json_incref(json_t *json) { - if(json && json->refcount != (unsigned int)-1) + if(json && json->refcount != (size_t)-1) ++json->refcount; return json; } @@ -69,17 +95,31 @@ json_t *json_incref(json_t *json) /* do not call json_delete directly */ void json_delete(json_t *json); -static JSON_INLINE +static inline void json_decref(json_t *json) { - if(json && json->refcount != (unsigned int)-1 && --json->refcount == 0) + if(json && json->refcount != (size_t)-1 && --json->refcount == 0) json_delete(json); } +/* error reporting */ + +#define JSON_ERROR_TEXT_LENGTH 160 +#define JSON_ERROR_SOURCE_LENGTH 80 + +typedef struct { + int line; + int column; + int position; + char source[JSON_ERROR_SOURCE_LENGTH]; + char text[JSON_ERROR_TEXT_LENGTH]; +} json_error_t; + + /* getters, setters, manipulation */ -unsigned int json_object_size(const json_t *object); +size_t json_object_size(const json_t *object); json_t *json_object_get(const json_t *object, const char *key); int json_object_set_new(json_t *object, const char *key, json_t *value); int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value); @@ -93,62 +133,76 @@ 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 JSON_INLINE +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)); } -static JSON_INLINE +static 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 JSON_INLINE +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); +size_t json_array_size(const json_t *array); +json_t *json_array_get(const json_t *array, size_t index); +int json_array_set_new(json_t *array, size_t index, json_t *value); int json_array_append_new(json_t *array, json_t *value); -int json_array_insert_new(json_t *array, unsigned int index, json_t *value); -int json_array_remove(json_t *array, unsigned int index); +int json_array_insert_new(json_t *array, size_t index, json_t *value); +int json_array_remove(json_t *array, size_t index); int json_array_clear(json_t *array); int json_array_extend(json_t *array, json_t *other); -static JSON_INLINE -int json_array_set(json_t *array, unsigned int index, json_t *value) +static inline +int json_array_set(json_t *array, size_t index, json_t *value) { return json_array_set_new(array, index, json_incref(value)); } -static JSON_INLINE +static inline int json_array_append(json_t *array, json_t *value) { return json_array_append_new(array, json_incref(value)); } -static JSON_INLINE -int json_array_insert(json_t *array, unsigned int index, json_t *value) +static inline +int json_array_insert(json_t *array, size_t index, json_t *value) { return json_array_insert_new(array, index, json_incref(value)); } const char *json_string_value(const json_t *string); -int json_integer_value(const json_t *integer); +json_int_t json_integer_value(const json_t *integer); double json_real_value(const json_t *real); double json_number_value(const json_t *json); int json_string_set(json_t *string, const char *value); int json_string_set_nocheck(json_t *string, const char *value); -int json_integer_set(json_t *integer, int value); +int json_integer_set(json_t *integer, json_int_t value); int json_real_set(json_t *real, double value); +/* pack, unpack */ + +json_t *json_pack(const char *fmt, ...); +json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...); +json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap); + +#define JSON_VALIDATE_ONLY 0x1 +#define JSON_STRICT 0x2 + +int json_unpack(json_t *root, const char *fmt, ...); +int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...); +int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, va_list ap); + + /* equality */ int json_equal(json_t *value1, json_t *value2); @@ -162,26 +216,27 @@ json_t *json_deep_copy(json_t *value); /* loading, printing */ -#define JSON_ERROR_TEXT_LENGTH 160 +json_t *json_loads(const char *input, size_t flags, json_error_t *error); +json_t *json_loadf(FILE *input, size_t flags, json_error_t *error); +json_t *json_load_file(const char *path, size_t flags, json_error_t *error); -typedef struct { - char text[JSON_ERROR_TEXT_LENGTH]; - int line; -} json_error_t; +#define JSON_INDENT(n) (n & 0x1F) +#define JSON_COMPACT 0x20 +#define JSON_ENSURE_ASCII 0x40 +#define JSON_SORT_KEYS 0x80 +#define JSON_PRESERVE_ORDER 0x100 -json_t *json_loads(const char *input, json_error_t *error); -json_t *json_loadf(FILE *input, json_error_t *error); -json_t *json_load_file(const char *path, json_error_t *error); +char *json_dumps(const json_t *json, size_t flags); +int json_dumpf(const json_t *json, FILE *output, size_t flags); +int json_dump_file(const json_t *json, const char *path, size_t flags); -#define JSON_INDENT(n) (n & 0xFF) -#define JSON_COMPACT 0x100 -#define JSON_ENSURE_ASCII 0x200 -#define JSON_SORT_KEYS 0x400 -#define JSON_PRESERVE_ORDER 0x800 -char *json_dumps(const json_t *json, unsigned long flags); -int json_dumpf(const json_t *json, FILE *output, unsigned long flags); -int json_dump_file(const json_t *json, const char *path, unsigned long flags); +/* custom memory allocation */ + +typedef void *(*json_malloc_t)(size_t); +typedef void (*json_free_t)(void *); + +void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn); #ifdef __cplusplus } diff --git a/3party/jansson/src/jansson_private.h b/3party/jansson/src/jansson_private.h index 6977bb5bf5..6c7e3bdc1b 100644 --- a/3party/jansson/src/jansson_private.h +++ b/3party/jansson/src/jansson_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * Jansson is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. @@ -8,23 +8,30 @@ #ifndef JANSSON_PRIVATE_H #define JANSSON_PRIVATE_H +#include +#include #include "jansson.h" #include "hashtable.h" #define container_of(ptr_, type_, member_) \ - ((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_)) + ((type_ *)((char *)ptr_ - offsetof(type_, member_))) + +/* On some platforms, max() may already be defined */ +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif typedef struct { json_t json; hashtable_t hashtable; - unsigned long serial; + size_t serial; int visited; } json_object_t; typedef struct { json_t json; - unsigned int size; - unsigned int entries; + size_t size; + size_t entries; json_t **table; int visited; } json_array_t; @@ -41,7 +48,7 @@ typedef struct { typedef struct { json_t json; - int value; + json_int_t value; } json_integer_t; #define json_to_object(json_) container_of(json_, json_object_t, json) @@ -50,11 +57,26 @@ typedef struct { #define json_to_real(json_) container_of(json_, json_real_t, json) #define json_to_integer(json_) container_of(json_, json_integer_t, json) +size_t jsonp_hash_key(const void *ptr); +int jsonp_key_equal(const void *ptr1, const void *ptr2); + typedef struct { - unsigned long serial; - char key[]; + size_t serial; + char key[1]; } object_key_t; object_key_t *jsonp_object_iter_fullkey(void *iter); +void jsonp_error_init(json_error_t *error, const char *source); +void jsonp_error_set_source(json_error_t *error, const char *source); +void jsonp_error_set(json_error_t *error, int line, int column, + size_t position, const char *msg, ...); +void jsonp_error_vset(json_error_t *error, int line, int column, + size_t position, const char *msg, va_list ap); + +/* Wrappers for custom memory functions */ +void* jsonp_malloc(size_t size); +void jsonp_free(void *ptr); +char *jsonp_strdup(const char *str); + #endif diff --git a/3party/jansson/src/load.c b/3party/jansson/src/load.c index de42d72e2f..1fbfddacac 100644 --- a/3party/jansson/src/load.c +++ b/3party/jansson/src/load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * Jansson is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. @@ -20,10 +20,9 @@ #include "strbuffer.h" #include "utf.h" -// Visual Studio fix -#ifdef _MSC_VER - #define snprintf _snprintf -#endif +#define STREAM_STATE_OK 0 +#define STREAM_STATE_EOF -1 +#define STREAM_STATE_ERROR -2 #define TOKEN_INVALID -1 #define TOKEN_EOF 0 @@ -34,113 +33,130 @@ #define TOKEN_FALSE 260 #define TOKEN_NULL 261 -/* read one byte from stream, return EOF on end of file */ -typedef int (*get_func)(void *data); +// Visual Studio fix +#ifdef _MSC_VER + #define snprintf _snprintf +#endif -/* return non-zero if end of file has been reached */ -typedef int (*eof_func)(void *data); +/* Read one byte from stream, convert to unsigned char, then int, and + return. return EOF on end of file. This corresponds to the + behaviour of fgetc(). */ +typedef int (*get_func)(void *data); typedef struct { get_func get; - eof_func eof; void *data; - int stream_pos; char buffer[5]; int buffer_pos; + int state; + int line; + int column, last_column; + size_t position; } stream_t; - typedef struct { stream_t stream; strbuffer_t saved_text; int token; - int line, column; union { char *string; - int integer; + json_int_t integer; double real; } value; } lex_t; +#define stream_to_lex(stream) container_of(stream, lex_t, stream) + /*** error reporting ***/ -static void error_init(json_error_t *error) -{ - if(error) - { - error->text[0] = '\0'; - error->line = -1; - } -} - static void error_set(json_error_t *error, const lex_t *lex, const char *msg, ...) { va_list ap; - char text[JSON_ERROR_TEXT_LENGTH]; + char msg_text[JSON_ERROR_TEXT_LENGTH]; - if(!error || error->text[0] != '\0') { - /* error already set */ + int line = -1, col = -1; + size_t pos = 0; + const char *result = msg_text; + + if(!error) return; - } va_start(ap, msg); - vsnprintf(text, JSON_ERROR_TEXT_LENGTH, msg, ap); + vsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap); va_end(ap); if(lex) { const char *saved_text = strbuffer_value(&lex->saved_text); - error->line = lex->line; + char msg_with_context[JSON_ERROR_TEXT_LENGTH]; + + line = lex->stream.line; + col = lex->stream.column; + pos = lex->stream.position; + if(saved_text && saved_text[0]) { if(lex->saved_text.length <= 20) { - snprintf(error->text, JSON_ERROR_TEXT_LENGTH, - "%s near '%s'", text, saved_text); + snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, + "%s near '%s'", msg_text, saved_text); + result = msg_with_context; } - else - snprintf(error->text, JSON_ERROR_TEXT_LENGTH, "%s", text); } else { - snprintf(error->text, JSON_ERROR_TEXT_LENGTH, - "%s near end of file", text); + if(lex->stream.state == STREAM_STATE_ERROR) { + /* No context for UTF-8 decoding errors */ + result = msg_text; + } + else { + snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, + "%s near end of file", msg_text); + result = msg_with_context; + } } } - else - { - error->line = -1; - snprintf(error->text, JSON_ERROR_TEXT_LENGTH, "%s", text); - } + + jsonp_error_set(error, line, col, pos, "%s", result); } /*** lexical analyzer ***/ static void -stream_init(stream_t *stream, get_func get, eof_func eof, void *data) +stream_init(stream_t *stream, get_func get, void *data) { stream->get = get; - stream->eof = eof; stream->data = data; - stream->stream_pos = 0; stream->buffer[0] = '\0'; stream->buffer_pos = 0; + + stream->state = STREAM_STATE_OK; + stream->line = 1; + stream->column = 0; + stream->position = 0; } -static char stream_get(stream_t *stream, json_error_t *error) +static int stream_get(stream_t *stream, json_error_t *error) { - char c; + int c; + + if(stream->state != STREAM_STATE_OK) + return stream->state; if(!stream->buffer[stream->buffer_pos]) { - stream->buffer[0] = stream->get(stream->data); + c = stream->get(stream->data); + if(c == EOF) { + stream->state = STREAM_STATE_EOF; + return STREAM_STATE_EOF; + } + + stream->buffer[0] = c; stream->buffer_pos = 0; - c = stream->buffer[0]; - - if((unsigned char)c >= 0x80 && c != (char)EOF) + if(0x80 <= c && c <= 0xFF) { /* multi-byte UTF-8 sequence */ int i, count; @@ -157,30 +173,47 @@ static char stream_get(stream_t *stream, json_error_t *error) if(!utf8_check_full(stream->buffer, count, NULL)) goto out; - stream->stream_pos += count; stream->buffer[count] = '\0'; } - else { + else stream->buffer[1] = '\0'; - stream->stream_pos++; - } } - return stream->buffer[stream->buffer_pos++]; + c = stream->buffer[stream->buffer_pos++]; + + stream->position++; + if(c == '\n') { + stream->line++; + stream->last_column = stream->column; + stream->column = 0; + } + else if(utf8_check_first(c)) { + /* track the Unicode character column, so increment only if + this is the first character of a UTF-8 sequence */ + stream->column++; + } + + return c; out: - error_set(error, NULL, "unable to decode byte 0x%x at position %d", - (unsigned char)c, stream->stream_pos); - - stream->buffer[0] = EOF; - stream->buffer[1] = '\0'; - stream->buffer_pos = 1; - - return EOF; + stream->state = STREAM_STATE_ERROR; + error_set(error, stream_to_lex(stream), "unable to decode byte 0x%x", c); + return STREAM_STATE_ERROR; } -static void stream_unget(stream_t *stream, char c) +static void stream_unget(stream_t *stream, int c) { + if(c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR) + return; + + stream->position--; + if(c == '\n') { + stream->line--; + stream->column = stream->last_column; + } + else if(utf8_check_first(c)) + stream->column--; + assert(stream->buffer_pos > 0); stream->buffer_pos--; assert(stream->buffer[stream->buffer_pos] == c); @@ -192,29 +225,32 @@ static int lex_get(lex_t *lex, json_error_t *error) return stream_get(&lex->stream, error); } -static int lex_eof(lex_t *lex) -{ - return lex->stream.eof(lex->stream.data); -} - -static void lex_save(lex_t *lex, char c) +static void lex_save(lex_t *lex, int c) { strbuffer_append_byte(&lex->saved_text, c); } static int lex_get_save(lex_t *lex, json_error_t *error) { - char c = stream_get(&lex->stream, error); - lex_save(lex, c); + int c = stream_get(&lex->stream, error); + if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) + lex_save(lex, c); return c; } -static void lex_unget_unsave(lex_t *lex, char c) +static void lex_unget(lex_t *lex, int c) { - char d; stream_unget(&lex->stream, c); - d = strbuffer_pop(&lex->saved_text); - assert(c == d); +} + +static void lex_unget_unsave(lex_t *lex, int c) +{ + if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) { + char d; + stream_unget(&lex->stream, c); + d = strbuffer_pop(&lex->saved_text); + assert(c == d); + } } static void lex_save_cached(lex_t *lex) @@ -223,6 +259,7 @@ static void lex_save_cached(lex_t *lex) { lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]); lex->stream.buffer_pos++; + lex->stream.position++; } } @@ -252,7 +289,7 @@ static int32_t decode_unicode_escape(const char *str) static void lex_scan_string(lex_t *lex, json_error_t *error) { - char c; + int c; const char *p; char *t; int i; @@ -263,14 +300,15 @@ static void lex_scan_string(lex_t *lex, json_error_t *error) c = lex_get_save(lex, error); while(c != '"') { - if(c == (char)EOF) { - lex_unget_unsave(lex, c); - if(lex_eof(lex)) - error_set(error, lex, "premature end of input"); + if(c == STREAM_STATE_ERROR) + goto out; + + else if(c == STREAM_STATE_EOF) { + error_set(error, lex, "premature end of input"); goto out; } - else if((unsigned char)c <= 0x1F) { + else if(0 <= c && c <= 0x1F) { /* control character */ lex_unget_unsave(lex, c); if(c == '\n') @@ -286,7 +324,6 @@ static void lex_scan_string(lex_t *lex, json_error_t *error) c = lex_get_save(lex, error); for(i = 0; i < 4; i++) { if(!isxdigit(c)) { - lex_unget_unsave(lex, c); error_set(error, lex, "invalid escape"); goto out; } @@ -297,7 +334,6 @@ static void lex_scan_string(lex_t *lex, json_error_t *error) c == 'f' || c == 'n' || c == 'r' || c == 't') c = lex_get_save(lex, error); else { - lex_unget_unsave(lex, c); error_set(error, lex, "invalid escape"); goto out; } @@ -313,7 +349,7 @@ static void lex_scan_string(lex_t *lex, json_error_t *error) - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair are converted to 4 bytes */ - lex->value.string = malloc(lex->saved_text.length + 1); + lex->value.string = jsonp_malloc(lex->saved_text.length + 1); if(!lex->value.string) { /* this is not very nice, since TOKEN_INVALID is returned */ goto out; @@ -403,10 +439,16 @@ static void lex_scan_string(lex_t *lex, json_error_t *error) return; out: - free(lex->value.string); + jsonp_free(lex->value.string); } -static int lex_scan_number(lex_t *lex, char c, json_error_t *error) +#if JSON_INTEGER_IS_LONG_LONG +#define json_strtoint strtoll +#else +#define json_strtoint strtol +#endif + +static int lex_scan_number(lex_t *lex, int c, json_error_t *error) { const char *saved_text; char *end; @@ -430,37 +472,40 @@ static int lex_scan_number(lex_t *lex, char c, json_error_t *error) c = lex_get_save(lex, error); } else { - lex_unget_unsave(lex, c); - goto out; + lex_unget_unsave(lex, c); + goto out; } if(c != '.' && c != 'E' && c != 'e') { - long value; + json_int_t value; lex_unget_unsave(lex, c); saved_text = strbuffer_value(&lex->saved_text); - value = strtol(saved_text, &end, 10); + + errno = 0; + value = json_strtoint(saved_text, &end, 10); + if(errno == ERANGE) { + if(value < 0) + error_set(error, lex, "too big negative integer"); + else + error_set(error, lex, "too big integer"); + goto out; + } + assert(end == saved_text + lex->saved_text.length); - if((value == LONG_MAX && errno == ERANGE) || value > INT_MAX) { - error_set(error, lex, "too big integer"); - goto out; - } - else if((value == LONG_MIN && errno == ERANGE) || value < INT_MIN) { - error_set(error, lex, "too big negative integer"); - goto out; - } - lex->token = TOKEN_INTEGER; - lex->value.integer = (int)value; + lex->value.integer = value; return 0; } if(c == '.') { c = lex_get(lex, error); - if(!isdigit(c)) + if(!isdigit(c)) { + lex_unget(lex, c); goto out; + } lex_save(lex, c); c = lex_get_save(lex, error); @@ -504,29 +549,26 @@ out: static int lex_scan(lex_t *lex, json_error_t *error) { - char c; + int c; strbuffer_clear(&lex->saved_text); if(lex->token == TOKEN_STRING) { - free(lex->value.string); + jsonp_free(lex->value.string); lex->value.string = NULL; } c = lex_get(lex, error); while(c == ' ' || c == '\t' || c == '\n' || c == '\r') - { - if(c == '\n') - lex->line++; - c = lex_get(lex, error); + + if(c == STREAM_STATE_EOF) { + lex->token = TOKEN_EOF; + goto out; } - if(c == (char)EOF) { - if(lex_eof(lex)) - lex->token = TOKEN_EOF; - else - lex->token = TOKEN_INVALID; + if(c == STREAM_STATE_ERROR) { + lex->token = TOKEN_INVALID; goto out; } @@ -586,22 +628,20 @@ static char *lex_steal_string(lex_t *lex) return result; } -static int lex_init(lex_t *lex, get_func get, eof_func eof, void *data) +static int lex_init(lex_t *lex, get_func get, void *data) { - stream_init(&lex->stream, get, eof, data); + stream_init(&lex->stream, get, data); if(strbuffer_init(&lex->saved_text)) return -1; lex->token = TOKEN_INVALID; - lex->line = 1; - return 0; } static void lex_close(lex_t *lex) { if(lex->token == TOKEN_STRING) - free(lex->value.string); + jsonp_free(lex->value.string); strbuffer_close(&lex->saved_text); } @@ -635,7 +675,7 @@ static json_t *parse_object(lex_t *lex, json_error_t *error) lex_scan(lex, error); if(lex->token != ':') { - free(key); + jsonp_free(key); error_set(error, lex, "':' expected"); goto error; } @@ -643,18 +683,18 @@ static json_t *parse_object(lex_t *lex, json_error_t *error) lex_scan(lex, error); value = parse_value(lex, error); if(!value) { - free(key); + jsonp_free(key); goto error; } if(json_object_set_nocheck(object, key, value)) { - free(key); + jsonp_free(key); json_decref(value); goto error; } json_decref(value); - free(key); + jsonp_free(key); lex_scan(lex, error); if(lex->token != ',') @@ -772,8 +812,6 @@ static json_t *parse_value(lex_t *lex, json_error_t *error) static json_t *parse_json(lex_t *lex, json_error_t *error) { - error_init(error); - lex_scan(lex, error); if(lex->token != '[' && lex->token != '{') { error_set(error, lex, "'[' or '{' expected"); @@ -799,29 +837,23 @@ static int string_get(void *data) else { stream->pos++; - return c; + return (unsigned char)c; } } -static int string_eof(void *data) -{ - string_data_t *stream = (string_data_t *)data; - return (stream->data[stream->pos] == '\0'); -} - -json_t *json_loads(const char *string, json_error_t *error) +json_t *json_loads(const char *string, size_t flags, json_error_t *error) { lex_t lex; json_t *result; + string_data_t stream_data = {string, 0}; - string_data_t stream_data = { - string, - 0 - }; + (void)flags; /* unused */ - if(lex_init(&lex, string_get, string_eof, (void *)&stream_data)) + if(lex_init(&lex, string_get, (void *)&stream_data)) return NULL; + jsonp_error_init(error, ""); + result = parse_json(&lex, error); if(!result) goto out; @@ -838,14 +870,23 @@ out: return result; } -json_t *json_loadf(FILE *input, json_error_t *error) +json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) { lex_t lex; + const char *source; json_t *result; + (void)flags; /* unused */ - if(lex_init(&lex, (get_func)fgetc, (eof_func)feof, input)) + if(lex_init(&lex, (get_func)fgetc, input)) return NULL; + if(input == stdin) + source = ""; + else + source = ""; + + jsonp_error_init(error, source); + result = parse_json(&lex, error); if(!result) goto out; @@ -862,12 +903,12 @@ out: return result; } -json_t *json_load_file(const char *path, json_error_t *error) +json_t *json_load_file(const char *path, size_t flags, json_error_t *error) { json_t *result; FILE *fp; - error_init(error); + jsonp_error_init(error, path); fp = fopen(path, "r"); if(!fp) @@ -877,7 +918,7 @@ json_t *json_load_file(const char *path, json_error_t *error) return NULL; } - result = json_loadf(fp, error); + result = json_loadf(fp, flags, error); fclose(fp); return result; diff --git a/3party/jansson/src/memory.c b/3party/jansson/src/memory.c new file mode 100644 index 0000000000..cf05bf909f --- /dev/null +++ b/3party/jansson/src/memory.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009-2011 Petri Lehtinen + * Copyright (c) 2011 Basile Starynkevitch + * + * Jansson is free software; you can redistribute it and/or modify it + * under the terms of the MIT license. See LICENSE for details. + */ + +#include +#include + +#include "jansson.h" +#include "jansson_private.h" + +/* memory function pointers */ +static json_malloc_t do_malloc = malloc; +static json_free_t do_free = free; + +void *jsonp_malloc(size_t size) +{ + if(!size) + return NULL; + + return (*do_malloc)(size); +} + +void jsonp_free(void *ptr) +{ + if(!ptr) + return; + + (*do_free)(ptr); +} + +char *jsonp_strdup(const char *str) +{ + char *new_str; + + new_str = jsonp_malloc(strlen(str) + 1); + if(!new_str) + return NULL; + + strcpy(new_str, str); + return new_str; +} + +void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn) +{ + do_malloc = malloc_fn; + do_free = free_fn; +} diff --git a/3party/jansson/src/pack_unpack.c b/3party/jansson/src/pack_unpack.c new file mode 100644 index 0000000000..5001764e19 --- /dev/null +++ b/3party/jansson/src/pack_unpack.c @@ -0,0 +1,610 @@ +/* + * Copyright (c) 2009-2011 Petri Lehtinen + * Copyright (c) 2011 Graeme Smecher + * + * Jansson is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#include +#include +#include "jansson_private.h" +#include "utf.h" + +typedef struct { + const char *start; + const char *fmt; + char token; + json_error_t *error; + size_t flags; + int line; + int column; +} scanner_t; + +static const char *type_names[] = { + "object", + "array", + "string", + "integer", + "real", + "true", + "false", + "null" +}; + +#define type_name(x) type_names[json_typeof(x)] + +static const char *unpack_value_starters = "{[siIbfFOon"; + + +static void scanner_init(scanner_t *s, json_error_t *error, + size_t flags, const char *fmt) +{ + s->error = error; + s->flags = flags; + s->fmt = s->start = fmt; + s->line = 1; + s->column = 0; +} + +static void next_token(scanner_t *s) +{ + const char *t = s->fmt; + s->column++; + + /* skip space and ignored chars */ + while(*t == ' ' || *t == '\t' || *t == '\n' || *t == ',' || *t == ':') { + if(*t == '\n') { + s->line++; + s->column = 1; + } + else + s->column++; + + t++; + } + + s->token = *t; + + t++; + s->fmt = t; +} + +static void set_error(scanner_t *s, const char *source, const char *fmt, ...) +{ + va_list ap; + size_t pos; + va_start(ap, fmt); + + pos = (size_t)(s->fmt - s->start); + jsonp_error_vset(s->error, s->line, s->column, pos, fmt, ap); + + jsonp_error_set_source(s->error, source); + + va_end(ap); +} + +static json_t *pack(scanner_t *s, va_list *ap); + +static json_t *pack_object(scanner_t *s, va_list *ap) +{ + json_t *object = json_object(); + next_token(s); + + while(s->token != '}') { + const char *key; + json_t *value; + + if(!s->token) { + set_error(s, "", "Unexpected end of format string"); + goto error; + } + + if(s->token != 's') { + set_error(s, "", "Expected format 's', got '%c'", s->token); + goto error; + } + + key = va_arg(*ap, const char *); + if(!key) { + set_error(s, "", "NULL object key"); + goto error; + } + + if(!utf8_check_string(key, -1)) { + set_error(s, "", "Invalid UTF-8 in object key"); + goto error; + } + + next_token(s); + + value = pack(s, ap); + if(!value) + goto error; + + if(json_object_set_new_nocheck(object, key, value)) { + set_error(s, "", "Unable to add key \"%s\"", key); + goto error; + } + + next_token(s); + } + + return object; + +error: + json_decref(object); + return NULL; +} + +static json_t *pack_array(scanner_t *s, va_list *ap) +{ + json_t *array = json_array(); + next_token(s); + + while(s->token != ']') { + json_t *value; + + if(!s->token) { + set_error(s, "", "Unexpected end of format string"); + goto error; + } + + value = pack(s, ap); + if(!value) + goto error; + + if(json_array_append_new(array, value)) { + set_error(s, "", "Unable to append to array"); + goto error; + } + + next_token(s); + } + return array; + +error: + json_decref(array); + return NULL; +} + +static json_t *pack(scanner_t *s, va_list *ap) +{ + switch(s->token) { + case '{': + return pack_object(s, ap); + + case '[': + return pack_array(s, ap); + + case 's': /* string */ + { + const char *str = va_arg(*ap, const char *); + if(!str) { + set_error(s, "", "NULL string argument"); + return NULL; + } + if(!utf8_check_string(str, -1)) { + set_error(s, "", "Invalid UTF-8 string"); + return NULL; + } + return json_string_nocheck(str); + } + + case 'n': /* null */ + return json_null(); + + case 'b': /* boolean */ + return va_arg(*ap, int) ? json_true() : json_false(); + + case 'i': /* integer from int */ + return json_integer(va_arg(*ap, int)); + + case 'I': /* integer from json_int_t */ + return json_integer(va_arg(*ap, json_int_t)); + + case 'f': /* real */ + return json_real(va_arg(*ap, double)); + + case 'O': /* a json_t object; increments refcount */ + return json_incref(va_arg(*ap, json_t *)); + + case 'o': /* a json_t object; doesn't increment refcount */ + return va_arg(*ap, json_t *); + + default: + set_error(s, "", "Unexpected format character '%c'", + s->token); + return NULL; + } +} + +static int unpack(scanner_t *s, json_t *root, va_list *ap); + +static int unpack_object(scanner_t *s, json_t *root, va_list *ap) +{ + int ret = -1; + int strict = 0; + + /* Use a set (emulated by a hashtable) to check that all object + keys are accessed. Checking that the correct number of keys + were accessed is not enough, as the same key can be unpacked + multiple times. + */ + hashtable_t key_set; + + if(hashtable_init(&key_set, jsonp_hash_key, jsonp_key_equal, NULL, NULL)) { + set_error(s, "", "Out of memory"); + return -1; + } + + if(!json_is_object(root)) { + set_error(s, "", "Expected object, got %s", + type_name(root)); + goto out; + } + next_token(s); + + while(s->token != '}') { + const char *key; + json_t *value; + + if(strict != 0) { + set_error(s, "", "Expected '}' after '%c', got '%c'", + (strict == 1 ? '!' : '*'), s->token); + goto out; + } + + if(!s->token) { + set_error(s, "", "Unexpected end of format string"); + goto out; + } + + if(s->token == '!' || s->token == '*') { + strict = (s->token == '!' ? 1 : -1); + next_token(s); + continue; + } + + if(s->token != 's') { + set_error(s, "", "Expected format 's', got '%c'", s->token); + goto out; + } + + key = va_arg(*ap, const char *); + if(!key) { + set_error(s, "", "NULL object key"); + goto out; + } + + next_token(s); + + value = json_object_get(root, key); + if(!value) { + set_error(s, "", "Object item not found: %s", key); + goto out; + } + + if(unpack(s, value, ap)) + goto out; + + hashtable_set(&key_set, (void *)key, NULL); + next_token(s); + } + + if(strict == 0 && (s->flags & JSON_STRICT)) + strict = 1; + + if(strict == 1 && key_set.size != json_object_size(root)) { + long diff = (long)json_object_size(root) - (long)key_set.size; + set_error(s, "", "%li object item(s) left unpacked", diff); + goto out; + } + + ret = 0; + +out: + hashtable_close(&key_set); + return ret; +} + +static int unpack_array(scanner_t *s, json_t *root, va_list *ap) +{ + size_t i = 0; + int strict = 0; + + if(!json_is_array(root)) { + set_error(s, "", "Expected array, got %s", type_name(root)); + return -1; + } + next_token(s); + + while(s->token != ']') { + json_t *value; + + if(strict != 0) { + set_error(s, "", "Expected ']' after '%c', got '%c'", + (strict == 1 ? '!' : '*'), + s->token); + return -1; + } + + if(!s->token) { + set_error(s, "", "Unexpected end of format string"); + return -1; + } + + if(s->token == '!' || s->token == '*') { + strict = (s->token == '!' ? 1 : -1); + next_token(s); + continue; + } + + if(!strchr(unpack_value_starters, s->token)) { + set_error(s, "", "Unexpected format character '%c'", + s->token); + return -1; + } + + value = json_array_get(root, i); + if(!value) { + set_error(s, "", "Array index %lu out of range", + (unsigned long)i); + return -1; + } + + if(unpack(s, value, ap)) + return -1; + + next_token(s); + i++; + } + + if(strict == 0 && (s->flags & JSON_STRICT)) + strict = 1; + + if(strict == 1 && i != json_array_size(root)) { + long diff = (long)json_array_size(root) - (long)i; + set_error(s, "", "%li array item(s) left unpacked", diff); + return -1; + } + + return 0; +} + +static int unpack(scanner_t *s, json_t *root, va_list *ap) +{ + switch(s->token) + { + case '{': + return unpack_object(s, root, ap); + + case '[': + return unpack_array(s, root, ap); + + case 's': + if(!json_is_string(root)) { + set_error(s, "", "Expected string, got %s", + type_name(root)); + return -1; + } + + if(!(s->flags & JSON_VALIDATE_ONLY)) { + const char **str; + + str = va_arg(*ap, const char **); + if(!str) { + set_error(s, "", "NULL string argument"); + return -1; + } + + *str = json_string_value(root); + } + return 0; + + case 'i': + if(!json_is_integer(root)) { + set_error(s, "", "Expected integer, got %s", + type_name(root)); + return -1; + } + + if(!(s->flags & JSON_VALIDATE_ONLY)) + *va_arg(*ap, int*) = json_integer_value(root); + + return 0; + + case 'I': + if(!json_is_integer(root)) { + set_error(s, "", "Expected integer, got %s", + type_name(root)); + return -1; + } + + if(!(s->flags & JSON_VALIDATE_ONLY)) + *va_arg(*ap, json_int_t*) = json_integer_value(root); + + return 0; + + case 'b': + if(!json_is_boolean(root)) { + set_error(s, "", "Expected true or false, got %s", + type_name(root)); + return -1; + } + + if(!(s->flags & JSON_VALIDATE_ONLY)) + *va_arg(*ap, int*) = json_is_true(root); + + return 0; + + case 'f': + if(!json_is_real(root)) { + set_error(s, "", "Expected real, got %s", + type_name(root)); + return -1; + } + + if(!(s->flags & JSON_VALIDATE_ONLY)) + *va_arg(*ap, double*) = json_real_value(root); + + return 0; + + case 'F': + if(!json_is_number(root)) { + set_error(s, "", "Expected real or integer, got %s", + type_name(root)); + return -1; + } + + if(!(s->flags & JSON_VALIDATE_ONLY)) + *va_arg(*ap, double*) = json_number_value(root); + + return 0; + + case 'O': + if(!(s->flags & JSON_VALIDATE_ONLY)) + json_incref(root); + /* Fall through */ + + case 'o': + if(!(s->flags & JSON_VALIDATE_ONLY)) + *va_arg(*ap, json_t**) = root; + + return 0; + + case 'n': + /* Never assign, just validate */ + if(!json_is_null(root)) { + set_error(s, "", "Expected null, got %s", + type_name(root)); + return -1; + } + return 0; + + default: + set_error(s, "", "Unexpected format character '%c'", + s->token); + return -1; + } +} + +json_t *json_vpack_ex(json_error_t *error, size_t flags, + const char *fmt, va_list ap) +{ + scanner_t s; + va_list ap_copy; + json_t *value; + + if(!fmt || !*fmt) { + jsonp_error_init(error, ""); + jsonp_error_set(error, -1, -1, 0, "NULL or empty format string"); + return NULL; + } + jsonp_error_init(error, NULL); + + scanner_init(&s, error, flags, fmt); + next_token(&s); + + va_copy(ap_copy, ap); + value = pack(&s, &ap_copy); + va_end(ap_copy); + + if(!value) + return NULL; + + next_token(&s); + if(s.token) { + json_decref(value); + set_error(&s, "", "Garbage after format string"); + return NULL; + } + + return value; +} + +json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...) +{ + json_t *value; + va_list ap; + + va_start(ap, fmt); + value = json_vpack_ex(error, flags, fmt, ap); + va_end(ap); + + return value; +} + +json_t *json_pack(const char *fmt, ...) +{ + json_t *value; + va_list ap; + + va_start(ap, fmt); + value = json_vpack_ex(NULL, 0, fmt, ap); + va_end(ap); + + return value; +} + +int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, + const char *fmt, va_list ap) +{ + scanner_t s; + va_list ap_copy; + + if(!root) { + jsonp_error_init(error, ""); + jsonp_error_set(error, -1, -1, 0, "NULL root value"); + return -1; + } + + if(!fmt || !*fmt) { + jsonp_error_init(error, ""); + jsonp_error_set(error, -1, -1, 0, "NULL or empty format string"); + return -1; + } + jsonp_error_init(error, NULL); + + scanner_init(&s, error, flags, fmt); + next_token(&s); + + va_copy(ap_copy, ap); + if(unpack(&s, root, &ap_copy)) { + va_end(ap_copy); + return -1; + } + va_end(ap_copy); + + next_token(&s); + if(s.token) { + set_error(&s, "", "Garbage after format string"); + return -1; + } + + return 0; +} + +int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = json_vunpack_ex(root, error, flags, fmt, ap); + va_end(ap); + + return ret; +} + +int json_unpack(json_t *root, const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = json_vunpack_ex(root, NULL, 0, fmt, ap); + va_end(ap); + + return ret; +} diff --git a/3party/jansson/src/strbuffer.c b/3party/jansson/src/strbuffer.c index 3496024770..758e95e7c0 100644 --- a/3party/jansson/src/strbuffer.c +++ b/3party/jansson/src/strbuffer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * Jansson is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. @@ -8,8 +8,8 @@ #define _GNU_SOURCE #include #include +#include "jansson_private.h" #include "strbuffer.h" -#include "util.h" #define STRBUFFER_MIN_SIZE 16 #define STRBUFFER_FACTOR 2 @@ -68,12 +68,21 @@ int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, int size) { if(strbuff->length + size >= strbuff->size) { - strbuff->size = max(strbuff->size * STRBUFFER_FACTOR, - strbuff->length + size + 1); + size_t new_size; + char *new_value; - strbuff->value = realloc(strbuff->value, strbuff->size); - if(!strbuff->value) + new_size = max(strbuff->size * STRBUFFER_FACTOR, + strbuff->length + size + 1); + + new_value = jsonp_malloc(new_size); + if(!new_value) return -1; + + memcpy(new_value, strbuff->value, strbuff->length); + + jsonp_free(strbuff->value); + strbuff->value = new_value; + strbuff->size = new_size; } memcpy(strbuff->value + strbuff->length, data, size); diff --git a/3party/jansson/src/strbuffer.h b/3party/jansson/src/strbuffer.h index f4c5f77183..b21ef8b068 100644 --- a/3party/jansson/src/strbuffer.h +++ b/3party/jansson/src/strbuffer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * Jansson is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. diff --git a/3party/jansson/src/utf.c b/3party/jansson/src/utf.c index 92484d025d..f48c2e7b24 100644 --- a/3party/jansson/src/utf.c +++ b/3party/jansson/src/utf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * Jansson is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. diff --git a/3party/jansson/src/utf.h b/3party/jansson/src/utf.h index 9ddcbc748f..0c3ab3136f 100644 --- a/3party/jansson/src/utf.h +++ b/3party/jansson/src/utf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * Jansson is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. @@ -8,16 +8,25 @@ #ifndef UTF_H #define UTF_H -#include "config.h" +#ifdef HAVE_CONFIG_H +#include #ifdef HAVE_INTTYPES_H - /* inttypes.h includes stdint.h in a standard environment, so there's - no need to include stdint.h separately. If inttypes.h doesn't define - int32_t, it's defined in config.h. */ - #include -#else - typedef __int32 int32_t; -#endif +/* inttypes.h includes stdint.h in a standard environment, so there's +no need to include stdint.h separately. If inttypes.h doesn't define +int32_t, it's defined in config.h. */ +#include +#endif /* HAVE_INTTYPES_H */ + +#else /* !HAVE_CONFIG_H */ +#ifdef _WIN32 +typedef int int32_t; +#else /* !_WIN32 */ +/* Assume a standard environment */ +#include +#endif /* _WIN32 */ + +#endif /* HAVE_CONFIG_H */ int utf8_encode(int codepoint, char *buffer, int *size); diff --git a/3party/jansson/src/value.c b/3party/jansson/src/value.c index 8f53440e2e..544c8911df 100644 --- a/3party/jansson/src/value.c +++ b/3party/jansson/src/value.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * Jansson is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. @@ -7,8 +7,7 @@ #define _GNU_SOURCE -#include "config.h" - +#include #include #include @@ -16,10 +15,9 @@ #include "hashtable.h" #include "jansson_private.h" #include "utf.h" -#include "util.h" -static JSON_INLINE void json_init(json_t *json, json_type type) +static inline void json_init(json_t *json, json_type type) { json->type = type; json->refcount = 1; @@ -34,14 +32,14 @@ static JSON_INLINE void json_init(json_t *json, json_type type) 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) +size_t jsonp_hash_key(const void *ptr) { const char *str = ((const object_key_t *)ptr)->key; - unsigned int hash = 5381; - unsigned int c; + size_t hash = 5381; + size_t c; - while((c = (unsigned int)*str)) + while((c = (size_t)*str)) { hash = ((hash << 5) + hash) + c; str++; @@ -50,7 +48,7 @@ static unsigned int hash_key(const void *ptr) return hash; } -static int key_equal(const void *ptr1, const void *ptr2) +int jsonp_key_equal(const void *ptr1, const void *ptr2) { return strcmp(((const object_key_t *)ptr1)->key, ((const object_key_t *)ptr2)->key) == 0; @@ -63,15 +61,16 @@ static void value_decref(void *value) json_t *json_object(void) { - json_object_t *object = malloc(sizeof(json_object_t)); + json_object_t *object = jsonp_malloc(sizeof(json_object_t)); if(!object) return NULL; json_init(&object->json, JSON_OBJECT); - if(hashtable_init(&object->hashtable, hash_key, key_equal, - free, value_decref)) + if(hashtable_init(&object->hashtable, + jsonp_hash_key, jsonp_key_equal, + jsonp_free, value_decref)) { - free(object); + jsonp_free(object); return NULL; } @@ -84,10 +83,10 @@ json_t *json_object(void) static void json_delete_object(json_object_t *object) { hashtable_close(&object->hashtable); - free(object); + jsonp_free(object); } -unsigned int json_object_size(const json_t *json) +size_t json_object_size(const json_t *json) { json_object_t *object; @@ -124,7 +123,10 @@ int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) } object = json_to_object(json); - k = malloc(sizeof(object_key_t) + strlen(key) + 1); + /* offsetof(...) returns the size of object_key_t without the + last, flexible member. This way, the correct amount is + allocated. */ + k = jsonp_malloc(offsetof(object_key_t, key) + strlen(key) + 1); if(!k) return -1; @@ -350,7 +352,7 @@ static json_t *json_object_deep_copy(json_t *object) json_t *json_array(void) { - json_array_t *array = malloc(sizeof(json_array_t)); + json_array_t *array = jsonp_malloc(sizeof(json_array_t)); if(!array) return NULL; json_init(&array->json, JSON_ARRAY); @@ -358,9 +360,9 @@ json_t *json_array(void) array->entries = 0; array->size = 8; - array->table = malloc(array->size * sizeof(json_t *)); + array->table = jsonp_malloc(array->size * sizeof(json_t *)); if(!array->table) { - free(array); + jsonp_free(array); return NULL; } @@ -371,16 +373,16 @@ json_t *json_array(void) static void json_delete_array(json_array_t *array) { - unsigned int i; + size_t i; for(i = 0; i < array->entries; i++) json_decref(array->table[i]); - free(array->table); - free(array); + jsonp_free(array->table); + jsonp_free(array); } -unsigned int json_array_size(const json_t *json) +size_t json_array_size(const json_t *json) { if(!json_is_array(json)) return 0; @@ -388,7 +390,7 @@ unsigned int json_array_size(const json_t *json) return json_to_array(json)->entries; } -json_t *json_array_get(const json_t *json, unsigned int index) +json_t *json_array_get(const json_t *json, size_t index) { json_array_t *array; if(!json_is_array(json)) @@ -401,7 +403,7 @@ json_t *json_array_get(const json_t *json, unsigned int index) return array->table[index]; } -int json_array_set_new(json_t *json, unsigned int index, json_t *value) +int json_array_set_new(json_t *json, size_t index, json_t *value) { json_array_t *array; @@ -427,24 +429,24 @@ int json_array_set_new(json_t *json, unsigned int index, json_t *value) return 0; } -static void array_move(json_array_t *array, unsigned int dest, - unsigned int src, unsigned int count) +static void array_move(json_array_t *array, size_t dest, + size_t src, size_t count) { memmove(&array->table[dest], &array->table[src], count * sizeof(json_t *)); } -static void array_copy(json_t **dest, unsigned int dpos, - json_t **src, unsigned int spos, - unsigned int count) +static void array_copy(json_t **dest, size_t dpos, + json_t **src, size_t spos, + size_t count) { memcpy(&dest[dpos], &src[spos], count * sizeof(json_t *)); } static json_t **json_array_grow(json_array_t *array, - unsigned int amount, + size_t amount, int copy) { - unsigned int new_size; + size_t new_size; json_t **old_table, **new_table; if(array->entries + amount <= array->size) @@ -453,7 +455,7 @@ static json_t **json_array_grow(json_array_t *array, old_table = array->table; new_size = max(array->size + amount, array->size * 2); - new_table = malloc(new_size * sizeof(json_t *)); + new_table = jsonp_malloc(new_size * sizeof(json_t *)); if(!new_table) return NULL; @@ -462,7 +464,7 @@ static json_t **json_array_grow(json_array_t *array, if(copy) { array_copy(array->table, 0, old_table, 0, array->entries); - free(old_table); + jsonp_free(old_table); return array->table; } @@ -494,7 +496,7 @@ int json_array_append_new(json_t *json, json_t *value) return 0; } -int json_array_insert_new(json_t *json, unsigned int index, json_t *value) +int json_array_insert_new(json_t *json, size_t index, json_t *value) { json_array_t *array; json_t **old_table; @@ -523,7 +525,7 @@ int json_array_insert_new(json_t *json, unsigned int index, json_t *value) array_copy(array->table, 0, old_table, 0, index); array_copy(array->table, index + 1, old_table, index, array->entries - index); - free(old_table); + jsonp_free(old_table); } else array_move(array, index + 1, index, array->entries - index); @@ -534,7 +536,7 @@ int json_array_insert_new(json_t *json, unsigned int index, json_t *value) return 0; } -int json_array_remove(json_t *json, unsigned int index) +int json_array_remove(json_t *json, size_t index) { json_array_t *array; @@ -556,7 +558,7 @@ int json_array_remove(json_t *json, unsigned int index) int json_array_clear(json_t *json) { json_array_t *array; - unsigned int i; + size_t i; if(!json_is_array(json)) return -1; @@ -572,7 +574,7 @@ int json_array_clear(json_t *json) int json_array_extend(json_t *json, json_t *other_json) { json_array_t *array, *other; - unsigned int i; + size_t i; if(!json_is_array(json) || !json_is_array(other_json)) return -1; @@ -593,7 +595,7 @@ int json_array_extend(json_t *json, json_t *other_json) static int json_array_equal(json_t *array1, json_t *array2) { - unsigned int i, size; + size_t i, size; size = json_array_size(array1); if(size != json_array_size(array2)) @@ -616,7 +618,7 @@ static int json_array_equal(json_t *array1, json_t *array2) static json_t *json_array_copy(json_t *array) { json_t *result; - unsigned int i; + size_t i; result = json_array(); if(!result) @@ -631,7 +633,7 @@ static json_t *json_array_copy(json_t *array) static json_t *json_array_deep_copy(json_t *array) { json_t *result; - unsigned int i; + size_t i; result = json_array(); if(!result) @@ -652,14 +654,14 @@ json_t *json_string_nocheck(const char *value) if(!value) return NULL; - string = malloc(sizeof(json_string_t)); + string = jsonp_malloc(sizeof(json_string_t)); if(!string) return NULL; json_init(&string->json, JSON_STRING); - string->value = strdup(value); + string->value = jsonp_strdup(value); if(!string->value) { - free(string); + jsonp_free(string); return NULL; } @@ -687,12 +689,12 @@ int json_string_set_nocheck(json_t *json, const char *value) char *dup; json_string_t *string; - dup = strdup(value); + dup = jsonp_strdup(value); if(!dup) return -1; string = json_to_string(json); - free(string->value); + jsonp_free(string->value); string->value = dup; return 0; @@ -708,8 +710,8 @@ int json_string_set(json_t *json, const char *value) static void json_delete_string(json_string_t *string) { - free(string->value); - free(string); + jsonp_free(string->value); + jsonp_free(string); } static int json_string_equal(json_t *string1, json_t *string2) @@ -725,9 +727,9 @@ static json_t *json_string_copy(json_t *string) /*** integer ***/ -json_t *json_integer(int value) +json_t *json_integer(json_int_t value) { - json_integer_t *integer = malloc(sizeof(json_integer_t)); + json_integer_t *integer = jsonp_malloc(sizeof(json_integer_t)); if(!integer) return NULL; json_init(&integer->json, JSON_INTEGER); @@ -736,7 +738,7 @@ json_t *json_integer(int value) return &integer->json; } -int json_integer_value(const json_t *json) +json_int_t json_integer_value(const json_t *json) { if(!json_is_integer(json)) return 0; @@ -744,7 +746,7 @@ int json_integer_value(const json_t *json) return json_to_integer(json)->value; } -int json_integer_set(json_t *json, int value) +int json_integer_set(json_t *json, json_int_t value) { if(!json_is_integer(json)) return -1; @@ -756,7 +758,7 @@ int json_integer_set(json_t *json, int value) static void json_delete_integer(json_integer_t *integer) { - free(integer); + jsonp_free(integer); } static int json_integer_equal(json_t *integer1, json_t *integer2) @@ -774,7 +776,7 @@ static json_t *json_integer_copy(json_t *integer) json_t *json_real(double value) { - json_real_t *real = malloc(sizeof(json_real_t)); + json_real_t *real = jsonp_malloc(sizeof(json_real_t)); if(!real) return NULL; json_init(&real->json, JSON_REAL); @@ -803,7 +805,7 @@ int json_real_set(json_t *json, double value) static void json_delete_real(json_real_t *real) { - free(real); + jsonp_free(real); } static int json_real_equal(json_t *real1, json_t *real2) @@ -834,30 +836,21 @@ double json_number_value(const json_t *json) json_t *json_true(void) { - static json_t the_true = { - JSON_TRUE, - (unsigned int)-1 - }; + static json_t the_true = {JSON_TRUE, (size_t)-1}; return &the_true; } json_t *json_false(void) { - static json_t the_false = { - JSON_FALSE, - (unsigned int)-1 - }; + static json_t the_false = {JSON_FALSE, (size_t)-1}; return &the_false; } json_t *json_null(void) { - static json_t the_null = { - JSON_NULL, - (unsigned int)-1 - }; + static json_t the_null = {JSON_NULL, (size_t)-1}; return &the_null; }