Format json-c with clang-format tooltags/json-c-0.14-20200419
| @@ -0,0 +1,53 @@ | |||
| BasedOnStyle: LLVM | |||
| # If true, clang-format will attempt to re-flow comments | |||
| ReflowComments: false | |||
| # The column limit. | |||
| ColumnLimit: 100 | |||
| # Indent width for line continuations. | |||
| ContinuationIndentWidth: 4 | |||
| # The number of columns to use for indentation. | |||
| IndentWidth: 8 | |||
| # The number of columns used for tab stops. | |||
| TabWidth: 8 | |||
| UseTab: ForIndentation | |||
| # Options for aligning backslashes in escaped newlines. | |||
| AlignEscapedNewlines: Left | |||
| # Short Block Style | |||
| AllowShortBlocksOnASingleLine: true | |||
| # If true, short case labels will be contracted to a single line. | |||
| AllowShortCaseLabelsOnASingleLine: true | |||
| # Dependent on the value, int f() { return 0; } can be put on a single line. | |||
| AllowShortFunctionsOnASingleLine: Empty | |||
| # The brace breaking style to use. | |||
| BreakBeforeBraces: Custom | |||
| # Control of individual brace wrapping cases. | |||
| BraceWrapping: | |||
| # Wrap class definition. | |||
| AfterClass: true | |||
| # Wrap control statements | |||
| AfterControlStatement: true | |||
| # Wrap enum definitions. | |||
| AfterEnum: true | |||
| # Wrap function definitions. | |||
| AfterFunction: true | |||
| # Wrap namespace definitions. | |||
| AfterNamespace: true | |||
| # Wrap struct definitions. | |||
| AfterStruct: true | |||
| # Wrap union definitions. | |||
| AfterUnion: true | |||
| # Wrap extern blocks. | |||
| AfterExternBlock: false | |||
| # Wrap before catch. | |||
| BeforeCatch: true | |||
| # Wrap before else. | |||
| BeforeElse: true | |||
| # Indent the wrapped braces themselves. | |||
| IndentBraces: false | |||
| # If false, empty function body can be put on a single line. | |||
| SplitEmptyFunction: false | |||
| # If false, empty record (e.g. class, struct or union) body can be put on a single line. | |||
| SplitEmptyRecord: false | |||
| # If false, empty namespace body can be put on a single line. | |||
| SplitEmptyNamespace: false | |||
| @@ -14,12 +14,12 @@ | |||
| #include <limits.h> | |||
| #ifdef STDC_HEADERS | |||
| # include <stdlib.h> | |||
| # include <string.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #endif /* STDC_HEADERS */ | |||
| #if defined(HAVE_STRINGS_H) && !defined(_STRING_H) && !defined(__USE_BSD) | |||
| # include <strings.h> | |||
| #include <strings.h> | |||
| #endif /* HAVE_STRINGS_H */ | |||
| #ifndef SIZE_T_MAX | |||
| @@ -36,111 +36,115 @@ | |||
| #include "arraylist.h" | |||
| struct array_list* | |||
| array_list_new(array_list_free_fn *free_fn) | |||
| struct array_list *array_list_new(array_list_free_fn *free_fn) | |||
| { | |||
| struct array_list *arr; | |||
| arr = (struct array_list*)calloc(1, sizeof(struct array_list)); | |||
| if(!arr) return NULL; | |||
| arr->size = ARRAY_LIST_DEFAULT_SIZE; | |||
| arr->length = 0; | |||
| arr->free_fn = free_fn; | |||
| if(!(arr->array = (void**)calloc(arr->size, sizeof(void*)))) { | |||
| free(arr); | |||
| return NULL; | |||
| } | |||
| return arr; | |||
| struct array_list *arr; | |||
| arr = (struct array_list *)calloc(1, sizeof(struct array_list)); | |||
| if (!arr) | |||
| return NULL; | |||
| arr->size = ARRAY_LIST_DEFAULT_SIZE; | |||
| arr->length = 0; | |||
| arr->free_fn = free_fn; | |||
| if (!(arr->array = (void **)calloc(arr->size, sizeof(void *)))) | |||
| { | |||
| free(arr); | |||
| return NULL; | |||
| } | |||
| return arr; | |||
| } | |||
| extern void | |||
| array_list_free(struct array_list *arr) | |||
| extern void array_list_free(struct array_list *arr) | |||
| { | |||
| size_t i; | |||
| for(i = 0; i < arr->length; i++) | |||
| if(arr->array[i]) arr->free_fn(arr->array[i]); | |||
| free(arr->array); | |||
| free(arr); | |||
| size_t i; | |||
| for (i = 0; i < arr->length; i++) | |||
| if (arr->array[i]) | |||
| arr->free_fn(arr->array[i]); | |||
| free(arr->array); | |||
| free(arr); | |||
| } | |||
| void* | |||
| array_list_get_idx(struct array_list *arr, size_t i) | |||
| void *array_list_get_idx(struct array_list *arr, size_t i) | |||
| { | |||
| if(i >= arr->length) return NULL; | |||
| return arr->array[i]; | |||
| if (i >= arr->length) | |||
| return NULL; | |||
| return arr->array[i]; | |||
| } | |||
| static int array_list_expand_internal(struct array_list *arr, size_t max) | |||
| { | |||
| void *t; | |||
| size_t new_size; | |||
| if(max < arr->size) return 0; | |||
| /* Avoid undefined behaviour on size_t overflow */ | |||
| if( arr->size >= SIZE_T_MAX / 2 ) | |||
| new_size = max; | |||
| else | |||
| { | |||
| new_size = arr->size << 1; | |||
| if (new_size < max) | |||
| new_size = max; | |||
| } | |||
| if (new_size > (~((size_t)0)) / sizeof(void*)) return -1; | |||
| if (!(t = realloc(arr->array, new_size*sizeof(void*)))) return -1; | |||
| arr->array = (void**)t; | |||
| (void)memset(arr->array + arr->size, 0, (new_size-arr->size)*sizeof(void*)); | |||
| arr->size = new_size; | |||
| return 0; | |||
| void *t; | |||
| size_t new_size; | |||
| if (max < arr->size) | |||
| return 0; | |||
| /* Avoid undefined behaviour on size_t overflow */ | |||
| if (arr->size >= SIZE_T_MAX / 2) | |||
| new_size = max; | |||
| else | |||
| { | |||
| new_size = arr->size << 1; | |||
| if (new_size < max) | |||
| new_size = max; | |||
| } | |||
| if (new_size > (~((size_t)0)) / sizeof(void *)) | |||
| return -1; | |||
| if (!(t = realloc(arr->array, new_size * sizeof(void *)))) | |||
| return -1; | |||
| arr->array = (void **)t; | |||
| (void)memset(arr->array + arr->size, 0, (new_size - arr->size) * sizeof(void *)); | |||
| arr->size = new_size; | |||
| return 0; | |||
| } | |||
| int | |||
| array_list_put_idx(struct array_list *arr, size_t idx, void *data) | |||
| int array_list_put_idx(struct array_list *arr, size_t idx, void *data) | |||
| { | |||
| if (idx > SIZE_T_MAX - 1 ) return -1; | |||
| if(array_list_expand_internal(arr, idx+1)) return -1; | |||
| if(idx < arr->length && arr->array[idx]) | |||
| arr->free_fn(arr->array[idx]); | |||
| arr->array[idx] = data; | |||
| if(arr->length <= idx) arr->length = idx + 1; | |||
| return 0; | |||
| if (idx > SIZE_T_MAX - 1) | |||
| return -1; | |||
| if (array_list_expand_internal(arr, idx + 1)) | |||
| return -1; | |||
| if (idx < arr->length && arr->array[idx]) | |||
| arr->free_fn(arr->array[idx]); | |||
| arr->array[idx] = data; | |||
| if (arr->length <= idx) | |||
| arr->length = idx + 1; | |||
| return 0; | |||
| } | |||
| int | |||
| array_list_add(struct array_list *arr, void *data) | |||
| int array_list_add(struct array_list *arr, void *data) | |||
| { | |||
| return array_list_put_idx(arr, arr->length, data); | |||
| return array_list_put_idx(arr, arr->length, data); | |||
| } | |||
| void | |||
| array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *)) | |||
| void array_list_sort(struct array_list *arr, int (*compar)(const void *, const void *)) | |||
| { | |||
| qsort(arr->array, arr->length, sizeof(arr->array[0]), compar); | |||
| qsort(arr->array, arr->length, sizeof(arr->array[0]), compar); | |||
| } | |||
| void* array_list_bsearch(const void **key, struct array_list *arr, | |||
| int (*compar)(const void *, const void *)) | |||
| void *array_list_bsearch(const void **key, struct array_list *arr, | |||
| int (*compar)(const void *, const void *)) | |||
| { | |||
| return bsearch(key, arr->array, arr->length, sizeof(arr->array[0]), | |||
| compar); | |||
| return bsearch(key, arr->array, arr->length, sizeof(arr->array[0]), compar); | |||
| } | |||
| size_t | |||
| array_list_length(struct array_list *arr) | |||
| size_t array_list_length(struct array_list *arr) | |||
| { | |||
| return arr->length; | |||
| return arr->length; | |||
| } | |||
| int | |||
| array_list_del_idx( struct array_list *arr, size_t idx, size_t count ) | |||
| int array_list_del_idx(struct array_list *arr, size_t idx, size_t count) | |||
| { | |||
| size_t i, stop; | |||
| stop = idx + count; | |||
| if ( idx >= arr->length || stop > arr->length ) return -1; | |||
| for ( i = idx; i < stop; ++i ) { | |||
| if ( arr->array[i] ) arr->free_fn( arr->array[i] ); | |||
| if (idx >= arr->length || stop > arr->length) | |||
| return -1; | |||
| for (i = idx; i < stop; ++i) | |||
| { | |||
| if (arr->array[i]) | |||
| arr->free_fn(arr->array[i]); | |||
| } | |||
| memmove( arr->array + idx, arr->array + stop, (arr->length - stop) * sizeof(void*) ); | |||
| memmove(arr->array + idx, arr->array + stop, (arr->length - stop) * sizeof(void *)); | |||
| arr->length -= count; | |||
| return 0; | |||
| } | |||
| @@ -24,44 +24,35 @@ extern "C" { | |||
| #define ARRAY_LIST_DEFAULT_SIZE 32 | |||
| typedef void (array_list_free_fn) (void *data); | |||
| typedef void(array_list_free_fn)(void *data); | |||
| struct array_list | |||
| { | |||
| void **array; | |||
| size_t length; | |||
| size_t size; | |||
| array_list_free_fn *free_fn; | |||
| void **array; | |||
| size_t length; | |||
| size_t size; | |||
| array_list_free_fn *free_fn; | |||
| }; | |||
| typedef struct array_list array_list; | |||
| extern struct array_list* | |||
| array_list_new(array_list_free_fn *free_fn); | |||
| extern struct array_list *array_list_new(array_list_free_fn *free_fn); | |||
| extern void | |||
| array_list_free(struct array_list *al); | |||
| extern void array_list_free(struct array_list *al); | |||
| extern void* | |||
| array_list_get_idx(struct array_list *al, size_t i); | |||
| extern void *array_list_get_idx(struct array_list *al, size_t i); | |||
| extern int | |||
| array_list_put_idx(struct array_list *al, size_t i, void *data); | |||
| extern int array_list_put_idx(struct array_list *al, size_t i, void *data); | |||
| extern int | |||
| array_list_add(struct array_list *al, void *data); | |||
| extern int array_list_add(struct array_list *al, void *data); | |||
| extern size_t | |||
| array_list_length(struct array_list *al); | |||
| extern size_t array_list_length(struct array_list *al); | |||
| extern void | |||
| array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *)); | |||
| extern void array_list_sort(struct array_list *arr, int (*compar)(const void *, const void *)); | |||
| extern void* | |||
| array_list_bsearch(const void **key, struct array_list *arr, | |||
| int (*compar)(const void *, const void *)); | |||
| extern void *array_list_bsearch(const void **key, struct array_list *arr, | |||
| int (*compar)(const void *, const void *)); | |||
| extern int | |||
| array_list_del_idx(struct array_list *arr, size_t idx, size_t count); | |||
| extern int array_list_del_idx(struct array_list *arr, size_t idx, size_t count); | |||
| #ifdef __cplusplus | |||
| } | |||
| @@ -11,17 +11,17 @@ | |||
| #include "config.h" | |||
| #include <stdarg.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <stdarg.h> | |||
| #if HAVE_SYSLOG_H | |||
| # include <syslog.h> | |||
| #include <syslog.h> | |||
| #endif /* HAVE_SYSLOG_H */ | |||
| #if HAVE_UNISTD_H | |||
| # include <unistd.h> | |||
| #include <unistd.h> | |||
| #endif /* HAVE_UNISTD_H */ | |||
| #if HAVE_SYS_PARAM_H | |||
| @@ -33,51 +33,64 @@ | |||
| static int _syslog = 0; | |||
| static int _debug = 0; | |||
| void mc_set_debug(int debug) { _debug = debug; } | |||
| int mc_get_debug(void) { return _debug; } | |||
| void mc_set_debug(int debug) | |||
| { | |||
| _debug = debug; | |||
| } | |||
| int mc_get_debug(void) | |||
| { | |||
| return _debug; | |||
| } | |||
| extern void mc_set_syslog(int syslog) | |||
| { | |||
| _syslog = syslog; | |||
| _syslog = syslog; | |||
| } | |||
| void mc_debug(const char *msg, ...) | |||
| { | |||
| va_list ap; | |||
| if(_debug) { | |||
| va_start(ap, msg); | |||
| va_list ap; | |||
| if (_debug) | |||
| { | |||
| va_start(ap, msg); | |||
| #if HAVE_VSYSLOG | |||
| if(_syslog) { | |||
| vsyslog(LOG_DEBUG, msg, ap); | |||
| } else | |||
| if (_syslog) | |||
| { | |||
| vsyslog(LOG_DEBUG, msg, ap); | |||
| } | |||
| else | |||
| #endif | |||
| vprintf(msg, ap); | |||
| va_end(ap); | |||
| } | |||
| vprintf(msg, ap); | |||
| va_end(ap); | |||
| } | |||
| } | |||
| void mc_error(const char *msg, ...) | |||
| { | |||
| va_list ap; | |||
| va_start(ap, msg); | |||
| va_list ap; | |||
| va_start(ap, msg); | |||
| #if HAVE_VSYSLOG | |||
| if(_syslog) { | |||
| if (_syslog) | |||
| { | |||
| vsyslog(LOG_ERR, msg, ap); | |||
| } else | |||
| } | |||
| else | |||
| #endif | |||
| vfprintf(stderr, msg, ap); | |||
| va_end(ap); | |||
| va_end(ap); | |||
| } | |||
| void mc_info(const char *msg, ...) | |||
| { | |||
| va_list ap; | |||
| va_start(ap, msg); | |||
| va_list ap; | |||
| va_start(ap, msg); | |||
| #if HAVE_VSYSLOG | |||
| if(_syslog) { | |||
| if (_syslog) | |||
| { | |||
| vsyslog(LOG_INFO, msg, ap); | |||
| } else | |||
| } | |||
| else | |||
| #endif | |||
| vfprintf(stderr, msg, ap); | |||
| va_end(ap); | |||
| va_end(ap); | |||
| } | |||
| @@ -24,7 +24,7 @@ extern "C" { | |||
| #endif | |||
| #ifndef JSON_EXPORT | |||
| #if defined(_MSC_VER) | |||
| #if defined(_MSC_VER) | |||
| #define JSON_EXPORT __declspec(dllexport) | |||
| #else | |||
| #define JSON_EXPORT extern | |||
| @@ -46,17 +46,24 @@ JSON_EXPORT void mc_info(const char *msg, ...); | |||
| #ifndef PARSER_BROKEN_FIXED | |||
| #define JASSERT(cond) do {} while(0) | |||
| #define JASSERT(cond) \ | |||
| do \ | |||
| { \ | |||
| } while (0) | |||
| #else | |||
| #define JASSERT(cond) do { \ | |||
| if (!(cond)) { \ | |||
| mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", __FILE__, __LINE__); \ | |||
| *(int *)0 = 1;\ | |||
| abort(); \ | |||
| }\ | |||
| } while(0) | |||
| #define JASSERT(cond) \ | |||
| do \ | |||
| { \ | |||
| if (!(cond)) \ | |||
| { \ | |||
| mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", \ | |||
| __FILE__, __LINE__); \ | |||
| *(int *)0 = 1; \ | |||
| abort(); \ | |||
| } \ | |||
| } while (0) | |||
| #endif | |||
| @@ -69,11 +76,19 @@ JSON_EXPORT void mc_info(const char *msg, ...); | |||
| #define MC_DEBUG(x, ...) mc_debug(x, ##__VA_ARGS__) | |||
| #define MC_INFO(x, ...) mc_info(x, ##__VA_ARGS__) | |||
| #else | |||
| #define MC_SET_DEBUG(x) if (0) mc_set_debug(x) | |||
| #define MC_SET_DEBUG(x) \ | |||
| if (0) \ | |||
| mc_set_debug(x) | |||
| #define MC_GET_DEBUG() (0) | |||
| #define MC_SET_SYSLOG(x) if (0) mc_set_syslog(x) | |||
| #define MC_DEBUG(x, ...) if (0) mc_debug(x, ##__VA_ARGS__) | |||
| #define MC_INFO(x, ...) if (0) mc_info(x, ##__VA_ARGS__) | |||
| #define MC_SET_SYSLOG(x) \ | |||
| if (0) \ | |||
| mc_set_syslog(x) | |||
| #define MC_DEBUG(x, ...) \ | |||
| if (0) \ | |||
| mc_debug(x, ##__VA_ARGS__) | |||
| #define MC_INFO(x, ...) \ | |||
| if (0) \ | |||
| mc_info(x, ##__VA_ARGS__) | |||
| #endif | |||
| #ifdef __cplusplus | |||
| @@ -2,12 +2,13 @@ | |||
| #include <json.h> | |||
| extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { | |||
| const char *data1 = reinterpret_cast<const char *>(data); | |||
| json_tokener *tok = json_tokener_new(); | |||
| json_object *obj = json_tokener_parse_ex(tok, data1, size); | |||
| extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) | |||
| { | |||
| const char *data1 = reinterpret_cast<const char *>(data); | |||
| json_tokener *tok = json_tokener_new(); | |||
| json_object *obj = json_tokener_parse_ex(tok, data1, size); | |||
| json_object_put(obj); | |||
| json_tokener_free(tok); | |||
| return 0; | |||
| json_object_put(obj); | |||
| json_tokener_free(tok); | |||
| return 0; | |||
| } | |||
| @@ -21,15 +21,15 @@ | |||
| extern "C" { | |||
| #endif | |||
| #include "debug.h" | |||
| #include "linkhash.h" | |||
| #include "arraylist.h" | |||
| #include "json_util.h" | |||
| #include "debug.h" | |||
| #include "json_c_version.h" | |||
| #include "json_object.h" | |||
| #include "json_object_iterator.h" | |||
| #include "json_pointer.h" | |||
| #include "json_tokener.h" | |||
| #include "json_object_iterator.h" | |||
| #include "json_c_version.h" | |||
| #include "json_util.h" | |||
| #include "linkhash.h" | |||
| #ifdef __cplusplus | |||
| } | |||
| @@ -17,4 +17,3 @@ int json_c_version_num(void) | |||
| { | |||
| return JSON_C_VERSION_NUM; | |||
| } | |||
| @@ -15,13 +15,12 @@ | |||
| #define JSON_C_MAJOR_VERSION 0 | |||
| #define JSON_C_MINOR_VERSION 13 | |||
| #define JSON_C_MICRO_VERSION 99 | |||
| #define JSON_C_VERSION_NUM ((JSON_C_MAJOR_VERSION << 16) | \ | |||
| (JSON_C_MINOR_VERSION << 8) | \ | |||
| JSON_C_MICRO_VERSION) | |||
| #define JSON_C_VERSION_NUM \ | |||
| ((JSON_C_MAJOR_VERSION << 16) | (JSON_C_MINOR_VERSION << 8) | JSON_C_MICRO_VERSION) | |||
| #define JSON_C_VERSION "0.13.99" | |||
| #ifndef JSON_EXPORT | |||
| #if defined(_MSC_VER) | |||
| #if defined(_MSC_VER) | |||
| #define JSON_EXPORT __declspec(dllexport) | |||
| #else | |||
| #define JSON_EXPORT extern | |||
| @@ -43,6 +42,6 @@ JSON_EXPORT const char *json_c_version(void); /* Returns JSON_C_VERSION */ | |||
| * @see JSON_C_VERSION_NUM | |||
| * @return the version of the json-c library as an int | |||
| */ | |||
| JSON_EXPORT int json_c_version_num(void); /* Returns JSON_C_VERSION_NUM */ | |||
| JSON_EXPORT int json_c_version_num(void); /* Returns JSON_C_VERSION_NUM */ | |||
| #endif | |||
| @@ -18,7 +18,7 @@ | |||
| #define _json_object_h_ | |||
| #ifdef __GNUC__ | |||
| #define THIS_FUNCTION_IS_DEPRECATED(func) func __attribute__ ((deprecated)) | |||
| #define THIS_FUNCTION_IS_DEPRECATED(func) func __attribute__((deprecated)) | |||
| #elif defined(_MSC_VER) | |||
| #define THIS_FUNCTION_IS_DEPRECATED(func) __declspec(deprecated) func | |||
| #elif defined(__clang__) | |||
| @@ -34,16 +34,16 @@ | |||
| #endif | |||
| #ifndef JSON_EXPORT | |||
| #if defined(_MSC_VER) | |||
| #if defined(_MSC_VER) | |||
| #define JSON_EXPORT __declspec(dllexport) | |||
| #else | |||
| #define JSON_EXPORT extern | |||
| #endif | |||
| #endif | |||
| #include <stddef.h> | |||
| #include "json_inttypes.h" | |||
| #include "printbuf.h" | |||
| #include <stddef.h> | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| @@ -56,13 +56,13 @@ extern "C" { | |||
| * json_object_to_file_ext() functions which causes the output | |||
| * to have no extra whitespace or formatting applied. | |||
| */ | |||
| #define JSON_C_TO_STRING_PLAIN 0 | |||
| #define JSON_C_TO_STRING_PLAIN 0 | |||
| /** | |||
| * A flag for the json_object_to_json_string_ext() and | |||
| * json_object_to_file_ext() functions which causes the output to have | |||
| * minimal whitespace inserted to make things slightly more readable. | |||
| */ | |||
| #define JSON_C_TO_STRING_SPACED (1<<0) | |||
| #define JSON_C_TO_STRING_SPACED (1 << 0) | |||
| /** | |||
| * A flag for the json_object_to_json_string_ext() and | |||
| * json_object_to_file_ext() functions which causes | |||
| @@ -71,7 +71,7 @@ extern "C" { | |||
| * See the "Two Space Tab" option at http://jsonformatter.curiousconcept.com/ | |||
| * for an example of the format. | |||
| */ | |||
| #define JSON_C_TO_STRING_PRETTY (1<<1) | |||
| #define JSON_C_TO_STRING_PRETTY (1 << 1) | |||
| /** | |||
| * A flag for the json_object_to_json_string_ext() and | |||
| * json_object_to_file_ext() functions which causes | |||
| @@ -79,16 +79,16 @@ extern "C" { | |||
| * | |||
| * Instead of a "Two Space Tab" this gives a single tab character. | |||
| */ | |||
| #define JSON_C_TO_STRING_PRETTY_TAB (1<<3) | |||
| #define JSON_C_TO_STRING_PRETTY_TAB (1 << 3) | |||
| /** | |||
| * A flag to drop trailing zero for float values | |||
| */ | |||
| #define JSON_C_TO_STRING_NOZERO (1<<2) | |||
| #define JSON_C_TO_STRING_NOZERO (1 << 2) | |||
| /** | |||
| * Don't escape forward slashes. | |||
| */ | |||
| #define JSON_C_TO_STRING_NOSLASHESCAPE (1<<4) | |||
| #define JSON_C_TO_STRING_NOSLASHESCAPE (1 << 4) | |||
| /** | |||
| * A flag for the json_object_object_add_ex function which | |||
| @@ -100,7 +100,7 @@ extern "C" { | |||
| * knows for sure the key values are unique (e.g. because the | |||
| * code adds a well-known set of constant key values). | |||
| */ | |||
| #define JSON_C_OBJECT_ADD_KEY_IS_NEW (1<<1) | |||
| #define JSON_C_OBJECT_ADD_KEY_IS_NEW (1 << 1) | |||
| /** | |||
| * A flag for the json_object_object_add_ex function which | |||
| * flags the key as being constant memory. This means that | |||
| @@ -118,7 +118,7 @@ extern "C" { | |||
| * json_object_object_add_ex(obj, "ip", json, | |||
| * JSON_C_OBJECT_KEY_IS_CONSTANT); | |||
| */ | |||
| #define JSON_C_OBJECT_KEY_IS_CONSTANT (1<<2) | |||
| #define JSON_C_OBJECT_KEY_IS_CONSTANT (1 << 2) | |||
| /** | |||
| * Set the global value of an option, which will apply to all | |||
| @@ -158,27 +158,26 @@ typedef struct json_object json_object; | |||
| /** | |||
| * Type of custom user delete functions. See json_object_set_serializer. | |||
| */ | |||
| typedef void (json_object_delete_fn)(struct json_object *jso, void *userdata); | |||
| typedef void(json_object_delete_fn)(struct json_object *jso, void *userdata); | |||
| /** | |||
| * Type of a custom serialization function. See json_object_set_serializer. | |||
| */ | |||
| typedef int (json_object_to_json_string_fn)(struct json_object *jso, | |||
| struct printbuf *pb, | |||
| int level, | |||
| int flags); | |||
| typedef int(json_object_to_json_string_fn)(struct json_object *jso, struct printbuf *pb, int level, | |||
| int flags); | |||
| /* supported object types */ | |||
| typedef enum json_type { | |||
| /* If you change this, be sure to update json_type_to_name() too */ | |||
| json_type_null, | |||
| json_type_boolean, | |||
| json_type_double, | |||
| json_type_int, | |||
| json_type_object, | |||
| json_type_array, | |||
| json_type_string | |||
| typedef enum json_type | |||
| { | |||
| /* If you change this, be sure to update json_type_to_name() too */ | |||
| json_type_null, | |||
| json_type_boolean, | |||
| json_type_double, | |||
| json_type_int, | |||
| json_type_object, | |||
| json_type_array, | |||
| json_type_string | |||
| } json_type; | |||
| /* reference counting functions */ | |||
| @@ -189,7 +188,7 @@ typedef enum json_type { | |||
| * | |||
| * @param obj the json_object instance | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_get(struct json_object *obj); | |||
| JSON_EXPORT struct json_object *json_object_get(struct json_object *obj); | |||
| /** | |||
| * Decrement the reference count of json_object and free if it reaches zero. | |||
| @@ -232,7 +231,6 @@ JSON_EXPORT int json_object_is_type(const struct json_object *obj, enum json_typ | |||
| */ | |||
| JSON_EXPORT enum json_type json_object_get_type(const struct json_object *obj); | |||
| /** Stringify object to json format. | |||
| * Equivalent to json_object_to_json_string_ext(obj, JSON_C_TO_STRING_SPACED) | |||
| * The pointer you get is an internal of your json object. You don't | |||
| @@ -242,7 +240,7 @@ JSON_EXPORT enum json_type json_object_get_type(const struct json_object *obj); | |||
| * @param obj the json_object instance | |||
| * @returns a string in JSON format | |||
| */ | |||
| JSON_EXPORT const char* json_object_to_json_string(struct json_object *obj); | |||
| JSON_EXPORT const char *json_object_to_json_string(struct json_object *obj); | |||
| /** Stringify object to json format | |||
| * @see json_object_to_json_string() for details on how to free string. | |||
| @@ -250,8 +248,7 @@ JSON_EXPORT const char* json_object_to_json_string(struct json_object *obj); | |||
| * @param flags formatting options, see JSON_C_TO_STRING_PRETTY and other constants | |||
| * @returns a string in JSON format | |||
| */ | |||
| JSON_EXPORT const char* json_object_to_json_string_ext(struct json_object *obj, int | |||
| flags); | |||
| JSON_EXPORT const char *json_object_to_json_string_ext(struct json_object *obj, int flags); | |||
| /** Stringify object to json format | |||
| * @see json_object_to_json_string() for details on how to free string. | |||
| @@ -260,8 +257,8 @@ flags); | |||
| * @param length a pointer where, if not NULL, the length (without null) is stored | |||
| * @returns a string in JSON format and the length if not NULL | |||
| */ | |||
| JSON_EXPORT const char* json_object_to_json_string_length(struct json_object *obj, int | |||
| flags, size_t *length); | |||
| JSON_EXPORT const char *json_object_to_json_string_length(struct json_object *obj, int flags, | |||
| size_t *length); | |||
| /** | |||
| * Returns the userdata set by json_object_set_userdata() or | |||
| @@ -269,7 +266,7 @@ flags, size_t *length); | |||
| * | |||
| * @param jso the object to return the userdata for | |||
| */ | |||
| JSON_EXPORT void* json_object_get_userdata(json_object *jso); | |||
| JSON_EXPORT void *json_object_get_userdata(json_object *jso); | |||
| /** | |||
| * Set an opaque userdata value for an object | |||
| @@ -297,7 +294,7 @@ JSON_EXPORT void* json_object_get_userdata(json_object *jso); | |||
| * @param user_delete an optional function from freeing userdata | |||
| */ | |||
| JSON_EXPORT void json_object_set_userdata(json_object *jso, void *userdata, | |||
| json_object_delete_fn *user_delete); | |||
| json_object_delete_fn *user_delete); | |||
| /** | |||
| * Set a custom serialization function to be used when this particular object | |||
| @@ -330,9 +327,8 @@ JSON_EXPORT void json_object_set_userdata(json_object *jso, void *userdata, | |||
| * @param user_delete an optional function from freeing userdata | |||
| */ | |||
| JSON_EXPORT void json_object_set_serializer(json_object *jso, | |||
| json_object_to_json_string_fn *to_string_func, | |||
| void *userdata, | |||
| json_object_delete_fn *user_delete); | |||
| json_object_to_json_string_fn *to_string_func, | |||
| void *userdata, json_object_delete_fn *user_delete); | |||
| #ifdef __clang__ | |||
| /* | |||
| @@ -369,7 +365,6 @@ JSON_EXPORT json_object_to_json_string_fn json_object_userdata_to_json_string; | |||
| #pragma clang diagnostic pop | |||
| #endif | |||
| /* object type methods */ | |||
| /** Create a new empty object with a reference count of 1. The caller of | |||
| @@ -382,18 +377,18 @@ JSON_EXPORT json_object_to_json_string_fn json_object_userdata_to_json_string; | |||
| * | |||
| * @returns a json_object of type json_type_object | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_new_object(void); | |||
| JSON_EXPORT struct json_object *json_object_new_object(void); | |||
| /** Get the hashtable of a json_object of type json_type_object | |||
| * @param obj the json_object instance | |||
| * @returns a linkhash | |||
| */ | |||
| JSON_EXPORT struct lh_table* json_object_get_object(const struct json_object *obj); | |||
| JSON_EXPORT struct lh_table *json_object_get_object(const struct json_object *obj); | |||
| /** Get the size of an object in terms of the number of fields it has. | |||
| * @param obj the json_object whose length to return | |||
| */ | |||
| JSON_EXPORT int json_object_object_length(const struct json_object* obj); | |||
| JSON_EXPORT int json_object_object_length(const struct json_object *obj); | |||
| /** Get the sizeof (struct json_object). | |||
| * @returns a size_t with the sizeof (struct json_object) | |||
| @@ -419,8 +414,8 @@ JSON_C_CONST_FUNCTION(JSON_EXPORT size_t json_c_object_sizeof(void)); | |||
| * @return On success, <code>0</code> is returned. | |||
| * On error, a negative value is returned. | |||
| */ | |||
| JSON_EXPORT int json_object_object_add(struct json_object* obj, const char *key, | |||
| struct json_object *val); | |||
| JSON_EXPORT int json_object_object_add(struct json_object *obj, const char *key, | |||
| struct json_object *val); | |||
| /** Add an object field to a json_object of type json_type_object | |||
| * | |||
| @@ -435,10 +430,8 @@ JSON_EXPORT int json_object_object_add(struct json_object* obj, const char *key, | |||
| * @param opts process-modifying options. To specify multiple options, use | |||
| * arithmetic or (OPT1|OPT2) | |||
| */ | |||
| JSON_EXPORT int json_object_object_add_ex(struct json_object* obj, | |||
| const char *const key, | |||
| struct json_object *const val, | |||
| const unsigned opts); | |||
| JSON_EXPORT int json_object_object_add_ex(struct json_object *obj, const char *const key, | |||
| struct json_object *const val, const unsigned opts); | |||
| /** Get the json_object associate with a given object field. | |||
| * Deprecated/discouraged: used json_object_object_get_ex instead. | |||
| @@ -461,8 +454,8 @@ JSON_EXPORT int json_object_object_add_ex(struct json_object* obj, | |||
| * @param key the object field name | |||
| * @returns the json_object associated with the given field name | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_object_get(const struct json_object* obj, | |||
| const char *key); | |||
| JSON_EXPORT struct json_object *json_object_object_get(const struct json_object *obj, | |||
| const char *key); | |||
| /** Get the json_object associated with a given object field. | |||
| * | |||
| @@ -482,9 +475,8 @@ JSON_EXPORT struct json_object* json_object_object_get(const struct json_object* | |||
| * It is safe to pass a NULL value. | |||
| * @returns whether or not the key exists | |||
| */ | |||
| JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object* obj, | |||
| const char *key, | |||
| struct json_object **value); | |||
| JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object *obj, const char *key, | |||
| struct json_object **value); | |||
| /** Delete the given json_object field | |||
| * | |||
| @@ -495,7 +487,7 @@ JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object* obj, | |||
| * @param obj the json_object instance | |||
| * @param key the object field name | |||
| */ | |||
| JSON_EXPORT void json_object_object_del(struct json_object* obj, const char *key); | |||
| JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key); | |||
| /** | |||
| * Iterate through all keys and values of an object. | |||
| @@ -512,31 +504,35 @@ JSON_EXPORT void json_object_object_del(struct json_object* obj, const char *key | |||
| */ | |||
| #if defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L | |||
| # define json_object_object_foreach(obj,key,val) \ | |||
| char *key = NULL; \ | |||
| struct json_object *val __attribute__((__unused__)) = NULL; \ | |||
| for(struct lh_entry *entry ## key = json_object_get_object(obj)->head, *entry_next ## key = NULL; \ | |||
| ({ if(entry ## key) { \ | |||
| key = (char*)lh_entry_k(entry ## key); \ | |||
| val = (struct json_object*)lh_entry_v(entry ## key); \ | |||
| entry_next ## key = entry ## key->next; \ | |||
| } ; entry ## key; }); \ | |||
| entry ## key = entry_next ## key ) | |||
| #define json_object_object_foreach(obj, key, val) \ | |||
| char *key = NULL; \ | |||
| struct json_object *val __attribute__((__unused__)) = NULL; \ | |||
| for (struct lh_entry *entry##key = json_object_get_object(obj)->head, \ | |||
| *entry_next##key = NULL; \ | |||
| ({ \ | |||
| if (entry##key) \ | |||
| { \ | |||
| key = (char *)lh_entry_k(entry##key); \ | |||
| val = (struct json_object *)lh_entry_v(entry##key); \ | |||
| entry_next##key = entry##key->next; \ | |||
| }; \ | |||
| entry##key; \ | |||
| }); \ | |||
| entry##key = entry_next##key) | |||
| #else /* ANSI C or MSC */ | |||
| # define json_object_object_foreach(obj,key,val) \ | |||
| char *key = NULL;\ | |||
| struct json_object *val = NULL; \ | |||
| struct lh_entry *entry ## key; \ | |||
| struct lh_entry *entry_next ## key = NULL; \ | |||
| for(entry ## key = json_object_get_object(obj)->head; \ | |||
| (entry ## key ? ( \ | |||
| key = (char*)lh_entry_k(entry ## key), \ | |||
| val = (struct json_object*)lh_entry_v(entry ## key), \ | |||
| entry_next ## key = entry ## key->next, \ | |||
| entry ## key) : 0); \ | |||
| entry ## key = entry_next ## key) | |||
| #define json_object_object_foreach(obj, key, val) \ | |||
| char *key = NULL; \ | |||
| struct json_object *val = NULL; \ | |||
| struct lh_entry *entry##key; \ | |||
| struct lh_entry *entry_next##key = NULL; \ | |||
| for (entry##key = json_object_get_object(obj)->head; \ | |||
| (entry##key ? (key = (char *)lh_entry_k(entry##key), \ | |||
| val = (struct json_object *)lh_entry_v(entry##key), \ | |||
| entry_next##key = entry##key->next, entry##key) \ | |||
| : 0); \ | |||
| entry##key = entry_next##key) | |||
| #endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L */ | |||
| @@ -544,23 +540,25 @@ JSON_EXPORT void json_object_object_del(struct json_object* obj, const char *key | |||
| * @param obj the json_object instance | |||
| * @param iter the object iterator, use type json_object_iter | |||
| */ | |||
| #define json_object_object_foreachC(obj,iter) \ | |||
| for(iter.entry = json_object_get_object(obj)->head; \ | |||
| (iter.entry ? (iter.key = (char*)lh_entry_k(iter.entry), iter.val = (struct json_object*)lh_entry_v(iter.entry), iter.entry) : 0); \ | |||
| iter.entry = iter.entry->next) | |||
| #define json_object_object_foreachC(obj, iter) \ | |||
| for (iter.entry = json_object_get_object(obj)->head; \ | |||
| (iter.entry ? (iter.key = (char *)lh_entry_k(iter.entry), \ | |||
| iter.val = (struct json_object *)lh_entry_v(iter.entry), iter.entry) \ | |||
| : 0); \ | |||
| iter.entry = iter.entry->next) | |||
| /* Array type methods */ | |||
| /** Create a new empty json_object of type json_type_array | |||
| * @returns a json_object of type json_type_array | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_new_array(void); | |||
| JSON_EXPORT struct json_object *json_object_new_array(void); | |||
| /** Get the arraylist of a json_object of type json_type_array | |||
| * @param obj the json_object instance | |||
| * @returns an arraylist | |||
| */ | |||
| JSON_EXPORT struct array_list* json_object_get_array(const struct json_object *obj); | |||
| JSON_EXPORT struct array_list *json_object_get_array(const struct json_object *obj); | |||
| /** Get the length of a json_object of type json_type_array | |||
| * @param obj the json_object instance | |||
| @@ -576,7 +574,8 @@ JSON_EXPORT size_t json_object_array_length(const struct json_object *obj); | |||
| * @param jso the json_object instance | |||
| * @param sort_fn a sorting function | |||
| */ | |||
| JSON_EXPORT void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *)); | |||
| JSON_EXPORT void json_object_array_sort(struct json_object *jso, | |||
| int (*sort_fn)(const void *, const void *)); | |||
| /** Binary search a sorted array for a specified key object. | |||
| * | |||
| @@ -592,10 +591,9 @@ JSON_EXPORT void json_object_array_sort(struct json_object *jso, int(*sort_fn)(c | |||
| * | |||
| * @return the wanted json_object instance | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_array_bsearch( | |||
| const struct json_object *key, | |||
| const struct json_object *jso, | |||
| int (*sort_fn)(const void *, const void *)); | |||
| JSON_EXPORT struct json_object * | |||
| json_object_array_bsearch(const struct json_object *key, const struct json_object *jso, | |||
| int (*sort_fn)(const void *, const void *)); | |||
| /** Add an element to the end of a json_object of type json_type_array | |||
| * | |||
| @@ -606,8 +604,7 @@ JSON_EXPORT struct json_object* json_object_array_bsearch( | |||
| * @param obj the json_object instance | |||
| * @param val the json_object to be added | |||
| */ | |||
| JSON_EXPORT int json_object_array_add(struct json_object *obj, | |||
| struct json_object *val); | |||
| JSON_EXPORT int json_object_array_add(struct json_object *obj, struct json_object *val); | |||
| /** Insert or replace an element at a specified index in an array (a json_object of type json_type_array) | |||
| * | |||
| @@ -625,15 +622,15 @@ JSON_EXPORT int json_object_array_add(struct json_object *obj, | |||
| * @param val the json_object to be added | |||
| */ | |||
| JSON_EXPORT int json_object_array_put_idx(struct json_object *obj, size_t idx, | |||
| struct json_object *val); | |||
| struct json_object *val); | |||
| /** Get the element at specified index of the array (a json_object of type json_type_array) | |||
| * @param obj the json_object instance | |||
| * @param idx the index to get the element at | |||
| * @returns the json_object at the specified index (or NULL) | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_array_get_idx(const struct json_object *obj, | |||
| size_t idx); | |||
| JSON_EXPORT struct json_object *json_object_array_get_idx(const struct json_object *obj, | |||
| size_t idx); | |||
| /** Delete an elements from a specified index in an array (a json_object of type json_type_array) | |||
| * | |||
| @@ -654,7 +651,7 @@ JSON_EXPORT int json_object_array_del_idx(struct json_object *obj, size_t idx, s | |||
| * @param b a json_bool 1 or 0 | |||
| * @returns a json_object of type json_type_boolean | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_new_boolean(json_bool b); | |||
| JSON_EXPORT struct json_object *json_object_new_boolean(json_bool b); | |||
| /** Get the json_bool value of a json_object | |||
| * | |||
| @@ -669,7 +666,6 @@ JSON_EXPORT struct json_object* json_object_new_boolean(json_bool b); | |||
| */ | |||
| JSON_EXPORT json_bool json_object_get_boolean(const struct json_object *obj); | |||
| /** Set the json_bool value of a json_object | |||
| * | |||
| * The type of obj is checked to be a json_type_boolean and 0 is returned | |||
| @@ -680,8 +676,7 @@ JSON_EXPORT json_bool json_object_get_boolean(const struct json_object *obj); | |||
| * @param new_value the value to be set | |||
| * @returns 1 if value is set correctly, 0 otherwise | |||
| */ | |||
| JSON_EXPORT int json_object_set_boolean(struct json_object *obj,json_bool new_value); | |||
| JSON_EXPORT int json_object_set_boolean(struct json_object *obj, json_bool new_value); | |||
| /* int type methods */ | |||
| @@ -691,22 +686,19 @@ JSON_EXPORT int json_object_set_boolean(struct json_object *obj,json_bool new_va | |||
| * @param i the integer | |||
| * @returns a json_object of type json_type_int | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_new_int(int32_t i); | |||
| JSON_EXPORT struct json_object *json_object_new_int(int32_t i); | |||
| /** Create a new empty json_object of type json_type_int | |||
| * @param i the integer | |||
| * @returns a json_object of type json_type_int | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_new_int64(int64_t i); | |||
| JSON_EXPORT struct json_object *json_object_new_int64(int64_t i); | |||
| /** Create a new empty json_object of type json_type_uint | |||
| * @param i the integer | |||
| * @returns a json_object of type json_type_uint | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_new_uint64(uint64_t i); | |||
| JSON_EXPORT struct json_object *json_object_new_uint64(uint64_t i); | |||
| /** Get the int value of a json_object | |||
| * | |||
| @@ -734,7 +726,7 @@ JSON_EXPORT int32_t json_object_get_int(const struct json_object *obj); | |||
| * @param new_value the value to be set | |||
| * @returns 1 if value is set correctly, 0 otherwise | |||
| */ | |||
| JSON_EXPORT int json_object_set_int(struct json_object *obj,int new_value); | |||
| JSON_EXPORT int json_object_set_int(struct json_object *obj, int new_value); | |||
| /** Increment a json_type_int object by the given amount, which may be negative. | |||
| * | |||
| @@ -792,7 +784,7 @@ JSON_EXPORT uint64_t json_object_get_uint64(const struct json_object *obj); | |||
| * @param new_value the value to be set | |||
| * @returns 1 if value is set correctly, 0 otherwise | |||
| */ | |||
| JSON_EXPORT int json_object_set_int64(struct json_object *obj,int64_t new_value); | |||
| JSON_EXPORT int json_object_set_int64(struct json_object *obj, int64_t new_value); | |||
| /** Set the uint64_t value of a json_object | |||
| * | |||
| @@ -804,7 +796,7 @@ JSON_EXPORT int json_object_set_int64(struct json_object *obj,int64_t new_value) | |||
| * @param new_value the value to be set | |||
| * @returns 1 if value is set correctly, 0 otherwise | |||
| */ | |||
| JSON_EXPORT int json_object_set_uint64(struct json_object *obj,uint64_t new_value); | |||
| JSON_EXPORT int json_object_set_uint64(struct json_object *obj, uint64_t new_value); | |||
| /* double type methods */ | |||
| @@ -815,7 +807,7 @@ JSON_EXPORT int json_object_set_uint64(struct json_object *obj,uint64_t new_valu | |||
| * @param d the double | |||
| * @returns a json_object of type json_type_double | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_new_double(double d); | |||
| JSON_EXPORT struct json_object *json_object_new_double(double d); | |||
| /** | |||
| * Create a new json_object of type json_type_double, using | |||
| @@ -844,7 +836,7 @@ JSON_EXPORT struct json_object* json_object_new_double(double d); | |||
| * @param d the numeric value of the double. | |||
| * @param ds the string representation of the double. This will be copied. | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_new_double_s(double d, const char *ds); | |||
| JSON_EXPORT struct json_object *json_object_new_double_s(double d, const char *ds); | |||
| /** | |||
| * Set a global or thread-local json-c option, depending on whether | |||
| @@ -858,9 +850,8 @@ JSON_EXPORT struct json_object* json_object_new_double_s(double d, const char *d | |||
| * | |||
| * @return -1 on errors, 0 on success. | |||
| */ | |||
| JSON_EXPORT int json_c_set_serialization_double_format(const char *double_format, int global_or_thread); | |||
| JSON_EXPORT int json_c_set_serialization_double_format(const char *double_format, | |||
| int global_or_thread); | |||
| /** Serialize a json_object of type json_type_double to a string. | |||
| * | |||
| @@ -881,10 +872,8 @@ JSON_EXPORT int json_c_set_serialization_double_format(const char *double_format | |||
| * @param level Ignored. | |||
| * @param flags Ignored. | |||
| */ | |||
| JSON_EXPORT int json_object_double_to_json_string(struct json_object* jso, | |||
| struct printbuf *pb, | |||
| int level, | |||
| int flags); | |||
| JSON_EXPORT int json_object_double_to_json_string(struct json_object *jso, struct printbuf *pb, | |||
| int level, int flags); | |||
| /** Get the double floating point value of a json_object | |||
| * | |||
| @@ -911,7 +900,6 @@ JSON_EXPORT int json_object_double_to_json_string(struct json_object* jso, | |||
| */ | |||
| JSON_EXPORT double json_object_get_double(const struct json_object *obj); | |||
| /** Set the double value of a json_object | |||
| * | |||
| * The type of obj is checked to be a json_type_double and 0 is returned | |||
| @@ -925,9 +913,7 @@ JSON_EXPORT double json_object_get_double(const struct json_object *obj); | |||
| * @param new_value the value to be set | |||
| * @returns 1 if value is set correctly, 0 otherwise | |||
| */ | |||
| JSON_EXPORT int json_object_set_double(struct json_object *obj,double new_value); | |||
| JSON_EXPORT int json_object_set_double(struct json_object *obj, double new_value); | |||
| /* string type methods */ | |||
| @@ -939,7 +925,7 @@ JSON_EXPORT int json_object_set_double(struct json_object *obj,double new_value) | |||
| * @returns a json_object of type json_type_string | |||
| * @see json_object_new_string_len() | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_new_string(const char *s); | |||
| JSON_EXPORT struct json_object *json_object_new_string(const char *s); | |||
| /** Create a new empty json_object of type json_type_string and allocate | |||
| * len characters for the new string. | |||
| @@ -951,7 +937,7 @@ JSON_EXPORT struct json_object* json_object_new_string(const char *s); | |||
| * @returns a json_object of type json_type_string | |||
| * @see json_object_new_string() | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_new_string_len(const char *s, const int len); | |||
| JSON_EXPORT struct json_object *json_object_new_string_len(const char *s, const int len); | |||
| /** Get the string value of a json_object | |||
| * | |||
| @@ -969,7 +955,7 @@ JSON_EXPORT struct json_object* json_object_new_string_len(const char *s, const | |||
| * @param obj the json_object instance | |||
| * @returns a string or NULL | |||
| */ | |||
| JSON_EXPORT const char* json_object_get_string(struct json_object *obj); | |||
| JSON_EXPORT const char *json_object_get_string(struct json_object *obj); | |||
| /** Get the string length of a json_object | |||
| * | |||
| @@ -981,12 +967,11 @@ JSON_EXPORT const char* json_object_get_string(struct json_object *obj); | |||
| */ | |||
| JSON_EXPORT int json_object_get_string_len(const struct json_object *obj); | |||
| /** Set the string value of a json_object with zero terminated strings | |||
| * equivalent to json_object_set_string_len (obj, new_value, strlen(new_value)) | |||
| * @returns 1 if value is set correctly, 0 otherwise | |||
| */ | |||
| JSON_EXPORT int json_object_set_string(json_object* obj, const char* new_value); | |||
| JSON_EXPORT int json_object_set_string(json_object *obj, const char *new_value); | |||
| /** Set the string value of a json_object str | |||
| * | |||
| @@ -999,13 +984,13 @@ JSON_EXPORT int json_object_set_string(json_object* obj, const char* new_value); | |||
| * @param len the length of new_value | |||
| * @returns 1 if value is set correctly, 0 otherwise | |||
| */ | |||
| JSON_EXPORT int json_object_set_string_len(json_object* obj, const char* new_value, int len); | |||
| JSON_EXPORT int json_object_set_string_len(json_object *obj, const char *new_value, int len); | |||
| /** This method exists only to provide a complementary function | |||
| * along the lines of the other json_object_new_* functions. | |||
| * It always returns NULL, and it is entirely acceptable to simply use NULL directly. | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_new_null(); | |||
| JSON_EXPORT struct json_object *json_object_new_null(); | |||
| /** Check if two json_object's are equal | |||
| * | |||
| @@ -1024,8 +1009,7 @@ JSON_EXPORT struct json_object* json_object_new_null(); | |||
| * @param obj2 the second json_object instance | |||
| * @returns whether both objects are equal or not | |||
| */ | |||
| JSON_EXPORT int json_object_equal(struct json_object *obj1, | |||
| struct json_object *obj2); | |||
| JSON_EXPORT int json_object_equal(struct json_object *obj1, struct json_object *obj2); | |||
| /** | |||
| * Perform a shallow copy of src into *dst as part of an overall json_object_deep_copy(). | |||
| @@ -1041,7 +1025,8 @@ JSON_EXPORT int json_object_equal(struct json_object *obj1, | |||
| * | |||
| * @return On success 1 or 2, -1 on errors | |||
| */ | |||
| typedef int (json_c_shallow_copy_fn)(json_object *src, json_object *parent, const char *key, size_t index, json_object **dst); | |||
| typedef int(json_c_shallow_copy_fn)(json_object *src, json_object *parent, const char *key, | |||
| size_t index, json_object **dst); | |||
| /** | |||
| * The default shallow copy implementation for use with json_object_deep_copy(). | |||
| @@ -1076,7 +1061,8 @@ JSON_EXPORT json_c_shallow_copy_fn json_c_shallow_copy_default; | |||
| * or if the destination pointer is non-NULL | |||
| */ | |||
| JSON_EXPORT int json_object_deep_copy(struct json_object *src, struct json_object **dst, json_c_shallow_copy_fn *shallow_copy); | |||
| JSON_EXPORT int json_object_deep_copy(struct json_object *src, struct json_object **dst, | |||
| json_c_shallow_copy_fn *shallow_copy); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| @@ -53,111 +53,100 @@ | |||
| /// Our current representation of the "end" iterator; | |||
| /// | |||
| /// @note May not always be NULL | |||
| static const void* kObjectEndIterValue = NULL; | |||
| static const void *kObjectEndIterValue = NULL; | |||
| /** | |||
| * **************************************************************************** | |||
| */ | |||
| struct json_object_iterator | |||
| json_object_iter_begin(struct json_object* obj) | |||
| struct json_object_iterator json_object_iter_begin(struct json_object *obj) | |||
| { | |||
| struct json_object_iterator iter; | |||
| struct lh_table* pTable; | |||
| /// @note json_object_get_object will return NULL if passed NULL | |||
| /// or a non-json_type_object instance | |||
| pTable = json_object_get_object(obj); | |||
| JASSERT(NULL != pTable); | |||
| /// @note For a pair-less Object, head is NULL, which matches our | |||
| /// definition of the "end" iterator | |||
| iter.opaque_ = pTable->head; | |||
| return iter; | |||
| struct json_object_iterator iter; | |||
| struct lh_table *pTable; | |||
| /// @note json_object_get_object will return NULL if passed NULL | |||
| /// or a non-json_type_object instance | |||
| pTable = json_object_get_object(obj); | |||
| JASSERT(NULL != pTable); | |||
| /// @note For a pair-less Object, head is NULL, which matches our | |||
| /// definition of the "end" iterator | |||
| iter.opaque_ = pTable->head; | |||
| return iter; | |||
| } | |||
| /** | |||
| * **************************************************************************** | |||
| */ | |||
| struct json_object_iterator | |||
| json_object_iter_end(const struct json_object* obj) | |||
| struct json_object_iterator json_object_iter_end(const struct json_object *obj) | |||
| { | |||
| struct json_object_iterator iter; | |||
| struct json_object_iterator iter; | |||
| JASSERT(NULL != obj); | |||
| JASSERT(json_object_is_type(obj, json_type_object)); | |||
| JASSERT(NULL != obj); | |||
| JASSERT(json_object_is_type(obj, json_type_object)); | |||
| iter.opaque_ = kObjectEndIterValue; | |||
| iter.opaque_ = kObjectEndIterValue; | |||
| return iter; | |||
| return iter; | |||
| } | |||
| /** | |||
| * **************************************************************************** | |||
| */ | |||
| void | |||
| json_object_iter_next(struct json_object_iterator* iter) | |||
| void json_object_iter_next(struct json_object_iterator *iter) | |||
| { | |||
| JASSERT(NULL != iter); | |||
| JASSERT(kObjectEndIterValue != iter->opaque_); | |||
| JASSERT(NULL != iter); | |||
| JASSERT(kObjectEndIterValue != iter->opaque_); | |||
| iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next; | |||
| iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next; | |||
| } | |||
| /** | |||
| * **************************************************************************** | |||
| */ | |||
| const char* | |||
| json_object_iter_peek_name(const struct json_object_iterator* iter) | |||
| const char *json_object_iter_peek_name(const struct json_object_iterator *iter) | |||
| { | |||
| JASSERT(NULL != iter); | |||
| JASSERT(kObjectEndIterValue != iter->opaque_); | |||
| JASSERT(NULL != iter); | |||
| JASSERT(kObjectEndIterValue != iter->opaque_); | |||
| return (const char*)(((const struct lh_entry *)iter->opaque_)->k); | |||
| return (const char *)(((const struct lh_entry *)iter->opaque_)->k); | |||
| } | |||
| /** | |||
| * **************************************************************************** | |||
| */ | |||
| struct json_object* | |||
| json_object_iter_peek_value(const struct json_object_iterator* iter) | |||
| struct json_object *json_object_iter_peek_value(const struct json_object_iterator *iter) | |||
| { | |||
| JASSERT(NULL != iter); | |||
| JASSERT(kObjectEndIterValue != iter->opaque_); | |||
| JASSERT(NULL != iter); | |||
| JASSERT(kObjectEndIterValue != iter->opaque_); | |||
| return (struct json_object*)lh_entry_v((const struct lh_entry *)iter->opaque_); | |||
| return (struct json_object *)lh_entry_v((const struct lh_entry *)iter->opaque_); | |||
| } | |||
| /** | |||
| * **************************************************************************** | |||
| */ | |||
| json_bool | |||
| json_object_iter_equal(const struct json_object_iterator* iter1, | |||
| const struct json_object_iterator* iter2) | |||
| json_bool json_object_iter_equal(const struct json_object_iterator *iter1, | |||
| const struct json_object_iterator *iter2) | |||
| { | |||
| JASSERT(NULL != iter1); | |||
| JASSERT(NULL != iter2); | |||
| JASSERT(NULL != iter1); | |||
| JASSERT(NULL != iter2); | |||
| return (iter1->opaque_ == iter2->opaque_); | |||
| return (iter1->opaque_ == iter2->opaque_); | |||
| } | |||
| /** | |||
| * **************************************************************************** | |||
| */ | |||
| struct json_object_iterator | |||
| json_object_iter_init_default(void) | |||
| struct json_object_iterator json_object_iter_init_default(void) | |||
| { | |||
| struct json_object_iterator iter; | |||
| struct json_object_iterator iter; | |||
| /** | |||
| * @note Make this a negative, invalid value, such that | |||
| * accidental access to it would likely be trapped by the | |||
| * hardware as an invalid address. | |||
| */ | |||
| iter.opaque_ = NULL; | |||
| /** | |||
| * @note Make this a negative, invalid value, such that | |||
| * accidental access to it would likely be trapped by the | |||
| * hardware as an invalid address. | |||
| */ | |||
| iter.opaque_ = NULL; | |||
| return iter; | |||
| return iter; | |||
| } | |||
| @@ -20,14 +20,13 @@ | |||
| ******************************************************************************* | |||
| */ | |||
| #ifndef JSON_OBJECT_ITERATOR_H | |||
| #define JSON_OBJECT_ITERATOR_H | |||
| #include <stddef.h> | |||
| #ifndef JSON_EXPORT | |||
| #if defined(_MSC_VER) | |||
| #if defined(_MSC_VER) | |||
| #define JSON_EXPORT __declspec(dllexport) | |||
| #else | |||
| #define JSON_EXPORT extern | |||
| @@ -47,17 +46,16 @@ struct json_object_iter_info_; | |||
| * The opaque iterator that references a name/value pair within | |||
| * a JSON Object instance or the "end" iterator value. | |||
| */ | |||
| struct json_object_iterator { | |||
| const void* opaque_; | |||
| struct json_object_iterator | |||
| { | |||
| const void *opaque_; | |||
| }; | |||
| /** | |||
| * forward declaration of json-c's JSON value instance structure | |||
| */ | |||
| struct json_object; | |||
| /** | |||
| * Initializes an iterator structure to a "default" value that | |||
| * is convenient for initializing an iterator variable to a | |||
| @@ -80,8 +78,7 @@ struct json_object; | |||
| * | |||
| * @return json_object_iterator | |||
| */ | |||
| JSON_EXPORT struct json_object_iterator | |||
| json_object_iter_init_default(void); | |||
| JSON_EXPORT struct json_object_iterator json_object_iter_init_default(void); | |||
| /** Retrieves an iterator to the first pair of the JSON Object. | |||
| * | |||
| @@ -114,8 +111,7 @@ json_object_iter_init_default(void); | |||
| * | |||
| * @endcode | |||
| */ | |||
| JSON_EXPORT struct json_object_iterator | |||
| json_object_iter_begin(struct json_object* obj); | |||
| JSON_EXPORT struct json_object_iterator json_object_iter_begin(struct json_object *obj); | |||
| /** Retrieves the iterator that represents the position beyond the | |||
| * last pair of the given JSON Object instance. | |||
| @@ -145,8 +141,7 @@ json_object_iter_begin(struct json_object* obj); | |||
| * (i.e., NOT the last pair, but "beyond the last | |||
| * pair" value) | |||
| */ | |||
| JSON_EXPORT struct json_object_iterator | |||
| json_object_iter_end(const struct json_object* obj); | |||
| JSON_EXPORT struct json_object_iterator json_object_iter_end(const struct json_object *obj); | |||
| /** Returns an iterator to the next pair, if any | |||
| * | |||
| @@ -163,9 +158,7 @@ json_object_iter_end(const struct json_object* obj); | |||
| * of json_object_iter_end() for the same JSON Object | |||
| * instance. | |||
| */ | |||
| JSON_EXPORT void | |||
| json_object_iter_next(struct json_object_iterator* iter); | |||
| JSON_EXPORT void json_object_iter_next(struct json_object_iterator *iter); | |||
| /** Returns a const pointer to the name of the pair referenced | |||
| * by the given iterator. | |||
| @@ -182,9 +175,7 @@ json_object_iter_next(struct json_object_iterator* iter); | |||
| * deleted or modified, and MUST NOT be modified or | |||
| * freed by the user. | |||
| */ | |||
| JSON_EXPORT const char* | |||
| json_object_iter_peek_name(const struct json_object_iterator* iter); | |||
| JSON_EXPORT const char *json_object_iter_peek_name(const struct json_object_iterator *iter); | |||
| /** Returns a pointer to the json-c instance representing the | |||
| * value of the referenced name/value pair, without altering | |||
| @@ -205,9 +196,8 @@ json_object_iter_peek_name(const struct json_object_iterator* iter); | |||
| * the JSON Null value as a NULL json_object instance | |||
| * pointer. | |||
| */ | |||
| JSON_EXPORT struct json_object* | |||
| json_object_iter_peek_value(const struct json_object_iterator* iter); | |||
| JSON_EXPORT struct json_object * | |||
| json_object_iter_peek_value(const struct json_object_iterator *iter); | |||
| /** Tests two iterators for equality. Typically used to test | |||
| * for end of iteration by comparing an iterator to the | |||
| @@ -235,14 +225,11 @@ json_object_iter_peek_value(const struct json_object_iterator* iter); | |||
| * reference the same name/value pair or are both at | |||
| * "end"); zero if they are not equal. | |||
| */ | |||
| JSON_EXPORT json_bool | |||
| json_object_iter_equal(const struct json_object_iterator* iter1, | |||
| const struct json_object_iterator* iter2); | |||
| JSON_EXPORT json_bool json_object_iter_equal(const struct json_object_iterator *iter1, | |||
| const struct json_object_iterator *iter2); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* JSON_OBJECT_ITERATOR_H */ | |||
| @@ -20,48 +20,55 @@ | |||
| extern "C" { | |||
| #endif | |||
| #define LEN_DIRECT_STRING_DATA 32 /**< how many bytes are directly stored in json_object for strings? */ | |||
| /**< how many bytes are directly stored in json_object for strings? */ | |||
| #define LEN_DIRECT_STRING_DATA 32 | |||
| typedef void (json_object_private_delete_fn)(struct json_object *o); | |||
| typedef void(json_object_private_delete_fn)(struct json_object *o); | |||
| /* json object int type, support extension*/ | |||
| typedef enum json_object_int_type { | |||
| json_object_int_type_int64, | |||
| json_object_int_type_uint64 | |||
| }json_object_int_type; | |||
| typedef enum json_object_int_type | |||
| { | |||
| json_object_int_type_int64, | |||
| json_object_int_type_uint64 | |||
| } json_object_int_type; | |||
| struct json_object | |||
| { | |||
| enum json_type o_type; | |||
| uint32_t _ref_count; | |||
| json_object_private_delete_fn *_delete; | |||
| json_object_to_json_string_fn *_to_json_string; | |||
| struct printbuf *_pb; | |||
| union data { | |||
| json_bool c_boolean; | |||
| double c_double; | |||
| struct { | |||
| union { | |||
| int64_t c_int64; | |||
| uint64_t c_uint64; | |||
| } cint; | |||
| enum json_object_int_type cint_type; | |||
| } c_int; | |||
| struct lh_table *c_object; | |||
| struct array_list *c_array; | |||
| struct { | |||
| union { | |||
| /* optimize: if we have small strings, we can store them | |||
| * directly. This saves considerable CPU cycles AND memory. | |||
| */ | |||
| char *ptr; | |||
| char data[LEN_DIRECT_STRING_DATA]; | |||
| } str; | |||
| int len; | |||
| } c_string; | |||
| } o; | |||
| json_object_delete_fn *_user_delete; | |||
| void *_userdata; | |||
| enum json_type o_type; | |||
| uint32_t _ref_count; | |||
| json_object_private_delete_fn *_delete; | |||
| json_object_to_json_string_fn *_to_json_string; | |||
| struct printbuf *_pb; | |||
| union data | |||
| { | |||
| json_bool c_boolean; | |||
| double c_double; | |||
| struct | |||
| { | |||
| union | |||
| { | |||
| int64_t c_int64; | |||
| uint64_t c_uint64; | |||
| } cint; | |||
| enum json_object_int_type cint_type; | |||
| } c_int; | |||
| struct lh_table *c_object; | |||
| struct array_list *c_array; | |||
| struct | |||
| { | |||
| union | |||
| { | |||
| /* optimize: if we have small strings, we can store them | |||
| * directly. This saves considerable CPU cycles AND memory. | |||
| */ | |||
| char *ptr; | |||
| char data[LEN_DIRECT_STRING_DATA]; | |||
| } str; | |||
| int len; | |||
| } c_string; | |||
| } o; | |||
| json_object_delete_fn *_user_delete; | |||
| void *_userdata; | |||
| }; | |||
| void _json_c_set_last_err(const char *err_fmt, ...); | |||
| @@ -10,11 +10,11 @@ | |||
| #include "strerror_override.h" | |||
| #include <ctype.h> | |||
| #include <stdarg.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <ctype.h> | |||
| #include "json_pointer.h" | |||
| #include "strdup_compat.h" | |||
| @@ -30,7 +30,8 @@ static void string_replace_all_occurrences_with_char(char *s, const char *occur, | |||
| int slen = strlen(s); | |||
| int skip = strlen(occur) - 1; /* length of the occurrence, minus the char we're replacing */ | |||
| char *p = s; | |||
| while ((p = strstr(p, occur))) { | |||
| while ((p = strstr(p, occur))) | |||
| { | |||
| *p = repl_char; | |||
| p++; | |||
| slen -= skip; | |||
| @@ -41,10 +42,13 @@ static void string_replace_all_occurrences_with_char(char *s, const char *occur, | |||
| static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx) | |||
| { | |||
| int i, len = strlen(path); | |||
| /* this code-path optimizes a bit, for when we reference the 0-9 index range in a JSON array | |||
| and because leading zeros not allowed */ | |||
| if (len == 1) { | |||
| if (isdigit((unsigned char)path[0])) { | |||
| /* this code-path optimizes a bit, for when we reference the 0-9 index range | |||
| * in a JSON array and because leading zeros not allowed | |||
| */ | |||
| if (len == 1) | |||
| { | |||
| if (isdigit((unsigned char)path[0])) | |||
| { | |||
| *idx = (path[0] - '0'); | |||
| goto check_oob; | |||
| } | |||
| @@ -52,26 +56,31 @@ static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx | |||
| return 0; | |||
| } | |||
| /* leading zeros not allowed per RFC */ | |||
| if (path[0] == '0') { | |||
| if (path[0] == '0') | |||
| { | |||
| errno = EINVAL; | |||
| return 0; | |||
| } | |||
| /* RFC states base-10 decimals */ | |||
| for (i = 0; i < len; i++) { | |||
| if (!isdigit((unsigned char)path[i])) { | |||
| for (i = 0; i < len; i++) | |||
| { | |||
| if (!isdigit((unsigned char)path[i])) | |||
| { | |||
| errno = EINVAL; | |||
| return 0; | |||
| } | |||
| } | |||
| *idx = strtol(path, NULL, 10); | |||
| if (*idx < 0) { | |||
| if (*idx < 0) | |||
| { | |||
| errno = EINVAL; | |||
| return 0; | |||
| } | |||
| check_oob: | |||
| len = json_object_array_length(jo); | |||
| if (*idx >= len) { | |||
| if (*idx >= len) | |||
| { | |||
| errno = ENOENT; | |||
| return 0; | |||
| } | |||
| @@ -79,14 +88,17 @@ check_oob: | |||
| return 1; | |||
| } | |||
| static int json_pointer_get_single_path(struct json_object *obj, char *path, struct json_object **value) | |||
| static int json_pointer_get_single_path(struct json_object *obj, char *path, | |||
| struct json_object **value) | |||
| { | |||
| if (json_object_is_type(obj, json_type_array)) { | |||
| if (json_object_is_type(obj, json_type_array)) | |||
| { | |||
| int32_t idx; | |||
| if (!is_valid_index(obj, path, &idx)) | |||
| return -1; | |||
| obj = json_object_array_get_idx(obj, idx); | |||
| if (obj) { | |||
| if (obj) | |||
| { | |||
| if (value) | |||
| *value = obj; | |||
| return 0; | |||
| @@ -100,7 +112,8 @@ static int json_pointer_get_single_path(struct json_object *obj, char *path, str | |||
| string_replace_all_occurrences_with_char(path, "~1", '/'); | |||
| string_replace_all_occurrences_with_char(path, "~0", '~'); | |||
| if (!json_object_object_get_ex(obj, path, value)) { | |||
| if (!json_object_object_get_ex(obj, path, value)) | |||
| { | |||
| errno = ENOENT; | |||
| return -1; | |||
| } | |||
| @@ -108,12 +121,11 @@ static int json_pointer_get_single_path(struct json_object *obj, char *path, str | |||
| return 0; | |||
| } | |||
| static int json_pointer_set_single_path( | |||
| struct json_object *parent, | |||
| const char *path, | |||
| struct json_object *value) | |||
| static int json_pointer_set_single_path(struct json_object *parent, const char *path, | |||
| struct json_object *value) | |||
| { | |||
| if (json_object_is_type(parent, json_type_array)) { | |||
| if (json_object_is_type(parent, json_type_array)) | |||
| { | |||
| int32_t idx; | |||
| /* RFC (Chapter 4) states that '-' may be used to add new elements to an array */ | |||
| if (path[0] == '-' && path[1] == '\0') | |||
| @@ -124,26 +136,27 @@ static int json_pointer_set_single_path( | |||
| } | |||
| /* path replacements should have been done in json_pointer_get_single_path(), | |||
| and we should still be good here */ | |||
| * and we should still be good here | |||
| */ | |||
| if (json_object_is_type(parent, json_type_object)) | |||
| return json_object_object_add(parent, path, value); | |||
| /* Getting here means that we tried to "dereference" a primitive JSON type (like string, int, bool). | |||
| i.e. add a sub-object to it */ | |||
| /* Getting here means that we tried to "dereference" a primitive JSON type | |||
| * (like string, int, bool).i.e. add a sub-object to it | |||
| */ | |||
| errno = ENOENT; | |||
| return -1; | |||
| } | |||
| static int json_pointer_get_recursive( | |||
| struct json_object *obj, | |||
| char *path, | |||
| struct json_object **value) | |||
| static int json_pointer_get_recursive(struct json_object *obj, char *path, | |||
| struct json_object **value) | |||
| { | |||
| char *endp; | |||
| int rc; | |||
| /* All paths (on each recursion level must have a leading '/' */ | |||
| if (path[0] != '/') { | |||
| if (path[0] != '/') | |||
| { | |||
| errno = EINVAL; | |||
| return -1; | |||
| } | |||
| @@ -157,8 +170,10 @@ static int json_pointer_get_recursive( | |||
| if ((rc = json_pointer_get_single_path(obj, path, &obj))) | |||
| return rc; | |||
| if (endp) { | |||
| *endp = '/'; /* Put the slash back, so that the sanity check passes on next recursion level */ | |||
| if (endp) | |||
| { | |||
| /* Put the slash back, so that the sanity check passes on next recursion level */ | |||
| *endp = '/'; | |||
| return json_pointer_get_recursive(obj, endp, value); | |||
| } | |||
| @@ -174,19 +189,22 @@ int json_pointer_get(struct json_object *obj, const char *path, struct json_obje | |||
| char *path_copy = NULL; | |||
| int rc; | |||
| if (!obj || !path) { | |||
| if (!obj || !path) | |||
| { | |||
| errno = EINVAL; | |||
| return -1; | |||
| } | |||
| if (path[0] == '\0') { | |||
| if (path[0] == '\0') | |||
| { | |||
| if (res) | |||
| *res = obj; | |||
| return 0; | |||
| } | |||
| /* pass a working copy to the recursive call */ | |||
| if (!(path_copy = strdup(path))) { | |||
| if (!(path_copy = strdup(path))) | |||
| { | |||
| errno = ENOMEM; | |||
| return -1; | |||
| } | |||
| @@ -202,7 +220,8 @@ int json_pointer_getf(struct json_object *obj, struct json_object **res, const c | |||
| int rc = 0; | |||
| va_list args; | |||
| if (!obj || !path_fmt) { | |||
| if (!obj || !path_fmt) | |||
| { | |||
| errno = EINVAL; | |||
| return -1; | |||
| } | |||
| @@ -214,7 +233,8 @@ int json_pointer_getf(struct json_object *obj, struct json_object **res, const c | |||
| if (rc < 0) | |||
| return rc; | |||
| if (path_copy[0] == '\0') { | |||
| if (path_copy[0] == '\0') | |||
| { | |||
| if (res) | |||
| *res = obj; | |||
| goto out; | |||
| @@ -234,30 +254,35 @@ int json_pointer_set(struct json_object **obj, const char *path, struct json_obj | |||
| struct json_object *set = NULL; | |||
| int rc; | |||
| if (!obj || !path) { | |||
| if (!obj || !path) | |||
| { | |||
| errno = EINVAL; | |||
| return -1; | |||
| } | |||
| if (path[0] == '\0') { | |||
| if (path[0] == '\0') | |||
| { | |||
| json_object_put(*obj); | |||
| *obj = value; | |||
| return 0; | |||
| } | |||
| if (path[0] != '/') { | |||
| if (path[0] != '/') | |||
| { | |||
| errno = EINVAL; | |||
| return -1; | |||
| } | |||
| /* If there's only 1 level to set, stop here */ | |||
| if ((endp = strrchr(path, '/')) == path) { | |||
| if ((endp = strrchr(path, '/')) == path) | |||
| { | |||
| path++; | |||
| return json_pointer_set_single_path(*obj, path, value); | |||
| } | |||
| /* pass a working copy to the recursive call */ | |||
| if (!(path_copy = strdup(path))) { | |||
| if (!(path_copy = strdup(path))) | |||
| { | |||
| errno = ENOMEM; | |||
| return -1; | |||
| } | |||
| @@ -272,7 +297,8 @@ int json_pointer_set(struct json_object **obj, const char *path, struct json_obj | |||
| return json_pointer_set_single_path(set, endp, value); | |||
| } | |||
| int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, ...) | |||
| int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, | |||
| ...) | |||
| { | |||
| char *endp; | |||
| char *path_copy = NULL; | |||
| @@ -280,7 +306,8 @@ int json_pointer_setf(struct json_object **obj, struct json_object *value, const | |||
| va_list args; | |||
| int rc = 0; | |||
| if (!obj || !path_fmt) { | |||
| if (!obj || !path_fmt) | |||
| { | |||
| errno = EINVAL; | |||
| return -1; | |||
| } | |||
| @@ -293,20 +320,23 @@ int json_pointer_setf(struct json_object **obj, struct json_object *value, const | |||
| if (rc < 0) | |||
| return rc; | |||
| if (path_copy[0] == '\0') { | |||
| if (path_copy[0] == '\0') | |||
| { | |||
| json_object_put(*obj); | |||
| *obj = value; | |||
| goto out; | |||
| } | |||
| if (path_copy[0] != '/') { | |||
| if (path_copy[0] != '/') | |||
| { | |||
| errno = EINVAL; | |||
| rc = -1; | |||
| goto out; | |||
| } | |||
| /* If there's only 1 level to set, stop here */ | |||
| if ((endp = strrchr(path_copy, '/')) == path_copy) { | |||
| if ((endp = strrchr(path_copy, '/')) == path_copy) | |||
| { | |||
| set = *obj; | |||
| goto set_single_path; | |||
| } | |||
| @@ -324,4 +354,3 @@ out: | |||
| free(path_copy); | |||
| return rc; | |||
| } | |||
| @@ -44,7 +44,8 @@ extern "C" { | |||
| * | |||
| * @return negative if an error (or not found), or 0 if succeeded | |||
| */ | |||
| JSON_EXPORT int json_pointer_get(struct json_object *obj, const char *path, struct json_object **res); | |||
| JSON_EXPORT int json_pointer_get(struct json_object *obj, const char *path, | |||
| struct json_object **res); | |||
| /** | |||
| * This is a variant of 'json_pointer_get()' that supports printf() style arguments. | |||
| @@ -62,7 +63,8 @@ JSON_EXPORT int json_pointer_get(struct json_object *obj, const char *path, stru | |||
| * | |||
| * @return negative if an error (or not found), or 0 if succeeded | |||
| */ | |||
| JSON_EXPORT int json_pointer_getf(struct json_object *obj, struct json_object **res, const char *path_fmt, ...); | |||
| JSON_EXPORT int json_pointer_getf(struct json_object *obj, struct json_object **res, | |||
| const char *path_fmt, ...); | |||
| /** | |||
| * Sets JSON object 'value' in the 'obj' tree at the location specified | |||
| @@ -93,7 +95,8 @@ JSON_EXPORT int json_pointer_getf(struct json_object *obj, struct json_object ** | |||
| * | |||
| * @return negative if an error (or not found), or 0 if succeeded | |||
| */ | |||
| JSON_EXPORT int json_pointer_set(struct json_object **obj, const char *path, struct json_object *value); | |||
| JSON_EXPORT int json_pointer_set(struct json_object **obj, const char *path, | |||
| struct json_object *value); | |||
| /** | |||
| * This is a variant of 'json_pointer_set()' that supports printf() style arguments. | |||
| @@ -110,8 +113,8 @@ JSON_EXPORT int json_pointer_set(struct json_object **obj, const char *path, str | |||
| * | |||
| * @return negative if an error (or not found), or 0 if succeeded | |||
| */ | |||
| JSON_EXPORT int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, ...); | |||
| JSON_EXPORT int json_pointer_setf(struct json_object **obj, struct json_object *value, | |||
| const char *path_fmt, ...); | |||
| #ifdef __cplusplus | |||
| } | |||
| @@ -16,66 +16,68 @@ | |||
| #ifndef _json_tokener_h_ | |||
| #define _json_tokener_h_ | |||
| #include <stddef.h> | |||
| #include "json_object.h" | |||
| #include <stddef.h> | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| enum json_tokener_error { | |||
| json_tokener_success, | |||
| json_tokener_continue, | |||
| json_tokener_error_depth, | |||
| json_tokener_error_parse_eof, | |||
| json_tokener_error_parse_unexpected, | |||
| json_tokener_error_parse_null, | |||
| json_tokener_error_parse_boolean, | |||
| json_tokener_error_parse_number, | |||
| json_tokener_error_parse_array, | |||
| json_tokener_error_parse_object_key_name, | |||
| json_tokener_error_parse_object_key_sep, | |||
| json_tokener_error_parse_object_value_sep, | |||
| json_tokener_error_parse_string, | |||
| json_tokener_error_parse_comment, | |||
| json_tokener_error_parse_utf8_string, | |||
| json_tokener_error_size | |||
| enum json_tokener_error | |||
| { | |||
| json_tokener_success, | |||
| json_tokener_continue, | |||
| json_tokener_error_depth, | |||
| json_tokener_error_parse_eof, | |||
| json_tokener_error_parse_unexpected, | |||
| json_tokener_error_parse_null, | |||
| json_tokener_error_parse_boolean, | |||
| json_tokener_error_parse_number, | |||
| json_tokener_error_parse_array, | |||
| json_tokener_error_parse_object_key_name, | |||
| json_tokener_error_parse_object_key_sep, | |||
| json_tokener_error_parse_object_value_sep, | |||
| json_tokener_error_parse_string, | |||
| json_tokener_error_parse_comment, | |||
| json_tokener_error_parse_utf8_string, | |||
| json_tokener_error_size | |||
| }; | |||
| enum json_tokener_state { | |||
| json_tokener_state_eatws, | |||
| json_tokener_state_start, | |||
| json_tokener_state_finish, | |||
| json_tokener_state_null, | |||
| json_tokener_state_comment_start, | |||
| json_tokener_state_comment, | |||
| json_tokener_state_comment_eol, | |||
| json_tokener_state_comment_end, | |||
| json_tokener_state_string, | |||
| json_tokener_state_string_escape, | |||
| json_tokener_state_escape_unicode, | |||
| json_tokener_state_boolean, | |||
| json_tokener_state_number, | |||
| json_tokener_state_array, | |||
| json_tokener_state_array_add, | |||
| json_tokener_state_array_sep, | |||
| json_tokener_state_object_field_start, | |||
| json_tokener_state_object_field, | |||
| json_tokener_state_object_field_end, | |||
| json_tokener_state_object_value, | |||
| json_tokener_state_object_value_add, | |||
| json_tokener_state_object_sep, | |||
| json_tokener_state_array_after_sep, | |||
| json_tokener_state_object_field_start_after_sep, | |||
| json_tokener_state_inf | |||
| enum json_tokener_state | |||
| { | |||
| json_tokener_state_eatws, | |||
| json_tokener_state_start, | |||
| json_tokener_state_finish, | |||
| json_tokener_state_null, | |||
| json_tokener_state_comment_start, | |||
| json_tokener_state_comment, | |||
| json_tokener_state_comment_eol, | |||
| json_tokener_state_comment_end, | |||
| json_tokener_state_string, | |||
| json_tokener_state_string_escape, | |||
| json_tokener_state_escape_unicode, | |||
| json_tokener_state_boolean, | |||
| json_tokener_state_number, | |||
| json_tokener_state_array, | |||
| json_tokener_state_array_add, | |||
| json_tokener_state_array_sep, | |||
| json_tokener_state_object_field_start, | |||
| json_tokener_state_object_field, | |||
| json_tokener_state_object_field_end, | |||
| json_tokener_state_object_value, | |||
| json_tokener_state_object_value_add, | |||
| json_tokener_state_object_sep, | |||
| json_tokener_state_array_after_sep, | |||
| json_tokener_state_object_field_start_after_sep, | |||
| json_tokener_state_inf | |||
| }; | |||
| struct json_tokener_srec | |||
| { | |||
| enum json_tokener_state state, saved_state; | |||
| struct json_object *obj; | |||
| struct json_object *current; | |||
| char *obj_field_name; | |||
| enum json_tokener_state state, saved_state; | |||
| struct json_object *obj; | |||
| struct json_object *current; | |||
| char *obj_field_name; | |||
| }; | |||
| #define JSON_TOKENER_DEFAULT_DEPTH 32 | |||
| @@ -89,18 +91,18 @@ struct json_tokener_srec | |||
| */ | |||
| struct json_tokener | |||
| { | |||
| char *str; | |||
| struct printbuf *pb; | |||
| int max_depth, depth, is_double, st_pos; | |||
| /** | |||
| * See json_tokener_get_parse_end() | |||
| */ | |||
| int char_offset; | |||
| enum json_tokener_error err; | |||
| unsigned int ucs_char; | |||
| char quote_char; | |||
| struct json_tokener_srec *stack; | |||
| int flags; | |||
| char *str; | |||
| struct printbuf *pb; | |||
| int max_depth, depth, is_double, st_pos; | |||
| /** | |||
| * See json_tokener_get_parse_end() | |||
| */ | |||
| int char_offset; | |||
| enum json_tokener_error err; | |||
| unsigned int ucs_char; | |||
| char quote_char; | |||
| struct json_tokener_srec *stack; | |||
| int flags; | |||
| }; | |||
| /** | |||
| @@ -119,7 +121,6 @@ struct json_tokener | |||
| */ | |||
| JSON_EXPORT size_t json_tokener_get_parse_end(struct json_tokener *tok); | |||
| /** | |||
| * @deprecated Unused in json-c code | |||
| */ | |||
| @@ -135,7 +136,7 @@ typedef struct json_tokener json_tokener; | |||
| * | |||
| * @see json_tokener_set_flags() | |||
| */ | |||
| #define JSON_TOKENER_STRICT 0x01 | |||
| #define JSON_TOKENER_STRICT 0x01 | |||
| /** | |||
| * Allow json_tokener_parse_ex() validate utf-8 char. | |||
| @@ -146,7 +147,7 @@ typedef struct json_tokener json_tokener; | |||
| * | |||
| * @see json_tokener_set_flags() | |||
| */ | |||
| #define JSON_TOKENER_VALIDATE_UTF8 0x10 | |||
| #define JSON_TOKENER_VALIDATE_UTF8 0x10 | |||
| /** | |||
| * Given an error previously returned by json_tokener_get_error(), | |||
| @@ -167,12 +168,13 @@ JSON_EXPORT const char *json_tokener_error_desc(enum json_tokener_error jerr); | |||
| */ | |||
| JSON_EXPORT enum json_tokener_error json_tokener_get_error(struct json_tokener *tok); | |||
| JSON_EXPORT struct json_tokener* json_tokener_new(void); | |||
| JSON_EXPORT struct json_tokener* json_tokener_new_ex(int depth); | |||
| JSON_EXPORT struct json_tokener *json_tokener_new(void); | |||
| JSON_EXPORT struct json_tokener *json_tokener_new_ex(int depth); | |||
| JSON_EXPORT void json_tokener_free(struct json_tokener *tok); | |||
| JSON_EXPORT void json_tokener_reset(struct json_tokener *tok); | |||
| JSON_EXPORT struct json_object* json_tokener_parse(const char *str); | |||
| JSON_EXPORT struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error); | |||
| JSON_EXPORT struct json_object *json_tokener_parse(const char *str); | |||
| JSON_EXPORT struct json_object *json_tokener_parse_verbose(const char *str, | |||
| enum json_tokener_error *error); | |||
| /** | |||
| * validete the utf-8 string in strict model. | |||
| @@ -253,8 +255,8 @@ if (json_tokener_get_parse_end(tok) < stringlen) | |||
| * @param str an string with any valid JSON expression, or portion of. This does not need to be null terminated. | |||
| * @param len the length of str | |||
| */ | |||
| JSON_EXPORT struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||
| const char *str, int len); | |||
| JSON_EXPORT struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *str, | |||
| int len); | |||
| #ifdef __cplusplus | |||
| } | |||
| @@ -14,13 +14,13 @@ | |||
| #include "strerror_override.h" | |||
| #include <ctype.h> | |||
| #include <limits.h> | |||
| #include <stdarg.h> | |||
| #include <stddef.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <stddef.h> | |||
| #include <limits.h> | |||
| #include <string.h> | |||
| #include <ctype.h> | |||
| #ifdef HAVE_SYS_TYPES_H | |||
| #include <sys/types.h> | |||
| @@ -35,32 +35,32 @@ | |||
| #endif /* HAVE_FCNTL_H */ | |||
| #ifdef HAVE_UNISTD_H | |||
| # include <unistd.h> | |||
| #include <unistd.h> | |||
| #endif /* HAVE_UNISTD_H */ | |||
| #ifdef WIN32 | |||
| # if MSC_VER < 1800 | |||
| #if MSC_VER < 1800 | |||
| /* strtoll/strtoull is available only since Visual Studio 2013 */ | |||
| # define strtoll _strtoi64 | |||
| # define strtoull _strtoui64 | |||
| # endif | |||
| # define WIN32_LEAN_AND_MEAN | |||
| # include <windows.h> | |||
| # include <io.h> | |||
| #define strtoll _strtoi64 | |||
| #define strtoull _strtoui64 | |||
| #endif | |||
| #define WIN32_LEAN_AND_MEAN | |||
| #include <io.h> | |||
| #include <windows.h> | |||
| #endif /* defined(WIN32) */ | |||
| #if !defined(HAVE_OPEN) && defined(WIN32) | |||
| # define open _open | |||
| #define open _open | |||
| #endif | |||
| #include "snprintf_compat.h" | |||
| #include "debug.h" | |||
| #include "printbuf.h" | |||
| #include "json_inttypes.h" | |||
| #include "json_object.h" | |||
| #include "json_tokener.h" | |||
| #include "json_util.h" | |||
| #include "printbuf.h" | |||
| static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename); | |||
| @@ -82,66 +82,74 @@ void _json_c_set_last_err(const char *err_fmt, ...) | |||
| va_end(ap); | |||
| } | |||
| struct json_object* json_object_from_fd(int fd) | |||
| struct json_object *json_object_from_fd(int fd) | |||
| { | |||
| return json_object_from_fd_ex(fd, -1); | |||
| } | |||
| struct json_object* json_object_from_fd_ex(int fd, int in_depth) | |||
| struct json_object *json_object_from_fd_ex(int fd, int in_depth) | |||
| { | |||
| struct printbuf *pb; | |||
| struct json_object *obj; | |||
| char buf[JSON_FILE_BUF_SIZE]; | |||
| int ret; | |||
| struct printbuf *pb; | |||
| struct json_object *obj; | |||
| char buf[JSON_FILE_BUF_SIZE]; | |||
| int ret; | |||
| int depth = JSON_TOKENER_DEFAULT_DEPTH; | |||
| json_tokener *tok; | |||
| if(!(pb = printbuf_new())) { | |||
| _json_c_set_last_err("json_object_from_file: printbuf_new failed\n"); | |||
| return NULL; | |||
| } | |||
| if (!(pb = printbuf_new())) | |||
| { | |||
| _json_c_set_last_err("json_object_from_file: printbuf_new failed\n"); | |||
| return NULL; | |||
| } | |||
| if (in_depth != -1) | |||
| depth = in_depth; | |||
| tok = json_tokener_new_ex(depth); | |||
| if (!tok) | |||
| { | |||
| _json_c_set_last_err("json_object_from_fd: unable to allocate json_tokener(depth=%d): %s\n", depth, strerror(errno)); | |||
| _json_c_set_last_err( | |||
| "json_object_from_fd: unable to allocate json_tokener(depth=%d): %s\n", depth, | |||
| strerror(errno)); | |||
| printbuf_free(pb); | |||
| return NULL; | |||
| } | |||
| while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) { | |||
| printbuf_memappend(pb, buf, ret); | |||
| } | |||
| if(ret < 0) { | |||
| _json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd, strerror(errno)); | |||
| json_tokener_free(tok); | |||
| printbuf_free(pb); | |||
| return NULL; | |||
| } | |||
| while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) | |||
| { | |||
| printbuf_memappend(pb, buf, ret); | |||
| } | |||
| if (ret < 0) | |||
| { | |||
| _json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd, | |||
| strerror(errno)); | |||
| json_tokener_free(tok); | |||
| printbuf_free(pb); | |||
| return NULL; | |||
| } | |||
| obj = json_tokener_parse_ex(tok, pb->buf, printbuf_length(pb)); | |||
| obj = json_tokener_parse_ex(tok, pb->buf, printbuf_length(pb)); | |||
| if (obj == NULL) | |||
| _json_c_set_last_err("json_tokener_parse_ex failed: %s\n", json_tokener_error_desc(json_tokener_get_error(tok))); | |||
| _json_c_set_last_err("json_tokener_parse_ex failed: %s\n", | |||
| json_tokener_error_desc(json_tokener_get_error(tok))); | |||
| json_tokener_free(tok); | |||
| printbuf_free(pb); | |||
| return obj; | |||
| } | |||
| struct json_object* json_object_from_file(const char *filename) | |||
| struct json_object *json_object_from_file(const char *filename) | |||
| { | |||
| struct json_object *obj; | |||
| int fd; | |||
| if((fd = open(filename, O_RDONLY)) < 0) { | |||
| _json_c_set_last_err("json_object_from_file: error opening file %s: %s\n", | |||
| filename, strerror(errno)); | |||
| return NULL; | |||
| } | |||
| obj = json_object_from_fd(fd); | |||
| close(fd); | |||
| return obj; | |||
| struct json_object *obj; | |||
| int fd; | |||
| if ((fd = open(filename, O_RDONLY)) < 0) | |||
| { | |||
| _json_c_set_last_err("json_object_from_file: error opening file %s: %s\n", filename, | |||
| strerror(errno)); | |||
| return NULL; | |||
| } | |||
| obj = json_object_from_fd(fd); | |||
| close(fd); | |||
| return obj; | |||
| } | |||
| /* extended "format and write to file" function */ | |||
| @@ -151,14 +159,16 @@ int json_object_to_file_ext(const char *filename, struct json_object *obj, int f | |||
| int fd, ret; | |||
| int saved_errno; | |||
| if (!obj) { | |||
| if (!obj) | |||
| { | |||
| _json_c_set_last_err("json_object_to_file: object is null\n"); | |||
| return -1; | |||
| } | |||
| if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) { | |||
| _json_c_set_last_err("json_object_to_file: error opening file %s: %s\n", | |||
| filename, strerror(errno)); | |||
| if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) | |||
| { | |||
| _json_c_set_last_err("json_object_to_file: error opening file %s: %s\n", filename, | |||
| strerror(errno)); | |||
| return -1; | |||
| } | |||
| ret = _json_object_to_fd(fd, obj, flags, filename); | |||
| @@ -170,7 +180,8 @@ int json_object_to_file_ext(const char *filename, struct json_object *obj, int f | |||
| int json_object_to_fd(int fd, struct json_object *obj, int flags) | |||
| { | |||
| if (!obj) { | |||
| if (!obj) | |||
| { | |||
| _json_c_set_last_err("json_object_to_fd: object is null\n"); | |||
| return -1; | |||
| } | |||
| @@ -185,17 +196,21 @@ static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const | |||
| filename = filename ? filename : "(fd)"; | |||
| if (!(json_str = json_object_to_json_string_ext(obj,flags))) { | |||
| if (!(json_str = json_object_to_json_string_ext(obj, flags))) | |||
| { | |||
| return -1; | |||
| } | |||
| wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */ | |||
| /* CAW: probably unnecessary, but the most 64bit safe */ | |||
| wsize = (unsigned int)(strlen(json_str) & UINT_MAX); | |||
| wpos = 0; | |||
| while(wpos < wsize) { | |||
| if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) { | |||
| _json_c_set_last_err("json_object_to_file: error writing file %s: %s\n", | |||
| filename, strerror(errno)); | |||
| return -1; | |||
| while (wpos < wsize) | |||
| { | |||
| if ((ret = write(fd, json_str + wpos, wsize - wpos)) < 0) | |||
| { | |||
| _json_c_set_last_err("json_object_to_file: error writing file %s: %s\n", | |||
| filename, strerror(errno)); | |||
| return -1; | |||
| } | |||
| /* because of the above check for ret < 0, we can safely cast and add */ | |||
| @@ -209,14 +224,14 @@ static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const | |||
| int json_object_to_file(const char *filename, struct json_object *obj) | |||
| { | |||
| return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN); | |||
| return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN); | |||
| } | |||
| int json_parse_double(const char *buf, double *retval) | |||
| { | |||
| char *end; | |||
| *retval = strtod(buf, &end); | |||
| return end == buf ? 1 : 0; | |||
| char *end; | |||
| *retval = strtod(buf, &end); | |||
| return end == buf ? 1 : 0; | |||
| } | |||
| int json_parse_int64(const char *buf, int64_t *retval) | |||
| @@ -237,10 +252,12 @@ int json_parse_uint64(const char *buf, uint64_t *retval) | |||
| uint64_t val; | |||
| errno = 1; | |||
| while (*buf == ' ') { | |||
| while (*buf == ' ') | |||
| { | |||
| buf++; | |||
| } | |||
| if (*buf == '-') errno = 0; | |||
| if (*buf == '-') | |||
| errno = 0; | |||
| val = strtoull(buf, &end, 10); | |||
| if (end != buf) | |||
| @@ -249,7 +266,7 @@ int json_parse_uint64(const char *buf, uint64_t *retval) | |||
| } | |||
| #ifndef HAVE_REALLOC | |||
| void* rpl_realloc(void* p, size_t n) | |||
| void *rpl_realloc(void *p, size_t n) | |||
| { | |||
| if (n == 0) | |||
| n = 1; | |||
| @@ -259,24 +276,27 @@ void* rpl_realloc(void* p, size_t n) | |||
| } | |||
| #endif | |||
| #define NELEM(a) (sizeof(a) / sizeof(a[0])) | |||
| static const char* json_type_name[] = { | |||
| /* If you change this, be sure to update the enum json_type definition too */ | |||
| "null", | |||
| "boolean", | |||
| "double", | |||
| "int", | |||
| "object", | |||
| "array", | |||
| "string", | |||
| #define NELEM(a) (sizeof(a) / sizeof(a[0])) | |||
| /* clang-format off */ | |||
| static const char *json_type_name[] = { | |||
| /* If you change this, be sure to update the enum json_type definition too */ | |||
| "null", | |||
| "boolean", | |||
| "double", | |||
| "int", | |||
| "object", | |||
| "array", | |||
| "string", | |||
| }; | |||
| /* clang-format on */ | |||
| const char *json_type_to_name(enum json_type o_type) | |||
| { | |||
| int o_type_int = (int)o_type; | |||
| if (o_type_int < 0 || o_type_int >= (int)NELEM(json_type_name)) | |||
| { | |||
| _json_c_set_last_err("json_type_to_name: type %d is out of range [0,%d]\n", o_type, NELEM(json_type_name)); | |||
| _json_c_set_last_err("json_type_to_name: type %d is out of range [0,%d]\n", o_type, | |||
| NELEM(json_type_name)); | |||
| return NULL; | |||
| } | |||
| return json_type_name[o_type]; | |||
| @@ -284,8 +304,7 @@ const char *json_type_to_name(enum json_type o_type) | |||
| void json_abort(const char *message) | |||
| { | |||
| if (message != NULL) | |||
| fprintf (stderr, "json-c aborts with error: %s\n", message); | |||
| abort(); | |||
| if (message != NULL) | |||
| fprintf(stderr, "json-c aborts with error: %s\n", message); | |||
| abort(); | |||
| } | |||
| @@ -12,21 +12,20 @@ | |||
| /** | |||
| * @file | |||
| * @brief Miscllaneous utility functions and macros. | |||
| */ | |||
| */ | |||
| #ifndef _json_util_h_ | |||
| #define _json_util_h_ | |||
| #include "json_object.h" | |||
| #ifndef json_min | |||
| #define json_min(a,b) ((a) < (b) ? (a) : (b)) | |||
| #define json_min(a, b) ((a) < (b) ? (a) : (b)) | |||
| #endif | |||
| #ifndef json_max | |||
| #define json_max(a,b) ((a) > (b) ? (a) : (b)) | |||
| #define json_max(a, b) ((a) > (b) ? (a) : (b)) | |||
| #endif | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| @@ -40,7 +39,7 @@ extern "C" { | |||
| * | |||
| * Returns NULL on failure. See json_util_get_last_err() for details. | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_from_file(const char *filename); | |||
| JSON_EXPORT struct json_object *json_object_from_file(const char *filename); | |||
| /** | |||
| * Create a JSON object from already opened file descriptor. | |||
| @@ -56,7 +55,7 @@ JSON_EXPORT struct json_object* json_object_from_file(const char *filename); | |||
| * | |||
| * Returns NULL on failure. See json_util_get_last_err() for details. | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_from_fd_ex(int fd, int depth); | |||
| JSON_EXPORT struct json_object *json_object_from_fd_ex(int fd, int depth); | |||
| /** | |||
| * Create a JSON object from an already opened file descriptor, using | |||
| @@ -64,7 +63,7 @@ JSON_EXPORT struct json_object* json_object_from_fd_ex(int fd, int depth); | |||
| * | |||
| * See json_object_from_fd_ex() for details. | |||
| */ | |||
| JSON_EXPORT struct json_object* json_object_from_fd(int fd); | |||
| JSON_EXPORT struct json_object *json_object_from_fd(int fd); | |||
| /** | |||
| * Equivalent to: | |||
| @@ -101,7 +100,6 @@ JSON_EXPORT int json_object_to_fd(int fd, struct json_object *obj, int flags); | |||
| */ | |||
| JSON_EXPORT const char *json_util_get_last_err(void); | |||
| JSON_EXPORT int json_parse_int64(const char *buf, int64_t *retval); | |||
| JSON_EXPORT int json_parse_uint64(const char *buf, uint64_t *retval); | |||
| JSON_EXPORT int json_parse_double(const char *buf, double *retval); | |||
| @@ -119,7 +117,7 @@ JSON_EXPORT const char *json_type_to_name(enum json_type o_type); | |||
| /* 'cold' attribute is for optimization, telling the computer this code | |||
| * path is unlikely. | |||
| */ | |||
| #define JSON_NORETURN __attribute__ ((noreturn, cold)) | |||
| #define JSON_NORETURN __attribute__((noreturn, cold)) | |||
| #endif | |||
| #endif | |||
| /** | |||
| @@ -13,45 +13,39 @@ | |||
| #include "json_visit.h" | |||
| #include "linkhash.h" | |||
| static int _json_c_visit(json_object *jso, json_object *parent_jso, | |||
| const char *jso_key, size_t *jso_index, | |||
| json_c_visit_userfunc *userfunc, void *userarg); | |||
| static int _json_c_visit(json_object *jso, json_object *parent_jso, const char *jso_key, | |||
| size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg); | |||
| int json_c_visit(json_object *jso, int future_flags, | |||
| json_c_visit_userfunc *userfunc, void *userarg) | |||
| int json_c_visit(json_object *jso, int future_flags, json_c_visit_userfunc *userfunc, void *userarg) | |||
| { | |||
| int ret = _json_c_visit(jso, NULL, NULL, NULL, userfunc, userarg); | |||
| switch(ret) | |||
| switch (ret) | |||
| { | |||
| case JSON_C_VISIT_RETURN_CONTINUE: | |||
| case JSON_C_VISIT_RETURN_SKIP: | |||
| case JSON_C_VISIT_RETURN_POP: | |||
| case JSON_C_VISIT_RETURN_STOP: | |||
| return 0; | |||
| default: | |||
| return JSON_C_VISIT_RETURN_ERROR; | |||
| case JSON_C_VISIT_RETURN_STOP: return 0; | |||
| default: return JSON_C_VISIT_RETURN_ERROR; | |||
| } | |||
| } | |||
| static int _json_c_visit(json_object *jso, json_object *parent_jso, | |||
| const char *jso_key, size_t *jso_index, | |||
| json_c_visit_userfunc *userfunc, void *userarg) | |||
| static int _json_c_visit(json_object *jso, json_object *parent_jso, const char *jso_key, | |||
| size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg) | |||
| { | |||
| int userret = userfunc(jso, 0, parent_jso, jso_key, jso_index, userarg); | |||
| switch(userret) | |||
| switch (userret) | |||
| { | |||
| case JSON_C_VISIT_RETURN_CONTINUE: | |||
| break; | |||
| case JSON_C_VISIT_RETURN_CONTINUE: break; | |||
| case JSON_C_VISIT_RETURN_SKIP: | |||
| case JSON_C_VISIT_RETURN_POP: | |||
| case JSON_C_VISIT_RETURN_STOP: | |||
| case JSON_C_VISIT_RETURN_ERROR: | |||
| return userret; | |||
| case JSON_C_VISIT_RETURN_ERROR: return userret; | |||
| default: | |||
| fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", userret); | |||
| fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", | |||
| userret); | |||
| return JSON_C_VISIT_RETURN_ERROR; | |||
| } | |||
| switch(json_object_get_type(jso)) | |||
| switch (json_object_get_type(jso)) | |||
| { | |||
| case json_type_null: | |||
| case json_type_boolean: | |||
| @@ -69,12 +63,13 @@ static int _json_c_visit(json_object *jso, json_object *parent_jso, | |||
| if (userret == JSON_C_VISIT_RETURN_POP) | |||
| break; | |||
| if (userret == JSON_C_VISIT_RETURN_STOP || | |||
| userret == JSON_C_VISIT_RETURN_ERROR) | |||
| userret == JSON_C_VISIT_RETURN_ERROR) | |||
| return userret; | |||
| if (userret != JSON_C_VISIT_RETURN_CONTINUE && | |||
| userret != JSON_C_VISIT_RETURN_SKIP) | |||
| userret != JSON_C_VISIT_RETURN_SKIP) | |||
| { | |||
| fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", userret); | |||
| fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", | |||
| userret); | |||
| return JSON_C_VISIT_RETURN_ERROR; | |||
| } | |||
| } | |||
| @@ -91,19 +86,21 @@ static int _json_c_visit(json_object *jso, json_object *parent_jso, | |||
| if (userret == JSON_C_VISIT_RETURN_POP) | |||
| break; | |||
| if (userret == JSON_C_VISIT_RETURN_STOP || | |||
| userret == JSON_C_VISIT_RETURN_ERROR) | |||
| userret == JSON_C_VISIT_RETURN_ERROR) | |||
| return userret; | |||
| if (userret != JSON_C_VISIT_RETURN_CONTINUE && | |||
| userret != JSON_C_VISIT_RETURN_SKIP) | |||
| userret != JSON_C_VISIT_RETURN_SKIP) | |||
| { | |||
| fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", userret); | |||
| fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", | |||
| userret); | |||
| return JSON_C_VISIT_RETURN_ERROR; | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| default: | |||
| fprintf(stderr, "INTERNAL ERROR: _json_c_visit found object of unknown type: %d\n", json_object_get_type(jso)); | |||
| fprintf(stderr, "INTERNAL ERROR: _json_c_visit found object of unknown type: %d\n", | |||
| json_object_get_type(jso)); | |||
| return JSON_C_VISIT_RETURN_ERROR; | |||
| } | |||
| @@ -112,22 +109,20 @@ static int _json_c_visit(json_object *jso, json_object *parent_jso, | |||
| // Non-container types will have already returned before this point. | |||
| userret = userfunc(jso, JSON_C_VISIT_SECOND, parent_jso, jso_key, jso_index, userarg); | |||
| switch(userret) | |||
| switch (userret) | |||
| { | |||
| case JSON_C_VISIT_RETURN_SKIP: | |||
| case JSON_C_VISIT_RETURN_POP: | |||
| // These are not really sensible during JSON_C_VISIT_SECOND, | |||
| // These are not really sensible during JSON_C_VISIT_SECOND, | |||
| // but map them to JSON_C_VISIT_CONTINUE anyway. | |||
| // FALLTHROUGH | |||
| case JSON_C_VISIT_RETURN_CONTINUE: | |||
| return JSON_C_VISIT_RETURN_CONTINUE; | |||
| case JSON_C_VISIT_RETURN_CONTINUE: return JSON_C_VISIT_RETURN_CONTINUE; | |||
| case JSON_C_VISIT_RETURN_STOP: | |||
| case JSON_C_VISIT_RETURN_ERROR: | |||
| return userret; | |||
| case JSON_C_VISIT_RETURN_ERROR: return userret; | |||
| default: | |||
| fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", userret); | |||
| fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", | |||
| userret); | |||
| return JSON_C_VISIT_RETURN_ERROR; | |||
| } | |||
| // NOTREACHED | |||
| } | |||
| @@ -8,9 +8,8 @@ | |||
| */ | |||
| #include "json_object.h" | |||
| typedef int (json_c_visit_userfunc)(json_object *jso, int flags, | |||
| json_object *parent_jso, const char *jso_key, | |||
| size_t *jso_index, void *userarg); | |||
| typedef int(json_c_visit_userfunc)(json_object *jso, int flags, json_object *parent_jso, | |||
| const char *jso_key, size_t *jso_index, void *userarg); | |||
| /** | |||
| * Visit each object in the JSON hierarchy starting at jso. | |||
| @@ -31,15 +30,15 @@ typedef int (json_c_visit_userfunc)(json_object *jso, int flags, | |||
| * Returns <0 if an error occurred during iteration, including if | |||
| * userfunc returned JSON_C_VISIT_RETURN_ERROR. | |||
| */ | |||
| JSON_EXPORT int json_c_visit(json_object *jso, int future_flags, | |||
| json_c_visit_userfunc *userfunc, void *userarg); | |||
| JSON_EXPORT int json_c_visit(json_object *jso, int future_flags, json_c_visit_userfunc *userfunc, | |||
| void *userarg); | |||
| /** | |||
| * Passed to json_c_visit_userfunc as one of the flags values to indicate | |||
| * that this is the second time a container (array or object) is being | |||
| * called, after all of it's members have been iterated over. | |||
| */ | |||
| #define JSON_C_VISIT_SECOND 0x02 | |||
| #define JSON_C_VISIT_SECOND 0x02 | |||
| /** | |||
| * This json_c_visit_userfunc return value indicates that iteration | |||
| @@ -47,7 +46,6 @@ JSON_EXPORT int json_c_visit(json_object *jso, int future_flags, | |||
| */ | |||
| #define JSON_C_VISIT_RETURN_CONTINUE 0 | |||
| /** | |||
| * This json_c_visit_userfunc return value indicates that iteration | |||
| * over the members of the current object should be skipped. | |||
| @@ -7,13 +7,13 @@ | |||
| #ifndef __warn_references | |||
| #if defined(__GNUC__) && defined (HAS_GNU_WARNING_LONG) | |||
| #if defined(__GNUC__) && defined(HAS_GNU_WARNING_LONG) | |||
| #define __warn_references(sym,msg) \ | |||
| __asm__(".section .gnu" #sym ",\n\t.ascii \"" msg "\"\n\t.text"); | |||
| #define __warn_references(sym, msg) \ | |||
| __asm__(".section .gnu" #sym ",\n\t.ascii \"" msg "\"\n\t.text"); | |||
| #else | |||
| #define __warn_references(sym,msg) /* nothing */ | |||
| #define __warn_references(sym, msg) /* nothing */ | |||
| #endif | |||
| #endif | |||
| @@ -12,24 +12,24 @@ | |||
| #include "config.h" | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <stdlib.h> | |||
| #include <limits.h> | |||
| #include <stdarg.h> | |||
| #include <stddef.h> | |||
| #include <limits.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #ifdef HAVE_ENDIAN_H | |||
| # include <endian.h> /* attempt to define endianness */ | |||
| #include <endian.h> /* attempt to define endianness */ | |||
| #endif | |||
| #if defined(_MSC_VER) || defined(__MINGW32__) | |||
| # define WIN32_LEAN_AND_MEAN | |||
| # include <windows.h> /* Get InterlockedCompareExchange */ | |||
| #define WIN32_LEAN_AND_MEAN | |||
| #include <windows.h> /* Get InterlockedCompareExchange */ | |||
| #endif | |||
| #include "random_seed.h" | |||
| #include "linkhash.h" | |||
| #include "random_seed.h" | |||
| /* hash functions */ | |||
| static unsigned long lh_char_hash(const void *k); | |||
| @@ -40,18 +40,13 @@ static lh_hash_fn *char_hash_fn = lh_char_hash; | |||
| int lh_char_equal(const void *k1, const void *k2); | |||
| int lh_ptr_equal(const void *k1, const void *k2); | |||
| int | |||
| json_global_set_string_hash(const int h) | |||
| int json_global_set_string_hash(const int h) | |||
| { | |||
| switch(h) { | |||
| case JSON_C_STR_HASH_DFLT: | |||
| char_hash_fn = lh_char_hash; | |||
| break; | |||
| case JSON_C_STR_HASH_PERLLIKE: | |||
| char_hash_fn = lh_perllike_str_hash; | |||
| break; | |||
| default: | |||
| return -1; | |||
| switch (h) | |||
| { | |||
| case JSON_C_STR_HASH_DFLT: char_hash_fn = lh_char_hash; break; | |||
| case JSON_C_STR_HASH_PERLLIKE: char_hash_fn = lh_perllike_str_hash; break; | |||
| default: return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| @@ -114,25 +109,23 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy. | |||
| * My best guess at if you are big-endian or little-endian. This may | |||
| * need adjustment. | |||
| */ | |||
| #if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ | |||
| __BYTE_ORDER == __LITTLE_ENDIAN) || \ | |||
| (defined(i386) || defined(__i386__) || defined(__i486__) || \ | |||
| defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) | |||
| # define HASH_LITTLE_ENDIAN 1 | |||
| # define HASH_BIG_ENDIAN 0 | |||
| #elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ | |||
| __BYTE_ORDER == __BIG_ENDIAN) || \ | |||
| (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) | |||
| # define HASH_LITTLE_ENDIAN 0 | |||
| # define HASH_BIG_ENDIAN 1 | |||
| #if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ | |||
| (defined(i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || \ | |||
| defined(__i686__) || defined(vax) || defined(MIPSEL)) | |||
| #define HASH_LITTLE_ENDIAN 1 | |||
| #define HASH_BIG_ENDIAN 0 | |||
| #elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \ | |||
| (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) | |||
| #define HASH_LITTLE_ENDIAN 0 | |||
| #define HASH_BIG_ENDIAN 1 | |||
| #else | |||
| # define HASH_LITTLE_ENDIAN 0 | |||
| # define HASH_BIG_ENDIAN 0 | |||
| #define HASH_LITTLE_ENDIAN 0 | |||
| #define HASH_BIG_ENDIAN 0 | |||
| #endif | |||
| #define hashsize(n) ((uint32_t)1<<(n)) | |||
| #define hashmask(n) (hashsize(n)-1) | |||
| #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) | |||
| #define hashsize(n) ((uint32_t)1 << (n)) | |||
| #define hashmask(n) (hashsize(n) - 1) | |||
| #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) | |||
| /* | |||
| ------------------------------------------------------------------------------- | |||
| @@ -178,15 +171,17 @@ on, and rotates are much kinder to the top and bottom bits, so I used | |||
| rotates. | |||
| ------------------------------------------------------------------------------- | |||
| */ | |||
| /* clang-format off */ | |||
| #define mix(a,b,c) \ | |||
| { \ | |||
| a -= c; a ^= rot(c, 4); c += b; \ | |||
| b -= a; b ^= rot(a, 6); a += c; \ | |||
| c -= b; c ^= rot(b, 8); b += a; \ | |||
| a -= c; a ^= rot(c,16); c += b; \ | |||
| b -= a; b ^= rot(a,19); a += c; \ | |||
| c -= b; c ^= rot(b, 4); b += a; \ | |||
| a -= c; a ^= rot(c, 4); c += b; \ | |||
| b -= a; b ^= rot(a, 6); a += c; \ | |||
| c -= b; c ^= rot(b, 8); b += a; \ | |||
| a -= c; a ^= rot(c,16); c += b; \ | |||
| b -= a; b ^= rot(a,19); a += c; \ | |||
| c -= b; c ^= rot(b, 4); b += a; \ | |||
| } | |||
| /* clang-format on */ | |||
| /* | |||
| ------------------------------------------------------------------------------- | |||
| @@ -213,17 +208,18 @@ and these came close: | |||
| 11 8 15 26 3 22 24 | |||
| ------------------------------------------------------------------------------- | |||
| */ | |||
| /* clang-format off */ | |||
| #define final(a,b,c) \ | |||
| { \ | |||
| c ^= b; c -= rot(b,14); \ | |||
| a ^= c; a -= rot(c,11); \ | |||
| b ^= a; b -= rot(a,25); \ | |||
| c ^= b; c -= rot(b,16); \ | |||
| a ^= c; a -= rot(c,4); \ | |||
| b ^= a; b -= rot(a,14); \ | |||
| c ^= b; c -= rot(b,24); \ | |||
| c ^= b; c -= rot(b,14); \ | |||
| a ^= c; a -= rot(c,11); \ | |||
| b ^= a; b -= rot(a,25); \ | |||
| c ^= b; c -= rot(b,16); \ | |||
| a ^= c; a -= rot(c,4); \ | |||
| b ^= a; b -= rot(a,14); \ | |||
| c ^= b; c -= rot(b,24); \ | |||
| } | |||
| /* clang-format on */ | |||
| /* | |||
| ------------------------------------------------------------------------------- | |||
| @@ -252,197 +248,208 @@ acceptable. Do NOT use for cryptographic purposes. | |||
| ------------------------------------------------------------------------------- | |||
| */ | |||
| static uint32_t hashlittle( const void *key, size_t length, uint32_t initval) | |||
| /* clang-format off */ | |||
| static uint32_t hashlittle(const void *key, size_t length, uint32_t initval) | |||
| { | |||
| uint32_t a,b,c; /* internal state */ | |||
| union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ | |||
| /* Set up the internal state */ | |||
| a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; | |||
| u.ptr = key; | |||
| if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { | |||
| const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ | |||
| /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ | |||
| while (length > 12) | |||
| { | |||
| a += k[0]; | |||
| b += k[1]; | |||
| c += k[2]; | |||
| mix(a,b,c); | |||
| length -= 12; | |||
| k += 3; | |||
| } | |||
| /*----------------------------- handle the last (probably partial) block */ | |||
| /* | |||
| * "k[2]&0xffffff" actually reads beyond the end of the string, but | |||
| * then masks off the part it's not allowed to read. Because the | |||
| * string is aligned, the masked-off tail is in the same word as the | |||
| * rest of the string. Every machine with memory protection I've seen | |||
| * does it on word boundaries, so is OK with this. But VALGRIND will | |||
| * still catch it and complain. The masking trick does make the hash | |||
| * noticably faster for short strings (like English words). | |||
| * AddressSanitizer is similarly picky about overrunning | |||
| * the buffer. (http://clang.llvm.org/docs/AddressSanitizer.html | |||
| */ | |||
| uint32_t a,b,c; /* internal state */ | |||
| union | |||
| { | |||
| const void *ptr; | |||
| size_t i; | |||
| } u; /* needed for Mac Powerbook G4 */ | |||
| /* Set up the internal state */ | |||
| a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; | |||
| u.ptr = key; | |||
| if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { | |||
| const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ | |||
| /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ | |||
| while (length > 12) | |||
| { | |||
| a += k[0]; | |||
| b += k[1]; | |||
| c += k[2]; | |||
| mix(a,b,c); | |||
| length -= 12; | |||
| k += 3; | |||
| } | |||
| /*----------------------------- handle the last (probably partial) block */ | |||
| /* | |||
| * "k[2]&0xffffff" actually reads beyond the end of the string, but | |||
| * then masks off the part it's not allowed to read. Because the | |||
| * string is aligned, the masked-off tail is in the same word as the | |||
| * rest of the string. Every machine with memory protection I've seen | |||
| * does it on word boundaries, so is OK with this. But VALGRIND will | |||
| * still catch it and complain. The masking trick does make the hash | |||
| * noticably faster for short strings (like English words). | |||
| * AddressSanitizer is similarly picky about overrunning | |||
| * the buffer. (http://clang.llvm.org/docs/AddressSanitizer.html | |||
| */ | |||
| #ifdef VALGRIND | |||
| # define PRECISE_MEMORY_ACCESS 1 | |||
| #define PRECISE_MEMORY_ACCESS 1 | |||
| #elif defined(__SANITIZE_ADDRESS__) /* GCC's ASAN */ | |||
| # define PRECISE_MEMORY_ACCESS 1 | |||
| #define PRECISE_MEMORY_ACCESS 1 | |||
| #elif defined(__has_feature) | |||
| # if __has_feature(address_sanitizer) /* Clang's ASAN */ | |||
| # define PRECISE_MEMORY_ACCESS 1 | |||
| # endif | |||
| #if __has_feature(address_sanitizer) /* Clang's ASAN */ | |||
| #define PRECISE_MEMORY_ACCESS 1 | |||
| #endif | |||
| #endif | |||
| #ifndef PRECISE_MEMORY_ACCESS | |||
| switch(length) | |||
| { | |||
| case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; | |||
| case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; | |||
| case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; | |||
| case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; | |||
| case 8 : b+=k[1]; a+=k[0]; break; | |||
| case 7 : b+=k[1]&0xffffff; a+=k[0]; break; | |||
| case 6 : b+=k[1]&0xffff; a+=k[0]; break; | |||
| case 5 : b+=k[1]&0xff; a+=k[0]; break; | |||
| case 4 : a+=k[0]; break; | |||
| case 3 : a+=k[0]&0xffffff; break; | |||
| case 2 : a+=k[0]&0xffff; break; | |||
| case 1 : a+=k[0]&0xff; break; | |||
| case 0 : return c; /* zero length strings require no mixing */ | |||
| } | |||
| switch(length) | |||
| { | |||
| case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; | |||
| case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; | |||
| case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; | |||
| case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; | |||
| case 8 : b+=k[1]; a+=k[0]; break; | |||
| case 7 : b+=k[1]&0xffffff; a+=k[0]; break; | |||
| case 6 : b+=k[1]&0xffff; a+=k[0]; break; | |||
| case 5 : b+=k[1]&0xff; a+=k[0]; break; | |||
| case 4 : a+=k[0]; break; | |||
| case 3 : a+=k[0]&0xffffff; break; | |||
| case 2 : a+=k[0]&0xffff; break; | |||
| case 1 : a+=k[0]&0xff; break; | |||
| case 0 : return c; /* zero length strings require no mixing */ | |||
| } | |||
| #else /* make valgrind happy */ | |||
| const uint8_t *k8 = (const uint8_t *)k; | |||
| switch(length) | |||
| { | |||
| case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; | |||
| case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ | |||
| case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ | |||
| case 9 : c+=k8[8]; /* fall through */ | |||
| case 8 : b+=k[1]; a+=k[0]; break; | |||
| case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ | |||
| case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ | |||
| case 5 : b+=k8[4]; /* fall through */ | |||
| case 4 : a+=k[0]; break; | |||
| case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ | |||
| case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ | |||
| case 1 : a+=k8[0]; break; | |||
| case 0 : return c; | |||
| } | |||
| const uint8_t *k8 = (const uint8_t *)k; | |||
| switch(length) | |||
| { | |||
| case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; | |||
| case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ | |||
| case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ | |||
| case 9 : c+=k8[8]; /* fall through */ | |||
| case 8 : b+=k[1]; a+=k[0]; break; | |||
| case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ | |||
| case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ | |||
| case 5 : b+=k8[4]; /* fall through */ | |||
| case 4 : a+=k[0]; break; | |||
| case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ | |||
| case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ | |||
| case 1 : a+=k8[0]; break; | |||
| case 0 : return c; | |||
| } | |||
| #endif /* !valgrind */ | |||
| } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { | |||
| const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ | |||
| const uint8_t *k8; | |||
| /*--------------- all but last block: aligned reads and different mixing */ | |||
| while (length > 12) | |||
| { | |||
| a += k[0] + (((uint32_t)k[1])<<16); | |||
| b += k[2] + (((uint32_t)k[3])<<16); | |||
| c += k[4] + (((uint32_t)k[5])<<16); | |||
| mix(a,b,c); | |||
| length -= 12; | |||
| k += 6; | |||
| } | |||
| /*----------------------------- handle the last (probably partial) block */ | |||
| k8 = (const uint8_t *)k; | |||
| switch(length) | |||
| { | |||
| case 12: c+=k[4]+(((uint32_t)k[5])<<16); | |||
| b+=k[2]+(((uint32_t)k[3])<<16); | |||
| a+=k[0]+(((uint32_t)k[1])<<16); | |||
| break; | |||
| case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ | |||
| case 10: c+=k[4]; | |||
| b+=k[2]+(((uint32_t)k[3])<<16); | |||
| a+=k[0]+(((uint32_t)k[1])<<16); | |||
| break; | |||
| case 9 : c+=k8[8]; /* fall through */ | |||
| case 8 : b+=k[2]+(((uint32_t)k[3])<<16); | |||
| a+=k[0]+(((uint32_t)k[1])<<16); | |||
| break; | |||
| case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ | |||
| case 6 : b+=k[2]; | |||
| a+=k[0]+(((uint32_t)k[1])<<16); | |||
| break; | |||
| case 5 : b+=k8[4]; /* fall through */ | |||
| case 4 : a+=k[0]+(((uint32_t)k[1])<<16); | |||
| break; | |||
| case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ | |||
| case 2 : a+=k[0]; | |||
| break; | |||
| case 1 : a+=k8[0]; | |||
| break; | |||
| case 0 : return c; /* zero length requires no mixing */ | |||
| } | |||
| } else { /* need to read the key one byte at a time */ | |||
| const uint8_t *k = (const uint8_t *)key; | |||
| /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ | |||
| while (length > 12) | |||
| { | |||
| a += k[0]; | |||
| a += ((uint32_t)k[1])<<8; | |||
| a += ((uint32_t)k[2])<<16; | |||
| a += ((uint32_t)k[3])<<24; | |||
| b += k[4]; | |||
| b += ((uint32_t)k[5])<<8; | |||
| b += ((uint32_t)k[6])<<16; | |||
| b += ((uint32_t)k[7])<<24; | |||
| c += k[8]; | |||
| c += ((uint32_t)k[9])<<8; | |||
| c += ((uint32_t)k[10])<<16; | |||
| c += ((uint32_t)k[11])<<24; | |||
| mix(a,b,c); | |||
| length -= 12; | |||
| k += 12; | |||
| } | |||
| /*-------------------------------- last block: affect all 32 bits of (c) */ | |||
| switch(length) /* all the case statements fall through */ | |||
| { | |||
| case 12: c+=((uint32_t)k[11])<<24; /* FALLTHRU */ | |||
| case 11: c+=((uint32_t)k[10])<<16; /* FALLTHRU */ | |||
| case 10: c+=((uint32_t)k[9])<<8; /* FALLTHRU */ | |||
| case 9 : c+=k[8]; /* FALLTHRU */ | |||
| case 8 : b+=((uint32_t)k[7])<<24; /* FALLTHRU */ | |||
| case 7 : b+=((uint32_t)k[6])<<16; /* FALLTHRU */ | |||
| case 6 : b+=((uint32_t)k[5])<<8; /* FALLTHRU */ | |||
| case 5 : b+=k[4]; /* FALLTHRU */ | |||
| case 4 : a+=((uint32_t)k[3])<<24; /* FALLTHRU */ | |||
| case 3 : a+=((uint32_t)k[2])<<16; /* FALLTHRU */ | |||
| case 2 : a+=((uint32_t)k[1])<<8; /* FALLTHRU */ | |||
| case 1 : a+=k[0]; | |||
| break; | |||
| case 0 : return c; | |||
| } | |||
| } | |||
| } | |||
| else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) | |||
| { | |||
| const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ | |||
| const uint8_t *k8; | |||
| final(a,b,c); | |||
| return c; | |||
| /*--------------- all but last block: aligned reads and different mixing */ | |||
| while (length > 12) | |||
| { | |||
| a += k[0] + (((uint32_t)k[1])<<16); | |||
| b += k[2] + (((uint32_t)k[3])<<16); | |||
| c += k[4] + (((uint32_t)k[5])<<16); | |||
| mix(a,b,c); | |||
| length -= 12; | |||
| k += 6; | |||
| } | |||
| /*----------------------------- handle the last (probably partial) block */ | |||
| k8 = (const uint8_t *)k; | |||
| switch(length) | |||
| { | |||
| case 12: c+=k[4]+(((uint32_t)k[5])<<16); | |||
| b+=k[2]+(((uint32_t)k[3])<<16); | |||
| a+=k[0]+(((uint32_t)k[1])<<16); | |||
| break; | |||
| case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ | |||
| case 10: c+=k[4]; | |||
| b+=k[2]+(((uint32_t)k[3])<<16); | |||
| a+=k[0]+(((uint32_t)k[1])<<16); | |||
| break; | |||
| case 9 : c+=k8[8]; /* fall through */ | |||
| case 8 : b+=k[2]+(((uint32_t)k[3])<<16); | |||
| a+=k[0]+(((uint32_t)k[1])<<16); | |||
| break; | |||
| case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ | |||
| case 6 : b+=k[2]; | |||
| a+=k[0]+(((uint32_t)k[1])<<16); | |||
| break; | |||
| case 5 : b+=k8[4]; /* fall through */ | |||
| case 4 : a+=k[0]+(((uint32_t)k[1])<<16); | |||
| break; | |||
| case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ | |||
| case 2 : a+=k[0]; | |||
| break; | |||
| case 1 : a+=k8[0]; | |||
| break; | |||
| case 0 : return c; /* zero length requires no mixing */ | |||
| } | |||
| } | |||
| else | |||
| { | |||
| /* need to read the key one byte at a time */ | |||
| const uint8_t *k = (const uint8_t *)key; | |||
| /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ | |||
| while (length > 12) | |||
| { | |||
| a += k[0]; | |||
| a += ((uint32_t)k[1])<<8; | |||
| a += ((uint32_t)k[2])<<16; | |||
| a += ((uint32_t)k[3])<<24; | |||
| b += k[4]; | |||
| b += ((uint32_t)k[5])<<8; | |||
| b += ((uint32_t)k[6])<<16; | |||
| b += ((uint32_t)k[7])<<24; | |||
| c += k[8]; | |||
| c += ((uint32_t)k[9])<<8; | |||
| c += ((uint32_t)k[10])<<16; | |||
| c += ((uint32_t)k[11])<<24; | |||
| mix(a,b,c); | |||
| length -= 12; | |||
| k += 12; | |||
| } | |||
| /*-------------------------------- last block: affect all 32 bits of (c) */ | |||
| switch(length) /* all the case statements fall through */ | |||
| { | |||
| case 12: c+=((uint32_t)k[11])<<24; /* FALLTHRU */ | |||
| case 11: c+=((uint32_t)k[10])<<16; /* FALLTHRU */ | |||
| case 10: c+=((uint32_t)k[9])<<8; /* FALLTHRU */ | |||
| case 9 : c+=k[8]; /* FALLTHRU */ | |||
| case 8 : b+=((uint32_t)k[7])<<24; /* FALLTHRU */ | |||
| case 7 : b+=((uint32_t)k[6])<<16; /* FALLTHRU */ | |||
| case 6 : b+=((uint32_t)k[5])<<8; /* FALLTHRU */ | |||
| case 5 : b+=k[4]; /* FALLTHRU */ | |||
| case 4 : a+=((uint32_t)k[3])<<24; /* FALLTHRU */ | |||
| case 3 : a+=((uint32_t)k[2])<<16; /* FALLTHRU */ | |||
| case 2 : a+=((uint32_t)k[1])<<8; /* FALLTHRU */ | |||
| case 1 : a+=k[0]; | |||
| break; | |||
| case 0 : return c; | |||
| } | |||
| } | |||
| final(a,b,c); | |||
| return c; | |||
| } | |||
| /* clang-format on */ | |||
| /* a simple hash function similiar to what perl does for strings. | |||
| * for good results, the string should not be excessivly large. | |||
| */ | |||
| static unsigned long lh_perllike_str_hash(const void *k) | |||
| static unsigned long lh_perllike_str_hash(const void *k) | |||
| { | |||
| const char *rkey = (const char *)k; | |||
| unsigned hashval = 1; | |||
| const char *rkey = (const char *)k; | |||
| unsigned hashval = 1; | |||
| while (*rkey) | |||
| hashval = hashval * 33 + *rkey++; | |||
| while (*rkey) | |||
| hashval = hashval * 33 + *rkey++; | |||
| return hashval; | |||
| return hashval; | |||
| } | |||
| static unsigned long lh_char_hash(const void *k) | |||
| @@ -454,10 +461,11 @@ static unsigned long lh_char_hash(const void *k) | |||
| #endif | |||
| static volatile RANDOM_SEED_TYPE random_seed = -1; | |||
| if (random_seed == -1) { | |||
| if (random_seed == -1) | |||
| { | |||
| RANDOM_SEED_TYPE seed; | |||
| /* we can't use -1 as it is the unitialized sentinel */ | |||
| while ((seed = json_c_get_random_seed()) == -1); | |||
| while ((seed = json_c_get_random_seed()) == -1) {} | |||
| #if SIZEOF_INT == 8 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 | |||
| #define USE_SYNC_COMPARE_AND_SWAP 1 | |||
| #endif | |||
| @@ -472,34 +480,32 @@ static unsigned long lh_char_hash(const void *k) | |||
| #elif defined _MSC_VER || defined __MINGW32__ | |||
| InterlockedCompareExchange(&random_seed, seed, -1); | |||
| #else | |||
| //#warning "racy random seed initializtion if used by multiple threads" | |||
| //#warning "racy random seed initializtion if used by multiple threads" | |||
| random_seed = seed; /* potentially racy */ | |||
| #endif | |||
| } | |||
| return hashlittle((const char*)k, strlen((const char*)k), random_seed); | |||
| return hashlittle((const char *)k, strlen((const char *)k), random_seed); | |||
| } | |||
| int lh_char_equal(const void *k1, const void *k2) | |||
| { | |||
| return (strcmp((const char*)k1, (const char*)k2) == 0); | |||
| return (strcmp((const char *)k1, (const char *)k2) == 0); | |||
| } | |||
| struct lh_table* lh_table_new(int size, | |||
| lh_entry_free_fn *free_fn, | |||
| lh_hash_fn *hash_fn, | |||
| lh_equal_fn *equal_fn) | |||
| struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn, | |||
| lh_equal_fn *equal_fn) | |||
| { | |||
| int i; | |||
| struct lh_table *t; | |||
| t = (struct lh_table*)calloc(1, sizeof(struct lh_table)); | |||
| t = (struct lh_table *)calloc(1, sizeof(struct lh_table)); | |||
| if (!t) | |||
| return NULL; | |||
| t->count = 0; | |||
| t->size = size; | |||
| t->table = (struct lh_entry*)calloc(size, sizeof(struct lh_entry)); | |||
| t->table = (struct lh_entry *)calloc(size, sizeof(struct lh_entry)); | |||
| if (!t->table) | |||
| { | |||
| free(t); | |||
| @@ -508,18 +514,17 @@ struct lh_table* lh_table_new(int size, | |||
| t->free_fn = free_fn; | |||
| t->hash_fn = hash_fn; | |||
| t->equal_fn = equal_fn; | |||
| for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY; | |||
| for (i = 0; i < size; i++) | |||
| t->table[i].k = LH_EMPTY; | |||
| return t; | |||
| } | |||
| struct lh_table* lh_kchar_table_new(int size, | |||
| lh_entry_free_fn *free_fn) | |||
| struct lh_table *lh_kchar_table_new(int size, lh_entry_free_fn *free_fn) | |||
| { | |||
| return lh_table_new(size, free_fn, char_hash_fn, lh_char_equal); | |||
| } | |||
| struct lh_table* lh_kptr_table_new(int size, | |||
| lh_entry_free_fn *free_fn) | |||
| struct lh_table *lh_kptr_table_new(int size, lh_entry_free_fn *free_fn) | |||
| { | |||
| return lh_table_new(size, free_fn, lh_ptr_hash, lh_ptr_equal); | |||
| } | |||
| @@ -558,16 +563,17 @@ int lh_table_resize(struct lh_table *t, int new_size) | |||
| void lh_table_free(struct lh_table *t) | |||
| { | |||
| struct lh_entry *c; | |||
| if(t->free_fn) { | |||
| for(c = t->head; c != NULL; c = c->next) | |||
| if (t->free_fn) | |||
| { | |||
| for (c = t->head; c != NULL; c = c->next) | |||
| t->free_fn(c); | |||
| } | |||
| free(t->table); | |||
| free(t); | |||
| } | |||
| int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, const unsigned opts) | |||
| int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, | |||
| const unsigned opts) | |||
| { | |||
| unsigned long n; | |||
| @@ -577,9 +583,12 @@ int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, con | |||
| n = h % t->size; | |||
| while( 1 ) { | |||
| if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) break; | |||
| if ((int)++n == t->size) n = 0; | |||
| while (1) | |||
| { | |||
| if (t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) | |||
| break; | |||
| if ((int)++n == t->size) | |||
| n = 0; | |||
| } | |||
| t->table[n].k = k; | |||
| @@ -587,10 +596,13 @@ int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, con | |||
| t->table[n].v = v; | |||
| t->count++; | |||
| if(t->head == NULL) { | |||
| if (t->head == NULL) | |||
| { | |||
| t->head = t->tail = &t->table[n]; | |||
| t->table[n].next = t->table[n].prev = NULL; | |||
| } else { | |||
| } | |||
| else | |||
| { | |||
| t->tail->next = &t->table[n]; | |||
| t->table[n].prev = t->tail; | |||
| t->table[n].next = NULL; | |||
| @@ -604,59 +616,78 @@ int lh_table_insert(struct lh_table *t, const void *k, const void *v) | |||
| return lh_table_insert_w_hash(t, k, v, lh_get_hash(t, k), 0); | |||
| } | |||
| struct lh_entry* lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, const unsigned long h) | |||
| struct lh_entry *lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, | |||
| const unsigned long h) | |||
| { | |||
| unsigned long n = h % t->size; | |||
| int count = 0; | |||
| while( count < t->size ) { | |||
| if(t->table[n].k == LH_EMPTY) return NULL; | |||
| if(t->table[n].k != LH_FREED && | |||
| t->equal_fn(t->table[n].k, k)) return &t->table[n]; | |||
| if ((int)++n == t->size) n = 0; | |||
| while (count < t->size) | |||
| { | |||
| if (t->table[n].k == LH_EMPTY) | |||
| return NULL; | |||
| if (t->table[n].k != LH_FREED && t->equal_fn(t->table[n].k, k)) | |||
| return &t->table[n]; | |||
| if ((int)++n == t->size) | |||
| n = 0; | |||
| count++; | |||
| } | |||
| return NULL; | |||
| } | |||
| struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k) | |||
| struct lh_entry *lh_table_lookup_entry(struct lh_table *t, const void *k) | |||
| { | |||
| return lh_table_lookup_entry_w_hash(t, k, lh_get_hash(t, k)); | |||
| } | |||
| json_bool lh_table_lookup_ex(struct lh_table* t, const void* k, void **v) | |||
| json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v) | |||
| { | |||
| struct lh_entry *e = lh_table_lookup_entry(t, k); | |||
| if (e != NULL) { | |||
| if (v != NULL) *v = lh_entry_v(e); | |||
| if (e != NULL) | |||
| { | |||
| if (v != NULL) | |||
| *v = lh_entry_v(e); | |||
| return 1; /* key found */ | |||
| } | |||
| if (v != NULL) *v = NULL; | |||
| return 0; /* key not found */ | |||
| if (v != NULL) | |||
| *v = NULL; | |||
| return 0; /* key not found */ | |||
| } | |||
| int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e) | |||
| { | |||
| ptrdiff_t n = (ptrdiff_t)(e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */ | |||
| /* CAW: fixed to be 64bit nice, still need the crazy negative case... */ | |||
| ptrdiff_t n = (ptrdiff_t)(e - t->table); | |||
| /* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */ | |||
| if(n < 0) { return -2; } | |||
| if (n < 0) | |||
| { | |||
| return -2; | |||
| } | |||
| if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) return -1; | |||
| if (t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) | |||
| return -1; | |||
| t->count--; | |||
| if(t->free_fn) t->free_fn(e); | |||
| if (t->free_fn) | |||
| t->free_fn(e); | |||
| t->table[n].v = NULL; | |||
| t->table[n].k = LH_FREED; | |||
| if(t->tail == &t->table[n] && t->head == &t->table[n]) { | |||
| if (t->tail == &t->table[n] && t->head == &t->table[n]) | |||
| { | |||
| t->head = t->tail = NULL; | |||
| } else if (t->head == &t->table[n]) { | |||
| } | |||
| else if (t->head == &t->table[n]) | |||
| { | |||
| t->head->next->prev = NULL; | |||
| t->head = t->head->next; | |||
| } else if (t->tail == &t->table[n]) { | |||
| } | |||
| else if (t->tail == &t->table[n]) | |||
| { | |||
| t->tail->prev->next = NULL; | |||
| t->tail = t->tail->prev; | |||
| } else { | |||
| } | |||
| else | |||
| { | |||
| t->table[n].prev->next = t->table[n].next; | |||
| t->table[n].next->prev = t->table[n].prev; | |||
| } | |||
| @@ -664,11 +695,11 @@ int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e) | |||
| return 0; | |||
| } | |||
| int lh_table_delete(struct lh_table *t, const void *k) | |||
| { | |||
| struct lh_entry *e = lh_table_lookup_entry(t, k); | |||
| if(!e) return -1; | |||
| if (!e) | |||
| return -1; | |||
| return lh_table_delete_entry(t, e); | |||
| } | |||
| @@ -40,12 +40,12 @@ extern "C" { | |||
| /** | |||
| * sentinel pointer value for empty slots | |||
| */ | |||
| #define LH_EMPTY (void*)-1 | |||
| #define LH_EMPTY (void *)-1 | |||
| /** | |||
| * sentinel pointer value for freed slots | |||
| */ | |||
| #define LH_FREED (void*)-2 | |||
| #define LH_FREED (void *)-2 | |||
| /** | |||
| * default string hash function | |||
| @@ -69,20 +69,21 @@ struct lh_entry; | |||
| /** | |||
| * callback function prototypes | |||
| */ | |||
| typedef void (lh_entry_free_fn) (struct lh_entry *e); | |||
| typedef void(lh_entry_free_fn)(struct lh_entry *e); | |||
| /** | |||
| * callback function prototypes | |||
| */ | |||
| typedef unsigned long (lh_hash_fn) (const void *k); | |||
| typedef unsigned long(lh_hash_fn)(const void *k); | |||
| /** | |||
| * callback function prototypes | |||
| */ | |||
| typedef int (lh_equal_fn) (const void *k1, const void *k2); | |||
| typedef int(lh_equal_fn)(const void *k1, const void *k2); | |||
| /** | |||
| * An entry in the hash table | |||
| */ | |||
| struct lh_entry { | |||
| struct lh_entry | |||
| { | |||
| /** | |||
| * The key. Use lh_entry_k() instead of accessing this directly. | |||
| */ | |||
| @@ -106,11 +107,11 @@ struct lh_entry { | |||
| struct lh_entry *prev; | |||
| }; | |||
| /** | |||
| * The hash table structure. | |||
| */ | |||
| struct lh_table { | |||
| struct lh_table | |||
| { | |||
| /** | |||
| * Size of our hash. | |||
| */ | |||
| @@ -141,12 +142,10 @@ struct lh_table { | |||
| }; | |||
| typedef struct lh_table lh_table; | |||
| /** | |||
| * Convenience list iterator. | |||
| */ | |||
| #define lh_foreach(table, entry) \ | |||
| for(entry = table->head; entry; entry = entry->next) | |||
| #define lh_foreach(table, entry) for (entry = table->head; entry; entry = entry->next) | |||
| /** | |||
| * lh_foreach_safe allows calling of deletion routine while iterating. | |||
| @@ -156,9 +155,7 @@ for(entry = table->head; entry; entry = entry->next) | |||
| * @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element | |||
| */ | |||
| #define lh_foreach_safe(table, entry, tmp) \ | |||
| for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp) | |||
| for (entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp) | |||
| /** | |||
| * Create a new linkhash table. | |||
| @@ -178,10 +175,8 @@ for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp) | |||
| * @return On success, a pointer to the new linkhash table is returned. | |||
| * On error, a null pointer is returned. | |||
| */ | |||
| extern struct lh_table* lh_table_new(int size, | |||
| lh_entry_free_fn *free_fn, | |||
| lh_hash_fn *hash_fn, | |||
| lh_equal_fn *equal_fn); | |||
| extern struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn, | |||
| lh_equal_fn *equal_fn); | |||
| /** | |||
| * Convenience function to create a new linkhash table with char keys. | |||
| @@ -191,9 +186,7 @@ extern struct lh_table* lh_table_new(int size, | |||
| * @return On success, a pointer to the new linkhash table is returned. | |||
| * On error, a null pointer is returned. | |||
| */ | |||
| extern struct lh_table* lh_kchar_table_new(int size, | |||
| lh_entry_free_fn *free_fn); | |||
| extern struct lh_table *lh_kchar_table_new(int size, lh_entry_free_fn *free_fn); | |||
| /** | |||
| * Convenience function to create a new linkhash table with ptr keys. | |||
| @@ -203,9 +196,7 @@ extern struct lh_table* lh_kchar_table_new(int size, | |||
| * @return On success, a pointer to the new linkhash table is returned. | |||
| * On error, a null pointer is returned. | |||
| */ | |||
| extern struct lh_table* lh_kptr_table_new(int size, | |||
| lh_entry_free_fn *free_fn); | |||
| extern struct lh_table *lh_kptr_table_new(int size, lh_entry_free_fn *free_fn); | |||
| /** | |||
| * Free a linkhash table. | |||
| @@ -217,7 +208,6 @@ extern struct lh_table* lh_kptr_table_new(int size, | |||
| */ | |||
| extern void lh_table_free(struct lh_table *t); | |||
| /** | |||
| * Insert a record into the table. | |||
| * | |||
| @@ -230,7 +220,6 @@ extern void lh_table_free(struct lh_table *t); | |||
| */ | |||
| extern int lh_table_insert(struct lh_table *t, const void *k, const void *v); | |||
| /** | |||
| * Insert a record into the table using a precalculated key hash. | |||
| * | |||
| @@ -245,8 +234,8 @@ extern int lh_table_insert(struct lh_table *t, const void *k, const void *v); | |||
| * @param opts if set to JSON_C_OBJECT_KEY_IS_CONSTANT, sets lh_entry.k_is_constant | |||
| * so t's free function knows to avoid freeing the key. | |||
| */ | |||
| extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, const unsigned opts); | |||
| extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, | |||
| const unsigned long h, const unsigned opts); | |||
| /** | |||
| * Lookup a record in the table. | |||
| @@ -255,7 +244,7 @@ extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void | |||
| * @param k a pointer to the key to lookup | |||
| * @return a pointer to the record structure of the value or NULL if it does not exist. | |||
| */ | |||
| extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k); | |||
| extern struct lh_entry *lh_table_lookup_entry(struct lh_table *t, const void *k); | |||
| /** | |||
| * Lookup a record in the table using a precalculated key hash. | |||
| @@ -269,7 +258,8 @@ extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k) | |||
| * @param h hash value of the key to lookup | |||
| * @return a pointer to the record structure of the value or NULL if it does not exist. | |||
| */ | |||
| extern struct lh_entry* lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, const unsigned long h); | |||
| extern struct lh_entry *lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, | |||
| const unsigned long h); | |||
| /** | |||
| * Lookup a record in the table. | |||
| @@ -293,7 +283,6 @@ extern json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v) | |||
| */ | |||
| extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e); | |||
| /** | |||
| * Delete a record from the table. | |||
| * | |||
| @@ -319,7 +308,6 @@ extern int lh_table_length(struct lh_table *t); | |||
| */ | |||
| int lh_table_resize(struct lh_table *t, int new_size); | |||
| /** | |||
| * @deprecated Don't use this outside of linkhash.h: | |||
| */ | |||
| @@ -9,17 +9,17 @@ | |||
| /* Define isnan, isinf, infinity and nan on Windows/MSVC */ | |||
| #ifndef HAVE_DECL_ISNAN | |||
| # ifdef HAVE_DECL__ISNAN | |||
| #ifdef HAVE_DECL__ISNAN | |||
| #include <float.h> | |||
| #define isnan(x) _isnan(x) | |||
| # endif | |||
| #endif | |||
| #endif | |||
| #ifndef HAVE_DECL_ISINF | |||
| # ifdef HAVE_DECL__FINITE | |||
| #ifdef HAVE_DECL__FINITE | |||
| #include <float.h> | |||
| #define isinf(x) (!_finite(x)) | |||
| # endif | |||
| #endif | |||
| #endif | |||
| #ifndef HAVE_DECL_INFINITY | |||
| @@ -20,9 +20,9 @@ | |||
| #include <string.h> | |||
| #ifdef HAVE_STDARG_H | |||
| # include <stdarg.h> | |||
| #include <stdarg.h> | |||
| #else /* !HAVE_STDARG_H */ | |||
| # error Not enough var arg support! | |||
| #error Not enough var arg support! | |||
| #endif /* HAVE_STDARG_H */ | |||
| #include "debug.h" | |||
| @@ -32,23 +32,24 @@ | |||
| static int printbuf_extend(struct printbuf *p, int min_size); | |||
| struct printbuf* printbuf_new(void) | |||
| struct printbuf *printbuf_new(void) | |||
| { | |||
| struct printbuf *p; | |||
| p = (struct printbuf*)calloc(1, sizeof(struct printbuf)); | |||
| if(!p) return NULL; | |||
| p->size = 32; | |||
| p->bpos = 0; | |||
| if(!(p->buf = (char*)malloc(p->size))) { | |||
| free(p); | |||
| return NULL; | |||
| } | |||
| p->buf[0]= '\0'; | |||
| return p; | |||
| struct printbuf *p; | |||
| p = (struct printbuf *)calloc(1, sizeof(struct printbuf)); | |||
| if (!p) | |||
| return NULL; | |||
| p->size = 32; | |||
| p->bpos = 0; | |||
| if (!(p->buf = (char *)malloc(p->size))) | |||
| { | |||
| free(p); | |||
| return NULL; | |||
| } | |||
| p->buf[0] = '\0'; | |||
| return p; | |||
| } | |||
| /** | |||
| * Extend the buffer p so it has a size of at least min_size. | |||
| * | |||
| @@ -67,13 +68,13 @@ static int printbuf_extend(struct printbuf *p, int min_size) | |||
| new_size = p->size * 2; | |||
| if (new_size < min_size + 8) | |||
| new_size = min_size + 8; | |||
| new_size = min_size + 8; | |||
| #ifdef PRINTBUF_DEBUG | |||
| MC_DEBUG("printbuf_memappend: realloc " | |||
| "bpos=%d min_size=%d old_size=%d new_size=%d\n", | |||
| p->bpos, min_size, p->size, new_size); | |||
| "bpos=%d min_size=%d old_size=%d new_size=%d\n", | |||
| p->bpos, min_size, p->size, new_size); | |||
| #endif /* PRINTBUF_DEBUG */ | |||
| if(!(t = (char*)realloc(p->buf, new_size))) | |||
| if (!(t = (char *)realloc(p->buf, new_size))) | |||
| return -1; | |||
| p->size = new_size; | |||
| p->buf = t; | |||
| @@ -82,14 +83,15 @@ static int printbuf_extend(struct printbuf *p, int min_size) | |||
| int printbuf_memappend(struct printbuf *p, const char *buf, int size) | |||
| { | |||
| if (p->size <= p->bpos + size + 1) { | |||
| if (printbuf_extend(p, p->bpos + size + 1) < 0) | |||
| return -1; | |||
| } | |||
| memcpy(p->buf + p->bpos, buf, size); | |||
| p->bpos += size; | |||
| p->buf[p->bpos]= '\0'; | |||
| return size; | |||
| if (p->size <= p->bpos + size + 1) | |||
| { | |||
| if (printbuf_extend(p, p->bpos + size + 1) < 0) | |||
| return -1; | |||
| } | |||
| memcpy(p->buf + p->bpos, buf, size); | |||
| p->bpos += size; | |||
| p->buf[p->bpos] = '\0'; | |||
| return size; | |||
| } | |||
| int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len) | |||
| @@ -114,42 +116,51 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len) | |||
| int sprintbuf(struct printbuf *p, const char *msg, ...) | |||
| { | |||
| va_list ap; | |||
| char *t; | |||
| int size; | |||
| char buf[128]; | |||
| /* user stack buffer first */ | |||
| va_start(ap, msg); | |||
| size = vsnprintf(buf, 128, msg, ap); | |||
| va_end(ap); | |||
| /* if string is greater than stack buffer, then use dynamic string | |||
| with vasprintf. Note: some implementation of vsnprintf return -1 | |||
| if output is truncated whereas some return the number of bytes that | |||
| would have been written - this code handles both cases. */ | |||
| if(size == -1 || size > 127) { | |||
| va_start(ap, msg); | |||
| if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; } | |||
| va_end(ap); | |||
| printbuf_memappend(p, t, size); | |||
| free(t); | |||
| return size; | |||
| } else { | |||
| printbuf_memappend(p, buf, size); | |||
| return size; | |||
| } | |||
| va_list ap; | |||
| char *t; | |||
| int size; | |||
| char buf[128]; | |||
| /* user stack buffer first */ | |||
| va_start(ap, msg); | |||
| size = vsnprintf(buf, 128, msg, ap); | |||
| va_end(ap); | |||
| /* if string is greater than stack buffer, then use dynamic string | |||
| * with vasprintf. Note: some implementation of vsnprintf return -1 | |||
| * if output is truncated whereas some return the number of bytes that | |||
| * would have been written - this code handles both cases. | |||
| */ | |||
| if (size == -1 || size > 127) | |||
| { | |||
| va_start(ap, msg); | |||
| if ((size = vasprintf(&t, msg, ap)) < 0) | |||
| { | |||
| va_end(ap); | |||
| return -1; | |||
| } | |||
| va_end(ap); | |||
| printbuf_memappend(p, t, size); | |||
| free(t); | |||
| return size; | |||
| } | |||
| else | |||
| { | |||
| printbuf_memappend(p, buf, size); | |||
| return size; | |||
| } | |||
| } | |||
| void printbuf_reset(struct printbuf *p) | |||
| { | |||
| p->buf[0] = '\0'; | |||
| p->bpos = 0; | |||
| p->buf[0] = '\0'; | |||
| p->bpos = 0; | |||
| } | |||
| void printbuf_free(struct printbuf *p) | |||
| { | |||
| if(p) { | |||
| free(p->buf); | |||
| free(p); | |||
| } | |||
| if (p) | |||
| { | |||
| free(p->buf); | |||
| free(p); | |||
| } | |||
| } | |||
| @@ -24,7 +24,7 @@ | |||
| #define _printbuf_h_ | |||
| #ifndef JSON_EXPORT | |||
| #if defined(_MSC_VER) | |||
| #if defined(_MSC_VER) | |||
| #define JSON_EXPORT __declspec(dllexport) | |||
| #else | |||
| #define JSON_EXPORT extern | |||
| @@ -35,15 +35,15 @@ | |||
| extern "C" { | |||
| #endif | |||
| struct printbuf { | |||
| char *buf; | |||
| int bpos; | |||
| int size; | |||
| struct printbuf | |||
| { | |||
| char *buf; | |||
| int bpos; | |||
| int size; | |||
| }; | |||
| typedef struct printbuf printbuf; | |||
| JSON_EXPORT struct printbuf* | |||
| printbuf_new(void); | |||
| JSON_EXPORT struct printbuf *printbuf_new(void); | |||
| /* As an optimization, printbuf_memappend_fast() is defined as a macro | |||
| * that handles copying data if the buffer is large enough; otherwise | |||
| @@ -53,17 +53,22 @@ printbuf_new(void); | |||
| * Your code should not use printbuf_memappend() directly unless it | |||
| * checks the return code. Use printbuf_memappend_fast() instead. | |||
| */ | |||
| JSON_EXPORT int | |||
| printbuf_memappend(struct printbuf *p, const char *buf, int size); | |||
| #define printbuf_memappend_fast(p, bufptr, bufsize) \ | |||
| do { \ | |||
| if ((p->size - p->bpos) > bufsize) { \ | |||
| memcpy(p->buf + p->bpos, (bufptr), bufsize); \ | |||
| p->bpos += bufsize; \ | |||
| p->buf[p->bpos]= '\0'; \ | |||
| } else { printbuf_memappend(p, (bufptr), bufsize); } \ | |||
| } while (0) | |||
| JSON_EXPORT int printbuf_memappend(struct printbuf *p, const char *buf, int size); | |||
| #define printbuf_memappend_fast(p, bufptr, bufsize) \ | |||
| do \ | |||
| { \ | |||
| if ((p->size - p->bpos) > bufsize) \ | |||
| { \ | |||
| memcpy(p->buf + p->bpos, (bufptr), bufsize); \ | |||
| p->bpos += bufsize; \ | |||
| p->buf[p->bpos] = '\0'; \ | |||
| } \ | |||
| else \ | |||
| { \ | |||
| printbuf_memappend(p, (bufptr), bufsize); \ | |||
| } \ | |||
| } while (0) | |||
| #define printbuf_length(p) ((p)->bpos) | |||
| @@ -87,7 +92,7 @@ do { \ | |||
| * sprintbuf() | |||
| */ | |||
| #define printbuf_strappend(pb, str) \ | |||
| printbuf_memappend ((pb), _printbuf_check_literal(str), sizeof(str) - 1) | |||
| printbuf_memappend((pb), _printbuf_check_literal(str), sizeof(str) - 1) | |||
| /** | |||
| * Set len bytes of the buffer to charvalue, starting at offset offset. | |||
| @@ -97,8 +102,7 @@ do { \ | |||
| * | |||
| * If offset is -1, this starts at the end of the current data in the buffer. | |||
| */ | |||
| JSON_EXPORT int | |||
| printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len); | |||
| JSON_EXPORT int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len); | |||
| /** | |||
| * Formatted print to printbuf. | |||
| @@ -114,14 +118,11 @@ printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len); | |||
| * printbuf_memappend() | |||
| * printbuf_strappend() | |||
| */ | |||
| JSON_EXPORT int | |||
| sprintbuf(struct printbuf *p, const char *msg, ...); | |||
| JSON_EXPORT int sprintbuf(struct printbuf *p, const char *msg, ...); | |||
| JSON_EXPORT void | |||
| printbuf_reset(struct printbuf *p); | |||
| JSON_EXPORT void printbuf_reset(struct printbuf *p); | |||
| JSON_EXPORT void | |||
| printbuf_free(struct printbuf *p); | |||
| JSON_EXPORT void printbuf_free(struct printbuf *p); | |||
| #ifdef __cplusplus | |||
| } | |||
| @@ -35,7 +35,7 @@ static int json_c_snprintf(char *str, size_t size, const char *format, ...) | |||
| #define snprintf json_c_snprintf | |||
| #elif !defined(HAVE_SNPRINTF) /* !HAVE_SNPRINTF */ | |||
| # error Need vsnprintf! | |||
| #error Need vsnprintf! | |||
| #endif /* !HAVE_SNPRINTF && defined(WIN32) */ | |||
| #endif /* __snprintf_compat_h */ | |||
| @@ -7,10 +7,10 @@ | |||
| */ | |||
| #if !defined(HAVE_STRDUP) && defined(_MSC_VER) | |||
| /* MSC has the version as _strdup */ | |||
| # define strdup _strdup | |||
| /* MSC has the version as _strdup */ | |||
| #define strdup _strdup | |||
| #elif !defined(HAVE_STRDUP) | |||
| # error You do not have strdup on your system. | |||
| #error You do not have strdup on your system. | |||
| #endif /* HAVE_STRDUP */ | |||
| #endif | |||
| @@ -5,10 +5,12 @@ | |||
| * Override strerror() to get consistent output across platforms. | |||
| */ | |||
| static struct { | |||
| static struct | |||
| { | |||
| int errno_value; | |||
| const char *errno_str; | |||
| } errno_list[] = { | |||
| /* clang-format off */ | |||
| #define STRINGIFY(x) #x | |||
| #define ENTRY(x) {x, &STRINGIFY(undef_ ## x)[6]} | |||
| ENTRY(EPERM), | |||
| @@ -52,6 +54,7 @@ static struct { | |||
| ENTRY(EAGAIN), | |||
| { 0, (char *)0 } | |||
| }; | |||
| /* clang-format on */ | |||
| // Enabled during tests | |||
| int _json_c_strerror_enable = 0; | |||
| @@ -76,7 +79,8 @@ char *_json_c_strerror(int errno_in) | |||
| if (errno_list[ii].errno_value != errno_in) | |||
| continue; | |||
| for (start_idx = sizeof(PREFIX) - 1, jj = 0; errno_str[jj] != '\0'; jj++, start_idx++) | |||
| for (start_idx = sizeof(PREFIX) - 1, jj = 0; errno_str[jj] != '\0'; | |||
| jj++, start_idx++) | |||
| { | |||
| errno_buf[start_idx] = errno_str[jj]; | |||
| } | |||
| @@ -92,10 +96,9 @@ char *_json_c_strerror(int errno_in) | |||
| digbuf[ii] = "0123456789"[(errno_in % 10)]; | |||
| // Reverse the digits | |||
| for (start_idx = sizeof(PREFIX) - 1 ; ii >= 0; ii--, start_idx++) | |||
| for (start_idx = sizeof(PREFIX) - 1; ii >= 0; ii--, start_idx++) | |||
| { | |||
| errno_buf[start_idx] = digbuf[ii]; | |||
| } | |||
| return errno_buf; | |||
| } | |||
| @@ -20,11 +20,11 @@ extern "C" { | |||
| JSON_EXPORT char *_json_c_strerror(int errno_in); | |||
| #ifndef STRERROR_OVERRIDE_IMPL | |||
| #define strerror _json_c_strerror | |||
| #define strerror _json_c_strerror | |||
| #endif | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* _json_strerror_override_h_ */ | |||
| #endif /* _json_strerror_override_h_ */ | |||
| @@ -7,19 +7,20 @@ | |||
| #include "parse_flags.h" | |||
| #if !defined(HAVE_STRCASECMP) && defined(_MSC_VER) | |||
| # define strcasecmp _stricmp | |||
| #define strcasecmp _stricmp | |||
| #elif !defined(HAVE_STRCASECMP) | |||
| # error You do not have strcasecmp on your system. | |||
| #error You do not have strcasecmp on your system. | |||
| #endif /* HAVE_STRNCASECMP */ | |||
| static struct { | |||
| static struct | |||
| { | |||
| const char *arg; | |||
| int flag; | |||
| } format_args[] = { | |||
| { "plain", JSON_C_TO_STRING_PLAIN }, | |||
| { "spaced", JSON_C_TO_STRING_SPACED }, | |||
| { "pretty", JSON_C_TO_STRING_PRETTY }, | |||
| { "pretty_tab", JSON_C_TO_STRING_PRETTY_TAB }, | |||
| {"plain", JSON_C_TO_STRING_PLAIN}, | |||
| {"spaced", JSON_C_TO_STRING_SPACED}, | |||
| {"pretty", JSON_C_TO_STRING_PRETTY}, | |||
| {"pretty_tab", JSON_C_TO_STRING_PRETTY_TAB}, | |||
| }; | |||
| #ifndef NELEM | |||
| @@ -30,7 +31,7 @@ int parse_flags(int argc, char **argv) | |||
| { | |||
| int arg_idx; | |||
| int sflags = 0; | |||
| for (arg_idx = 1; arg_idx < argc ; arg_idx++) | |||
| for (arg_idx = 1; arg_idx < argc; arg_idx++) | |||
| { | |||
| int jj; | |||
| for (jj = 0; jj < (int)NELEM(format_args); jj++) | |||
| @@ -1,19 +1,19 @@ | |||
| #include <assert.h> | |||
| #include <stddef.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <stddef.h> | |||
| #include <string.h> | |||
| #include <assert.h> | |||
| #include "json.h" | |||
| #include "parse_flags.h" | |||
| static int sort_fn (const void *j1, const void *j2) | |||
| static int sort_fn(const void *j1, const void *j2) | |||
| { | |||
| json_object * const *jso1, * const *jso2; | |||
| json_object *const *jso1, *const *jso2; | |||
| int i1, i2; | |||
| jso1 = (json_object* const*)j1; | |||
| jso2 = (json_object* const*)j2; | |||
| jso1 = (json_object *const *)j1; | |||
| jso2 = (json_object *const *)j2; | |||
| if (!*jso1 && !*jso2) | |||
| return 0; | |||
| if (!*jso1) | |||
| @@ -38,7 +38,8 @@ static const char *to_json_string(json_object *obj, int flags) | |||
| copy = strdup(result); | |||
| if (copy == NULL) | |||
| printf("to_json_string: Allocation failed!\n"); | |||
| else { | |||
| else | |||
| { | |||
| result = json_object_to_json_string_ext(obj, flags); | |||
| if (length != strlen(result)) | |||
| printf("to_json_string: Length mismatch!\n"); | |||
| @@ -48,7 +49,7 @@ static const char *to_json_string(json_object *obj, int flags) | |||
| } | |||
| return result; | |||
| } | |||
| #define json_object_to_json_string(obj) to_json_string(obj,sflags) | |||
| #define json_object_to_json_string(obj) to_json_string(obj, sflags) | |||
| #else | |||
| /* no special define */ | |||
| #endif | |||
| @@ -84,7 +85,7 @@ void test_array_del_idx() | |||
| orig_array_len = json_object_array_length(my_array); | |||
| printf("my_array=\n"); | |||
| for(ii = 0; ii < json_object_array_length(my_array); ii++) | |||
| for (ii = 0; ii < json_object_array_length(my_array); ii++) | |||
| { | |||
| json_object *obj = json_object_array_get_idx(my_array, ii); | |||
| printf("\t[%d]=%s\n", (int)ii, json_object_to_json_string(obj)); | |||
| @@ -94,38 +95,38 @@ void test_array_del_idx() | |||
| for (ii = 0; ii < orig_array_len; ii++) | |||
| { | |||
| rc = json_object_array_del_idx(my_array, 0, 1); | |||
| printf("after del_idx(0,1)=%d, my_array.to_string()=%s\n", | |||
| rc, json_object_to_json_string(my_array)); | |||
| printf("after del_idx(0,1)=%d, my_array.to_string()=%s\n", rc, | |||
| json_object_to_json_string(my_array)); | |||
| } | |||
| /* One more time, with the empty array: */ | |||
| rc = json_object_array_del_idx(my_array, 0, 1); | |||
| printf("after del_idx(0,1)=%d, my_array.to_string()=%s\n", | |||
| rc, json_object_to_json_string(my_array)); | |||
| printf("after del_idx(0,1)=%d, my_array.to_string()=%s\n", rc, | |||
| json_object_to_json_string(my_array)); | |||
| json_object_put(my_array); | |||
| /* Delete all array indexes at once */ | |||
| my_array = make_array(); | |||
| rc = json_object_array_del_idx(my_array, 0, orig_array_len); | |||
| printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", | |||
| (int)orig_array_len, rc, json_object_to_json_string(my_array)); | |||
| printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", (int)orig_array_len, rc, | |||
| json_object_to_json_string(my_array)); | |||
| json_object_put(my_array); | |||
| /* Delete *more* than all array indexes at once */ | |||
| my_array = make_array(); | |||
| rc = json_object_array_del_idx(my_array, 0, orig_array_len + 1); | |||
| printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", | |||
| (int)(orig_array_len + 1), rc, json_object_to_json_string(my_array)); | |||
| printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", (int)(orig_array_len + 1), rc, | |||
| json_object_to_json_string(my_array)); | |||
| json_object_put(my_array); | |||
| /* Delete some array indexes, then add more */ | |||
| my_array = make_array(); | |||
| rc = json_object_array_del_idx(my_array, 0, orig_array_len - 1); | |||
| printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", | |||
| (int)(orig_array_len - 1), rc, json_object_to_json_string(my_array)); | |||
| printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", (int)(orig_array_len - 1), rc, | |||
| json_object_to_json_string(my_array)); | |||
| json_object_array_add(my_array, json_object_new_string("s1")); | |||
| json_object_array_add(my_array, json_object_new_string("s2")); | |||
| json_object_array_add(my_array, json_object_new_string("s3")); | |||
| @@ -162,13 +163,15 @@ int main(int argc, char **argv) | |||
| my_string = json_object_new_string("/"); | |||
| printf("my_string=%s\n", json_object_get_string(my_string)); | |||
| printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string)); | |||
| printf("my_string.to_string(NOSLASHESCAPE)=%s\n", json_object_to_json_string_ext(my_string, JSON_C_TO_STRING_NOSLASHESCAPE)); | |||
| printf("my_string.to_string(NOSLASHESCAPE)=%s\n", | |||
| json_object_to_json_string_ext(my_string, JSON_C_TO_STRING_NOSLASHESCAPE)); | |||
| json_object_put(my_string); | |||
| my_string = json_object_new_string("/foo/bar/baz"); | |||
| printf("my_string=%s\n", json_object_get_string(my_string)); | |||
| printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string)); | |||
| printf("my_string.to_string(NOSLASHESCAPE)=%s\n", json_object_to_json_string_ext(my_string, JSON_C_TO_STRING_NOSLASHESCAPE)); | |||
| printf("my_string.to_string(NOSLASHESCAPE)=%s\n", | |||
| json_object_to_json_string_ext(my_string, JSON_C_TO_STRING_NOSLASHESCAPE)); | |||
| json_object_put(my_string); | |||
| my_string = json_object_new_string("foo"); | |||
| @@ -188,7 +191,7 @@ int main(int argc, char **argv) | |||
| json_object_array_add(my_array, json_object_new_int(3)); | |||
| json_object_array_put_idx(my_array, 4, json_object_new_int(5)); | |||
| printf("my_array=\n"); | |||
| for(i=0; i < json_object_array_length(my_array); i++) | |||
| for (i = 0; i < json_object_array_length(my_array); i++) | |||
| { | |||
| json_object *obj = json_object_array_get_idx(my_array, i); | |||
| printf("\t[%d]=%s\n", (int)i, json_object_to_json_string(obj)); | |||
| @@ -205,7 +208,7 @@ int main(int argc, char **argv) | |||
| json_object_array_add(my_array, json_object_new_int(2)); | |||
| json_object_array_put_idx(my_array, 4, json_object_new_int(0)); | |||
| printf("my_array=\n"); | |||
| for(i=0; i < json_object_array_length(my_array); i++) | |||
| for (i = 0; i < json_object_array_length(my_array); i++) | |||
| { | |||
| json_object *obj = json_object_array_get_idx(my_array, i); | |||
| printf("\t[%d]=%s\n", (int)i, json_object_to_json_string(obj)); | |||
| @@ -213,7 +216,7 @@ int main(int argc, char **argv) | |||
| printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array)); | |||
| json_object_array_sort(my_array, sort_fn); | |||
| printf("my_array=\n"); | |||
| for(i=0; i < json_object_array_length(my_array); i++) | |||
| for (i = 0; i < json_object_array_length(my_array); i++) | |||
| { | |||
| json_object *obj = json_object_array_get_idx(my_array, i); | |||
| printf("\t[%d]=%s\n", (int)i, json_object_to_json_string(obj)); | |||
| @@ -1,18 +1,17 @@ | |||
| #include <stddef.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <stddef.h> | |||
| #include <string.h> | |||
| #include "json.h" | |||
| #include "parse_flags.h" | |||
| #ifdef TEST_FORMATTED | |||
| #define json_object_to_json_string(obj) json_object_to_json_string_ext(obj,sflags) | |||
| #define json_object_to_json_string(obj) json_object_to_json_string_ext(obj, sflags) | |||
| #else | |||
| /* no special define */ | |||
| #endif | |||
| int main(int argc, char **argv) | |||
| { | |||
| json_object *new_obj; | |||
| @@ -26,8 +25,13 @@ int main(int argc, char **argv) | |||
| sflags = parse_flags(argc, argv); | |||
| #endif | |||
| new_obj = json_tokener_parse("/* more difficult test case */" | |||
| "{ \"glossary\": { \"title\": \"example glossary\", \"GlossDiv\": { \"title\": \"S\", \"GlossList\": [ { \"ID\": \"SGML\", \"SortAs\": \"SGML\", \"GlossTerm\": \"Standard Generalized Markup Language\", \"Acronym\": \"SGML\", \"Abbrev\": \"ISO 8879:1986\", \"GlossDef\": \"A meta-markup language, used to create markup languages such as DocBook.\", \"GlossSeeAlso\": [\"GML\", \"XML\", \"markup\"] } ] } } }"); | |||
| new_obj = json_tokener_parse( | |||
| "/* more difficult test case */" | |||
| "{ \"glossary\": { \"title\": \"example glossary\", \"GlossDiv\": { \"title\": \"S\", " | |||
| "\"GlossList\": [ { \"ID\": \"SGML\", \"SortAs\": \"SGML\", \"GlossTerm\": \"Standard " | |||
| "Generalized Markup Language\", \"Acronym\": \"SGML\", \"Abbrev\": \"ISO 8879:1986\", " | |||
| "\"GlossDef\": \"A meta-markup language, used to create markup languages such as " | |||
| "DocBook.\", \"GlossSeeAlso\": [\"GML\", \"XML\", \"markup\"] } ] } } }"); | |||
| printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); | |||
| json_object_put(new_obj); | |||
| @@ -2,24 +2,24 @@ | |||
| * gcc -o utf8 utf8.c -I/home/y/include -L./.libs -ljson | |||
| */ | |||
| #include "config.h" | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include "config.h" | |||
| #include "json_inttypes.h" | |||
| #include "json_object.h" | |||
| #include "json_tokener.h" | |||
| void print_hex(const char* s) | |||
| void print_hex(const char *s) | |||
| { | |||
| const char *iter = s; | |||
| unsigned char ch; | |||
| while ((ch = *iter++) != 0) | |||
| { | |||
| if( ',' != ch) | |||
| if (',' != ch) | |||
| printf("%x ", ch); | |||
| else | |||
| printf( ","); | |||
| printf(","); | |||
| } | |||
| putchar('\n'); | |||
| } | |||
| @@ -27,19 +27,22 @@ void print_hex(const char* s) | |||
| int main(void) | |||
| { | |||
| const char *input = "\"\\ud840\\udd26,\\ud840\\udd27,\\ud800\\udd26,\\ud800\\udd27\""; | |||
| const char *expected = "\xF0\xA0\x84\xA6,\xF0\xA0\x84\xA7,\xF0\x90\x84\xA6,\xF0\x90\x84\xA7"; | |||
| const char *expected = | |||
| "\xF0\xA0\x84\xA6,\xF0\xA0\x84\xA7,\xF0\x90\x84\xA6,\xF0\x90\x84\xA7"; | |||
| struct json_object *parse_result = json_tokener_parse(input); | |||
| const char *unjson = json_object_get_string(parse_result); | |||
| printf("input: %s\n", input); | |||
| int strings_match = !strcmp( expected, unjson); | |||
| int strings_match = !strcmp(expected, unjson); | |||
| int retval = 0; | |||
| if (strings_match) | |||
| { | |||
| printf("JSON parse result is correct: %s\n", unjson); | |||
| puts("PASS"); | |||
| } else { | |||
| } | |||
| else | |||
| { | |||
| printf("JSON parse result doesn't match expected string\n"); | |||
| printf("expected string bytes: "); | |||
| print_hex(expected); | |||
| @@ -1,6 +1,6 @@ | |||
| #include <stddef.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <stddef.h> | |||
| #include <string.h> | |||
| #include "json.h" | |||
| @@ -67,12 +67,12 @@ int main(int argc, char **argv) | |||
| } | |||
| if (new_count != orig_count) | |||
| { | |||
| printf("mismatch between original count (%d) and new count (%d)\n", | |||
| orig_count, new_count); | |||
| printf("mismatch between original count (%d) and new count (%d)\n", orig_count, | |||
| new_count); | |||
| retval = 1; | |||
| } | |||
| json_object_put( my_object ); | |||
| json_object_put(my_object); | |||
| return retval; | |||
| } | |||
| @@ -3,10 +3,10 @@ | |||
| * Also checks the json_object_get_type and json_object_is_type functions. | |||
| */ | |||
| #include "config.h" | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <stdlib.h> | |||
| #include "config.h" | |||
| #include <string.h> | |||
| #include "json_inttypes.h" | |||
| #include "json_object.h" | |||
| @@ -75,44 +75,31 @@ static void getit(struct json_object *new_obj, const char *field) | |||
| printf("Field %s does not exist\n", field); | |||
| enum json_type o_type = json_object_get_type(o); | |||
| printf("new_obj.%s json_object_get_type()=%s\n", field, | |||
| json_type_to_name(o_type)); | |||
| printf("new_obj.%s json_object_get_int()=%d\n", field, | |||
| json_object_get_int(o)); | |||
| printf("new_obj.%s json_object_get_int64()=%" PRId64 "\n", field, | |||
| json_object_get_int64(o)); | |||
| printf("new_obj.%s json_object_get_type()=%s\n", field, json_type_to_name(o_type)); | |||
| printf("new_obj.%s json_object_get_int()=%d\n", field, json_object_get_int(o)); | |||
| printf("new_obj.%s json_object_get_int64()=%" PRId64 "\n", field, json_object_get_int64(o)); | |||
| printf("new_obj.%s json_object_get_uint64()=%" PRIu64 "\n", field, | |||
| json_object_get_uint64(o)); | |||
| printf("new_obj.%s json_object_get_boolean()=%d\n", field, | |||
| json_object_get_boolean(o)); | |||
| printf("new_obj.%s json_object_get_double()=%f\n", field, | |||
| json_object_get_double(o)); | |||
| printf("new_obj.%s json_object_get_boolean()=%d\n", field, json_object_get_boolean(o)); | |||
| printf("new_obj.%s json_object_get_double()=%f\n", field, json_object_get_double(o)); | |||
| } | |||
| static void checktype_header() | |||
| { | |||
| printf("json_object_is_type: %s,%s,%s,%s,%s,%s,%s\n", | |||
| json_type_to_name(json_type_null), | |||
| json_type_to_name(json_type_boolean), | |||
| json_type_to_name(json_type_double), | |||
| json_type_to_name(json_type_int), | |||
| json_type_to_name(json_type_object), | |||
| json_type_to_name(json_type_array), | |||
| json_type_to_name(json_type_string)); | |||
| printf("json_object_is_type: %s,%s,%s,%s,%s,%s,%s\n", json_type_to_name(json_type_null), | |||
| json_type_to_name(json_type_boolean), json_type_to_name(json_type_double), | |||
| json_type_to_name(json_type_int), json_type_to_name(json_type_object), | |||
| json_type_to_name(json_type_array), json_type_to_name(json_type_string)); | |||
| } | |||
| static void checktype(struct json_object *new_obj, const char *field) | |||
| { | |||
| struct json_object *o = new_obj; | |||
| if (field && !json_object_object_get_ex(new_obj, field, &o)) | |||
| printf("Field %s does not exist\n", field); | |||
| printf("new_obj%s%-18s: %d,%d,%d,%d,%d,%d,%d\n", | |||
| field ? "." : " ", field ? field : "", | |||
| json_object_is_type(o, json_type_null), | |||
| json_object_is_type(o, json_type_boolean), | |||
| json_object_is_type(o, json_type_double), | |||
| json_object_is_type(o, json_type_int), | |||
| json_object_is_type(o, json_type_object), | |||
| json_object_is_type(o, json_type_array), | |||
| json_object_is_type(o, json_type_string)); | |||
| printf("new_obj%s%-18s: %d,%d,%d,%d,%d,%d,%d\n", field ? "." : " ", field ? field : "", | |||
| json_object_is_type(o, json_type_null), json_object_is_type(o, json_type_boolean), | |||
| json_object_is_type(o, json_type_double), json_object_is_type(o, json_type_int), | |||
| json_object_is_type(o, json_type_object), json_object_is_type(o, json_type_array), | |||
| json_object_is_type(o, json_type_string)); | |||
| } | |||
| @@ -1,8 +1,8 @@ | |||
| #include <assert.h> | |||
| #include <stddef.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <stddef.h> | |||
| #include <string.h> | |||
| #include <assert.h> | |||
| #include "json.h" | |||
| #include "json_tokener.h" | |||
| @@ -28,13 +28,13 @@ static void test_case_parse() | |||
| json_tokener_set_flags(tok, JSON_TOKENER_STRICT); | |||
| new_obj = json_tokener_parse_ex(tok, "True", 4); | |||
| assert (new_obj == NULL); | |||
| assert(new_obj == NULL); | |||
| new_obj = json_tokener_parse_ex(tok, "False", 5); | |||
| assert (new_obj == NULL); | |||
| assert(new_obj == NULL); | |||
| new_obj = json_tokener_parse_ex(tok, "Null", 4); | |||
| assert (new_obj == NULL); | |||
| assert(new_obj == NULL); | |||
| printf("OK\n"); | |||
| @@ -2,9 +2,9 @@ | |||
| * Tests if json_object_equal behaves correct. | |||
| */ | |||
| #include "config.h" | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include "config.h" | |||
| #include "json_inttypes.h" | |||
| #include "json_object.h" | |||
| @@ -1,6 +1,6 @@ | |||
| #include <stddef.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <stddef.h> | |||
| #include <string.h> | |||
| #ifdef NDEBUG | |||
| #undef NDEBUG | |||
| @@ -14,76 +14,76 @@ | |||
| static void do_benchmark(json_object *src1); | |||
| static const char *json_str1 = | |||
| "{" | |||
| " \"glossary\": {" | |||
| " \"title\": \"example glossary\"," | |||
| " \"GlossDiv\": {" | |||
| " \"number\": 16446744073709551615," | |||
| " \"title\": \"S\"," | |||
| " \"null_obj\": null, " | |||
| " \"exixt\": false," | |||
| " \"quantity\":20," | |||
| " \"univalent\":19.8," | |||
| " \"GlossList\": {" | |||
| " \"GlossEntry\": {" | |||
| " \"ID\": \"SGML\"," | |||
| " \"SortAs\": \"SGML\"," | |||
| " \"GlossTerm\": \"Standard Generalized Markup Language\"," | |||
| " \"Acronym\": \"SGML\"," | |||
| " \"Abbrev\": \"ISO 8879:1986\"," | |||
| " \"GlossDef\": {" | |||
| " \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\"," | |||
| " \"GlossSeeAlso\": [\"GML\", \"XML\"]" | |||
| " }," | |||
| " \"GlossSee\": \"markup\"" | |||
| " }" | |||
| " }" | |||
| " }" | |||
| " }" | |||
| "}"; | |||
| static const char *json_str1 = | |||
| "{" | |||
| " \"glossary\": {" | |||
| " \"title\": \"example glossary\"," | |||
| " \"GlossDiv\": {" | |||
| " \"number\": 16446744073709551615," | |||
| " \"title\": \"S\"," | |||
| " \"null_obj\": null, " | |||
| " \"exixt\": false," | |||
| " \"quantity\":20," | |||
| " \"univalent\":19.8," | |||
| " \"GlossList\": {" | |||
| " \"GlossEntry\": {" | |||
| " \"ID\": \"SGML\"," | |||
| " \"SortAs\": \"SGML\"," | |||
| " \"GlossTerm\": \"Standard Generalized Markup Language\"," | |||
| " \"Acronym\": \"SGML\"," | |||
| " \"Abbrev\": \"ISO 8879:1986\"," | |||
| " \"GlossDef\": {" | |||
| " \"para\": \"A meta-markup language, used to create markup languages " | |||
| "such as DocBook.\"," | |||
| " \"GlossSeeAlso\": [\"GML\", \"XML\"]" | |||
| " }," | |||
| " \"GlossSee\": \"markup\"" | |||
| " }" | |||
| " }" | |||
| " }" | |||
| " }" | |||
| "}"; | |||
| static const char *json_str2 = | |||
| "{\"menu\": {" | |||
| " \"header\": \"SVG Viewer\"," | |||
| " \"items\": [" | |||
| " {\"id\": \"Open\"}," | |||
| " {\"id\": \"OpenNew\", \"label\": \"Open New\"}," | |||
| " null," | |||
| " {\"id\": \"ZoomIn\", \"label\": \"Zoom In\"}," | |||
| " {\"id\": \"ZoomOut\", \"label\": \"Zoom Out\"}," | |||
| " {\"id\": \"OriginalView\", \"label\": \"Original View\"}," | |||
| " null," | |||
| " {\"id\": \"Quality\", \"another_null\": null}," | |||
| " {\"id\": \"Pause\"}," | |||
| " {\"id\": \"Mute\"}," | |||
| " null," | |||
| " {\"id\": \"Find\", \"label\": \"Find...\"}," | |||
| " {\"id\": \"FindAgain\", \"label\": \"Find Again\"}," | |||
| " {\"id\": \"Copy\"}," | |||
| " {\"id\": \"CopyAgain\", \"label\": \"Copy Again\"}," | |||
| " {\"id\": \"CopySVG\", \"label\": \"Copy SVG\"}," | |||
| " {\"id\": \"ViewSVG\", \"label\": \"View SVG\"}," | |||
| " {\"id\": \"ViewSource\", \"label\": \"View Source\"}," | |||
| " {\"id\": \"SaveAs\", \"label\": \"Save As\"}," | |||
| " null," | |||
| " {\"id\": \"Help\"}," | |||
| " {\"id\": \"About\", \"label\": \"About Adobe CVG Viewer...\"}" | |||
| " ]" | |||
| "}}"; | |||
| static const char *json_str3 = | |||
| "{\"menu\": {" | |||
| " \"id\": \"file\"," | |||
| " \"value\": \"File\"," | |||
| " \"popup\": {" | |||
| " \"menuitem\": [" | |||
| " {\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"}," | |||
| " {\"value\": \"Open\", \"onclick\": \"OpenDoc()\"}," | |||
| " {\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}" | |||
| " ]" | |||
| " }" | |||
| "}}"; | |||
| "{\"menu\": {" | |||
| " \"header\": \"SVG Viewer\"," | |||
| " \"items\": [" | |||
| " {\"id\": \"Open\"}," | |||
| " {\"id\": \"OpenNew\", \"label\": \"Open New\"}," | |||
| " null," | |||
| " {\"id\": \"ZoomIn\", \"label\": \"Zoom In\"}," | |||
| " {\"id\": \"ZoomOut\", \"label\": \"Zoom Out\"}," | |||
| " {\"id\": \"OriginalView\", \"label\": \"Original View\"}," | |||
| " null," | |||
| " {\"id\": \"Quality\", \"another_null\": null}," | |||
| " {\"id\": \"Pause\"}," | |||
| " {\"id\": \"Mute\"}," | |||
| " null," | |||
| " {\"id\": \"Find\", \"label\": \"Find...\"}," | |||
| " {\"id\": \"FindAgain\", \"label\": \"Find Again\"}," | |||
| " {\"id\": \"Copy\"}," | |||
| " {\"id\": \"CopyAgain\", \"label\": \"Copy Again\"}," | |||
| " {\"id\": \"CopySVG\", \"label\": \"Copy SVG\"}," | |||
| " {\"id\": \"ViewSVG\", \"label\": \"View SVG\"}," | |||
| " {\"id\": \"ViewSource\", \"label\": \"View Source\"}," | |||
| " {\"id\": \"SaveAs\", \"label\": \"Save As\"}," | |||
| " null," | |||
| " {\"id\": \"Help\"}," | |||
| " {\"id\": \"About\", \"label\": \"About Adobe CVG Viewer...\"}" | |||
| " ]" | |||
| "}}"; | |||
| static const char *json_str3 = "{\"menu\": {" | |||
| " \"id\": \"file\"," | |||
| " \"value\": \"File\"," | |||
| " \"popup\": {" | |||
| " \"menuitem\": [" | |||
| " {\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"}," | |||
| " {\"value\": \"Open\", \"onclick\": \"OpenDoc()\"}," | |||
| " {\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}" | |||
| " ]" | |||
| " }" | |||
| "}}"; | |||
| json_object_to_json_string_fn my_custom_serializer; | |||
| int my_custom_serializer(struct json_object *jso, struct printbuf *pb, int level, int flags) | |||
| @@ -93,7 +93,8 @@ int my_custom_serializer(struct json_object *jso, struct printbuf *pb, int level | |||
| } | |||
| json_c_shallow_copy_fn my_shallow_copy; | |||
| int my_shallow_copy(json_object *src, json_object *parent, const char *key, size_t index, json_object **dst) | |||
| int my_shallow_copy(json_object *src, json_object *parent, const char *key, size_t index, | |||
| json_object **dst) | |||
| { | |||
| int rc; | |||
| rc = json_c_shallow_copy_default(src, parent, key, index, dst); | |||
| @@ -109,7 +110,6 @@ int my_shallow_copy(json_object *src, json_object *parent, const char *key, size | |||
| return rc; | |||
| } | |||
| int main(int argc, char **argv) | |||
| { | |||
| struct json_object *src1, *src2, *src3; | |||
| @@ -238,19 +238,24 @@ static void do_benchmark(json_object *src2) | |||
| time_t start = time(NULL); | |||
| start = time(NULL); | |||
| for (ii = 0; ii < iterations; ii++) { | |||
| for (ii = 0; ii < iterations; ii++) | |||
| { | |||
| dst2 = json_tokener_parse(json_object_get_string(src2)); | |||
| json_object_put(dst2); | |||
| } | |||
| printf("BENCHMARK - %d iterations of 'dst2 = json_tokener_parse(json_object_get_string(src2))' took %d seconds\n", iterations, (int)(time(NULL) - start)); | |||
| printf("BENCHMARK - %d iterations of 'dst2 = " | |||
| "json_tokener_parse(json_object_get_string(src2))' took %d seconds\n", | |||
| iterations, (int)(time(NULL) - start)); | |||
| start = time(NULL); | |||
| dst2 = NULL; | |||
| for (ii = 0; ii < iterations; ii++) { | |||
| for (ii = 0; ii < iterations; ii++) | |||
| { | |||
| json_object_deep_copy(src2, &dst2, NULL); | |||
| json_object_put(dst2); | |||
| dst2 = NULL; | |||
| } | |||
| printf("BENCHMARK - %d iterations of 'json_object_deep_copy(src2, &dst2, NULL)' took %d seconds\n", iterations, (int)(time(NULL) - start)); | |||
| printf("BENCHMARK - %d iterations of 'json_object_deep_copy(src2, &dst2, NULL)' took %d " | |||
| "seconds\n", | |||
| iterations, (int)(time(NULL) - start)); | |||
| } | |||
| @@ -2,8 +2,8 @@ | |||
| * Tests if the format string for double serialization is handled correctly | |||
| */ | |||
| #include <stdio.h> | |||
| #include "config.h" | |||
| #include <stdio.h> | |||
| #include "json_object.h" | |||
| #include "json_object_private.h" | |||
| @@ -49,7 +49,8 @@ int main() | |||
| if (json_c_set_serialization_double_format("T%0.2fX", JSON_C_OPTION_THREAD) < 0) | |||
| printf("ERROR: json_c_set_serialization_double_format() failed"); | |||
| printf("obj.to_string(with thread format)=%s\n", json_object_to_json_string(obj)); | |||
| if (json_c_set_serialization_double_format("Ttttttttttttt%0.2fxxxxxxxxxxxxxxxxxxX", JSON_C_OPTION_THREAD) < 0) | |||
| if (json_c_set_serialization_double_format("Ttttttttttttt%0.2fxxxxxxxxxxxxxxxxxxX", | |||
| JSON_C_OPTION_THREAD) < 0) | |||
| printf("ERROR: json_c_set_serialization_double_format() failed"); | |||
| printf("obj.to_string(long thread format)=%s\n", json_object_to_json_string(obj)); | |||
| if (json_c_set_serialization_double_format(NULL, JSON_C_OPTION_THREAD) < 0) | |||
| @@ -96,11 +97,11 @@ int main() | |||
| json_object_put(obj); | |||
| /* Test Infinity and -Infinity handling */ | |||
| obj = json_object_new_double(1.0/zero_dot_zero); | |||
| obj = json_object_new_double(1.0 / zero_dot_zero); | |||
| printf("obj(1.0/0.0)=%s\n", json_object_to_json_string(obj)); | |||
| json_object_put(obj); | |||
| obj = json_object_new_double(-1.0/zero_dot_zero); | |||
| obj = json_object_new_double(-1.0 / zero_dot_zero); | |||
| printf("obj(-1.0/0.0)=%s\n", json_object_to_json_string(obj)); | |||
| json_object_put(obj); | |||
| @@ -1,28 +1,28 @@ | |||
| /* Copyright (C) 2016 by Rainer Gerhards | |||
| * Released under ASL 2.0 */ | |||
| #include "config.h" | |||
| #include <stdio.h> | |||
| #include "json_object.h" | |||
| #include "json_tokener.h" | |||
| #include <stdio.h> | |||
| int main(void) | |||
| { | |||
| json_object *json; | |||
| json_object *json; | |||
| json = json_object_new_double(1.0); | |||
| printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||
| json_object_put(json); | |||
| json = json_object_new_double(1.0); | |||
| printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||
| json_object_put(json); | |||
| json = json_object_new_double(-1.0); | |||
| printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||
| json_object_put(json); | |||
| json = json_object_new_double(1.23); | |||
| printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||
| json_object_put(json); | |||
| json = json_object_new_double(123456789.0); | |||
| printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||
| json_object_put(json); | |||
| json = json_object_new_double(123456789.123); | |||
| printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||
| json_object_put(json); | |||
| return 0; | |||
| json = json_object_new_double(-1.0); | |||
| printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||
| json_object_put(json); | |||
| json = json_object_new_double(1.23); | |||
| printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||
| json_object_put(json); | |||
| json = json_object_new_double(123456789.0); | |||
| printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||
| json_object_put(json); | |||
| json = json_object_new_double(123456789.123); | |||
| printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||
| json_object_put(json); | |||
| return 0; | |||
| } | |||
| @@ -43,7 +43,7 @@ int main(int argc, char **argv) | |||
| assert(json_object_get_int64(tmp) != INT64_MIN); | |||
| json_object_put(tmp); | |||
| printf("INT64 ADD UNDERFLOW PASSED\n"); | |||
| // uint64 + negative int64--> negative int64 | |||
| // uint64 + negative int64--> negative int64 | |||
| tmp = json_object_new_uint64(400); | |||
| json_object_int_inc(tmp, -200); | |||
| assert(json_object_get_int64(tmp) == 200); | |||
| @@ -20,53 +20,57 @@ static void test_example_int(struct json_object *jo1, const char *json_pointer, | |||
| } | |||
| static const char *input_json_str = "{ " | |||
| "'foo': ['bar', 'baz'], " | |||
| "'': 0, " | |||
| "'a/b': 1, " | |||
| "'c%d': 2, " | |||
| "'e^f': 3, " | |||
| "'g|h': 4, " | |||
| "'i\\\\j': 5, " | |||
| "'k\\\"l': 6, " | |||
| "' ': 7, " | |||
| "'m~n': 8 " | |||
| "}"; | |||
| static const char *rec_input_json_str = "{" | |||
| "'arr' : [" | |||
| "{" | |||
| "'obj': [" | |||
| "{},{}," | |||
| "{" | |||
| "'obj1': 0," | |||
| "'obj2': \"1\"" | |||
| "}" | |||
| "]" | |||
| "}" | |||
| "]," | |||
| "'obj' : {" | |||
| "'obj': {" | |||
| "'obj': [" | |||
| "{" | |||
| "'obj1': 0," | |||
| "'obj2': \"1\"" | |||
| "}" | |||
| "]" | |||
| "}" | |||
| "}" | |||
| "}"; | |||
| "'foo': ['bar', 'baz'], " | |||
| "'': 0, " | |||
| "'a/b': 1, " | |||
| "'c%d': 2, " | |||
| "'e^f': 3, " | |||
| "'g|h': 4, " | |||
| "'i\\\\j': 5, " | |||
| "'k\\\"l': 6, " | |||
| "' ': 7, " | |||
| "'m~n': 8 " | |||
| "}"; | |||
| /* clang-format off */ | |||
| static const char *rec_input_json_str = | |||
| "{" | |||
| "'arr' : [" | |||
| "{" | |||
| "'obj': [" | |||
| "{},{}," | |||
| "{" | |||
| "'obj1': 0," | |||
| "'obj2': \"1\"" | |||
| "}" | |||
| "]" | |||
| "}" | |||
| "]," | |||
| "'obj' : {" | |||
| "'obj': {" | |||
| "'obj': [" | |||
| "{" | |||
| "'obj1': 0," | |||
| "'obj2': \"1\"" | |||
| "}" | |||
| "]" | |||
| "}" | |||
| "}" | |||
| "}"; | |||
| /* clang-format on */ | |||
| /* Example from RFC */ | |||
| static void test_example_get() | |||
| { | |||
| int i; | |||
| struct json_object *jo1, *jo2, *jo3; | |||
| struct json_pointer_map_s_i { | |||
| struct json_pointer_map_s_i | |||
| { | |||
| const char *s; | |||
| int i; | |||
| }; | |||
| /* Create a map to iterate over for the ints */ | |||
| /* clang-format off */ | |||
| struct json_pointer_map_s_i json_pointers[] = { | |||
| { "/", 0 }, | |||
| { "/a~1b", 1 }, | |||
| @@ -79,6 +83,7 @@ static void test_example_get() | |||
| { "/m~0n", 8 }, | |||
| { NULL, 0} | |||
| }; | |||
| /* clang-format on */ | |||
| jo1 = json_tokener_parse(input_json_str); | |||
| assert(NULL != jo1); | |||
| @@ -114,7 +119,7 @@ static void test_example_get() | |||
| assert(0 == strcmp("bar", json_object_get_string(jo2))); | |||
| printf("PASSED - GET - /foo/0 == 'bar'\n"); | |||
| for (i = 0 ; json_pointers[i].s; i++) | |||
| for (i = 0; json_pointers[i].s; i++) | |||
| test_example_int(jo1, json_pointers[i].s, json_pointers[i].i); | |||
| json_object_put(jo1); | |||
| @@ -235,7 +240,8 @@ static void test_example_set() | |||
| printf("%s\n", json_object_get_string(jo1)); | |||
| assert(0 == json_pointer_set(&jo1, "/foo/1", json_object_new_string("cod"))); | |||
| assert(0 == strcmp("cod", json_object_get_string(json_object_array_get_idx(json_object_object_get(jo1, "foo"), 1)))); | |||
| assert(0 == strcmp("cod", json_object_get_string(json_object_array_get_idx( | |||
| json_object_object_get(jo1, "foo"), 1)))); | |||
| printf("PASSED - SET - 'cod' in /foo/1\n"); | |||
| assert(0 != json_pointer_set(&jo1, "/fud/gaw", (jo2 = json_tokener_parse("[1,2,3]")))); | |||
| assert(errno == ENOENT); | |||
| @@ -252,7 +258,9 @@ static void test_example_set() | |||
| assert(0 == json_pointer_set(&jo1, "/", json_object_new_int(9))); | |||
| printf("PASSED - SET - / == 9\n"); | |||
| jo2 = json_tokener_parse("{ 'foo': [ 'bar', 'cod' ], '': 9, 'a/b': 1, 'c%d': 2, 'e^f': 3, 'g|h': 4, 'i\\\\j': 5, 'k\\\"l': 6, ' ': 7, 'm~n': 8, 'fud': { 'gaw': [ 0, 2, 3, 4 ] } }"); | |||
| jo2 = json_tokener_parse( | |||
| "{ 'foo': [ 'bar', 'cod' ], '': 9, 'a/b': 1, 'c%d': 2, 'e^f': 3, 'g|h': 4, 'i\\\\j': " | |||
| "5, 'k\\\"l': 6, ' ': 7, 'm~n': 8, 'fud': { 'gaw': [ 0, 2, 3, 4 ] } }"); | |||
| assert(json_object_equal(jo2, jo1)); | |||
| printf("PASSED - SET - Final JSON is: %s\n", json_object_get_string(jo1)); | |||
| json_object_put(jo2); | |||
| @@ -282,7 +290,8 @@ static void test_wrong_inputs_set() | |||
| printf("PASSED - SET - failed 'cod' with path 'foo/bar'\n"); | |||
| json_object_put(jo2); | |||
| assert(0 != json_pointer_setf(&jo1, (jo2 = json_object_new_string("cod")), "%s", "foo/bar")); | |||
| assert(0 != | |||
| json_pointer_setf(&jo1, (jo2 = json_object_new_string("cod")), "%s", "foo/bar")); | |||
| printf("PASSED - SET - failed 'cod' with path 'foo/bar'\n"); | |||
| json_object_put(jo2); | |||
| @@ -1,8 +1,8 @@ | |||
| #include <assert.h> | |||
| #include <stddef.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <stddef.h> | |||
| #include <string.h> | |||
| #include <assert.h> | |||
| #include "config.h" | |||
| #include "json.h" | |||
| @@ -37,8 +37,7 @@ int main(int argc, char **argv) | |||
| (void)snprintf(buf2, sizeof(buf2), "%f", 0.1); | |||
| if (strcmp(buf1, buf2) != 0) | |||
| printf("ERROR: Original locale not restored \"%s\" != \"%s\"", | |||
| buf1, buf2); | |||
| printf("ERROR: Original locale not restored \"%s\" != \"%s\"", buf1, buf2); | |||
| #ifdef HAVE_SETLOCALE | |||
| setlocale(LC_NUMERIC, "C"); | |||
| @@ -49,16 +48,16 @@ int main(int argc, char **argv) | |||
| // string that was parsed. (see json_object_new_double_s()) | |||
| printf("new_obj.to_string()=["); | |||
| unsigned int ii; | |||
| for (ii = 0 ; ii < json_object_array_length(new_obj); ii++) | |||
| for (ii = 0; ii < json_object_array_length(new_obj); ii++) | |||
| { | |||
| json_object *val = json_object_array_get_idx(new_obj, ii); | |||
| printf("%s%.2lf", (ii > 0) ? "," : "", json_object_get_double(val)); | |||
| } | |||
| printf("]\n"); | |||
| printf("new_obj.to_string()=%s\n", json_object_to_json_string_ext(new_obj,JSON_C_TO_STRING_NOZERO)); | |||
| printf("new_obj.to_string()=%s\n", | |||
| json_object_to_json_string_ext(new_obj, JSON_C_TO_STRING_NOZERO)); | |||
| json_object_put(new_obj); | |||
| return 0; | |||
| } | |||
| @@ -2,9 +2,9 @@ | |||
| * Tests if binary strings are supported. | |||
| */ | |||
| #include "config.h" | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include "config.h" | |||
| #include "json_inttypes.h" | |||
| #include "json_object.h" | |||
| @@ -18,20 +18,22 @@ int main(void) | |||
| struct json_object *string = json_object_new_string_len(input, 3); | |||
| const char *json = json_object_to_json_string(string); | |||
| int strings_match = !strcmp( expected, json); | |||
| int strings_match = !strcmp(expected, json); | |||
| int retval = 0; | |||
| if (strings_match) | |||
| { | |||
| printf("JSON write result is correct: %s\n", json); | |||
| puts("PASS"); | |||
| } else { | |||
| } | |||
| else | |||
| { | |||
| puts("JSON write result doesn't match expected string"); | |||
| printf("expected string: "); | |||
| puts(expected); | |||
| printf("parsed string: "); | |||
| puts(json); | |||
| puts("FAIL"); | |||
| retval=1; | |||
| retval = 1; | |||
| } | |||
| json_object_put(string); | |||
| @@ -42,7 +44,7 @@ int main(void) | |||
| const char *parsed_cstr = json_object_get_string(parsed_str); | |||
| int ii; | |||
| printf("Re-parsed object string len=%d, chars=[", parsed_len); | |||
| for (ii = 0; ii < parsed_len ; ii++) | |||
| for (ii = 0; ii < parsed_len; ii++) | |||
| { | |||
| printf("%s%d", (ii ? ", " : ""), (int)parsed_cstr[ii]); | |||
| } | |||
| @@ -1,8 +1,8 @@ | |||
| #include <assert.h> | |||
| #include <stddef.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <stddef.h> | |||
| #include <string.h> | |||
| #include <assert.h> | |||
| #include "json.h" | |||
| #include "json_tokener.h" | |||
| @@ -106,7 +106,7 @@ static void test_basic_parse() | |||
| single_basic_parse("{\"FoO\" : -12.3E512}", 0); | |||
| single_basic_parse("{\"FoO\" : -12.3e512}", 0); | |||
| single_basic_parse("{\"FoO\" : -12.3E51.2}", 0); /* non-sensical, returns null */ | |||
| single_basic_parse("{\"FoO\" : -12.3E51.2}", 0); /* non-sensical, returns null */ | |||
| single_basic_parse("{\"FoO\" : -12.3E512E12}", 0); /* non-sensical, returns null */ | |||
| single_basic_parse("[\"\\n\"]", 0); | |||
| single_basic_parse("[\"\\nabc\\n\"]", 0); | |||
| @@ -119,7 +119,9 @@ static void test_basic_parse() | |||
| single_basic_parse("{ \'foo\': \'bar\' }", 0); | |||
| single_basic_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }", 0); | |||
| single_basic_parse("{ \"foo\": [null, \"foo\"] }", 0); | |||
| single_basic_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }", 0); | |||
| single_basic_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, " | |||
| "\"arr\": [ 1, 2, 3, null, 5 ] }", | |||
| 0); | |||
| single_basic_parse("{ \"abc\": \"blue\nred\\ngreen\" }", 0); | |||
| // Clear serializer for these tests so we see the actual parsed value. | |||
| @@ -130,7 +132,7 @@ static void test_basic_parse() | |||
| single_basic_parse("[0e+-1]", 1); | |||
| single_basic_parse("\"hello world!\"", 1); | |||
| // uint64/int64 range test | |||
| // uint64/int64 range test | |||
| single_basic_parse("[9223372036854775806]", 1); | |||
| single_basic_parse("[9223372036854775807]", 1); | |||
| single_basic_parse("[9223372036854775808]", 1); | |||
| @@ -147,8 +149,8 @@ static void test_utf8_parse() | |||
| // json_tokener_parse doesn't support checking for byte order marks. | |||
| // It's the responsibility of the caller to detect and skip a BOM. | |||
| // Both of these checks return null. | |||
| char utf8_bom[] = { 0xEF, 0xBB, 0xBF, 0x00 }; | |||
| char utf8_bom_and_chars[] = { 0xEF, 0xBB, 0xBF, '{', '}', 0x00 }; | |||
| char utf8_bom[] = {0xEF, 0xBB, 0xBF, 0x00}; | |||
| char utf8_bom_and_chars[] = {0xEF, 0xBB, 0xBF, '{', '}', 0x00}; | |||
| single_basic_parse(utf8_bom, 0); | |||
| single_basic_parse(utf8_bom_and_chars, 0); | |||
| } | |||
| @@ -161,10 +163,8 @@ static void do_clear_serializer(json_object *jso) | |||
| json_c_visit(jso, 0, clear_serializer, NULL); | |||
| } | |||
| static int clear_serializer(json_object *jso, int flags, | |||
| json_object *parent_jso, | |||
| const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| static int clear_serializer(json_object *jso, int flags, json_object *parent_jso, | |||
| const char *jso_key, size_t *jso_index, void *userarg) | |||
| { | |||
| if (jso) | |||
| json_object_set_serializer(jso, NULL, NULL, NULL); | |||
| @@ -177,24 +177,25 @@ static void test_verbose_parse() | |||
| enum json_tokener_error error = json_tokener_success; | |||
| new_obj = json_tokener_parse_verbose("{ foo }", &error); | |||
| assert (error == json_tokener_error_parse_object_key_name); | |||
| assert (new_obj == NULL); | |||
| assert(error == json_tokener_error_parse_object_key_name); | |||
| assert(new_obj == NULL); | |||
| new_obj = json_tokener_parse("{ foo }"); | |||
| assert (new_obj == NULL); | |||
| assert(new_obj == NULL); | |||
| new_obj = json_tokener_parse("foo"); | |||
| assert (new_obj == NULL); | |||
| assert(new_obj == NULL); | |||
| new_obj = json_tokener_parse_verbose("foo", &error); | |||
| assert (new_obj == NULL); | |||
| assert(new_obj == NULL); | |||
| /* b/c the string starts with 'f' parsing return a boolean error */ | |||
| assert (error == json_tokener_error_parse_boolean); | |||
| assert(error == json_tokener_error_parse_boolean); | |||
| puts("json_tokener_parse_verbose() OK"); | |||
| } | |||
| struct incremental_step { | |||
| struct incremental_step | |||
| { | |||
| const char *string_to_parse; | |||
| int length; | |||
| int char_offset; | |||
| @@ -202,203 +203,205 @@ struct incremental_step { | |||
| int reset_tokener; | |||
| } incremental_steps[] = { | |||
| /* Check that full json messages can be parsed, both w/ and w/o a reset */ | |||
| { "{ \"foo\": 123 }", -1, -1, json_tokener_success, 0 }, | |||
| { "{ \"foo\": 456 }", -1, -1, json_tokener_success, 1 }, | |||
| { "{ \"foo\": 789 }", -1, -1, json_tokener_success, 1 }, | |||
| /* Check the comment parse*/ | |||
| { "/* hello */{ \"foo\"", -1, -1, json_tokener_continue, 0 }, | |||
| { "/* hello */:/* hello */", -1, -1, json_tokener_continue, 0 }, | |||
| { "\"bar\"/* hello */", -1, -1, json_tokener_continue, 0 }, | |||
| { "}/* hello */", -1, -1, json_tokener_success, 1 }, | |||
| { "/ hello ", -1, 1, json_tokener_error_parse_comment, 1 }, | |||
| { "/* hello\"foo\"", -1, -1, json_tokener_continue, 1 }, | |||
| { "/* hello*\"foo\"", -1, -1, json_tokener_continue, 1 }, | |||
| { "// hello\"foo\"", -1, -1, json_tokener_continue, 1 }, | |||
| /* Check a basic incremental parse */ | |||
| { "{ \"foo", -1, -1, json_tokener_continue, 0 }, | |||
| { "\": {\"bar", -1, -1, json_tokener_continue, 0 }, | |||
| { "\":13}}", -1, -1, json_tokener_success, 1 }, | |||
| /* Check that json_tokener_reset actually resets */ | |||
| { "{ \"foo", -1, -1, json_tokener_continue, 1 }, | |||
| { ": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1 }, | |||
| /* Check incremental parsing with trailing characters */ | |||
| { "{ \"foo", -1, -1, json_tokener_continue, 0 }, | |||
| { "\": {\"bar", -1, -1, json_tokener_continue, 0 }, | |||
| { "\":13}}XXXX", 10, 6, json_tokener_success, 0 }, | |||
| { "XXXX", 4, 0, json_tokener_error_parse_unexpected, 1 }, | |||
| /* Check that trailing characters can change w/o a reset */ | |||
| { "{\"x\": 123 }\"X\"", -1, 11, json_tokener_success, 0 }, | |||
| { "\"Y\"", -1, -1, json_tokener_success, 1 }, | |||
| /* To stop parsing a number we need to reach a non-digit, e.g. a \0 */ | |||
| { "1", 1, 1, json_tokener_continue, 0 }, | |||
| /* This should parse as the number 12, since it continues the "1" */ | |||
| { "2", 2, 1, json_tokener_success, 0 }, | |||
| { "12{", 3, 2, json_tokener_success, 1 }, | |||
| /* Parse number in strict model */ | |||
| { "[02]", -1, 3, json_tokener_error_parse_number, 3 }, | |||
| /* Similar tests for other kinds of objects: */ | |||
| /* These could all return success immediately, since regardless of | |||
| /* Check that full json messages can be parsed, both w/ and w/o a reset */ | |||
| {"{ \"foo\": 123 }", -1, -1, json_tokener_success, 0}, | |||
| {"{ \"foo\": 456 }", -1, -1, json_tokener_success, 1}, | |||
| {"{ \"foo\": 789 }", -1, -1, json_tokener_success, 1}, | |||
| /* Check the comment parse*/ | |||
| {"/* hello */{ \"foo\"", -1, -1, json_tokener_continue, 0}, | |||
| {"/* hello */:/* hello */", -1, -1, json_tokener_continue, 0}, | |||
| {"\"bar\"/* hello */", -1, -1, json_tokener_continue, 0}, | |||
| {"}/* hello */", -1, -1, json_tokener_success, 1}, | |||
| {"/ hello ", -1, 1, json_tokener_error_parse_comment, 1}, | |||
| {"/* hello\"foo\"", -1, -1, json_tokener_continue, 1}, | |||
| {"/* hello*\"foo\"", -1, -1, json_tokener_continue, 1}, | |||
| {"// hello\"foo\"", -1, -1, json_tokener_continue, 1}, | |||
| /* Check a basic incremental parse */ | |||
| {"{ \"foo", -1, -1, json_tokener_continue, 0}, | |||
| {"\": {\"bar", -1, -1, json_tokener_continue, 0}, | |||
| {"\":13}}", -1, -1, json_tokener_success, 1}, | |||
| /* Check that json_tokener_reset actually resets */ | |||
| {"{ \"foo", -1, -1, json_tokener_continue, 1}, | |||
| {": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1}, | |||
| /* Check incremental parsing with trailing characters */ | |||
| {"{ \"foo", -1, -1, json_tokener_continue, 0}, | |||
| {"\": {\"bar", -1, -1, json_tokener_continue, 0}, | |||
| {"\":13}}XXXX", 10, 6, json_tokener_success, 0}, | |||
| {"XXXX", 4, 0, json_tokener_error_parse_unexpected, 1}, | |||
| /* Check that trailing characters can change w/o a reset */ | |||
| {"{\"x\": 123 }\"X\"", -1, 11, json_tokener_success, 0}, | |||
| {"\"Y\"", -1, -1, json_tokener_success, 1}, | |||
| /* To stop parsing a number we need to reach a non-digit, e.g. a \0 */ | |||
| {"1", 1, 1, json_tokener_continue, 0}, | |||
| /* This should parse as the number 12, since it continues the "1" */ | |||
| {"2", 2, 1, json_tokener_success, 0}, | |||
| {"12{", 3, 2, json_tokener_success, 1}, | |||
| /* Parse number in strict model */ | |||
| {"[02]", -1, 3, json_tokener_error_parse_number, 3}, | |||
| /* Similar tests for other kinds of objects: */ | |||
| /* These could all return success immediately, since regardless of | |||
| what follows the false/true/null token we *will* return a json object, | |||
| but it currently doesn't work that way. hmm... */ | |||
| { "false", 5, 5, json_tokener_continue, 1 }, | |||
| { "false", 6, 5, json_tokener_success, 1 }, | |||
| { "true", 4, 4, json_tokener_continue, 1 }, | |||
| { "true", 5, 4, json_tokener_success, 1 }, | |||
| { "null", 4, 4, json_tokener_continue, 1 }, | |||
| { "null", 5, 4, json_tokener_success, 1 }, | |||
| { "Infinity", 9, 8, json_tokener_success, 1 }, | |||
| { "infinity", 9, 8, json_tokener_success, 1 }, | |||
| { "-infinity", 10, 9, json_tokener_success, 1 }, | |||
| { "infinity", 9, 0, json_tokener_error_parse_unexpected, 3 }, | |||
| { "-infinity", 10, 1, json_tokener_error_parse_unexpected, 3 }, | |||
| { "inf", 3, 3, json_tokener_continue, 0 }, | |||
| { "inity", 6, 5, json_tokener_success, 1 }, | |||
| { "-inf", 4, 4, json_tokener_continue, 0 }, | |||
| { "inity", 6, 5, json_tokener_success, 1 }, | |||
| { "i", 1, 1, json_tokener_continue, 0 }, | |||
| { "n", 1, 1, json_tokener_continue, 0 }, | |||
| { "f", 1, 1, json_tokener_continue, 0 }, | |||
| { "i", 1, 1, json_tokener_continue, 0 }, | |||
| { "n", 1, 1, json_tokener_continue, 0 }, | |||
| { "i", 1, 1, json_tokener_continue, 0 }, | |||
| { "t", 1, 1, json_tokener_continue, 0 }, | |||
| { "y", 1, 1, json_tokener_continue, 0 }, | |||
| { "", 1, 0, json_tokener_success, 1 }, | |||
| { "-", 1, 1, json_tokener_continue, 0 }, | |||
| { "inf", 3, 3, json_tokener_continue, 0 }, | |||
| { "ini", 3, 3, json_tokener_continue, 0 }, | |||
| { "ty", 3, 2, json_tokener_success, 1 }, | |||
| { "-", 1, 1, json_tokener_continue, 0 }, | |||
| { "i", 1, 1, json_tokener_continue, 0 }, | |||
| { "nfini", 5, 5, json_tokener_continue, 0 }, | |||
| { "ty", 3, 2, json_tokener_success, 1 }, | |||
| { "-i", 2, 2, json_tokener_continue, 0 }, | |||
| { "nfinity", 8, 7, json_tokener_success, 1 }, | |||
| { "InfinityX", 10, 8, json_tokener_success, 0 }, | |||
| { "X", 1, 0, json_tokener_error_parse_unexpected, 1 }, | |||
| { "Infinity1234", 13, 8, json_tokener_success, 0 }, | |||
| { "1234", 5, 4, json_tokener_success, 1 }, | |||
| { "Infinity9999", 8, 8, json_tokener_continue, 0 }, | |||
| /* returns the Infinity loaded up by the previous call: */ | |||
| { "1234", 5, 0, json_tokener_success, 0 }, | |||
| { "1234", 5, 4, json_tokener_success, 1 }, | |||
| /* offset=1 because "n" is the start of "null". hmm... */ | |||
| { "noodle", 7, 1, json_tokener_error_parse_null, 1 }, | |||
| /* offset=2 because "na" is the start of "nan". hmm... */ | |||
| { "naodle", 7, 2, json_tokener_error_parse_null, 1 }, | |||
| /* offset=2 because "tr" is the start of "true". hmm... */ | |||
| { "track", 6, 2, json_tokener_error_parse_boolean, 1 }, | |||
| { "fail", 5, 2, json_tokener_error_parse_boolean, 1 }, | |||
| /* Although they may initially look like they should fail, | |||
| the next few tests check that parsing multiple sequential | |||
| json objects in the input works as expected */ | |||
| { "null123", 9, 4, json_tokener_success, 0 }, | |||
| { &"null123"[4], 4, 3, json_tokener_success, 1 }, | |||
| { "nullx", 5, 4, json_tokener_success, 0 }, | |||
| { &"nullx"[4], 2, 0, json_tokener_error_parse_unexpected, 1 }, | |||
| { "{\"a\":1}{\"b\":2}",15, 7, json_tokener_success, 0 }, | |||
| { &"{\"a\":1}{\"b\":2}"[7], | |||
| 8, 7, json_tokener_success, 1 }, | |||
| /* Some bad formatting. Check we get the correct error status */ | |||
| { "2015-01-15", 10, 4, json_tokener_error_parse_number, 1 }, | |||
| /* Strings have a well defined end point, so we can stop at the quote */ | |||
| { "\"blue\"", -1, -1, json_tokener_success, 0 }, | |||
| /* Check each of the escape sequences defined by the spec */ | |||
| { "\"\\\"\"", -1, -1, json_tokener_success, 0 }, | |||
| { "\"\\\\\"", -1, -1, json_tokener_success, 0 }, | |||
| { "\"\\b\"", -1, -1, json_tokener_success, 0 }, | |||
| { "\"\\f\"", -1, -1, json_tokener_success, 0 }, | |||
| { "\"\\n\"", -1, -1, json_tokener_success, 0 }, | |||
| { "\"\\r\"", -1, -1, json_tokener_success, 0 }, | |||
| { "\"\\t\"", -1, -1, json_tokener_success, 0 }, | |||
| { "\"\\/\"", -1, -1, json_tokener_success, 0 }, | |||
| // Escaping a forward slash is optional | |||
| { "\"/\"", -1, -1, json_tokener_success, 0 }, | |||
| /* Check wrong escape sequences */ | |||
| { "\"\\a\"", -1, 2, json_tokener_error_parse_string, 1 }, | |||
| /* Check '\'' in strict model */ | |||
| { "\'foo\'", -1, 0, json_tokener_error_parse_unexpected, 3 }, | |||
| /* Parse array/object */ | |||
| { "[1,2,3]", -1, -1, json_tokener_success, 0 }, | |||
| { "[1,2,3}", -1, 6, json_tokener_error_parse_array, 1 }, | |||
| { "{\"a\"}", -1, 4, json_tokener_error_parse_object_key_sep, 1 }, | |||
| { "{\"a\":1]", -1, 6, json_tokener_error_parse_object_value_sep, 1 }, | |||
| { "{\"a\"::1}", -1, 5, json_tokener_error_parse_unexpected, 1 }, | |||
| { "{\"a\":}", -1, 5, json_tokener_error_parse_unexpected, 1 }, | |||
| { "{\"a\":1,\"a\":2}",-1, -1, json_tokener_success, 1 }, | |||
| { "\"a\":1}", -1, 3, json_tokener_success, 1 }, | |||
| { "{\"a\":1", -1, -1, json_tokener_continue, 1 }, | |||
| { "[,]", -1, 1, json_tokener_error_parse_unexpected, 1 }, | |||
| { "[,1]", -1, 1, json_tokener_error_parse_unexpected, 1 }, | |||
| /* This behaviour doesn't entirely follow the json spec, but until we have | |||
| a way to specify how strict to be we follow Postel's Law and be liberal | |||
| in what we accept (up to a point). */ | |||
| { "[1,2,3,]", -1, -1, json_tokener_success, 0 }, | |||
| { "[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0 }, | |||
| { "[1,2,3,]", -1, 7, json_tokener_error_parse_unexpected, 3 }, | |||
| { "{\"a\":1,}", -1, 7, json_tokener_error_parse_unexpected, 3 }, | |||
| // utf-8 test | |||
| // acsll encoding | |||
| { "\x22\x31\x32\x33\x61\x73\x63\x24\x25\x26\x22",-1, -1, json_tokener_success, 5 }, | |||
| { "\x22\x31\x32\x33\x61\x73\x63\x24\x25\x26\x22",-1, -1, json_tokener_success, 1 }, | |||
| // utf-8 encoding | |||
| { "\x22\xe4\xb8\x96\xe7\x95\x8c\x22",-1, -1, json_tokener_success, 5 }, | |||
| { "\x22\xe4\xb8",-1, 3, json_tokener_error_parse_utf8_string, 4 }, | |||
| { "\x96\xe7\x95\x8c\x22",-1, 0, json_tokener_error_parse_utf8_string, 5 }, | |||
| { "\x22\xe4\xb8\x96\xe7\x95\x8c\x22",-1, -1, json_tokener_success, 1 }, | |||
| { "\x22\xcf\x80\xcf\x86\x22",-1, -1, json_tokener_success, 5 }, | |||
| { "\x22\xf0\xa5\x91\x95\x22",-1, -1, json_tokener_success, 5 }, | |||
| // wrong utf-8 encoding | |||
| { "\x22\xe6\x9d\x4e\x22",-1, 3, json_tokener_error_parse_utf8_string, 5 }, | |||
| { "\x22\xe6\x9d\x4e\x22",-1, 5, json_tokener_success, 1 }, | |||
| // GBK encoding | |||
| { "\x22\xc0\xee\xc5\xf4\x22",-1, 2, json_tokener_error_parse_utf8_string, 5 }, | |||
| { "\x22\xc0\xee\xc5\xf4\x22",-1, 6, json_tokener_success, 1 }, | |||
| // char after space | |||
| { "\x20\x20\x22\xe4\xb8\x96\x22",-1, -1, json_tokener_success, 5 }, | |||
| { "\x20\x20\x81\x22\xe4\xb8\x96\x22",-1, 2, json_tokener_error_parse_utf8_string, 5 }, | |||
| { "\x5b\x20\x81\x31\x5d",-1, 2, json_tokener_error_parse_utf8_string, 5 }, | |||
| // char in state inf | |||
| { "\x49\x6e\x66\x69\x6e\x69\x74\x79",9, 8, json_tokener_success, 1 }, | |||
| { "\x49\x6e\x66\x81\x6e\x69\x74\x79",-1, 3, json_tokener_error_parse_utf8_string, 5 }, | |||
| // char in escape unicode | |||
| { "\x22\x5c\x75\x64\x38\x35\x35\x5c\x75\x64\x63\x35\x35\x22",15, 14, json_tokener_success, 5 }, | |||
| { "\x22\x5c\x75\x64\x38\x35\x35\xc0\x75\x64\x63\x35\x35\x22",-1, 8, json_tokener_error_parse_utf8_string, 5 }, | |||
| { "\x22\x5c\x75\x64\x30\x30\x33\x31\xc0\x22",-1, 9, json_tokener_error_parse_utf8_string, 5 }, | |||
| // char in number | |||
| { "\x31\x31\x81\x31\x31",-1, 2, json_tokener_error_parse_utf8_string, 5 }, | |||
| // char in object | |||
| { "\x7b\x22\x31\x81\x22\x3a\x31\x7d",-1, 3, json_tokener_error_parse_utf8_string, 5 }, | |||
| { NULL, -1, -1, json_tokener_success, 0 }, | |||
| {"false", 5, 5, json_tokener_continue, 1}, | |||
| {"false", 6, 5, json_tokener_success, 1}, | |||
| {"true", 4, 4, json_tokener_continue, 1}, | |||
| {"true", 5, 4, json_tokener_success, 1}, | |||
| {"null", 4, 4, json_tokener_continue, 1}, | |||
| {"null", 5, 4, json_tokener_success, 1}, | |||
| {"Infinity", 9, 8, json_tokener_success, 1}, | |||
| {"infinity", 9, 8, json_tokener_success, 1}, | |||
| {"-infinity", 10, 9, json_tokener_success, 1}, | |||
| {"infinity", 9, 0, json_tokener_error_parse_unexpected, 3}, | |||
| {"-infinity", 10, 1, json_tokener_error_parse_unexpected, 3}, | |||
| {"inf", 3, 3, json_tokener_continue, 0}, | |||
| {"inity", 6, 5, json_tokener_success, 1}, | |||
| {"-inf", 4, 4, json_tokener_continue, 0}, | |||
| {"inity", 6, 5, json_tokener_success, 1}, | |||
| {"i", 1, 1, json_tokener_continue, 0}, | |||
| {"n", 1, 1, json_tokener_continue, 0}, | |||
| {"f", 1, 1, json_tokener_continue, 0}, | |||
| {"i", 1, 1, json_tokener_continue, 0}, | |||
| {"n", 1, 1, json_tokener_continue, 0}, | |||
| {"i", 1, 1, json_tokener_continue, 0}, | |||
| {"t", 1, 1, json_tokener_continue, 0}, | |||
| {"y", 1, 1, json_tokener_continue, 0}, | |||
| {"", 1, 0, json_tokener_success, 1}, | |||
| {"-", 1, 1, json_tokener_continue, 0}, | |||
| {"inf", 3, 3, json_tokener_continue, 0}, | |||
| {"ini", 3, 3, json_tokener_continue, 0}, | |||
| {"ty", 3, 2, json_tokener_success, 1}, | |||
| {"-", 1, 1, json_tokener_continue, 0}, | |||
| {"i", 1, 1, json_tokener_continue, 0}, | |||
| {"nfini", 5, 5, json_tokener_continue, 0}, | |||
| {"ty", 3, 2, json_tokener_success, 1}, | |||
| {"-i", 2, 2, json_tokener_continue, 0}, | |||
| {"nfinity", 8, 7, json_tokener_success, 1}, | |||
| {"InfinityX", 10, 8, json_tokener_success, 0}, | |||
| {"X", 1, 0, json_tokener_error_parse_unexpected, 1}, | |||
| {"Infinity1234", 13, 8, json_tokener_success, 0}, | |||
| {"1234", 5, 4, json_tokener_success, 1}, | |||
| {"Infinity9999", 8, 8, json_tokener_continue, 0}, | |||
| /* returns the Infinity loaded up by the previous call: */ | |||
| {"1234", 5, 0, json_tokener_success, 0}, | |||
| {"1234", 5, 4, json_tokener_success, 1}, | |||
| /* offset=1 because "n" is the start of "null". hmm... */ | |||
| {"noodle", 7, 1, json_tokener_error_parse_null, 1}, | |||
| /* offset=2 because "na" is the start of "nan". hmm... */ | |||
| {"naodle", 7, 2, json_tokener_error_parse_null, 1}, | |||
| /* offset=2 because "tr" is the start of "true". hmm... */ | |||
| {"track", 6, 2, json_tokener_error_parse_boolean, 1}, | |||
| {"fail", 5, 2, json_tokener_error_parse_boolean, 1}, | |||
| /* Although they may initially look like they should fail, | |||
| * the next few tests check that parsing multiple sequential | |||
| * json objects in the input works as expected | |||
| */ | |||
| {"null123", 9, 4, json_tokener_success, 0}, | |||
| {&"null123"[4], 4, 3, json_tokener_success, 1}, | |||
| {"nullx", 5, 4, json_tokener_success, 0}, | |||
| {&"nullx"[4], 2, 0, json_tokener_error_parse_unexpected, 1}, | |||
| {"{\"a\":1}{\"b\":2}", 15, 7, json_tokener_success, 0}, | |||
| {&"{\"a\":1}{\"b\":2}"[7], 8, 7, json_tokener_success, 1}, | |||
| /* Some bad formatting. Check we get the correct error status */ | |||
| {"2015-01-15", 10, 4, json_tokener_error_parse_number, 1}, | |||
| /* Strings have a well defined end point, so we can stop at the quote */ | |||
| {"\"blue\"", -1, -1, json_tokener_success, 0}, | |||
| /* Check each of the escape sequences defined by the spec */ | |||
| {"\"\\\"\"", -1, -1, json_tokener_success, 0}, | |||
| {"\"\\\\\"", -1, -1, json_tokener_success, 0}, | |||
| {"\"\\b\"", -1, -1, json_tokener_success, 0}, | |||
| {"\"\\f\"", -1, -1, json_tokener_success, 0}, | |||
| {"\"\\n\"", -1, -1, json_tokener_success, 0}, | |||
| {"\"\\r\"", -1, -1, json_tokener_success, 0}, | |||
| {"\"\\t\"", -1, -1, json_tokener_success, 0}, | |||
| {"\"\\/\"", -1, -1, json_tokener_success, 0}, | |||
| // Escaping a forward slash is optional | |||
| {"\"/\"", -1, -1, json_tokener_success, 0}, | |||
| /* Check wrong escape sequences */ | |||
| {"\"\\a\"", -1, 2, json_tokener_error_parse_string, 1}, | |||
| /* Check '\'' in strict model */ | |||
| {"\'foo\'", -1, 0, json_tokener_error_parse_unexpected, 3}, | |||
| /* Parse array/object */ | |||
| {"[1,2,3]", -1, -1, json_tokener_success, 0}, | |||
| {"[1,2,3}", -1, 6, json_tokener_error_parse_array, 1}, | |||
| {"{\"a\"}", -1, 4, json_tokener_error_parse_object_key_sep, 1}, | |||
| {"{\"a\":1]", -1, 6, json_tokener_error_parse_object_value_sep, 1}, | |||
| {"{\"a\"::1}", -1, 5, json_tokener_error_parse_unexpected, 1}, | |||
| {"{\"a\":}", -1, 5, json_tokener_error_parse_unexpected, 1}, | |||
| {"{\"a\":1,\"a\":2}", -1, -1, json_tokener_success, 1}, | |||
| {"\"a\":1}", -1, 3, json_tokener_success, 1}, | |||
| {"{\"a\":1", -1, -1, json_tokener_continue, 1}, | |||
| {"[,]", -1, 1, json_tokener_error_parse_unexpected, 1}, | |||
| {"[,1]", -1, 1, json_tokener_error_parse_unexpected, 1}, | |||
| /* This behaviour doesn't entirely follow the json spec, but until we have | |||
| * a way to specify how strict to be we follow Postel's Law and be liberal | |||
| * in what we accept (up to a point). | |||
| */ | |||
| {"[1,2,3,]", -1, -1, json_tokener_success, 0}, | |||
| {"[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0}, | |||
| {"[1,2,3,]", -1, 7, json_tokener_error_parse_unexpected, 3}, | |||
| {"{\"a\":1,}", -1, 7, json_tokener_error_parse_unexpected, 3}, | |||
| // utf-8 test | |||
| // acsll encoding | |||
| {"\x22\x31\x32\x33\x61\x73\x63\x24\x25\x26\x22", -1, -1, json_tokener_success, 5}, | |||
| {"\x22\x31\x32\x33\x61\x73\x63\x24\x25\x26\x22", -1, -1, json_tokener_success, 1}, | |||
| // utf-8 encoding | |||
| {"\x22\xe4\xb8\x96\xe7\x95\x8c\x22", -1, -1, json_tokener_success, 5}, | |||
| {"\x22\xe4\xb8", -1, 3, json_tokener_error_parse_utf8_string, 4}, | |||
| {"\x96\xe7\x95\x8c\x22", -1, 0, json_tokener_error_parse_utf8_string, 5}, | |||
| {"\x22\xe4\xb8\x96\xe7\x95\x8c\x22", -1, -1, json_tokener_success, 1}, | |||
| {"\x22\xcf\x80\xcf\x86\x22", -1, -1, json_tokener_success, 5}, | |||
| {"\x22\xf0\xa5\x91\x95\x22", -1, -1, json_tokener_success, 5}, | |||
| // wrong utf-8 encoding | |||
| {"\x22\xe6\x9d\x4e\x22", -1, 3, json_tokener_error_parse_utf8_string, 5}, | |||
| {"\x22\xe6\x9d\x4e\x22", -1, 5, json_tokener_success, 1}, | |||
| // GBK encoding | |||
| {"\x22\xc0\xee\xc5\xf4\x22", -1, 2, json_tokener_error_parse_utf8_string, 5}, | |||
| {"\x22\xc0\xee\xc5\xf4\x22", -1, 6, json_tokener_success, 1}, | |||
| // char after space | |||
| {"\x20\x20\x22\xe4\xb8\x96\x22", -1, -1, json_tokener_success, 5}, | |||
| {"\x20\x20\x81\x22\xe4\xb8\x96\x22", -1, 2, json_tokener_error_parse_utf8_string, 5}, | |||
| {"\x5b\x20\x81\x31\x5d", -1, 2, json_tokener_error_parse_utf8_string, 5}, | |||
| // char in state inf | |||
| {"\x49\x6e\x66\x69\x6e\x69\x74\x79", 9, 8, json_tokener_success, 1}, | |||
| {"\x49\x6e\x66\x81\x6e\x69\x74\x79", -1, 3, json_tokener_error_parse_utf8_string, 5}, | |||
| // char in escape unicode | |||
| {"\x22\x5c\x75\x64\x38\x35\x35\x5c\x75\x64\x63\x35\x35\x22", 15, 14, json_tokener_success, 5}, | |||
| {"\x22\x5c\x75\x64\x38\x35\x35\xc0\x75\x64\x63\x35\x35\x22", -1, 8, | |||
| json_tokener_error_parse_utf8_string, 5}, | |||
| {"\x22\x5c\x75\x64\x30\x30\x33\x31\xc0\x22", -1, 9, json_tokener_error_parse_utf8_string, 5}, | |||
| // char in number | |||
| {"\x31\x31\x81\x31\x31", -1, 2, json_tokener_error_parse_utf8_string, 5}, | |||
| // char in object | |||
| {"\x7b\x22\x31\x81\x22\x3a\x31\x7d", -1, 3, json_tokener_error_parse_utf8_string, 5}, | |||
| {NULL, -1, -1, json_tokener_success, 0}, | |||
| }; | |||
| static void test_incremental_parse() | |||
| @@ -420,7 +423,8 @@ static void test_incremental_parse() | |||
| string_to_parse = "{ \"foo"; /* } */ | |||
| printf("json_tokener_parse(%s) ... ", string_to_parse); | |||
| new_obj = json_tokener_parse(string_to_parse); | |||
| if (new_obj == NULL) puts("got error as expected"); | |||
| if (new_obj == NULL) | |||
| puts("got error as expected"); | |||
| /* test incremental parsing in various forms */ | |||
| tok = json_tokener_new(); | |||
| @@ -432,19 +436,19 @@ static void test_incremental_parse() | |||
| size_t expected_char_offset; | |||
| if (step->reset_tokener & 2) | |||
| { | |||
| if (step->reset_tokener & 4) | |||
| json_tokener_set_flags(tok, 3); | |||
| else | |||
| json_tokener_set_flags(tok, JSON_TOKENER_STRICT); | |||
| } | |||
| { | |||
| if (step->reset_tokener & 4) | |||
| json_tokener_set_flags(tok, 3); | |||
| else | |||
| json_tokener_set_flags(tok, JSON_TOKENER_STRICT); | |||
| } | |||
| else | |||
| { | |||
| if (step->reset_tokener & 4) | |||
| json_tokener_set_flags(tok, JSON_TOKENER_VALIDATE_UTF8); | |||
| else | |||
| json_tokener_set_flags(tok, 0); | |||
| } | |||
| { | |||
| if (step->reset_tokener & 4) | |||
| json_tokener_set_flags(tok, JSON_TOKENER_VALIDATE_UTF8); | |||
| else | |||
| json_tokener_set_flags(tok, 0); | |||
| } | |||
| if (length == -1) | |||
| length = strlen(step->string_to_parse); | |||
| @@ -453,8 +457,8 @@ static void test_incremental_parse() | |||
| else | |||
| expected_char_offset = step->char_offset; | |||
| printf("json_tokener_parse_ex(tok, %-12s, %3d) ... ", | |||
| step->string_to_parse, length); | |||
| printf("json_tokener_parse_ex(tok, %-12s, %3d) ... ", step->string_to_parse, | |||
| length); | |||
| new_obj = json_tokener_parse_ex(tok, step->string_to_parse, length); | |||
| jerr = json_tokener_get_error(tok); | |||
| @@ -468,8 +472,7 @@ static void test_incremental_parse() | |||
| json_tokener_error_desc(jerr)); | |||
| else if (json_tokener_get_parse_end(tok) != expected_char_offset) | |||
| printf("ERROR: wrong char_offset %zu != expected %zu\n", | |||
| json_tokener_get_parse_end(tok), | |||
| expected_char_offset); | |||
| json_tokener_get_parse_end(tok), expected_char_offset); | |||
| else | |||
| { | |||
| printf("OK: got correct error: %s\n", | |||
| @@ -480,19 +483,17 @@ static void test_incremental_parse() | |||
| else | |||
| { | |||
| if (new_obj == NULL && | |||
| !(step->length >= 4 && | |||
| strncmp(step->string_to_parse, "null", 4) == 0)) | |||
| !(step->length >= 4 && strncmp(step->string_to_parse, "null", 4) == 0)) | |||
| printf("ERROR: expected valid object, instead: %s\n", | |||
| json_tokener_error_desc(jerr)); | |||
| else if (json_tokener_get_parse_end(tok) != expected_char_offset) | |||
| printf("ERROR: wrong char_offset %zu != expected %zu\n", | |||
| json_tokener_get_parse_end(tok), | |||
| expected_char_offset); | |||
| json_tokener_get_parse_end(tok), expected_char_offset); | |||
| else | |||
| { | |||
| printf("OK: got object of type [%s]: %s\n", | |||
| json_type_to_name(json_object_get_type(new_obj)), | |||
| json_object_to_json_string(new_obj)); | |||
| json_type_to_name(json_object_get_type(new_obj)), | |||
| json_object_to_json_string(new_obj)); | |||
| this_step_ok = 1; | |||
| } | |||
| } | |||
| @@ -35,7 +35,7 @@ int main() | |||
| { | |||
| char buf[100]; | |||
| printf("==========json_parse_int64() test===========\n"); | |||
| printf("==========json_parse_int64() test===========\n"); | |||
| checkit("x"); | |||
| checkit("0"); | |||
| @@ -70,7 +70,7 @@ int main() | |||
| strcpy(buf, "4294967295"); // aka UINT32_MAX | |||
| checkit(buf); | |||
| strcpy(buf, "4294967296"); // aka UINT32_MAX + 1 | |||
| strcpy(buf, "4294967296"); // aka UINT32_MAX + 1 | |||
| checkit(buf); | |||
| strcpy(buf, "21474836470"); // INT32_MAX * 10 | |||
| @@ -122,7 +122,7 @@ int main() | |||
| strcpy(buf, "123"); | |||
| checkit(buf); | |||
| printf("\n==========json_parse_uint64() test===========\n"); | |||
| printf("\n==========json_parse_uint64() test===========\n"); | |||
| checkit_uint("x"); | |||
| checkit_uint("0"); | |||
| @@ -154,7 +154,7 @@ int main() | |||
| strcpy(buf, "4294967295"); // aka UINT32_MAX | |||
| checkit_uint(buf); | |||
| strcpy(buf, "4294967296"); // aka UINT32_MAX + 1 | |||
| strcpy(buf, "4294967296"); // aka UINT32_MAX + 1 | |||
| checkit_uint(buf); | |||
| strcpy(buf, "21474836470"); // INT32_MAX * 10 | |||
| @@ -1,9 +1,9 @@ | |||
| #include <assert.h> | |||
| #include <limits.h> | |||
| #include <stddef.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <limits.h> | |||
| #include "debug.h" | |||
| #include "printbuf.h" | |||
| @@ -78,7 +78,7 @@ static void test_printbuf_memappend(int *before_resize) | |||
| initial_size = pb->size; | |||
| while(pb->size == initial_size) | |||
| while (pb->size == initial_size) | |||
| { | |||
| printbuf_memappend_fast(pb, "x", 1); | |||
| } | |||
| @@ -89,7 +89,7 @@ static void test_printbuf_memappend(int *before_resize) | |||
| printbuf_memappend_fast(pb, "bluexyz123", 3); | |||
| printf("Partial append: %d, [%s]\n", printbuf_length(pb), pb->buf); | |||
| char with_nulls[] = { 'a', 'b', '\0', 'c' }; | |||
| char with_nulls[] = {'a', 'b', '\0', 'c'}; | |||
| printbuf_reset(pb); | |||
| printbuf_memappend_fast(pb, with_nulls, (int)sizeof(with_nulls)); | |||
| printf("With embedded \\0 character: %d, [%s]\n", printbuf_length(pb), pb->buf); | |||
| @@ -118,7 +118,7 @@ static void test_printbuf_memappend(int *before_resize) | |||
| printbuf_strappend(pb, SA_TEST_STR); | |||
| printf("Buffer size after printbuf_strappend(): %d, [%s]\n", printbuf_length(pb), pb->buf); | |||
| printbuf_free(pb); | |||
| #undef SA_TEST_STR | |||
| #undef SA_TEST_STR | |||
| printf("%s: end test\n", __func__); | |||
| } | |||
| @@ -127,10 +127,11 @@ static void test_sprintbuf(int before_resize); | |||
| static void test_sprintbuf(int before_resize) | |||
| { | |||
| struct printbuf *pb; | |||
| const char *max_char = "if string is greater than stack buffer, then use dynamic string" | |||
| " with vasprintf. Note: some implementation of vsnprintf return -1 " | |||
| " if output is truncated whereas some return the number of bytes that " | |||
| " would have been written - this code handles both cases."; | |||
| const char *max_char = | |||
| "if string is greater than stack buffer, then use dynamic string" | |||
| " with vasprintf. Note: some implementation of vsnprintf return -1 " | |||
| " if output is truncated whereas some return the number of bytes that " | |||
| " would have been written - this code handles both cases."; | |||
| printf("%s: starting test\n", __func__); | |||
| pb = printbuf_new(); | |||
| @@ -141,7 +142,8 @@ static void test_sprintbuf(int before_resize) | |||
| data[before_resize + 1] = '\0'; | |||
| sprintbuf(pb, "%s", data); | |||
| free(data); | |||
| printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, printbuf_length(pb), pb->buf, (int)strlen(pb->buf)); | |||
| printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, | |||
| printbuf_length(pb), pb->buf, (int)strlen(pb->buf)); | |||
| printbuf_reset(pb); | |||
| sprintbuf(pb, "plain"); | |||
| @@ -5,7 +5,8 @@ | |||
| #include "json.h" | |||
| #include "printbuf.h" | |||
| struct myinfo { | |||
| struct myinfo | |||
| { | |||
| int value; | |||
| }; | |||
| @@ -17,10 +18,7 @@ static void freeit(json_object *jso, void *userdata) | |||
| // Don't actually free anything here, the userdata is stack allocated. | |||
| freeit_was_called = 1; | |||
| } | |||
| static int custom_serializer(struct json_object *o, | |||
| struct printbuf *pb, | |||
| int level, | |||
| int flags) | |||
| static int custom_serializer(struct json_object *o, struct printbuf *pb, int level, int flags) | |||
| { | |||
| sprintbuf(pb, "Custom Output"); | |||
| return 0; | |||
| @@ -39,10 +37,11 @@ int main(int argc, char **argv) | |||
| printf("my_object.to_string(standard)=%s\n", json_object_to_json_string(my_object)); | |||
| struct myinfo userdata = { .value = 123 }; | |||
| struct myinfo userdata = {.value = 123}; | |||
| json_object_set_serializer(my_object, custom_serializer, &userdata, freeit); | |||
| printf("my_object.to_string(custom serializer)=%s\n", json_object_to_json_string(my_object)); | |||
| printf("my_object.to_string(custom serializer)=%s\n", | |||
| json_object_to_json_string(my_object)); | |||
| printf("Next line of output should be from the custom freeit function:\n"); | |||
| freeit_was_called = 0; | |||
| @@ -60,7 +59,8 @@ int main(int argc, char **argv) | |||
| json_object_set_serializer(my_object, custom_serializer, &userdata, freeit); | |||
| json_object_get(my_object); | |||
| json_object_put(my_object); | |||
| printf("my_object.to_string(custom serializer)=%s\n", json_object_to_json_string(my_object)); | |||
| printf("my_object.to_string(custom serializer)=%s\n", | |||
| json_object_to_json_string(my_object)); | |||
| printf("Next line of output should be from the custom freeit function:\n"); | |||
| freeit_was_called = 0; | |||
| @@ -6,85 +6,85 @@ | |||
| int main(int argc, char **argv) | |||
| { | |||
| json_object *tmp=json_object_new_int(123); | |||
| assert (json_object_get_int(tmp)==123); | |||
| json_object_set_int(tmp,321); | |||
| assert (json_object_get_int(tmp)==321); | |||
| json_object *tmp = json_object_new_int(123); | |||
| assert(json_object_get_int(tmp) == 123); | |||
| json_object_set_int(tmp, 321); | |||
| assert(json_object_get_int(tmp) == 321); | |||
| printf("INT PASSED\n"); | |||
| json_object_set_int64(tmp,(int64_t)321321321); | |||
| assert (json_object_get_int64(tmp)==321321321); | |||
| json_object_set_int64(tmp, (int64_t)321321321); | |||
| assert(json_object_get_int64(tmp) == 321321321); | |||
| json_object_put(tmp); | |||
| printf("INT64 PASSED\n"); | |||
| tmp=json_object_new_uint64(123); | |||
| assert (json_object_get_boolean(tmp)==1); | |||
| assert (json_object_get_int(tmp)==123); | |||
| assert (json_object_get_int64(tmp)==123); | |||
| assert (json_object_get_uint64(tmp)==123); | |||
| assert (json_object_get_double(tmp)==123.000000); | |||
| json_object_set_uint64(tmp,(uint64_t)321321321); | |||
| assert (json_object_get_uint64(tmp)==321321321); | |||
| json_object_set_uint64(tmp,9223372036854775808U); | |||
| assert (json_object_get_int(tmp)==INT32_MAX); | |||
| assert (json_object_get_uint64(tmp)==9223372036854775808U); | |||
| tmp = json_object_new_uint64(123); | |||
| assert(json_object_get_boolean(tmp) == 1); | |||
| assert(json_object_get_int(tmp) == 123); | |||
| assert(json_object_get_int64(tmp) == 123); | |||
| assert(json_object_get_uint64(tmp) == 123); | |||
| assert(json_object_get_double(tmp) == 123.000000); | |||
| json_object_set_uint64(tmp, (uint64_t)321321321); | |||
| assert(json_object_get_uint64(tmp) == 321321321); | |||
| json_object_set_uint64(tmp, 9223372036854775808U); | |||
| assert(json_object_get_int(tmp) == INT32_MAX); | |||
| assert(json_object_get_uint64(tmp) == 9223372036854775808U); | |||
| json_object_put(tmp); | |||
| printf("UINT64 PASSED\n"); | |||
| tmp=json_object_new_boolean(1); | |||
| assert (json_object_get_boolean(tmp)==1); | |||
| json_object_set_boolean(tmp,0); | |||
| assert (json_object_get_boolean(tmp)==0); | |||
| json_object_set_boolean(tmp,1); | |||
| assert (json_object_get_boolean(tmp)==1); | |||
| tmp = json_object_new_boolean(1); | |||
| assert(json_object_get_boolean(tmp) == 1); | |||
| json_object_set_boolean(tmp, 0); | |||
| assert(json_object_get_boolean(tmp) == 0); | |||
| json_object_set_boolean(tmp, 1); | |||
| assert(json_object_get_boolean(tmp) == 1); | |||
| json_object_put(tmp); | |||
| printf("BOOL PASSED\n"); | |||
| tmp=json_object_new_double(12.34); | |||
| assert (json_object_get_double(tmp)==12.34); | |||
| json_object_set_double(tmp,34.56); | |||
| assert (json_object_get_double(tmp)==34.56); | |||
| json_object_set_double(tmp,6435.34); | |||
| assert (json_object_get_double(tmp)==6435.34); | |||
| json_object_set_double(tmp,2e21); | |||
| assert (json_object_get_int(tmp)==INT32_MAX); | |||
| assert (json_object_get_int64(tmp)==INT64_MAX); | |||
| assert (json_object_get_uint64(tmp)==UINT64_MAX); | |||
| json_object_set_double(tmp,-2e21); | |||
| assert (json_object_get_int(tmp)==INT32_MIN); | |||
| assert (json_object_get_int64(tmp)==INT64_MIN); | |||
| assert (json_object_get_uint64(tmp)==0); | |||
| tmp = json_object_new_double(12.34); | |||
| assert(json_object_get_double(tmp) == 12.34); | |||
| json_object_set_double(tmp, 34.56); | |||
| assert(json_object_get_double(tmp) == 34.56); | |||
| json_object_set_double(tmp, 6435.34); | |||
| assert(json_object_get_double(tmp) == 6435.34); | |||
| json_object_set_double(tmp, 2e21); | |||
| assert(json_object_get_int(tmp) == INT32_MAX); | |||
| assert(json_object_get_int64(tmp) == INT64_MAX); | |||
| assert(json_object_get_uint64(tmp) == UINT64_MAX); | |||
| json_object_set_double(tmp, -2e21); | |||
| assert(json_object_get_int(tmp) == INT32_MIN); | |||
| assert(json_object_get_int64(tmp) == INT64_MIN); | |||
| assert(json_object_get_uint64(tmp) == 0); | |||
| json_object_put(tmp); | |||
| printf("DOUBLE PASSED\n"); | |||
| #define SHORT "SHORT" | |||
| #define MID "A MID STRING" | |||
| // 12345678901234567890123456789012.... | |||
| #define HUGE "A string longer than 32 chars as to check non local buf codepath" | |||
| tmp=json_object_new_string(SHORT); | |||
| assert (strcmp(json_object_get_string(tmp),SHORT)==0); | |||
| json_object_set_string(tmp,MID); | |||
| assert (strcmp(json_object_get_string(tmp),MID)==0); | |||
| json_object_set_string(tmp,HUGE); | |||
| assert (strcmp(json_object_get_string(tmp),HUGE)==0); | |||
| json_object_set_string(tmp,SHORT); | |||
| assert (strcmp(json_object_get_string(tmp),SHORT)==0); | |||
| #define SHORT "SHORT" | |||
| #define MID "A MID STRING" | |||
| // 12345678901234567890123456789012.... | |||
| #define HUGE "A string longer than 32 chars as to check non local buf codepath" | |||
| tmp = json_object_new_string(SHORT); | |||
| assert(strcmp(json_object_get_string(tmp), SHORT) == 0); | |||
| json_object_set_string(tmp, MID); | |||
| assert(strcmp(json_object_get_string(tmp), MID) == 0); | |||
| json_object_set_string(tmp, HUGE); | |||
| assert(strcmp(json_object_get_string(tmp), HUGE) == 0); | |||
| json_object_set_string(tmp, SHORT); | |||
| assert(strcmp(json_object_get_string(tmp), SHORT) == 0); | |||
| json_object_put(tmp); | |||
| printf("STRING PASSED\n"); | |||
| #define STR "STR" | |||
| #define DOUBLE "123.123" | |||
| #define DOUBLE_E "12E+3" | |||
| #define DOUBLE_STR "123.123STR" | |||
| #define DOUBLE_OVER "1.8E+308" | |||
| #define DOUBLE_OVER_NEGATIVE "-1.8E+308" | |||
| tmp=json_object_new_string(STR); | |||
| assert (json_object_get_double(tmp)==0.0); | |||
| json_object_set_string(tmp,DOUBLE); | |||
| assert (json_object_get_double(tmp)==123.123000); | |||
| json_object_set_string(tmp,DOUBLE_E); | |||
| assert (json_object_get_double(tmp)==12000.000000); | |||
| json_object_set_string(tmp,DOUBLE_STR); | |||
| assert (json_object_get_double(tmp)==0.0); | |||
| json_object_set_string(tmp,DOUBLE_OVER); | |||
| assert (json_object_get_double(tmp)==0.0); | |||
| json_object_set_string(tmp,DOUBLE_OVER_NEGATIVE); | |||
| assert (json_object_get_double(tmp)==0.0); | |||
| #define STR "STR" | |||
| #define DOUBLE "123.123" | |||
| #define DOUBLE_E "12E+3" | |||
| #define DOUBLE_STR "123.123STR" | |||
| #define DOUBLE_OVER "1.8E+308" | |||
| #define DOUBLE_OVER_NEGATIVE "-1.8E+308" | |||
| tmp = json_object_new_string(STR); | |||
| assert(json_object_get_double(tmp) == 0.0); | |||
| json_object_set_string(tmp, DOUBLE); | |||
| assert(json_object_get_double(tmp) == 123.123000); | |||
| json_object_set_string(tmp, DOUBLE_E); | |||
| assert(json_object_get_double(tmp) == 12000.000000); | |||
| json_object_set_string(tmp, DOUBLE_STR); | |||
| assert(json_object_get_double(tmp) == 0.0); | |||
| json_object_set_string(tmp, DOUBLE_OVER); | |||
| assert(json_object_get_double(tmp) == 0.0); | |||
| json_object_set_string(tmp, DOUBLE_OVER_NEGATIVE); | |||
| assert(json_object_get_double(tmp) == 0.0); | |||
| json_object_put(tmp); | |||
| printf("STRINGTODOUBLE PASSED\n"); | |||
| @@ -92,7 +92,7 @@ int main(int argc, char **argv) | |||
| json_object_set_double(tmp, 12.3); | |||
| const char *serialized = json_object_to_json_string(tmp); | |||
| fprintf(stderr, "%s\n", serialized); | |||
| assert(strncmp(serialized, "12.3", 4)==0); | |||
| assert(strncmp(serialized, "12.3", 4) == 0); | |||
| json_object_put(tmp); | |||
| printf("PARSE AND SET PASSED\n"); | |||
| @@ -2,20 +2,20 @@ | |||
| #include "strerror_override_private.h" | |||
| #ifdef WIN32 | |||
| #define WIN32_LEAN_AND_MEAN | |||
| #include <windows.h> | |||
| #include <io.h> | |||
| #endif /* defined(WIN32) */ | |||
| #include <windows.h> | |||
| #endif /* defined(WIN32) */ | |||
| #include <fcntl.h> | |||
| #include <limits.h> | |||
| #include <stddef.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <stddef.h> | |||
| #include <string.h> | |||
| #include <fcntl.h> | |||
| #include <limits.h> | |||
| #if HAVE_UNISTD_H | |||
| # include <unistd.h> | |||
| #include <unistd.h> | |||
| #endif /* HAVE_UNISTD_H */ | |||
| #include <sys/types.h> | |||
| #include <sys/stat.h> | |||
| #include <sys/types.h> | |||
| #include "json.h" | |||
| #include "json_util.h" | |||
| @@ -38,21 +38,20 @@ static void test_write_to_file() | |||
| json_object *jso; | |||
| jso = json_tokener_parse("{" | |||
| "\"foo\":1234," | |||
| "\"foo1\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo2\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo3\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo4\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo5\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo6\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo7\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo8\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo9\":\"abcdefghijklmnopqrstuvwxyz\"" | |||
| "}"); | |||
| "\"foo\":1234," | |||
| "\"foo1\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo2\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo3\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo4\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo5\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo6\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo7\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo8\":\"abcdefghijklmnopqrstuvwxyz\"," | |||
| "\"foo9\":\"abcdefghijklmnopqrstuvwxyz\"" | |||
| "}"); | |||
| const char *outfile = "json.out"; | |||
| int rv = json_object_to_file(outfile, jso); | |||
| printf("%s: json_object_to_file(%s, jso)=%d\n", | |||
| (rv == 0) ? "OK" : "FAIL", outfile, rv); | |||
| printf("%s: json_object_to_file(%s, jso)=%d\n", (rv == 0) ? "OK" : "FAIL", outfile, rv); | |||
| if (rv == 0) | |||
| stat_and_cat(outfile); | |||
| @@ -66,7 +65,7 @@ static void test_write_to_file() | |||
| stat_and_cat(outfile2); | |||
| const char *outfile3 = "json3.out"; | |||
| int d = open(outfile3, O_WRONLY|O_CREAT, 0600); | |||
| int d = open(outfile3, O_WRONLY | O_CREAT, 0600); | |||
| if (d < 0) | |||
| { | |||
| printf("FAIL: unable to open %s %s\n", outfile3, strerror(errno)); | |||
| @@ -92,19 +91,17 @@ static void stat_and_cat(const char *file) | |||
| int d = open(file, O_RDONLY, 0600); | |||
| if (d < 0) | |||
| { | |||
| printf("FAIL: unable to open %s: %s\n", | |||
| file, strerror(errno)); | |||
| printf("FAIL: unable to open %s: %s\n", file, strerror(errno)); | |||
| return; | |||
| } | |||
| if (fstat(d, &sb) < 0) | |||
| { | |||
| printf("FAIL: unable to stat %s: %s\n", | |||
| file, strerror(errno)); | |||
| printf("FAIL: unable to stat %s: %s\n", file, strerror(errno)); | |||
| close(d); | |||
| return; | |||
| } | |||
| char *buf = malloc(sb.st_size + 1); | |||
| if(!buf) | |||
| if (!buf) | |||
| { | |||
| printf("FAIL: unable to allocate memory\n"); | |||
| close(d); | |||
| @@ -112,8 +109,7 @@ static void stat_and_cat(const char *file) | |||
| } | |||
| if (read(d, buf, sb.st_size) < sb.st_size) | |||
| { | |||
| printf("FAIL: unable to read all of %s: %s\n", | |||
| file, strerror(errno)); | |||
| printf("FAIL: unable to read all of %s: %s\n", file, strerror(errno)); | |||
| free(buf); | |||
| close(d); | |||
| return; | |||
| @@ -126,8 +122,8 @@ static void stat_and_cat(const char *file) | |||
| int main(int argc, char **argv) | |||
| { | |||
| // json_object_to_file(file, obj); | |||
| // json_object_to_file_ext(file, obj, flags); | |||
| // json_object_to_file(file, obj); | |||
| // json_object_to_file_ext(file, obj, flags); | |||
| _json_c_strerror_enable = 1; | |||
| @@ -135,9 +131,9 @@ int main(int argc, char **argv) | |||
| if (argc < 2) | |||
| { | |||
| fprintf(stderr, | |||
| "Usage: %s <testdir>\n" | |||
| " <testdir> is the location of input files\n", | |||
| argv[0]); | |||
| "Usage: %s <testdir>\n" | |||
| " <testdir> is the location of input files\n", | |||
| argv[0]); | |||
| return EXIT_FAILURE; | |||
| } | |||
| testdir = argv[1]; | |||
| @@ -158,23 +154,19 @@ static void test_read_valid_with_fd(const char *testdir) | |||
| int d = open(filename, O_RDONLY, 0); | |||
| if (d < 0) | |||
| { | |||
| fprintf(stderr, | |||
| "FAIL: unable to open %s: %s\n", | |||
| filename, strerror(errno)); | |||
| fprintf(stderr, "FAIL: unable to open %s: %s\n", filename, strerror(errno)); | |||
| exit(EXIT_FAILURE); | |||
| } | |||
| json_object *jso = json_object_from_fd(d); | |||
| if (jso != NULL) | |||
| { | |||
| printf("OK: json_object_from_fd(valid.json)=%s\n", | |||
| json_object_to_json_string(jso)); | |||
| printf("OK: json_object_from_fd(valid.json)=%s\n", json_object_to_json_string(jso)); | |||
| json_object_put(jso); | |||
| } | |||
| else | |||
| { | |||
| fprintf(stderr, | |||
| "FAIL: unable to parse contents of %s: %s\n", | |||
| filename, json_util_get_last_err()); | |||
| fprintf(stderr, "FAIL: unable to parse contents of %s: %s\n", filename, | |||
| json_util_get_last_err()); | |||
| } | |||
| close(d); | |||
| } | |||
| @@ -187,9 +179,7 @@ static void test_read_valid_nested_with_fd(const char *testdir) | |||
| int d = open(filename, O_RDONLY, 0); | |||
| if (d < 0) | |||
| { | |||
| fprintf(stderr, | |||
| "FAIL: unable to open %s: %s\n", | |||
| filename, strerror(errno)); | |||
| fprintf(stderr, "FAIL: unable to open %s: %s\n", filename, strerror(errno)); | |||
| exit(EXIT_FAILURE); | |||
| } | |||
| json_object *jso = json_object_from_fd_ex(d, 20); | |||
| @@ -201,9 +191,8 @@ static void test_read_valid_nested_with_fd(const char *testdir) | |||
| } | |||
| else | |||
| { | |||
| fprintf(stderr, | |||
| "FAIL: unable to parse contents of %s: %s\n", | |||
| filename, json_util_get_last_err()); | |||
| fprintf(stderr, "FAIL: unable to parse contents of %s: %s\n", filename, | |||
| json_util_get_last_err()); | |||
| } | |||
| (void)lseek(d, SEEK_SET, 0); | |||
| @@ -211,14 +200,15 @@ static void test_read_valid_nested_with_fd(const char *testdir) | |||
| jso = json_object_from_fd_ex(d, 3); | |||
| if (jso != NULL) | |||
| { | |||
| printf("FAIL: json_object_from_fd_ex(%s, 3)=%s\n", | |||
| filename, json_object_to_json_string(jso)); | |||
| printf("FAIL: json_object_from_fd_ex(%s, 3)=%s\n", filename, | |||
| json_object_to_json_string(jso)); | |||
| json_object_put(jso); | |||
| } | |||
| else | |||
| { | |||
| printf("OK: correctly unable to parse contents of valid_nested.json with low max depth: %s\n", | |||
| json_util_get_last_err()); | |||
| printf("OK: correctly unable to parse contents of valid_nested.json with low max " | |||
| "depth: %s\n", | |||
| json_util_get_last_err()); | |||
| } | |||
| close(d); | |||
| } | |||
| @@ -230,14 +220,14 @@ static void test_read_nonexistant() | |||
| json_object *jso = json_object_from_file(filename); | |||
| if (jso != NULL) | |||
| { | |||
| printf("FAIL: json_object_from_file(%s) returned %p when NULL expected\n", | |||
| filename, (void *)jso); | |||
| printf("FAIL: json_object_from_file(%s) returned %p when NULL expected\n", filename, | |||
| (void *)jso); | |||
| json_object_put(jso); | |||
| } | |||
| else | |||
| { | |||
| printf("OK: json_object_from_file(%s) correctly returned NULL: %s\n", | |||
| filename, json_util_get_last_err()); | |||
| printf("OK: json_object_from_file(%s) correctly returned NULL: %s\n", filename, | |||
| json_util_get_last_err()); | |||
| } | |||
| } | |||
| @@ -245,7 +235,7 @@ static void test_read_closed() | |||
| { | |||
| // Test reading from a closed fd | |||
| int d = open("/dev/null", O_RDONLY, 0); | |||
| if(d < 0) | |||
| if (d < 0) | |||
| { | |||
| puts("FAIL: unable to open"); | |||
| } | |||
| @@ -261,8 +251,7 @@ static void test_read_closed() | |||
| json_object *jso = json_object_from_fd(fixed_d); | |||
| if (jso != NULL) | |||
| { | |||
| printf("FAIL: read from closed fd returning non-NULL: %p\n", | |||
| (void *)jso); | |||
| printf("FAIL: read from closed fd returning non-NULL: %p\n", (void *)jso); | |||
| fflush(stdout); | |||
| printf(" jso=%s\n", json_object_to_json_string(jso)); | |||
| json_object_put(jso); | |||
| @@ -1,8 +1,8 @@ | |||
| #include <assert.h> | |||
| #include <stddef.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <stddef.h> | |||
| #include <string.h> | |||
| #include <assert.h> | |||
| #include "json.h" | |||
| #include "json_tokener.h" | |||
| @@ -68,24 +68,17 @@ int main(void) | |||
| return 0; | |||
| } | |||
| static int emit_object(json_object *jso, int flags, | |||
| json_object *parent_jso, | |||
| const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| static int emit_object(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| { | |||
| printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", | |||
| flags, | |||
| (jso_key ? jso_key : "(null)"), | |||
| (jso_index ? (long)*jso_index : -1L), | |||
| printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", flags, | |||
| (jso_key ? jso_key : "(null)"), (jso_index ? (long)*jso_index : -1L), | |||
| json_object_to_json_string(jso)); | |||
| return JSON_C_VISIT_RETURN_CONTINUE; | |||
| } | |||
| static int skip_arrays(json_object *jso, int flags, | |||
| json_object *parent_jso, | |||
| const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| static int skip_arrays(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| { | |||
| (void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | |||
| if (json_object_get_type(jso) == json_type_array) | |||
| @@ -93,10 +86,8 @@ static int skip_arrays(json_object *jso, int flags, | |||
| return JSON_C_VISIT_RETURN_CONTINUE; | |||
| } | |||
| static int pop_and_stop(json_object *jso, int flags, | |||
| json_object *parent_jso, | |||
| const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| static int pop_and_stop(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| { | |||
| (void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | |||
| if (jso_key != NULL && strcmp(jso_key, "subobj1") == 0) | |||
| @@ -112,10 +103,8 @@ static int pop_and_stop(json_object *jso, int flags, | |||
| return JSON_C_VISIT_RETURN_CONTINUE; | |||
| } | |||
| static int err_on_subobj2(json_object *jso, int flags, | |||
| json_object *parent_jso, | |||
| const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| static int err_on_subobj2(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| { | |||
| (void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | |||
| if (jso_key != NULL && strcmp(jso_key, "subobj2") == 0) | |||
| @@ -126,9 +115,7 @@ static int err_on_subobj2(json_object *jso, int flags, | |||
| return JSON_C_VISIT_RETURN_CONTINUE; | |||
| } | |||
| static int pop_array(json_object *jso, int flags, | |||
| json_object *parent_jso, | |||
| const char *jso_key, | |||
| static int pop_array(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| { | |||
| (void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | |||
| @@ -140,10 +127,8 @@ static int pop_array(json_object *jso, int flags, | |||
| return JSON_C_VISIT_RETURN_CONTINUE; | |||
| } | |||
| static int stop_array(json_object *jso, int flags, | |||
| json_object *parent_jso, | |||
| const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| static int stop_array(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| { | |||
| (void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg); | |||
| if (jso_index != NULL && (*jso_index == 0)) | |||
| @@ -154,15 +139,11 @@ static int stop_array(json_object *jso, int flags, | |||
| return JSON_C_VISIT_RETURN_CONTINUE; | |||
| } | |||
| static int err_return(json_object *jso, int flags, | |||
| json_object *parent_jso, | |||
| const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| static int err_return(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||
| size_t *jso_index, void *userarg) | |||
| { | |||
| printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", | |||
| flags, | |||
| (jso_key ? jso_key : "(null)"), | |||
| (jso_index ? (long)*jso_index : -1L), | |||
| printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", flags, | |||
| (jso_key ? jso_key : "(null)"), (jso_index ? (long)*jso_index : -1L), | |||
| json_object_to_json_string(jso)); | |||
| return 100; | |||
| } | |||
| @@ -18,24 +18,36 @@ static int vasprintf(char **buf, const char *fmt, va_list ap) | |||
| int chars; | |||
| char *b; | |||
| if(!buf) { return -1; } | |||
| if (!buf) | |||
| { | |||
| return -1; | |||
| } | |||
| #ifdef WIN32 | |||
| chars = _vscprintf(fmt, ap)+1; | |||
| #else /* !defined(WIN32) */ | |||
| chars = _vscprintf(fmt, ap) + 1; | |||
| #else /* !defined(WIN32) */ | |||
| /* 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 */ | |||
| * 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 */ | |||
| #endif /* defined(WIN32) */ | |||
| b = (char*)malloc(sizeof(char)*chars); | |||
| if(!b) { return -1; } | |||
| b = (char *)malloc(sizeof(char) * chars); | |||
| if (!b) | |||
| { | |||
| return -1; | |||
| } | |||
| if((chars = vsprintf(b, fmt, ap)) < 0) | |||
| if ((chars = vsprintf(b, fmt, ap)) < 0) | |||
| { | |||
| free(b); | |||
| } else { | |||
| } | |||
| else | |||
| { | |||
| *buf = b; | |||
| } | |||