From 9c260769a50956e9ece40a10e226da8e7191158c Mon Sep 17 00:00:00 2001 From: Steven Barth Date: Thu, 20 Nov 2008 19:22:05 +0000 Subject: [PATCH] More C-Functions (luci.cutil.instanceof, luci.cutil.pcdata) --- .cproject | 9 ++- libs/core/Makefile | 2 +- libs/core/luasrc/util.lua | 6 ++ libs/core/src/luci_cutil.c | 109 ++++++++++++++++++++++++++++++++++--- 4 files changed, 115 insertions(+), 11 deletions(-) diff --git a/.cproject b/.cproject index f56f28e85..e1a477410 100644 --- a/.cproject +++ b/.cproject @@ -12,20 +12,23 @@ - - - diff --git a/libs/core/Makefile b/libs/core/Makefile index 7c9b3d794..8a30256a0 100644 --- a/libs/core/Makefile +++ b/libs/core/Makefile @@ -9,4 +9,4 @@ compile: src/luci_cutil.o $(LINK) $(SHLIB_FLAGS) -o dist$(LUCI_LIBRARYDIR)/cutil.so src/luci_cutil.o clean: luaclean - rm src/*.o \ No newline at end of file + rm -f src/*.o diff --git a/libs/core/luasrc/util.lua b/libs/core/luasrc/util.lua index ffab60cb0..e49381125 100644 --- a/libs/core/luasrc/util.lua +++ b/libs/core/luasrc/util.lua @@ -105,6 +105,7 @@ class = cutil.class -- @return Boolean indicating whether the object is an instance -- @see class -- @see clone +--[[ function instanceof(object, class) local meta = getmetatable(object) while meta and meta.__index do @@ -115,6 +116,8 @@ function instanceof(object, class) end return false end +]]-- +instanceof = cutil.instanceof -- @@ -201,6 +204,7 @@ end --- Create valid XML PCDATA from given string. -- @param value String value containing the data to escape -- @return String value containing the escaped data +--[[ function pcdata(value) return value and tostring(value):gsub("[&\"'<>]", { ["&"] = "&", @@ -210,6 +214,8 @@ function pcdata(value) [">"] = ">" }) end +]]-- +pcdata = cutil.pcdata --- Strip HTML tags from given string. -- @param value String containing the HTML text diff --git a/libs/core/src/luci_cutil.c b/libs/core/src/luci_cutil.c index 9f56c432b..31bec041d 100644 --- a/libs/core/src/luci_cutil.c +++ b/libs/core/src/luci_cutil.c @@ -33,14 +33,12 @@ static int luci__string_mod(lua_State *L) { lua_settop(L, 2); /* Get format and push it to the bottom of the stack */ - lua_pushliteral(L, ""); - lua_getfield(L, -1, "format"); + lua_getfield(L, 1, "format"); lua_insert(L, 1); - lua_pop(L, 1); /* If second argument is a table, unpack it */ if (lua_istable(L, 3)) { - n = luaL_getn(L, 3); + n = lua_objlen(L, 3); if (n > 0) { luaL_checkstack(L, n, "too many results to unpack"); for (i=1; i<=n; i++) { @@ -91,13 +89,11 @@ static int luci__instantiate(lua_State *L) { /* luci.cutil.class(baseclass) */ static int luci_class(lua_State *L) { - int n = lua_gettop(L); - /* Create class */ lua_newtable(L); /* Create metatable and register parent class if any */ - if (n && lua_istable(L, 1)) { + if (lua_gettop(L) > 1 && lua_istable(L, 1)) { lua_createtable(L, 0, 2); lua_pushvalue(L, 1); lua_setfield(L, -2, "__index"); @@ -113,10 +109,106 @@ static int luci_class(lua_State *L) { return 1; } +/* luci.cutil.instanceof(object, class) */ +static int luci_instanceof(lua_State *L) { + int stat = 0; + + luaL_checkany(L, 1); + luaL_checkany(L, 2); + + if (lua_getmetatable(L, 1)) { + /* get parent class */ + lua_getfield(L, -1, "__index"); + while (lua_istable(L, -1)) { + /* parent class == class */ + if (lua_equal(L, -1, 2)) { + stat = 1; + break; + } + + /* remove last metatable */ + lua_remove(L, -2); + + /* get metatable of parent class */ + if (lua_getmetatable(L, -1)) { + /* remove last parent class */ + lua_remove(L, -2); + + /* get next parent class */ + lua_getfield(L, -1, "__index"); + } else { + break; + } + } + } + + lua_pushboolean(L, stat); + return 1; +} + + +/* luci.cutil.pcdata(obj) */ +static int luci_pcdata(lua_State *L) { + if (lua_isnone(L, 1)) { + lua_pushnil(L); + return 1; + } + + /* Discard anything else */ + lua_settop(L, 1); + + /* tostring(obj) */ + lua_pushvalue(L, lua_upvalueindex(1)); + lua_insert(L, 1); + lua_call(L, 1, 1); + + /* pattern */ + lua_pushvalue(L, lua_upvalueindex(2)); + + /* repl */ + lua_pushvalue(L, lua_upvalueindex(3)); + + /* get gsub function */ + lua_getfield(L, -3, "gsub"); + lua_insert(L, 1); + + /* tostring(obj):gsub(pattern, repl) */ + lua_call(L, 3, 1); + return 1; +} + + +/* Registration helper for luci.cutil.pcdata */ +static void luci__register_pcdata(lua_State *L) { + /* tostring */ + lua_getfield(L, LUA_GLOBALSINDEX, "tostring"); + + /* pattern */ + lua_pushliteral(L, "[&\"'<>]"); + + /* repl */ + lua_createtable(L, 0, 5); + + lua_pushliteral(L, "&"); + lua_setfield(L, -2, "&"); + lua_pushliteral(L, """); + lua_setfield(L, -2, "\""); + lua_pushliteral(L, "'"); + lua_setfield(L, -2, "'"); + lua_pushliteral(L, "<"); + lua_setfield(L, -2, "<"); + lua_pushliteral(L, ">"); + lua_setfield(L, -2, ">"); + + /* register function */ + lua_pushcclosure(L, luci_pcdata, 3); + lua_setfield(L, -2, "pcdata"); +} /* Registry */ static const luaL_Reg registry[] = { {"class", luci_class}, + {"instanceof", luci_instanceof}, { NULL, NULL }, }; @@ -130,6 +222,9 @@ LUALIB_API int luaopen_luci_cutil(lua_State *L) { lua_pushliteral(L, LUCI_MODCOPY); lua_setfield(L, -2, "_COPYRIGHT"); + /* Additional registrations */ + luci__register_pcdata(L); + /* Register pythonic printf string operator */ lua_pushliteral(L, ""); -- 2.25.1