aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lauxlib.c85
-rw-r--r--lauxlib.h5
-rw-r--r--ltablib.c65
3 files changed, 94 insertions, 61 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 }
diff --git a/lauxlib.h b/lauxlib.h
index 25d8499c..fb2b0ab6 100644
--- a/lauxlib.h
+++ b/lauxlib.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.h,v 1.55 2002/11/14 15:41:38 roberto Exp roberto $ 2** $Id: lauxlib.h,v 1.56 2003/01/17 15:28:09 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*/
@@ -51,6 +51,9 @@ LUALIB_API int luaL_findstring (const char *st, const char *const lst[]);
51LUALIB_API int luaL_ref (lua_State *L, int t); 51LUALIB_API int luaL_ref (lua_State *L, int t);
52LUALIB_API void luaL_unref (lua_State *L, int t, int ref); 52LUALIB_API void luaL_unref (lua_State *L, int t, int ref);
53 53
54LUALIB_API int luaL_getn (lua_State *L, int t);
55LUALIB_API void luaL_setn (lua_State *L, int t, int n);
56
54LUALIB_API int luaL_loadfile (lua_State *L, const char *filename); 57LUALIB_API int luaL_loadfile (lua_State *L, const char *filename);
55LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz, 58LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
56 const char *name); 59 const char *name);
diff --git a/ltablib.c b/ltablib.c
index 504081bc..c0e773aa 100644
--- a/ltablib.c
+++ b/ltablib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltablib.c,v 1.17 2002/12/04 17:38:31 roberto Exp roberto $ 2** $Id: ltablib.c,v 1.18 2002/12/20 10:26:33 roberto Exp roberto $
3** Library for Table Manipulation 3** Library for Table Manipulation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -15,52 +15,7 @@
15#include "lualib.h" 15#include "lualib.h"
16 16
17 17
18 18#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
19static int checkint (lua_State *L) {
20 int n = (int)lua_tonumber(L, -1);
21 if (n == 0 && !lua_isnumber(L, -1)) n = -1;
22 lua_pop(L, 1);
23 return n;
24}
25
26
27static void aux_setn (lua_State *L, int t, int n) {
28 lua_pushliteral(L, "n");
29 lua_rawget(L, t);
30 if (checkint(L) >= 0) {
31 lua_pushliteral(L, "n"); /* use it */
32 lua_pushnumber(L, n);
33 lua_rawset(L, t);
34 }
35 else { /* use N */
36 lua_pushvalue(L, t);
37 lua_pushnumber(L, n);
38 lua_rawset(L, lua_upvalueindex(1)); /* N[t] = n */
39 }
40}
41
42
43static int aux_getn (lua_State *L, int t) {
44 int n;
45 luaL_checktype(L, t, LUA_TTABLE);
46 lua_pushliteral(L, "n"); /* try t.n */
47 lua_rawget(L, t);
48 if ((n = checkint(L)) >= 0) return n;
49 lua_pushvalue(L, t); /* try N[t] */
50 lua_rawget(L, lua_upvalueindex(1));
51 if ((n = checkint(L)) >= 0) return n;
52 else { /* must count elements */
53 n = 0;
54 for (;;) {
55 lua_rawgeti(L, t, ++n);
56 if (lua_isnil(L, -1)) break;
57 lua_pop(L, 1);
58 }
59 lua_pop(L, 1);
60 aux_setn(L, t, n - 1);
61 return n - 1;
62 }
63}
64 19
65 20
66static int luaB_foreachi (lua_State *L) { 21static int luaB_foreachi (lua_State *L) {
@@ -106,7 +61,7 @@ static int luaB_getn (lua_State *L) {
106 61
107static int luaB_setn (lua_State *L) { 62static int luaB_setn (lua_State *L) {
108 luaL_checktype(L, 1, LUA_TTABLE); 63 luaL_checktype(L, 1, LUA_TTABLE);
109 aux_setn(L, 1, luaL_checkint(L, 2)); 64 luaL_setn(L, 1, luaL_checkint(L, 2));
110 return 0; 65 return 0;
111} 66}
112 67
@@ -122,7 +77,7 @@ static int luaB_tinsert (lua_State *L) {
122 if (pos > n) n = pos; /* `grow' array if necessary */ 77 if (pos > n) n = pos; /* `grow' array if necessary */
123 v = 3; /* function may be called with more than 3 args */ 78 v = 3; /* function may be called with more than 3 args */
124 } 79 }
125 aux_setn(L, 1, n); /* new size */ 80 luaL_setn(L, 1, n); /* new size */
126 while (--n >= pos) { /* move up elements */ 81 while (--n >= pos) { /* move up elements */
127 lua_rawgeti(L, 1, n); 82 lua_rawgeti(L, 1, n);
128 lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ 83 lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */
@@ -137,7 +92,7 @@ static int luaB_tremove (lua_State *L) {
137 int n = aux_getn(L, 1); 92 int n = aux_getn(L, 1);
138 int pos = luaL_optint(L, 2, n); 93 int pos = luaL_optint(L, 2, n);
139 if (n <= 0) return 0; /* table is `empty' */ 94 if (n <= 0) return 0; /* table is `empty' */
140 aux_setn(L, 1, n-1); /* t.n = n-1 */ 95 luaL_setn(L, 1, n-1); /* t.n = n-1 */
141 lua_rawgeti(L, 1, pos); /* result = t[pos] */ 96 lua_rawgeti(L, 1, pos); /* result = t[pos] */
142 for ( ;pos<n; pos++) { 97 for ( ;pos<n; pos++) {
143 lua_rawgeti(L, 1, pos+1); 98 lua_rawgeti(L, 1, pos+1);
@@ -156,7 +111,7 @@ static int str_concat (lua_State *L) {
156 int i = luaL_optint(L, 3, 1); 111 int i = luaL_optint(L, 3, 1);
157 int n = luaL_optint(L, 4, 0); 112 int n = luaL_optint(L, 4, 0);
158 luaL_checktype(L, 1, LUA_TTABLE); 113 luaL_checktype(L, 1, LUA_TTABLE);
159 if (n == 0) n = aux_getn(L, 1); 114 if (n == 0) n = luaL_getn(L, 1);
160 luaL_buffinit(L, &b); 115 luaL_buffinit(L, &b);
161 for (; i <= n; i++) { 116 for (; i <= n; i++) {
162 lua_rawgeti(L, 1, i); 117 lua_rawgeti(L, 1, i);
@@ -289,13 +244,7 @@ static const luaL_reg tab_funcs[] = {
289 244
290 245
291LUALIB_API int lua_tablibopen (lua_State *L) { 246LUALIB_API int lua_tablibopen (lua_State *L) {
292 lua_newtable(L); /* create N (table to store num. elements in tables) */ 247 luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 0);
293 lua_pushvalue(L, -1); /* `N' will be its own metatable */
294 lua_setmetatable(L, -2);
295 lua_pushliteral(L, "__mode");
296 lua_pushliteral(L, "k");
297 lua_rawset(L, -3); /* metatable(N).__mode = "k" */
298 luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 1);
299 return 1; 248 return 1;
300} 249}
301 250