const char* buffer;
const char *parse = expr;
int retval = 0, was_unmatched = 0;
-
+ unsigned regex = 0;
+
*was_error = 0;
if (!parse) {
case TOKEN_NOT:
new->parent = current;
current = current->right = new;
+ ++regex;
break;
default:
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;
current->value = re_check(ctx, current->left->token.value,
current->right->token.value);
+ --regex;
}
else {
DEBUG_PRINTF((ctx, " Compare (%s) with (%s)\n",