diff options
author | Mark Pulford <mark@kyne.com.au> | 2011-12-29 23:53:11 +1030 |
---|---|---|
committer | Mark Pulford <mark@kyne.com.au> | 2011-12-29 23:53:11 +1030 |
commit | 6cc88e3ac5275868e168acaf60203563f131355b (patch) | |
tree | c574da2dff2c4e95cc6d39d6de2393b64eedf4fc | |
parent | 155393d5bd801ce5dbd76020facecd9270679e94 (diff) | |
download | lua-cjson-6cc88e3ac5275868e168acaf60203563f131355b.tar.gz lua-cjson-6cc88e3ac5275868e168acaf60203563f131355b.tar.bz2 lua-cjson-6cc88e3ac5275868e168acaf60203563f131355b.zip |
Remove POSIX locale workaround
-rw-r--r-- | CMakeLists.txt | 10 | ||||
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | lua-cjson-1.0devel-1.rockspec | 15 | ||||
-rw-r--r-- | lua-cjson.spec | 3 | ||||
-rw-r--r-- | lua_cjson.c | 72 | ||||
-rw-r--r-- | manual.txt | 14 |
6 files changed, 4 insertions, 124 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index bfb28cc..349342e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -11,16 +11,6 @@ set(CMAKE_BUILD_TYPE Release) | |||
11 | find_package(Lua51 REQUIRED) | 11 | find_package(Lua51 REQUIRED) |
12 | include_directories(${LUA_INCLUDE_DIR}) | 12 | include_directories(${LUA_INCLUDE_DIR}) |
13 | 13 | ||
14 | # Use thread-safe POSIX.1-2008 uselocale() where available, otherwise | ||
15 | # fall back to ANSI C setlocale(). | ||
16 | include(CheckFunctionExists) | ||
17 | CHECK_FUNCTION_EXISTS(uselocale HAVE_USELOCALE) | ||
18 | if(HAVE_USELOCALE) | ||
19 | add_definitions(-DUSE_POSIX_USELOCALE) | ||
20 | else() | ||
21 | add_definitions(-DUSE_POSIX_SETLOCALE) | ||
22 | endif() | ||
23 | |||
24 | # Handle platforms missing isinf() macro (Eg, some Solaris systems). | 14 | # Handle platforms missing isinf() macro (Eg, some Solaris systems). |
25 | include(CheckSymbolExists) | 15 | include(CheckSymbolExists) |
26 | CHECK_SYMBOL_EXISTS(isinf math.h HAVE_ISINF) | 16 | CHECK_SYMBOL_EXISTS(isinf math.h HAVE_ISINF) |
@@ -1,13 +1,6 @@ | |||
1 | LUA_VERSION = 5.1 | 1 | LUA_VERSION = 5.1 |
2 | 2 | ||
3 | ## Available Lua CJSON specific workarounds | 3 | ## Available defines for CJSON_CFLAGS |
4 | # | ||
5 | # To ensure JSON encoding/decoding works correctly for locales using | ||
6 | # comma decimal separators, Lua CJSON must be compiled with one of | ||
7 | # these options: | ||
8 | # USE_POSIX_USELOCALE: Linux, OSX. Thread safe. Recommended option. | ||
9 | # USE_POSIX_SETLOCALE: Works on all ANSI C platforms. May be used when | ||
10 | # thread-safety isn't required. | ||
11 | # | 4 | # |
12 | # USE_INTERNAL_ISINF: Workaround for Solaris platforms missing isinf(). | 5 | # USE_INTERNAL_ISINF: Workaround for Solaris platforms missing isinf(). |
13 | 6 | ||
@@ -15,7 +8,6 @@ LUA_VERSION = 5.1 | |||
15 | PREFIX = /usr/local | 8 | PREFIX = /usr/local |
16 | #CFLAGS = -g -Wall -pedantic -fno-inline | 9 | #CFLAGS = -g -Wall -pedantic -fno-inline |
17 | CFLAGS = -O3 -Wall -pedantic | 10 | CFLAGS = -O3 -Wall -pedantic |
18 | CJSON_CFLAGS = -DUSE_POSIX_SETLOCALE | ||
19 | CJSON_LDFLAGS = -shared | 11 | CJSON_LDFLAGS = -shared |
20 | LUA_INCLUDE_DIR = $(PREFIX)/include | 12 | LUA_INCLUDE_DIR = $(PREFIX)/include |
21 | LUA_MODULE_DIR = $(PREFIX)/lib/lua/$(LUA_VERSION) | 13 | LUA_MODULE_DIR = $(PREFIX)/lib/lua/$(LUA_VERSION) |
@@ -29,18 +21,16 @@ INSTALL_CMD = install | |||
29 | # specific details. | 21 | # specific details. |
30 | 22 | ||
31 | ## Linux | 23 | ## Linux |
32 | #CJSON_CFLAGS = -DUSE_POSIX_USELOCALE | ||
33 | 24 | ||
34 | ## FreeBSD | 25 | ## FreeBSD |
35 | #LUA_INCLUDE_DIR = $(PREFIX)/include/lua51 | 26 | #LUA_INCLUDE_DIR = $(PREFIX)/include/lua51 |
36 | 27 | ||
37 | ## MacOSX (Macports) | 28 | ## MacOSX (Macports) |
38 | #PREFIX = /opt/local | 29 | #PREFIX = /opt/local |
39 | #CJSON_CFLAGS = -DUSE_POSIX_USELOCALE | ||
40 | #CJSON_LDFLAGS = -bundle -undefined dynamic_lookup | 30 | #CJSON_LDFLAGS = -bundle -undefined dynamic_lookup |
41 | 31 | ||
42 | ## Solaris | 32 | ## Solaris |
43 | #CJSON_CFLAGS = -DUSE_POSIX_SETLOCALE -DUSE_INTERNAL_ISINF | 33 | #CJSON_CFLAGS = -DUSE_INTERNAL_ISINF |
44 | 34 | ||
45 | ## End platform specific section | 35 | ## End platform specific section |
46 | 36 | ||
diff --git a/lua-cjson-1.0devel-1.rockspec b/lua-cjson-1.0devel-1.rockspec index 8df0658..3890ec1 100644 --- a/lua-cjson-1.0devel-1.rockspec +++ b/lua-cjson-1.0devel-1.rockspec | |||
@@ -24,29 +24,16 @@ build = { | |||
24 | modules = { | 24 | modules = { |
25 | cjson = { | 25 | cjson = { |
26 | sources = { "lua_cjson.c", "strbuf.c" }, | 26 | sources = { "lua_cjson.c", "strbuf.c" }, |
27 | -- Optional workarounds: | 27 | -- Optional workaround: |
28 | -- USE_POSIX_USELOCALE: Linux, OSX. Thread safe. Recommended. | ||
29 | -- USE_POSIX_SETLOCALE: Works on all ANSI C platforms. May be used when | ||
30 | -- thread-safety isn't required. | ||
31 | -- USE_INTERNAL_ISINF: Provide internal isinf() implementation. Required | 28 | -- USE_INTERNAL_ISINF: Provide internal isinf() implementation. Required |
32 | -- on some Solaris platforms. | 29 | -- on some Solaris platforms. |
33 | defines = { | 30 | defines = { |
34 | "USE_POSIX_SETLOCALE", | ||
35 | -- LuaRocks does not support platform specific configuration for Solaris. | 31 | -- LuaRocks does not support platform specific configuration for Solaris. |
36 | -- Uncomment the line below on Solaris platforms. | 32 | -- Uncomment the line below on Solaris platforms. |
37 | -- "USE_INTERNAL_ISINF" | 33 | -- "USE_INTERNAL_ISINF" |
38 | } | 34 | } |
39 | } | 35 | } |
40 | }, | 36 | }, |
41 | -- Override default build options (per platform) | ||
42 | platforms = { | ||
43 | linux = { modules = { cjson = { defines = { | ||
44 | [1] = "USE_POSIX_USELOCALE" | ||
45 | } } } }, | ||
46 | macosx = { modules = { cjson = { defines = { | ||
47 | [1] = "USE_POSIX_USELOCALE" | ||
48 | } } } } | ||
49 | }, | ||
50 | copy_directories = { "tests" } | 37 | copy_directories = { "tests" } |
51 | } | 38 | } |
52 | 39 | ||
diff --git a/lua-cjson.spec b/lua-cjson.spec index 942151e..c7aec95 100644 --- a/lua-cjson.spec +++ b/lua-cjson.spec | |||
@@ -24,8 +24,7 @@ Lua CJSON provides fast, standards compliant JSON support for Lua. | |||
24 | 24 | ||
25 | 25 | ||
26 | %build | 26 | %build |
27 | make %{?_smp_mflags} CFLAGS="%{optflags}" CJSON_CFLAGS="-DUSE_POSIX_USELOCALE" \ | 27 | make %{?_smp_mflags} CFLAGS="%{optflags}" LUA_INCLUDE_DIR="%{_includedir}" |
28 | LUA_INCLUDE_DIR="%{_includedir}" | ||
29 | 28 | ||
30 | 29 | ||
31 | %install | 30 | %install |
diff --git a/lua_cjson.c b/lua_cjson.c index 0f6d675..f5ea0dd 100644 --- a/lua_cjson.c +++ b/lua_cjson.c | |||
@@ -48,48 +48,6 @@ | |||
48 | #define CJSON_VERSION "1.0devel" | 48 | #define CJSON_VERSION "1.0devel" |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | /* Support to reset locale to POSIX for strtod() / sprintf(). | ||
52 | * Some locales use comma as a decimal separator. This breaks JSON. */ | ||
53 | #ifdef USE_POSIX_USELOCALE | ||
54 | |||
55 | #ifdef USE_POSIX_SETLOCALE | ||
56 | #error Must not define USE_POSIX_USELOCALE and USE_POSIX_SETLOCALE simultaneously. | ||
57 | #endif | ||
58 | |||
59 | /* unistd.h defines _POSIX_VERSION */ | ||
60 | #include <unistd.h> | ||
61 | |||
62 | #if _POSIX_VERSION >= 200809L | ||
63 | /* POSIX.1-2008 adds threadsafe locale support */ | ||
64 | #include <locale.h> | ||
65 | #elif defined(_POSIX_VERSION) | ||
66 | /* Some pre-POSIX.1-2008 operating systems offer xlocale.h instead */ | ||
67 | #include <xlocale.h> | ||
68 | #else | ||
69 | #error Missing _POSIX_VERSION define | ||
70 | #endif /* _POSIX_VERSION */ | ||
71 | |||
72 | #define LOCALE_SET_POSIX(x) (x)->saved_locale = uselocale((x)->posix_locale) | ||
73 | #define LOCALE_RESTORE(x) uselocale((x)->saved_locale) | ||
74 | |||
75 | #elif defined(USE_POSIX_SETLOCALE) | ||
76 | /* ANSI C / ISO C90 implementation. Not thread-safe, affects entire process. */ | ||
77 | #include <locale.h> | ||
78 | |||
79 | #define LOCALE_SET_POSIX(x) \ | ||
80 | do { \ | ||
81 | (x)->saved_locale = setlocale(LC_NUMERIC, NULL); \ | ||
82 | setlocale(LC_NUMERIC, "C"); \ | ||
83 | } while(0) | ||
84 | #define LOCALE_RESTORE(x) setlocale(LC_NUMERIC, (x)->saved_locale) | ||
85 | |||
86 | #else /* Do not work around locale support in strtod() / sprintf() */ | ||
87 | |||
88 | #define LOCALE_SET_POSIX(x) do { } while(0) | ||
89 | #define LOCALE_RESTORE(x) do { } while(0) | ||
90 | |||
91 | #endif | ||
92 | |||
93 | /* Workaround for Solaris platforms missing isinf() */ | 51 | /* Workaround for Solaris platforms missing isinf() */ |
94 | #if !defined(isinf) && (defined(USE_INTERNAL_ISINF) || defined(MISSING_ISINF)) | 52 | #if !defined(isinf) && (defined(USE_INTERNAL_ISINF) || defined(MISSING_ISINF)) |
95 | #define isinf(x) (!isnan(x) && isnan((x) - (x))) | 53 | #define isinf(x) (!isnan(x) && isnan((x) - (x))) |
@@ -146,12 +104,6 @@ typedef struct { | |||
146 | char *char2escape[256]; /* Encoding */ | 104 | char *char2escape[256]; /* Encoding */ |
147 | #endif | 105 | #endif |
148 | strbuf_t encode_buf; | 106 | strbuf_t encode_buf; |
149 | #if defined(USE_POSIX_USELOCALE) | ||
150 | locale_t saved_locale; | ||
151 | locale_t posix_locale; | ||
152 | #elif defined(USE_POSIX_SETLOCALE) | ||
153 | const char *saved_locale; | ||
154 | #endif | ||
155 | char number_fmt[8]; /* "%.XXg\0" */ | 107 | char number_fmt[8]; /* "%.XXg\0" */ |
156 | int current_depth; | 108 | int current_depth; |
157 | 109 | ||
@@ -395,10 +347,6 @@ static int json_destroy_config(lua_State *l) | |||
395 | json_config_t *cfg; | 347 | json_config_t *cfg; |
396 | 348 | ||
397 | cfg = lua_touserdata(l, 1); | 349 | cfg = lua_touserdata(l, 1); |
398 | #ifdef USE_POSIX_USELOCALE | ||
399 | if (cfg->posix_locale) | ||
400 | freelocale(cfg->posix_locale); | ||
401 | #endif | ||
402 | if (cfg) | 350 | if (cfg) |
403 | strbuf_free(&cfg->encode_buf); | 351 | strbuf_free(&cfg->encode_buf); |
404 | cfg = NULL; | 352 | cfg = NULL; |
@@ -420,13 +368,6 @@ static void json_create_config(lua_State *l) | |||
420 | lua_setmetatable(l, -2); | 368 | lua_setmetatable(l, -2); |
421 | 369 | ||
422 | strbuf_init(&cfg->encode_buf, 0); | 370 | strbuf_init(&cfg->encode_buf, 0); |
423 | #ifdef USE_POSIX_USELOCALE | ||
424 | cfg->saved_locale = NULL; | ||
425 | /* Must not lua_error() before cfg->posix_locale has been initialised */ | ||
426 | cfg->posix_locale = newlocale(LC_ALL_MASK, "C", NULL); | ||
427 | if (!cfg->posix_locale) | ||
428 | luaL_error(l, "Failed to create POSIX locale for JSON"); | ||
429 | #endif | ||
430 | 371 | ||
431 | cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT; | 372 | cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT; |
432 | cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO; | 373 | cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO; |
@@ -490,7 +431,6 @@ static void json_encode_exception(lua_State *l, json_config_t *cfg, int lindex, | |||
490 | { | 431 | { |
491 | if (!cfg->encode_keep_buffer) | 432 | if (!cfg->encode_keep_buffer) |
492 | strbuf_free(&cfg->encode_buf); | 433 | strbuf_free(&cfg->encode_buf); |
493 | LOCALE_RESTORE(cfg); | ||
494 | luaL_error(l, "Cannot serialise %s: %s", | 434 | luaL_error(l, "Cannot serialise %s: %s", |
495 | lua_typename(l, lua_type(l, lindex)), reason); | 435 | lua_typename(l, lua_type(l, lindex)), reason); |
496 | } | 436 | } |
@@ -581,7 +521,6 @@ static void json_encode_descend(lua_State *l, json_config_t *cfg) | |||
581 | if (cfg->current_depth > cfg->encode_max_depth) { | 521 | if (cfg->current_depth > cfg->encode_max_depth) { |
582 | if (!cfg->encode_keep_buffer) | 522 | if (!cfg->encode_keep_buffer) |
583 | strbuf_free(&cfg->encode_buf); | 523 | strbuf_free(&cfg->encode_buf); |
584 | LOCALE_RESTORE(cfg); | ||
585 | luaL_error(l, "Cannot serialise, excessive nesting (%d)", | 524 | luaL_error(l, "Cannot serialise, excessive nesting (%d)", |
586 | cfg->current_depth); | 525 | cfg->current_depth); |
587 | } | 526 | } |
@@ -746,13 +685,9 @@ static int json_encode(lua_State *l) | |||
746 | else | 685 | else |
747 | strbuf_init(&cfg->encode_buf, 0); | 686 | strbuf_init(&cfg->encode_buf, 0); |
748 | 687 | ||
749 | LOCALE_SET_POSIX(cfg); | ||
750 | |||
751 | json_append_data(l, cfg, &cfg->encode_buf); | 688 | json_append_data(l, cfg, &cfg->encode_buf); |
752 | json = strbuf_string(&cfg->encode_buf, &len); | 689 | json = strbuf_string(&cfg->encode_buf, &len); |
753 | 690 | ||
754 | LOCALE_RESTORE(cfg); | ||
755 | |||
756 | lua_pushlstring(l, json, len); | 691 | lua_pushlstring(l, json, len); |
757 | 692 | ||
758 | if (!cfg->encode_keep_buffer) | 693 | if (!cfg->encode_keep_buffer) |
@@ -1133,8 +1068,6 @@ static void json_throw_parse_error(lua_State *l, json_parse_t *json, | |||
1133 | else | 1068 | else |
1134 | found = json_token_type_name[token->type]; | 1069 | found = json_token_type_name[token->type]; |
1135 | 1070 | ||
1136 | LOCALE_RESTORE(json->cfg); | ||
1137 | |||
1138 | /* Note: token->index is 0 based, display starting from 1 */ | 1071 | /* Note: token->index is 0 based, display starting from 1 */ |
1139 | luaL_error(l, "Expected %s but found %s at character %d", | 1072 | luaL_error(l, "Expected %s but found %s at character %d", |
1140 | exp, found, token->index + 1); | 1073 | exp, found, token->index + 1); |
@@ -1146,7 +1079,6 @@ static void json_decode_checkstack(lua_State *l, json_parse_t *json, int n) | |||
1146 | return; | 1079 | return; |
1147 | 1080 | ||
1148 | strbuf_free(json->tmp); | 1081 | strbuf_free(json->tmp); |
1149 | LOCALE_RESTORE(json->cfg); | ||
1150 | luaL_error(l, "Too many nested data structures"); | 1082 | luaL_error(l, "Too many nested data structures"); |
1151 | } | 1083 | } |
1152 | 1084 | ||
@@ -1276,8 +1208,6 @@ static void lua_json_decode(lua_State *l, const char *json_text, int json_len) | |||
1276 | * string must be smaller than the entire json string */ | 1208 | * string must be smaller than the entire json string */ |
1277 | json.tmp = strbuf_new(json_len); | 1209 | json.tmp = strbuf_new(json_len); |
1278 | 1210 | ||
1279 | LOCALE_SET_POSIX(json.cfg); | ||
1280 | |||
1281 | json_next_token(&json, &token); | 1211 | json_next_token(&json, &token); |
1282 | json_process_value(l, &json, &token); | 1212 | json_process_value(l, &json, &token); |
1283 | 1213 | ||
@@ -1287,8 +1217,6 @@ static void lua_json_decode(lua_State *l, const char *json_text, int json_len) | |||
1287 | if (token.type != T_END) | 1217 | if (token.type != T_END) |
1288 | json_throw_parse_error(l, &json, "the end", &token); | 1218 | json_throw_parse_error(l, &json, "the end", &token); |
1289 | 1219 | ||
1290 | LOCALE_RESTORE(json.cfg); | ||
1291 | |||
1292 | strbuf_free(json.tmp); | 1220 | strbuf_free(json.tmp); |
1293 | } | 1221 | } |
1294 | 1222 | ||
@@ -47,20 +47,6 @@ LuaRocks:: Unix, Windows | |||
47 | Build options (#define) | 47 | Build options (#define) |
48 | ~~~~~~~~~~~~~~~~~~~~~~~ | 48 | ~~~~~~~~~~~~~~~~~~~~~~~ |
49 | 49 | ||
50 | Lua CJSON uses +strtod+(3) and +snprintf+(3) to perform numeric | ||
51 | conversion as they are usually well supported, fast and bug free. Lua | ||
52 | CJSON may optionally be compiled with (only) one of the following | ||
53 | preprocessor macros to support locales with comma decimal separators: | ||
54 | |||
55 | [horizontal] | ||
56 | USE_POSIX_USELOCALE:: Thread safe. Supported by Linux and Mac OSX. | ||
57 | Recommended where available. | ||
58 | |||
59 | USE_POSIX_SETLOCALE:: Use only with single threaded programs. | ||
60 | Works on all ANSI C platforms. | ||
61 | |||
62 | Also available: | ||
63 | |||
64 | [horizontal] | 50 | [horizontal] |
65 | USE_INTERNAL_ISINF:: Workaround for Solaris platforms missing isinf(). | 51 | USE_INTERNAL_ISINF:: Workaround for Solaris platforms missing isinf(). |
66 | 52 | ||