Allow limited access to unsafepairs/unsafenext
This commit is contained in:
@@ -313,7 +313,7 @@ static void auxsort (lua_State *L, int tab, int l, int u) {
|
|||||||
} /* repeat the routine for the larger one */
|
} /* repeat the routine for the larger one */
|
||||||
}
|
}
|
||||||
|
|
||||||
int table_sortedpairs(lua_State *L, bool *unsortable) {
|
int table_getpairs(lua_State *L, bool sort, bool *unsortable) {
|
||||||
lua_checkstack(L, 40);
|
lua_checkstack(L, 40);
|
||||||
LuaArg tab;
|
LuaArg tab;
|
||||||
LuaVar key, value;
|
LuaVar key, value;
|
||||||
@@ -328,7 +328,10 @@ int table_sortedpairs(lua_State *L, bool *unsortable) {
|
|||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
int total = 0;
|
int total = 0;
|
||||||
while (lua_next(L, tab.index()) != 0) {
|
while (lua_next(L, tab.index()) != 0) {
|
||||||
total += 1;
|
int ktype = lua_type(L, -2);
|
||||||
|
if (ktype == LUA_TNUMBER || ktype == LUA_TSTRING || ktype == LUA_TBOOLEAN) {
|
||||||
|
total += 1;
|
||||||
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
// Create the table, store the initial 1.
|
// Create the table, store the initial 1.
|
||||||
@@ -350,7 +353,9 @@ int table_sortedpairs(lua_State *L, bool *unsortable) {
|
|||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auxsort(L, pairs.index(), 1, total);
|
if (sort) {
|
||||||
|
auxsort(L, pairs.index(), 1, total);
|
||||||
|
}
|
||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,7 +367,7 @@ int table_sortedpairs(lua_State *L, bool *unsortable) {
|
|||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static int nextsortedpair(lua_State *L) {
|
LuaDefine(table_nextpair, "c") {
|
||||||
if (lua_gettop(L) < 2) {
|
if (lua_gettop(L) < 2) {
|
||||||
luaL_error(L, "Not enough arguments to nextpair");
|
luaL_error(L, "Not enough arguments to nextpair");
|
||||||
}
|
}
|
||||||
@@ -387,18 +392,37 @@ static int nextsortedpair(lua_State *L) {
|
|||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
LuaDefine(table_unsafenext, "c") {
|
||||||
|
luaL_checktype(L, 1, LUA_TTABLE);
|
||||||
|
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
|
||||||
|
if (lua_next(L, 1))
|
||||||
|
return 2;
|
||||||
|
else {
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaDefine(table_unsafepairs, "c") {
|
||||||
|
luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */
|
||||||
|
lua_pushcfunction(L, table_unsafenext); /* will return generator, */
|
||||||
|
lua_pushvalue(L, 1); /* state, */
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
LuaDefine(table_pairs, "f") {
|
LuaDefine(table_pairs, "f") {
|
||||||
LuaArg tab;
|
LuaArg tab;
|
||||||
LuaRet closure, rtab, key;
|
LuaRet closure, rtab, key;
|
||||||
LuaStack LS(L, tab, closure, rtab, key);
|
LuaStack LS(L, tab, closure, rtab, key);
|
||||||
lua_pushvalue(L, tab.index());
|
lua_pushvalue(L, tab.index());
|
||||||
bool unsortable;
|
bool unsortable;
|
||||||
table_sortedpairs(L, &unsortable);
|
table_getpairs(L, true, &unsortable);
|
||||||
if (unsortable) {
|
if (unsortable) {
|
||||||
luaL_error(L, "Cannot iterate over a table with unsortable keys");
|
luaL_error(L, "Cannot iterate over a table with unsortable keys");
|
||||||
}
|
}
|
||||||
lua_replace(L, rtab.index());
|
lua_replace(L, rtab.index());
|
||||||
LS.set(closure, nextsortedpair);
|
LS.set(closure, table_nextpair);
|
||||||
LS.set(key, LuaNil);
|
LS.set(key, LuaNil);
|
||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,10 +78,13 @@ int table_count(lua_State *L);
|
|||||||
// This is not exposed directly to lua, but it is used
|
// This is not exposed directly to lua, but it is used
|
||||||
// in the new version of the 'pairs' iterator.
|
// in the new version of the 'pairs' iterator.
|
||||||
//
|
//
|
||||||
// The boolean 'unsortable' is set to indicate whether
|
// The boolean 'sort' is used to control whether the pairs
|
||||||
// or not the table contains unsortable values.
|
// are to be sorted or not.
|
||||||
//
|
//
|
||||||
int table_sortedpairs(lua_State *L, bool *unsortable);
|
// The boolean 'unsortable' returns a flag indicating
|
||||||
|
// whether or not unsortable items were omitted.
|
||||||
|
//
|
||||||
|
int table_getpairs(lua_State *L, bool sort, bool *unsortable);
|
||||||
|
|
||||||
// table_clear
|
// table_clear
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ inspect.KEY = {}
|
|||||||
inspect.METATABLE = {}
|
inspect.METATABLE = {}
|
||||||
|
|
||||||
local function rawpairs(t)
|
local function rawpairs(t)
|
||||||
return next, t, nil
|
return table.unsafepairs(t)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Apostrophizes the string if it has quotes, but not aphostrophes
|
-- Apostrophizes the string if it has quotes, but not aphostrophes
|
||||||
|
|||||||
Reference in New Issue
Block a user