Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c0a3b2a55 | ||
|
|
eab23f05d8 | ||
|
|
0944ac8d91 | ||
|
|
279d8bf108 | ||
|
|
38e35e0973 | ||
|
|
c30e92603c | ||
|
|
6ecba84817 | ||
|
|
b90ed1accb | ||
|
|
1111960120 | ||
|
|
7f09f48e7e | ||
|
|
b397711a66 |
31
CHANGES
31
CHANGES
@@ -1,3 +1,34 @@
|
||||
Version 2.0.1
|
||||
=============
|
||||
|
||||
Released 2011-03-31
|
||||
|
||||
* Bug fixes:
|
||||
|
||||
- Replace a few `malloc()` and `free()` calls with their
|
||||
counterparts that support custom memory management.
|
||||
|
||||
- Fix object key hashing in json_unpack() strict checking mode.
|
||||
|
||||
- Fix the parentheses in JANSSON_VERSION_HEX macro.
|
||||
|
||||
- Fix `json_object_size()` return value.
|
||||
|
||||
- Fix a few compilation issues.
|
||||
|
||||
* Portability:
|
||||
|
||||
- Enhance portability of `va_copy()`.
|
||||
|
||||
- Test framework portability enhancements.
|
||||
|
||||
* Documentation:
|
||||
|
||||
- Distribute ``doc/upgrading.rst`` with the source tarball.
|
||||
|
||||
- Build documentation in strict mode in ``make distcheck``.
|
||||
|
||||
|
||||
Version 2.0
|
||||
===========
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
EXTRA_DIST = CHANGES LICENSE README.rst
|
||||
SUBDIRS = doc src test
|
||||
|
||||
check-doc:
|
||||
# "make distcheck" builds the dvi target, so use it to check that the
|
||||
# documentation is built correctly.
|
||||
dvi:
|
||||
$(MAKE) SPHINXOPTS_EXTRA=-W html
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ([2.60])
|
||||
AC_INIT([jansson], [2.0], [petri@digip.org])
|
||||
AC_INIT([jansson], [2.0.1], [petri@digip.org])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.10 foreign])
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
EXTRA_DIST = conf.py apiref.rst changes.rst conformance.rst \
|
||||
gettingstarted.rst github_commits.c index.rst tutorial.rst \
|
||||
ext/refcounting.py
|
||||
upgrading.rst ext/refcounting.py
|
||||
|
||||
SPHINXBUILD = sphinx-build
|
||||
SPHINXOPTS = -d _build/doctrees $(SPHINXOPTS_EXTRA)
|
||||
|
||||
@@ -50,7 +50,7 @@ copyright = u'2009-2011, Petri Lehtinen'
|
||||
# The short X.Y version.
|
||||
version = '2.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '2.0'
|
||||
release = '2.0.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -17,9 +17,9 @@ libjansson_la_SOURCES = \
|
||||
value.c
|
||||
libjansson_la_LDFLAGS = \
|
||||
-export-symbols-regex '^json_' \
|
||||
-version-info 4:0:0
|
||||
-version-info 4:1:0
|
||||
|
||||
if GCC
|
||||
# These flags are gcc specific
|
||||
AM_CFLAGS = -Wall -Wextra -Werror
|
||||
AM_CFLAGS = -Wall -Wextra -Wdeclaration-after-statement -Werror
|
||||
endif
|
||||
|
||||
@@ -18,10 +18,12 @@ void jsonp_error_init(json_error_t *error, const char *source)
|
||||
|
||||
void jsonp_error_set_source(json_error_t *error, const char *source)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
if(!error || !source)
|
||||
return;
|
||||
|
||||
size_t length = strlen(source);
|
||||
length = strlen(source);
|
||||
if(length < JSON_ERROR_SOURCE_LENGTH)
|
||||
strcpy(error->source, source);
|
||||
else {
|
||||
|
||||
@@ -126,7 +126,7 @@ static int hashtable_do_del(hashtable_t *hashtable,
|
||||
if(hashtable->free_value)
|
||||
hashtable->free_value(pair->value);
|
||||
|
||||
free(pair);
|
||||
jsonp_free(pair);
|
||||
hashtable->size--;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -22,16 +22,16 @@ extern "C" {
|
||||
|
||||
#define JANSSON_MAJOR_VERSION 2
|
||||
#define JANSSON_MINOR_VERSION 0
|
||||
#define JANSSON_MICRO_VERSION 0
|
||||
#define JANSSON_MICRO_VERSION 1
|
||||
|
||||
/* Micro version is omitted if it's 0 */
|
||||
#define JANSSON_VERSION "2.0"
|
||||
#define JANSSON_VERSION "2.0.1"
|
||||
|
||||
/* 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)))
|
||||
(JANSSON_MICRO_VERSION << 0))
|
||||
|
||||
|
||||
/* types */
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#define JANSSON_PRIVATE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include "jansson.h"
|
||||
#include "hashtable.h"
|
||||
|
||||
@@ -21,6 +20,16 @@
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/* va_copy is a C99 feature. In C89 implementations, it's sometimes
|
||||
available as __va_copy. If not, memcpy() should do the trick. */
|
||||
#ifndef va_copy
|
||||
#ifdef __va_copy
|
||||
#define va_copy __va_copy
|
||||
#else
|
||||
#define va_copy(a, b) memcpy(&(a), &(b), sizeof(va_list))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
json_t json;
|
||||
hashtable_t hashtable;
|
||||
@@ -57,8 +66,8 @@ 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);
|
||||
size_t jsonp_hash_str(const void *ptr);
|
||||
int jsonp_str_equal(const void *ptr1, const void *ptr2);
|
||||
|
||||
typedef struct {
|
||||
size_t serial;
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <jansson.h>
|
||||
@@ -840,10 +839,13 @@ 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;
|
||||
|
||||
(void)flags; /* unused */
|
||||
|
||||
stream_data.data = string;
|
||||
stream_data.pos = 0;
|
||||
|
||||
if(lex_init(&lex, string_get, (void *)&stream_data))
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
|
||||
*/
|
||||
hashtable_t key_set;
|
||||
|
||||
if(hashtable_init(&key_set, jsonp_hash_key, jsonp_key_equal, NULL, NULL)) {
|
||||
if(hashtable_init(&key_set, jsonp_hash_str, jsonp_str_equal, NULL, NULL)) {
|
||||
set_error(s, "<internal>", "Out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ int strbuffer_init(strbuffer_t *strbuff)
|
||||
strbuff->size = STRBUFFER_MIN_SIZE;
|
||||
strbuff->length = 0;
|
||||
|
||||
strbuff->value = malloc(strbuff->size);
|
||||
strbuff->value = jsonp_malloc(strbuff->size);
|
||||
if(!strbuff->value)
|
||||
return -1;
|
||||
|
||||
@@ -30,7 +30,7 @@ int strbuffer_init(strbuffer_t *strbuff)
|
||||
|
||||
void strbuffer_close(strbuffer_t *strbuff)
|
||||
{
|
||||
free(strbuff->value);
|
||||
jsonp_free(strbuff->value);
|
||||
strbuff->size = 0;
|
||||
strbuff->length = 0;
|
||||
strbuff->value = NULL;
|
||||
|
||||
37
src/value.c
37
src/value.c
@@ -26,15 +26,10 @@ static JSON_INLINE void json_init(json_t *json, json_type type)
|
||||
|
||||
/*** object ***/
|
||||
|
||||
/* This macro just returns a pointer that's a few bytes backwards from
|
||||
string. This makes it possible to pass a pointer to object_key_t
|
||||
when only the string inside it is used, without actually creating
|
||||
an object_key_t instance. */
|
||||
#define string_to_key(string) container_of(string, object_key_t, key)
|
||||
|
||||
size_t jsonp_hash_key(const void *ptr)
|
||||
/* From http://www.cse.yorku.ca/~oz/hash.html */
|
||||
size_t jsonp_hash_str(const void *ptr)
|
||||
{
|
||||
const char *str = ((const object_key_t *)ptr)->key;
|
||||
const char *str = (const char *)ptr;
|
||||
|
||||
size_t hash = 5381;
|
||||
size_t c;
|
||||
@@ -48,10 +43,26 @@ size_t jsonp_hash_key(const void *ptr)
|
||||
return hash;
|
||||
}
|
||||
|
||||
int jsonp_key_equal(const void *ptr1, const void *ptr2)
|
||||
int jsonp_str_equal(const void *ptr1, const void *ptr2)
|
||||
{
|
||||
return strcmp(((const object_key_t *)ptr1)->key,
|
||||
((const object_key_t *)ptr2)->key) == 0;
|
||||
return strcmp((const char *)ptr1, (const char *)ptr2) == 0;
|
||||
}
|
||||
|
||||
/* This macro just returns a pointer that's a few bytes backwards from
|
||||
string. This makes it possible to pass a pointer to object_key_t
|
||||
when only the string inside it is used, without actually creating
|
||||
an object_key_t instance. */
|
||||
#define string_to_key(string) container_of(string, object_key_t, key)
|
||||
|
||||
static size_t hash_key(const void *ptr)
|
||||
{
|
||||
return jsonp_hash_str(((const object_key_t *)ptr)->key);
|
||||
}
|
||||
|
||||
static int key_equal(const void *ptr1, const void *ptr2)
|
||||
{
|
||||
return jsonp_str_equal(((const object_key_t *)ptr1)->key,
|
||||
((const object_key_t *)ptr2)->key);
|
||||
}
|
||||
|
||||
static void value_decref(void *value)
|
||||
@@ -67,7 +78,7 @@ json_t *json_object(void)
|
||||
json_init(&object->json, JSON_OBJECT);
|
||||
|
||||
if(hashtable_init(&object->hashtable,
|
||||
jsonp_hash_key, jsonp_key_equal,
|
||||
hash_key, key_equal,
|
||||
jsonp_free, value_decref))
|
||||
{
|
||||
jsonp_free(object);
|
||||
@@ -91,7 +102,7 @@ size_t json_object_size(const json_t *json)
|
||||
json_object_t *object;
|
||||
|
||||
if(!json_is_object(json))
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
object = json_to_object(json);
|
||||
return object->hashtable.size;
|
||||
|
||||
@@ -30,31 +30,46 @@ for test_path in $suite_srcdir/*; do
|
||||
rm -rf $test_log
|
||||
mkdir -p $test_log
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo -n "$test_name... "
|
||||
printf '%s... ' "$test_name"
|
||||
fi
|
||||
|
||||
if run_test; then
|
||||
# Success
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo "ok"
|
||||
else
|
||||
echo -n "."
|
||||
fi
|
||||
rm -rf $test_log
|
||||
else
|
||||
# Failure
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo "FAILED"
|
||||
else
|
||||
echo -n "F"
|
||||
fi
|
||||
run_test
|
||||
case $? in
|
||||
0)
|
||||
# Success
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
printf 'ok\n'
|
||||
else
|
||||
printf '.'
|
||||
fi
|
||||
rm -rf $test_log
|
||||
;;
|
||||
|
||||
[ $STOP -eq 1 ] && break
|
||||
fi
|
||||
77)
|
||||
# Skip
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
printf 'skipped\n'
|
||||
else
|
||||
printf 'S'
|
||||
fi
|
||||
rm -rf $test_log
|
||||
;;
|
||||
|
||||
*)
|
||||
# Failure
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
printf 'FAILED\n'
|
||||
else
|
||||
printf 'F'
|
||||
fi
|
||||
|
||||
[ $STOP -eq 1 ] && break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $VERBOSE -eq 0 ]; then
|
||||
echo
|
||||
printf '\n'
|
||||
fi
|
||||
|
||||
if [ -n "$(ls -A $suite_log)" ]; then
|
||||
|
||||
@@ -89,7 +89,10 @@ EOF
|
||||
|
||||
SOFILE="../src/.libs/libjansson.so"
|
||||
|
||||
nm -D $SOFILE | grep ' T ' | cut -d' ' -f3 | sort >$test_log/output
|
||||
nm -D $SOFILE >/dev/null >$test_log/symbols 2>/dev/null \
|
||||
|| exit 77 # Skip if "nm -D" doesn't seem to work
|
||||
|
||||
grep ' T ' $test_log/symbols | cut -d' ' -f3 | sort >$test_log/output
|
||||
|
||||
if ! cmp -s $test_log/exports $test_log/output; then
|
||||
diff -u $test_log/exports $test_log/output >&2
|
||||
|
||||
@@ -122,6 +122,13 @@ int main()
|
||||
fail("json_unpack simple array failed");
|
||||
json_decref(j);
|
||||
|
||||
/* object with many items & strict checking */
|
||||
j = json_pack("{s:i, s:i, s:i}", "a", 1, "b", 2, "c", 3);
|
||||
rv = json_unpack(j, "{s:i, s:i, s:i}", "a", &i1, "b", &i2, "c", &i3);
|
||||
if(rv || i1 != 1 || i2 != 2 || i3 != 3)
|
||||
fail("json_unpack object with many items failed");
|
||||
json_decref(j);
|
||||
|
||||
/*
|
||||
* Invalid cases
|
||||
*/
|
||||
@@ -285,7 +292,7 @@ int main()
|
||||
/* Unpack the same item twice */
|
||||
j = json_pack("{s:s, s:i}", "foo", "bar", "baz", 42);
|
||||
if(!json_unpack_ex(j, &error, 0, "{s:s,s:s!}", "foo", &s, "foo", &s))
|
||||
fail("json_unpack object with strict validation failed");
|
||||
fail("json_unpack object with strict validation failed");
|
||||
check_error("1 object item(s) left unpacked", "<validation>", 1, 10, 10);
|
||||
json_decref(j);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user