diff options
Diffstat (limited to 'lib/lua/src/LuaLib/ltablib.c')
-rw-r--r-- | lib/lua/src/LuaLib/ltablib.c | 130 |
1 files changed, 79 insertions, 51 deletions
diff --git a/lib/lua/src/LuaLib/ltablib.c b/lib/lua/src/LuaLib/ltablib.c index 71f3afa..6bd11fb 100644 --- a/lib/lua/src/LuaLib/ltablib.c +++ b/lib/lua/src/LuaLib/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.4 2004-11-27 21:46:10 pixel Exp $ +** $Id: ltablib.c,v 1.5 2007-07-27 10:05:55 pixel Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -8,6 +8,7 @@ #include <stddef.h> #define ltablib_c +#define LUA_LIB #include "lua.h" @@ -18,13 +19,13 @@ #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) -static int luaB_foreachi (lua_State *L) { +static int foreachi (lua_State *L) { int i; int n = aux_getn(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); - for (i=1; i<=n; i++) { + for (i=1; i <= n; i++) { lua_pushvalue(L, 2); /* function */ - lua_pushnumber(L, (lua_Number)i); /* 1st argument */ + lua_pushinteger(L, i); /* 1st argument */ lua_rawgeti(L, 1, i); /* 2nd argument */ lua_call(L, 2, 1); if (!lua_isnil(L, -1)) @@ -35,13 +36,11 @@ static int luaB_foreachi (lua_State *L) { } -static int luaB_foreach (lua_State *L) { +static int foreach (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 2, LUA_TFUNCTION); lua_pushnil(L); /* first key */ - for (;;) { - if (lua_next(L, 1) == 0) - return 0; + while (lua_next(L, 1)) { lua_pushvalue(L, 2); /* function */ lua_pushvalue(L, -3); /* key */ lua_pushvalue(L, -3); /* value */ @@ -50,74 +49,102 @@ static int luaB_foreach (lua_State *L) { return 1; lua_pop(L, 2); /* remove value and result */ } + return 0; +} + + +static int maxn (lua_State *L) { + lua_Number max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pop(L, 1); /* remove value */ + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_Number v = lua_tonumber(L, -1); + if (v > max) max = v; + } + } + lua_pushnumber(L, max); + return 1; } -static int luaB_getn (lua_State *L) { - lua_pushnumber(L, (lua_Number)aux_getn(L, 1)); +static int getn (lua_State *L) { + lua_pushinteger(L, aux_getn(L, 1)); return 1; } -static int luaB_setn (lua_State *L) { +static int setn (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); +#ifndef luaL_setn luaL_setn(L, 1, luaL_checkint(L, 2)); - return 0; +#else + luaL_error(L, LUA_QL("setn") " is obsolete"); +#endif + lua_pushvalue(L, 1); + return 1; } -static int luaB_tinsert (lua_State *L) { - int v = lua_gettop(L); /* number of arguments */ - int n = aux_getn(L, 1) + 1; +static int tinsert (lua_State *L) { + int e = aux_getn(L, 1) + 1; /* first empty element */ int pos; /* where to insert new element */ - if (v == 2) /* called with only 2 arguments */ - pos = n; /* insert new element at the end */ - else { - pos = luaL_checkint(L, 2); /* 2nd argument is the position */ - if (pos > n) n = pos; /* `grow' array if necessary */ - v = 3; /* function may be called with more than 3 args */ - } - luaL_setn(L, 1, n); /* new size */ - while (--n >= pos) { /* move up elements */ - lua_rawgeti(L, 1, n); - lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ + switch (lua_gettop(L)) { + case 2: { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: { + int i; + pos = luaL_checkint(L, 2); /* 2nd argument is the position */ + if (pos > e) e = pos; /* `grow' array if necessary */ + for (i = e; i > pos; i--) { /* move up elements */ + lua_rawgeti(L, 1, i-1); + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ + } + break; + } + default: { + return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + } } - lua_pushvalue(L, v); + luaL_setn(L, 1, e); /* new size */ lua_rawseti(L, 1, pos); /* t[pos] = v */ return 0; } -static int luaB_tremove (lua_State *L) { - int n = aux_getn(L, 1); - int pos = luaL_optint(L, 2, n); - if (n <= 0) return 0; /* table is `empty' */ - luaL_setn(L, 1, n-1); /* t.n = n-1 */ +static int tremove (lua_State *L) { + int e = aux_getn(L, 1); + int pos = luaL_optint(L, 2, e); + if (e == 0) return 0; /* table is `empty' */ + luaL_setn(L, 1, e - 1); /* t.n = n-1 */ lua_rawgeti(L, 1, pos); /* result = t[pos] */ - for ( ;pos<n; pos++) { + for ( ;pos<e; pos++) { lua_rawgeti(L, 1, pos+1); lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ } lua_pushnil(L); - lua_rawseti(L, 1, n); /* t[n] = nil */ + lua_rawseti(L, 1, e); /* t[e] = nil */ return 1; } -static int str_concat (lua_State *L) { +static int tconcat (lua_State *L) { luaL_Buffer b; size_t lsep; + int i, last; const char *sep = luaL_optlstring(L, 2, "", &lsep); - int i = luaL_optint(L, 3, 1); - int n = luaL_optint(L, 4, 0); luaL_checktype(L, 1, LUA_TTABLE); - if (n == 0) n = luaL_getn(L, 1); + i = luaL_optint(L, 3, 1); + last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1)); luaL_buffinit(L, &b); - for (; i <= n; i++) { + for (; i <= last; i++) { lua_rawgeti(L, 1, i); luaL_argcheck(L, lua_isstring(L, -1), 1, "table contains non-strings"); luaL_addvalue(&b); - if (i != n) + if (i != last) luaL_addlstring(&b, sep, lsep); } luaL_pushresult(&b); @@ -217,7 +244,7 @@ static void auxsort (lua_State *L, int l, int u) { } /* repeat the routine for the larger one */ } -static int luaB_sort (lua_State *L) { +static int sort (lua_State *L) { int n = aux_getn(L, 1); luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ @@ -230,21 +257,22 @@ static int luaB_sort (lua_State *L) { /* }====================================================== */ -static const luaL_reg tab_funcs[] = { - {"concat", str_concat}, - {"foreach", luaB_foreach}, - {"foreachi", luaB_foreachi}, - {"getn", luaB_getn}, - {"setn", luaB_setn}, - {"sort", luaB_sort}, - {"insert", luaB_tinsert}, - {"remove", luaB_tremove}, +static const luaL_Reg tab_funcs[] = { + {"concat", tconcat}, + {"foreach", foreach}, + {"foreachi", foreachi}, + {"getn", getn}, + {"maxn", maxn}, + {"insert", tinsert}, + {"remove", tremove}, + {"setn", setn}, + {"sort", sort}, {NULL, NULL} }; LUALIB_API int luaopen_table (lua_State *L) { - luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 0); + luaL_register(L, LUA_TABLIBNAME, tab_funcs); return 1; } |