|
|
|
@ -1,5 +1,4 @@ |
|
|
|
|
%token_prefix TK_ |
|
|
|
|
%token_type {buffer *} |
|
|
|
|
%extra_argument {config_t *ctx} |
|
|
|
|
%name configparser |
|
|
|
|
|
|
|
|
@ -65,15 +64,13 @@ data_unset *configparser_merge_data(config_t *ctx, data_unset *op1, const data_u |
|
|
|
|
data_string *ds = (data_string *)op1; |
|
|
|
|
buffer_append_long(ds->value, ((data_integer*)op2)->value); |
|
|
|
|
return op1; |
|
|
|
|
} |
|
|
|
|
else if (op1->type == TYPE_INTEGER && op2->type == TYPE_STRING) { |
|
|
|
|
} else if (op1->type == TYPE_INTEGER && op2->type == TYPE_STRING) { |
|
|
|
|
data_string *ds = data_string_init(); |
|
|
|
|
buffer_append_long(ds->value, ((data_integer*)op1)->value); |
|
|
|
|
buffer_append_string_buffer(ds->value, ((data_string*)op2)->value); |
|
|
|
|
op1->free(op1); |
|
|
|
|
return (data_unset *)ds; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
} else { |
|
|
|
|
fprintf(stderr, "data type mismatch, cannot be merge\n"); |
|
|
|
|
ctx->ok = 0; |
|
|
|
|
op1->free(op1); |
|
|
|
@ -119,32 +116,47 @@ input ::= metalines. |
|
|
|
|
metalines ::= metalines metaline. |
|
|
|
|
metalines ::= . |
|
|
|
|
metaline ::= varline. |
|
|
|
|
metaline ::= condlines EOL. |
|
|
|
|
metaline ::= condlines(A) EOL. { A = NULL; } |
|
|
|
|
metaline ::= include. |
|
|
|
|
metaline ::= EOL. |
|
|
|
|
|
|
|
|
|
%type value {data_unset *} |
|
|
|
|
%type expression {data_unset *} |
|
|
|
|
%type context_rvalue {data_unset *} |
|
|
|
|
%type aelement {data_unset *} |
|
|
|
|
%type aelements {array *} |
|
|
|
|
%type array {array *} |
|
|
|
|
%type condline {data_config *} |
|
|
|
|
%type condlines {data_config *} |
|
|
|
|
%type cond {config_cond_t } |
|
|
|
|
%token_destructor { buffer_free($$); } |
|
|
|
|
%type value {data_unset *} |
|
|
|
|
%type expression {data_unset *} |
|
|
|
|
%type aelement {data_unset *} |
|
|
|
|
%type condline {data_config *} |
|
|
|
|
%type condlines {data_config *} |
|
|
|
|
%type aelements {array *} |
|
|
|
|
%type array {array *} |
|
|
|
|
%type key {buffer *} |
|
|
|
|
|
|
|
|
|
%type cond {config_cond_t } |
|
|
|
|
|
|
|
|
|
%destructor value { $$->free($$); } |
|
|
|
|
%destructor expression { $$->free($$); } |
|
|
|
|
%destructor aelement { $$->free($$); } |
|
|
|
|
%destructor condline { $$->free((data_unset *)$$); } |
|
|
|
|
%destructor condlines { $$->free((data_unset *)$$); } |
|
|
|
|
%destructor aelements { array_free($$); } |
|
|
|
|
%destructor array { array_free($$); } |
|
|
|
|
%destructor key { buffer_free($$); } |
|
|
|
|
|
|
|
|
|
%token_type {buffer *} |
|
|
|
|
%token_destructor { buffer_free($$); } |
|
|
|
|
|
|
|
|
|
varline ::= key(A) ASSIGN expression(B). { |
|
|
|
|
buffer_copy_string_buffer(B->key, A); |
|
|
|
|
if (NULL == array_get_element(ctx->current->value, B->key->ptr)) { |
|
|
|
|
array_insert_unique(ctx->current->value, B); |
|
|
|
|
B = NULL; |
|
|
|
|
} else { |
|
|
|
|
fprintf(stderr, "Duplicate config variable in conditional 1 %s: %s\n", |
|
|
|
|
ctx->current->key->ptr, B->key->ptr); |
|
|
|
|
ctx->ok = 0; |
|
|
|
|
B->free(B); |
|
|
|
|
B = NULL; |
|
|
|
|
} |
|
|
|
|
buffer_free(A); |
|
|
|
|
A = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
varline ::= key(A) APPEND expression(B). { |
|
|
|
@ -177,8 +189,9 @@ key(A) ::= LKEY(B). { |
|
|
|
|
if (strchr(B->ptr, '.') == NULL) { |
|
|
|
|
A = buffer_init_string("var."); |
|
|
|
|
buffer_append_string_buffer(A, B); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
buffer_free(B); |
|
|
|
|
B = NULL; |
|
|
|
|
} else { |
|
|
|
|
A = B; |
|
|
|
|
B = NULL; |
|
|
|
|
} |
|
|
|
@ -213,17 +226,20 @@ value(A) ::= STRING(B). { |
|
|
|
|
A = (data_unset *)data_string_init(); |
|
|
|
|
buffer_copy_string_buffer(((data_string *)(A))->value, B); |
|
|
|
|
buffer_free(B); |
|
|
|
|
B = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
value(A) ::= INTEGER(B). { |
|
|
|
|
A = (data_unset *)data_integer_init(); |
|
|
|
|
((data_integer *)(A))->value = strtol(B->ptr, NULL, 10); |
|
|
|
|
buffer_free(B); |
|
|
|
|
B = NULL; |
|
|
|
|
} |
|
|
|
|
value(A) ::= array(B). { |
|
|
|
|
A = (data_unset *)data_array_init(); |
|
|
|
|
array_free(((data_array *)(A))->value); |
|
|
|
|
((data_array *)(A))->value = B; |
|
|
|
|
B = NULL; |
|
|
|
|
} |
|
|
|
|
array(A) ::= LPARAN aelements(B) RPARAN. { |
|
|
|
|
A = B; |
|
|
|
@ -234,23 +250,28 @@ aelements(A) ::= aelements(C) COMMA aelement(B). { |
|
|
|
|
if (buffer_is_empty(B->key) || |
|
|
|
|
NULL == array_get_element(C, B->key->ptr)) { |
|
|
|
|
array_insert_unique(C, B); |
|
|
|
|
B = NULL; |
|
|
|
|
} else { |
|
|
|
|
fprintf(stderr, "Duplicate array-key: %s\n", |
|
|
|
|
B->key->ptr); |
|
|
|
|
B->free(B); |
|
|
|
|
ctx->ok = 0; |
|
|
|
|
B->free(B); |
|
|
|
|
B = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
A = C; |
|
|
|
|
C = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
aelements(A) ::= aelements(C) COMMA. { |
|
|
|
|
A = C; |
|
|
|
|
C = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
aelements(A) ::= aelement(B). { |
|
|
|
|
A = array_init(); |
|
|
|
|
array_insert_unique(A, B); |
|
|
|
|
B = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
aelement(A) ::= expression(B). { |
|
|
|
@ -260,6 +281,7 @@ aelement(A) ::= expression(B). { |
|
|
|
|
aelement(A) ::= STRING(B) ARRAY_ASSIGN expression(C). { |
|
|
|
|
buffer_copy_string_buffer(C->key, B); |
|
|
|
|
buffer_free(B); |
|
|
|
|
B = NULL; |
|
|
|
|
|
|
|
|
|
A = C; |
|
|
|
|
C = NULL; |
|
|
|
@ -386,6 +408,10 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET STRING(C) RBRACKET cond(E) expression( |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
buffer_free(b); |
|
|
|
|
buffer_free(B); |
|
|
|
|
B = NULL; |
|
|
|
|
buffer_free(C); |
|
|
|
|
C = NULL; |
|
|
|
|
D->free(D); |
|
|
|
|
D = NULL; |
|
|
|
|
} |
|
|
|
@ -413,7 +439,7 @@ include ::= INCLUDE expression(A). { |
|
|
|
|
ctx->ok = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
A->free(A); |
|
|
|
|
} |
|
|
|
|
A->free(A); |
|
|
|
|
A = NULL; |
|
|
|
|
} |
|
|
|
|