diff options
Diffstat (limited to 'src/configparser.y')
-rw-r--r-- | src/configparser.y | 200 |
1 files changed, 74 insertions, 126 deletions
diff --git a/src/configparser.y b/src/configparser.y index aa6fe98..4ca4fa0 100644 --- a/src/configparser.y +++ b/src/configparser.y @@ -3,13 +3,15 @@ %name configparser %include { -#include "configfile.h" -#include "buffer.h" -#include "array.h" - #include <assert.h> #include <stdio.h> #include <string.h> +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "configfile.h" +#include "buffer.h" +#include "array.h" static void configparser_push(config_t *ctx, data_config *dc, int isnew) { if (isnew) { @@ -19,10 +21,6 @@ static void configparser_push(config_t *ctx, data_config *dc, int isnew) { dc->parent = ctx->current; array_insert_unique(dc->parent->childs, (data_unset *)dc); } - if (ctx->configs_stack->used > 0 && ctx->current->context_ndx == 0) { - fprintf(stderr, "Cannot use conditionals inside a global { ... } block\n"); - exit(-1); - } array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current); ctx->current = dc; } @@ -35,25 +33,43 @@ static data_config *configparser_pop(config_t *ctx) { /* return a copied variable */ static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) { - data_unset *du; - data_config *dc; + if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) { + char *env; + + if (NULL != (env = getenv(key->ptr + 4))) { + data_string *ds; + ds = data_string_init(); + buffer_append_string(ds->value, env); + return (data_unset *)ds; + } + + fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4); + ctx->ok = 0; + + return NULL; + } else { + data_unset *du; + data_config *dc; #if 0 - fprintf(stderr, "get var %s\n", key->ptr); + fprintf(stderr, "get var %s\n", key->ptr); #endif - for (dc = ctx->current; dc; dc = dc->parent) { + for (dc = ctx->current; dc; dc = dc->parent) { #if 0 - fprintf(stderr, "get var on block: %s\n", dc->key->ptr); - array_print(dc->value, 0); + fprintf(stderr, "get var on block: %s\n", dc->key->ptr); + array_print(dc->value, 0); #endif - if (NULL != (du = array_get_element(dc->value, key->ptr))) { - return du->copy(du); + if (NULL != (du = array_get_element(dc->value, key->ptr))) { + return du->copy(du); + } } + fprintf(stderr, "Undefined config variable: %s\n", key->ptr); + ctx->ok = 0; + return NULL; } - return NULL; } -/* op1 is to be eat/return by this function if success, op1->key is not cared +/* op1 is to be eat/return by this function, op1->key is not cared op2 is left untouch, unreferenced */ data_unset *configparser_merge_data(data_unset *op1, const data_unset *op2) { @@ -70,7 +86,8 @@ data_unset *configparser_merge_data(data_unset *op1, const data_unset *op2) { op1->free(op1); return (data_unset *)ds; } else { - fprintf(stderr, "data type mismatch, cannot merge\n"); + fprintf(stderr, "data type mismatch, cannot be merge\n"); + op1->free(op1); return NULL; } } @@ -113,7 +130,6 @@ input ::= metalines. metalines ::= metalines metaline. metalines ::= . metaline ::= varline. -metaline ::= global. metaline ::= condlines(A) EOL. { A = NULL; } metaline ::= include. metaline ::= include_shell. @@ -124,7 +140,6 @@ metaline ::= EOL. %type aelement {data_unset *} %type condline {data_config *} %type condlines {data_config *} -%type global {data_config *} %type aelements {array *} %type array {array *} %type key {buffer *} @@ -144,24 +159,17 @@ metaline ::= EOL. %token_destructor { buffer_free($$); } varline ::= key(A) ASSIGN expression(B). { - if (ctx->ok) { - buffer_copy_string_buffer(B->key, A); - if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) { - fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n", - ctx->current->context_ndx, - ctx->current->key->ptr, A->ptr); - ctx->ok = 0; - } else 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 %d %s: %s\n", - ctx->current->context_ndx, - ctx->current->key->ptr, B->key->ptr); - ctx->ok = 0; - B->free(B); - B = NULL; - } + 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 %d %s: %s\n", + ctx->current->context_ndx, + ctx->current->key->ptr, B->key->ptr); + ctx->ok = 0; + B->free(B); + B = NULL; } buffer_free(A); A = NULL; @@ -171,12 +179,7 @@ varline ::= key(A) APPEND expression(B). { array *vars = ctx->current->value; data_unset *du; - if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) { - fprintf(stderr, "Appending env variable is not supported in conditional %d %s: %s\n", - ctx->current->context_ndx, - ctx->current->key->ptr, A->ptr); - ctx->ok = 0; - } else if (NULL != (du = array_get_element(vars, A->ptr))) { + if (NULL != (du = array_get_element(vars, A->ptr))) { /* exists in current block */ du = configparser_merge_data(du, B); if (NULL == du) { @@ -186,7 +189,6 @@ varline ::= key(A) APPEND expression(B). { buffer_copy_string_buffer(du->key, A); array_replace(vars, du); } - B->free(B); } else if (NULL != (du = configparser_get_variable(ctx, A))) { du = configparser_merge_data(du, B); if (NULL == du) { @@ -196,13 +198,15 @@ varline ::= key(A) APPEND expression(B). { buffer_copy_string_buffer(du->key, A); array_insert_unique(ctx->current->value, du); } - B->free(B); } else { - buffer_copy_string_buffer(B->key, A); - array_insert_unique(ctx->current->value, B); + fprintf(stderr, "Undefined config variable in conditional %d %s: %s\n", + ctx->current->context_ndx, + ctx->current->key->ptr, A->ptr); + ctx->ok = 0; } buffer_free(A); A = NULL; + B->free(B); B = NULL; } @@ -234,24 +238,7 @@ expression(A) ::= value(B). { } value(A) ::= key(B). { - A = NULL; - if (strncmp(B->ptr, "env.", sizeof("env.") - 1) == 0) { - char *env; - - if (NULL != (env = getenv(B->ptr + 4))) { - data_string *ds; - ds = data_string_init(); - buffer_append_string(ds->value, env); - A = (data_unset *)ds; - } - else { - fprintf(stderr, "Undefined env variable: %s\n", B->ptr + 4); - ctx->ok = 0; - } - } else if (NULL == (A = configparser_get_variable(ctx, B))) { - fprintf(stderr, "Undefined config variable: %s\n", B->ptr); - ctx->ok = 0; - } + A = configparser_get_variable(ctx, B); if (!A) { /* make a dummy so it won't crash */ A = (data_unset *)data_string_init(); @@ -279,9 +266,6 @@ value(A) ::= array(B). { ((data_array *)(A))->value = B; B = NULL; } -array(A) ::= LPARAN RPARAN. { - A = array_init(); -} array(A) ::= LPARAN aelements(B) RPARAN. { A = B; B = NULL; @@ -293,13 +277,13 @@ aelements(A) ::= aelements(C) COMMA aelement(B). { array_insert_unique(C, B); B = NULL; } else { - fprintf(stderr, "Duplicate array-key: %s\n", + fprintf(stderr, "Duplicate array-key: %s\n", B->key->ptr); ctx->ok = 0; B->free(B); B = NULL; } - + A = C; C = NULL; } @@ -323,7 +307,7 @@ aelement(A) ::= stringop(B) ARRAY_ASSIGN expression(C). { buffer_copy_string_buffer(C->key, B); buffer_free(B); B = NULL; - + A = C; C = NULL; } @@ -331,29 +315,8 @@ aelement(A) ::= stringop(B) ARRAY_ASSIGN expression(C). { eols ::= EOL. eols ::= . -globalstart ::= GLOBAL. { - data_config *dc; - dc = (data_config *)array_get_element(ctx->srv->config_context, "global"); - assert(dc); - configparser_push(ctx, dc, 0); -} - -global(A) ::= globalstart LCURLY metalines RCURLY. { - data_config *cur; - - cur = ctx->current; - configparser_pop(ctx); - - assert(cur && ctx->current); - - A = cur; -} - condlines(A) ::= condlines(B) eols ELSE condline(C). { - if (B->context_ndx >= C->context_ndx) { - fprintf(stderr, "unreachable else condition\n"); - ctx->ok = 0; - } + assert(B->context_ndx < C->context_ndx); C->prev = B; B->next = C; A = C; @@ -368,7 +331,7 @@ condlines(A) ::= condline(B). { condline(A) ::= context LCURLY metalines RCURLY. { data_config *cur; - + cur = ctx->current; configparser_pop(ctx); @@ -412,7 +375,7 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio buffer_append_string_buffer(b, op); rvalue = ((data_string*)D)->value; buffer_append_string_buffer(b, rvalue); - + if (NULL != (dc = (data_config *)array_get_element(ctx->all_configs, b->ptr))) { configparser_push(ctx, dc, 0); } else { @@ -425,22 +388,15 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio { COMP_HTTP_URL, CONST_STR_LEN("HTTP[\"url\"]" ) }, { COMP_HTTP_HOST, CONST_STR_LEN("HTTP[\"host\"]" ) }, { COMP_HTTP_REFERER, CONST_STR_LEN("HTTP[\"referer\"]" ) }, - { COMP_HTTP_USER_AGENT, CONST_STR_LEN("HTTP[\"useragent\"]" ) }, - { COMP_HTTP_USER_AGENT, CONST_STR_LEN("HTTP[\"user-agent\"]" ) }, - { COMP_HTTP_LANGUAGE, CONST_STR_LEN("HTTP[\"language\"]" ) }, + { COMP_HTTP_USERAGENT, CONST_STR_LEN("HTTP[\"useragent\"]" ) }, { COMP_HTTP_COOKIE, CONST_STR_LEN("HTTP[\"cookie\"]" ) }, - { COMP_HTTP_REMOTE_IP, CONST_STR_LEN("HTTP[\"remoteip\"]" ) }, - { COMP_HTTP_REMOTE_IP, CONST_STR_LEN("HTTP[\"remote-ip\"]" ) }, - { COMP_HTTP_QUERY_STRING, CONST_STR_LEN("HTTP[\"querystring\"]") }, - { COMP_HTTP_QUERY_STRING, CONST_STR_LEN("HTTP[\"query-string\"]") }, - { COMP_HTTP_REQUEST_METHOD, CONST_STR_LEN("HTTP[\"request-method\"]") }, - { COMP_HTTP_SCHEME, CONST_STR_LEN("HTTP[\"scheme\"]" ) }, + { COMP_HTTP_REMOTEIP, CONST_STR_LEN("HTTP[\"remoteip\"]" ) }, { COMP_UNSET, NULL, 0 }, }; size_t i; dc = data_config_init(); - + buffer_copy_string_buffer(dc->key, b); buffer_copy_string_buffer(dc->op, op); buffer_copy_string_buffer(dc->comp_key, B); @@ -448,7 +404,7 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio buffer_append_string_buffer(dc->comp_key, C); buffer_append_string_len(dc->comp_key, CONST_STR_LEN("\"]")); dc->cond = E; - + for (i = 0; comps[i].comp_key; i ++) { if (buffer_is_equal_string( dc->comp_key, comps[i].comp_key, comps[i].len)) { @@ -470,37 +426,29 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio case CONFIG_COND_MATCH: { #ifdef HAVE_PCRE_H const char *errptr; - int erroff, captures; - - if (NULL == (dc->regex = + int erroff; + + if (NULL == (dc->regex = pcre_compile(rvalue->ptr, 0, &errptr, &erroff, NULL))) { dc->string = buffer_init_string(errptr); dc->cond = CONFIG_COND_UNSET; - fprintf(stderr, "parsing regex failed: %s -> %s at offset %d\n", + fprintf(stderr, "parsing regex failed: %s -> %s at offset %d\n", rvalue->ptr, errptr, erroff); ctx->ok = 0; } else if (NULL == (dc->regex_study = - pcre_study(dc->regex, 0, &errptr)) && + pcre_study(dc->regex, 0, &errptr)) && errptr != NULL) { - fprintf(stderr, "studying regex failed: %s -> %s\n", + fprintf(stderr, "studying regex failed: %s -> %s\n", rvalue->ptr, errptr); ctx->ok = 0; - } else if (0 != (pcre_fullinfo(dc->regex, dc->regex_study, PCRE_INFO_CAPTURECOUNT, &captures))) { - fprintf(stderr, "getting capture count for regex failed: %s\n", - rvalue->ptr); - ctx->ok = 0; - } else if (captures > 9) { - fprintf(stderr, "Too many captures in regex, use (?:...) instead of (...): %s\n", - rvalue->ptr); - ctx->ok = 0; } else { dc->string = buffer_init_buffer(rvalue); } #else - fprintf(stderr, "can't handle '$%s[%s] =~ ...' as you compiled without pcre support. \n" - "(perhaps just a missing pcre-devel package ?) \n", + fprintf(stderr, "regex conditionals are not allowed as pcre-support" \ + "is missing: $%s[%s]\n", B->ptr, C->ptr); ctx->ok = 0; #endif @@ -508,12 +456,12 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio } default: - fprintf(stderr, "unknown condition for $%s[%s]\n", + fprintf(stderr, "unknown condition for $%s[%s]\n", B->ptr, C->ptr); ctx->ok = 0; break; } - + configparser_push(ctx, dc, 1); } |