Conflicts: json_util.ctags/json-c-0.11-20130402
| @@ -23,7 +23,7 @@ AM_CONDITIONAL(ENABLE_OLDNAME_COMPAT, [test "x${enable_oldname_compat}" != "xno" | |||||
| AM_CONFIG_HEADER(config.h) | AM_CONFIG_HEADER(config.h) | ||||
| AM_CONFIG_HEADER(json_config.h) | AM_CONFIG_HEADER(json_config.h) | ||||
| AC_HEADER_STDC | AC_HEADER_STDC | ||||
| AC_CHECK_HEADERS(fcntl.h limits.h strings.h syslog.h unistd.h [sys/cdefs.h] [sys/param.h] stdarg.h) | |||||
| AC_CHECK_HEADERS(fcntl.h limits.h strings.h syslog.h unistd.h [sys/cdefs.h] [sys/param.h] stdarg.h locale.h) | |||||
| AC_CHECK_HEADER(inttypes.h,[AC_DEFINE([JSON_C_HAVE_INTTYPES_H],[1],[Public define for json_inttypes.h])]) | AC_CHECK_HEADER(inttypes.h,[AC_DEFINE([JSON_C_HAVE_INTTYPES_H],[1],[Public define for json_inttypes.h])]) | ||||
| # Checks for typedefs, structures, and compiler characteristics. | # Checks for typedefs, structures, and compiler characteristics. | ||||
| @@ -35,7 +35,7 @@ AC_FUNC_VPRINTF | |||||
| AC_FUNC_MEMCMP | AC_FUNC_MEMCMP | ||||
| AC_FUNC_MALLOC | AC_FUNC_MALLOC | ||||
| AC_FUNC_REALLOC | AC_FUNC_REALLOC | ||||
| AC_CHECK_FUNCS(strcasecmp strdup strndup strerror snprintf vsnprintf vasprintf open vsyslog strncasecmp) | |||||
| AC_CHECK_FUNCS(strcasecmp strdup strndup strerror snprintf vsnprintf vasprintf open vsyslog strncasecmp setlocale) | |||||
| #check if .section.gnu.warning accepts long strings (for __warn_references) | #check if .section.gnu.warning accepts long strings (for __warn_references) | ||||
| AC_LANG_PUSH([C]) | AC_LANG_PUSH([C]) | ||||
| @@ -559,7 +559,28 @@ static int json_object_double_to_json_string(struct json_object* jso, | |||||
| int level, | int level, | ||||
| int flags) | int flags) | ||||
| { | { | ||||
| return sprintbuf(pb, "%f", jso->o.c_double); | |||||
| char buf[128], *p, *q; | |||||
| int size; | |||||
| size = snprintf(buf, 128, "%f", jso->o.c_double); | |||||
| p = strchr(buf, ','); | |||||
| if (p) { | |||||
| *p = '.'; | |||||
| } else { | |||||
| p = strchr(buf, '.'); | |||||
| } | |||||
| if (p && (flags & JSON_C_TO_STRING_NOZERO)) { | |||||
| /* last useful digit, always keep 1 zero */ | |||||
| p++; | |||||
| for (q=p ; *q ; q++) { | |||||
| if (*q!='0') p=q; | |||||
| } | |||||
| /* drop trailing zeroes */ | |||||
| *(++p) = 0; | |||||
| size = p-buf; | |||||
| } | |||||
| printbuf_memappend(pb, buf, size); | |||||
| return size; | |||||
| } | } | ||||
| struct json_object* json_object_new_double(double d) | struct json_object* json_object_new_double(double d) | ||||
| @@ -42,6 +42,10 @@ extern "C" { | |||||
| * for an example of the format. | * for an example of the format. | ||||
| */ | */ | ||||
| #define JSON_C_TO_STRING_PRETTY (1<<1) | #define JSON_C_TO_STRING_PRETTY (1<<1) | ||||
| /** | |||||
| * A flag to drop trailing zero for float values | |||||
| */ | |||||
| #define JSON_C_TO_STRING_NOZERO (1<<2) | |||||
| #undef FALSE | #undef FALSE | ||||
| #define FALSE ((json_bool)0) | #define FALSE ((json_bool)0) | ||||
| @@ -31,6 +31,10 @@ | |||||
| #include "json_tokener.h" | #include "json_tokener.h" | ||||
| #include "json_util.h" | #include "json_util.h" | ||||
| #ifdef HAVE_LOCALE_H | |||||
| #include <locale.h> | |||||
| #endif /* HAVE_LOCALE_H */ | |||||
| #if !HAVE_STRDUP && defined(_MSC_VER) | #if !HAVE_STRDUP && defined(_MSC_VER) | ||||
| /* MSC has the version as _strdup */ | /* MSC has the version as _strdup */ | ||||
| # define strdup _strdup | # define strdup _strdup | ||||
| @@ -239,6 +243,13 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||||
| { | { | ||||
| struct json_object *obj = NULL; | struct json_object *obj = NULL; | ||||
| char c = '\1'; | char c = '\1'; | ||||
| #ifdef HAVE_SETLOCALE | |||||
| char *oldlocale=NULL, *tmplocale; | |||||
| tmplocale = setlocale(LC_NUMERIC, NULL); | |||||
| if (tmplocale) oldlocale = strdup(tmplocale); | |||||
| setlocale(LC_NUMERIC, "C"); | |||||
| #endif | |||||
| tok->char_offset = 0; | tok->char_offset = 0; | ||||
| tok->err = json_tokener_success; | tok->err = json_tokener_success; | ||||
| @@ -597,7 +608,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||||
| double numd; | double numd; | ||||
| if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) { | if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) { | ||||
| current = json_object_new_int64(num64); | current = json_object_new_int64(num64); | ||||
| } else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) { | |||||
| } else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0) { | |||||
| current = json_object_new_double(numd); | current = json_object_new_double(numd); | ||||
| } else { | } else { | ||||
| tok->err = json_tokener_error_parse_number; | tok->err = json_tokener_error_parse_number; | ||||
| @@ -736,6 +747,11 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||||
| tok->err = json_tokener_error_parse_eof; | tok->err = json_tokener_error_parse_eof; | ||||
| } | } | ||||
| #ifdef HAVE_SETLOCALE | |||||
| setlocale(LC_NUMERIC, oldlocale); | |||||
| if (oldlocale) free(oldlocale); | |||||
| #endif | |||||
| if (tok->err == json_tokener_success) | if (tok->err == json_tokener_success) | ||||
| { | { | ||||
| json_object *ret = json_object_get(current); | json_object *ret = json_object_get(current); | ||||
| @@ -146,6 +146,11 @@ int json_object_to_file(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) | |||||
| { | |||||
| return (sscanf(buf, "%lf", retval)==1 ? 0 : 1); | |||||
| } | |||||
| /* | /* | ||||
| * Not all implementations of sscanf actually work properly. | * Not all implementations of sscanf actually work properly. | ||||
| * Check whether the one we're currently using does, and if | * Check whether the one we're currently using does, and if | ||||
| @@ -25,6 +25,7 @@ extern struct json_object* json_object_from_file(const char *filename); | |||||
| extern int json_object_to_file(char *filename, struct json_object *obj); | extern int json_object_to_file(char *filename, struct json_object *obj); | ||||
| extern int json_object_to_file_ext(char *filename, struct json_object *obj, int flags); | extern int json_object_to_file_ext(char *filename, struct json_object *obj, int flags); | ||||
| extern int json_parse_int64(const char *buf, int64_t *retval); | extern int json_parse_int64(const char *buf, int64_t *retval); | ||||
| extern int json_parse_double(const char *buf, double *retval); | |||||
| /** | /** | ||||
| @@ -11,6 +11,7 @@ check_PROGRAMS += test_parse_int64 | |||||
| check_PROGRAMS += test_null | check_PROGRAMS += test_null | ||||
| check_PROGRAMS += test_cast | check_PROGRAMS += test_cast | ||||
| check_PROGRAMS += test_parse | check_PROGRAMS += test_parse | ||||
| check_PROGRAMS += test_locale | |||||
| test1_LDADD = $(LIBJSON_LA) | test1_LDADD = $(LIBJSON_LA) | ||||
| @@ -36,6 +37,8 @@ test_cast_LDADD = $(LIBJSON_LA) | |||||
| test_parse_LDADD = $(LIBJSON_LA) | test_parse_LDADD = $(LIBJSON_LA) | ||||
| test_locale_LDADD = $(LIBJSON_LA) | |||||
| TESTS = test1.test test2.test test4.test testReplaceExisting.test parse_int64.test test_null.test test_cast.test test_parse.test | TESTS = test1.test test2.test test4.test testReplaceExisting.test parse_int64.test test_null.test test_cast.test test_parse.test | ||||
| TESTS+= test_printbuf.test | TESTS+= test_printbuf.test | ||||
| @@ -0,0 +1,31 @@ | |||||
| #include <stdio.h> | |||||
| #include <stdlib.h> | |||||
| #include <stddef.h> | |||||
| #include <string.h> | |||||
| #include <assert.h> | |||||
| #include "config.h" | |||||
| #include "json.h" | |||||
| #include "json_tokener.h" | |||||
| #ifdef HAVE_LOCALE_H | |||||
| #include <locale.h> | |||||
| #endif /* HAVE_LOCALE_H */ | |||||
| int main(int argc, char **argv) | |||||
| { | |||||
| json_object *new_obj; | |||||
| #ifdef HAVE_SETLOCALE | |||||
| setlocale(LC_NUMERIC, "de_DE"); | |||||
| #else | |||||
| printf("No locale\n"); | |||||
| #endif | |||||
| MC_SET_DEBUG(1); | |||||
| new_obj = json_tokener_parse("[1.2,3.4,123456.78,5.0,2.3e10]"); | |||||
| printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); | |||||
| 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); | |||||
| } | |||||