From cbdde7a3370f61be6e82a53770fbb4c4d44ceee4 Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer <reinhold@kainhofer.com> Date: Sun, 17 Nov 2013 13:32:58 +0100 Subject: [PATCH] Make function names and operators case-insensitive Internally, operators are converted to UPPER case, while function names are converted to lower case. --- rules_shipping_advanced.php | 31 ++++++++++++++++--------------- rules_shipping_base.php | 6 +++--- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/rules_shipping_advanced.php b/rules_shipping_advanced.php index 5a1610a..13d69a8 100644 --- a/rules_shipping_advanced.php +++ b/rules_shipping_advanced.php @@ -113,7 +113,7 @@ class ShippingRule_Advanced extends ShippingRule { // (OR, AND, in; but make sure we don't capture parts of words, so we need to // use lookbehind/lookahead patterns to exclude OR following another letter // or followed by another letter) and then all arithmetic operators - $re = '/\s*("[^"]*"|\'[^\']*\'|(?<![A-Za-z0-9])(?:OR|AND|IN|or|and|in)(?![A-Za-z0-9])|&&|<=|=>|>=|=>|<>|!=|==|<|=|>|~|\+|-|\*|\/|%|\(|\)|\^|,)\s*/'; + $re = '/\s*("[^"]*"|\'[^\']*\'|(?<![A-Za-z0-9])(?:OR|AND|IN)(?![A-Za-z0-9])|&&|<=|=>|>=|=>|<>|!=|==|<|=|>|~|\+|-|\*|\/|%|\(|\)|\^|,)\s*/i'; $atoms = preg_split($re, $expression, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); // JFactory::getApplication()->enqueueMessage("TOKENIZING '$expression' returns: <pre>".print_r($atoms,1)."</pre>", 'error'); return $atoms; @@ -162,21 +162,21 @@ class ShippingRule_Advanced extends ShippingRule { $operators = array( ".-" => 100, ".+" => 100, - "in" => 80, + "IN" => 80, "^" => 70, "*" => 60, "/" => 60, "%" => 60, "+" => 50, "-" => 50, "<" => 40, "<=" => 40, ">" => 40, ">=" => 40, "=>" => 40, "=<" => 40, "==" => 40, "!=" => 40, "<>" => 40, "~" => 40, - "&&" => 21, "AND" => 21, - "OR" => 20, + "&&" => 21, "AND" => 21, + "OR" => 20, "=" => 10, "(" => 0, ")" =>0 ); $unary_ops = array("-" => ".-", "+" => ".+"); // Any of these indicate a comparison and thus a condition: - $condition_ops = array('<', '<=', '=<', '<>', '!=', '==', '>', '>=', '=>', '~', 'OR', 'AND', 'AND', '&&', 'in'); + $condition_ops = array('<', '<=', '=<', '<>', '!=', '==', '>', '>=', '=>', '~', 'OR', 'AND', '&&', 'IN'); $comparison_ops = array('<', '<=', '=<', '<>', '!=', '==', '>', '>=', '=>', '~'); $is_condition = false; $is_assignment = false; @@ -186,6 +186,7 @@ class ShippingRule_Advanced extends ShippingRule { $function_args = array(); $out_stack = array(); foreach ($atoms as $a) { // 2) + $aupper = strtoupper($a); # All operators are converted to uppercase! if ($a == ",") { // A function argument separator // pop-and-apply all operators back to the left function paren @@ -209,7 +210,7 @@ class ShippingRule_Advanced extends ShippingRule { } elseif ($a == "(" and !$prev_token_operator) { // 5) parenthesis after operand -> FUNCTION CALL array_push ($stack, "FUNCTION("); // retrieve function name from RPN list (remove last entry from operand stack!) - $function = array_pop ($out_stack); + $function = strtolower(array_pop ($out_stack)); $new_stack = array(); // Set up function call data structure on function_args stack: $function_args[] = array(/* old operand stack: */$out_stack, $function); @@ -253,10 +254,10 @@ class ShippingRule_Advanced extends ShippingRule { } while (true); $prev_token_operator = false; - } elseif (isset($unary_ops[$a]) && $prev_token_operator) { // 4) UNARY operators + } elseif (isset($unary_ops[$aupper]) && $prev_token_operator) { // 4) UNARY operators // Unary and binary operators need to be handled differently: // Unary operators must only pop other unary operators, never any binary operator - $unary_op = $unary_ops[$a]; + $unary_op = $unary_ops[$aupper]; // For unary operators, pop other unary operators from the stack until you reach an opening parenthesis, // an operator of lower precedence, or a right associative symbol of equal precedence. while (count($stack)>0) { // 4a) @@ -273,10 +274,10 @@ class ShippingRule_Advanced extends ShippingRule { array_push ($stack, $unary_op); // 4b) $prev_token_operator = true; - } elseif (isset($operators[$a])) { // 4) BINARY operators - $prec = $operators[$a]; - $is_condition |= in_array($a, $condition_ops); - $is_assignment |= ($a == "="); + } elseif (isset($operators[$aupper])) { // 4) BINARY operators + $prec = $operators[$aupper]; + $is_condition |= in_array($aupper, $condition_ops); + $is_assignment |= ($aupper == "="); // For operators, pop operators from the stack until you reach an opening parenthesis, // an operator of lower precedence, or a right associative symbol of equal precedence. @@ -295,7 +296,7 @@ class ShippingRule_Advanced extends ShippingRule { array_push ($out_stack, $op); } } while (0); - array_push ($stack, $a); // 4b) + array_push ($stack, $aupper); // 4b) $prev_token_operator = true; } else { // 3) Everything else is an Operand @@ -368,12 +369,12 @@ class ShippingRule_Advanced extends ShippingRule { // if e is a comparison, and operator(o1) is also a comparison, // insert the arguments to the existing comparison instead of creating a new one if (in_array ($e, $comparison_ops)) { - if ($o1[0]=='comparison') { + if ($o1[0]=='COMPARISON') { $op = $o1; // Append the new comparison to the existing one array_push($op, $e, $o2); } else { - $op = array ('comparison', $o1, $e, $o2); + $op = array ('COMPARISON', $o1, $e, $o2); } } else { $op = array ($e, $o1, $o2); // 4b) diff --git a/rules_shipping_base.php b/rules_shipping_base.php index 776b8b3..422b795 100644 --- a/rules_shipping_base.php +++ b/rules_shipping_base.php @@ -872,7 +872,7 @@ class ShippingRule { } foreach ($expr as $e) { $term = $evaluate ? ($this->evaluateTerm($e, $vals)) : $e; - if ($op == 'comparison') { + if ($op == 'COMPARISON') { // For comparisons, we only evaluate every other term (the operators are NOT evaluated!) $evaluate = !$evaluate; } @@ -888,7 +888,7 @@ class ShippingRule { case 'OR': foreach ($args as $a) { $res = ($res || $a); }; break; case '&&': case 'AND': $res = true; foreach ($args as $a) { $res = ($res && $a); }; break; - case 'in': $res = in_array($args[0], $args[1]); break; + case 'IN': $res = in_array($args[0], $args[1]); break; // Comparisons: case '<': @@ -902,7 +902,7 @@ class ShippingRule { case '>': case '~': $res = $this->evaluateComparison(array($args[0], $op, $args[1]), $vals); break; - case 'comparison': + case 'COMPARISON': $res = $this->evaluateComparison($args, $vals); break; // Unary operators: -- GitLab