diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-01-27 11:46:16 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-01-27 11:46:16 -0200 |
commit | 41ed3c47719b29dd02dc9fcf07f79dc6f2c4381d (patch) | |
tree | 0481135889c06eded52f6573f203742ab64186c1 /lauxlib.c | |
parent | 635b7c707d146ab56127260601b6fb84c0c140f3 (diff) | |
download | lua-41ed3c47719b29dd02dc9fcf07f79dc6f2c4381d.tar.gz lua-41ed3c47719b29dd02dc9fcf07f79dc6f2c4381d.tar.bz2 lua-41ed3c47719b29dd02dc9fcf07f79dc6f2c4381d.zip |
getn/setn in C moved to lauxlib
Diffstat (limited to 'lauxlib.c')
-rw-r--r-- | lauxlib.c | 85 |
1 files changed, 83 insertions, 2 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.c,v 1.91 2002/12/04 17:38:31 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.92 2003/01/23 11:34:18 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -23,6 +23,13 @@ | |||
23 | #include "lauxlib.h" | 23 | #include "lauxlib.h" |
24 | 24 | ||
25 | 25 | ||
26 | /* number of prereserved references (for internal use) */ | ||
27 | #define RESERVED_REFS 1 | ||
28 | |||
29 | /* reserved reference for array sizes */ | ||
30 | #define ARRAYSIZE_REF 1 | ||
31 | |||
32 | |||
26 | /* | 33 | /* |
27 | ** {====================================================== | 34 | ** {====================================================== |
28 | ** Error-report functions | 35 | ** Error-report functions |
@@ -197,6 +204,78 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, | |||
197 | 204 | ||
198 | /* | 205 | /* |
199 | ** {====================================================== | 206 | ** {====================================================== |
207 | ** getn-setn: size for arrays | ||
208 | ** ======================================================= | ||
209 | */ | ||
210 | |||
211 | static int checkint (lua_State *L, int topop) { | ||
212 | int n = (int)lua_tonumber(L, -1); | ||
213 | if (n == 0 && !lua_isnumber(L, -1)) n = -1; | ||
214 | lua_pop(L, topop); | ||
215 | return n; | ||
216 | } | ||
217 | |||
218 | |||
219 | static void getsizes (lua_State *L) { | ||
220 | lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); | ||
221 | if (lua_isnil(L, -1)) { /* no `size' table? */ | ||
222 | lua_newtable(L); /* create it */ | ||
223 | lua_pushvalue(L, -1); /* `size' will be its own metatable */ | ||
224 | lua_setmetatable(L, -2); | ||
225 | lua_pushliteral(L, "__mode"); | ||
226 | lua_pushliteral(L, "k"); | ||
227 | lua_rawset(L, -3); /* metatable(N).__mode = "k" */ | ||
228 | lua_pushvalue(L, -1); | ||
229 | lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */ | ||
230 | } | ||
231 | } | ||
232 | |||
233 | |||
234 | void luaL_setn (lua_State *L, int t, int n) { | ||
235 | lua_pushliteral(L, "n"); | ||
236 | lua_rawget(L, t); | ||
237 | if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ | ||
238 | lua_pushliteral(L, "n"); /* use it */ | ||
239 | lua_pushnumber(L, n); | ||
240 | lua_rawset(L, t); | ||
241 | } | ||
242 | else { /* use `sizes' */ | ||
243 | getsizes(L); | ||
244 | lua_pushvalue(L, t); | ||
245 | lua_pushnumber(L, n); | ||
246 | lua_rawset(L, -3); /* sizes[t] = n */ | ||
247 | lua_pop(L, 1); /* remove `sizes' */ | ||
248 | } | ||
249 | } | ||
250 | |||
251 | |||
252 | int luaL_getn (lua_State *L, int t) { | ||
253 | int n; | ||
254 | lua_pushliteral(L, "n"); /* try t.n */ | ||
255 | lua_rawget(L, t); | ||
256 | if ((n = checkint(L, 1)) >= 0) return n; | ||
257 | getsizes(L); /* else try sizes[t] */ | ||
258 | lua_pushvalue(L, t); | ||
259 | lua_rawget(L, -2); | ||
260 | if ((n = checkint(L, 2)) >= 0) return n; | ||
261 | else { /* must count elements */ | ||
262 | for (n = 1; ; n++) { | ||
263 | lua_rawgeti(L, t, n); | ||
264 | if (lua_isnil(L, -1)) break; | ||
265 | lua_pop(L, 1); | ||
266 | } | ||
267 | lua_pop(L, 1); | ||
268 | luaL_setn(L, t, n - 1); | ||
269 | return n - 1; | ||
270 | } | ||
271 | } | ||
272 | |||
273 | /* }====================================================== */ | ||
274 | |||
275 | |||
276 | |||
277 | /* | ||
278 | ** {====================================================== | ||
200 | ** Generic Buffer manipulation | 279 | ** Generic Buffer manipulation |
201 | ** ======================================================= | 280 | ** ======================================================= |
202 | */ | 281 | */ |
@@ -308,8 +387,10 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { | |||
308 | lua_pushliteral(L, "n"); | 387 | lua_pushliteral(L, "n"); |
309 | lua_pushvalue(L, -1); | 388 | lua_pushvalue(L, -1); |
310 | lua_rawget(L, t); /* get t.n */ | 389 | lua_rawget(L, t); /* get t.n */ |
311 | ref = (int)lua_tonumber(L, -1) + 1; /* ref = t.n + 1 */ | 390 | ref = (int)lua_tonumber(L, -1); /* ref = t.n */ |
312 | lua_pop(L, 1); /* pop t.n */ | 391 | lua_pop(L, 1); /* pop t.n */ |
392 | if (ref == 0) ref = RESERVED_REFS; /* skip reserved references */ | ||
393 | ref++; /* create new reference */ | ||
313 | lua_pushnumber(L, ref); | 394 | lua_pushnumber(L, ref); |
314 | lua_rawset(L, t); /* t.n = t.n + 1 */ | 395 | lua_rawset(L, t); /* t.n = t.n + 1 */ |
315 | } | 396 | } |