From: André Malo Date: Mon, 25 Aug 2003 16:05:13 +0000 (+0000) Subject: short circuit && and || evaluation. For backwards compat this is only X-Git-Tag: pre_ajp_proxy~1215 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=41fd1c504c0268f1c665f4ac40a88b6363508418;p=apache 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 --- 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",