[core] rewrite config parser
* no more hash values - only lists and list of key-value pairs * "master" config: the config loaded on startup can use all features, configs loaded later (vhost on demand from sql...) can't use include* and cannot modify global vars. * scoped variables - add a global var store in the server struct - global vars can be set with "global foo = bar" - if a variable already exists in a scope it will be modified on a write, otherwise a new local variable is created - global vars won't be modified if not in "master" mode - vars can be made explicitly local with "local foo = bar"; create a local copy with "local foo = foo" - globals vars are available in live config loads for reading - each file and action block {...} creates a new scope; if/else branches do NOT create a new scope * to append a value to a list use "l + [v]" (not "l + v" anymore); lists are concatenated with "+" * [...] always marks a list * (...) is a list if it contains a "," or "=>", otherwise it justs groups an expression * a list can either contain key-value pairs or other values. mixing is not allowedpersonal/stbuehler/wip
parent
a1fbaab86b
commit
e76ebe2021
|
@ -85,11 +85,15 @@ LI_API liHandlerResult li_action_execute(liVRequest *vr);
|
|||
LI_API void li_action_release(liServer *srv, liAction *a);
|
||||
LI_API void li_action_acquire(liAction *a);
|
||||
/* create new action */
|
||||
LI_API liAction *li_action_new_setting(liOptionSet setting);
|
||||
LI_API liAction *li_action_new_settingptr(liOptionPtrSet setting);
|
||||
LI_API liAction *li_action_new_function(liActionFuncCB func, liActionCleanupCB fcleanup, liActionFreeCB ffree, gpointer param);
|
||||
LI_API liAction *li_action_new_list(void);
|
||||
LI_API liAction *li_action_new_condition(liCondition *cond, liAction *target, liAction *target_else);
|
||||
LI_API liAction *li_action_new_balancer(liBackendSelectCB bselect, liBackendFallbackCB bfallback, liBackendFinishedCB bfinished, liBalancerFreeCB bfree, gpointer param, gboolean provide_backlog);
|
||||
LI_API liAction* li_action_new(void);
|
||||
LI_API liAction* li_action_new_setting(liOptionSet setting);
|
||||
LI_API liAction* li_action_new_settingptr(liOptionPtrSet setting);
|
||||
LI_API liAction* li_action_new_function(liActionFuncCB func, liActionCleanupCB fcleanup, liActionFreeCB ffree, gpointer param);
|
||||
LI_API liAction* li_action_new_list(void);
|
||||
LI_API liAction* li_action_new_condition(liCondition *cond, liAction *target, liAction *target_else);
|
||||
LI_API liAction* li_action_new_balancer(liBackendSelectCB bselect, liBackendFallbackCB bfallback, liBackendFinishedCB bfinished, liBalancerFreeCB bfree, gpointer param, gboolean provide_backlog);
|
||||
|
||||
/* assert(list->refcount == 1)! converts list to a list in place if necessary */
|
||||
LI_API void li_action_append_inplace(liAction *list, liAction *element);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,56 +3,12 @@
|
|||
|
||||
#include <lighttpd/base.h>
|
||||
|
||||
typedef struct liConfigParserContext liConfigParserContext;
|
||||
|
||||
typedef enum {
|
||||
LI_CFG_PARSER_CAST_NONE,
|
||||
LI_CFG_PARSER_CAST_INT,
|
||||
LI_CFG_PARSER_CAST_STR
|
||||
} liCastType;
|
||||
|
||||
struct liConfigParserContext {
|
||||
/* ragel vars */
|
||||
int cs;
|
||||
int *stack;
|
||||
int top;
|
||||
int stacksize; /* not really used by ragel but need to remember it */
|
||||
char *p, *pe, *eof;
|
||||
|
||||
gchar *mark;
|
||||
gboolean in_setup_block;
|
||||
|
||||
gboolean action_call_with_param;
|
||||
|
||||
gboolean condition_with_key;
|
||||
gboolean condition_nonbool;
|
||||
gboolean condition_negated;
|
||||
|
||||
liCompOperator op;
|
||||
|
||||
liCastType cast;
|
||||
|
||||
GHashTable *uservars; /* foo = ...; */
|
||||
|
||||
GQueue *action_list_stack; /* first entry is current action list */
|
||||
GQueue *value_stack; /* stack of liValue* */
|
||||
GQueue *value_op_stack; /* stack of gchar* */
|
||||
GQueue *condition_stack; /* stack of condition* */
|
||||
|
||||
/* information about currenty parsed file */
|
||||
gchar *filename;
|
||||
gchar *ptr; /* pointer to the data */
|
||||
gsize len;
|
||||
gsize line; /* holds current line */
|
||||
};
|
||||
#define LI_CONFIG_ERROR li_config_error_quark()
|
||||
LI_API GQuark li_config_error_quark(void);
|
||||
|
||||
LI_API gboolean li_config_parse(liServer *srv, const gchar *config_path);
|
||||
|
||||
/* returns a new config parser stack with the first context in it */
|
||||
LI_API GList* li_config_parser_init(liServer *srv);
|
||||
LI_API void li_config_parser_finish(liServer *srv, GList *ctx_stack, gboolean free_all);
|
||||
|
||||
/* loads a file into memory and parses it */
|
||||
LI_API gboolean li_config_parser_file(liServer *srv, GList *ctx_stack, const gchar *path);
|
||||
/* parse more config snippets at runtime. does not support includes and modifying global vars */
|
||||
LI_API liAction* li_config_parse_live(liWorker *wrk, const gchar *sourcename, const char *source, gsize sourcelen, GError **error);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -82,6 +82,8 @@ struct liServer {
|
|||
GHashTable *plugins; /**< const gchar* => (liPlugin*) */
|
||||
liPlugin *core_plugin;
|
||||
|
||||
GHashTable *config_global_vars; /** for later reuse, (GString*) => (liValue*) */
|
||||
|
||||
/* registered by plugins */
|
||||
GHashTable *options; /**< const gchar* => (liServerOption*) */
|
||||
GHashTable *optionptrs; /**< const gchar* => (liServerOptionPtr*) */
|
||||
|
|
|
@ -33,6 +33,7 @@ typedef struct liActionFunc liActionFunc;
|
|||
typedef struct liBalancerFunc liBalancerFunc;
|
||||
|
||||
typedef enum {
|
||||
LI_ACTION_TNOTHING,
|
||||
LI_ACTION_TSETTING,
|
||||
LI_ACTION_TSETTINGPTR,
|
||||
LI_ACTION_TFUNCTION,
|
||||
|
|
|
@ -18,6 +18,8 @@ void li_action_release(liServer *srv, liAction *a) {
|
|||
assert(g_atomic_int_get(&a->refcount) > 0);
|
||||
if (g_atomic_int_dec_and_test(&a->refcount)) {
|
||||
switch (a->type) {
|
||||
case LI_ACTION_TNOTHING:
|
||||
break;
|
||||
case LI_ACTION_TSETTING:
|
||||
break;
|
||||
case LI_ACTION_TSETTINGPTR:
|
||||
|
@ -54,6 +56,15 @@ void li_action_acquire(liAction *a) {
|
|||
g_atomic_int_inc(&a->refcount);
|
||||
}
|
||||
|
||||
liAction* li_action_new(void) {
|
||||
liAction *a = g_slice_new(liAction);
|
||||
|
||||
a->refcount = 1;
|
||||
a->type = LI_ACTION_TNOTHING;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
liAction *li_action_new_setting(liOptionSet setting) {
|
||||
liAction *a = g_slice_new(liAction);
|
||||
|
||||
|
@ -128,12 +139,35 @@ liAction *li_action_new_balancer(liBackendSelectCB bselect, liBackendFallbackCB
|
|||
return a;
|
||||
}
|
||||
|
||||
void li_action_append_inplace(liAction *list, liAction *element) {
|
||||
assert(NULL != list && NULL != element);
|
||||
assert(1 == g_atomic_int_get(&list->refcount));
|
||||
|
||||
if (LI_ACTION_TLIST != list->type) {
|
||||
liAction *wrapped = NULL;
|
||||
if (LI_ACTION_TNOTHING != list->type) {
|
||||
wrapped = li_action_new();
|
||||
*wrapped = *list;
|
||||
}
|
||||
memset(list, 0, sizeof(*list));
|
||||
list->refcount = 1;
|
||||
list->type = LI_ACTION_TLIST;
|
||||
list->data.list = g_array_new(FALSE, TRUE, sizeof(liAction *));
|
||||
if (NULL != wrapped) g_array_append_val(list->data.list, wrapped);
|
||||
}
|
||||
if (LI_ACTION_TNOTHING != element->type) {
|
||||
li_action_acquire(element);
|
||||
g_array_append_val(list->data.list, element);
|
||||
}
|
||||
}
|
||||
|
||||
static void action_stack_element_release(liServer *srv, liVRequest *vr, action_stack_element *ase) {
|
||||
liAction *a = ase->act;
|
||||
|
||||
if (!ase || !a) return;
|
||||
|
||||
switch (a->type) {
|
||||
case LI_ACTION_TNOTHING:
|
||||
case LI_ACTION_TSETTING:
|
||||
case LI_ACTION_TSETTINGPTR:
|
||||
break;
|
||||
|
@ -313,6 +347,9 @@ liHandlerResult li_action_execute(liVRequest *vr) {
|
|||
ase_ndx = as->stack->len - 1; /* sometimes the stack gets modified - reread "ase" after that */
|
||||
|
||||
switch (a->type) {
|
||||
case LI_ACTION_TNOTHING:
|
||||
action_stack_pop(srv, vr, as);
|
||||
break;
|
||||
case LI_ACTION_TSETTING:
|
||||
vr->options[a->data.setting.ndx] = a->data.setting.value;
|
||||
action_stack_pop(srv, vr, as);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <fcntl.h>
|
||||
|
||||
GQuark li_chunk_error_quark(void) {
|
||||
return g_quark_from_string("g-chunk-error-quark");
|
||||
return g_quark_from_string("li-chunk-error-quark");
|
||||
}
|
||||
|
||||
/******************
|
||||
|
|
|
@ -17,8 +17,6 @@ static liValue* lua_params_to_value(liServer *srv, lua_State *L) {
|
|||
case 0:
|
||||
case 1: /* first parameter is the table the __call method is for */
|
||||
return NULL;
|
||||
case 2:
|
||||
return li_value_from_lua(srv, L);
|
||||
default:
|
||||
val = li_value_new_list();
|
||||
g_array_set_size(val->data.list, lua_gettop(L) - 1);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -93,6 +93,7 @@ liServer* li_server_new(const gchar *module_dir, gboolean module_resident) {
|
|||
srv->prepare_callbacks = g_array_new(FALSE, TRUE, sizeof(liServerPrepareCallbackData));
|
||||
|
||||
srv->mainaction = NULL;
|
||||
srv->config_global_vars = li_value_new_hashtable();
|
||||
|
||||
srv->action_mutex = g_mutex_new();
|
||||
|
||||
|
@ -166,6 +167,9 @@ void li_server_free(liServer* srv) {
|
|||
}
|
||||
|
||||
li_action_release(srv, srv->mainaction);
|
||||
srv->mainaction = NULL;
|
||||
g_hash_table_destroy(srv->config_global_vars);
|
||||
srv->config_global_vars = NULL;
|
||||
|
||||
li_event_clear(&srv->state_ready_watcher);
|
||||
g_mutex_free(srv->statelock);
|
||||
|
|
Loading…
Reference in New Issue