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
Diffstat (limited to '')
| -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 | ||
