summaryrefslogtreecommitdiff
path: root/lua_cjson.c
diff options
context:
space:
mode:
authorMark Pulford <mark@kyne.com.au>2011-12-30 17:48:12 +1030
committerMark Pulford <mark@kyne.com.au>2011-12-30 17:48:12 +1030
commit85bf3b798f6d52c374c35f7fbe47df132891d3b2 (patch)
tree39b0da8e6d6536cdd90038547a985559102962de /lua_cjson.c
parent2416b145073211b840781da6abf4b6d97f4657a6 (diff)
downloadlua-cjson-85bf3b798f6d52c374c35f7fbe47df132891d3b2.tar.gz
lua-cjson-85bf3b798f6d52c374c35f7fbe47df132891d3b2.tar.bz2
lua-cjson-85bf3b798f6d52c374c35f7fbe47df132891d3b2.zip
Add support for Lua 5.2 and cjson.new
Update all Lua scripts to use new module init style everywhere: local json = require "cjson" Lua CJSON does not register a global table under Lua 5.2. The global table can be disabled under Lua 5.1 with DISABLE_CJSON_GLOBAL. Other changes: - Store CJSON configuration as an upvalue for each function. - Add "cjson.new" function to create another module table with a separate configuration. - Add _NAME and _VERSION variables.
Diffstat (limited to 'lua_cjson.c')
-rw-r--r--lua_cjson.c73
1 files changed, 57 insertions, 16 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
index 8e9b237..be5cdc2 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -45,6 +45,10 @@
45#include "strbuf.h" 45#include "strbuf.h"
46#include "fpconv.h" 46#include "fpconv.h"
47 47
48#ifndef CJSON_MODNAME
49#define CJSON_MODNAME "cjson"
50#endif
51
48#ifndef CJSON_VERSION 52#ifndef CJSON_VERSION
49#define CJSON_VERSION "1.0devel" 53#define CJSON_VERSION "1.0devel"
50#endif 54#endif
@@ -175,22 +179,16 @@ static const char *char2escape[256] = {
175 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 179 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
176}; 180};
177 181
178static int json_config_key;
179
180/* ===== CONFIGURATION ===== */ 182/* ===== CONFIGURATION ===== */
181 183
182static json_config_t *json_fetch_config(lua_State *l) 184static json_config_t *json_fetch_config(lua_State *l)
183{ 185{
184 json_config_t *cfg; 186 json_config_t *cfg;
185 187
186 lua_pushlightuserdata(l, &json_config_key); 188 cfg = lua_touserdata(l, lua_upvalueindex(1));
187 lua_gettable(l, LUA_REGISTRYINDEX);
188 cfg = lua_touserdata(l, -1);
189 if (!cfg) 189 if (!cfg)
190 luaL_error(l, "BUG: Unable to fetch CJSON configuration"); 190 luaL_error(l, "BUG: Unable to fetch CJSON configuration");
191 191
192 lua_pop(l, 1);
193
194 return cfg; 192 return cfg;
195} 193}
196 194
@@ -1246,7 +1244,27 @@ static int json_decode(lua_State *l)
1246 1244
1247/* ===== INITIALISATION ===== */ 1245/* ===== INITIALISATION ===== */
1248 1246
1249int luaopen_cjson(lua_State *l) 1247#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
1248/* Compatibility for Lua 5.1.
1249 *
1250 * luaL_setfuncs() is used to create a module table where the functions have
1251 * json_config_t as their first upvalue. Code borrowed from Lua 5.2 source. */
1252static void luaL_setfuncs (lua_State *l, const luaL_Reg *reg, int nup)
1253{
1254 int i;
1255
1256 luaL_checkstack(l, nup, "too many upvalues");
1257 for (; reg->name != NULL; reg++) { /* fill the table with given functions */
1258 for (i = 0; i < nup; i++) /* copy upvalues to the top */
1259 lua_pushvalue(l, -nup);
1260 lua_pushcclosure(l, reg->func, nup); /* closure with those upvalues */
1261 lua_setfield(l, -(nup + 2), reg->name);
1262 }
1263 lua_pop(l, nup); /* remove upvalues */
1264}
1265#endif
1266
1267static int lua_cjson_new(lua_State *l)
1250{ 1268{
1251 luaL_Reg reg[] = { 1269 luaL_Reg reg[] = {
1252 { "encode", json_encode }, 1270 { "encode", json_encode },
@@ -1257,28 +1275,51 @@ int luaopen_cjson(lua_State *l)
1257 { "encode_keep_buffer", json_cfg_encode_keep_buffer }, 1275 { "encode_keep_buffer", json_cfg_encode_keep_buffer },
1258 { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers }, 1276 { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers },
1259 { "update_locale", json_update_locale }, 1277 { "update_locale", json_update_locale },
1278 { "new", lua_cjson_new },
1260 { NULL, NULL } 1279 { NULL, NULL }
1261 }; 1280 };
1262 1281
1263 /* Update the current locale for g_fmt/strtod */ 1282 /* Update the current locale for g_fmt/strtod.
1283 * Using different locales per-thread is not supported. */
1264 fpconv_update_locale(); 1284 fpconv_update_locale();
1265 1285
1266 /* Use json_config_key as a pointer. 1286 /* cjson module table */
1267 * It's faster than using a config string, and more unique */ 1287 lua_newtable(l);
1268 lua_pushlightuserdata(l, &json_config_key);
1269 json_create_config(l);
1270 lua_settable(l, LUA_REGISTRYINDEX);
1271 1288
1272 luaL_register(l, "cjson", reg); 1289 /* Register functions with config data as upvalue */
1290 json_create_config(l);
1291 luaL_setfuncs(l, reg, 1);
1273 1292
1274 /* Set cjson.null */ 1293 /* Set cjson.null */
1275 lua_pushlightuserdata(l, NULL); 1294 lua_pushlightuserdata(l, NULL);
1276 lua_setfield(l, -2, "null"); 1295 lua_setfield(l, -2, "null");
1277 1296
1278 /* Set cjson.version */ 1297 /* Set module name / version fields */
1298 lua_pushliteral(l, CJSON_MODNAME);
1299 lua_setfield(l, -2, "_NAME");
1300 lua_pushliteral(l, CJSON_VERSION);
1301 lua_setfield(l, -2, "_VERSION");
1279 lua_pushliteral(l, CJSON_VERSION); 1302 lua_pushliteral(l, CJSON_VERSION);
1280 lua_setfield(l, -2, "version"); 1303 lua_setfield(l, -2, "version");
1281 1304
1305 return 1;
1306}
1307
1308int luaopen_cjson(lua_State *l)
1309{
1310 lua_cjson_new(l);
1311
1312#if !defined(DISABLE_CJSON_GLOBAL) && (!defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502)
1313 /* Register a global "cjson" table to maintain compatibility with earlier
1314 * versions of Lua CJSON which used luaL_register() under Lua 5.1.
1315 *
1316 * From Lua 5.2 onwards, Lua CJSON does not automatically register a global
1317 * table.
1318 */
1319 lua_pushvalue(l, -1);
1320 lua_setglobal(l, CJSON_MODNAME);
1321#endif
1322
1282 /* Return cjson table */ 1323 /* Return cjson table */
1283 return 1; 1324 return 1;
1284} 1325}