Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2caac965d4 | ||
|
|
1347686dbf | ||
|
|
8b2b12e05f | ||
|
|
1a090bbcd3 | ||
|
|
dec3ad498e | ||
|
|
978a47e2c5 | ||
|
|
453e4c0aa2 | ||
|
|
2630980f49 | ||
|
|
782acfe378 | ||
|
|
f9475f9577 | ||
|
|
8857aeadfd | ||
|
|
047a1417fb | ||
|
|
ce42e30b8c | ||
|
|
4e63fcd55d | ||
|
|
024106bbfb | ||
|
|
29ee3832cf | ||
|
|
c7c2edae8a | ||
|
|
bb89a5d4d3 | ||
|
|
f76966b438 | ||
|
|
49880cbabe | ||
|
|
f284e3c069 | ||
|
|
66a69f3f10 | ||
|
|
7d5982e6fe | ||
|
|
a2a9107600 | ||
|
|
42621370c3 | ||
|
|
8e61b7c0f0 | ||
|
|
35ddd2de20 | ||
|
|
f18ef5144a | ||
|
|
307167fb66 | ||
|
|
7e8b128740 | ||
|
|
acec2559a5 | ||
|
|
286823227c | ||
|
|
8d75235ff2 | ||
|
|
79e9dae9a0 | ||
|
|
f021ba00a2 | ||
|
|
adb1b58627 | ||
|
|
b8059a1880 | ||
|
|
49d40f020b | ||
|
|
910a2f318b | ||
|
|
08dc8d9baf | ||
|
|
c9fc055351 | ||
|
|
d1a0c3ffc2 | ||
|
|
b07e69c37a | ||
|
|
2b43e7dbda | ||
|
|
5b1a666cf1 | ||
|
|
b495b96547 | ||
|
|
72e3948438 | ||
|
|
f5662a82cd | ||
|
|
ab2e567685 | ||
|
|
d8ea2f8c4b | ||
|
|
aaae37afba | ||
|
|
04f7e27877 | ||
|
|
3dd29366b8 | ||
|
|
38950b081c | ||
|
|
56687e9b56 | ||
|
|
c9b33e3386 | ||
|
|
2ad4634de5 | ||
|
|
e080667729 | ||
|
|
ef6c35ae1b | ||
|
|
95bf762eeb | ||
|
|
dd36e4e838 | ||
|
|
df35adc438 | ||
|
|
f88a5a0e6b | ||
|
|
cc06bc334a | ||
|
|
2dc2b6bab7 | ||
|
|
49a64a6edf | ||
|
|
f0be52f9f8 | ||
|
|
1bc0225441 | ||
|
|
87df8bb0fe | ||
|
|
69437a7183 | ||
|
|
63f762bc48 | ||
|
|
5a0efe6536 | ||
|
|
01759517aa | ||
|
|
17805e5829 | ||
|
|
492d95329a | ||
|
|
7ba18d3f0a | ||
|
|
7d09af38c1 | ||
|
|
8d3a9e347c | ||
|
|
f79a81dad9 | ||
|
|
b98e9d180c | ||
|
|
8d5d2a93d5 | ||
|
|
d77c2e3fb0 | ||
|
|
7ef3202f83 | ||
|
|
36085ab49a | ||
|
|
f743c4ee7f | ||
|
|
c994eddec4 | ||
|
|
5a20e2695b | ||
|
|
cd18aa97f0 | ||
|
|
bd09127859 | ||
|
|
6818c117ee | ||
|
|
39601c183a | ||
|
|
1e3b41e8ea |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
*~
|
||||
*.o
|
||||
*.a
|
||||
.libs
|
||||
@@ -23,3 +24,4 @@ missing
|
||||
stamp-h1
|
||||
*.pyc
|
||||
*.pc
|
||||
/src/jansson.h
|
||||
|
||||
55
CHANGES
55
CHANGES
@@ -1,3 +1,58 @@
|
||||
Version 1.3
|
||||
===========
|
||||
|
||||
Released 2010-06-13
|
||||
|
||||
* New encoding flags:
|
||||
|
||||
- ``JSON_PRESERVE_ORDER``: Preserve the insertion order of object
|
||||
keys.
|
||||
|
||||
* Bug fixes:
|
||||
|
||||
- Fix an error that occured when an array or object was first
|
||||
encoded as empty, then populated with some data, and then
|
||||
re-encoded
|
||||
|
||||
- Fix the situation like above, but when the first encoding resulted
|
||||
in an error
|
||||
|
||||
* Documentation:
|
||||
|
||||
- Clarify the documentation on reference stealing, providing an
|
||||
example usage pattern
|
||||
|
||||
|
||||
Version 1.2.1
|
||||
=============
|
||||
|
||||
Released 2010-04-03
|
||||
|
||||
* Bug fixes:
|
||||
|
||||
- Fix reference counting on ``true``, ``false`` and ``null``
|
||||
- Estimate real number underflows in decoder with 0.0 instead of
|
||||
issuing an error
|
||||
|
||||
* Portability:
|
||||
|
||||
- Make ``int32_t`` available on all systems
|
||||
- Support compilers that don't have the ``inline`` keyword
|
||||
- Require Autoconf 2.60 (for ``int32_t``)
|
||||
|
||||
* Tests:
|
||||
|
||||
- Print test names correctly when ``VERBOSE=1``
|
||||
- ``test/suites/api``: Fail when a test fails
|
||||
- Enhance tests for iterators
|
||||
- Enhance tests for decoding texts that contain null bytes
|
||||
|
||||
* Documentation:
|
||||
|
||||
- Don't remove ``changes.rst`` in ``make clean``
|
||||
- Add a chapter on RFC conformance
|
||||
|
||||
|
||||
Version 1.2
|
||||
===========
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
15
configure.ac
15
configure.ac
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ([2.59])
|
||||
AC_INIT([jansson], [1.2], [petri@digip.org])
|
||||
AC_PREREQ([2.60])
|
||||
AC_INIT([jansson], [1.3], [petri@digip.org])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.10 foreign])
|
||||
|
||||
@@ -8,6 +8,7 @@ AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
# Checks for libraries.
|
||||
@@ -15,6 +16,15 @@ AC_PROG_LIBTOOL
|
||||
# Checks for header files.
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_TYPE_INT32_T
|
||||
|
||||
AC_C_INLINE
|
||||
case $ac_cv_c_inline in
|
||||
yes) json_inline=inline;;
|
||||
no) json_inline=;;
|
||||
*) json_inline=$ac_cv_c_inline;;
|
||||
esac
|
||||
AC_SUBST([json_inline])
|
||||
|
||||
# Checks for library functions.
|
||||
|
||||
@@ -23,6 +33,7 @@ AC_CONFIG_FILES([
|
||||
Makefile
|
||||
doc/Makefile
|
||||
src/Makefile
|
||||
src/jansson.h
|
||||
test/Makefile
|
||||
test/bin/Makefile
|
||||
test/suites/Makefile
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
EXTRA_DIST = conf.py apiref.rst changes.rst gettingstarted.rst \
|
||||
github_commits.c index.rst tutorial.rst ext/refcounting.py
|
||||
EXTRA_DIST = conf.py apiref.rst changes.rst conformance.rst \
|
||||
gettingstarted.rst github_commits.c index.rst tutorial.rst \
|
||||
ext/refcounting.py
|
||||
|
||||
SPHINXBUILD = sphinx-build
|
||||
SPHINXOPTS = -d _build/doctrees -W
|
||||
@@ -16,4 +17,4 @@ uninstall-local:
|
||||
|
||||
clean-local:
|
||||
rm -rf _build
|
||||
rm -f ext/refcounting.pyc changes.rst
|
||||
rm -f ext/refcounting.pyc
|
||||
|
||||
@@ -154,9 +154,31 @@ Normally, all functions accepting a JSON value as an argument will
|
||||
manage the reference, i.e. increase and decrease the reference count
|
||||
as needed. However, some functions **steal** the reference, i.e. they
|
||||
have the same result as if the user called :cfunc:`json_decref()` on
|
||||
the argument right after calling the function. These are usually
|
||||
convenience functions for adding new references to containers and not
|
||||
to worry about the reference count.
|
||||
the argument right after calling the function. These functions are
|
||||
suffixed with ``_new`` or have ``_new_`` somewhere in their name.
|
||||
|
||||
For example, the following code creates a new JSON array and appends
|
||||
an integer to it::
|
||||
|
||||
json_t *array, *integer;
|
||||
|
||||
array = json_array();
|
||||
integer = json_integer(42);
|
||||
|
||||
json_array_append(array, integer);
|
||||
json_decref(integer);
|
||||
|
||||
Note how the caller has to release the reference to the integer value
|
||||
by calling :cfunc:`json_decref()`. By using a reference stealing
|
||||
function :cfunc:`json_array_append_new()` instead of
|
||||
:cfunc:`json_array_append()`, the code becomes much simpler::
|
||||
|
||||
json_t *array = json_array();
|
||||
json_array_append_new(array, json_integer(42));
|
||||
|
||||
In this case, the user doesn't have to explicitly release the
|
||||
reference to the integer value, as :cfunc:`json_array_append_new()`
|
||||
steals the reference when appending the value to the array.
|
||||
|
||||
In the following sections it is clearly documented whether a function
|
||||
will return a new or borrowed reference or steal a reference to its
|
||||
@@ -493,6 +515,16 @@ The following functions implement an iteration protocol for objects:
|
||||
Returns an opaque iterator which can be used to iterate over all
|
||||
key-value pairs in *object*, or *NULL* if *object* is empty.
|
||||
|
||||
.. cfunction:: void *json_object_iter_at(json_t *object, const char *key)
|
||||
|
||||
Like :cfunc:`json_object_iter()`, but returns an iterator to the
|
||||
key-value pair in *object* whose key is equal to *key*, or NULL if
|
||||
*key* is not found in *object*. Iterating forward to the end of
|
||||
*object* only yields all key-value pairs of the object if *key*
|
||||
happens to be the first key in the underlying hash table.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. cfunction:: void *json_object_iter_next(json_t *object, void *iter)
|
||||
|
||||
Returns an iterator pointing to the next key-value pair in *object*
|
||||
@@ -509,6 +541,21 @@ The following functions implement an iteration protocol for objects:
|
||||
|
||||
Extract the associated value from *iter*.
|
||||
|
||||
.. cfunction:: int json_object_iter_set(json_t *object, void *iter, json_t *value)
|
||||
|
||||
Set the value of the key-value pair in *object*, that is pointed to
|
||||
by *iter*, to *value*.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. cfunction:: int json_object_iter_set_new(json_t *object, void *iter, json_t *value)
|
||||
|
||||
Like :cfunc:`json_object_iter_set()`, but steals the reference to
|
||||
*value*. This is useful when *value* is newly created and not used
|
||||
after the call.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
The iteration protocol can be used for example as follows::
|
||||
|
||||
/* obj is a JSON object */
|
||||
@@ -570,6 +617,14 @@ can be ORed together to obtain *flags*.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
``JSON_PRESERVE_ORDER``
|
||||
If this flag is used, object keys in the output are sorted into the
|
||||
same order in which they were first inserted to the object. For
|
||||
example, decoding a JSON text and then encoding with this flag
|
||||
preserves the order of object keys.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
The following functions perform the actual JSON encoding. The result
|
||||
is in UTF-8.
|
||||
|
||||
|
||||
@@ -43,16 +43,16 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Jansson'
|
||||
copyright = u'2009, Petri Lehtinen'
|
||||
copyright = u'2009, 2010 Petri Lehtinen'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.2'
|
||||
version = '1.3'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.2'
|
||||
release = '1.3'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
102
doc/conformance.rst
Normal file
102
doc/conformance.rst
Normal file
@@ -0,0 +1,102 @@
|
||||
***************
|
||||
RFC Conformance
|
||||
***************
|
||||
|
||||
JSON is specified in :rfc:`4627`, *"The application/json Media Type
|
||||
for JavaScript Object Notation (JSON)"*. This chapter discusses
|
||||
Jansson's conformance to this specification.
|
||||
|
||||
Character Encoding
|
||||
==================
|
||||
|
||||
Jansson only supports UTF-8 encoded JSON texts. It does not support or
|
||||
auto-detect any of the other encodings mentioned in the RFC, namely
|
||||
UTF-16LE, UTF-16BE, UTF-32LE or UTF-32BE. Pure ASCII is supported, as
|
||||
it's a subset of UTF-8.
|
||||
|
||||
Strings
|
||||
=======
|
||||
|
||||
JSON strings are mapped to C-style null-terminated character arrays,
|
||||
and UTF-8 encoding is used internally. Strings may not contain
|
||||
embedded null characters, not even escaped ones.
|
||||
|
||||
For example, trying to decode the following JSON text leads to a parse
|
||||
error::
|
||||
|
||||
["this string contains the null character: \u0000"]
|
||||
|
||||
All other Unicode codepoints U+0001 through U+10FFFF are allowed.
|
||||
|
||||
Numbers
|
||||
=======
|
||||
|
||||
Real vs. Integer
|
||||
----------------
|
||||
|
||||
JSON makes no distinction between real and integer numbers; Jansson
|
||||
does. Real numbers are mapped to the ``double`` type and integers to
|
||||
the ``int`` type.
|
||||
|
||||
A JSON number is considered to be a real number if its lexical
|
||||
representation includes one of ``e``, ``E``, or ``.``; regardless if
|
||||
its actual numeric value is a true integer (e.g., all of ``1E6``,
|
||||
``3.0``, ``400E-2``, and ``3.14E3`` are mathematical integers, but
|
||||
will be treated as real values).
|
||||
|
||||
All other JSON numbers are considered integers.
|
||||
|
||||
When encoding to JSON, real values are always represented
|
||||
with a fractional part; e.g., the ``double`` value 3.0 will be
|
||||
represented in JSON as ``3.0``, not ``3``.
|
||||
|
||||
Overflow, Underflow & Precision
|
||||
-------------------------------
|
||||
|
||||
Real numbers whose absolute values are too small to be represented in
|
||||
a C double will be silently estimated with 0.0. Thus, depending on
|
||||
platform, JSON numbers very close to zero such as 1E-999 may result in
|
||||
0.0.
|
||||
|
||||
Real numbers whose absolute values are too large to be represented in
|
||||
a C ``double`` type will result in an overflow error (a JSON decoding
|
||||
error). Thus, depending on platform, JSON numbers like 1E+999 or
|
||||
-1E+999 may result in a parsing error.
|
||||
|
||||
Likewise, integer numbers whose absolute values are too large to be
|
||||
represented in the ``int`` type will result in an overflow error (a
|
||||
JSON decoding error). Thus, depending on platform, JSON numbers like
|
||||
1000000000000000 may result in parsing error.
|
||||
|
||||
Parsing JSON real numbers may result in a loss of precision. As long
|
||||
as overflow does not occur (i.e. a total loss of precision), the
|
||||
rounded approximate value is silently used. Thus the JSON number
|
||||
1.000000000000000005 may, depending on platform, result in the
|
||||
``double`` value 1.0.
|
||||
|
||||
Signed zeros
|
||||
------------
|
||||
|
||||
JSON makes no statement about what a number means; however Javascript
|
||||
(ECMAscript) does state that +0.0 and -0.0 must be treated as being
|
||||
distinct values, i.e. -0.0 |not-equal| 0.0. Jansson relies on the
|
||||
underlying floating point library in the C environment in which it is
|
||||
compiled. Therefore it is platform-dependent whether 0.0 and -0.0 will
|
||||
be distinct values. Most platforms that use the IEEE 754
|
||||
floating-point standard will support signed zeros.
|
||||
|
||||
Note that this only applies to floating-point; neither JSON, C, or
|
||||
IEEE support the concept of signed integer zeros.
|
||||
|
||||
.. |not-equal| unicode:: U+2260
|
||||
|
||||
Types
|
||||
-----
|
||||
|
||||
No support is provided in Jansson for any C numeric types other than
|
||||
``int`` and ``double``. This excludes things such as unsigned types,
|
||||
``long``, ``long long``, ``long double``, etc. Obviously, shorter
|
||||
types like ``short`` and ``float`` are implicitly handled via the
|
||||
ordinary C type coercion rules (subject to overflow semantics). Also,
|
||||
no support or hooks are provided for any supplemental "bignum" type
|
||||
add-on packages.
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
<description of the json_object function>
|
||||
|
||||
:copyright: Copyright 2009 Petri Lehtinen <petri@digip.org>
|
||||
:copyright: Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
:license: MIT, see LICENSE for details.
|
||||
"""
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -34,6 +34,7 @@ Contents
|
||||
|
||||
gettingstarted
|
||||
tutorial
|
||||
conformance
|
||||
apiref
|
||||
changes
|
||||
|
||||
|
||||
@@ -15,6 +15,6 @@ libjansson_la_SOURCES = \
|
||||
value.c
|
||||
libjansson_la_LDFLAGS = \
|
||||
-export-symbols-regex '^json_' \
|
||||
-version-info 2:0:2
|
||||
-version-info 3:0:3
|
||||
|
||||
AM_CFLAGS = -Wall -Wextra -Werror
|
||||
|
||||
82
src/dump.c
82
src/dump.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <jansson.h>
|
||||
@@ -154,9 +153,16 @@ static int dump_string(const char *str, int ascii, dump_func dump, void *data)
|
||||
return dump("\"", 1, data);
|
||||
}
|
||||
|
||||
static int object_key_cmp(const void *key1, const void *key2)
|
||||
static int object_key_compare_keys(const void *key1, const void *key2)
|
||||
{
|
||||
return strcmp(*(const char **)key1, *(const char **)key2);
|
||||
return strcmp((*(const object_key_t **)key1)->key,
|
||||
(*(const object_key_t **)key2)->key);
|
||||
}
|
||||
|
||||
static int object_key_compare_serials(const void *key1, const void *key2)
|
||||
{
|
||||
return (*(const object_key_t **)key1)->serial -
|
||||
(*(const object_key_t **)key2)->serial;
|
||||
}
|
||||
|
||||
static int do_dump(const json_t *json, unsigned long flags, int depth,
|
||||
@@ -225,38 +231,44 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
||||
/* detect circular references */
|
||||
array = json_to_array(json);
|
||||
if(array->visited)
|
||||
return -1;
|
||||
goto array_error;
|
||||
array->visited = 1;
|
||||
|
||||
n = json_array_size(json);
|
||||
|
||||
if(dump("[", 1, data))
|
||||
return -1;
|
||||
if(n == 0)
|
||||
goto array_error;
|
||||
if(n == 0) {
|
||||
array->visited = 0;
|
||||
return dump("]", 1, data);
|
||||
}
|
||||
if(dump_indent(flags, depth + 1, 0, dump, data))
|
||||
return -1;
|
||||
goto array_error;
|
||||
|
||||
for(i = 0; i < n; ++i) {
|
||||
if(do_dump(json_array_get(json, i), flags, depth + 1,
|
||||
dump, data))
|
||||
return -1;
|
||||
goto array_error;
|
||||
|
||||
if(i < n - 1)
|
||||
{
|
||||
if(dump(",", 1, data) ||
|
||||
dump_indent(flags, depth + 1, 1, dump, data))
|
||||
return -1;
|
||||
goto array_error;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dump_indent(flags, depth, 0, dump, data))
|
||||
return -1;
|
||||
goto array_error;
|
||||
}
|
||||
}
|
||||
|
||||
array->visited = 0;
|
||||
return dump("]", 1, data);
|
||||
|
||||
array_error:
|
||||
array->visited = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
case JSON_OBJECT:
|
||||
@@ -278,48 +290,54 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
||||
/* detect circular references */
|
||||
object = json_to_object(json);
|
||||
if(object->visited)
|
||||
return -1;
|
||||
goto object_error;
|
||||
object->visited = 1;
|
||||
|
||||
iter = json_object_iter((json_t *)json);
|
||||
|
||||
if(dump("{", 1, data))
|
||||
return -1;
|
||||
if(!iter)
|
||||
goto object_error;
|
||||
if(!iter) {
|
||||
object->visited = 0;
|
||||
return dump("}", 1, data);
|
||||
}
|
||||
if(dump_indent(flags, depth + 1, 0, dump, data))
|
||||
return -1;
|
||||
goto object_error;
|
||||
|
||||
if(flags & JSON_SORT_KEYS)
|
||||
if(flags & JSON_SORT_KEYS || flags & JSON_PRESERVE_ORDER)
|
||||
{
|
||||
/* Sort keys */
|
||||
|
||||
const char **keys;
|
||||
const object_key_t **keys;
|
||||
unsigned int size;
|
||||
unsigned int i;
|
||||
int (*cmp_func)(const void *, const void *);
|
||||
|
||||
size = json_object_size(json);
|
||||
keys = malloc(size * sizeof(const char *));
|
||||
keys = malloc(size * sizeof(object_key_t *));
|
||||
if(!keys)
|
||||
return -1;
|
||||
goto object_error;
|
||||
|
||||
i = 0;
|
||||
while(iter)
|
||||
{
|
||||
keys[i] = json_object_iter_key(iter);
|
||||
keys[i] = jsonp_object_iter_fullkey(iter);
|
||||
iter = json_object_iter_next((json_t *)json, iter);
|
||||
i++;
|
||||
}
|
||||
assert(i == size);
|
||||
|
||||
qsort(keys, size, sizeof(const char *), object_key_cmp);
|
||||
if(flags & JSON_SORT_KEYS)
|
||||
cmp_func = object_key_compare_keys;
|
||||
else
|
||||
cmp_func = object_key_compare_serials;
|
||||
|
||||
qsort(keys, size, sizeof(object_key_t *), cmp_func);
|
||||
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
const char *key;
|
||||
json_t *value;
|
||||
|
||||
key = keys[i];
|
||||
key = keys[i]->key;
|
||||
value = json_object_get(json, key);
|
||||
assert(value);
|
||||
|
||||
@@ -328,7 +346,7 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
||||
do_dump(value, flags, depth + 1, dump, data))
|
||||
{
|
||||
free(keys);
|
||||
return -1;
|
||||
goto object_error;
|
||||
}
|
||||
|
||||
if(i < size - 1)
|
||||
@@ -337,7 +355,7 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
||||
dump_indent(flags, depth + 1, 1, dump, data))
|
||||
{
|
||||
free(keys);
|
||||
return -1;
|
||||
goto object_error;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -345,7 +363,7 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
||||
if(dump_indent(flags, depth, 0, dump, data))
|
||||
{
|
||||
free(keys);
|
||||
return -1;
|
||||
goto object_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -364,18 +382,18 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
||||
if(dump(separator, separator_length, data) ||
|
||||
do_dump(json_object_iter_value(iter), flags, depth + 1,
|
||||
dump, data))
|
||||
return -1;
|
||||
goto object_error;
|
||||
|
||||
if(next)
|
||||
{
|
||||
if(dump(",", 1, data) ||
|
||||
dump_indent(flags, depth + 1, 1, dump, data))
|
||||
return -1;
|
||||
goto object_error;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dump_indent(flags, depth, 0, dump, data))
|
||||
return -1;
|
||||
goto object_error;
|
||||
}
|
||||
|
||||
iter = next;
|
||||
@@ -384,6 +402,10 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
||||
|
||||
object->visited = 0;
|
||||
return dump("}", 1, data);
|
||||
|
||||
object_error:
|
||||
object->visited = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include "hashtable.h"
|
||||
|
||||
@@ -247,31 +249,39 @@ int hashtable_set(hashtable_t *hashtable, void *key, void *value)
|
||||
bucket_t *bucket;
|
||||
unsigned int hash, index;
|
||||
|
||||
hash = hashtable->hash_key(key);
|
||||
|
||||
/* if the key already exists, delete it */
|
||||
hashtable_do_del(hashtable, key, hash);
|
||||
|
||||
/* rehash if the load ratio exceeds 1 */
|
||||
if(hashtable->size >= num_buckets(hashtable))
|
||||
if(hashtable_do_rehash(hashtable))
|
||||
return -1;
|
||||
|
||||
pair = malloc(sizeof(pair_t));
|
||||
if(!pair)
|
||||
return -1;
|
||||
|
||||
pair->key = key;
|
||||
pair->value = value;
|
||||
pair->hash = hash;
|
||||
list_init(&pair->list);
|
||||
|
||||
hash = hashtable->hash_key(key);
|
||||
index = hash % num_buckets(hashtable);
|
||||
bucket = &hashtable->buckets[index];
|
||||
pair = hashtable_find_pair(hashtable, bucket, key, hash);
|
||||
|
||||
insert_to_bucket(hashtable, bucket, &pair->list);
|
||||
if(pair)
|
||||
{
|
||||
if(hashtable->free_key)
|
||||
hashtable->free_key(key);
|
||||
if(hashtable->free_value)
|
||||
hashtable->free_value(pair->value);
|
||||
pair->value = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
pair = malloc(sizeof(pair_t));
|
||||
if(!pair)
|
||||
return -1;
|
||||
|
||||
hashtable->size++;
|
||||
pair->key = key;
|
||||
pair->value = value;
|
||||
pair->hash = hash;
|
||||
list_init(&pair->list);
|
||||
|
||||
insert_to_bucket(hashtable, bucket, &pair->list);
|
||||
|
||||
hashtable->size++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -318,6 +328,22 @@ void *hashtable_iter(hashtable_t *hashtable)
|
||||
return hashtable_iter_next(hashtable, &hashtable->list);
|
||||
}
|
||||
|
||||
void *hashtable_iter_at(hashtable_t *hashtable, const void *key)
|
||||
{
|
||||
pair_t *pair;
|
||||
unsigned int hash;
|
||||
bucket_t *bucket;
|
||||
|
||||
hash = hashtable->hash_key(key);
|
||||
bucket = &hashtable->buckets[hash % num_buckets(hashtable)];
|
||||
|
||||
pair = hashtable_find_pair(hashtable, bucket, key, hash);
|
||||
if(!pair)
|
||||
return NULL;
|
||||
|
||||
return &pair->list;
|
||||
}
|
||||
|
||||
void *hashtable_iter_next(hashtable_t *hashtable, void *iter)
|
||||
{
|
||||
list_t *list = (list_t *)iter;
|
||||
@@ -337,3 +363,13 @@ void *hashtable_iter_value(void *iter)
|
||||
pair_t *pair = list_to_pair((list_t *)iter);
|
||||
return pair->value;
|
||||
}
|
||||
|
||||
void hashtable_iter_set(hashtable_t *hashtable, void *iter, void *value)
|
||||
{
|
||||
pair_t *pair = list_to_pair((list_t *)iter);
|
||||
|
||||
if(hashtable->free_value)
|
||||
hashtable->free_value(pair->value);
|
||||
|
||||
pair->value = value;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -160,6 +160,17 @@ void hashtable_clear(hashtable_t *hashtable);
|
||||
*/
|
||||
void *hashtable_iter(hashtable_t *hashtable);
|
||||
|
||||
/**
|
||||
* hashtable_iter_at - Return an iterator at a specific key
|
||||
*
|
||||
* @hashtable: The hashtable object
|
||||
* @key: The key that the iterator should point to
|
||||
*
|
||||
* Like hashtable_iter() but returns an iterator pointing to a
|
||||
* specific key.
|
||||
*/
|
||||
void *hashtable_iter_at(hashtable_t *hashtable, const void *key);
|
||||
|
||||
/**
|
||||
* hashtable_iter_next - Advance an iterator
|
||||
*
|
||||
@@ -185,4 +196,12 @@ void *hashtable_iter_key(void *iter);
|
||||
*/
|
||||
void *hashtable_iter_value(void *iter);
|
||||
|
||||
/**
|
||||
* hashtable_iter_set - Set the value pointed by an iterator
|
||||
*
|
||||
* @iter: The iterator
|
||||
* @value: The value to set
|
||||
*/
|
||||
void hashtable_iter_set(hashtable_t *hashtable, void *iter, void *value);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -10,7 +10,10 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef __cplusplus
|
||||
#define JSON_INLINE @json_inline@
|
||||
#else
|
||||
#define JSON_INLINE inline
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -56,7 +59,8 @@ json_t *json_true(void);
|
||||
json_t *json_false(void);
|
||||
json_t *json_null(void);
|
||||
|
||||
static inline json_t *json_incref(json_t *json)
|
||||
static JSON_INLINE
|
||||
json_t *json_incref(json_t *json)
|
||||
{
|
||||
if(json && json->refcount != (unsigned int)-1)
|
||||
++json->refcount;
|
||||
@@ -66,7 +70,8 @@ static inline json_t *json_incref(json_t *json)
|
||||
/* do not call json_delete directly */
|
||||
void json_delete(json_t *json);
|
||||
|
||||
static inline void json_decref(json_t *json)
|
||||
static JSON_INLINE
|
||||
void json_decref(json_t *json)
|
||||
{
|
||||
if(json && json->refcount != (unsigned int)-1 && --json->refcount == 0)
|
||||
json_delete(json);
|
||||
@@ -83,22 +88,30 @@ int json_object_del(json_t *object, const char *key);
|
||||
int json_object_clear(json_t *object);
|
||||
int json_object_update(json_t *object, json_t *other);
|
||||
void *json_object_iter(json_t *object);
|
||||
void *json_object_iter_at(json_t *object, const char *key);
|
||||
void *json_object_iter_next(json_t *object, void *iter);
|
||||
const char *json_object_iter_key(void *iter);
|
||||
json_t *json_object_iter_value(void *iter);
|
||||
int json_object_iter_set_new(json_t *object, void *iter, json_t *value);
|
||||
|
||||
static inline
|
||||
static JSON_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 inline
|
||||
static JSON_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 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);
|
||||
@@ -108,19 +121,19 @@ int json_array_remove(json_t *array, unsigned int index);
|
||||
int json_array_clear(json_t *array);
|
||||
int json_array_extend(json_t *array, json_t *other);
|
||||
|
||||
static inline
|
||||
static JSON_INLINE
|
||||
int json_array_set(json_t *array, unsigned int index, json_t *value)
|
||||
{
|
||||
return json_array_set_new(array, index, json_incref(value));
|
||||
}
|
||||
|
||||
static inline
|
||||
static JSON_INLINE
|
||||
int json_array_append(json_t *array, json_t *value)
|
||||
{
|
||||
return json_array_append_new(array, json_incref(value));
|
||||
}
|
||||
|
||||
static inline
|
||||
static JSON_INLINE
|
||||
int json_array_insert(json_t *array, unsigned int index, json_t *value)
|
||||
{
|
||||
return json_array_insert_new(array, index, json_incref(value));
|
||||
@@ -165,6 +178,7 @@ json_t *json_load_file(const char *path, json_error_t *error);
|
||||
#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);
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -17,6 +17,7 @@
|
||||
typedef struct {
|
||||
json_t json;
|
||||
hashtable_t hashtable;
|
||||
unsigned long serial;
|
||||
int visited;
|
||||
} json_object_t;
|
||||
|
||||
@@ -49,4 +50,11 @@ 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)
|
||||
|
||||
typedef struct {
|
||||
unsigned long serial;
|
||||
char key[];
|
||||
} object_key_t;
|
||||
|
||||
const object_key_t *jsonp_object_iter_fullkey(void *iter);
|
||||
|
||||
#endif
|
||||
|
||||
15
src/load.c
15
src/load.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <jansson.h>
|
||||
#include "jansson_private.h"
|
||||
@@ -114,7 +113,8 @@ static void error_set(json_error_t *error, const lex_t *lex,
|
||||
|
||||
/*** lexical analyzer ***/
|
||||
|
||||
void stream_init(stream_t *stream, get_func get, eof_func eof, void *data)
|
||||
static void
|
||||
stream_init(stream_t *stream, get_func get, eof_func eof, void *data)
|
||||
{
|
||||
stream->get = get;
|
||||
stream->eof = eof;
|
||||
@@ -484,14 +484,7 @@ static int lex_scan_number(lex_t *lex, char c, json_error_t *error)
|
||||
value = strtod(saved_text, &end);
|
||||
assert(end == saved_text + lex->saved_text.length);
|
||||
|
||||
if(value == 0 && errno == ERANGE) {
|
||||
error_set(error, lex, "real number underflow");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Cannot test for +/-HUGE_VAL because the HUGE_VAL constant is
|
||||
only defined in C99 mode. So let's trust in sole errno. */
|
||||
else if(errno == ERANGE) {
|
||||
if(errno == ERANGE && value != 0) {
|
||||
error_set(error, lex, "real number overflow");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "utf.h"
|
||||
|
||||
int utf8_encode(int32_t codepoint, char *buffer, int *size)
|
||||
{
|
||||
|
||||
11
src/utf.h
11
src/utf.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -8,6 +8,15 @@
|
||||
#ifndef UTF_H
|
||||
#define UTF_H
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#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 <inttypes.h>
|
||||
#endif
|
||||
|
||||
int utf8_encode(int codepoint, char *buffer, int *size);
|
||||
|
||||
int utf8_check_first(char byte);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
78
src/value.c
78
src/value.c
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -25,9 +28,16 @@ static inline void json_init(json_t *json, json_type type)
|
||||
|
||||
/*** object ***/
|
||||
|
||||
static unsigned int hash_string(const void *key)
|
||||
/* 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 unsigned int hash_key(const void *ptr)
|
||||
{
|
||||
const char *str = (const char *)key;
|
||||
const char *str = ((const object_key_t *)ptr)->key;
|
||||
|
||||
unsigned int hash = 5381;
|
||||
unsigned int c;
|
||||
|
||||
@@ -40,9 +50,10 @@ static unsigned int hash_string(const void *key)
|
||||
return hash;
|
||||
}
|
||||
|
||||
static int string_equal(const void *key1, const void *key2)
|
||||
static int key_equal(const void *ptr1, const void *ptr2)
|
||||
{
|
||||
return strcmp((const char *)key1, (const char *)key2) == 0;
|
||||
return strcmp(((const object_key_t *)ptr1)->key,
|
||||
((const object_key_t *)ptr2)->key) == 0;
|
||||
}
|
||||
|
||||
static void value_decref(void *value)
|
||||
@@ -57,13 +68,14 @@ json_t *json_object(void)
|
||||
return NULL;
|
||||
json_init(&object->json, JSON_OBJECT);
|
||||
|
||||
if(hashtable_init(&object->hashtable, hash_string, string_equal,
|
||||
if(hashtable_init(&object->hashtable, hash_key, key_equal,
|
||||
free, value_decref))
|
||||
{
|
||||
free(object);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
object->serial = 0;
|
||||
object->visited = 0;
|
||||
|
||||
return &object->json;
|
||||
@@ -94,12 +106,13 @@ json_t *json_object_get(const json_t *json, const char *key)
|
||||
return NULL;
|
||||
|
||||
object = json_to_object(json);
|
||||
return hashtable_get(&object->hashtable, key);
|
||||
return hashtable_get(&object->hashtable, string_to_key(key));
|
||||
}
|
||||
|
||||
int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
|
||||
{
|
||||
json_object_t *object;
|
||||
object_key_t *k;
|
||||
|
||||
if(!key || !value)
|
||||
return -1;
|
||||
@@ -111,7 +124,14 @@ int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
|
||||
}
|
||||
object = json_to_object(json);
|
||||
|
||||
if(hashtable_set(&object->hashtable, strdup(key), value))
|
||||
k = malloc(sizeof(object_key_t) + strlen(key) + 1);
|
||||
if(!k)
|
||||
return -1;
|
||||
|
||||
k->serial = object->serial++;
|
||||
strcpy(k->key, key);
|
||||
|
||||
if(hashtable_set(&object->hashtable, k, value))
|
||||
{
|
||||
json_decref(value);
|
||||
return -1;
|
||||
@@ -139,7 +159,7 @@ int json_object_del(json_t *json, const char *key)
|
||||
return -1;
|
||||
|
||||
object = json_to_object(json);
|
||||
return hashtable_del(&object->hashtable, key);
|
||||
return hashtable_del(&object->hashtable, string_to_key(key));
|
||||
}
|
||||
|
||||
int json_object_clear(json_t *json)
|
||||
@@ -190,6 +210,17 @@ void *json_object_iter(json_t *json)
|
||||
return hashtable_iter(&object->hashtable);
|
||||
}
|
||||
|
||||
void *json_object_iter_at(json_t *json, const char *key)
|
||||
{
|
||||
json_object_t *object;
|
||||
|
||||
if(!key || !json_is_object(json))
|
||||
return NULL;
|
||||
|
||||
object = json_to_object(json);
|
||||
return hashtable_iter_at(&object->hashtable, string_to_key(key));
|
||||
}
|
||||
|
||||
void *json_object_iter_next(json_t *json, void *iter)
|
||||
{
|
||||
json_object_t *object;
|
||||
@@ -201,12 +232,20 @@ void *json_object_iter_next(json_t *json, void *iter)
|
||||
return hashtable_iter_next(&object->hashtable, iter);
|
||||
}
|
||||
|
||||
const object_key_t *jsonp_object_iter_fullkey(void *iter)
|
||||
{
|
||||
if(!iter)
|
||||
return NULL;
|
||||
|
||||
return hashtable_iter_key(iter);
|
||||
}
|
||||
|
||||
const char *json_object_iter_key(void *iter)
|
||||
{
|
||||
if(!iter)
|
||||
return NULL;
|
||||
|
||||
return (const char *)hashtable_iter_key(iter);
|
||||
return jsonp_object_iter_fullkey(iter)->key;
|
||||
}
|
||||
|
||||
json_t *json_object_iter_value(void *iter)
|
||||
@@ -217,6 +256,19 @@ json_t *json_object_iter_value(void *iter)
|
||||
return (json_t *)hashtable_iter_value(iter);
|
||||
}
|
||||
|
||||
int json_object_iter_set_new(json_t *json, void *iter, json_t *value)
|
||||
{
|
||||
json_object_t *object;
|
||||
|
||||
if(!json_is_object(json) || !iter || !value)
|
||||
return -1;
|
||||
|
||||
object = json_to_object(json);
|
||||
hashtable_iter_set(&object->hashtable, iter, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int json_object_equal(json_t *object1, json_t *object2)
|
||||
{
|
||||
void *iter;
|
||||
@@ -784,7 +836,7 @@ json_t *json_true(void)
|
||||
{
|
||||
static json_t the_true = {
|
||||
.type = JSON_TRUE,
|
||||
.refcount = (unsigned int)1
|
||||
.refcount = (unsigned int)-1
|
||||
};
|
||||
return &the_true;
|
||||
}
|
||||
@@ -794,7 +846,7 @@ json_t *json_false(void)
|
||||
{
|
||||
static json_t the_false = {
|
||||
.type = JSON_FALSE,
|
||||
.refcount = (unsigned int)1
|
||||
.refcount = (unsigned int)-1
|
||||
};
|
||||
return &the_false;
|
||||
}
|
||||
@@ -804,7 +856,7 @@ json_t *json_null(void)
|
||||
{
|
||||
static json_t the_null = {
|
||||
.type = JSON_NULL,
|
||||
.refcount = (unsigned int)1
|
||||
.refcount = (unsigned int)-1
|
||||
};
|
||||
return &the_null;
|
||||
}
|
||||
|
||||
2
test/.gitignore
vendored
2
test/.gitignore
vendored
@@ -3,7 +3,9 @@ bin/json_process
|
||||
suites/api/test_array
|
||||
suites/api/test_equal
|
||||
suites/api/test_copy
|
||||
suites/api/test_dump
|
||||
suites/api/test_load
|
||||
suites/api/test_number
|
||||
suites/api/test_object
|
||||
suites/api/test_simple
|
||||
suites/api/test_cpp
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -53,6 +53,9 @@ int main(int argc, char *argv[])
|
||||
if(getenv_int("JSON_ENSURE_ASCII"))
|
||||
flags |= JSON_ENSURE_ASCII;
|
||||
|
||||
if(getenv_int("JSON_PRESERVE_ORDER"))
|
||||
flags |= JSON_PRESERVE_ORDER;
|
||||
|
||||
if(getenv_int("JSON_SORT_KEYS"))
|
||||
flags |= JSON_SORT_KEYS;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -29,7 +29,7 @@ for test_path in $suite_srcdir/*; do
|
||||
rm -rf $test_log
|
||||
mkdir -p $test_log
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo -n "$name... "
|
||||
echo -n "$test_name... "
|
||||
fi
|
||||
|
||||
if run_test; then
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -4,6 +4,7 @@ check_PROGRAMS = \
|
||||
test_array \
|
||||
test_equal \
|
||||
test_copy \
|
||||
test_dump \
|
||||
test_load \
|
||||
test_simple \
|
||||
test_number \
|
||||
@@ -11,6 +12,7 @@ check_PROGRAMS = \
|
||||
|
||||
test_array_SOURCES = test_array.c util.h
|
||||
test_copy_SOURCES = test_copy.c util.h
|
||||
test_dump_SOURCES = test_dump.c util.h
|
||||
test_load_SOURCES = test_load.c util.h
|
||||
test_simple_SOURCES = test_simple.c util.h
|
||||
test_number_SOURCES = test_number.c util.h
|
||||
|
||||
@@ -39,9 +39,11 @@ json_object_del
|
||||
json_object_clear
|
||||
json_object_update
|
||||
json_object_iter
|
||||
json_object_iter_at
|
||||
json_object_iter_next
|
||||
json_object_iter_key
|
||||
json_object_iter_value
|
||||
json_object_iter_set_new
|
||||
json_dumps
|
||||
json_dumpf
|
||||
json_dump_file
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
is_test() {
|
||||
[ "${test_name%.c}" != "$test_name" ] && return 0
|
||||
[ -x $test_path -a ! -f $test_path.c ] && return 0
|
||||
return 1
|
||||
case "$test_name" in
|
||||
*.c|check-exports)
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
run_test() {
|
||||
if [ -x $test_path ]; then
|
||||
if [ "$test_name" = "check-exports" ]; then
|
||||
test_log=$test_log $test_path >$test_log/stdout 2>$test_log/stderr
|
||||
else
|
||||
$test_runner $suite_builddir/${test_name%.c} \
|
||||
>$test_log/stdout \
|
||||
2>$test_log/stderr
|
||||
2>$test_log/stderr \
|
||||
|| return 1
|
||||
valgrind_check $test_log/stderr || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
91
test/suites/api/test_dump.c
Normal file
91
test/suites/api/test_dump.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <jansson.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
json_t *json;
|
||||
char *result;
|
||||
|
||||
/* Encode an empty object/array, add an item, encode again */
|
||||
|
||||
json = json_object();
|
||||
result = json_dumps(json, 0);
|
||||
if(!result || strcmp(result, "{}"))
|
||||
fail("json_dumps failed");
|
||||
free(result);
|
||||
|
||||
json_object_set_new(json, "foo", json_integer(5));
|
||||
result = json_dumps(json, 0);
|
||||
if(!result || strcmp(result, "{\"foo\": 5}"))
|
||||
fail("json_dumps failed");
|
||||
free(result);
|
||||
|
||||
json_decref(json);
|
||||
|
||||
json = json_array();
|
||||
result = json_dumps(json, 0);
|
||||
if(!result || strcmp(result, "[]"))
|
||||
fail("json_dumps failed");
|
||||
free(result);
|
||||
|
||||
json_array_append_new(json, json_integer(5));
|
||||
result = json_dumps(json, 0);
|
||||
if(!result || strcmp(result, "[5]"))
|
||||
fail("json_dumps failed");
|
||||
free(result);
|
||||
|
||||
json_decref(json);
|
||||
|
||||
/* Construct a JSON object/array with a circular reference:
|
||||
|
||||
object: {"a": {"b": {"c": <circular reference to $.a>}}}
|
||||
array: [[[<circular reference to the $[0] array>]]]
|
||||
|
||||
Encode it, remove the circular reference and encode again.
|
||||
*/
|
||||
json = json_object();
|
||||
json_object_set_new(json, "a", json_object());
|
||||
json_object_set_new(json_object_get(json, "a"), "b", json_object());
|
||||
json_object_set(json_object_get(json_object_get(json, "a"), "b"), "c",
|
||||
json_object_get(json, "a"));
|
||||
|
||||
if(json_dumps(json, 0))
|
||||
fail("json_dumps encoded a circular reference!");
|
||||
|
||||
json_object_del(json_object_get(json_object_get(json, "a"), "b"), "c");
|
||||
|
||||
result = json_dumps(json, 0);
|
||||
if(!result || strcmp(result, "{\"a\": {\"b\": {}}}"))
|
||||
fail("json_dumps failed!");
|
||||
free(result);
|
||||
|
||||
json_decref(json);
|
||||
|
||||
json = json_array();
|
||||
json_array_append_new(json, json_array());
|
||||
json_array_append_new(json_array_get(json, 0), json_array());
|
||||
json_array_append(json_array_get(json_array_get(json, 0), 0),
|
||||
json_array_get(json, 0));
|
||||
|
||||
if(json_dumps(json, 0))
|
||||
fail("json_dumps encoded a circular reference!");
|
||||
|
||||
json_array_remove(json_array_get(json_array_get(json, 0), 0), 0);
|
||||
|
||||
result = json_dumps(json, 0);
|
||||
if(!result || strcmp(result, "[[[]]]"))
|
||||
fail("json_dumps failed!");
|
||||
free(result);
|
||||
|
||||
json_decref(json);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -205,10 +205,98 @@ static void test_set_nocheck()
|
||||
json_decref(object);
|
||||
}
|
||||
|
||||
static void test_iterators()
|
||||
{
|
||||
json_t *object, *foo, *bar, *baz;
|
||||
void *iter;
|
||||
|
||||
if(json_object_iter(NULL))
|
||||
fail("able to iterate over NULL");
|
||||
|
||||
if(json_object_iter_next(NULL, NULL))
|
||||
fail("able to increment an iterator on a NULL object");
|
||||
|
||||
object = json_object();
|
||||
foo = json_string("foo");
|
||||
bar = json_string("bar");
|
||||
baz = json_string("baz");
|
||||
if(!object || !foo || !bar || !bar)
|
||||
fail("unable to create values");
|
||||
|
||||
if(json_object_iter_next(object, NULL))
|
||||
fail("able to increment a NULL iterator");
|
||||
|
||||
if(json_object_set(object, "a", foo) ||
|
||||
json_object_set(object, "b", bar) ||
|
||||
json_object_set(object, "c", baz))
|
||||
fail("unable to populate object");
|
||||
|
||||
iter = json_object_iter(object);
|
||||
if(!iter)
|
||||
fail("unable to get iterator");
|
||||
if(strcmp(json_object_iter_key(iter), "a"))
|
||||
fail("iterating failed: wrong key");
|
||||
if(json_object_iter_value(iter) != foo)
|
||||
fail("iterating failed: wrong value");
|
||||
|
||||
iter = json_object_iter_next(object, iter);
|
||||
if(!iter)
|
||||
fail("unable to increment iterator");
|
||||
if(strcmp(json_object_iter_key(iter), "b"))
|
||||
fail("iterating failed: wrong key");
|
||||
if(json_object_iter_value(iter) != bar)
|
||||
fail("iterating failed: wrong value");
|
||||
|
||||
iter = json_object_iter_next(object, iter);
|
||||
if(!iter)
|
||||
fail("unable to increment iterator");
|
||||
if(strcmp(json_object_iter_key(iter), "c"))
|
||||
fail("iterating failed: wrong key");
|
||||
if(json_object_iter_value(iter) != baz)
|
||||
fail("iterating failed: wrong value");
|
||||
|
||||
if(json_object_iter_next(object, iter) != NULL)
|
||||
fail("able to iterate over the end");
|
||||
|
||||
if(json_object_iter_at(object, "foo"))
|
||||
fail("json_object_iter_at() succeeds for non-existent key");
|
||||
|
||||
iter = json_object_iter_at(object, "b");
|
||||
if(!iter)
|
||||
fail("json_object_iter_at() fails for an existing key");
|
||||
|
||||
if(strcmp(json_object_iter_key(iter), "b"))
|
||||
fail("iterating failed: wrong key");
|
||||
if(json_object_iter_value(iter) != bar)
|
||||
fail("iterating failed: wrong value");
|
||||
|
||||
iter = json_object_iter_next(object, iter);
|
||||
if(!iter)
|
||||
fail("unable to increment iterator");
|
||||
if(strcmp(json_object_iter_key(iter), "c"))
|
||||
fail("iterating failed: wrong key");
|
||||
if(json_object_iter_value(iter) != baz)
|
||||
fail("iterating failed: wrong value");
|
||||
|
||||
if(json_object_iter_set(object, iter, bar))
|
||||
fail("unable to set value at iterator");
|
||||
|
||||
if(strcmp(json_object_iter_key(iter), "c"))
|
||||
fail("json_object_iter_key() fails after json_object_iter_set()");
|
||||
if(json_object_iter_value(iter) != bar)
|
||||
fail("json_object_iter_value() fails after json_object_iter_set()");
|
||||
if(json_object_get(object, "c") != bar)
|
||||
fail("json_object_get() fails after json_object_iter_set()");
|
||||
|
||||
json_decref(object);
|
||||
json_decref(foo);
|
||||
json_decref(bar);
|
||||
json_decref(baz);
|
||||
}
|
||||
|
||||
static void test_misc()
|
||||
{
|
||||
json_t *object, *string, *other_string, *value;
|
||||
void *iter;
|
||||
|
||||
object = json_object();
|
||||
string = json_string("test");
|
||||
@@ -231,17 +319,6 @@ static void test_misc()
|
||||
if(!json_object_set(object, "a", NULL))
|
||||
fail("able to set NULL value");
|
||||
|
||||
iter = json_object_iter(object);
|
||||
if(!iter)
|
||||
fail("unable to get iterator");
|
||||
|
||||
if(strcmp(json_object_iter_key(iter), "a"))
|
||||
fail("iterating failed: wrong key");
|
||||
if(json_object_iter_value(iter) != string)
|
||||
fail("iterating failed: wrong value");
|
||||
if(json_object_iter_next(object, iter) != NULL)
|
||||
fail("able to iterate over the end");
|
||||
|
||||
/* invalid UTF-8 in key */
|
||||
if(!json_object_set(object, "a\xefz", string))
|
||||
fail("able to set invalid unicode key");
|
||||
@@ -325,6 +402,41 @@ static void test_misc()
|
||||
json_decref(object);
|
||||
}
|
||||
|
||||
static void test_preserve_order()
|
||||
{
|
||||
json_t *object;
|
||||
char *result;
|
||||
|
||||
const char *expected = "{\"foobar\": 1, \"bazquux\": 6, \"lorem ipsum\": 3, \"sit amet\": 5, \"helicopter\": 7}";
|
||||
|
||||
object = json_object();
|
||||
|
||||
json_object_set_new(object, "foobar", json_integer(1));
|
||||
json_object_set_new(object, "bazquux", json_integer(2));
|
||||
json_object_set_new(object, "lorem ipsum", json_integer(3));
|
||||
json_object_set_new(object, "dolor", json_integer(4));
|
||||
json_object_set_new(object, "sit amet", json_integer(5));
|
||||
|
||||
/* changing a value should preserve the order */
|
||||
json_object_set_new(object, "bazquux", json_integer(6));
|
||||
|
||||
/* deletion shouldn't change the order of others */
|
||||
json_object_del(object, "dolor");
|
||||
|
||||
/* add a new item just to make sure */
|
||||
json_object_set_new(object, "helicopter", json_integer(7));
|
||||
|
||||
result = json_dumps(object, JSON_PRESERVE_ORDER);
|
||||
|
||||
if(strcmp(expected, result) != 0) {
|
||||
fprintf(stderr, "%s != %s", expected, result);
|
||||
fail("JSON_PRESERVE_ORDER doesn't work");
|
||||
}
|
||||
|
||||
free(result);
|
||||
json_decref(object);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_misc();
|
||||
@@ -332,6 +444,8 @@ int main()
|
||||
test_update();
|
||||
test_circular();
|
||||
test_set_nocheck();
|
||||
test_iterators();
|
||||
test_preserve_order();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -150,5 +150,36 @@ int main()
|
||||
fail("json_null failed");
|
||||
json_decref(value);
|
||||
|
||||
/* Test reference counting on singletons (true, false, null) */
|
||||
value = json_true();
|
||||
if(value->refcount != (unsigned int)-1)
|
||||
fail("refcounting true works incorrectly");
|
||||
json_decref(value);
|
||||
if(value->refcount != (unsigned int)-1)
|
||||
fail("refcounting true works incorrectly");
|
||||
json_incref(value);
|
||||
if(value->refcount != (unsigned int)-1)
|
||||
fail("refcounting true works incorrectly");
|
||||
|
||||
value = json_false();
|
||||
if(value->refcount != (unsigned int)-1)
|
||||
fail("refcounting false works incorrectly");
|
||||
json_decref(value);
|
||||
if(value->refcount != (unsigned int)-1)
|
||||
fail("refcounting false works incorrectly");
|
||||
json_incref(value);
|
||||
if(value->refcount != (unsigned int)-1)
|
||||
fail("refcounting false works incorrectly");
|
||||
|
||||
value = json_null();
|
||||
if(value->refcount != (unsigned int)-1)
|
||||
fail("refcounting null works incorrectly");
|
||||
json_decref(value);
|
||||
if(value->refcount != (unsigned int)-1)
|
||||
fail("refcounting null works incorrectly");
|
||||
json_incref(value);
|
||||
if(value->refcount != (unsigned int)-1)
|
||||
fail("refcounting null works incorrectly");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
1
test/suites/encoding-flags/preserve-order/env
Normal file
1
test/suites/encoding-flags/preserve-order/env
Normal file
@@ -0,0 +1 @@
|
||||
export JSON_PRESERVE_ORDER=1
|
||||
1
test/suites/encoding-flags/preserve-order/input
Normal file
1
test/suites/encoding-flags/preserve-order/input
Normal file
@@ -0,0 +1 @@
|
||||
{"foo": 1, "bar": 2, "asdf": 3, "deadbeef": 4, "badc0ffee": 5, "qwerty": 6}
|
||||
1
test/suites/encoding-flags/preserve-order/output
Normal file
1
test/suites/encoding-flags/preserve-order/output
Normal file
@@ -0,0 +1 @@
|
||||
{"foo": 1, "bar": 2, "asdf": 3, "deadbeef": 4, "badc0ffee": 5, "qwerty": 6}
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
1
|
||||
\u0000 is not allowed
|
||||
@@ -0,0 +1 @@
|
||||
["\u0000 (null byte not allowed)"]
|
||||
@@ -1,2 +1,2 @@
|
||||
1
|
||||
\u0000 is not allowed
|
||||
control character 0x0 near '"null byte '
|
||||
|
||||
Binary file not shown.
2
test/suites/invalid-strip/null-byte-outside-string/error
Normal file
2
test/suites/invalid-strip/null-byte-outside-string/error
Normal file
@@ -0,0 +1,2 @@
|
||||
1
|
||||
invalid token near end of file
|
||||
BIN
test/suites/invalid-strip/null-byte-outside-string/input
Normal file
BIN
test/suites/invalid-strip/null-byte-outside-string/input
Normal file
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
1
|
||||
real number underflow near '123e-10000000'
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
2
test/suites/invalid/escaped-null-byte-in-string/error
Normal file
2
test/suites/invalid/escaped-null-byte-in-string/error
Normal file
@@ -0,0 +1,2 @@
|
||||
1
|
||||
\u0000 is not allowed
|
||||
1
test/suites/invalid/escaped-null-byte-in-string/input
Normal file
1
test/suites/invalid/escaped-null-byte-in-string/input
Normal file
@@ -0,0 +1 @@
|
||||
["\u0000 (null byte not allowed)"]
|
||||
@@ -1,2 +1,2 @@
|
||||
1
|
||||
\u0000 is not allowed
|
||||
control character 0x0 near '"null byte '
|
||||
|
||||
Binary file not shown.
2
test/suites/invalid/null-byte-outside-string/error
Normal file
2
test/suites/invalid/null-byte-outside-string/error
Normal file
@@ -0,0 +1,2 @@
|
||||
1
|
||||
invalid token near end of file
|
||||
BIN
test/suites/invalid/null-byte-outside-string/input
Normal file
BIN
test/suites/invalid/null-byte-outside-string/input
Normal file
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
1
|
||||
real number underflow near '123e-10000000'
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
1
test/suites/valid-strip/real-underflow/output
Normal file
1
test/suites/valid-strip/real-underflow/output
Normal file
@@ -0,0 +1 @@
|
||||
[0.0]
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
1
test/suites/valid/real-underflow/output
Normal file
1
test/suites/valid/real-underflow/output
Normal file
@@ -0,0 +1 @@
|
||||
[0.0]
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
Reference in New Issue
Block a user