aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Pulford <mark@kyne.com.au>2011-12-29 23:53:11 +1030
committerMark Pulford <mark@kyne.com.au>2011-12-29 23:53:11 +1030
commit6cc88e3ac5275868e168acaf60203563f131355b (patch)
treec574da2dff2c4e95cc6d39d6de2393b64eedf4fc
parent155393d5bd801ce5dbd76020facecd9270679e94 (diff)
downloadlua-cjson-6cc88e3ac5275868e168acaf60203563f131355b.tar.gz
lua-cjson-6cc88e3ac5275868e168acaf60203563f131355b.tar.bz2
lua-cjson-6cc88e3ac5275868e168acaf60203563f131355b.zip
Remove POSIX locale workaround
-rw-r--r--CMakeLists.txt10
-rw-r--r--Makefile14
-rw-r--r--lua-cjson-1.0devel-1.rockspec15
-rw-r--r--lua-cjson.spec3
-rw-r--r--lua_cjson.c72
-rw-r--r--manual.txt14
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)
11find_package(Lua51 REQUIRED) 11find_package(Lua51 REQUIRED)
12include_directories(${LUA_INCLUDE_DIR}) 12include_directories(${LUA_INCLUDE_DIR})
13 13
14# Use thread-safe POSIX.1-2008 uselocale() where available, otherwise
15# fall back to ANSI C setlocale().
16include(CheckFunctionExists)
17CHECK_FUNCTION_EXISTS(uselocale HAVE_USELOCALE)
18if(HAVE_USELOCALE)
19 add_definitions(-DUSE_POSIX_USELOCALE)
20else()
21 add_definitions(-DUSE_POSIX_SETLOCALE)
22endif()
23
24# Handle platforms missing isinf() macro (Eg, some Solaris systems). 14# Handle platforms missing isinf() macro (Eg, some Solaris systems).
25include(CheckSymbolExists) 15include(CheckSymbolExists)
26CHECK_SYMBOL_EXISTS(isinf math.h HAVE_ISINF) 16CHECK_SYMBOL_EXISTS(isinf math.h HAVE_ISINF)
diff --git a/Makefile b/Makefile
index 9b1b649..7685363 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,6 @@
1LUA_VERSION = 5.1 1LUA_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
15PREFIX = /usr/local 8PREFIX = /usr/local
16#CFLAGS = -g -Wall -pedantic -fno-inline 9#CFLAGS = -g -Wall -pedantic -fno-inline
17CFLAGS = -O3 -Wall -pedantic 10CFLAGS = -O3 -Wall -pedantic
18CJSON_CFLAGS = -DUSE_POSIX_SETLOCALE
19CJSON_LDFLAGS = -shared 11CJSON_LDFLAGS = -shared
20LUA_INCLUDE_DIR = $(PREFIX)/include 12LUA_INCLUDE_DIR = $(PREFIX)/include
21LUA_MODULE_DIR = $(PREFIX)/lib/lua/$(LUA_VERSION) 13LUA_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
27make %{?_smp_mflags} CFLAGS="%{optflags}" CJSON_CFLAGS="-DUSE_POSIX_USELOCALE" \ 27make %{?_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
diff --git a/manual.txt b/manual.txt
index 2917339..a3e12cf 100644
--- a/manual.txt
+++ b/manual.txt
@@ -47,20 +47,6 @@ LuaRocks:: Unix, Windows
47Build options (#define) 47Build options (#define)
48~~~~~~~~~~~~~~~~~~~~~~~ 48~~~~~~~~~~~~~~~~~~~~~~~
49 49
50Lua CJSON uses +strtod+(3) and +snprintf+(3) to perform numeric
51conversion as they are usually well supported, fast and bug free. Lua
52CJSON may optionally be compiled with (only) one of the following
53preprocessor macros to support locales with comma decimal separators:
54
55[horizontal]
56USE_POSIX_USELOCALE:: Thread safe. Supported by Linux and Mac OSX.
57Recommended where available.
58
59USE_POSIX_SETLOCALE:: Use only with single threaded programs.
60Works on all ANSI C platforms.
61
62Also available:
63
64[horizontal] 50[horizontal]
65USE_INTERNAL_ISINF:: Workaround for Solaris platforms missing isinf(). 51USE_INTERNAL_ISINF:: Workaround for Solaris platforms missing isinf().
66 52