lighttpd 1.4.x
https://www.lighttpd.net/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
3.8 KiB
180 lines
3.8 KiB
%token_prefix TK_ |
|
%token_type {buffer *} |
|
%extra_argument {config_t *ctx} |
|
%name configparser |
|
|
|
%include { |
|
#include <assert.h> |
|
#include <stdio.h> |
|
#include "config.h" |
|
#include "configfile.h" |
|
#include "buffer.h" |
|
#include "array.h" |
|
} |
|
|
|
%parse_failure { |
|
ctx->ok = 0; |
|
} |
|
|
|
input ::= metalines. |
|
metalines ::= metalines metaline. |
|
metalines ::= . |
|
metaline ::= varline. |
|
metaline ::= condline. |
|
metaline ::= EOL. |
|
|
|
%type value {data_unset *} |
|
%type aelement {data_unset *} |
|
%type aelements {array *} |
|
%type array {array *} |
|
%type cond {config_cond_t } |
|
%token_destructor { buffer_free($$); } |
|
|
|
varline ::= key(A) ASSIGN value(B). { |
|
buffer_copy_string_buffer(B->key, A); |
|
if (NULL == array_get_element(ctx->ctx_config, B->key->ptr)) { |
|
array_insert_unique(ctx->ctx_config, B); |
|
} else { |
|
fprintf(stderr, "Duplicate config variable in conditional %s: %s\n", |
|
ctx->ctx_name->ptr, B->key->ptr); |
|
ctx->ok = 0; |
|
B->free(B); |
|
} |
|
buffer_free(A); |
|
} |
|
|
|
key(A) ::= LKEY(B). { |
|
A = B; |
|
B = NULL; |
|
} |
|
|
|
value(A) ::= STRING(B). { |
|
A = (data_unset *)data_string_init(); |
|
buffer_copy_string_buffer(((data_string *)(A))->value, B); |
|
buffer_free(B); |
|
} |
|
|
|
value(A) ::= INTEGER(B). { |
|
A = (data_unset *)data_integer_init(); |
|
((data_integer *)(A))->value = strtol(B->ptr, NULL, 10); |
|
buffer_free(B); |
|
} |
|
value(A) ::= array(B). { |
|
A = (data_unset *)data_array_init(); |
|
array_free(((data_array *)(A))->value); |
|
((data_array *)(A))->value = B; |
|
} |
|
array(A) ::= LPARAN aelements(B) RPARAN. { |
|
A = B; |
|
B = NULL; |
|
} |
|
|
|
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); |
|
} else { |
|
fprintf(stderr, "Duplicate array-key: %s\n", |
|
B->key->ptr); |
|
B->free(B); |
|
ctx->ok = 0; |
|
} |
|
|
|
A = C; |
|
} |
|
|
|
aelements(A) ::= aelements(C) COMMA. { |
|
A = C; |
|
} |
|
|
|
aelements(A) ::= aelement(B). { |
|
A = array_init(); |
|
array_insert_unique(A, B); |
|
} |
|
|
|
aelement(A) ::= value(B). { |
|
A = B; |
|
B = NULL; |
|
} |
|
aelement(A) ::= STRING(B) ARRAY_ASSIGN value(C). { |
|
buffer_copy_string_buffer(C->key, B); |
|
buffer_free(B); |
|
|
|
A = C; |
|
C = NULL; |
|
} |
|
condline ::= context LCURLY metalines RCURLY EOL. { |
|
data_config *dc; |
|
|
|
dc = (data_config *)array_get_element(ctx->config, "global"); |
|
assert(dc); |
|
ctx->ctx_name = dc->key; |
|
ctx->ctx_config = dc->value; |
|
} |
|
|
|
context ::= DOLLAR SRVVARNAME(B) LBRACKET STRING(C) RBRACKET cond(E) STRING(D). { |
|
data_config *dc; |
|
buffer *b; |
|
|
|
b = buffer_init(); |
|
buffer_copy_string_buffer(b, B); |
|
buffer_append_string_buffer(b, C); |
|
buffer_append_string_buffer(b, D); |
|
buffer_append_long(b, E); |
|
|
|
if (NULL != (dc = (data_config *)array_get_element(ctx->config, b->ptr))) { |
|
ctx->ctx_name = dc->key; |
|
ctx->ctx_config = dc->value; |
|
} else { |
|
dc = data_config_init(); |
|
|
|
buffer_copy_string_buffer(dc->key, b); |
|
buffer_copy_string_buffer(dc->comp_key, B); |
|
buffer_append_string_buffer(dc->comp_key, C); |
|
dc->cond = E; |
|
|
|
switch(E) { |
|
case CONFIG_COND_NE: |
|
case CONFIG_COND_EQ: |
|
dc->match.string = buffer_init_string(D->ptr); |
|
break; |
|
#ifdef HAVE_PCRE_H |
|
case CONFIG_COND_NOMATCH: |
|
case CONFIG_COND_MATCH: { |
|
const char *errptr; |
|
int erroff; |
|
|
|
if (NULL == (dc->match.regex = |
|
pcre_compile(D->ptr, 0, &errptr, &erroff, NULL))) { |
|
dc->match.string = buffer_init_string(errptr); |
|
dc->cond = CONFIG_COND_UNSET; |
|
} |
|
break; |
|
} |
|
#endif |
|
default: |
|
break; |
|
} |
|
|
|
array_insert_unique(ctx->config, (data_unset *)dc); |
|
|
|
ctx->ctx_name = dc->key; |
|
ctx->ctx_config = dc->value; |
|
} |
|
buffer_free(b); |
|
buffer_free(B); |
|
buffer_free(C); |
|
buffer_free(D); |
|
} |
|
cond(A) ::= EQ. { |
|
A = CONFIG_COND_EQ; |
|
} |
|
cond(A) ::= MATCH. { |
|
A = CONFIG_COND_MATCH; |
|
} |
|
cond(A) ::= NE. { |
|
A = CONFIG_COND_NE; |
|
} |
|
cond(A) ::= NOMATCH. { |
|
A = CONFIG_COND_NOMATCH; |
|
}
|
|
|