rlm@1: /* rlm@1: ** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ rlm@1: ** Library for Table Manipulation rlm@1: ** See Copyright Notice in lua.h rlm@1: */ rlm@1: rlm@1: rlm@1: #include rlm@1: rlm@1: #define ltablib_c rlm@1: #define LUA_LIB rlm@1: rlm@1: #include "lua.h" rlm@1: rlm@1: #include "lauxlib.h" rlm@1: #include "lualib.h" rlm@1: rlm@1: rlm@1: #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) rlm@1: rlm@1: rlm@1: static int foreachi (lua_State *L) { rlm@1: int i; rlm@1: int n = aux_getn(L, 1); rlm@1: luaL_checktype(L, 2, LUA_TFUNCTION); rlm@1: for (i=1; i <= n; i++) { rlm@1: lua_pushvalue(L, 2); /* function */ rlm@1: lua_pushinteger(L, i); /* 1st argument */ rlm@1: lua_rawgeti(L, 1, i); /* 2nd argument */ rlm@1: lua_call(L, 2, 1); rlm@1: if (!lua_isnil(L, -1)) rlm@1: return 1; rlm@1: lua_pop(L, 1); /* remove nil result */ rlm@1: } rlm@1: return 0; rlm@1: } rlm@1: rlm@1: rlm@1: static int foreach (lua_State *L) { rlm@1: luaL_checktype(L, 1, LUA_TTABLE); rlm@1: luaL_checktype(L, 2, LUA_TFUNCTION); rlm@1: lua_pushnil(L); /* first key */ rlm@1: while (lua_next(L, 1)) { rlm@1: lua_pushvalue(L, 2); /* function */ rlm@1: lua_pushvalue(L, -3); /* key */ rlm@1: lua_pushvalue(L, -3); /* value */ rlm@1: lua_call(L, 2, 1); rlm@1: if (!lua_isnil(L, -1)) rlm@1: return 1; rlm@1: lua_pop(L, 2); /* remove value and result */ rlm@1: } rlm@1: return 0; rlm@1: } rlm@1: rlm@1: rlm@1: static int maxn (lua_State *L) { rlm@1: lua_Number max = 0; rlm@1: luaL_checktype(L, 1, LUA_TTABLE); rlm@1: lua_pushnil(L); /* first key */ rlm@1: while (lua_next(L, 1)) { rlm@1: lua_pop(L, 1); /* remove value */ rlm@1: if (lua_type(L, -1) == LUA_TNUMBER) { rlm@1: lua_Number v = lua_tonumber(L, -1); rlm@1: if (v > max) max = v; rlm@1: } rlm@1: } rlm@1: lua_pushnumber(L, max); rlm@1: return 1; rlm@1: } rlm@1: rlm@1: rlm@1: static int getn (lua_State *L) { rlm@1: lua_pushinteger(L, aux_getn(L, 1)); rlm@1: return 1; rlm@1: } rlm@1: rlm@1: rlm@1: static int setn (lua_State *L) { rlm@1: luaL_checktype(L, 1, LUA_TTABLE); rlm@1: #ifndef luaL_setn rlm@1: luaL_setn(L, 1, luaL_checkint(L, 2)); rlm@1: #else rlm@1: luaL_error(L, LUA_QL("setn") " is obsolete"); rlm@1: #endif rlm@1: lua_pushvalue(L, 1); rlm@1: return 1; rlm@1: } rlm@1: rlm@1: rlm@1: static int tinsert (lua_State *L) { rlm@1: int e = aux_getn(L, 1) + 1; /* first empty element */ rlm@1: int pos; /* where to insert new element */ rlm@1: switch (lua_gettop(L)) { rlm@1: case 2: { /* called with only 2 arguments */ rlm@1: pos = e; /* insert new element at the end */ rlm@1: break; rlm@1: } rlm@1: case 3: { rlm@1: int i; rlm@1: pos = luaL_checkint(L, 2); /* 2nd argument is the position */ rlm@1: if (pos > e) e = pos; /* `grow' array if necessary */ rlm@1: for (i = e; i > pos; i--) { /* move up elements */ rlm@1: lua_rawgeti(L, 1, i-1); rlm@1: lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ rlm@1: } rlm@1: break; rlm@1: } rlm@1: default: { rlm@1: return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); rlm@1: } rlm@1: } rlm@1: luaL_setn(L, 1, e); /* new size */ rlm@1: lua_rawseti(L, 1, pos); /* t[pos] = v */ rlm@1: return 0; rlm@1: } rlm@1: rlm@1: rlm@1: static int tremove (lua_State *L) { rlm@1: int e = aux_getn(L, 1); rlm@1: int pos = luaL_optint(L, 2, e); rlm@1: if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ rlm@1: return 0; /* nothing to remove */ rlm@1: luaL_setn(L, 1, e - 1); /* t.n = n-1 */ rlm@1: lua_rawgeti(L, 1, pos); /* result = t[pos] */ rlm@1: for ( ;pos= P */ rlm@1: while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { rlm@1: if (i>u) luaL_error(L, "invalid order function for sorting"); rlm@1: lua_pop(L, 1); /* remove a[i] */ rlm@1: } rlm@1: /* repeat --j until a[j] <= P */ rlm@1: while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { rlm@1: if (j