From 41fd1c504c0268f1c665f4ac40a88b6363508418 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20Malo?= Date: Mon, 25 Aug 2003 16:05:13 +0000 Subject: [PATCH] short circuit && and || evaluation. For backwards compat this is only possible if there's no regex on the short circuited side (since it fills in the backref data). The user may optimize this by putting the regex onto the left side of the operator. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@101097 13f79535-47bb-0310-9956-ffa450edef68 --- modules/filters/mod_include.c | 64 ++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/modules/filters/mod_include.c b/modules/filters/mod_include.c index e4290ed1dd..a31941f182 100644 --- a/modules/filters/mod_include.c +++ b/modules/filters/mod_include.c @@ -1123,7 +1123,8 @@ static int parse_expr(include_ctx_t *ctx, const char *expr, int *was_error) const char* buffer; const char *parse = expr; int retval = 0, was_unmatched = 0; - + unsigned regex = 0; + *was_error = 0; if (!parse) { @@ -1196,6 +1197,7 @@ static int parse_expr(include_ctx_t *ctx, const char *expr, int *was_error) case TOKEN_NOT: new->parent = current; current = current->right = new; + ++regex; break; default: @@ -1438,39 +1440,54 @@ static int parse_expr(include_ctx_t *ctx, const char *expr, int *was_error) continue; } } - if (!current->right->done) { - switch (current->right->token.type) { - case TOKEN_STRING: - buffer = ap_ssi_parse_string(ctx, - current->right->token.value, - NULL, 0, SSI_EXPAND_DROP_NAME); - current->right->token.value = buffer; - current->right->value = !!*current->right->token.value; - current->right->done = 1; - break; + /* short circuit evaluation */ + if (!current->right->done && !regex && + ((current->token.type == TOKEN_AND && !current->left->value) || + (current->token.type == TOKEN_OR && current->left->value))) { + DEBUG_PRINTF((ctx, " Left: %c\n", current->left->value + ? '1' : '0')); + DEBUG_PRINTF((ctx, " Right: short circuited\n")); - default: - current = current->right; - continue; - } + current->value = current->left->value; } + else { + if (!current->right->done) { + switch (current->right->token.type) { + case TOKEN_STRING: + buffer = ap_ssi_parse_string(ctx, + current->right->token.value, + NULL, 0, + SSI_EXPAND_DROP_NAME); + + current->right->token.value = buffer; + current->right->value = !!*current->right->token.value; + current->right->done = 1; + break; + + default: + current = current->right; + continue; + } + } - DEBUG_PRINTF((ctx, " Left: %c\n", current->left->value + DEBUG_PRINTF((ctx, " Left: %c\n", current->left->value ? '1' : '0')); - DEBUG_PRINTF((ctx, " Right: %c\n", current->right->value + DEBUG_PRINTF((ctx, " Right: %c\n", current->right->value ? '1' : '0')); - if (current->token.type == TOKEN_AND) { - current->value = current->left->value && current->right->value; - } - else { - current->value = current->left->value || current->right->value; + if (current->token.type == TOKEN_AND) { + current->value = current->left->value && + current->right->value; + } + else { + current->value = current->left->value || + current->right->value; + } } DEBUG_PRINTF((ctx, " Returning %c\n", current->value ? '1' : '0')); - current->done = 1; current = current->parent; break; @@ -1505,6 +1522,7 @@ static int parse_expr(include_ctx_t *ctx, const char *expr, int *was_error) current->value = re_check(ctx, current->left->token.value, current->right->token.value); + --regex; } else { DEBUG_PRINTF((ctx, " Compare (%s) with (%s)\n", -- 2.50.1