[config parser] change syntax again: user defined variables are now defined as 'x = ...;'. user defined actions are not special anymore

personal/stbuehler/wip
Thomas Porzelt 12 years ago
parent abd58794d8
commit 04c8356b44

@ -32,8 +32,7 @@ struct liConfigParserContext {
liCastType cast;
GHashTable *action_blocks; /* foo { } */
GHashTable *uservars; /* var.foo */
GHashTable *uservars; /* foo = ...; */
GQueue *action_list_stack; /* first entry is current action list */
GQueue *value_stack; /* stack of liValue* */

@ -449,64 +449,53 @@ static gboolean config_parser_include(liServer *srv, GList *ctx_stack, gchar *pa
action actionref {
/* varname is on the stack */
liValue *o, *r, *t;
o = g_queue_pop_head(ctx->value_stack);
_printf("got actionref: %s in line %zd\n", o->data.string->str, ctx->line);
liValue *name, *v;
/* action refs starting with "var." are user defined variables */
if (g_str_has_prefix(o->data.string->str, "var.")) {
/* look up var in hashtable, copy and push value onto stack */
t = g_hash_table_lookup(ctx->uservars, o->data.string);
name = g_queue_pop_head(ctx->value_stack);
assert(name->type == LI_VALUE_STRING);
if (t == NULL) {
WARNING(srv, "unknown variable '%s'", o->data.string->str);
li_value_free(o);
return FALSE;
}
_printf("got actionref: %s in line %zd\n", name->data.string->str, ctx->line);
r = li_value_copy(t);
} else if (g_str_equal(o->data.string->str, "sys.pid")) {
r = li_value_new_number(getpid());
} else if (g_str_equal(o->data.string->str, "sys.cwd")) {
/* there are some special variables that we just create here */
if (g_str_equal(name->data.string->str, "sys.pid")) {
v = li_value_new_number(getpid());
} else if (g_str_equal(name->data.string->str, "sys.cwd")) {
gchar cwd[1024];
if (NULL != getcwd(cwd, 1023)) {
r = li_value_new_string(g_string_new(cwd));
v = li_value_new_string(g_string_new(cwd));
} else {
ERROR(srv, "failed to get CWD: %s", g_strerror(errno));
li_value_free(o);
li_value_free(name);
return FALSE;
}
} else if (g_str_equal(o->data.string->str, "sys.version")) {
r = li_value_new_string(g_string_new(PACKAGE_VERSION));
} else if (g_str_has_prefix(o->data.string->str, "sys.env.")) {
} else if (g_str_equal(name->data.string->str, "sys.version")) {
v = li_value_new_string(g_string_new(PACKAGE_VERSION));
} else if (g_str_has_prefix(name->data.string->str, "sys.env.")) {
/* look up string in environment, push value onto stack */
gchar *env = getenv(o->data.string->str + sizeof("sys.env.") - 1);
gchar *env = getenv(name->data.string->str + sizeof("sys.env.") - 1);
if (env == NULL) {
ERROR(srv, "unknown environment variable: %s", o->data.string->str + sizeof("sys.env.") - 1);
li_value_free(o);
ERROR(srv, "unknown environment variable: %s", name->data.string->str + sizeof("sys.env.") - 1);
li_value_free(name);
return FALSE;
}
r = li_value_new_string(g_string_new(env));
v = li_value_new_string(g_string_new(env));
} else {
/* real action, lookup hashtable and create new action value */
liAction *a;
a = g_hash_table_lookup(ctx->action_blocks, o->data.string);
/* look up uservar in hashtable, copy and push value onto stack */
v = g_hash_table_lookup(ctx->uservars, name->data.string);
if (a == NULL) {
WARNING(srv, "unknown action block referenced: %s", o->data.string->str);
if (v == NULL) {
WARNING(srv, "unknown uservar '%s'", name->data.string->str);
li_value_free(name);
return FALSE;
}
li_action_acquire(a);
r = li_value_new_action(srv, a);
v = li_value_copy(v);
}
g_queue_push_head(ctx->value_stack, r);
li_value_free(o);
g_queue_push_head(ctx->value_stack, v);
li_value_free(name);
}
action operator {
@ -541,7 +530,7 @@ static gboolean config_parser_include(liServer *srv, GList *ctx_stack, gchar *pa
}
action action_call {
liValue *val, *name;
liValue *val, *name, *uservar;
liAction *a, *al;
if (ctx->action_call_with_param) {
@ -641,39 +630,20 @@ static gboolean config_parser_include(liServer *srv, GList *ctx_stack, gchar *pa
li_value_free(name);
if (val)
li_value_free(val);
} else if (g_str_has_prefix(name->data.string->str, "var.")) {
/* assignment vor user defined variable, insert into hashtable */
gpointer old_key;
gpointer old_val;
GString *str;
_printf("%s", "... which is a user defined var\n");
if (!val) {
WARNING(srv, "%s", "var. definitions expect a parameter");
li_value_free(name);
return FALSE;
}
str = li_value_extract_string(name);
/* free old key and value if we are overwriting it */
if (g_hash_table_lookup_extended(ctx->uservars, str, &old_key, &old_val)) {
g_hash_table_remove(ctx->uservars, str);
g_string_free(old_key, TRUE);
li_value_free(old_val);
}
g_hash_table_insert(ctx->uservars, str, val);
li_value_free(name);
}
/* normal action call */
else {
/* user defined action */
if (NULL != (a = g_hash_table_lookup(ctx->action_blocks, name->data.string))) {
if (NULL != (uservar = g_hash_table_lookup(ctx->uservars, name->data.string))) {
_printf("%s", "... which is a user defined action\n");
if (val) {
if (uservar->type != LI_VALUE_ACTION) {
WARNING(srv, "value of type action expected, got %s", li_value_type_string(uservar->type));
li_value_free(name);
if (val)
li_value_free(val);
return FALSE;
} else if (val) {
WARNING(srv, "%s", "user defined actions don't take a parameter");
li_value_free(name);
li_value_free(val);
@ -684,6 +654,7 @@ static gboolean config_parser_include(liServer *srv, GList *ctx_stack, gchar *pa
return FALSE;
}
a = uservar->data.val_action.action;
li_action_acquire(a);
al = g_queue_peek_head(ctx->action_list_stack);
g_array_append_val(al->data.list, a);
@ -793,31 +764,50 @@ static gboolean config_parser_include(liServer *srv, GList *ctx_stack, gchar *pa
ctx->in_setup_block = FALSE;
}
action action_definition {
action uservar_definition {
/* assignment vor user defined variable, insert into hashtable */
liValue *name, *v;
liAction *al;
GString *str;
gpointer old_key;
gpointer old_val;
/* we have the action list and then the name on the option stack */
v = g_queue_pop_head(ctx->value_stack);
assert(v->type == LI_VALUE_ACTION);
name = g_queue_pop_head(ctx->value_stack);
assert(name->type == LI_VALUE_STRING);
if (ctx->in_setup_block) {
ERROR(srv, "%s", "no action block definition inside the setup block allowed");
_printf("uservar definition %s = %s in line %zd\n", name->data.string->str, li_value_type_string(v->type), ctx->line);
if (NULL != g_hash_table_lookup(srv->setups, name->data.string->str)) {
WARNING(srv, "cannot define uservar with name '%s', a setup action with same name exists already", name->data.string->str);
li_value_free(name);
li_value_free(v);
return FALSE;
}
if (NULL != g_hash_table_lookup(srv->actions, name->data.string->str)) {
WARNING(srv, "cannot define uservar with name '%s', an action with same name exists already", name->data.string->str);
li_value_free(name);
li_value_free(v);
return FALSE;
}
if (NULL != g_hash_table_lookup(srv->optionptrs, name->data.string->str)) {
WARNING(srv, "cannot define uservar with name '%s', an option with same name exists already", name->data.string->str);
li_value_free(name);
li_value_free(v);
return FALSE;
}
_printf("action block definition %s in line %zd\n", name->data.string->str, ctx->line);
str = li_value_extract_string(name);
al = li_value_extract_action(v);
str = g_string_new_len(name->data.string->str, name->data.string->len);
g_hash_table_insert(ctx->action_blocks, str, al);
/* free old key and value if we are overwriting it */
if (g_hash_table_lookup_extended(ctx->uservars, str, &old_key, &old_val)) {
g_hash_table_remove(ctx->uservars, str);
g_string_free(old_key, TRUE);
li_value_free(old_val);
}
li_value_free(v);
g_hash_table_insert(ctx->uservars, str, v);
li_value_free(name);
}
@ -1181,11 +1171,11 @@ static gboolean config_parser_include(liServer *srv, GList *ctx_stack, gchar *pa
condition_chain = ( cond_if (noise+ cond_else_if)* (noise+ cond_else)? ) %condition_chain;
# statements
action_definition = ( 'action' ws+ varname noise+ action_block ) %action_definition;
uservar_definition = ( varname ws+ '=' ws+ value_statement ';' ) %uservar_definition;
action_call_noparam = ( varname ws* ';' ) %action_call_noparam;
action_call_param = ( varname ws+ value_statement ';' ) %action_call_param;
action_call = ( action_call_noparam | action_call_param ) %action_call;
statement = ( action_call | action_definition | condition_chain | setup_block );
statement = ( action_call | uservar_definition | condition_chain | setup_block );
# scanner
list_scanner := ( ((value_statement %list_push ( ',' value_statement %list_push )*) | noise*) ')' >list_end );
@ -1216,12 +1206,9 @@ static liConfigParserContext *config_parser_context_new(liServer *srv, GList *ct
ctx->value_stack = ((liConfigParserContext*) ctx_stack->data)->value_stack;
ctx->condition_stack = ((liConfigParserContext*) ctx_stack->data)->condition_stack;
ctx->value_op_stack = ((liConfigParserContext*) ctx_stack->data)->value_op_stack;
ctx->action_blocks = ((liConfigParserContext*) ctx_stack->data)->action_blocks;
ctx->uservars = ((liConfigParserContext*) ctx_stack->data)->uservars;
}
else {
ctx->action_blocks = g_hash_table_new_full((GHashFunc) g_string_hash, (GEqualFunc) g_string_equal, NULL, NULL);
ctx->uservars = g_hash_table_new_full((GHashFunc) g_string_hash, (GEqualFunc) g_string_equal, NULL, NULL);
ctx->action_list_stack = g_queue_new();
@ -1286,15 +1273,6 @@ void li_config_parser_finish(liServer *srv, GList *ctx_stack, gboolean free_all)
if (free_all) {
ctx = (liConfigParserContext*) ctx_stack->data;
g_hash_table_iter_init(&iter, ctx->action_blocks);
while (g_hash_table_iter_next(&iter, &key, &val)) {
li_action_release(srv, val);
g_string_free(key, TRUE);
}
g_hash_table_destroy(ctx->action_blocks);
g_hash_table_iter_init(&iter, ctx->uservars);
while (g_hash_table_iter_next(&iter, &key, &val)) {
@ -1305,7 +1283,6 @@ void li_config_parser_finish(liServer *srv, GList *ctx_stack, gboolean free_all)
g_hash_table_destroy(ctx->uservars);
config_parser_context_free(srv, ctx, TRUE);
g_list_free(ctx_stack);

Loading…
Cancel
Save