X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=blobdiff_plain;f=libs%2Fcore%2Fsrc%2Fluci_cutil.c;h=49a33ac9400b1741b1a8e1859e03e907decf8c0d;hp=9f56c432b1acf1a46625914c2e5ac7582f797d81;hb=a3cf596d37e4116a7068daaa724270a0898cb7da;hpb=9a203c52dd9bcbdb11bc86b99ea61027eec7cc26 diff --git a/libs/core/src/luci_cutil.c b/libs/core/src/luci_cutil.c index 9f56c432b..49a33ac94 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,118 @@ 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; + } + luaL_checkstring(L, 1); + + /* Discard anything else */ + lua_settop(L, 1); + + /* pattern */ + lua_pushvalue(L, lua_upvalueindex(1)); + + /* repl */ + lua_pushvalue(L, lua_upvalueindex(2)); + + /* get gsub function */ + lua_getfield(L, 1, "gsub"); + lua_insert(L, 1); + + /* tostring(obj):gsub(pattern, repl) */ + lua_call(L, 3, 1); + return 1; +} + +/* luci.cutil.trim(str) */ +static int luci_trim(lua_State *L) { + luaL_checkstring(L, 1); + lua_settop(L, 1); + + /* pattern and repl */ + lua_pushliteral(L, "^%s*(.-)%s*$"); + lua_pushliteral(L, "%1"); + + /* get str.gsub */ + lua_getfield(L, 1, "gsub"); + lua_insert(L, 1); + + /* str.gsub(str, pattern, repl) */ + lua_call(L, 3, 1); + return 1; +} + + +/* Registration helper for luci.cutil.pcdata */ +static void luci__register_pcdata(lua_State *L) { + /* 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, 2); + lua_setfield(L, -2, "pcdata"); +} /* Registry */ static const luaL_Reg registry[] = { {"class", luci_class}, + {"instanceof", luci_instanceof}, + {"trim", luci_trim}, { NULL, NULL }, }; @@ -130,6 +234,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, "");