personal/stbuehler/wip
parent
2537bb9d82
commit
2f7359b14c
@ -0,0 +1,54 @@
|
||||
|
||||
#include "actions_lua.h"
|
||||
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
#define LUA_ACTION "action*"
|
||||
|
||||
action* lua_get_action(lua_State *L, int ndx) {
|
||||
if (!lua_isuserdata(L, ndx)) return NULL;
|
||||
if (!lua_getmetatable(L, ndx)) return NULL;
|
||||
luaL_getmetatable(L, LUA_ACTION);
|
||||
if (lua_isnil(L, -1) || lua_isnil(L, -2) || !lua_equal(L, -1, -2)) {
|
||||
lua_pop(L, 2);
|
||||
return NULL;
|
||||
}
|
||||
lua_pop(L, 2);
|
||||
return *(action**) lua_touserdata(L, ndx);
|
||||
}
|
||||
|
||||
static int lua_action_gc(lua_State *L) {
|
||||
server *srv;
|
||||
action **a = (action**) luaL_checkudata(L, 1, LUA_ACTION);
|
||||
if (!a || !*a) return 0;
|
||||
|
||||
srv = (server*) lua_touserdata(L, lua_upvalueindex(1));
|
||||
action_release(srv, *a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_push_action(server *srv, lua_State *L, action *a) {
|
||||
action **pa;
|
||||
|
||||
pa = (action**) lua_newuserdata(L, sizeof(action*));
|
||||
action_acquire(a);
|
||||
*pa = a;
|
||||
|
||||
if (luaL_newmetatable(L, LUA_ACTION)) {
|
||||
lua_pushlightuserdata(L, srv);
|
||||
lua_pushcclosure(L, lua_action_gc, 1);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
}
|
||||
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
action_list* lua_get_actionlist(lua_State *L) {
|
||||
action *a;
|
||||
if (lua_isnil(L, -1)) return NULL;
|
||||
a = lua_get_action(L, 1);
|
||||
if (!a) return NULL;
|
||||
return action_list_from_action(a);
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#ifndef _LIGHTTPD_ACTIONS_LUA_H_
|
||||
#define _LIGHTTPD_ACTIONS_LUA_H_
|
||||
|
||||
#include "actions.h"
|
||||
#include <lua.h>
|
||||
|
||||
action* lua_get_action(lua_State *L, int ndx);
|
||||
int lua_push_action(server *srv, lua_State *L, action *a);
|
||||
action_list* lua_get_actionlist(lua_State *L);
|
||||
|
||||
#endif
|
@ -0,0 +1,46 @@
|
||||
|
||||
#include "condition_lua.h"
|
||||
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
#define LUA_CONDITION "condition*"
|
||||
|
||||
condition* lua_get_condition(lua_State *L, int ndx) {
|
||||
if (!lua_isuserdata(L, ndx)) return NULL;
|
||||
if (!lua_getmetatable(L, ndx)) return NULL;
|
||||
luaL_getmetatable(L, LUA_CONDITION);
|
||||
if (lua_isnil(L, -1) || lua_isnil(L, -2) || !lua_equal(L, -1, -2)) {
|
||||
lua_pop(L, 2);
|
||||
return NULL;
|
||||
}
|
||||
lua_pop(L, 2);
|
||||
return *(condition**) lua_touserdata(L, ndx);
|
||||
}
|
||||
|
||||
static int lua_condition_gc(lua_State *L) {
|
||||
server *srv;
|
||||
condition **c = (condition**) luaL_checkudata(L, 1, LUA_CONDITION);
|
||||
if (!c || !*c) return 0;
|
||||
|
||||
srv = (server*) lua_touserdata(L, lua_upvalueindex(1));
|
||||
condition_release(srv, *c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_push_condition(server *srv, lua_State *L, condition *c) {
|
||||
condition **pc;
|
||||
|
||||
pc = (condition**) lua_newuserdata(L, sizeof(condition*));
|
||||
condition_acquire(c);
|
||||
*pc = c;
|
||||
|
||||
if (luaL_newmetatable(L, LUA_CONDITION)) {
|
||||
lua_pushlightuserdata(L, srv);
|
||||
lua_pushcclosure(L, lua_condition_gc, 1);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
}
|
||||
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
#ifndef _LIGHTTPD_CONDITION_LUA_H_
|
||||
#define _LIGHTTPD_CONDITION_LUA_H_
|
||||
|
||||
#include "condition.h"
|
||||
#include <lua.h>
|
||||
|
||||
condition* lua_get_condition(lua_State *L, int ndx);
|
||||
int lua_push_condition(server *srv, lua_State *L, condition *c);
|
||||
|
||||
#endif
|
@ -0,0 +1,220 @@
|
||||
|
||||
#include "base.h"
|
||||
#include "options_lua.h"
|
||||
#include "actions_lua.h"
|
||||
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
typedef int (*LuaWrapper)(server *srv, lua_State *L, gpointer data);
|
||||
|
||||
option* lua_params_to_option(server *srv, lua_State *L) {
|
||||
option *opt, *subopt;
|
||||
switch (lua_gettop(L)) {
|
||||
case 0:
|
||||
return NULL;
|
||||
case 1:
|
||||
return option_from_lua(srv, L);
|
||||
default:
|
||||
opt = option_new_list();
|
||||
while (lua_gettop(L) > 0) {
|
||||
if (NULL == (subopt = option_from_lua(srv, L))) {
|
||||
ERROR(srv, "%s", "Couldn't convert option to lua");
|
||||
option_free(opt);
|
||||
return NULL;
|
||||
}
|
||||
g_array_append_val(opt->value.opt_list, subopt);
|
||||
}
|
||||
return opt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int lua_str_hash_index(lua_State *L) {
|
||||
server *srv;
|
||||
GHashTable *ht;
|
||||
LuaWrapper wrapper;
|
||||
const char *key;
|
||||
gpointer d;
|
||||
|
||||
srv = (server*) lua_touserdata(L, lua_upvalueindex(1));
|
||||
ht = (GHashTable*) lua_touserdata(L, lua_upvalueindex(2));
|
||||
wrapper = (LuaWrapper)(intptr_t) lua_touserdata(L, lua_upvalueindex(3));
|
||||
key = luaL_checklstring(L, 2, NULL);
|
||||
|
||||
if (key && NULL != (d = g_hash_table_lookup(ht, key))) {
|
||||
lua_pop(L, lua_gettop(L));
|
||||
return wrapper(srv, L, d);
|
||||
}
|
||||
|
||||
lua_pop(L, lua_gettop(L));
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Creates a table on the lua stack */
|
||||
static gboolean publish_str_hash(server *srv, lua_State *L, GHashTable *ht, LuaWrapper wrapper) {
|
||||
lua_newtable(L); /* { } */
|
||||
lua_newtable(L); /* metatable */
|
||||
|
||||
lua_pushlightuserdata(L, srv);
|
||||
lua_pushlightuserdata(L, ht);
|
||||
lua_pushlightuserdata(L, (void*)(intptr_t)wrapper);
|
||||
lua_pushcclosure(L, lua_str_hash_index, 3);
|
||||
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_setmetatable(L, -2);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int handle_server_action(lua_State *L) {
|
||||
server *srv;
|
||||
server_action *sa;
|
||||
option *opt;
|
||||
action *a;
|
||||
|
||||
srv = (server*) lua_touserdata(L, lua_upvalueindex(1));
|
||||
sa = (server_action*) lua_touserdata(L, lua_upvalueindex(2));
|
||||
|
||||
opt = lua_params_to_option(srv, L);
|
||||
|
||||
TRACE(srv, "%s", "Creating action");
|
||||
|
||||
if (NULL == (a = sa->create_action(srv, sa->p, opt))) {
|
||||
lua_pushstring(L, "creating action failed");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
return lua_push_action(srv, L, a);
|
||||
}
|
||||
|
||||
static int wrap_server_action(server *srv, lua_State *L, gpointer sa) {
|
||||
lua_pushlightuserdata(L, srv);
|
||||
lua_pushlightuserdata(L, sa);
|
||||
lua_pushcclosure(L, handle_server_action, 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int handle_server_setup(lua_State *L) {
|
||||
server *srv;
|
||||
server_setup *ss;
|
||||
option *opt;
|
||||
|
||||
srv = (server*) lua_touserdata(L, lua_upvalueindex(1));
|
||||
ss = (server_setup*) lua_touserdata(L, lua_upvalueindex(2));
|
||||
|
||||
opt = lua_params_to_option(srv, L);
|
||||
|
||||
TRACE(srv, "%s", "Calling setup");
|
||||
|
||||
if (!ss->setup(srv, ss->p, opt)) {
|
||||
lua_pushstring(L, "setup failed");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wrap_server_setup(server *srv, lua_State *L, gpointer ss) {
|
||||
lua_pushlightuserdata(L, srv);
|
||||
lua_pushlightuserdata(L, ss);
|
||||
lua_pushcclosure(L, handle_server_setup, 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static action* action_from_lua(server *srv, lua_State *L) {
|
||||
const gchar *optname;
|
||||
option *value;
|
||||
action *a;
|
||||
|
||||
optname = luaL_checklstring(L, -2, NULL);
|
||||
if (!optname) {
|
||||
lua_pushstring(L, "wrong config argument, expected string");
|
||||
lua_error(L);
|
||||
}
|
||||
value = option_from_lua(srv, L);
|
||||
if (!value) {
|
||||
lua_pushstring(L, "missing config value");
|
||||
lua_error(L);
|
||||
}
|
||||
a = action_new_setting(srv, optname, value);
|
||||
if (!a) {
|
||||
option_free(value);
|
||||
lua_pushstring(L, "couldn't create action from setting");
|
||||
lua_error(L);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
static int handle_option(lua_State *L) {
|
||||
server *srv;
|
||||
action *a, *suba;
|
||||
|
||||
srv = (server*) lua_touserdata(L, lua_upvalueindex(1));
|
||||
switch (lua_gettop(L)) {
|
||||
case 1:
|
||||
if (!lua_istable(L, 1)) {
|
||||
lua_pushstring(L, "wrong config argument, expected table");
|
||||
lua_error(L);
|
||||
}
|
||||
a = action_new_list();
|
||||
lua_push_action(srv, L, a);
|
||||
lua_insert(L, 1);
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 2) != 0) {
|
||||
suba = action_from_lua(srv, L);
|
||||
g_array_append_val(a->value.list->actions, suba);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return 1;
|
||||
case 2:
|
||||
a = action_from_lua(srv, L);
|
||||
return lua_push_action(srv, L, a);
|
||||
default:
|
||||
lua_pushstring(L, "wrong count of arguments to config()");
|
||||
lua_error(L);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean config_lua_load(server *srv, const gchar *filename) {
|
||||
lua_State *L;
|
||||
|
||||
L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
|
||||
if (0 != luaL_loadfile(L, filename)) {
|
||||
ERROR(srv, "Loading script '%s' failed: %s", filename, lua_tostring(L, -1));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE(srv, "Loaded config script '%s'", filename);
|
||||
|
||||
publish_str_hash(srv, L, srv->setups, wrap_server_setup);
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "setup");
|
||||
|
||||
publish_str_hash(srv, L, srv->actions, wrap_server_action);
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "action");
|
||||
|
||||
lua_pushlightuserdata(L, srv);
|
||||
lua_pushcclosure(L, handle_option, 1);
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "option");
|
||||
|
||||
|
||||
if (lua_pcall(L, 0, 1, 0)) {
|
||||
ERROR(srv, "lua_pcall(): %s", lua_tostring(L, -1));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lua_pop(L, 1); /* pop the ret-value */
|
||||
|
||||
lua_getfield(L, LUA_GLOBALSINDEX, "action");
|
||||
srv->mainactionlist = lua_get_actionlist(L);
|
||||
lua_pop(L, 1);
|
||||
|
||||
assert(lua_gettop(L) == 0);
|
||||
|
||||
lua_close(L);
|
||||
return TRUE;
|
||||
}
|
Loading…
Reference in new issue