2nd commit ;-)

personal/stbuehler/wip
Stefan Bühler 15 years ago
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;
}

@ -11,4 +11,14 @@ typedef struct server server;
struct connection;
typedef struct connection connection;
#include "plugin.h"
struct server {
GHashTable *plugins;
size_t option_count;
GHashTable *options;
gpointer *option_def_values;
};
#endif

@ -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);
}

@ -9,6 +9,7 @@ typedef struct option option;
struct option_mark;
typedef struct option_mark option_mark;
#include "base.h"
struct option {
option_type type;
@ -19,7 +20,7 @@ struct option {
/* array of option */
GArray *opt_list;
/* hash GString => option */
GHash *opt_hash;
GHashTable *opt_hash;
} value;
};
@ -28,4 +29,11 @@ struct option_mark {
gpointer value;
};
LI_API option* option_new_bool(gboolean val);
LI_API option* option_new_int(gint val);
LI_API option* option_new_string(GString *val);
LI_API option* option_new_list();
LI_API option* option_new_hash();
LI_API void option_free(option* opt);
#endif

@ -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

@ -1,8 +1,5 @@
#ifndef _PLUGIN_H_
#define _PLUGIN_H_
#include "base.h"
#include "option.h"
#ifndef _LIGHTTPD_PLUGIN_H_
#define _LIGHTTPD_PLUGIN_H_
struct plugin;
typedef struct plugin plugin;
@ -10,6 +7,9 @@ typedef struct plugin plugin;
struct module_option;
typedef struct module_option module_option;
struct server_option;
typedef struct server_option server_option;
#define INIT_FUNC(x) \
LI_EXPORT void * x(server *srv, plugin *)
@ -17,14 +17,15 @@ typedef struct module_option module_option;
size_t id; \
ssize_t option_base_ndx
#include "base.h"
#include "options.h"
struct plugin {
size_t version;
GString *name; /* name of the plugin */
void *(* init) (server *srv, plugin *p);
/* the plugin must free the _content_ of the option */
option_mark *(* parse_option) (server *src, void *p_d, size_t option_ndx, option *option);
gpointer data;
@ -41,8 +42,18 @@ struct module_option {
struct server_option {
plugin *p;
/* the plugin must free the _content_ of the option
* opt is zero to get the global default value if nothing is specified
* save result in value
*/
gboolean (* parse_option) (server *srv, void *p_d, size_t ndx, option *opt, gpointer *value);
void (* free_option) (server *srv, void *p_d, size_t ndx, gpointer value);
size_t index, module_index;
option_type type;
};
LI_API gboolean parse_option(server *srv, const char *key, option *opt, option_mark *mark);
#endif

@ -1,6 +1,22 @@
#include "base.h"
#include "log.h"
static server* server_new() {
server* srv = g_slice_new0(server);
srv->plugins = g_hash_table_new(g_str_hash, g_str_equal);
srv->options = g_hash_table_new(g_str_hash, g_str_equal);
return srv;
}
static void server_free(server* srv) {
if (!srv) return;
/* TODO */
g_slice_free(server, srv);
}
int main() {
TRACE("%s", "Test!");
return 0;

@ -7,11 +7,14 @@ import Params
common_uselib = 'glib '
common_source='''
base.c
chunks.c
log.c
options.c
options_lua.c
sys-files.c
sys-socket.c
'''
# sys-socket.c
main_source = '''
server.c
@ -68,7 +71,7 @@ def build(bld):
main.name = 'lighttpd'
main.source = common_source + main_source
main.target='lighttpd' + env['APPEND']
main.uselib += 'lighty dl openssl pcre ' + common_uselib
main.uselib += 'lighty dl openssl pcre lua glib ' + common_uselib
#lighty_mod(bld, 'mod_access', 'mod_access.c')
#lighty_mod(bld, 'mod_alias', 'mod_alias.c')

Loading…
Cancel
Save