Hello community, here is the log from the commit of package libfastjson for openSUSE:Factory checked in at 2017-11-16 13:58:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libfastjson (Old) and /work/SRC/openSUSE:Factory/.libfastjson.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "libfastjson" Thu Nov 16 13:58:53 2017 rev:7 rq:541839 version:0.99.7 Changes: -------- --- /work/SRC/openSUSE:Factory/libfastjson/libfastjson.changes 2017-08-12 19:33:26.424133581 +0200 +++ /work/SRC/openSUSE:Factory/.libfastjson.new/libfastjson.changes 2017-11-16 13:58:56.870118451 +0100 @@ -1,0 +2,7 @@ +Tue Nov 14 14:45:51 UTC 2017 - astieger@suse.com + +- update to 0.99.7: + * add option for case-insensitive comparisons + * Remove userdata and custom-serialization functions + +------------------------------------------------------------------- Old: ---- libfastjson-0.99.6.tar.gz New: ---- libfastjson-0.99.7.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libfastjson.spec ++++++ --- /var/tmp/diff_new_pack.jQ56oa/_old 2017-11-16 13:58:57.918080480 +0100 +++ /var/tmp/diff_new_pack.jQ56oa/_new 2017-11-16 13:58:57.918080480 +0100 @@ -18,7 +18,7 @@ %define somajor 4 Name: libfastjson -Version: 0.99.6 +Version: 0.99.7 Release: 0 Summary: Fast JSON parsing library, a fork of json-c License: MIT ++++++ libfastjson-0.99.6.tar.gz -> libfastjson-0.99.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/ChangeLog new/libfastjson-0.99.7/ChangeLog --- old/libfastjson-0.99.6/ChangeLog 2017-05-11 16:09:47.000000000 +0200 +++ new/libfastjson-0.99.7/ChangeLog 2017-10-16 11:38:52.000000000 +0200 @@ -1,6 +1,35 @@ -0.99.6 2017-05-12 +0.99.7 2017-10-17 +- added option for case-insensitive comparisons + This permits to search for json keys in a case-sensitive way. + The default is "off", as this is against the JSON spec. However, + rsyslog needs this capability to increase usability inside the + variable system. + We add a new API call to switch between case-sensitive and + case-insensitive comparison, with case-sensitive being the default. + closes https://github.com/rsyslog/libfastjson/issues/142 +- Removed userdata and custom-serialization functions + Reasoning (from pull request): + The library uses the concept of "userdata" and "custom serialization + functions" that can be set from user space. However, to effectively + make use of this feature, a user must have a deep understanding of + the internal data representation of the library, which makes this + feature not very useful. + But what is worse: internally, the library itself also sometimes + assigns data to this userdata member (especially when working with + doubles), and it also sometimes assigns alternative serialization + functions. This makes the feature even more unusable, because as a + user you never can know when the userdata pointer is save to use + for your own settings, and when you must leave it alone because + it is used by the library. + Long story short. In this pull request I got rid of the userdata + pointer completely. The case where the library was using the + "userdata" (for storing the original string representation of a + parsed double) has been moved into the union that is already used + for storing values. + see also: https://github.com/rsyslog/libfastjson/pull/141 + Thanks to Emiel Bruijntjes for the patch. +0.99.6 2017-06-19 - fix a build issue under Solaris - 0.99.5 2017-05-03 - fix tautology comparison in tautology in `fjson_object_iter_equal` - made build under Solaris again diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/Makefile.am new/libfastjson-0.99.7/Makefile.am --- old/libfastjson-0.99.6/Makefile.am 2017-05-11 15:25:57.000000000 +0200 +++ new/libfastjson-0.99.7/Makefile.am 2017-10-16 11:41:24.000000000 +0200 @@ -23,7 +23,7 @@ # info on version-info: # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.h... libfastjson_la_LDFLAGS = \ - -version-info 5:0:1 \ + -version-info 6:0:2 \ -export-symbols-regex '^fjson_.*' \ -no-undefined \ @JSON_BSYMBOLIC_LDFLAGS@ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/Makefile.in new/libfastjson-0.99.7/Makefile.in --- old/libfastjson-0.99.6/Makefile.in 2017-05-11 16:11:06.000000000 +0200 +++ new/libfastjson-0.99.7/Makefile.in 2017-10-16 11:43:17.000000000 +0200 @@ -437,7 +437,7 @@ # info on version-info: # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.h... libfastjson_la_LDFLAGS = \ - -version-info 5:0:1 \ + -version-info 6:0:2 \ -export-symbols-regex '^fjson_.*' \ -no-undefined \ @JSON_BSYMBOLIC_LDFLAGS@ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/configure new/libfastjson-0.99.7/configure --- old/libfastjson-0.99.6/configure 2017-05-11 16:11:06.000000000 +0200 +++ new/libfastjson-0.99.7/configure 2017-10-16 11:43:18.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libfastjson 0.99.6. +# Generated by GNU Autoconf 2.69 for libfastjson 0.99.7. # # Report bugs to <rsyslog@lists.adiscon.com>. # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='libfastjson' PACKAGE_TARNAME='libfastjson' -PACKAGE_VERSION='0.99.6' -PACKAGE_STRING='libfastjson 0.99.6' +PACKAGE_VERSION='0.99.7' +PACKAGE_STRING='libfastjson 0.99.7' PACKAGE_BUGREPORT='rsyslog@lists.adiscon.com' PACKAGE_URL='' @@ -1336,7 +1336,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -`configure' configures libfastjson 0.99.6 to adapt to many kinds of systems. +`configure' configures libfastjson 0.99.7 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1407,7 +1407,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libfastjson 0.99.6:";; + short | recursive ) echo "Configuration of libfastjson 0.99.7:";; esac cat <<_ACEOF @@ -1525,7 +1525,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<_ACEOF -libfastjson configure 0.99.6 +libfastjson configure 0.99.7 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1948,7 +1948,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libfastjson $as_me 0.99.6, which was +It was created by libfastjson $as_me 0.99.7, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2838,7 +2838,7 @@ # Define the identity of the package. PACKAGE='libfastjson' - VERSION='0.99.6' + VERSION='0.99.7' cat >>confdefs.h <<_ACEOF @@ -14559,7 +14559,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libfastjson $as_me 0.99.6, which was +This file was extended by libfastjson $as_me 0.99.7, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14625,7 +14625,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\""`$]/\\&/g'`" ac_cs_version="\ -libfastjson config.status 0.99.6 +libfastjson config.status 0.99.7 configured by $0, generated by GNU Autoconf 2.69, with options \"$ac_cs_config\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/configure.ac new/libfastjson-0.99.7/configure.ac --- old/libfastjson-0.99.6/configure.ac 2017-05-11 16:10:39.000000000 +0200 +++ new/libfastjson-0.99.7/configure.ac 2017-10-16 11:40:10.000000000 +0200 @@ -1,7 +1,7 @@ AC_PREREQ(2.52) # Process this file with autoconf to produce a configure script. -AC_INIT([libfastjson], [0.99.6], [rsyslog@lists.adiscon.com]) +AC_INIT([libfastjson], [0.99.7], [rsyslog@lists.adiscon.com]) # AIXPORT START: Detect the underlying OS unamestr=$(uname) AM_CONDITIONAL([AIX], [test x$unamestr = xAIX]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/json.h new/libfastjson-0.99.7/json.h --- old/libfastjson-0.99.6/json.h 2017-05-11 14:02:02.000000000 +0200 +++ new/libfastjson-0.99.7/json.h 2017-10-13 11:22:06.000000000 +0200 @@ -42,6 +42,19 @@ * @param size new initial size for printbuf (formatting buffer) */ extern void fjson_global_set_printbuf_initial_size(int size); + +/** + * Set case sensitive/insensitive comparison mode. If set to 0, + * comparisons for JSON keys will be case-insensitive. Otherwise, + * they will be case-sensitive. + * NOTE: the JSON standard demands case sensitivity. By turning + * this off, the JSON standard is not obeyed. Most importantly, + * if keys exists which only differ in case, only partial data + * access is possible. So use with care and only if you know + * exactly what you are doing! + */ +extern void fjson_global_do_case_sensitive_comparison(const int newval); + /** * report the current libfastjson version */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/json_object.c new/libfastjson-0.99.7/json_object.c --- old/libfastjson-0.99.6/json_object.c 2017-05-11 14:02:02.000000000 +0200 +++ new/libfastjson-0.99.7/json_object.c 2017-10-16 11:33:40.000000000 +0200 @@ -2,7 +2,7 @@ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. * Michael Clark <michael@metaparadigm.com> * Copyright (c) 2009 Hewlett-Packard Development Company, L.P. - * Copyright (c) 2015 Rainer Gerhards + * Copyright (c) 2015-2017 Rainer Gerhards * * This library is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See COPYING for details. @@ -29,6 +29,7 @@ #include "atomic.h" #include "printbuf.h" #include "arraylist.h" +#include "json.h" #include "json_object.h" #include "json_object_private.h" #include "json_object_iterator.h" @@ -55,6 +56,11 @@ static fjson_object_to_json_string_fn fjson_object_string_to_json_string; static fjson_object_to_json_string_fn fjson_object_array_to_json_string; +static int do_case_sensitive_comparison = 1; +void fjson_global_do_case_sensitive_comparison(const int newval) +{ + do_case_sensitive_comparison = newval; +} /* helper for accessing the optimized string data component in fjson_object */ @@ -190,8 +196,6 @@ const int cnt = ATOMIC_DEC_AND_FETCH(&jso->_ref_count, &jso->_mut_ref_count); if(cnt > 0) return 0; - if (jso->_user_delete) - jso->_user_delete(jso, jso->_userdata); jso->_delete(jso); return 1; } @@ -237,61 +241,6 @@ return jso->o_type; } -/* set a custom conversion to string */ - -void fjson_object_set_serializer(fjson_object *jso, - fjson_object_to_json_string_fn to_string_func, - void *userdata, - fjson_object_delete_fn *user_delete) -{ - // First, clean up any previously existing user info - if (jso->_user_delete) - { - jso->_user_delete(jso, jso->_userdata); - } - jso->_userdata = NULL; - jso->_user_delete = NULL; - - if (to_string_func == NULL) - { - // Reset to the standard serialization function - switch(jso->o_type) - { - case fjson_type_null: - jso->_to_json_string = NULL; - break; - case fjson_type_boolean: - jso->_to_json_string = &fjson_object_boolean_to_json_string; - break; - case fjson_type_double: - jso->_to_json_string = &fjson_object_double_to_json_string; - break; - case fjson_type_int: - jso->_to_json_string = &fjson_object_int_to_json_string; - break; - case fjson_type_object: - jso->_to_json_string = &fjson_object_object_to_json_string; - break; - case fjson_type_array: - jso->_to_json_string = &fjson_object_array_to_json_string; - break; - case fjson_type_string: - jso->_to_json_string = &fjson_object_string_to_json_string; - break; - default: - /* this should NOT HAPPEN! */ - jso->_to_json_string = NULL; - break; - } - return; - } - - jso->_to_json_string = to_string_func; - jso->_userdata = userdata; - jso->_user_delete = user_delete; -} - - /* extended conversion to string */ const char* fjson_object_to_json_string_ext(struct fjson_object *jso, int flags) @@ -335,8 +284,8 @@ /* fjson_object_object */ static int fjson_object_object_to_json_string(struct fjson_object* jso, - struct printbuf *pb, - int level, + struct printbuf *pb, + int level, int flags) { struct fjson_object *val; @@ -427,8 +376,13 @@ struct fjson_object_iterator it = fjson_object_iter_begin(jso); struct fjson_object_iterator itEnd = fjson_object_iter_end(jso); while (!fjson_object_iter_equal(&it, &itEnd)) { - if (!strcmp (key, fjson_object_iter_peek_name(&it))) - return _fjson_object_iter_peek_child(&it); + if (do_case_sensitive_comparison) { + if (!strcmp (key, fjson_object_iter_peek_name(&it))) + return _fjson_object_iter_peek_child(&it); + } else { + if (!strcasecmp (key, fjson_object_iter_peek_name(&it))) + return _fjson_object_iter_peek_child(&it); + } fjson_object_iter_next(&it); } return NULL; @@ -570,8 +524,8 @@ /* fjson_object_boolean */ static int fjson_object_boolean_to_json_string(struct fjson_object* jso, - struct printbuf *pb, - int __attribute__((unused)) level, + struct printbuf *pb, + int __attribute__((unused)) level, int __attribute__((unused)) flags) { if (jso->o.c_boolean) @@ -602,7 +556,7 @@ case fjson_type_int: return (jso->o.c_int64 != 0); case fjson_type_double: - return (jso->o.c_double != 0); + return (jso->o.c_double.value != 0); case fjson_type_string: return (jso->o.c_string.len != 0); case fjson_type_null: @@ -665,7 +619,7 @@ else return (int32_t)cint64; case fjson_type_double: - return (int32_t)jso->o.c_double; + return (int32_t)jso->o.c_double.value; case fjson_type_boolean: return jso->o.c_boolean; case fjson_type_null: @@ -698,7 +652,7 @@ case fjson_type_int: return jso->o.c_int64; case fjson_type_double: - return (int64_t)jso->o.c_double; + return (int64_t)jso->o.c_double.value; case fjson_type_boolean: return jso->o.c_boolean; case fjson_type_string: @@ -716,29 +670,35 @@ /* fjson_object_double */ static int fjson_object_double_to_json_string(struct fjson_object* jso, - struct printbuf *pb, - int __attribute__((unused)) level, + struct printbuf *pb, + int __attribute__((unused)) level, int __attribute__((unused)) flags) { char buf[128], *p, *q; int size; double dummy; /* needed for modf() */ + + if (jso->o.c_double.source) { + printbuf_memappend_no_nul(pb, jso->o.c_double.source, strlen(jso->o.c_double.source)); + return 0; /* we need to keep compatible with the API */ + } + /* Although JSON RFC does not support * NaN or Infinity as numeric values * ECMA 262 section 9.8.1 defines * how to handle these cases as strings */ - if(isnan(jso->o.c_double)) + if(isnan(jso->o.c_double.value)) size = snprintf(buf, sizeof(buf), "NaN"); - else if(isinf(jso->o.c_double)) - if(jso->o.c_double > 0) + else if(isinf(jso->o.c_double.value)) + if(jso->o.c_double.value > 0) size = snprintf(buf, sizeof(buf), "Infinity"); else size = snprintf(buf, sizeof(buf), "-Infinity"); else size = snprintf(buf, sizeof(buf), - (modf(jso->o.c_double, &dummy)==0)?"%.17g.0":"%.17g", - jso->o.c_double); + (modf(jso->o.c_double.value, &dummy)==0)?"%.17g.0":"%.17g", + jso->o.c_double.value); p = strchr(buf, ','); if (p) { @@ -760,13 +720,20 @@ return 0; /* we need to keep compatible with the API */ } +static void fjson_object_double_delete(struct fjson_object *jso) +{ + free(jso->o.c_double.source); + fjson_object_generic_delete(jso); +} + struct fjson_object* fjson_object_new_double(double d) { struct fjson_object *jso = fjson_object_new(fjson_type_double); if (!jso) return NULL; jso->_to_json_string = &fjson_object_double_to_json_string; - jso->o.c_double = d; + jso->o.c_double.value = d; + jso->o.c_double.source = NULL; return jso; } @@ -776,31 +743,17 @@ if (!jso) return NULL; - char *new_ds = strdup(ds); - if (!new_ds) + jso->o.c_double.source = strdup(ds); + if (!jso->o.c_double.source) { fjson_object_generic_delete(jso); errno = ENOMEM; return NULL; } - fjson_object_set_serializer(jso, fjson_object_userdata_to_json_string, - new_ds, fjson_object_free_userdata); + jso->_delete = &fjson_object_double_delete; return jso; } -int fjson_object_userdata_to_json_string(struct fjson_object *jso, - struct printbuf *pb, int __attribute__((unused)) level, int __attribute__((unused)) flags) -{ - int userdata_len = strlen((const char *)jso->_userdata); - printbuf_memappend_no_nul(pb, (const char *)jso->_userdata, userdata_len); - return 0; /* we need to keep compatible with the API */ -} - -void fjson_object_free_userdata(struct fjson_object __attribute__((unused)) *jso, void *userdata) -{ - free(userdata); -} - double fjson_object_get_double(struct fjson_object *jso) { double cdouble; @@ -809,7 +762,7 @@ if(!jso) return 0.0; switch(jso->o_type) { case fjson_type_double: - return jso->o.c_double; + return jso->o.c_double.value; case fjson_type_int: return jso->o.c_int64; case fjson_type_boolean: @@ -857,9 +810,9 @@ /* fjson_object_string */ static int fjson_object_string_to_json_string(struct fjson_object* jso, - struct printbuf *pb, - int __attribute__((unused)) level, - int __attribute__((unused)) flags) + struct printbuf *pb, + int __attribute__((unused)) level, + int __attribute__((unused)) flags) { printbuf_memappend_char(pb, '"'); fjson_escape_str(pb, get_string_component(jso)); @@ -1051,13 +1004,13 @@ } int fjson_object_array_put_idx(struct fjson_object *jso, int idx, - struct fjson_object *val) + struct fjson_object *val) { return array_list_put_idx(jso->o.c_array, idx, val); } struct fjson_object* fjson_object_array_get_idx(struct fjson_object *jso, - int idx) + int idx) { return (struct fjson_object*)array_list_get_idx(jso->o.c_array, idx); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/json_object.h new/libfastjson-0.99.7/json_object.h --- old/libfastjson-0.99.6/json_object.h 2017-05-11 14:02:02.000000000 +0200 +++ new/libfastjson-0.99.7/json_object.h 2017-10-16 11:33:40.000000000 +0200 @@ -133,19 +133,6 @@ */ typedef size_t (fjson_write_fn)(void *ptr, const char *buffer, size_t size); -/** - * Type of custom user delete functions. See fjson_object_set_serializer. - */ -typedef void (fjson_object_delete_fn)(struct fjson_object *jso, void *userdata); - -/** - * Type of a custom serialization function. See fjson_object_set_serializer. - */ -typedef int (fjson_object_to_json_string_fn)(struct fjson_object *jso, - struct printbuf *pb, - int level, - int flags); - /* supported object types */ typedef enum fjson_type { @@ -209,8 +196,25 @@ */ extern enum fjson_type fjson_object_get_type(struct fjson_object *obj); +/** + * Get the size of the json string if it was dumped + * @param obj object to calculate the size of + * @returns the size of the json string + */ +extern size_t fjson_object_size(struct fjson_object *obj); -/** Dump object to a user-supplied function. +/** + * Extended version of the above function that accept a flags parameter identical + * to the fjson_object_dump_ext() function that you can use the specify how to + * format the string for which the size is calculated + * @param obj the object to calculate the size of + * @param flags extra flags + * @return size_t + */ +extern size_t fjson_object_size_ext(struct fjson_object *obj, int flags); + +/** + * Dump object to a user-supplied function. * Equivalent to fjson_object_write_ext(obj, FJSON_TO_STRING_SPACED, func, ptr) * @param obj object to be written * @param func your function that will be called to write the data @@ -231,6 +235,28 @@ extern size_t fjson_object_dump_ext(struct fjson_object *obj, int flags, fjson_write_fn *func, void *ptr); /** + * Dump function that uses a user-supplied temporary buffer for dumping the + * json. Both the above declared fjson_object_dump() and fjson_object_dump_ext() + * functions uses an internal buffer of 128 bytes that is first filled before + * the user-supplied function is called. This buffer prevents that many calls + * to the callback function are done for single quotes, comma's and curly + * braces. All these calls are first buffered and grouped into a single call + * to the user space function. However, since the buffer limit is somewhat + * arbitrary, you can also use this fjson_object_dump_buffered() function to + * use your own temporary buffer. Note that the buffer might be completely + * overwritten during the call to this function, and that the contents of the + * buffer are undefined after the call. + * @param obj object to be written + * @param flags extra flags + * @param temp your temporary buffer that is used to group calls + * @param size size of your temporary buffer + * @param func your function that will be called to write the data + * @param ptr pointer that will be passed as first argument to your function + */ +extern size_t fjson_object_dump_buffered(struct fjson_object *obj, int flags, char *temp, +size_t size, fjson_write_fn *func, void *ptr); + +/** * Write the json tree to a file * Equivalent to fjson_object_write_ext(obj, FJSON_TO_STRING_SPACED, fp) * @param obj object to be written @@ -268,57 +294,6 @@ extern const char* fjson_object_to_json_string_ext(struct fjson_object *obj, int flags); -/** - * Set a custom serialization function to be used when this particular object - * is converted to a string by fjson_object_to_json_string. - * - * If a custom serializer is already set on this object, any existing - * user_delete function is called before the new one is set. - * - * If to_string_func is NULL, the other parameters are ignored - * and the default behaviour is reset. - * - * The userdata parameter is optional and may be passed as NULL. If provided, - * it is passed to to_string_func as-is. This parameter may be NULL even - * if user_delete is non-NULL. - * - * The user_delete parameter is optional and may be passed as NULL, even if - * the userdata parameter is non-NULL. It will be called just before the - * fjson_object is deleted, after it's reference count goes to zero - * (see fjson_object_put()). - * If this is not provided, it is up to the caller to free the userdata at - * an appropriate time. (i.e. after the fjson_object is deleted) - * - * @param jso the object to customize - * @param to_string_func the custom serialization function - * @param userdata an optional opaque cookie - * @param user_delete an optional function from freeing userdata - */ -extern void fjson_object_set_serializer(fjson_object *jso, - fjson_object_to_json_string_fn to_string_func, - void *userdata, - fjson_object_delete_fn *user_delete); - -/** - * Simply call free on the userdata pointer. - * Can be used with fjson_object_set_serializer(). - * - * @param jso unused - * @param userdata the pointer that is passed to free(). - */ -fjson_object_delete_fn fjson_object_free_userdata; - -/** - * Copy the jso->_userdata string over to pb as-is. - * Can be used with fjson_object_set_serializer(). - * - * @param jso The object whose _userdata is used. - * @param pb The destination buffer. - * @param level Ignored. - * @param flags Ignored. - */ -fjson_object_to_json_string_fn fjson_object_userdata_to_json_string; - /* object type methods */ @@ -504,7 +479,7 @@ * @param val the fjson_object to be added */ extern int fjson_object_array_put_idx(struct fjson_object *obj, int idx, - struct fjson_object *val); + struct fjson_object *val); /** Get the element at specificed index of the array (a fjson_object of type fjson_type_array) * @param obj the fjson_object instance @@ -512,7 +487,7 @@ * @returns the fjson_object at the specified index (or NULL) */ extern struct fjson_object* fjson_object_array_get_idx(struct fjson_object *obj, - int idx); + int idx); /* fjson_bool type methods */ @@ -596,7 +571,7 @@ /** * Create a new fjson_object of type fjson_type_double, using - * the exact serialized representation of the value. + * the exact representation of the value. * * This allows for numbers that would otherwise get displayed * inefficiently (e.g. 12.3 => "12.300000000000001") to be @@ -605,13 +580,6 @@ * Note: this is used by fjson_tokener_parse_ex() to allow for * an exact re-serialization of a parsed object. * - * An equivalent sequence of calls is: - * @code - * jso = fjson_object_new_double(d); - * fjson_object_set_serializer(d, fjson_object_userdata_to_json_string, - * strdup(ds), fjson_object_free_userdata) - * @endcode - * * @param d the numeric value of the double. * @param ds the string representation of the double. This will be copied. */ @@ -739,8 +707,6 @@ #define json_object_object_add(a, b, c) fjson_object_object_add((a), (b), (c)) #define json_object_object_add_ex fjson_object_object_add_ex #define json_object_object_get_ex fjson_object_object_get_ex -#define json_object_object_foreach fjson_object_object_foreach -#define json_object_object_foreachC fjson_object_object_foreachC #define json_object_object_get fjson_object_object_get #define json_object_object_del fjson_object_object_del #define json_object_new_array fjson_object_new_array diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/json_object_private.h new/libfastjson-0.99.7/json_object_private.h --- old/libfastjson-0.99.6/json_object_private.h 2017-05-11 14:02:02.000000000 +0200 +++ new/libfastjson-0.99.7/json_object_private.h 2017-10-16 11:33:40.000000000 +0200 @@ -19,7 +19,14 @@ #define LEN_DIRECT_STRING_DATA 32 /**< how many bytes are directly stored in fjson_object for strings? */ +/** + * Type of the delete and serialization functions. + */ typedef void (fjson_object_private_delete_fn)(struct fjson_object *o); +typedef int (fjson_object_to_json_string_fn)(struct fjson_object *jso, + struct printbuf *pb, + int level, + int flags); struct _fjson_child { /** @@ -50,7 +57,10 @@ struct printbuf *_pb; union data { fjson_bool c_boolean; - double c_double; + struct { + double value; + char *source; + } c_double; int64_t c_int64; struct { int nelem; @@ -70,8 +80,6 @@ int len; } c_string; } o; - fjson_object_delete_fn *_user_delete; - void *_userdata; DEF_ATOMIC_HELPER_MUT(_mut_ref_count) }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/json_print.c new/libfastjson-0.99.7/json_print.c --- old/libfastjson-0.99.6/json_print.c 2017-05-11 14:02:02.000000000 +0200 +++ new/libfastjson-0.99.7/json_print.c 2017-10-16 11:33:40.000000000 +0200 @@ -20,6 +20,12 @@ #include <string.h> #include <math.h> +#ifdef HAVE_STDARG_H +# include <stdarg.h> +#else /* !HAVE_STDARG_H */ +# error Not enough var arg support! +#endif /* HAVE_STDARG_H */ + #include "json_object.h" #include "json_object_private.h" #include "json_object_iterator.h" @@ -29,9 +35,185 @@ # error You do not have snprintf on your system. #endif /* HAVE_SNPRINTF */ +#if !defined(HAVE_VASPRINTF) +/* CAW: compliant version of vasprintf */ +/* Note: on OpenCSW, we have vasprintf() inside the headers, but not inside the lib. + * So we need to use a different name, else we get issues with redefinitions. We + * we solve this by using the macro below, which just renames the function BUT + * does not affect the (variadic) arguments. + * rgerhards, 2017-04-11 + */ +#define vasprintf rs_vasprintf +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +static int rs_vasprintf(char **buf, const char *fmt, va_list ap) +{ + int chars; + char *b; + static char _T_emptybuffer = '\0'; + + if(!buf) { return -1; } + + /* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite + our buffer like on some 64bit sun systems.... but hey, its time to move on */ + chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1; + if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */ + + b = (char*)malloc(sizeof(char)*chars); + if(!b) { return -1; } + + if((chars = vsprintf(b, fmt, ap)) < 0) { + free(b); + } else { + *buf = b; + } + + return chars; +} +#pragma GCC diagnostic pop +#endif /* !HAVE_VASPRINTF */ + +/** + * Internal structure that we use for buffering the print output + */ +struct buffer { + char *buffer; + size_t size; + size_t filled; + fjson_write_fn *overflow; + void *ptr; +}; + +/** + * Internal method to flush the buffer + * @param buffer + * @return size_t + */ +static size_t buffer_flush(struct buffer *buffer) +{ + // call the user-supplied overflow function + size_t result = buffer->overflow(buffer->ptr, buffer->buffer, buffer->filled); + + // buffer is empty now + buffer->filled = 0; + + // done + return result; +} + +/** + * Internal method to append data to the buffer + * @param buffer + * @param data + * @param size + * @return size_t + */ +static size_t buffer_append(struct buffer *buffer, const char *data, size_t size) +{ + // return value + size_t result = 0; + + // is the data to big to fit in the buffer? + if (buffer->filled + size > buffer->size) + { + // flush current buffer + if (buffer->filled > 0) result += buffer_flush(buffer); + + // does it still not fit? then we pass it to the callback immediately + if (size > buffer->size) return result + buffer->overflow(buffer->ptr, data, size); + } + + // append to the buffer + memcpy(buffer->buffer + buffer->filled, data, size); + + // update buffer size + buffer->filled += size; + + // done + return result; +} + +/** + * Internal method to printf() into the buffer + * @param buffer + * @param format + * @param ... + * @return size_t + */ +__attribute__((__format__(__printf__, 2, 3))) +static size_t buffer_printf(struct buffer *buffer, const char *format, ...) +{ + // return value + size_t result = 0; + + // variables used in this function + va_list arguments; + char *tmp; + int size; + + // make sure we have sufficient room in our buffer + if (buffer->size - buffer->filled < 32) result += buffer_flush(buffer); + + // initialize varargs + va_start(arguments, format); + + // write to the buffer (note the extra char for the extra null that is written by vsnprintf()) + size = vsnprintf(buffer->buffer + buffer->filled, buffer->size - buffer->filled - 1, format, arguments); + + // clean up varargs (it is not possible to reuse the vararg arguments later on, + // the have to be reset and possible reinitialized later on) + va_end(arguments); + + // was this all successful? + if (size >= 0 && size < (int)(buffer->size - buffer->filled)) + { + // this was a major success + buffer->filled += size; + } + else if (size > 0 && size < (int)buffer->size) + { + // there was not enough room in the buffer, but it would have been enough if + // we would have been able to use the entire buffer, so we reset the buffer, + // and retry the whole procedure + result += buffer_flush(buffer); + + // buffer is empty now, we can retry, start with the vararg initialization + va_start(arguments, format); + + // format into the buffer, again + buffer->size += vsnprintf(buffer->buffer + buffer->filled, buffer->size - buffer->filled - 1, format, arguments); + + // clean up varargs + va_end(arguments); + } + else + { + // initialize varargs + va_start(arguments, format); + + // our own buffer is not big enough to fit the text, we are going to use + // a dynamically allocated buffer using vasprintf(), init varargs first + va_start(arguments, format); + + // use dynamically allocated vasprintf() call + size = vasprintf(&tmp, format, arguments); + + // clean up varargs + va_end(arguments); + + // was this a success? + if (size > 0) result += buffer_append(buffer, tmp, size); + + // deallocate the memory + if (size >= 0) free(tmp); + } + + // done + return result; +} /* Forward declaration of the write function */ -static size_t write(struct fjson_object *jso, int level, int flags, fjson_write_fn *func, void *ptr); +static size_t write(struct fjson_object *jso, int level, int flags, struct buffer *buffer); /** * helper for accessing the optimized string data component in fjson_object @@ -80,45 +262,41 @@ /** * Function to escape a string * @param str the string to be escaped - * @param func user supplied write function - * @param ptr user supplied pointer + * @param buffer the internal buffer to write to * @return size_t number of bytes written */ -static size_t escape(const char *str, fjson_write_fn *func, void *ptr) +static size_t escape(const char *str, struct buffer *buffer) { - int size; - char tempbuf[6]; size_t result = 0; const char *start_offset = str; while(1) { /* broken below on 0-byte */ if(char_needsEscape[*((unsigned char*)str)]) { if(*str == '\0') break; - if(str != start_offset) result += func(ptr, start_offset, str - start_offset); + if(str != start_offset) result += buffer_append(buffer, start_offset, str - start_offset); switch(*str) { - case '\b': result += func(ptr, "\b", 2); break; - case '\n': result += func(ptr, "\n", 2); break; - case '\r': result += func(ptr, "\r", 2); break; - case '\t': result += func(ptr, "\t", 2); break; - case '\f': result += func(ptr, "\f", 2); break; - case '"': result += func(ptr, "\"", 2); break; - case '\': result += func(ptr, "\\", 2); break; - case '/': result += func(ptr, "\/", 2); break; + case '\b': result += buffer_append(buffer, "\b", 2); break; + case '\n': result += buffer_append(buffer, "\n", 2); break; + case '\r': result += buffer_append(buffer, "\r", 2); break; + case '\t': result += buffer_append(buffer, "\t", 2); break; + case '\f': result += buffer_append(buffer, "\f", 2); break; + case '"': result += buffer_append(buffer, "\"", 2); break; + case '\': result += buffer_append(buffer, "\\", 2); break; + case '/': result += buffer_append(buffer, "\/", 2); break; default: - size = snprintf(tempbuf, sizeof(tempbuf), "\u00%c%c", fjson_hex_chars[*str >> 4], fjson_hex_chars[*str & 0xf]); - result += func(ptr, tempbuf, size); + result += buffer_printf(buffer, "\u00%c%c", fjson_hex_chars[*str >> 4], fjson_hex_chars[*str & 0xf]); break; } start_offset = ++str; } else ++str; } - if(str != start_offset) result += func(ptr, start_offset, str - start_offset); + if(str != start_offset) result += buffer_append(buffer, start_offset, str - start_offset); return result; } /* add indentation */ -static size_t indent(int level, int flags, fjson_write_fn *func, void *ptr) +static size_t indent(int level, int flags, struct buffer *buffer) { // result variable, and loop counter size_t result = 0; @@ -131,8 +309,8 @@ for (i = 0; i < level; ++i) { // write a tab or two spaces - if (flags & FJSON_TO_STRING_PRETTY_TAB) result += func(ptr, "\t", 1); - else result += func(ptr, " ", 2); + if (flags & FJSON_TO_STRING_PRETTY_TAB) result += buffer_append(buffer, "\t", 1); + else result += buffer_append(buffer, " ", 2); } // done @@ -141,86 +319,100 @@ /* write a json object */ -static size_t write_object(struct fjson_object* jso, int level, int flags, fjson_write_fn *func, void *ptr) +static size_t write_object(struct fjson_object* jso, int level, int flags, struct buffer *buffer) { int had_children = 0; size_t result = 0; - result += func(ptr, "{" /*}*/, 1); - if (flags & FJSON_TO_STRING_PRETTY) result += func(ptr, "\n", 1); + result += buffer_append(buffer, "{" /*}*/, 1); + if (flags & FJSON_TO_STRING_PRETTY) result += buffer_append(buffer, "\n", 1); struct fjson_object_iterator it = fjson_object_iter_begin(jso); struct fjson_object_iterator itEnd = fjson_object_iter_end(jso); while (!fjson_object_iter_equal(&it, &itEnd)) { if (had_children) { - result += func(ptr, ",", 1); - if (flags & FJSON_TO_STRING_PRETTY) result += func(ptr, "\n", 1); + result += buffer_append(buffer, ",", 1); + if (flags & FJSON_TO_STRING_PRETTY) result += buffer_append(buffer, "\n", 1); } had_children = 1; - if (flags & FJSON_TO_STRING_SPACED) result += func(ptr, " ", 1); - result += indent(level+1, flags, func, ptr); - result += func(ptr, """, 1); - result += escape(fjson_object_iter_peek_name(&it), func, ptr); - if (flags & FJSON_TO_STRING_SPACED) result += func(ptr, "": ", 3); - else result += func(ptr, "":", 2); - result += write(fjson_object_iter_peek_value(&it), level+1, flags, func, ptr); + if (flags & FJSON_TO_STRING_SPACED) result += buffer_append(buffer, " ", 1); + result += indent(level+1, flags, buffer); + result += buffer_append(buffer, """, 1); + result += escape(fjson_object_iter_peek_name(&it), buffer); + if (flags & FJSON_TO_STRING_SPACED) result += buffer_append(buffer, "": ", 3); + else result += buffer_append(buffer, "":", 2); + result += write(fjson_object_iter_peek_value(&it), level+1, flags, buffer); fjson_object_iter_next(&it); } if (flags & FJSON_TO_STRING_PRETTY) { - if (had_children) result += func(ptr, "\n", 1); - result += indent(level, flags, func, ptr); + if (had_children) result += buffer_append(buffer, "\n", 1); + result += indent(level, flags, buffer); } - if (flags & FJSON_TO_STRING_SPACED) result += func(ptr, /*{*/ " }", 2); - else result += func(ptr, /*{*/ "}", 1); + if (flags & FJSON_TO_STRING_SPACED) result += buffer_append(buffer, /*{*/ " }", 2); + else result += buffer_append(buffer, /*{*/ "}", 1); return result; } /* write a json boolean */ -static size_t write_boolean(struct fjson_object* jso, fjson_write_fn *func, void *ptr) +static size_t write_boolean(struct fjson_object* jso, struct buffer *buffer) { - if (jso->o.c_boolean) return func(ptr, "true", 4); - else return func(ptr, "false", 5); + if (jso->o.c_boolean) return buffer_append(buffer, "true", 4); + else return buffer_append(buffer, "false", 5); } /* write a json int */ -static size_t write_int(struct fjson_object* jso, fjson_write_fn *func, void *ptr) +static size_t write_int(struct fjson_object* jso, struct buffer *buffer) { - // temporary buffer - char tempbuffer[32]; - size_t bytes = snprintf(tempbuffer, sizeof(tempbuffer), "%" PRId64, jso->o.c_int64); - return func(ptr, tempbuffer, bytes); + // printf into the buffer + return buffer_printf(buffer, "%" PRId64, jso->o.c_int64); } /* write a json floating point */ -static size_t write_double(struct fjson_object* jso, int flags, fjson_write_fn *func, void *ptr) +static size_t write_double(struct fjson_object* jso, int flags, struct buffer *buffer) { - char buf[128], *p, *q; - int size; + // return value for the function + size_t result = 0; + + // helper functions to fix the output + char *buf, *p, *q; + + // needed for modf() + double dummy; + + // if the original value is set, we reuse that + if (jso->o.c_double.source) return buffer_append(buffer, jso->o.c_double.source, strlen(jso->o.c_double.source)); + /* Although JSON RFC does not support * NaN or Infinity as numeric values * ECMA 262 section 9.8.1 defines * how to handle these cases as strings */ - if(isnan(jso->o.c_double)) - size = snprintf(buf, sizeof(buf), "NaN"); - else if(isinf(jso->o.c_double)) - if(jso->o.c_double > 0) - size = snprintf(buf, sizeof(buf), "Infinity"); - else - size = snprintf(buf, sizeof(buf), "-Infinity"); - else - size = snprintf(buf, sizeof(buf), "%.17g", jso->o.c_double); + if(isnan(jso->o.c_double.value)) return buffer_append(buffer, "NaN", 3); + if(isinf(jso->o.c_double.value)) return buffer_printf(buffer, jso->o.c_double.value > 0 ? "Infinity" : "-Infinity"); + + // store the beginning of the buffer (this is where buffer_printf() will most likely write) + buf = buffer->buffer + buffer->filled; + // write to the buffer + result = buffer_printf(buffer, (modf(jso->o.c_double.value, &dummy)==0)?"%.17g.0":"%.17g", jso->o.c_double.value); + + // if the buffer got flushed + if (buffer->buffer + buffer->filled < buf) buf = buffer->buffer; + + // if localization stuff caused "," to be generated instead of "." + // @todo is there not a nicer way to work around that??? p = strchr(buf, ','); if (p) { *p = '.'; } else { p = strchr(buf, '.'); } + + // remove trailing zero's if (p && (flags & FJSON_TO_STRING_NOZERO)) { /* last useful digit, always keep 1 zero */ p++; @@ -228,67 +420,68 @@ if (*q!='0') p=q; } /* drop trailing zeroes */ - *(++p) = 0; - size = p-buf; + buffer->filled = p - buffer->buffer; } - return func(ptr, buf, size); + + // done + return result; } /* write a json string */ -static size_t write_string(struct fjson_object* jso, fjson_write_fn *func, void *ptr) +static size_t write_string(struct fjson_object* jso, struct buffer *buffer) { - return func(ptr, """, 1) + escape(get_string_component(jso), func, ptr) + func(ptr, """, 1); + return buffer_append(buffer, """, 1) + escape(get_string_component(jso), buffer) + buffer_append(buffer, """, 1); } /* write a json array */ -static size_t write_array(struct fjson_object* jso, int level, int flags, fjson_write_fn *func, void *ptr) +static size_t write_array(struct fjson_object* jso, int level, int flags, struct buffer *buffer) { int had_children = 0; int ii; size_t result = 0; - result += func(ptr, "[", 1); - if (flags & FJSON_TO_STRING_PRETTY) result += func(ptr, "\n", 1); + result += buffer_append(buffer, "[", 1); + if (flags & FJSON_TO_STRING_PRETTY) result += buffer_append(buffer, "\n", 1); for(ii=0; ii < fjson_object_array_length(jso); ii++) { if (had_children) { - result += func(ptr, ",", 1); - if (flags & FJSON_TO_STRING_PRETTY) result += func(ptr, "\n", 1); + result += buffer_append(buffer, ",", 1); + if (flags & FJSON_TO_STRING_PRETTY) result += buffer_append(buffer, "\n", 1); } had_children = 1; - if (flags & FJSON_TO_STRING_SPACED) result += func(ptr, " ", 1); - result += indent(level + 1, flags, func, ptr); - result += write(fjson_object_array_get_idx(jso, ii), level+1, flags, func, ptr); + if (flags & FJSON_TO_STRING_SPACED) result += buffer_append(buffer, " ", 1); + result += indent(level + 1, flags, buffer); + result += write(fjson_object_array_get_idx(jso, ii), level+1, flags, buffer); } if (flags & FJSON_TO_STRING_PRETTY) { - if (had_children) result += func(ptr, "\n", 1); - result += indent(level, flags, func, ptr); + if (had_children) result += buffer_append(buffer, "\n", 1); + result += indent(level, flags, buffer); } - if (flags & FJSON_TO_STRING_SPACED) result += func(ptr, " ]", 2); - else result += func(ptr, "]", 1); + if (flags & FJSON_TO_STRING_SPACED) result += buffer_append(buffer, " ]", 2); + else result += buffer_append(buffer, "]", 1); return result; } /* write a json value */ -static size_t write(struct fjson_object *jso, int level, int flags, fjson_write_fn *func, void *ptr) +static size_t write(struct fjson_object *jso, int level, int flags, struct buffer *buffer) { // if object is not set - if (!jso) return func(ptr, "null", 4); + if (!jso) return buffer_append(buffer, "null", 4); // check type switch(jso->o_type) { - case fjson_type_null: return func(ptr, "null", 4); - case fjson_type_boolean: return write_boolean(jso, func, ptr); - case fjson_type_double: return write_double(jso, flags, func, ptr); - case fjson_type_int: return write_int(jso, func, ptr); - case fjson_type_object: return write_object(jso, level, flags, func, ptr); - case fjson_type_array: return write_array(jso, level, flags, func, ptr); - case fjson_type_string: return write_string(jso, func, ptr); + case fjson_type_null: return buffer_append(buffer, "null", 4); + case fjson_type_boolean: return write_boolean(jso, buffer); + case fjson_type_double: return write_double(jso, flags, buffer); + case fjson_type_int: return write_int(jso, buffer); + case fjson_type_object: return write_object(jso, level, flags, buffer); + case fjson_type_array: return write_array(jso, level, flags, buffer); + case fjson_type_string: return write_string(jso, buffer); default: return 0; } } @@ -300,12 +493,47 @@ return fwrite(buffer, 1, size, ptr); } +/* dummy output function that does not output, but is used to calculate the size */ + +static size_t calculate(void __attribute__((unused)) *ptr, const char __attribute__((unused)) *buffer, size_t size) +{ + return size; +} + +/* extended dump to which the helper buffer can be passed */ + +size_t fjson_object_dump_buffered(struct fjson_object *jso, int flags, char *temp, +size_t size, fjson_write_fn *func, void *ptr) +{ + // construct a buffer + struct buffer object; + + // initialize the properties + object.buffer = temp; + object.size = size; + object.filled = 0; + object.overflow = func; + object.ptr = ptr; + + // write the value + size_t result = write(jso, 0, flags, &object); + + // ready if buffer is now empty + if (object.size == 0) return result; + + // flush the buffer + return result + buffer_flush(&object); +} + /* extended dump function to string */ size_t fjson_object_dump_ext(struct fjson_object *jso, int flags, fjson_write_fn *func, void *ptr) { - // write the value - return write(jso, 0, flags, func, ptr); + // create a local 1k buffer on the stack + char buffer[1024]; + + // pass on to the other function + return fjson_object_dump_buffered(jso, flags, buffer, 1024, func, ptr); } /* more simple write function */ @@ -313,7 +541,25 @@ size_t fjson_object_dump(struct fjson_object *jso, fjson_write_fn *func, void *ptr) { // write the value - return write(jso, 0, FJSON_TO_STRING_SPACED, func, ptr); + return fjson_object_dump_ext(jso, FJSON_TO_STRING_SPACED, func, ptr); +} + +/* extended function to calculate the size */ + +size_t fjson_object_size_ext(struct fjson_object *jso, int flags) +{ + // write the value with a dummy function (this is a simple implementation that + // can later be optimized in a pure size-calculating function) + return fjson_object_dump_ext(jso, flags, &calculate, NULL); +} + +/* function to calculate the size */ + +size_t fjson_object_size(struct fjson_object *jso) +{ + // write the value with a dummy function (this is a simple implementation that + // can later be optimized in a pure size-calculating function) + return fjson_object_dump(jso, &calculate, NULL); } /* write to a file* */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/tests/Makefile.am new/libfastjson-0.99.7/tests/Makefile.am --- old/libfastjson-0.99.6/tests/Makefile.am 2017-05-11 14:02:02.000000000 +0200 +++ new/libfastjson-0.99.7/tests/Makefile.am 2017-10-16 11:33:40.000000000 +0200 @@ -17,7 +17,6 @@ TESTS+= test_locale.test TESTS+= test_charcase.test TESTS+= test_printbuf.test -TESTS+= test_set_serializer.test TESTS+= test_obj_iter-del.test TESTS+= test_object_object_add_ex.test TESTS+= test_many_subobj.test @@ -43,7 +42,6 @@ chk_version_SOURCES = chk_version.c test_printbuf_SOURCES = test_printbuf.c -test_set_serializer_SOURCES = test_set_serializer.c # Note: handled by test1.test check_PROGRAMS += test1Formatted @@ -82,7 +80,6 @@ EXTRA_DIST += test_parse_int64.expected EXTRA_DIST += test_printbuf.expected EXTRA_DIST += testReplaceExisting.expected -EXTRA_DIST += test_set_serializer.expected EXTRA_DIST += test_obj_iter-del.expected EXTRA_DIST += test_object_object_add_ex.expected EXTRA_DIST += test_object_object_add_exFormatted_plain.expected diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/tests/Makefile.in new/libfastjson-0.99.7/tests/Makefile.in --- old/libfastjson-0.99.6/tests/Makefile.in 2017-05-11 16:11:06.000000000 +0200 +++ new/libfastjson-0.99.7/tests/Makefile.in 2017-10-16 11:43:17.000000000 +0200 @@ -90,10 +90,9 @@ TESTS = ucs_copyright_char.test test_float.test test1.test test2.test \ test4.test testReplaceExisting.test test_parse_int64.test \ test_cast.test test_parse.test test_locale.test \ - test_charcase.test test_printbuf.test test_set_serializer.test \ - test_obj_iter-del.test test_object_object_add_ex.test \ - test_many_subobj.test test_obj_obj_get_ex-null.test \ - chk_version$(EXEEXT) + test_charcase.test test_printbuf.test test_obj_iter-del.test \ + test_object_object_add_ex.test test_many_subobj.test \ + test_obj_obj_get_ex-null.test chk_version$(EXEEXT) check_PROGRAMS = $(am__EXEEXT_1) chk_version$(EXEEXT) \ cr_obj_multi$(EXEEXT) chk_version$(EXEEXT) \ cr_obj_multi$(EXEEXT) test1Formatted$(EXEEXT) \ @@ -122,9 +121,9 @@ testReplaceExisting$(EXEEXT) test_parse_int64$(EXEEXT) \ test_cast$(EXEEXT) test_parse$(EXEEXT) test_locale$(EXEEXT) \ test_charcase$(EXEEXT) test_printbuf$(EXEEXT) \ - test_set_serializer$(EXEEXT) test_obj_iter-del$(EXEEXT) \ - test_object_object_add_ex$(EXEEXT) test_many_subobj$(EXEEXT) \ - test_obj_obj_get_ex-null$(EXEEXT) chk_version$(EXEEXT) + test_obj_iter-del$(EXEEXT) test_object_object_add_ex$(EXEEXT) \ + test_many_subobj$(EXEEXT) test_obj_obj_get_ex-null$(EXEEXT) \ + chk_version$(EXEEXT) am_chk_version_OBJECTS = chk_version.$(OBJEXT) chk_version_OBJECTS = $(am_chk_version_OBJECTS) chk_version_LDADD = $(LDADD) @@ -237,11 +236,6 @@ test_printbuf_LDADD = $(LDADD) test_printbuf_DEPENDENCIES = $(top_builddir)/libfastjson.la \ $(top_builddir)/libfastjson-internal.la -am_test_set_serializer_OBJECTS = test_set_serializer.$(OBJEXT) -test_set_serializer_OBJECTS = $(am_test_set_serializer_OBJECTS) -test_set_serializer_LDADD = $(LDADD) -test_set_serializer_DEPENDENCIES = $(top_builddir)/libfastjson.la \ - $(top_builddir)/libfastjson-internal.la ucs_copyright_char_SOURCES = ucs_copyright_char.c ucs_copyright_char_OBJECTS = ucs_copyright_char.$(OBJEXT) ucs_copyright_char_LDADD = $(LDADD) @@ -289,7 +283,7 @@ test_object_object_add_ex.c \ $(test_object_object_add_exFormatted_SOURCES) test_parse.c \ test_parse_int64.c $(test_printbuf_SOURCES) \ - $(test_set_serializer_SOURCES) ucs_copyright_char.c + ucs_copyright_char.c DIST_SOURCES = $(chk_version_SOURCES) $(cr_obj_multi_SOURCES) test1.c \ $(test1Formatted_SOURCES) test2.c $(test2Formatted_SOURCES) \ test4.c testReplaceExisting.c test_cast.c test_charcase.c \ @@ -298,7 +292,7 @@ test_object_object_add_ex.c \ $(test_object_object_add_exFormatted_SOURCES) test_parse.c \ test_parse_int64.c $(test_printbuf_SOURCES) \ - $(test_set_serializer_SOURCES) ucs_copyright_char.c + ucs_copyright_char.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -658,7 +652,6 @@ cr_obj_multi_SOURCES = cr_obj_multi.c chk_version_SOURCES = chk_version.c test_printbuf_SOURCES = test_printbuf.c -test_set_serializer_SOURCES = test_set_serializer.c test1Formatted_SOURCES = test1.c parse_flags.c parse_flags.h test1Formatted_CPPFLAGS = -DTEST_FORMATTED test2Formatted_SOURCES = test2.c parse_flags.c parse_flags.h @@ -674,8 +667,8 @@ test_cast.expected test_charcase.expected test_locale.expected \ test_null.expected test_parse.expected \ test_parse_int64.expected test_printbuf.expected \ - testReplaceExisting.expected test_set_serializer.expected \ - test_obj_iter-del.expected test_object_object_add_ex.expected \ + testReplaceExisting.expected test_obj_iter-del.expected \ + test_object_object_add_ex.expected \ test_object_object_add_exFormatted_plain.expected \ test_object_object_add_exFormatted_pretty.expected \ test_object_object_add_exFormatted_spaced.expected \ @@ -805,10 +798,6 @@ @rm -f test_printbuf$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_printbuf_OBJECTS) $(test_printbuf_LDADD) $(LIBS) -test_set_serializer$(EXEEXT): $(test_set_serializer_OBJECTS) $(test_set_serializer_DEPENDENCIES) $(EXTRA_test_set_serializer_DEPENDENCIES) - @rm -f test_set_serializer$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_set_serializer_OBJECTS) $(test_set_serializer_LDADD) $(LIBS) - ucs_copyright_char$(EXEEXT): $(ucs_copyright_char_OBJECTS) $(ucs_copyright_char_DEPENDENCIES) $(EXTRA_ucs_copyright_char_DEPENDENCIES) @rm -f ucs_copyright_char$(EXEEXT) $(AM_V_CCLD)$(LINK) $(ucs_copyright_char_OBJECTS) $(ucs_copyright_char_LDADD) $(LIBS) @@ -842,7 +831,6 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_parse_int64.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_printbuf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_set_serializer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ucs_copyright_char.Po@am__quote@ .c.o: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/tests/test_set_serializer.c new/libfastjson-0.99.7/tests/test_set_serializer.c --- old/libfastjson-0.99.6/tests/test_set_serializer.c 2017-05-11 14:02:02.000000000 +0200 +++ new/libfastjson-0.99.7/tests/test_set_serializer.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,81 +0,0 @@ -#include "config.h" -#include <stdio.h> -#include <string.h> - -#include "../json.h" -#include "../printbuf.h" -#include "../debug.h" - -/* this is a work-around until we manage to fix configure.ac */ -#pragma GCC diagnostic ignored "-Wdeclaration-after-statement" - -#define CHK(x) if (!(x)) { \ - printf("%s:%d: unexpected result with '%s'\n", \ - __FILE__, __LINE__, #x); \ - exit(1); \ -} - -struct myinfo { - int value; -}; - -static int freeit_was_called = 0; -static void freeit(fjson_object __attribute__((unused)) *jso, void *userdata) -{ - struct myinfo *info = userdata; - printf("freeit, value=%d\n", info->value); - // Don't actually free anything here, the userdata is stack allocated. - freeit_was_called = 1; -} -static int custom_serializer(struct fjson_object __attribute__((unused)) *o, - struct printbuf *pb, - int __attribute__((unused)) level, - int __attribute__((unused)) flags) -{ - sprintbuf(pb, "Custom Output"); - return 0; -} - -int main(int __attribute__((unused)) argc, char __attribute__((unused)) **argv) -{ - fjson_object *my_object; - - MC_SET_DEBUG(1); - - printf("Test setting, then resetting a custom serializer:\n"); - my_object = fjson_object_new_object(); - fjson_object_object_add(my_object, "abc", fjson_object_new_int(12)); - fjson_object_object_add(my_object, "foo", fjson_object_new_string("bar")); - - printf("my_object.to_string(standard)=%s\n", fjson_object_to_json_string(my_object)); - - struct myinfo userdata = { .value = 123 }; - fjson_object_set_serializer(my_object, custom_serializer, &userdata, freeit); - - printf("my_object.to_string(custom serializer)=%s\n", fjson_object_to_json_string(my_object)); - - printf("Next line of output should be from the custom freeit function:\n"); - freeit_was_called = 0; - fjson_object_set_serializer(my_object, NULL, NULL, NULL); - CHK(freeit_was_called); - - printf("my_object.to_string(standard)=%s\n", fjson_object_to_json_string(my_object)); - - fjson_object_put(my_object); - - // ============================================ - - my_object = fjson_object_new_object(); - printf("Check that the custom serializer isn't free'd until the last fjson_object_put:\n"); - fjson_object_set_serializer(my_object, custom_serializer, &userdata, freeit); - fjson_object_get(my_object); - fjson_object_put(my_object); - printf("my_object.to_string(custom serializer)=%s\n", fjson_object_to_json_string(my_object)); - printf("Next line of output should be from the custom freeit function:\n"); - - freeit_was_called = 0; - fjson_object_put(my_object); - CHK(freeit_was_called); - - return 0; -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/tests/test_set_serializer.expected new/libfastjson-0.99.7/tests/test_set_serializer.expected --- old/libfastjson-0.99.6/tests/test_set_serializer.expected 2017-05-11 14:02:02.000000000 +0200 +++ new/libfastjson-0.99.7/tests/test_set_serializer.expected 1970-01-01 01:00:00.000000000 +0100 @@ -1,10 +0,0 @@ -Test setting, then resetting a custom serializer: -my_object.to_string(standard)={ "abc": 12, "foo": "bar" } -my_object.to_string(custom serializer)=Custom Output -Next line of output should be from the custom freeit function: -freeit, value=123 -my_object.to_string(standard)={ "abc": 12, "foo": "bar" } -Check that the custom serializer isn't free'd until the last fjson_object_put: -my_object.to_string(custom serializer)=Custom Output -Next line of output should be from the custom freeit function: -freeit, value=123 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfastjson-0.99.6/tests/test_set_serializer.test new/libfastjson-0.99.7/tests/test_set_serializer.test --- old/libfastjson-0.99.6/tests/test_set_serializer.test 2017-05-11 14:02:02.000000000 +0200 +++ new/libfastjson-0.99.7/tests/test_set_serializer.test 1970-01-01 01:00:00.000000000 +0100 @@ -1,12 +0,0 @@ -#!/bin/sh - -# Common definitions -if test -z "$srcdir"; then - srcdir="${0%/*}" - test "$srcdir" = "$0" && srcdir=. - test -z "$srcdir" && srcdir=. -fi -. "$srcdir/test-defs.sh" - -run_output_test test_set_serializer -exit $?