Browse Source

Merge branch 'remicollet-issue-float'

Conflicts:
	json_util.c
tags/json-c-0.11-20130402
Eric Haszlakiewicz 12 years ago
parent
commit
5b36a432c8
8 changed files with 85 additions and 4 deletions
  1. +2
    -2
      configure.in
  2. +22
    -1
      json_object.c
  3. +4
    -0
      json_object.h
  4. +17
    -1
      json_tokener.c
  5. +5
    -0
      json_util.c
  6. +1
    -0
      json_util.h
  7. +3
    -0
      tests/Makefile.am
  8. +31
    -0
      tests/test_locale.c

+ 2
- 2
configure.in View File

@@ -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])


+ 22
- 1
json_object.c View File

@@ -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)


+ 4
- 0
json_object.h View File

@@ -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)


+ 17
- 1
json_tokener.c View File

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


+ 5
- 0
json_util.c View File

@@ -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


+ 1
- 0
json_util.h View File

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




/** /**


+ 3
- 0
tests/Makefile.am View File

@@ -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


+ 31
- 0
tests/test_locale.c View File

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


Loading…
Cancel
Save