option/action/plugin
parent
b74a2ba5d3
commit
fccd44f2ad
|
@ -47,7 +47,7 @@ struct action {
|
|||
|
||||
union {
|
||||
struct {
|
||||
GArray *options; /** array of option_mark */
|
||||
GArray *options; /** array of option_set */
|
||||
} setting;
|
||||
|
||||
struct {
|
||||
|
|
17
src/base.c
17
src/base.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
33
src/plugin.h
33
src/plugin.h
|
@ -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
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ common_source='''
|
|||
http_request_parser.rl
|
||||
log.c
|
||||
options.c
|
||||
plugin.c
|
||||
request.c
|
||||
sys-files.c
|
||||
sys-socket.c
|
||||
|
|
Loading…
Reference in New Issue