summaryrefslogtreecommitdiffhomepage
path: root/libs/core/src/luci_cutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/core/src/luci_cutil.c')
-rw-r--r--libs/core/src/luci_cutil.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/libs/core/src/luci_cutil.c b/libs/core/src/luci_cutil.c
new file mode 100644
index 000000000..001273b55
--- /dev/null
+++ b/libs/core/src/luci_cutil.c
@@ -0,0 +1,140 @@
+/**
+ * LuCI Core - Utility library
+ * Copyright (C) 2008 Steven Barth <steven@midlink.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lauxlib.h"
+
+#define LUCI_MODNAME "luci.cutil"
+#define LUCI_MODDESC "LuCI Core Utility Library"
+#define LUCI_MODCOPY "2008 Steven Barth"
+
+
+/* Pythonic overloaded MOD operator */
+static int luci__string_mod(lua_State *L) {
+ int i, n=1;
+
+ luaL_checkstring(L, 1);
+ luaL_checkany(L, 2);
+
+ /* Discard further arguments */
+ lua_settop(L, 2);
+
+ /* Get format and push it to the bottom of the stack */
+ lua_pushliteral(L, "");
+ 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);
+ if (n > 0) {
+ luaL_checkstack(L, n, "too many results to unpack");
+ for (i=1; i<=n; i++) {
+ lua_rawgeti(L, 3, i);
+ }
+ } else {
+ n = 0;
+ }
+ lua_remove(L, 3);
+ }
+
+ lua_call(L, n+1, 1);
+ return 1;
+}
+
+/* Instantiate a class */
+static int luci__instantiate(lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ /* Create the object */
+ lua_newtable(L);
+
+ /* Create the metatable */
+ lua_createtable(L, 0, 1);
+ lua_pushvalue(L, 1);
+ lua_setfield(L, -2, "__index");
+ lua_setmetatable(L, -2);
+
+ /* Move instance at the bottom of the stack */
+ lua_replace(L, 1);
+
+ /* Invoke constructor if it exists */
+ lua_getfield(L, 1, "__init__");
+ if (lua_isfunction(L, -1)) {
+ /* Put instance at the bottom for the 2nd time */
+ lua_pushvalue(L, 1);
+ lua_insert(L, 1);
+
+ /* Call constructor */
+ lua_insert(L, 2);
+ lua_call(L, lua_gettop(L)-2, 0);
+ }
+
+ lua_settop(L, 1);
+ return 1;
+}
+
+
+/* luci.cutil.class(baseclass) */
+static int luci_class(lua_State *L) {
+ /* Create class */
+ lua_newtable(L);
+
+ /* Create metatable and register parent class if any */
+ if (lua_istable(L, 1)) {
+ lua_createtable(L, 0, 2);
+ lua_pushvalue(L, 1);
+ lua_setfield(L, -2, "__index");
+ } else {
+ lua_createtable(L, 0, 1);
+ }
+
+ /* Set instantiator */
+ lua_pushcfunction(L, luci__instantiate);
+ lua_setfield(L, -2, "__call");
+
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+
+/* Registry */
+static const luaL_Reg registry[] = {
+ {"class", luci_class},
+ { NULL, NULL },
+};
+
+/* Registrator */
+LUALIB_API int luaopen_luci_cutil(lua_State *L) {
+ luaL_register(L, LUCI_MODNAME, registry);
+
+ lua_pushliteral(L, LUCI_MODDESC);
+ lua_setfield(L, -2, "_DESCRIPTION");
+
+ lua_pushliteral(L, LUCI_MODCOPY);
+ lua_setfield(L, -2, "_COPYRIGHT");
+
+
+ /* Register pythonic printf string operator */
+ lua_pushliteral(L, "");
+ lua_getmetatable(L, -1);
+ lua_pushcfunction(L, luci__string_mod);
+ lua_setfield(L, -2, "__mod");
+ lua_pop(L, 2);
+
+ return 1;
+}