|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|