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); | |||||
} | |||||