2
0
Fork 0

options stuff

personal/stbuehler/wip
Thomas Porzelt 2008-07-08 22:38:22 +02:00
commit 4488ebaca6
8 changed files with 185 additions and 40 deletions

View File

@ -34,6 +34,7 @@ struct server; struct connection;
typedef action_result (*action_func)(struct server *srv, struct connection *con, void* param);
#include "condition.h"
#include "plugin.h"
struct action_list {
gint refcount;
@ -46,9 +47,7 @@ struct action {
action_type type;
union {
struct {
GArray *options; /** array of option_mark */
} setting;
option_set setting;
struct {
condition *cond;

View File

@ -1,20 +1,3 @@
#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;
/* TODO */
UNUSED(opt);
return FALSE;
}

View File

@ -1,6 +1,12 @@
#include "options.h"
void options_init()
{
options = g_array_new(FALSE, TRUE, sizeof(option *));
options_hash = g_hash_table_new((GHashFunc) g_int_hash, (GEqualFunc) g_int_equal);
}
option* option_new_bool(gboolean val) {
option *opt = g_slice_new0(option);
opt->value.opt_bool = val;
@ -43,30 +49,81 @@ option* option_new_hash() {
void option_free(option* opt) {
guint i;
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:
option_list_free(opt->value.opt_list);
break;
case OPTION_HASH:
g_hash_table_destroy((GHashTable*) opt->value.opt_hash);
break;
}
opt->type = OPTION_NONE;
g_slice_free(option, opt);
}
const char* option_type_string(option_type type) {
switch(type) {
case OPTION_NONE:
return "none";
case OPTION_BOOLEAN:
return "boolean";
case OPTION_INT:
return "int";
case OPTION_STRING:
return "string";
case OPTION_LIST:
return "list";
case OPTION_HASH:
return "hash";
}
return "<unknown>";
}
void option_list_free(GArray *optlist) {
if (!optlist) return;
for (gsize i = 0; i < optlist->len; i++) {
option_free(g_array_index(optlist, option*, i));
}
g_array_free(optlist, TRUE);
}
/* Extract value from option, destroy option */
gpointer option_extract_value(option *opt) {
gpointer val = NULL;
if (!opt) return NULL;
switch (opt->type) {
case OPTION_NONE:
break;
case OPTION_BOOLEAN:
val = GINT_TO_POINTER(opt->value.opt_bool);
break;
case OPTION_INT:
/* Nothing to free */
val = GINT_TO_POINTER(opt->value.opt_int);
break;
case OPTION_STRING:
g_string_free(opt->value.opt_string, TRUE);
val = opt->value.opt_string;
break;
case OPTION_LIST:
for (i = 0; i < opt->value.opt_list->len; i++)
option_free(g_array_index(opt->value.opt_list, option *, i));
g_array_free(opt->value.opt_list, FALSE);
val = opt->value.opt_list;
break;
case OPTION_HASH:
g_hash_table_destroy(opt->value.opt_hash);
val = opt->value.opt_hash;
break;
}
opt->type = OPTION_NONE;
g_slice_free(option, opt);
return val;
}

View File

@ -1,13 +1,20 @@
#ifndef _LIGHTTPD_OPTIONS_H_
#define _LIGHTTPD_OPTIONS_H_
typedef enum { OPTION_NONE, OPTION_BOOLEAN, OPTION_INT, OPTION_STRING, OPTION_LIST, OPTION_HASH } option_type;
typedef enum {
OPTION_NONE,
OPTION_BOOLEAN,
OPTION_INT,
OPTION_STRING,
OPTION_LIST,
OPTION_HASH
} option_type;
struct option;
typedef struct option option;
struct option_mark;
typedef struct option_mark option_mark;
struct option_set;
typedef struct option_set option_set;
#include "base.h"
@ -29,9 +36,12 @@ struct option {
} value;
};
struct server_option;
struct option_set {
guint ndx;
option opt;
size_t ndx;
gpointer value;
struct server_option *sopt;
};
LI_API option* option_new_bool(gboolean val);
@ -41,6 +51,7 @@ LI_API option* option_new_list();
LI_API option* option_new_hash();
LI_API void option_free(option* opt);
/* registers an option */
LI_API gboolean option_register(GString *name, option *opt);
/* unregisters an option */
@ -48,4 +59,11 @@ LI_API gboolean option_unregister(GString *name);
/* retrieves the index of a previously registered option. returns TRUE if option was found, FALSE otherwise */
LI_API gboolean option_index(GString *name, guint *index);
LI_API const char* option_type_string(option_type type);
LI_API void option_list_free(GArray *optlist);
/* Extract value from option, destroy option */
LI_API gpointer option_extract_value(option *opt);
#endif

67
src/plugin.c Normal file
View File

@ -0,0 +1,67 @@
#include "plugin.h"
#include "log.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_set *mark) {
server_option *sopt;
if (!srv || !key || !mark) return FALSE;
sopt = find_option(srv, key);
if (!sopt) {
ERROR("Unknown option '%s'", key);
return FALSE;
}
if (sopt->type != opt->type) {
ERROR("Unexpected option type '%s', expected '%s'",
option_type_string(opt->type), option_type_string(sopt->type));
return FALSE;
}
if (!sopt->parse_option) {
mark->value = option_extract_value(opt);
} else {
if (!sopt->parse_option(srv, sopt->p->data, sopt->module_index, opt, &mark->value)) {
/* errors should be logged by parse function */
return FALSE;
}
}
mark->ndx = sopt->index;
mark->sopt = sopt;
return TRUE;
}
void release_option(server *srv, option_set *mark) { /** Does not free the option_set memory */
server_option *sopt = mark->sopt;
if (!srv || !mark || !sopt) return;
mark->sopt = NULL;
if (!sopt->free_option) {
switch (sopt->type) {
case OPTION_NONE:
case OPTION_BOOLEAN:
case OPTION_INT:
/* Nothing to free */
break;
case OPTION_STRING:
g_string_free((GString*) mark->value, TRUE);
break;
case OPTION_LIST:
option_list_free((GArray*) mark->value);
break;
case OPTION_HASH:
g_hash_table_destroy((GHashTable*) mark->value);
break;
}
} else {
sopt->free_option(srv, sopt->p->data, sopt->module_index, mark->value);
}
mark->value = NULL;
}

View File

@ -20,17 +20,26 @@ typedef struct server_option server_option;
#include "base.h"
#include "options.h"
typedef void (*ModuleInit) (server *srv, plugin *p);
typedef void (*ModuleFree) (server *srv, plugin *p);
typedef gboolean (*ModuleParseOption) (server *srv, gpointer p_d, size_t ndx, option *opt, gpointer *value);
typedef void (*ModuleFreeOption) (server *srv, gpointer p_d, size_t ndx, gpointer value);
struct module {
GString *name;
GModule *lib;
};
struct plugin {
size_t version;
GString *name; /* name of the plugin */
void *(* init) (server *srv, plugin *p);
gpointer data;
/* dlopen handle */
void *lib;
ModuleFree *free;
module_option *options;
};
@ -38,6 +47,9 @@ struct plugin {
struct module_option {
const char *key;
option_type type;
ModuleParseOption parse_option;
ModuleFreeOption free_option;
};
struct server_option {
@ -46,14 +58,21 @@ struct server_option {
/* 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
*
* Default behaviour (NULL) is to just use the option as 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);
ModuleParseOption parse_option;
ModuleFreeOption free_option;
size_t index, module_index;
option_type type;
};
LI_API gboolean parse_option(server *srv, const char *key, option *opt, option_mark *mark);
LI_API gboolean plugin_register(server *srv, ModuleInit *init);
LI_API gboolean parse_option(server *srv, const char *key, option *opt, option_set *mark);
LI_API void release_option(server *srv, option_set *mark); /** Does not free the option_set memory */
LI_API gboolean plugin_load(server *srv, const char *module);
#endif

View File

@ -11,6 +11,7 @@
#endif
#include <glib.h>
#include <gmodule.h>
#include <assert.h>

View File

@ -17,6 +17,7 @@ common_source='''
http_request_parser.rl
log.c
options.c
plugin.c
request.c
sys-files.c
sys-socket.c