lua

A copy of the Lua development repository
Log | Files | Refs | README

commit 03bbe1baf190ec768690805b967571b78c8dd34b
parent f9037ae8c1ccb614e38cb56054927aef6203cfd9
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Fri, 25 Jul 2014 15:45:35 -0300

first implementation for 'table.copy'

Diffstat:
Mltablib.c | 40+++++++++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/ltablib.c b/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.70 2014/05/16 18:53:25 roberto Exp roberto $ +** $Id: ltablib.c,v 1.71 2014/07/16 12:44:52 roberto Exp roberto $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -132,6 +132,43 @@ static int tremove (lua_State *L) { } +static int tcopy (lua_State *L) { + TabA ta; + lua_Integer f = luaL_checkinteger(L, 2); + lua_Integer e = luaL_checkinteger(L, 3); + lua_Integer t; + int tt = 4; /* destination table */ + /* the following restriction avoids several problems with overflows */ + luaL_argcheck(L, f > 0, 2, "initial position must be positive"); + if (lua_istable(L, tt)) + t = luaL_checkinteger(L, 5); + else { + tt = 1; /* destination table is equal to source */ + t = luaL_checkinteger(L, 4); + } + if (e >= f) { /* otherwise, nothing to move */ + lua_Integer n, i; + ta.geti = (!luaL_getmetafield(L, 1, "__index")) ? lua_rawgeti : geti; + ta.seti = (!luaL_getmetafield(L, tt, "__newindex")) ? lua_rawseti : seti; + n = e - f + 1; /* number of elements to move */ + if (t > f) { + for (i = n - 1; i >= 0; i--) { + (*ta.geti)(L, 1, f + i); + (*ta.seti)(L, tt, t + i); + } + } + else { + for (i = 0; i < n; i++) { + (*ta.geti)(L, 1, f + i); + (*ta.seti)(L, tt, t + i); + } + } + } + lua_pushvalue(L, tt); /* return "to table" */ + return 1; +} + + static void addfield (lua_State *L, luaL_Buffer *b, TabA *ta, lua_Integer i) { (*ta->geti)(L, 1, i); if (!lua_isstring(L, -1)) @@ -318,6 +355,7 @@ static const luaL_Reg tab_funcs[] = { {"pack", pack}, {"unpack", unpack}, {"remove", tremove}, + {"copy", tcopy}, {"sort", sort}, {NULL, NULL} };