You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2008/03/04 17:53:38 UTC

svn commit: r633547 [3/4] - in /poi/trunk/src: java/org/apache/poi/hssf/model/ java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/record/constant/ java/org/apache/poi/hssf/record/formula/ java/org/apache/poi/hssf/usermodel/ java/org/apache/poi/u...

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java Tue Mar  4 08:53:32 2008
@@ -14,10 +14,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 8, 2005
- *
- */
+
 package org.apache.poi.hssf.record.formula.eval;
 
 import org.apache.poi.hssf.record.formula.Ptg;
@@ -27,14 +24,12 @@
  * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
  *  
  */
-public class UnaryMinusEval extends NumericOperationEval {
+public final class UnaryMinusEval extends NumericOperationEval {
 
     private UnaryMinusPtg delegate;
     private static final ValueEvalToNumericXlator NUM_XLATOR = 
         new ValueEvalToNumericXlator((short)
                 ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
                 | ValueEvalToNumericXlator.STRING_IS_PARSED
                 | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
@@ -49,32 +44,24 @@
         return NUM_XLATOR;
     }
 
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        ValueEval retval = null;
+    public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
+    	if(args.length != 1) {
+    		return ErrorEval.VALUE_INVALID;
+    	}
         double d = 0;
         
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.UNKNOWN_ERROR;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                d = ((NumericValueEval) ve).getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else if (ve instanceof ErrorEval) {
-                retval = ve;
-            }
+        ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol);
+        if (ve instanceof NumericValueEval) {
+            d = ((NumericValueEval) ve).getNumberValue();
         }
-        
-        if (retval == null) {
-            retval = new NumberEval(-d);
+        else if (ve instanceof BlankEval) {
+            // do nothing
         }
-
-        return retval;
+        else if (ve instanceof ErrorEval) {
+            return ve;
+        }
+        
+        return new NumberEval(-d);
     }
 
     public int getNumberOfOperands() {

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java Tue Mar  4 08:53:32 2008
@@ -14,10 +14,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 8, 2005
- *
- */
+
 package org.apache.poi.hssf.record.formula.eval;
 
 import org.apache.poi.hssf.record.formula.Ptg;
@@ -27,114 +24,38 @@
  * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
  *  
  */
-public class UnaryPlusEval implements OperationEval /*extends NumericOperationEval*/ {
+public final class UnaryPlusEval implements OperationEval {
 
     private UnaryPlusPtg delegate;
     
-    /* 
-     * COMMENT FOR COMMENTED CODE IN THIS FILE
-     * 
-     * In excel the programmer seems to not have cared to
-     * think about how strings were handled in other numeric
-     * operations when he/she was implementing this operation :P
-     * 
-     * Here's what I mean:
-     * 
-     * Q. If the formula -"hello" evaluates to #VALUE! in excel, what should
-     * the formula +"hello" evaluate to?
-     * 
-     * A. +"hello" evaluates to "hello" (what the...?)
-     * 
-     */
-
-    
-//    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-//        new ValueEvalToNumericXlator((short)
-//                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-//                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-//                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-//                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-//                | ValueEvalToNumericXlator.STRING_IS_PARSED
-//                ));
-
-
     /**
      * called by reflection
      */
     public UnaryPlusEval(Ptg ptg) {
         this.delegate = (UnaryPlusPtg) ptg;
     }
-    
-//    protected ValueEvalToNumericXlator getXlator() {
-//        return NUM_XLATOR;
-//    }
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        ValueEval retval = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.UNKNOWN_ERROR;
-            break;
-        case 1:
-
-//            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-//            if (ve instanceof NumericValueEval) {
-//                d = ((NumericValueEval) ve).getNumberValue();
-//            }
-//            else if (ve instanceof BlankEval) {
-//                // do nothing
-//            }
-//            else if (ve instanceof ErrorEval) {
-//                retval = ve;
-//            }
-            if (operands[0] instanceof RefEval) {
-                RefEval re = (RefEval) operands[0];
-                retval = re.getInnerValueEval();
-            }
-            else if (operands[0] instanceof AreaEval) {
-                AreaEval ae = (AreaEval) operands[0];
-                if (ae.contains(srcRow, srcCol)) { // circular ref!
-                    retval = ErrorEval.CIRCULAR_REF_ERROR;
-                }
-                else if (ae.isRow()) {
-                    if (ae.containsColumn(srcCol)) {
-                        ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
-                        if (ve instanceof RefEval) {
-                            ve = ((RefEval) ve).getInnerValueEval();
-                        }
-                        retval = ve;
-                    }
-                    else {
-                        retval = ErrorEval.VALUE_INVALID;
-                    }
-                }
-                else if (ae.isColumn()) {
-                    if (ae.containsRow(srcRow)) {
-                        ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
-                        if (ve instanceof RefEval) {
-                            ve = ((RefEval) ve).getInnerValueEval();
-                        }
-                        retval = ve;
-                    }
-                    else {
-                        retval = ErrorEval.VALUE_INVALID;
-                    }
-                }
-                else {
-                    retval = ErrorEval.VALUE_INVALID;
-                }
-            }
-            else {
-                retval = (ValueEval) operands[0];
-            }
-        }
-        
-        if (retval instanceof BlankEval) {
-            retval = new NumberEval(0);
-        }
 
-        return retval;
+    public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+    	if(args.length != 1) {
+    		return ErrorEval.VALUE_INVALID;
+    	}
+    	double d;
+		try {
+			ValueEval ve = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
+			if(ve instanceof BlankEval) {
+				return NumberEval.ZERO;
+			}
+			if(ve instanceof StringEval) {
+				// Note - asymmetric with UnaryMinus
+				// -"hello" evaluates to #VALUE!
+				// but +"hello" evaluates to "hello"
+				return ve;
+			}
+			d = OperandResolver.coerceValueToDouble(ve);
+		} catch (EvaluationException e) {
+			return e.getErrorEval();
+		}
+    	return new NumberEval(+d);    	
     }
 
     public int getNumberOfOperands() {
@@ -144,5 +65,4 @@
     public int getType() {
         return delegate.getType();
     }
-
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java Tue Mar  4 08:53:32 2008
@@ -24,7 +24,7 @@
  * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
  *
  */
-public class ValueEvalToNumericXlator {
+public final class ValueEvalToNumericXlator {
 
     public static final int STRING_IS_PARSED = 0x0001;
     public static final int BOOL_IS_PARSED = 0x0002;
@@ -34,26 +34,18 @@
     public static final int REF_BOOL_IS_PARSED = 0x0010;
     public static final int REF_BLANK_IS_PARSED = 0x0020;
     
-    public static final int EVALUATED_REF_STRING_IS_PARSED = 0x0040;
-    public static final int EVALUATED_REF_BOOL_IS_PARSED = 0x0080;
-    public static final int EVALUATED_REF_BLANK_IS_PARSED = 0x0100;
-    
-    public static final int STRING_TO_BOOL_IS_PARSED = 0x0200;
-    public static final int REF_STRING_TO_BOOL_IS_PARSED = 0x0400;
-    
     public static final int STRING_IS_INVALID_VALUE = 0x0800;
-    public static final int REF_STRING_IS_INVALID_VALUE = 0x1000;
-    
-//    public static final int BOOL_IS_BLANK = 0x2000;
-//    public static final int REF_BOOL_IS_BLANK = 0x4000;
-//    public static final int STRING_IS_BLANK = 0x8000;
-//    public static final int REF_STRING_IS_BLANK = 0x10000;
     
     private final int flags;
     
     
     public ValueEvalToNumericXlator(int flags) {
-        this.flags = flags;
+    	
+    	if (false) { // uncomment to see who is using this class
+			System.err.println(new Throwable().getStackTrace()[1].getClassName() + "\t0x"
+					+ Integer.toHexString(flags).toUpperCase());
+		}
+		this.flags = flags;
     }
     
     /**
@@ -71,7 +63,7 @@
         
         // most common case - least worries :)
         else if (eval instanceof NumberEval) {
-            retval = (NumberEval) eval; 
+            retval = eval; 
         }
         
         // booleval
@@ -125,50 +117,33 @@
      * @param eval
      */
     private ValueEval xlateRefEval(RefEval reval) {
-        ValueEval retval = null;
-        ValueEval eval = (ValueEval) reval.getInnerValueEval();
+        ValueEval eval = reval.getInnerValueEval();
         
         // most common case - least worries :)
         if (eval instanceof NumberEval) {
-            retval = (NumberEval) eval;
+            return eval;
         }
         
-        // booleval
-        else if (eval instanceof BoolEval) {
-            retval = ((flags & REF_BOOL_IS_PARSED) > 0)
+        if (eval instanceof BoolEval) {
+            return ((flags & REF_BOOL_IS_PARSED) > 0)
                     ? (ValueEval) eval
                     : BlankEval.INSTANCE;
         } 
         
-        // stringeval 
-        else if (eval instanceof StringEval) {
-            retval = xlateRefStringEval((StringEval) eval);
-        }
-        
-        // erroreval
-        else if (eval instanceof ErrorEval) {
-            retval = eval;
-        }
-        
-        // refeval
-        else if (eval instanceof RefEval) {
-            RefEval re = (RefEval) eval;
-            retval = xlateRefEval(re);
+        if (eval instanceof StringEval) {
+            return xlateRefStringEval((StringEval) eval);
         }
         
-        else if (eval instanceof BlankEval) {
-            retval = xlateBlankEval(reval.isEvaluated() ? EVALUATED_REF_BLANK_IS_PARSED : REF_BLANK_IS_PARSED);
+        if (eval instanceof ErrorEval) {
+            return eval;
         }
         
-        // probably AreaEval ? then not acceptable.
-        else { 
-            throw new RuntimeException("Invalid ValueEval type passed for conversion: " + eval.getClass());
+        if (eval instanceof BlankEval) {
+            return xlateBlankEval(REF_BLANK_IS_PARSED);
         }
-
         
-        
-
-        return retval;
+        throw new RuntimeException("Invalid ValueEval type passed for conversion: ("
+        		+ eval.getClass().getName() + ")");
     }
     
     /**
@@ -176,93 +151,38 @@
      * @param eval
      */
     private ValueEval xlateStringEval(StringEval eval) {
-        ValueEval retval = null;
+
         if ((flags & STRING_IS_PARSED) > 0) {
             String s = eval.getStringValue();
-            try { 
-                double d = Double.parseDouble(s);
-                retval = new NumberEval(d);
-            } 
-            catch (Exception e) {
-                if ((flags & STRING_TO_BOOL_IS_PARSED) > 0) {
-                    try { 
-                        boolean b = Boolean.getBoolean(s);
-                        retval = b ? BoolEval.TRUE : BoolEval.FALSE;
-                    } 
-                    catch (Exception e2) { retval = ErrorEval.VALUE_INVALID; }
-                }
-                else {
-                    retval = ErrorEval.VALUE_INVALID;
-                }
+            Double d = OperandResolver.parseDouble(s);
+            if(d == null) {
+                return ErrorEval.VALUE_INVALID;
             }
+            return new NumberEval(d.doubleValue());
         }
-        else if ((flags & STRING_TO_BOOL_IS_PARSED) > 0) {
-            String s = eval.getStringValue();
-            try { 
-                boolean b = Boolean.getBoolean(s);
-                retval = b ? BoolEval.TRUE : BoolEval.FALSE;
-            } 
-            catch (Exception e) { retval = ErrorEval.VALUE_INVALID; }
-        }
-        
         // strings are errors?
-        else if ((flags & STRING_IS_INVALID_VALUE) > 0) {
-            retval = ErrorEval.VALUE_INVALID;
+        if ((flags & STRING_IS_INVALID_VALUE) > 0) {
+            return ErrorEval.VALUE_INVALID;
         }
         
         // ignore strings
-        else {
-            retval = xlateBlankEval(BLANK_IS_PARSED);
-        }
-        return retval;
+        return xlateBlankEval(BLANK_IS_PARSED);
     }
     
     /**
      * uses the relevant flags to decode the StringEval
      * @param eval
      */
-    private ValueEval xlateRefStringEval(StringEval eval) {
-        ValueEval retval = null;
+    private ValueEval xlateRefStringEval(StringEval sve) {
         if ((flags & REF_STRING_IS_PARSED) > 0) {
-            StringEval sve = (StringEval) eval;
             String s = sve.getStringValue();
-            try { 
-                double d = Double.parseDouble(s);
-                retval = new NumberEval(d);
-            } 
-            catch (Exception e) { 
-                if ((flags & REF_STRING_TO_BOOL_IS_PARSED) > 0) {
-                    try { 
-                        boolean b = Boolean.getBoolean(s);
-                        retval = b ? BoolEval.TRUE : BoolEval.FALSE;
-                    } 
-                    catch (Exception e2) { retval = ErrorEval.VALUE_INVALID; }
-                }
-                else {
-                    retval = ErrorEval.VALUE_INVALID;
-                }
+            Double d = OperandResolver.parseDouble(s);
+            if(d == null) {
+                return ErrorEval.VALUE_INVALID;
             }
+            return new NumberEval(d.doubleValue());
         }
-        else if ((flags & REF_STRING_TO_BOOL_IS_PARSED) > 0) {
-            StringEval sve = (StringEval) eval;
-            String s = sve.getStringValue();
-            try { 
-                boolean b = Boolean.getBoolean(s);
-                retval = b ? BoolEval.TRUE : BoolEval.FALSE;;
-            } 
-            catch (Exception e) { retval = ErrorEval.VALUE_INVALID; }
-        }
-        
-        // strings are errors?
-        else if ((flags & REF_STRING_IS_INVALID_VALUE) > 0) {
-            retval = ErrorEval.VALUE_INVALID;
-        }
-        
         // strings are blanks
-        else {
-            retval = BlankEval.INSTANCE;
-        }
-        return retval;
+        return BlankEval.INSTANCE;
     }
-    
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Avedev.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Avedev.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Avedev.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Avedev.java Tue Mar  4 08:53:32 2008
@@ -33,8 +33,8 @@
 public class Avedev extends MultiOperandNumericFunction {
 
     private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
-        new ValueEvalToNumericXlator((short) (0
-              //    ValueEvalToNumericXlator.BOOL_IS_PARSED  
+        new ValueEvalToNumericXlator((short) (
+                  ValueEvalToNumericXlator.BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.STRING_IS_PARSED  
@@ -44,7 +44,6 @@
               //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
               //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
-                | ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
                 ));
     
     /**

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Average.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Average.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Average.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Average.java Tue Mar  4 08:53:32 2008
@@ -33,8 +33,8 @@
 public class Average extends MultiOperandNumericFunction {
 
     private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
-        new ValueEvalToNumericXlator((short) (0
-              //    ValueEvalToNumericXlator.BOOL_IS_PARSED  
+        new ValueEvalToNumericXlator((short) (
+                    ValueEvalToNumericXlator.BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.STRING_IS_PARSED  
@@ -44,7 +44,6 @@
               //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
               //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
-                | ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
                 ));
     
     /**

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java Tue Mar  4 08:53:32 2008
@@ -14,10 +14,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on Jun 20, 2005
- *
- */
+
 package org.apache.poi.hssf.record.formula.functions;
 
 import org.apache.poi.hssf.record.formula.eval.BoolEval;
@@ -38,13 +35,10 @@
         new ValueEvalToNumericXlator((short) (0
                 | ValueEvalToNumericXlator.BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.STRING_IS_PARSED  
                 | ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
                 | ValueEvalToNumericXlator.BLANK_IS_PARSED  
                 | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED  
-                | ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED  
               //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
               //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
@@ -56,11 +50,11 @@
      * if they desire to return a different ValueEvalToNumericXlator instance
      * than the default.
      */
-    protected ValueEvalToNumericXlator getXlator() {
+    protected final ValueEvalToNumericXlator getXlator() {
         return DEFAULT_NUM_XLATOR;
     }
     
-    protected ValueEval singleOperandNumericAsBoolean(Eval eval, int srcRow, short srcCol) {
+    protected final ValueEval singleOperandNumericAsBoolean(Eval eval, int srcRow, short srcCol) {
         ValueEval retval = null;
         retval = singleOperandEvaluate(eval, srcRow, srcCol);
         if (retval instanceof NumericValueEval) {
@@ -74,5 +68,4 @@
         }
         return retval;
     }
-
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java Tue Mar  4 08:53:32 2008
@@ -28,28 +28,22 @@
  * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
  * 
  */
-public class If implements Function {
+public final class If implements Function {
+
+    public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
 
-    public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) {
-        Eval retval = null;
         Eval evalWhenFalse = BoolEval.FALSE;
-        switch (evals.length) {
+        switch (args.length) {
         case 3:
-            evalWhenFalse = evals[2];
+            evalWhenFalse = args[2];
         case 2:
-            BoolEval beval = (BoolEval) evals[0];
+            BoolEval beval = (BoolEval) args[0]; // TODO - class cast exception
             if (beval.getBooleanValue()) {
-                retval = evals[1];
-            }
-            else {
-                retval = evalWhenFalse;
+                return args[1];
             }
-            break;
+            return evalWhenFalse;
         default:
-            retval = ErrorEval.UNKNOWN_ERROR;
+            return ErrorEval.VALUE_INVALID;
         }
-        return retval;
     }
-
-
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isblank.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isblank.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isblank.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isblank.java Tue Mar  4 08:53:32 2008
@@ -14,79 +14,35 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 15, 2005
- *
- */
+
 package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.BlankEval;
 import org.apache.poi.hssf.record.formula.eval.BoolEval;
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.RefEval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 
 /**
  * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
  *
  */
-public class Isblank implements Function {
+public final class Isblank implements Function {
 
-    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
-        ValueEval retval = null;
-        boolean b = false;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            if (operands[0] instanceof BlankEval) {
-                b = true;
-            }
-            else if (operands[0] instanceof AreaEval) {
-                AreaEval ae = (AreaEval) operands[0];
-                if (ae.contains(srcCellRow, srcCellCol)) { // circular ref!
-                    retval = ErrorEval.CIRCULAR_REF_ERROR;
-                }
-                else if (ae.isRow()) {
-                    if (ae.containsColumn(srcCellCol)) {
-                        ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCellCol);
-                        b = (ve instanceof BlankEval);
-                    }
-                    else {
-                        b = false;
-                    }
-                }
-                else if (ae.isColumn()) {
-                    if (ae.containsRow(srcCellRow)) {
-                        ValueEval ve = ae.getValueAt(srcCellRow, ae.getFirstColumn());
-                        b = (ve instanceof BlankEval);
-                    }
-                    else {
-                        b = false;
-                    }
-                }
-                else {
-                    b = false;
-                }
-            }
-            else if (operands[0] instanceof RefEval) {
-                RefEval re = (RefEval) operands[0];
-                b = (!re.isEvaluated()) && re.getInnerValueEval() instanceof BlankEval; 
-            }
-            else {
-                b = false;
-            }
-        }
-        
-        if (retval == null) {
-            retval = b
-                    ? BoolEval.TRUE
-                    : BoolEval.FALSE;
-        }
-        return retval;
-    }
+	public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+		if(args.length != 1) {
+			return ErrorEval.VALUE_INVALID;
+		}
+		Eval arg = args[0];
+		
+		ValueEval singleCellValue;
+		try {
+			singleCellValue = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+		} catch (EvaluationException e) {
+			return BoolEval.FALSE;
+		}
+		return BoolEval.valueOf(singleCellValue instanceof BlankEval);
+	}
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Len.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Len.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Len.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Len.java Tue Mar  4 08:53:32 2008
@@ -14,125 +14,36 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 15, 2005
- *
- */
+
 package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.AreaEval;
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.RefEval;
-import org.apache.poi.hssf.record.formula.eval.StringValueEval;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 
 /**
  * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
  *
  */
-public class Len extends TextFunction {
-
+public final class Len extends TextFunction {
 
-    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
-        ValueEval retval = null;
-        String s = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
-            if (ve instanceof StringValueEval) {
-                StringValueEval sve = (StringValueEval) ve;
-                s = sve.getStringValue();
-            }
-            else if (ve instanceof RefEval) {
-                RefEval re = (RefEval) ve;
-                ValueEval ive = re.getInnerValueEval();
-                if (ive instanceof BlankEval) {
-                    s = re.isEvaluated() ? "0" : null;
-                }
-                else if (ive instanceof StringValueEval) {
-                    s = ((StringValueEval) ive).getStringValue();
-                }
-                else if (ive instanceof BlankEval) {}
-                else {
-                    retval = ErrorEval.VALUE_INVALID;
-                }
-            }
-            else if (ve instanceof BlankEval) {}
-            else {
-                retval = ErrorEval.VALUE_INVALID;
-                break;
-            }
-        }
-        
-        if (retval == null) {
-            s = (s == null) ? EMPTY_STRING : s;
-            retval = new NumberEval(s.length());
-        }
-        
-        return retval;
-    }
-    
-    
-    protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) {
-        ValueEval retval;
-        if (eval instanceof AreaEval) {
-            AreaEval ae = (AreaEval) eval;
-            if (ae.contains(srcRow, srcCol)) { // circular ref!
-                retval = ErrorEval.CIRCULAR_REF_ERROR;
-            }
-            else if (ae.isRow()) {
-                if (ae.containsColumn(srcCol)) {
-                    ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
-                    retval = attemptXlateToText(ve);
-                }
-                else {
-                    retval = ErrorEval.VALUE_INVALID;
-                }
-            }
-            else if (ae.isColumn()) {
-                if (ae.containsRow(srcRow)) {
-                    ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
-                    retval = attemptXlateToText(ve);
-                }
-                else {
-                    retval = ErrorEval.VALUE_INVALID;
-                }
-            }
-            else {
-                retval = ErrorEval.VALUE_INVALID;
-            }
-        }
-        else {
-            retval = attemptXlateToText((ValueEval) eval);
-        }
-        return retval;
-    }
+	public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+		
+		if(args.length != 1) {
+			return ErrorEval.VALUE_INVALID;
+		}
+		
+		try {
+			ValueEval veval = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
 
-    
-    /**
-     * converts from Different ValueEval types to StringEval.
-     * Note: AreaEvals are not handled, if arg is an AreaEval,
-     * the returned value is ErrorEval.VALUE_INVALID
-     * @param ve
-     */
-    protected ValueEval attemptXlateToText(ValueEval ve) {
-        ValueEval retval;
-        if (ve instanceof StringValueEval || ve instanceof RefEval) {
-            retval = ve;
-        }
-        else if (ve instanceof BlankEval) {
-            retval = ve;
-        }
-        else {
-            retval = ErrorEval.VALUE_INVALID;
-        }
-        return retval;
-    }
+			String str = OperandResolver.coerceValueToString(veval);
+			
+			return new NumberEval(str.length());
+		} catch (EvaluationException e) {
+			return e.getErrorEval();
+		}
+	}
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Maxa.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Maxa.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Maxa.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Maxa.java Tue Mar  4 08:53:32 2008
@@ -14,10 +14,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 15, 2005
- *
- */
+
 package org.apache.poi.hssf.record.formula.functions;
 
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
@@ -30,12 +27,11 @@
  * @author Amol S. Deshmukh < amolweb at ya hoo dot com > 
  *
  */
-public class Maxa extends MultiOperandNumericFunction {
+public final class Maxa extends MultiOperandNumericFunction {
     private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
         new ValueEvalToNumericXlator((short) (
                   ValueEvalToNumericXlator.BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.STRING_IS_PARSED  
               //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
               //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mid.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mid.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mid.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mid.java Tue Mar  4 08:53:32 2008
@@ -23,7 +23,6 @@
 import org.apache.poi.hssf.record.formula.eval.EvaluationException;
 import org.apache.poi.hssf.record.formula.eval.OperandResolver;
 import org.apache.poi.hssf.record.formula.eval.StringEval;
-import org.apache.poi.hssf.record.formula.eval.StringValueEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 
 /**
@@ -35,7 +34,7 @@
  * 
  * @author Manda Wilson < wilson at c bio dot msk cc dot org >
  */
-public class Mid extends TextFunction {
+public class Mid implements Function {
 	/**
 	 * Returns a specific number of characters from a text string, starting at
 	 * the position you specify, based on the number of characters you specify.
@@ -52,7 +51,8 @@
 		int numChars;
 
 		try {
-			text = evaluateTextArg(args[0], srcCellRow, srcCellCol);
+			ValueEval evText = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
+			text = OperandResolver.coerceValueToString(evText);
 			int startCharNum = evaluateNumberArg(args[1], srcCellRow, srcCellCol);
 			numChars = evaluateNumberArg(args[2], srcCellRow, srcCellCol);
 			startIx = startCharNum - 1; // convert to zero-based
@@ -79,7 +79,7 @@
 
 	}
 
-	public static int evaluateNumberArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
+	private static int evaluateNumberArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
 		ValueEval ev = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
 		if (ev instanceof BlankEval) {
 			// Note - for start_num arg, blank causes error(#VALUE!),
@@ -88,13 +88,5 @@
 		}
 
 		return OperandResolver.coerceValueToInt(ev);
-	}
-
-	private static String evaluateTextArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
-		ValueEval ev = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
-		if (ev instanceof StringValueEval) {
-			return ((StringValueEval) ev).getStringValue();
-		}
-		throw EvaluationException.invalidValue();
 	}
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mina.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mina.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mina.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mina.java Tue Mar  4 08:53:32 2008
@@ -14,10 +14,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 15, 2005
- *
- */
+
 package org.apache.poi.hssf.record.formula.functions;
 
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
@@ -35,7 +32,6 @@
         new ValueEvalToNumericXlator((short) (
                   ValueEvalToNumericXlator.BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.STRING_IS_PARSED  
               //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
               //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java Tue Mar  4 08:53:32 2008
@@ -76,32 +76,9 @@
         }
     }
     
-
-    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
-        new ValueEvalToNumericXlator((short) (
-                  ValueEvalToNumericXlator.BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_IS_PARSED  
-                | ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
-              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE  
-                ));
-    
     private static final int DEFAULT_MAX_NUM_OPERANDS = 30;
 
-    /**
-     * this is the default impl for the factory method getXlator
-     * of the super class NumericFunction. Subclasses can override this method
-     * if they desire to return a different ValueEvalToNumericXlator instance
-     * than the default.
-     */
-    protected ValueEvalToNumericXlator getXlator() {
-        return DEFAULT_NUM_XLATOR;
-    }
+    protected abstract ValueEvalToNumericXlator getXlator();
     
     /**
      * Maximum number of operands accepted by this function.
@@ -160,9 +137,7 @@
                  * HSSFFormulaEvaluator where we store an array
                  * of RefEvals as the "values" array. 
                  */
-                RefEval re = (values[j] instanceof RefEval)
-                        ? new Ref2DEval(null, ((RefEval) values[j]).getInnerValueEval(), true)
-                        : new Ref2DEval(null, values[j], false);
+                RefEval re = new Ref2DEval(null, values[j]);
                 ValueEval ve = singleOperandEvaluate(re, srcRow, srcCol);
                 
                 if (ve instanceof NumericValueEval) {

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/NumericFunction.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/NumericFunction.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/NumericFunction.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/NumericFunction.java Tue Mar  4 08:53:32 2008
@@ -39,10 +39,8 @@
         new ValueEvalToNumericXlator((short) (
                   ValueEvalToNumericXlator.BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.STRING_IS_PARSED  
                 | ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
               //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdev.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdev.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdev.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdev.java Tue Mar  4 08:53:32 2008
@@ -33,8 +33,8 @@
 public class Stdev extends MultiOperandNumericFunction {
 
     private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
-        new ValueEvalToNumericXlator((short) (0
-              //    ValueEvalToNumericXlator.BOOL_IS_PARSED  
+        new ValueEvalToNumericXlator((short) (
+                  ValueEvalToNumericXlator.BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.STRING_IS_PARSED  
@@ -44,7 +44,6 @@
               //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
               //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
-                | ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
                 ));
     
     /**

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumsq.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumsq.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumsq.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumsq.java Tue Mar  4 08:53:32 2008
@@ -33,18 +33,18 @@
 public class Sumsq extends MultiOperandNumericFunction {
     private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
         new ValueEvalToNumericXlator((short) (
-              //  ValueEvalToNumericXlator.BOOL_IS_PARSED  
+                ValueEvalToNumericXlator.BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
               //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
               //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
               //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
               //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
               //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE  
-                  ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
-                | ValueEvalToNumericXlator.BLANK_IS_PARSED
+              //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
+              //| ValueEvalToNumericXlator.BLANK_IS_PARSED
                 ));
     
     protected ValueEvalToNumericXlator getXlator() {

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java Tue Mar  4 08:53:32 2008
@@ -14,50 +14,23 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
+package org.apache.poi.hssf.record.formula.functions;
 
 /**
+ * Implementation of Excel function SUMX2MY2()<p/>
+ * 
+ * Calculates the sum of differences of squares in two arrays of the same size.<br/>
+ * <b>Syntax</b>:<br/>
+ * <b>SUMX2MY2</b>(<b>arrayX</b>, <b>arrayY</b>)<p/>
+ * 
+ * result = &Sigma;<sub>i: 0..n</sub>(x<sub>i</sub><sup>2</sup>-y<sub>i</sub><sup>2</sup>)
+ * 
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
- *
  */
-public class Sumx2my2 extends XYNumericFunction {
+public final class Sumx2my2 extends XYNumericFunction {
 
-    
-    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
-        ValueEval retval = null;
-        double[][] values = null;
-        
-        int checkLen = 0; // check to see that all array lengths are equal
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 2:
-            values = getValues(operands, srcCellRow, srcCellCol);
-            if (values==null 
-                    || values[X] == null || values[Y] == null
-                    || values[X].length == 0 || values[Y].length == 0
-                    || values[X].length != values[Y].length) {
-                retval = ErrorEval.VALUE_INVALID;
-            }
-        }
-        
-        if (retval == null) {
-            double d = MathX.sumx2my2(values[X], values[Y]);
-            retval = (Double.isNaN(d) || Double.isInfinite(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        
-        return retval;
+    protected double evaluate(double[] xArray, double[] yArray) {
+    	return MathX.sumx2my2(xArray, yArray);
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2py2.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2py2.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2py2.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2py2.java Tue Mar  4 08:53:32 2008
@@ -14,50 +14,23 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
+package org.apache.poi.hssf.record.formula.functions;
 
 /**
+ * Implementation of Excel function SUMX2PY2()<p/>
+ * 
+ * Calculates the sum of squares in two arrays of the same size.<br/>
+ * <b>Syntax</b>:<br/>
+ * <b>SUMX2PY2</b>(<b>arrayX</b>, <b>arrayY</b>)<p/>
+ * 
+ * result = &Sigma;<sub>i: 0..n</sub>(x<sub>i</sub><sup>2</sup>+y<sub>i</sub><sup>2</sup>)
+ * 
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
- *
  */
-public class Sumx2py2 extends XYNumericFunction {
+public final class Sumx2py2 extends XYNumericFunction {
 
-    
-    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
-        ValueEval retval = null;
-        double[][] values = null;
-        
-        int checkLen = 0; // check to see that all array lengths are equal
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 2:
-            values = getValues(operands, srcCellRow, srcCellCol);
-            if (values==null 
-                    || values[X] == null || values[Y] == null
-                    || values[X].length == 0 || values[Y].length == 0
-                    || values[X].length != values[Y].length) {
-                retval = ErrorEval.VALUE_INVALID;
-            }
-        }
-        
-        if (retval == null) {
-            double d = MathX.sumx2py2(values[X], values[Y]);
-            retval = (Double.isNaN(d) || Double.isInfinite(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        
-        return retval;
+    protected double evaluate(double[] xArray, double[] yArray) {
+    	return MathX.sumx2py2(xArray, yArray);
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumxmy2.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumxmy2.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumxmy2.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumxmy2.java Tue Mar  4 08:53:32 2008
@@ -14,50 +14,23 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
+package org.apache.poi.hssf.record.formula.functions;
 
 /**
+ * Implementation of Excel function SUMXMY2()<p/>
+ * 
+ * Calculates the sum of squares of differences between two arrays of the same size.<br/>
+ * <b>Syntax</b>:<br/>
+ * <b>SUMXMY2</b>(<b>arrayX</b>, <b>arrayY</b>)<p/>
+ * 
+ * result = &Sigma;<sub>i: 0..n</sub>(x<sub>i</sub>-y<sub>i</sub>)<sup>2</sup>
+ * 
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
- *
  */
-public class Sumxmy2 extends XYNumericFunction {
+public final class Sumxmy2 extends XYNumericFunction {
 
-    
-    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
-        ValueEval retval = null;
-        double[][] values = null;
-        
-        int checkLen = 0; // check to see that all array lengths are equal
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 2:
-            values = getValues(operands, srcCellRow, srcCellCol);
-            if (values==null 
-                    || values[X] == null || values[Y] == null
-                    || values[X].length == 0 || values[Y].length == 0
-                    || values[X].length != values[Y].length) {
-                retval = ErrorEval.VALUE_INVALID;
-            }
-        }
-        
-        if (retval == null) {
-            double d = MathX.sumxmy2(values[X], values[Y]);
-            retval = (Double.isNaN(d) || Double.isInfinite(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        
-        return retval;
+    protected double evaluate(double[] xArray, double[] yArray) {
+    	return MathX.sumxmy2(xArray, yArray);
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trim.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trim.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trim.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trim.java Tue Mar  4 08:53:32 2008
@@ -16,12 +16,11 @@
 */
 package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
 import org.apache.poi.hssf.record.formula.eval.StringEval;
-import org.apache.poi.hssf.record.formula.eval.StringValueEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 
 /**
@@ -30,46 +29,25 @@
  *  value is string.
  * @author Manda Wilson &lt; wilson at c bio dot msk cc dot org &gt;
  */
-public class Trim extends TextFunction {
+public final class Trim extends TextFunction {
 
-	/**
-	 * Removes leading and trailing spaces from value if evaluated 
-	 *  operand value is string.
-	 * Returns StringEval only if evaluated operand is of type string 
-	 *  (and is not blank or null) or number. If evaluated operand is 
-	 *  of type string and is blank or null, or if evaluated operand is 
-	 *  of type blank, returns BlankEval.  Otherwise returns ErrorEval.
-	 * 
-	 * @see org.apache.poi.hssf.record.formula.eval.Eval
-	 */
-    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
-    	Eval retval = ErrorEval.VALUE_INVALID;
-        String str = null;
-        
-        switch (operands.length) {
-	        default:
-	            break;
-	        case 1:
-	            ValueEval veval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
-	            if (veval instanceof StringValueEval) {
-	                StringValueEval sve = (StringValueEval) veval;
-	                str = sve.getStringValue();
-	                if (str == null || str.trim().equals("")) {
-	                	return BlankEval.INSTANCE;
-	                }
-	            }
-	            else if (veval instanceof NumberEval) {
-	                NumberEval neval = (NumberEval) veval;
-	                str = neval.getStringValue();
-	            } 
-	            else if (veval instanceof BlankEval) {
-	            	return BlankEval.INSTANCE;
-	            }
-	    }
-	        
-        if (str != null) {
-            retval = new StringEval(str.trim());
-        } 
-        return retval;
-    }
+	public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+		
+		if(args.length != 1) {
+			return ErrorEval.VALUE_INVALID;
+		}
+		
+		try {
+			ValueEval veval = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
+
+			String str = OperandResolver.coerceValueToString(veval);
+			str = str.trim();
+			if(str.length() < 1) {
+				return StringEval.EMPTY_INSTANCE;
+			}
+			return new StringEval(str);
+		} catch (EvaluationException e) {
+			return e.getErrorEval();
+		}
+	}
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java Tue Mar  4 08:53:32 2008
@@ -14,154 +14,151 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 29, 2005
- *
- */
+
 package org.apache.poi.hssf.record.formula.functions;
 
 import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
 import org.apache.poi.hssf.record.formula.eval.RefEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public abstract class XYNumericFunction extends NumericFunction {
+public abstract class XYNumericFunction implements Function {
     protected static final int X = 0;
     protected static final int Y = 1;
+    
+    protected static final class DoubleArrayPair {
 
-    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
-        new ValueEvalToNumericXlator((short) (
-                  ValueEvalToNumericXlator.BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_IS_PARSED  
-                | ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
-              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE  
-                ));
+		private final double[] _xArray;
+		private final double[] _yArray;
 
-    /**
-     * this is the default impl for the factory method getXlator
-     * of the super class NumericFunction. Subclasses can override this method
-     * if they desire to return a different ValueEvalToNumericXlator instance
-     * than the default.
-     */
-    protected ValueEvalToNumericXlator getXlator() {
-        return DEFAULT_NUM_XLATOR;
-    }
-    
-    protected int getMaxNumOperands() {
-        return 30;
+		public DoubleArrayPair(double[] xArray, double[] yArray) {
+			_xArray = xArray;
+			_yArray = yArray;
+		}
+		public double[] getXArray() {
+			return _xArray;
+		}
+		public double[] getYArray() {
+			return _yArray;
+		}
     }
 
+
+    public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+    	if(args.length != 2) {
+    		return ErrorEval.VALUE_INVALID;
+    	}
+    	
+        double[][] values;
+		try {
+			values = getValues(args[0], args[1]);
+		} catch (EvaluationException e) {
+			return e.getErrorEval();
+		}
+        if (values==null 
+                || values[X] == null || values[Y] == null
+                || values[X].length == 0 || values[Y].length == 0
+                || values[X].length != values[Y].length) {
+            return ErrorEval.VALUE_INVALID;
+        }
+        
+        double d = evaluate(values[X], values[Y]);
+        if (Double.isNaN(d) || Double.isInfinite(d)) {
+			return ErrorEval.NUM_ERROR;
+		}
+		return new NumberEval(d);
+    }    
+    protected abstract double evaluate(double[] xArray, double[] yArray);
+
     /**
      * Returns a double array that contains values for the numeric cells
      * from among the list of operands. Blanks and Blank equivalent cells
      * are ignored. Error operands or cells containing operands of type
      * that are considered invalid and would result in #VALUE! error in 
      * excel cause this function to return null.
-     * 
-     * @param xops
-     * @param yops
-     * @param srcRow
-     * @param srcCol
      */
-    protected double[][] getNumberArray(Eval[] xops, Eval[] yops, int srcRow, short srcCol) {
-        double[][] retval = new double[2][30];
+    private static double[][] getNumberArray(Eval[] xops, Eval[] yops) throws EvaluationException {
+    	
+    	// check for errors first: size mismatch, value errors in x, value errors in y
+    	
+    	int nArrayItems = xops.length;
+		if(nArrayItems != yops.length) {
+    		throw new EvaluationException(ErrorEval.NA);
+    	}
+		for (int i = 0; i < xops.length; i++) {
+			Eval eval = xops[i];
+			if (eval instanceof ErrorEval) {
+				throw new EvaluationException((ErrorEval) eval);
+			}
+		}
+		for (int i = 0; i < yops.length; i++) {
+			Eval eval = yops[i];
+			if (eval instanceof ErrorEval) {
+				throw new EvaluationException((ErrorEval) eval);
+			}
+		}
+		
+        double[] xResult = new double[nArrayItems];
+        double[] yResult = new double[nArrayItems];
+    	
         int count = 0;
         
-        if (xops.length > getMaxNumOperands() 
-                || yops.length > getMaxNumOperands()
-                || xops.length != yops.length) {
-            retval = null;
-        }
-        else {
-            
-            for (int i=0, iSize=xops.length; i<iSize; i++) {
-                Eval xEval = xops[i];
-                Eval yEval = yops[i];
-                
-                if (isNumberEval(xEval) && isNumberEval(yEval)) {
-                    retval[X] = ensureCapacity(retval[X], count);
-                    retval[Y] = ensureCapacity(retval[Y], count);
-                    retval[X][count] = getDoubleValue(xEval);
-                    retval[Y][count] = getDoubleValue(yEval);
-                    if (Double.isNaN(retval[X][count]) || Double.isNaN(retval[Y][count])) {
-                        retval = null;
-                        break;
-                    }
-                    count++;
-                }
-            }
-        }
-        
-        if (retval != null) {
-            double[][] temp = retval;
-            retval[X] = trimToSize(retval[X], count);
-            retval[Y] = trimToSize(retval[Y], count);
-        }
-        
-        return retval;
-    }
-    
-    protected double[][] getValues(Eval[] operands, int srcCellRow, short srcCellCol) {
-        double[][] retval = null;
-        
-        outer: do {
-            if (operands.length == 2) {
-                Eval[] xEvals = new Eval[1];
-                Eval[] yEvals = new Eval[1];
-                if (operands[X] instanceof AreaEval) {
-                    AreaEval ae = (AreaEval) operands[0];
-                    xEvals = ae.getValues();
-                }
-                else if (operands[X] instanceof ErrorEval) {
-                    break outer;
-                }
-                else {
-                    xEvals[0] = operands[X];
-                }
-                
-                if (operands[Y] instanceof AreaEval) {
-                    AreaEval ae = (AreaEval) operands[Y];
-                    yEvals = ae.getValues();
-                }
-                else if (operands[Y] instanceof ErrorEval) {
-                    break outer;
-                }
-                else {
-                    yEvals[0] = operands[Y];
-                }
-                
-                retval = getNumberArray(xEvals, yEvals, srcCellRow, srcCellCol);
-            }
-        } while (false);
-        
-        return retval;
-    }
-    
-
-    protected static double[] ensureCapacity(double[] arr, int pos) {
-        double[] temp = arr;
-        while (pos >= arr.length) {
-            arr = new double[arr.length << 2];
-        }
-        if (temp.length != arr.length)
-            System.arraycopy(temp, 0, arr, 0, temp.length);
-        return arr;
+		for (int i=0, iSize=nArrayItems; i<iSize; i++) {
+		    Eval xEval = xops[i];
+		    Eval yEval = yops[i];
+		    
+		    if (isNumberEval(xEval) && isNumberEval(yEval)) {
+		    	xResult[count] = getDoubleValue(xEval);
+		    	yResult[count] = getDoubleValue(yEval);
+		        if (Double.isNaN(xResult[count]) || Double.isNaN(xResult[count])) {
+		            throw new EvaluationException(ErrorEval.NUM_ERROR);
+		        }
+		        count++;
+		    }
+		}
+        
+		return new double[][] {
+        	trimToSize(xResult, count),
+            trimToSize(yResult, count),
+		};
+    }
+    
+    private static double[][] getValues(Eval argX, Eval argY) throws EvaluationException {
+    	
+    	if (argX instanceof ErrorEval) {
+			throw new EvaluationException((ErrorEval) argX);
+		}
+    	if (argY instanceof ErrorEval) {
+			throw new EvaluationException((ErrorEval) argY);
+		}
+    	
+        Eval[] xEvals;
+		Eval[] yEvals;
+		if (argX instanceof AreaEval) {
+		    AreaEval ae = (AreaEval) argX;
+		    xEvals = ae.getValues();
+		} else {
+		    xEvals = new Eval[] { argX, };
+		}
+		
+		if (argY instanceof AreaEval) {
+		    AreaEval ae = (AreaEval) argY;
+		    yEvals = ae.getValues();
+		} else {
+		    yEvals = new Eval[] { argY, };
+		}
+		
+		return getNumberArray(xEvals, yEvals);
     }
     
-    protected static double[] trimToSize(double[] arr, int len) {
+    private static double[] trimToSize(double[] arr, int len) {
         double[] tarr = arr;
         if (arr.length > len) {
             tarr = new double[len];
@@ -170,7 +167,7 @@
         return tarr;
     }
     
-    protected static boolean isNumberEval(Eval eval) {
+    private static boolean isNumberEval(Eval eval) {
         boolean retval = false;
         
         if (eval instanceof NumberEval) {
@@ -185,7 +182,7 @@
         return retval;
     }
     
-    protected static double getDoubleValue(Eval eval) {
+    private static double getDoubleValue(Eval eval) {
         double retval = 0;
         if (eval instanceof NumberEval) {
             NumberEval ne = (NumberEval) eval;

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java Tue Mar  4 08:53:32 2008
@@ -80,6 +80,7 @@
 import org.apache.poi.hssf.record.formula.eval.LessEqualEval;
 import org.apache.poi.hssf.record.formula.eval.LessThanEval;
 import org.apache.poi.hssf.record.formula.eval.MultiplyEval;
+import org.apache.poi.hssf.record.formula.eval.NameEval;
 import org.apache.poi.hssf.record.formula.eval.NotEqualEval;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
 import org.apache.poi.hssf.record.formula.eval.OperationEval;
@@ -360,16 +361,16 @@
         EvaluationCycleDetector tracker = EvaluationCycleDetectorManager.getTracker();
         
         if(!tracker.startEvaluate(workbook, sheet, srcRowNum, srcColNum)) {
-        	return ErrorEval.CIRCULAR_REF_ERROR;
+            return ErrorEval.CIRCULAR_REF_ERROR;
         }
         try {
-        	return evaluateCell(workbook, sheet, srcRowNum, srcColNum, srcCell.getCellFormula());
+            return evaluateCell(workbook, sheet, srcRowNum, srcColNum, srcCell.getCellFormula());
         } finally {
-        	tracker.endEvaluate(workbook, sheet, srcRowNum, srcColNum);
+            tracker.endEvaluate(workbook, sheet, srcRowNum, srcColNum);
         }
     }
     private static ValueEval evaluateCell(HSSFWorkbook workbook, HSSFSheet sheet, 
-    		int srcRowNum, short srcColNum, String cellFormulaText) {
+            int srcRowNum, short srcColNum, String cellFormulaText) {
         FormulaParser parser = new FormulaParser(cellFormulaText, workbook.getWorkbook());
         parser.parse();
         Ptg[] ptgs = parser.getRPNPtg();
@@ -380,15 +381,24 @@
         for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
 
             // since we don't know how to handle these yet :(
-            if (ptgs[i] instanceof ControlPtg) { continue; }
-            if (ptgs[i] instanceof MemErrPtg) { continue; }
-            if (ptgs[i] instanceof MissingArgPtg) { continue; }
-            if (ptgs[i] instanceof NamePtg) { continue; }
-            if (ptgs[i] instanceof NameXPtg) { continue; }
-            if (ptgs[i] instanceof UnknownPtg) { continue; }
+            Ptg ptg = ptgs[i];
+            if (ptg instanceof ControlPtg) { continue; }
+            if (ptg instanceof MemErrPtg) { continue; }
+            if (ptg instanceof MissingArgPtg) { continue; }
+            if (ptg instanceof NamePtg) { 
+            	// named ranges, macro functions
+                NamePtg namePtg = (NamePtg) ptg;
+                stack.push(new NameEval(namePtg.getIndex()));
+                continue; 
+            }
+            if (ptg instanceof NameXPtg) {
+            	// TODO - external functions
+                continue;
+            }
+            if (ptg instanceof UnknownPtg) { continue; }
 
-            if (ptgs[i] instanceof OperationPtg) {
-                OperationPtg optg = (OperationPtg) ptgs[i];
+            if (ptg instanceof OperationPtg) {
+                OperationPtg optg = (OperationPtg) ptg;
 
                 // parens can be ignored since we have RPN tokens
                 if (optg instanceof ParenthesisPtg) { continue; }
@@ -408,47 +418,67 @@
                 Eval opresult = invokeOperation(operation, ops, srcRowNum, srcColNum, workbook, sheet);
                 stack.push(opresult);
             }
-            else if (ptgs[i] instanceof ReferencePtg) {
-                ReferencePtg ptg = (ReferencePtg) ptgs[i];
-                short colnum = ptg.getColumn();
-                short rownum = ptg.getRow();
+            else if (ptg instanceof ReferencePtg) {
+                ReferencePtg refPtg = (ReferencePtg) ptg;
+                short colnum = refPtg.getColumn();
+                short rownum = refPtg.getRow();
                 HSSFRow row = sheet.getRow(rownum);
                 HSSFCell cell = (row != null) ? row.getCell(colnum) : null;
-                stack.push(createRef2DEval(ptg, cell, row, sheet, workbook));
+                stack.push(createRef2DEval(refPtg, cell, row, sheet, workbook));
             }
-            else if (ptgs[i] instanceof Ref3DPtg) {
-                Ref3DPtg ptg = (Ref3DPtg) ptgs[i];
-                short colnum = ptg.getColumn();
-                short rownum = ptg.getRow();
+            else if (ptg instanceof Ref3DPtg) {
+                Ref3DPtg refPtg = (Ref3DPtg) ptg;
+                short colnum = refPtg.getColumn();
+                short rownum = refPtg.getRow();
                 Workbook wb = workbook.getWorkbook();
-                HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(ptg.getExternSheetIndex()));
+                HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(refPtg.getExternSheetIndex()));
                 HSSFRow row = xsheet.getRow(rownum);
                 HSSFCell cell = (row != null) ? row.getCell(colnum) : null;
-                stack.push(createRef3DEval(ptg, cell, row, xsheet, workbook));
+                stack.push(createRef3DEval(refPtg, cell, row, xsheet, workbook));
             }
-            else if (ptgs[i] instanceof AreaPtg) {
-                AreaPtg ap = (AreaPtg) ptgs[i];
+            else if (ptg instanceof AreaPtg) {
+                AreaPtg ap = (AreaPtg) ptg;
                 AreaEval ae = evaluateAreaPtg(sheet, workbook, ap);
                 stack.push(ae);
             }
-            else if (ptgs[i] instanceof Area3DPtg) {
-                Area3DPtg a3dp = (Area3DPtg) ptgs[i];
+            else if (ptg instanceof Area3DPtg) {
+                Area3DPtg a3dp = (Area3DPtg) ptg;
                 AreaEval ae = evaluateArea3dPtg(workbook, a3dp);
                 stack.push(ae);
             }
             else {
-                Eval ptgEval = getEvalForPtg(ptgs[i]);
+                Eval ptgEval = getEvalForPtg(ptg);
                 stack.push(ptgEval);
             }
         }
 
         ValueEval value = ((ValueEval) stack.pop());
-        if (value instanceof RefEval) {
-            RefEval rv = (RefEval) value;
+        if (!stack.isEmpty()) {
+            throw new IllegalStateException("evaluation stack not empty");
+        }
+        value = dereferenceValue(value, srcRowNum, srcColNum);
+        if (value instanceof BlankEval) {
+        	// Note Excel behaviour here. A blank final final value is converted to zero.  
+            return NumberEval.ZERO;
+            // Formulas _never_ evaluate to blank.  If a formula appears to have evaluated to 
+            // blank, the actual value is empty string. This can be verified with ISBLANK().
+        }
+        return value;
+    }
+
+    /**
+     * Dereferences a single value from any AreaEval or RefEval evaluation result.
+     * If the supplied evaluationResult is just a plain value, it is returned as-is.
+	 * @return a <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt>,
+	 *  <tt>BlankEval</tt> or <tt>ErrorEval</tt>. Never <code>null</code>.
+     */
+    private static ValueEval dereferenceValue(ValueEval evaluationResult, int srcRowNum, short srcColNum) {
+        if (evaluationResult instanceof RefEval) {
+            RefEval rv = (RefEval) evaluationResult;
             return rv.getInnerValueEval();
         }
-        if (value instanceof AreaEval) {
-            AreaEval ae = (AreaEval) value;
+        if (evaluationResult instanceof AreaEval) {
+            AreaEval ae = (AreaEval) evaluationResult;
             if (ae.isRow()) {
                 if(ae.isColumn()) {
                     return ae.getValues()[0];
@@ -460,7 +490,7 @@
             }
             return ErrorEval.VALUE_INVALID;
         }
-        return value;
+        return evaluationResult;
     }
 
     private static Eval invokeOperation(OperationEval operation, Eval[] ops, int srcRowNum, short srcColNum,
@@ -486,7 +516,7 @@
         // (eg C:C)
         // TODO: Handle whole column ranges properly
         if(row1 == -1 && row0 >= 0) {
-        	row1 = (short)sheet.getLastRowNum();
+            row1 = (short)sheet.getLastRowNum();
         }
         
         ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)];
@@ -514,7 +544,7 @@
         // (eg C:C)
         // TODO: Handle whole column ranges properly
         if(row1 == -1 && row0 >= 0) {
-        	row1 = (short)xsheet.getLastRowNum();
+            row1 = (short)xsheet.getLastRowNum();
         }
         
         ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)];
@@ -631,22 +661,22 @@
     private static Ref2DEval createRef2DEval(ReferencePtg ptg, HSSFCell cell, 
             HSSFRow row, HSSFSheet sheet, HSSFWorkbook workbook) {
         if (cell == null) {
-            return new Ref2DEval(ptg, BlankEval.INSTANCE, false);
+            return new Ref2DEval(ptg, BlankEval.INSTANCE);
         }
         
         switch (cell.getCellType()) {
             case HSSFCell.CELL_TYPE_NUMERIC:
-                return new Ref2DEval(ptg, new NumberEval(cell.getNumericCellValue()), false);
+                return new Ref2DEval(ptg, new NumberEval(cell.getNumericCellValue()));
             case HSSFCell.CELL_TYPE_STRING:
-                return new Ref2DEval(ptg, new StringEval(cell.getRichStringCellValue().getString()), false);
+                return new Ref2DEval(ptg, new StringEval(cell.getRichStringCellValue().getString()));
             case HSSFCell.CELL_TYPE_FORMULA:
-                return new Ref2DEval(ptg, internalEvaluate(cell, row, sheet, workbook), true);
+                return new Ref2DEval(ptg, internalEvaluate(cell, row, sheet, workbook));
             case HSSFCell.CELL_TYPE_BOOLEAN:
-                return new Ref2DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue()), false);
+                return new Ref2DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue()));
             case HSSFCell.CELL_TYPE_BLANK:
-                return new Ref2DEval(ptg, BlankEval.INSTANCE, false);
+                return new Ref2DEval(ptg, BlankEval.INSTANCE);
             case HSSFCell.CELL_TYPE_ERROR:
-                return new  Ref2DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue()), false);
+                return new  Ref2DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue()));
         }
         throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")");
     }
@@ -657,21 +687,21 @@
     private static Ref3DEval createRef3DEval(Ref3DPtg ptg, HSSFCell cell, 
             HSSFRow row, HSSFSheet sheet, HSSFWorkbook workbook) {
         if (cell == null) {
-            return new Ref3DEval(ptg, BlankEval.INSTANCE, false);
+            return new Ref3DEval(ptg, BlankEval.INSTANCE);
         }
         switch (cell.getCellType()) {
             case HSSFCell.CELL_TYPE_NUMERIC:
-                return new Ref3DEval(ptg, new NumberEval(cell.getNumericCellValue()), false);
+                return new Ref3DEval(ptg, new NumberEval(cell.getNumericCellValue()));
             case HSSFCell.CELL_TYPE_STRING:
-                return new Ref3DEval(ptg, new StringEval(cell.getRichStringCellValue().getString()), false);
+                return new Ref3DEval(ptg, new StringEval(cell.getRichStringCellValue().getString()));
             case HSSFCell.CELL_TYPE_FORMULA:
-                return new Ref3DEval(ptg, internalEvaluate(cell, row, sheet, workbook), true);
+                return new Ref3DEval(ptg, internalEvaluate(cell, row, sheet, workbook));
             case HSSFCell.CELL_TYPE_BOOLEAN:
-                return new Ref3DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue()), false);
+                return new Ref3DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue()));
             case HSSFCell.CELL_TYPE_BLANK:
-                return new Ref3DEval(ptg, BlankEval.INSTANCE, false);
+                return new Ref3DEval(ptg, BlankEval.INSTANCE);
             case HSSFCell.CELL_TYPE_ERROR:
-                return new Ref3DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue()), false);
+                return new Ref3DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue()));
         }
         throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")");
     }

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/eventusermodel/TestMissingRecordAwareHSSFListener.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/eventusermodel/TestMissingRecordAwareHSSFListener.java?rev=633547&r1=633546&r2=633547&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/eventusermodel/TestMissingRecordAwareHSSFListener.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/eventusermodel/TestMissingRecordAwareHSSFListener.java Tue Mar  4 08:53:32 2008
@@ -16,14 +16,14 @@
 ==================================================================== */
 
 package org.apache.poi.hssf.eventusermodel;
-import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
-import org.apache.poi.hssf.eventusermodel.HSSFListener;
-
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.IOException;
 import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
 
-import org.apache.poi.hssf.eventusermodel.HSSFRequest;
 import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
 import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
 import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord;
@@ -31,31 +31,33 @@
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.RowRecord;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-
-import junit.framework.TestCase;
-
-public class TestMissingRecordAwareHSSFListener extends TestCase {
-	private String dirname;
-	
-	public TestMissingRecordAwareHSSFListener() {
-		dirname = System.getProperty("HSSF.testdata.path");
-	}
+/**
+ * Tests for MissingRecordAwareHSSFListener
+ */
+public final class TestMissingRecordAwareHSSFListener extends TestCase {
 	
-	public void testMissingRowRecords() throws Exception {
+	private Record[] r;
+
+	public void setUp() {
+		String dirname = System.getProperty("HSSF.testdata.path");
 		File f = new File(dirname + "/MissingBits.xls");
-		
+
 		HSSFRequest req = new HSSFRequest();
 		MockHSSFListener mockListen = new MockHSSFListener();
 		MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(mockListen);
 		req.addListenerForAllRecords(listener);
 		
-		POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(f));
 		HSSFEventFactory factory = new HSSFEventFactory();
-		factory.processWorkbookEvents(req, fs);
-		
-		// Check we got the dummy records
-		Record[] r = (Record[])
-			mockListen.records.toArray(new Record[mockListen.records.size()]);
+		try {
+			POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(f));
+			factory.processWorkbookEvents(req, fs);
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+		r = mockListen.getRecords();
+	} 
+	
+	public void testMissingRowRecords() throws Exception {
 		
 		// We have rows 0, 1, 2, 20 and 21
 		int row0 = -1;
@@ -105,20 +107,6 @@
 	}
 	
 	public void testEndOfRowRecords() throws Exception {
-		File f = new File(dirname + "/MissingBits.xls");
-		
-		HSSFRequest req = new HSSFRequest();
-		MockHSSFListener mockListen = new MockHSSFListener();
-		MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(mockListen);
-		req.addListenerForAllRecords(listener);
-		
-		POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(f));
-		HSSFEventFactory factory = new HSSFEventFactory();
-		factory.processWorkbookEvents(req, fs);
-		
-		// Check we got the dummy records
-		Record[] r = (Record[])
-			mockListen.records.toArray(new Record[mockListen.records.size()]);
 		
 		// Find the cell at 0,0
 		int cell00 = -1;
@@ -240,20 +228,6 @@
 	
 	
 	public void testMissingCellRecords() throws Exception {
-		File f = new File(dirname + "/MissingBits.xls");
-		
-		HSSFRequest req = new HSSFRequest();
-		MockHSSFListener mockListen = new MockHSSFListener();
-		MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(mockListen);
-		req.addListenerForAllRecords(listener);
-		
-		POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(f));
-		HSSFEventFactory factory = new HSSFEventFactory();
-		factory.processWorkbookEvents(req, fs);
-		
-		// Check we got the dummy records
-		Record[] r = (Record[])
-			mockListen.records.toArray(new Record[mockListen.records.size()]);
 		
 		// Find the cell at 0,0
 		int cell00 = -1;
@@ -352,25 +326,35 @@
 		assertEquals(10, mc.getColumn());
 	}
 
-	private static class MockHSSFListener implements HSSFListener {
-		private MockHSSFListener() {}
-		private ArrayList records = new ArrayList();
+	private static final class MockHSSFListener implements HSSFListener {
+		public MockHSSFListener() {}
+		private final List _records = new ArrayList();
 
 		public void processRecord(Record record) {
-			records.add(record);
+			_records.add(record);
 			
 			if(record instanceof MissingRowDummyRecord) {
 				MissingRowDummyRecord mr = (MissingRowDummyRecord)record;
-				System.out.println("Got dummy row " + mr.getRowNumber());
+				log("Got dummy row " + mr.getRowNumber());
 			}
 			if(record instanceof MissingCellDummyRecord) {
 				MissingCellDummyRecord mc = (MissingCellDummyRecord)record;
-				System.out.println("Got dummy cell " + mc.getRow() + " " + mc.getColumn());
+				log("Got dummy cell " + mc.getRow() + " " + mc.getColumn());
 			}
 			if(record instanceof LastCellOfRowDummyRecord) {
 				LastCellOfRowDummyRecord lc = (LastCellOfRowDummyRecord)record;
-				System.out.println("Got end-of row, row was " + lc.getRow() + ", last column was " + lc.getLastColumnNumber());
+				log("Got end-of row, row was " + lc.getRow() + ", last column was " + lc.getLastColumnNumber());
+			}
+		}
+		private static void log(String msg) {
+			if(false) { // successful tests should be quiet
+				System.out.println(msg);
 			}
+		}
+		public Record[] getRecords() {
+			Record[] result = new Record[_records.size()];
+			_records.toArray(result);
+			return result;
 		}
 	}
 }

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java?rev=633547&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java (added)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java Tue Mar  4 08:53:32 2008
@@ -0,0 +1,38 @@
+/* ====================================================================
+   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.hssf.record.formula.eval;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Collects all tests the package <tt>org.apache.poi.hssf.record.formula.eval</tt>.
+ * 
+ * @author Josh Micich
+ */
+public class AllFormulaEvalTests {
+	
+	public static Test suite() {
+		TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula.eval");
+		result.addTestSuite(TestCircularReferences.class);
+		result.addTestSuite(TestExternalFunction.class);
+		result.addTestSuite(TestFormulasFromSpreadsheet.class);
+		result.addTestSuite(TestUnaryPlusEval.class);
+		return result;
+	}
+}

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java
------------------------------------------------------------------------------
    svn:executable = *



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org