added option_copy(); fixed variable statements in config parser where assignments without parser func lead to OPTION_NONE options
commit
978eb166d1
|
@ -317,19 +317,21 @@
|
|||
|
||||
action actionref {
|
||||
/* varname is on the stack */
|
||||
option *o, *r;
|
||||
option *o, *r, *t;
|
||||
|
||||
o = g_queue_pop_head(ctx->option_stack);
|
||||
|
||||
/* action refs starting with "var." are user defined variables */
|
||||
if (g_str_has_prefix(o->value.opt_string->str, "var.")) {
|
||||
/* look up var in hashtable, push option onto stack */
|
||||
r = g_hash_table_lookup(ctx->uservars, o->value.opt_string);
|
||||
/* look up var in hashtable, copy and push option onto stack */
|
||||
t = g_hash_table_lookup(ctx->uservars, o->value.opt_string);
|
||||
|
||||
if (r == NULL) {
|
||||
if (t == NULL) {
|
||||
log_warning(srv, NULL, "unknown variable '%s'", o->value.opt_string->str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
r = option_copy(t);
|
||||
}
|
||||
else {
|
||||
/* real action, lookup hashtable and create new action option */
|
||||
|
@ -471,6 +473,16 @@
|
|||
|
||||
option_free(val);
|
||||
}
|
||||
/* internal functions */
|
||||
else if (g_str_equal(name->value.opt_string->str, "__print")) {
|
||||
g_printerr("%s:%zd type: %s", ctx->filename, ctx->line, option_type_string(val->type));
|
||||
switch (val->type) {
|
||||
case OPTION_INT: g_printerr(", value: %d\n", val->value.opt_int); break;
|
||||
case OPTION_STRING: g_printerr(", value: %s\n", val->value.opt_string->str); break;
|
||||
default: g_printerr("\n");
|
||||
}
|
||||
}
|
||||
/* normal function action */
|
||||
else {
|
||||
/* TODO */
|
||||
if (ctx->in_setup_block) {
|
||||
|
@ -679,7 +691,7 @@
|
|||
string = ( '"' (any-'"')* '"' ) %string;
|
||||
|
||||
# advanced types
|
||||
varname = ( (alpha ( alnum | [._] )*) - boolean ) >mark %varname;
|
||||
varname = ( '__' ? (alpha ( alnum | [._] )*) - boolean ) >mark %varname;
|
||||
actionref = ( varname ) %actionref;
|
||||
list = ( '(' >list_start );
|
||||
hash = ( '[' >hash_start );
|
||||
|
|
|
@ -63,6 +63,41 @@ option* option_new_condition(server *srv, condition *c) {
|
|||
return opt;
|
||||
}
|
||||
|
||||
option* option_copy(option* opt) {
|
||||
option *n;
|
||||
|
||||
switch (opt->type) {
|
||||
case OPTION_NONE: n = option_new_bool(FALSE); n->type = OPTION_NONE; return n; /* hack */
|
||||
case OPTION_BOOLEAN: return option_new_bool(opt->value.opt_bool);
|
||||
case OPTION_INT: return option_new_int(opt->value.opt_int);
|
||||
case OPTION_STRING: return option_new_string(g_string_new_len(GSTR_LEN(opt->value.opt_string)));
|
||||
/* list: we have to copy every option in the list! */
|
||||
case OPTION_LIST:
|
||||
n = option_new_list();
|
||||
g_array_set_size(n->value.opt_list, opt->value.opt_list->len);
|
||||
for (guint i = 0; i < opt->value.opt_list->len; i++)
|
||||
//g_array_insert_val((*(n->value.opt_list)), i, option_copy(g_array_index(opt->value.opt_list, option*, i)));
|
||||
g_array_insert_vals(n->value.opt_list, i, option_copy(g_array_index(opt->value.opt_list, option*, i)), 1);
|
||||
return n;
|
||||
/* hash: iterate over hashtable, clone each option */
|
||||
case OPTION_HASH:
|
||||
n = option_new_hash();
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer k, v;
|
||||
g_hash_table_iter_init(&iter, opt->value.opt_hash);
|
||||
while (g_hash_table_iter_next(&iter, &k, &v))
|
||||
g_hash_table_insert(n->value.opt_hash, g_string_new_len(GSTR_LEN((GString*)k)), option_copy((option*)v));
|
||||
}
|
||||
return n;
|
||||
/* TODO: does it make sense to clone action and condition options? */
|
||||
case OPTION_ACTION:
|
||||
case OPTION_CONDITION:
|
||||
assert(NULL);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void option_free(option* opt) {
|
||||
if (!opt) return;
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ LI_API option* option_new_list();
|
|||
LI_API option* option_new_hash();
|
||||
LI_API option* option_new_action(server *srv, action *a);
|
||||
LI_API option* option_new_condition(server *srv, condition *c);
|
||||
|
||||
LI_API option* option_copy(option* opt);
|
||||
LI_API void option_free(option* opt);
|
||||
|
||||
LI_API const char* option_type_string(option_type type);
|
||||
|
|
Loading…
Reference in New Issue