static struct uci_context *ctx = NULL;
static struct uci_package *
-find_package(const char *name)
+find_package(lua_State *L, const char *name, bool autoload)
{
struct uci_package *p = NULL;
struct uci_element *e;
+
uci_foreach_element(&ctx->root, e) {
if (strcmp(e->name, name) != 0)
continue;
p = uci_to_package(e);
- break;
+ goto done;
+ }
+
+ if (autoload) {
+ do {
+ lua_getfield(L, LUA_GLOBALSINDEX, "uci");
+ lua_getfield(L, -1, "autoload");
+ if (!lua_isboolean(L, -1))
+ break;
+
+ if (!lua_toboolean(L, -1))
+ break;
+
+ uci_load(ctx, name, &p);
+ } while (0);
+ lua_pop(L, 2);
}
+
+done:
return p;
}
luaL_checkstring(L, 1);
s = lua_tostring(L, -1);
- p = find_package(s);
+ p = find_package(L, s, false);
if (p) {
uci_unload(ctx, p);
lua_pushboolean(L, 1);
if (!lua_isfunction(L, 3) || !package)
luaL_error(L, "Invalid argument");
- p = find_package(package);
+ p = find_package(L, package, true);
if (!p)
goto done;
goto error;
}
- p = find_package(package);
+ p = find_package(L, package, true);
if (!p) {
err = UCI_ERR_NOTFOUND;
goto error;
}
static int
-uci_lua_set(lua_State *L)
+uci_lua_add(lua_State *L)
{
+ struct uci_section *s = NULL;
struct uci_package *p;
- char *package = NULL;
- char *section = NULL;
- char *option = NULL;
- char *value = NULL;
- char *s;
+ const char *package;
+ const char *type;
+ const char *name = NULL;
+
+ do {
+ package = luaL_checkstring(L, 1);
+ type = luaL_checkstring(L, 2);
+ p = find_package(L, package, true);
+ if (!p)
+ break;
+
+ if (uci_add_section(ctx, p, type, &s) || !s)
+ break;
+
+ name = s->e.name;
+ } while (0);
+
+ lua_pushstring(L, name);
+ return 1;
+}
+
+static int
+uci_lua_delete(lua_State *L)
+{
+ const char *package = NULL;
+ const char *section = NULL;
+ const char *option = NULL;
+ struct uci_package *p;
+ const char *s;
int err = UCI_ERR_MEM;
+ int nargs;
- luaL_checkstring(L, 1);
- s = strdup(lua_tostring(L, -1));
- if (!s)
+ nargs = lua_gettop(L);
+ s = luaL_checkstring(L, 1);
+ switch(nargs) {
+ case 1:
+ /* Format: uci.delete("p.s[.o]") */
+ s = strdup(s);
+ if (!s)
+ goto error;
+
+ if ((err = uci_parse_tuple(ctx, (char *) s, (char **) &package, (char **) §ion, (char **) &option, NULL)))
+ goto error;
+ break;
+ case 3:
+ /* Format: uci.delete("p", "s", "o") */
+ option = luaL_checkstring(L, 3);
+ /* fall through */
+ case 2:
+ /* Format: uci.delete("p", "s") */
+ section = luaL_checkstring(L, 2);
+ package = s;
+ break;
+ default:
+ err = UCI_ERR_INVAL;
goto error;
+ }
- if ((err = uci_parse_tuple(ctx, s, &package, §ion, &option, &value)))
+ p = find_package(L, package, true);
+ if (!p) {
+ err = UCI_ERR_NOTFOUND;
goto error;
+ }
+ err = uci_delete(ctx, p, section, option);
+
+error:
+ if (err)
+ uci_lua_perror(L, "uci.set");
+ lua_pushboolean(L, (err == 0));
+ return 1;
+}
+
+static int
+uci_lua_set(lua_State *L)
+{
+ struct uci_package *p;
+ const char *package = NULL;
+ const char *section = NULL;
+ const char *option = NULL;
+ const char *value = NULL;
+ const char *s;
+ int err = UCI_ERR_MEM;
+ int nargs;
+
+ nargs = lua_gettop(L);
+
+ s = luaL_checkstring(L, 1);
+ switch(nargs) {
+ case 1:
+ /* Format: uci.set("p.s.o=v") or uci.set("p.s=v") */
+ s = strdup(s);
+ if (!s)
+ goto error;
+
+ if ((err = uci_parse_tuple(ctx, (char *) s, (char **) &package, (char **) §ion, (char **) &option, (char **) &value)))
+ goto error;
+ break;
+ case 4:
+ /* Format: uci.set("p", "s", "o", "v") */
+ option = luaL_checkstring(L, 3);
+ /* fall through */
+ case 3:
+ /* Format: uci.set("p", "s", "v") */
+ package = s;
+ section = luaL_checkstring(L, 2);
+ value = luaL_checkstring(L, nargs);
+ break;
+ default:
+ err = UCI_ERR_INVAL;
+ goto error;
+ }
if ((section == NULL) || (value == NULL)) {
err = UCI_ERR_INVAL;
goto error;
}
- p = find_package(package);
+ p = find_package(L, package, true);
if (!p) {
err = UCI_ERR_NOTFOUND;
goto error;
s = lua_tostring(L, -1);
lua_pop(L, 1);
break;
+ case 0:
+ break;
default:
err:
luaL_error(L, "Invalid argument count");
{ "unload", uci_lua_unload },
{ "get", uci_lua_get },
{ "get_all", uci_lua_get_all },
+ { "add", uci_lua_add },
{ "set", uci_lua_set },
{ "save", uci_lua_save },
+ { "delete", uci_lua_delete },
{ "commit", uci_lua_commit },
{ "revert", uci_lua_revert },
{ "foreach", uci_lua_foreach },
if (!ctx)
luaL_error(L, "Cannot allocate UCI context\n");
luaL_register(L, MODNAME, uci);
+
+ /* enable autoload by default */
+ lua_getfield(L, LUA_GLOBALSINDEX, "uci");
+ lua_pushboolean(L, 1);
+ lua_setfield(L, -2, "autoload");
+ lua_pop(L, 1);
+
return 0;
}