2nd commit ;-)
parent
9372e41393
commit
031b7bf7df
@ -0,0 +1,17 @@
|
||||
|
||||
#include "base.h"
|
||||
|
||||
static server_option* find_option(server *srv, const char *key) {
|
||||
return (server_option*) g_hash_table_lookup(srv->options, key);
|
||||
}
|
||||
|
||||
gboolean parse_option(server *srv, const char *key, option *opt, option_mark *mark) {
|
||||
server_option *sopt;
|
||||
|
||||
if (!srv || !key || !mark) return FALSE;
|
||||
|
||||
sopt = find_option(srv, key);
|
||||
if (!sopt) return FALSE;
|
||||
|
||||
return FALSE;
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
|
||||
#include "options.h"
|
||||
|
||||
option* option_new_bool(gboolean val) {
|
||||
option *opt = g_slice_new0(option);
|
||||
opt->value.opt_bool = val;
|
||||
return opt;
|
||||
}
|
||||
|
||||
option* option_new_int(gint val) {
|
||||
option *opt = g_slice_new0(option);
|
||||
opt->value.opt_int = val;
|
||||
return opt;
|
||||
}
|
||||
|
||||
option* option_new_string(GString *val) {
|
||||
option *opt = g_slice_new0(option);
|
||||
opt->value.opt_string = val;
|
||||
return opt;
|
||||
}
|
||||
|
||||
option* option_new_list() {
|
||||
option *opt = g_slice_new0(option);
|
||||
opt->value.opt_list = g_array_new(FALSE, TRUE, sizeof(option*));
|
||||
return opt;
|
||||
}
|
||||
|
||||
void _option_hash_free_key(gpointer data) {
|
||||
g_string_free((GString*) data, TRUE);
|
||||
}
|
||||
|
||||
void _option_hash_free_value(gpointer data) {
|
||||
option_free((option*) data);
|
||||
}
|
||||
|
||||
option* option_new_hash() {
|
||||
option *opt = g_slice_new0(option);
|
||||
opt->value.opt_hash = g_hash_table_new_full(
|
||||
(GHashFunc) g_string_hash, (GEqualFunc) g_string_equal,
|
||||
_option_hash_free_key, _option_hash_free_value);
|
||||
return opt;
|
||||
}
|
||||
|
||||
|
||||
void option_free(option* opt) {
|
||||
if (!opt) return;
|
||||
|
||||
switch (opt->type) {
|
||||
case OPTION_NONE:
|
||||
case OPTION_BOOLEAN:
|
||||
case OPTION_INT:
|
||||
/* Nothing to free */
|
||||
break;
|
||||
case OPTION_STRING:
|
||||
g_string_free(opt->value.opt_string, TRUE);
|
||||
break;
|
||||
case OPTION_LIST:
|
||||
/* TODO */
|
||||
break;
|
||||
case OPTION_HASH:
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
opt->type = OPTION_NONE;
|
||||
g_slice_free(option, opt);
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
|
||||
#include "options_lua.h"
|
||||
#include "log.h"
|
||||
|
||||
/* replace a negative stack index with a positive one,
|
||||
* so that you don't need to care about push/pop
|
||||
*/
|
||||
static int lua_fixindex(lua_State *L, int ndx) {
|
||||
int top;
|
||||
if (ndx < 0 && ndx >= -(top = lua_gettop(L)))
|
||||
ndx = top + ndx + 1;
|
||||
return ndx;
|
||||
}
|
||||
|
||||
static option* option_from_lua_table(lua_State *L, int ndx) {
|
||||
option *opt = NULL, *sub_option;
|
||||
GArray *list = NULL;
|
||||
GHashTable *hash = NULL;
|
||||
int ikey;
|
||||
GString *skey;
|
||||
|
||||
ndx = lua_fixindex(L, ndx);
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, ndx) != 0) {
|
||||
switch (lua_type(L, -2)) {
|
||||
case LUA_TNUMBER:
|
||||
if (hash) goto mixerror;
|
||||
if (!list) {
|
||||
opt = option_new_list();
|
||||
list = opt->value.opt_list;
|
||||
}
|
||||
ikey = lua_tointeger(L, -2);
|
||||
if (ikey < 0) {
|
||||
ERROR("Invalid key < 0: %i - skipping entry", ikey);
|
||||
lua_pop(L, 1);
|
||||
continue;
|
||||
}
|
||||
sub_option = option_from_lua(L);
|
||||
if (!sub_option) continue;
|
||||
if ((size_t) ikey >= list->len) {
|
||||
g_array_set_size(list, ikey + 1);
|
||||
}
|
||||
g_array_index(list, option*, ikey) = sub_option;
|
||||
break;
|
||||
|
||||
case LUA_TSTRING:
|
||||
if (list) goto mixerror;
|
||||
if (!hash) {
|
||||
opt = option_new_hash();
|
||||
hash = opt->value.opt_hash;
|
||||
}
|
||||
skey = lua_togstring(L, -2);
|
||||
if (g_hash_table_lookup(hash, skey)) {
|
||||
ERROR("Key already exists in hash: '%s' - skipping entry", skey->str);
|
||||
lua_pop(L, 1);
|
||||
continue;
|
||||
}
|
||||
sub_option = option_from_lua(L);
|
||||
if (!sub_option) {
|
||||
g_string_free(skey, TRUE);
|
||||
continue;
|
||||
}
|
||||
g_hash_table_insert(hash, skey, sub_option);
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR("Unexpted key type in table: %s (%i) - skipping entry", lua_typename(L, -1), lua_type(L, -1));
|
||||
lua_pop(L, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return opt;
|
||||
|
||||
mixerror:
|
||||
ERROR("%s", "Cannot mix list with hash; skipping remaining part of table");
|
||||
lua_pop(L, 2);
|
||||
return opt;
|
||||
}
|
||||
|
||||
|
||||
option* option_from_lua(lua_State *L) {
|
||||
option *opt;
|
||||
|
||||
switch (lua_type(L, -1)) {
|
||||
case LUA_TNIL:
|
||||
lua_pop(L, 1);
|
||||
return NULL;
|
||||
|
||||
case LUA_TBOOLEAN:
|
||||
opt = option_new_bool(lua_toboolean(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return opt;
|
||||
|
||||
case LUA_TNUMBER:
|
||||
opt = option_new_int(lua_tointeger(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return opt;
|
||||
|
||||
case LUA_TSTRING:
|
||||
opt = option_new_string(lua_togstring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return opt;
|
||||
|
||||
case LUA_TTABLE:
|
||||
opt = option_from_lua_table(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return opt;
|
||||
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
case LUA_TFUNCTION:
|
||||
case LUA_TUSERDATA:
|
||||
case LUA_TTHREAD:
|
||||
case LUA_TNONE:
|
||||
default:
|
||||
ERROR("Unexpected lua type: %s (%i)", lua_typename(L, -1), lua_type(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GString* lua_togstring(lua_State *L, int ndx) {
|
||||
const char *buf;
|
||||
size_t len = 0;
|
||||
GString *str = NULL;
|
||||
|
||||
if (lua_type(L, ndx) == LUA_TSTRING) {
|
||||
buf = lua_tolstring(L, ndx, &len);
|
||||
if (buf) str = g_string_new_len(buf, len);
|
||||
} else {
|
||||
lua_pushvalue(L, ndx);
|
||||
buf = lua_tolstring(L, -1, &len);
|
||||
if (buf) str = g_string_new_len(buf, len);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
#ifndef _LIGHTTPD_OPTIONS_LUA_H_
|
||||
#define _LIGHTTPD_OPTIONS_LUA_H_
|
||||
|
||||
#include "options.h"
|
||||
|
||||
#include <lua.h>
|
||||
|
||||
/* converts the top of the stack into an option
|
||||
* and pops the value
|
||||
* returns NULL if it couldn't convert the value (still pops it)
|
||||
*/
|
||||
LI_API option* option_from_lua(lua_State *L);
|
||||
|
||||
LI_API GString* lua_togstring(lua_State *L, int ndx);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue