Author: yegor
Date: Mon Jan  7 14:34:19 2019
New Revision: 1850646

URL: http://svn.apache.org/viewvc?rev=1850646&view=rev
Log:
Bug 62904: Support array arguments in IF and logical IS*** functions

Added:
    
poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestIFFunctionFromSpreadsheet.java
   (with props)
    
poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestLogicalFunctionsFromSpreadsheet.java
   (with props)
    poi/trunk/test-data/spreadsheet/IfFunctionTestCaseData.xls   (with props)
    poi/trunk/test-data/spreadsheet/LogicalFunctionsTestCaseData.xls   (with 
props)
Modified:
    poi/trunk/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java
    poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
    
poi/trunk/src/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java
    
poi/trunk/src/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java
    poi/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java
    poi/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java
    poi/trunk/src/java/org/apache/poi/ss/formula/functions/ArrayFunction.java
    poi/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java
    poi/trunk/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java

Modified: 
poi/trunk/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java?rev=1850646&r1=1850645&r2=1850646&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java 
Mon Jan  7 14:34:19 2019
@@ -56,6 +56,7 @@ import org.apache.poi.ss.formula.functio
 import org.apache.poi.ss.formula.functions.ArrayFunction;
 import org.apache.poi.ss.formula.functions.Function;
 import org.apache.poi.ss.formula.functions.Indirect;
+import org.apache.poi.ss.util.CellRangeAddress;
 
 /**
  * This class creates <tt>OperationEval</tt> instances to help evaluate 
<tt>OperationPtg</tt>
@@ -138,8 +139,16 @@ final class OperationEvaluatorFactory {
                        EvaluationSheet evalSheet = 
ec.getWorkbook().getSheet(ec.getSheetIndex());
                        EvaluationCell evalCell = 
evalSheet.getCell(ec.getRowIndex(), ec.getColumnIndex());
 
-                   if (evalCell != null && 
(evalCell.isPartOfArrayFormulaGroup() || ec.isArraymode()) && result instanceof 
ArrayFunction)
-                       return ((ArrayFunction) result).evaluateArray(args, 
ec.getRowIndex(), ec.getColumnIndex());
+                   if (evalCell != null && result instanceof ArrayFunction) {
+                               ArrayFunction func = (ArrayFunction) result;
+                               if(evalCell.isPartOfArrayFormulaGroup()){
+                                       // array arguments must be evaluated 
relative to the function defining range
+                                       CellRangeAddress ca = 
evalCell.getArrayFormulaRange();
+                                       return func.evaluateArray(args, 
ca.getFirstRow(), ca.getFirstColumn());
+                               } else if (ec.isArraymode()){
+                                       return func.evaluateArray(args, 
ec.getRowIndex(), ec.getColumnIndex());
+                               }
+                       }
                                
                        return  result.evaluate(args, ec.getRowIndex(), 
ec.getColumnIndex());
                } else if (udfFunc != null){

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java?rev=1850646&r1=1850645&r2=1850646&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java Mon Jan 
 7 14:34:19 2019
@@ -453,15 +453,24 @@ public final class WorkbookEvaluator {
                         // nothing to skip - true param follows
                     } else {
                         int dist = attrPtg.getData();
+                        Ptg currPtg = ptgs[i+1];
                         i+= countTokensToBeSkipped(ptgs, i, dist);
                         Ptg nextPtg = ptgs[i+1];
-                        if (ptgs[i] instanceof AttrPtg && nextPtg instanceof 
FuncVarPtg && 
-                                // in order to verify that there is no third 
param, we need to check 
+
+                        if (ptgs[i] instanceof AttrPtg && nextPtg instanceof 
FuncVarPtg &&
+                                // in order to verify that there is no third 
param, we need to check
                                 // if we really have the IF next or some other 
FuncVarPtg as third param, e.g. ROW()/COLUMN()!
                                 ((FuncVarPtg)nextPtg).getFunctionIndex() == 
FunctionMetadataRegistry.FUNCTION_INDEX_IF) {
                             // this is an if statement without a false param 
(as opposed to MissingArgPtg as the false param)
-                            i++;
-                            stack.push(BoolEval.FALSE);
+                            //i++;
+                            stack.push(arg0);
+                            if(currPtg instanceof AreaPtg){
+                                // IF in array mode. See Bug 62904
+                                ValueEval currEval = getEvalForPtg(currPtg, 
ec);
+                                stack.push(currEval);
+                            } else {
+                                stack.push(BoolEval.FALSE);
+                            }
                         }
                     }
                     continue;
@@ -759,7 +768,7 @@ public final class WorkbookEvaluator {
             return evaluateNameFormula(nameRecord.getNameDefinition(), ec);
         }
 
-        throw new RuntimeException("Don't now how to evalate name '" + 
nameRecord.getNameText() + "'");
+        throw new RuntimeException("Don't now how to evaluate name '" + 
nameRecord.getNameText() + "'");
     }
     
     /**

Modified: 
poi/trunk/src/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java?rev=1850646&r1=1850645&r2=1850646&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java 
Mon Jan  7 14:34:19 2019
@@ -17,7 +17,6 @@
 
 package org.apache.poi.ss.formula.eval;
 
-import org.apache.poi.ss.formula.CacheAreaEval;
 import org.apache.poi.ss.formula.functions.ArrayFunction;
 import org.apache.poi.ss.formula.functions.Fixed2ArgFunction;
 import org.apache.poi.ss.formula.functions.Function;
@@ -74,84 +73,16 @@ public abstract class RelationalOperatio
                return BoolEval.valueOf(result);
        }
 
+       @Override
        public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int 
srcColumnIndex) {
                ValueEval arg0 = args[0];
                ValueEval arg1 = args[1];
+               return evaluateTwoArrayArgs(arg0, arg1, srcRowIndex, 
srcColumnIndex, (vA, vB) -> {
+                       int cmpResult = doCompare(vA, vB);
+                       boolean result = convertComparisonResult(cmpResult);
+                       return BoolEval.valueOf(result);
+               });
 
-               int w1, w2, h1, h2;
-               int a1FirstCol = 0, a1FirstRow = 0;
-               if (arg0 instanceof AreaEval) {
-                       AreaEval ae = (AreaEval)arg0;
-                       w1 = ae.getWidth();
-                       h1 = ae.getHeight();
-                       a1FirstCol = ae.getFirstColumn();
-                       a1FirstRow = ae.getFirstRow();
-               } else if (arg0 instanceof RefEval){
-                       RefEval ref = (RefEval)arg0;
-                       w1 = 1;
-                       h1 = 1;
-                       a1FirstCol = ref.getColumn();
-                       a1FirstRow = ref.getRow();
-               } else {
-                       w1 = 1;
-                       h1 = 1;
-               }
-               int a2FirstCol = 0, a2FirstRow = 0;
-               if (arg1 instanceof AreaEval) {
-                       AreaEval ae = (AreaEval)arg1;
-                       w2 = ae.getWidth();
-                       h2 = ae.getHeight();
-                       a2FirstCol = ae.getFirstColumn();
-                       a2FirstRow = ae.getFirstRow();
-               } else if (arg1 instanceof RefEval){
-                       RefEval ref = (RefEval)arg1;
-                       w2 = 1;
-                       h2 = 1;
-                       a2FirstCol = ref.getColumn();
-                       a2FirstRow = ref.getRow();
-               } else {
-                       w2 = 1;
-                       h2 = 1;
-               }
-
-               int width = Math.max(w1, w2);
-               int height = Math.max(h1, h2);
-
-               ValueEval[] vals = new ValueEval[height * width];
-
-               int idx = 0;
-               for(int i = 0; i < height; i++){
-                       for(int j = 0; j < width; j++){
-                               ValueEval vA;
-                               try {
-                                       vA = 
OperandResolver.getSingleValue(arg0, a1FirstRow + i, a1FirstCol + j);
-                               } catch (EvaluationException e) {
-                                       vA = e.getErrorEval();
-                               }
-                               ValueEval vB;
-                               try {
-                                       vB = 
OperandResolver.getSingleValue(arg1, a2FirstRow + i, a2FirstCol + j);
-                               } catch (EvaluationException e) {
-                                       vB = e.getErrorEval();
-                               }
-                               if(vA instanceof ErrorEval){
-                                       vals[idx++] = vA;
-                               } else if (vB instanceof ErrorEval) {
-                                       vals[idx++] = vB;
-                               } else {
-                                       int cmpResult = doCompare(vA, vB);
-                                       boolean result = 
convertComparisonResult(cmpResult);
-                                       vals[idx++] = BoolEval.valueOf(result);
-                               }
-
-                       }
-               }
-
-               if (vals.length == 1) {
-                       return vals[0];
-               }
-
-               return new CacheAreaEval(srcRowIndex, srcColumnIndex, 
srcRowIndex + height - 1, srcColumnIndex + width - 1, vals);
        }
 
        private static int doCompare(ValueEval va, ValueEval vb) {

Modified: 
poi/trunk/src/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java?rev=1850646&r1=1850645&r2=1850646&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java
 (original)
+++ 
poi/trunk/src/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java
 Mon Jan  7 14:34:19 2019
@@ -37,7 +37,20 @@ public abstract class TwoOperandNumericO
            if (args.length != 2) {
                return ErrorEval.VALUE_INVALID;
            }
-           return new ArrayEval().evaluate(srcRowIndex, srcColumnIndex, 
args[0], args[1]);
+           //return new ArrayEval().evaluate(srcRowIndex, srcColumnIndex, 
args[0], args[1]);
+
+               return evaluateTwoArrayArgs(args[0], args[1], srcRowIndex, 
srcColumnIndex,
+                               (vA, vB) -> {
+                                       try {
+                                               double d0 = 
OperandResolver.coerceValueToDouble(vA);
+                                               double d1 = 
OperandResolver.coerceValueToDouble(vB);
+                                               double result = evaluate(d0, 
d1);
+                                               return new NumberEval(result);
+                                       } catch (EvaluationException e){
+                                               return e.getErrorEval();
+                                       }
+                               });
+
        }
        
        public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, 
ValueEval arg0, ValueEval arg1) {

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java?rev=1850646&r1=1850645&r2=1850646&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java Mon 
Jan  7 14:34:19 2019
@@ -17,13 +17,14 @@
 
 package org.apache.poi.ss.formula.eval;
 
+import org.apache.poi.ss.formula.functions.ArrayFunction;
 import org.apache.poi.ss.formula.functions.Fixed1ArgFunction;
 import org.apache.poi.ss.formula.functions.Function;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  */
-public final class UnaryMinusEval extends Fixed1ArgFunction {
+public final class UnaryMinusEval extends Fixed1ArgFunction  implements 
ArrayFunction {
 
        public static final Function instance = new UnaryMinusEval();
 
@@ -44,4 +45,12 @@ public final class UnaryMinusEval extend
                }
                return new NumberEval(-d);
        }
+
+       @Override
+       public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int 
srcColumnIndex){
+               return evaluateOneArrayArg(args, srcRowIndex, srcColumnIndex, 
(valA) ->
+                               evaluate(srcRowIndex, srcColumnIndex, valA)
+               );
+       }
+
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java?rev=1850646&r1=1850645&r2=1850646&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java Mon 
Jan  7 14:34:19 2019
@@ -17,6 +17,7 @@
 
 package org.apache.poi.ss.formula.eval;
 
+import org.apache.poi.ss.formula.functions.ArrayFunction;
 import org.apache.poi.ss.formula.functions.Fixed1ArgFunction;
 import org.apache.poi.ss.formula.functions.Function;
 
@@ -24,7 +25,7 @@ import org.apache.poi.ss.formula.functio
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  */
-public final class UnaryPlusEval extends Fixed1ArgFunction {
+public final class UnaryPlusEval extends Fixed1ArgFunction  implements 
ArrayFunction {
 
        public static final Function instance = new UnaryPlusEval();
 
@@ -48,4 +49,12 @@ public final class UnaryPlusEval extends
                }
                return new NumberEval(+d);
        }
+
+       @Override
+       public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int 
srcColumnIndex){
+               return evaluateOneArrayArg(args, srcRowIndex, srcColumnIndex, 
(valA) ->
+                               evaluate(srcRowIndex, srcColumnIndex, valA)
+               );
+       }
+
 }

Modified: 
poi/trunk/src/java/org/apache/poi/ss/formula/functions/ArrayFunction.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/functions/ArrayFunction.java?rev=1850646&r1=1850645&r2=1850646&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/functions/ArrayFunction.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/functions/ArrayFunction.java 
Mon Jan  7 14:34:19 2019
@@ -17,10 +17,11 @@
 
 package org.apache.poi.ss.formula.functions;
 
-import org.apache.poi.ss.formula.eval.BlankEval;
-import org.apache.poi.ss.formula.eval.ErrorEval;
-import org.apache.poi.ss.formula.eval.MissingArgEval;
-import org.apache.poi.ss.formula.eval.ValueEval;
+import org.apache.poi.ss.formula.CacheAreaEval;
+import org.apache.poi.ss.formula.FormulaParseException;
+import org.apache.poi.ss.formula.eval.*;
+
+import java.util.function.BiFunction;
 
 /**
  * @author Robert Hulbert
@@ -41,4 +42,153 @@ public interface ArrayFunction {
      */
 
     ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int 
srcColumnIndex);
+
+    /**
+     * Evaluate an array function with two arguments.
+     *
+     * @param arg0 the first function argument. Empty values are represented 
with
+     *        {@link BlankEval} or {@link MissingArgEval}, never 
<code>null</code>
+     * @param arg1 the first function argument. Empty values are represented 
with
+     *      @link BlankEval} or {@link MissingArgEval}, never <code>null</code>
+     *
+     * @param srcRowIndex row index of the cell containing the formula under 
evaluation
+     * @param srcColumnIndex column index of the cell containing the formula 
under evaluation
+     * @return The evaluated result, possibly an {@link ErrorEval}, never 
<code>null</code>.
+     * <b>Note</b> - Excel uses the error code <i>#NUM!</i> instead of IEEE 
<i>NaN</i>, so when
+     * numeric functions evaluate to {@link Double#NaN} be sure to translate 
the result to {@link
+     * ErrorEval#NUM_ERROR}.
+     */
+    default ValueEval evaluateTwoArrayArgs(ValueEval arg0, ValueEval arg1, int 
srcRowIndex, int srcColumnIndex,
+                                           BiFunction<ValueEval, ValueEval, 
ValueEval> evalFunc) {
+        int w1, w2, h1, h2;
+        int a1FirstCol = 0, a1FirstRow = 0;
+        if (arg0 instanceof AreaEval) {
+            AreaEval ae = (AreaEval)arg0;
+            w1 = ae.getWidth();
+            h1 = ae.getHeight();
+            a1FirstCol = ae.getFirstColumn();
+            a1FirstRow = ae.getFirstRow();
+        } else if (arg0 instanceof RefEval){
+            RefEval ref = (RefEval)arg0;
+            w1 = 1;
+            h1 = 1;
+            a1FirstCol = ref.getColumn();
+            a1FirstRow = ref.getRow();
+        } else {
+            w1 = 1;
+            h1 = 1;
+        }
+        int a2FirstCol = 0, a2FirstRow = 0;
+        if (arg1 instanceof AreaEval) {
+            AreaEval ae = (AreaEval)arg1;
+            w2 = ae.getWidth();
+            h2 = ae.getHeight();
+            a2FirstCol = ae.getFirstColumn();
+            a2FirstRow = ae.getFirstRow();
+        } else if (arg1 instanceof RefEval){
+            RefEval ref = (RefEval)arg1;
+            w2 = 1;
+            h2 = 1;
+            a2FirstCol = ref.getColumn();
+            a2FirstRow = ref.getRow();
+        } else {
+            w2 = 1;
+            h2 = 1;
+        }
+
+        int width = Math.max(w1, w2);
+        int height = Math.max(h1, h2);
+
+        ValueEval[] vals = new ValueEval[height * width];
+
+        int idx = 0;
+        for(int i = 0; i < height; i++){
+            for(int j = 0; j < width; j++){
+                ValueEval vA;
+                try {
+                    vA = OperandResolver.getSingleValue(arg0, a1FirstRow + i, 
a1FirstCol + j);
+                } catch (FormulaParseException e) {
+                    vA = ErrorEval.NAME_INVALID;
+                } catch (EvaluationException e) {
+                    vA = e.getErrorEval();
+                }
+                ValueEval vB;
+                try {
+                    vB = OperandResolver.getSingleValue(arg1, a2FirstRow + i, 
a2FirstCol + j);
+                } catch (FormulaParseException e) {
+                    vB = ErrorEval.NAME_INVALID;
+                } catch (EvaluationException e) {
+                    vB = e.getErrorEval();
+                }
+                if(vA instanceof ErrorEval){
+                    vals[idx++] = vA;
+                } else if (vB instanceof ErrorEval) {
+                    vals[idx++] = vB;
+                } else {
+                    vals[idx++] = evalFunc.apply(vA, vB);
+                }
+
+            }
+        }
+
+        if (vals.length == 1) {
+            return vals[0];
+        }
+
+        return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + 
height - 1, srcColumnIndex + width - 1, vals);
+    }
+
+    default ValueEval evaluateOneArrayArg(ValueEval[] args, int srcRowIndex, 
int srcColumnIndex,
+                                          
java.util.function.Function<ValueEval, ValueEval> evalFunc){
+        ValueEval arg0 = args[0];
+
+        int w1, w2, h1, h2;
+        int a1FirstCol = 0, a1FirstRow = 0;
+        if (arg0 instanceof AreaEval) {
+            AreaEval ae = (AreaEval)arg0;
+            w1 = ae.getWidth();
+            h1 = ae.getHeight();
+            a1FirstCol = ae.getFirstColumn();
+            a1FirstRow = ae.getFirstRow();
+        } else if (arg0 instanceof RefEval){
+            RefEval ref = (RefEval)arg0;
+            w1 = 1;
+            h1 = 1;
+            a1FirstCol = ref.getColumn();
+            a1FirstRow = ref.getRow();
+        } else {
+            w1 = 1;
+            h1 = 1;
+        }
+        w2 = 1;
+        h2 = 1;
+
+        int width = Math.max(w1, w2);
+        int height = Math.max(h1, h2);
+
+        ValueEval[] vals = new ValueEval[height * width];
+
+        int idx = 0;
+        for(int i = 0; i < height; i++){
+            for(int j = 0; j < width; j++){
+                ValueEval vA;
+                try {
+                    vA = OperandResolver.getSingleValue(arg0, a1FirstRow + i, 
a1FirstCol + j);
+                } catch (FormulaParseException e) {
+                    vA = ErrorEval.NAME_INVALID;
+                } catch (EvaluationException e) {
+                    vA = e.getErrorEval();
+                }
+                vals[idx++] = evalFunc.apply(vA);
+            }
+        }
+
+        if (vals.length == 1) {
+            return vals[0];
+        }
+
+        return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + 
height - 1, srcColumnIndex + width - 1, vals);
+
+    }
+
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java?rev=1850646&r1=1850645&r2=1850646&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/functions/IfFunc.java Mon Jan  
7 14:34:19 2019
@@ -17,12 +17,7 @@
 
 package org.apache.poi.ss.formula.functions;
 
-import org.apache.poi.ss.formula.eval.BlankEval;
-import org.apache.poi.ss.formula.eval.BoolEval;
-import org.apache.poi.ss.formula.eval.EvaluationException;
-import org.apache.poi.ss.formula.eval.MissingArgEval;
-import org.apache.poi.ss.formula.eval.OperandResolver;
-import org.apache.poi.ss.formula.eval.ValueEval;
+import org.apache.poi.ss.formula.eval.*;
 import org.apache.poi.ss.formula.ptg.Ptg;
 import org.apache.poi.ss.formula.ptg.RefPtg;
 
@@ -36,8 +31,9 @@ import org.apache.poi.ss.formula.ptg.Ref
  * See bug numbers #55324 and #55747 for the full details on this.
  * TODO Fix this...
  */
-public final class IfFunc extends Var2or3ArgFunction {
+public final class IfFunc extends Var2or3ArgFunction implements ArrayFunction {
 
+    @Override
        public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, 
ValueEval arg0, ValueEval arg1) {
                boolean b;
                try {
@@ -54,6 +50,7 @@ public final class IfFunc extends Var2or
                return BoolEval.FALSE;
        }
 
+    @Override
        public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, 
ValueEval arg0, ValueEval arg1,
                        ValueEval arg2) {
                boolean b;
@@ -83,4 +80,29 @@ public final class IfFunc extends Var2or
                }
                return b.booleanValue();
        }
