2
0
Fork 0

option/action/plugin

personal/stbuehler/wip
Stefan Bühler 2008-07-08 21:29:02 +02:00
parent b74a2ba5d3
commit fccd44f2ad
8 changed files with 185 additions and 47 deletions

View File

@ -47,7 +47,7 @@ struct action {
union {
struct {
GArray *options; /** array of option_mark */
GArray *options; /** array of option_set */
} setting;
struct {

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

@ -43,28 +43,79 @@ 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:
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);
break;
case OPTION_HASH:
g_hash_table_destroy(opt->value.opt_hash);
break;
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:
val = GINT_TO_POINTER(opt->value.opt_int);
break;
case OPTION_STRING:
val = opt->value.opt_string;
break;
case OPTION_LIST:
val = opt->value.opt_list;
break;
case OPTION_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"
@ -24,9 +31,11 @@ struct option {
} value;
};
struct option_mark {
struct server_option;
struct option_set {
size_t ndx;
gpointer value;
struct server_option *sopt;
};
LI_API option* option_new_bool(gboolean val);
@ -36,4 +45,11 @@ LI_API option* option_new_list();
LI_API option* option_new_hash();
LI_API void option_free(option* opt);
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