webmcp
diff libraries/json/json.c @ 155:185e944182cb
Better C macros for null-marker in JSON library
author | jbe |
---|---|
date | Thu Jul 31 03:18:04 2014 +0200 (2014-07-31) |
parents | c8669dde9ce2 |
children | 004d2d50419e |
line diff
1.1 --- a/libraries/json/json.c Thu Jul 31 03:01:53 2014 +0200 1.2 +++ b/libraries/json/json.c Thu Jul 31 03:18:04 2014 +0200 1.3 @@ -14,21 +14,19 @@ 1.4 // returning nil and an error string). 1.5 #define JSON_MAXDEPTH 500 1.6 1.7 +// generate dummy memory addresses that represents null values: 1.8 +char json_nullmark; 1.9 +#define json_isnullmark(L, i) (lua_touserdata((L), (i)) == &json_nullmark) 1.10 +#define json_pushnullmark(L) lua_pushlightuserdata((L), &json_nullmark) 1.11 + 1.12 // macros for usage of Lua registry: 1.13 #define JSON_REGENT char 1.14 #define JSON_REGPOINTER void * 1.15 -#define json_pushlightref(L, x) lua_pushlightuserdata((L), &json_reference.x) 1.16 -#define json_islightref(L, i, x) (lua_touserdata((L), (i)) == &json_reference.x) 1.17 #define json_regpointer(x) (&json_registry.x) 1.18 #define json_regfetchpointer(L, x) lua_rawgetp((L), LUA_REGISTRYINDEX, (x)) 1.19 #define json_regfetch(L, x) json_regfetchpointer(L, json_regpointer(x)) 1.20 #define json_regstore(L, x) lua_rawsetp(L, LUA_REGISTRYINDEX, json_regpointer(x)) 1.21 1.22 -// generate dummy memory addresses that represent non-modifiable lightuserdata (dummy) objects: 1.23 -static struct { 1.24 - JSON_REGENT nullmark; // magic value to indicate JSON null value in shadow table 1.25 -} json_reference; 1.26 - 1.27 // generate dummy memory addresses that represent Lua objects 1.28 // via lightuserdata keys and LUA_REGISTRYINDEX: 1.29 static struct { 1.30 @@ -109,7 +107,6 @@ 1.31 #define json_import_objectmt_idx 2 1.32 #define json_import_arraymt_idx 3 1.33 #define json_import_shadowtbl_idx 4 1.34 -#define json_import_nullmark_idx 5 1.35 1.36 // decodes a JSON document: 1.37 static int json_import(lua_State *L) { 1.38 @@ -131,8 +128,6 @@ 1.39 json_regfetch(L, arraymt); 1.40 // push shadowtbl onto stack position 4: 1.41 json_regfetch(L, shadowtbl); 1.42 - // push nullmark onto stack position 5: 1.43 - json_pushlightref(L, nullmark); 1.44 // require string as first argument: 1.45 str = luaL_checklstring(L, 1, &total); 1.46 // if string contains a NULL byte, this is a syntax error 1.47 @@ -386,7 +381,7 @@ 1.48 if (level) { 1.49 // if sub-level, 1.50 // push special null-marker onto stack: 1.51 - lua_pushvalue(L, json_import_nullmark_idx); 1.52 + json_pushnullmark(L); 1.53 } else { 1.54 // if top-level, 1.55 // push nil onto stack: 1.56 @@ -446,10 +441,9 @@ 1.57 1.58 // special Lua stack indicies for json_path function: 1.59 #define json_path_shadowtbl_idx 1 1.60 -#define json_path_nullmark_idx 2 1.61 1.62 // stack offset of arguments to json_path function: 1.63 -#define json_path_idxshift 2 1.64 +#define json_path_idxshift 1 1.65 1.66 // gets a value or its type from a JSON document (passed as first argument) 1.67 // using a path (passed as variable number of keys after first argument): 1.68 @@ -459,9 +453,6 @@ 1.69 // insert shadowtbl into stack at position 1 (shifting the arguments): 1.70 json_regfetch(L, shadowtbl); 1.71 lua_insert(L, 1); 1.72 - // insert nullmark into stack at position 2 (shifting the arguments): 1.73 - json_pushlightref(L, nullmark); 1.74 - lua_insert(L, 2); 1.75 // store stack index of top of stack: 1.76 stacktop = lua_gettop(L); 1.77 // use first argument as "current value" (stored on top of stack): 1.78 @@ -501,11 +492,11 @@ 1.79 if (!type_mode) { 1.80 // if a value (and not its type) was requested, 1.81 // check if value is the null-marker, and store nil on top of Lua stack in that case: 1.82 - if (lua_rawequal(L, -1, json_path_nullmark_idx)) lua_pushnil(L); 1.83 + if (json_isnullmark(L, -1)) lua_pushnil(L); 1.84 } else { 1.85 // if the type was requested, 1.86 // check if value is the null-marker: 1.87 - if (lua_rawequal(L, -1, json_path_nullmark_idx)) { 1.88 + if (json_isnullmark(L, -1)) { 1.89 // if yes, store string "null" on top of Lua stack: 1.90 lua_pushliteral(L, "null"); 1.91 } else { 1.92 @@ -608,7 +599,7 @@ 1.93 } 1.94 // push key (second argument) and null-marker after shadow table onto stack: 1.95 lua_pushvalue(L, 2); 1.96 - json_pushlightref(L, nullmark); 1.97 + json_pushnullmark(L); 1.98 // store key and null-marker in shadow table: 1.99 lua_rawset(L, -3); 1.100 // return nothing: 1.101 @@ -628,27 +619,20 @@ 1.102 return 1; 1.103 } 1.104 1.105 -// special Lua stack indicies for json_index function: 1.106 -#define json_index_nullmark_idx 3 1.107 -#define json_index_shadowtbl_idx 4 1.108 - 1.109 static int json_index(lua_State *L) { 1.110 // stack shall contain two function arguments: 1.111 lua_settop(L, 2); 1.112 - // push nullmark onto stack position 3: 1.113 - json_pushlightref(L, nullmark); 1.114 - // push shadowtbl onto stack position 4: 1.115 + // get corresponding shadow table for first argument: 1.116 json_regfetch(L, shadowtbl); 1.117 - // get corresponding shadow table for first argument: 1.118 lua_pushvalue(L, 1); 1.119 - lua_rawget(L, json_index_shadowtbl_idx); 1.120 + lua_rawget(L, -2); 1.121 // throw error if no shadow table was found: 1.122 if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found"); 1.123 // use key passed as second argument to lookup value in shadow table: 1.124 lua_pushvalue(L, 2); 1.125 lua_rawget(L, -2); 1.126 // if value is null-marker, then push nil onto stack: 1.127 - if (lua_rawequal(L, -1, json_index_nullmark_idx)) lua_pushnil(L); 1.128 + if (json_isnullmark(L, -1)) lua_pushnil(L); 1.129 // return either looked up value, or nil 1.130 return 1; 1.131 } 1.132 @@ -671,20 +655,13 @@ 1.133 return 0; 1.134 } 1.135 1.136 -// special Lua stack indicies for json_pairs_iterfunc function: 1.137 -#define json_pairs_iterfunc_nullmark_idx 3 1.138 -#define json_pairs_iterfunc_shadowtbl_idx 4 1.139 - 1.140 static int json_pairs_iterfunc(lua_State *L) { 1.141 // stack shall contain two function arguments: 1.142 lua_settop(L, 2); 1.143 - // push nullmark onto stack position 3: 1.144 - json_pushlightref(L, nullmark); 1.145 - // push shadowtbl onto stack position 4: 1.146 + // get corresponding shadow table for first argument: 1.147 json_regfetch(L, shadowtbl); 1.148 - // get corresponding shadow table for first argument: 1.149 lua_pushvalue(L, 1); 1.150 - lua_rawget(L, json_pairs_iterfunc_shadowtbl_idx); 1.151 + lua_rawget(L, -2); 1.152 // throw error if no shadow table was found: 1.153 if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found"); 1.154 // get next key value pair from shadow table (using previous key from argument 2) 1.155 @@ -692,7 +669,7 @@ 1.156 lua_pushvalue(L, 2); 1.157 if (!lua_next(L, -2)) return 0; 1.158 // replace null-marker with nil: 1.159 - if (lua_rawequal(L, -1, json_pairs_iterfunc_nullmark_idx)) { 1.160 + if (json_isnullmark(L, -1)) { 1.161 lua_pop(L, 1); 1.162 lua_pushnil(L); 1.163 } 1.164 @@ -710,23 +687,16 @@ 1.165 return 3; 1.166 } 1.167 1.168 -// special Lua stack indicies for json_ipairs_iterfunc function: 1.169 -#define json_ipairs_iterfunc_nullmark_idx 3 1.170 -#define json_ipairs_iterfunc_shadowtbl_idx 4 1.171 - 1.172 static int json_ipairs_iterfunc(lua_State *L) { 1.173 lua_Integer idx; 1.174 // stack shall contain two function arguments: 1.175 lua_settop(L, 2); 1.176 - // push nullmark onto stack position 3: 1.177 - json_pushlightref(L, nullmark); 1.178 - // push shadowtbl onto stack position 4: 1.179 - json_regfetch(L, shadowtbl); 1.180 // calculate new index by incrementing second argument: 1.181 idx = lua_tointeger(L, 2) + 1; 1.182 // get corresponding shadow table for first argument: 1.183 + json_regfetch(L, shadowtbl); 1.184 lua_pushvalue(L, 1); 1.185 - lua_rawget(L, json_ipairs_iterfunc_shadowtbl_idx); 1.186 + lua_rawget(L, -2); 1.187 // throw error if no shadow table was found: 1.188 if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found"); 1.189 // do integer lookup in shadow table: 1.190 @@ -737,7 +707,7 @@ 1.191 // either the looked up value if it is not equal to the null-marker 1.192 // or nil instead of null-marker: 1.193 lua_pushinteger(L, idx); 1.194 - if (lua_rawequal(L, -2, json_ipairs_iterfunc_nullmark_idx)) lua_pushnil(L); 1.195 + if (json_isnullmark(L, -2)) lua_pushnil(L); 1.196 else lua_pushvalue(L, -2); 1.197 return 2; 1.198 } 1.199 @@ -852,7 +822,7 @@ 1.200 lua_call(L, 1, 1); 1.201 luaL_addvalue(&buf); 1.202 luaL_addchar(&buf, ':'); 1.203 - if (json_islightref(L, 3, nullmark)) { 1.204 + if (json_isnullmark(L, 3)) { 1.205 luaL_addstring(&buf, "null"); 1.206 } else { 1.207 lua_pushcfunction(L, json_export);