+
+
+       @Override
+       public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int 
srcColumnIndex) {
+               ValueEval arg0 = args[0];
+               ValueEval arg1 = args[1];
+               return evaluateTwoArrayArgs(arg0, arg1, srcRowIndex, 
srcColumnIndex,
+                (vA, vB) -> {
+                                       Boolean b;
+                                       try {
+                                               b = 
OperandResolver.coerceValueToBoolean(vA, false);
+                                       } catch (EvaluationException e) {
+                                               return e.getErrorEval();
+                                       }
+                                       if (b != null && b) {
+                                               if (vB == 
MissingArgEval.instance) {
+                                                       return 
BlankEval.instance;
+                                               }
+                                               return vB;
+                                       }
+                                       return BoolEval.FALSE;
+                               }
+        );
+       }
+
 }

Modified: 
poi/trunk/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java?rev=1850646&r1=1850645&r2=1850646&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/functions/LogicalFunction.java 
Mon Jan  7 14:34:19 2019
@@ -23,7 +23,7 @@ import org.apache.poi.ss.formula.eval.*;
  * Implementation of the various ISxxx Logical Functions, which
  *  take a single expression argument, and return True or False.
  */
-public abstract class LogicalFunction extends Fixed1ArgFunction {
+public abstract class LogicalFunction extends Fixed1ArgFunction implements 
ArrayFunction{
 
     @SuppressWarnings("unused")
     public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval 
arg0) {
@@ -41,6 +41,14 @@ public abstract class LogicalFunction ex
                return BoolEval.valueOf(evaluate(ve));
 
        }
+
+       @Override
+       public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int 
srcColumnIndex){
+               return evaluateOneArrayArg(args, srcRowIndex, srcColumnIndex, 
(valA) ->
+                               BoolEval.valueOf(evaluate(valA))
+               );
+       }
+
        /**
         * @param arg any {@link ValueEval}, potentially {@link BlankEval} or 
{@link ErrorEval}.
         */

Added: 
poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestIFFunctionFromSpreadsheet.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestIFFunctionFromSpreadsheet.java?rev=1850646&view=auto
==============================================================================
--- 
poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestIFFunctionFromSpreadsheet.java
 (added)
+++ 
poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestIFFunctionFromSpreadsheet.java
 Mon Jan  7 14:34:19 2019
@@ -0,0 +1,32 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.functions;
+
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Collection;
+
+/**
+ * Tests IF() as loaded from a test data spreadsheet.<p>
+ */
+public class TestIFFunctionFromSpreadsheet extends 
BaseTestFunctionsFromSpreadsheet {
+    @Parameters(name="{0}")
+    public static Collection<Object[]> data() throws Exception {
+        return data(TestIFFunctionFromSpreadsheet.class, 
"IfFunctionTestCaseData.xls");
+    }
+}

Propchange: 
poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestIFFunctionFromSpreadsheet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestLogicalFunctionsFromSpreadsheet.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestLogicalFunctionsFromSpreadsheet.java?rev=1850646&view=auto
==============================================================================
--- 
poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestLogicalFunctionsFromSpreadsheet.java
 (added)
+++ 
poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestLogicalFunctionsFromSpreadsheet.java
 Mon Jan  7 14:34:19 2019
@@ -0,0 +1,32 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.functions;
+
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Collection;
+
+/**
+ * Tests for logical ISxxx functions as loaded from a test data spreadsheet.<p>
+ */
+public class TestLogicalFunctionsFromSpreadsheet extends 
BaseTestFunctionsFromSpreadsheet {
+    @Parameters(name="{0}")
+    public static Collection<Object[]> data() throws Exception {
+        return data(TestLogicalFunctionsFromSpreadsheet.class, 
"LogicalFunctionsTestCaseData.xls");
+    }
+}

Propchange: 
poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestLogicalFunctionsFromSpreadsheet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: poi/trunk/test-data/spreadsheet/IfFunctionTestCaseData.xls
URL: 
http://svn.apache.org/viewvc/poi/trunk/test-data/spreadsheet/IfFunctionTestCaseData.xls?rev=1850646&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/test-data/spreadsheet/IfFunctionTestCaseData.xls
------------------------------------------------------------------------------
    svn:mime-type = application/vnd.ms-excel

Added: poi/trunk/test-data/spreadsheet/LogicalFunctionsTestCaseData.xls
URL: 
http://svn.apache.org/viewvc/poi/trunk/test-data/spreadsheet/LogicalFunctionsTestCaseData.xls?rev=1850646&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/test-data/spreadsheet/LogicalFunctionsTestCaseData.xls
------------------------------------------------------------------------------
    svn:mime-type = application/vnd.ms-excel



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to