aboutsummaryrefslogtreecommitdiff
path: root/lauxlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-01-27 11:46:16 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-01-27 11:46:16 -0200
commit41ed3c47719b29dd02dc9fcf07f79dc6f2c4381d (patch)
tree0481135889c06eded52f6573f203742ab64186c1 /lauxlib.c
parent635b7c707d146ab56127260601b6fb84c0c140f3 (diff)
downloadlua-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.c85
1 files changed, 83 insertions, 2 deletions
diff --git a/lauxlib.c b/lauxlib.c
index 9ecec884..9f39b46b 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -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
211static 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
219static 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
234void 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
252int 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 }