You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jo...@apache.org on 2009/02/03 00:53:22 UTC

svn commit: r740159 - in /poi/trunk/src: java/org/apache/poi/hssf/record/formula/ java/org/apache/poi/hssf/record/formula/eval/ java/org/apache/poi/hssf/record/formula/function/ java/org/apache/poi/ss/formula/ testcases/org/apache/poi/hssf/model/

Author: josh
Date: Mon Feb  2 23:53:22 2009
New Revision: 740159

URL: http://svn.apache.org/viewvc?rev=740159&view=rev
Log:
Modified formula parser to encode SUM taking a single argument as tAttrSum (from comment 7 of bugzilla 46643)

Modified:
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataRegistry.java
    poi/trunk/src/java/org/apache/poi/ss/formula/FormulaParser.java
    poi/trunk/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java
    poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java?rev=740159&r1=740158&r2=740159&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java Mon Feb  2 23:53:22 2009
@@ -79,8 +79,7 @@
         _chooseFuncOffset = -1;
     }
 
-    public AttrPtg(LittleEndianInput in) 
-    {
+    public AttrPtg(LittleEndianInput in) {
         field_1_options = in.readByte();
         field_2_data    = in.readShort();
         if (isOptimizedChoose()) {
@@ -113,44 +112,30 @@
         return new AttrPtg(space.set(0), data, null, -1);
     }
 
-    public void setOptions(byte options)
-    {
-        field_1_options = options;
+    public static AttrPtg getSumSingle() {
+        return new AttrPtg(sum.set(0), 0, null, -1);
     }
 
-    public byte getOptions()
-    {
-        return field_1_options;
-    }
 
-    public boolean isSemiVolatile()
-    {
-        return semiVolatile.isSet(getOptions());
+    public boolean isSemiVolatile() {
+        return semiVolatile.isSet(field_1_options);
     }
 
-    public boolean isOptimizedIf()
-    {
-        return optiIf.isSet(getOptions());
+    public boolean isOptimizedIf() {
+        return optiIf.isSet(field_1_options);
     }
 
-    public boolean isOptimizedChoose()
-    {
-        return optiChoose.isSet(getOptions());
+    public boolean isOptimizedChoose() {
+        return optiChoose.isSet(field_1_options);
     }
 
     // lets hope no one uses this anymore
-    public boolean isGoto()
-    {
-        return optGoto.isSet(getOptions());
-    }
-
-    public boolean isSum()
-    {
-        return sum.isSet(getOptions());
+    public boolean isGoto() {
+        return optGoto.isSet(field_1_options);
     }
 
-    public void setSum(boolean bsum) {
-        field_1_options=sum.setByteBoolean(field_1_options,bsum);
+    public boolean isSum() {
+        return sum.isSet(field_1_options);
     }
 
     public void setOptimizedIf(boolean bif) {
@@ -166,24 +151,20 @@
     }
 
     // lets hope no one uses this anymore
-    public boolean isBaxcel()
-    {
-        return baxcel.isSet(getOptions());
+    private boolean isBaxcel() {
+        return baxcel.isSet(field_1_options);
     }
 
     // biff3&4 only  shouldn't happen anymore
-    public boolean isSpace()
-    {
-        return space.isSet(getOptions());
+    public boolean isSpace() {
+        return space.isSet(field_1_options);
     }
 
-    public void setData(short data)
-    {
+    public void setData(short data) {
         field_2_data = data;
     }
 
-    public short getData()
-    {
+    public short getData() {
         return field_2_data;
     }
 
@@ -227,8 +208,7 @@
         }
     }
 
-    public int getSize()
-    {
+    public int getSize() {
         if (_jumpTable != null) {
             return SIZE + (_jumpTable.length + 1) * LittleEndian.SHORT_SIZE;
         }
@@ -239,22 +219,20 @@
         if(space.isSet(field_1_options)) {
             return operands[ 0 ];
         } else if (optiIf.isSet(field_1_options)) {
-            return toFormulaString() + "(" + operands[ 0 ]             +")";
+            return toFormulaString() + "(" + operands[0] + ")";
         } else if (optGoto.isSet(field_1_options)) {
             return toFormulaString() + operands[0];   //goto isn't a real formula element should not show up
         } else {
-            return toFormulaString() + "(" + operands[ 0 ] + ")";
+            return toFormulaString() + "(" + operands[0] + ")";
         }
     }
 
 
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 1;
     }
 
-    public int getType()
-    {
+    public int getType() {
         return -1;
     }
 
@@ -288,7 +266,7 @@
         if (_jumpTable == null) {
             jt = null;
         } else {
-            jt = (int[]) _jumpTable.clone();
+            jt = _jumpTable.clone();
         }
         return new AttrPtg(field_1_options, field_2_data, jt, _chooseFuncOffset);
     }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java?rev=740159&r1=740158&r2=740159&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java Mon Feb  2 23:53:22 2009
@@ -20,6 +20,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
 import org.apache.poi.hssf.record.formula.functions.*;
 
 /**
@@ -31,12 +32,14 @@
      * Some function IDs that require special treatment
      */
     private static final class FunctionID {
+        /** 4 */
+        public static final int SUM = FunctionMetadataRegistry.FUNCTION_INDEX_SUM;
         /** 78 */
         public static final int OFFSET = 78;
         /** 148 */
         public static final int INDIRECT = 148;
         /** 255 */
-        public static final int EXTERNAL_FUNC = 255;
+        public static final int EXTERNAL_FUNC = FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL;
     }
     // convenient access to namespace
     private static final FunctionID ID = null;
@@ -75,7 +78,7 @@
         retval[1] = new If(); // IF
         retval[2] = new IsNa(); // ISNA
         retval[3] = new IsError(); // ISERROR
-        retval[4] = AggregateFunction.SUM;
+        retval[ID.SUM] = AggregateFunction.SUM;
         retval[5] = AggregateFunction.AVERAGE;
         retval[6] = AggregateFunction.MIN;
         retval[7] = AggregateFunction.MAX;

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataRegistry.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataRegistry.java?rev=740159&r1=740158&r2=740159&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataRegistry.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataRegistry.java Mon Feb  2 23:53:22 2009
@@ -30,11 +30,12 @@
 	 */ 
 	public static final String FUNCTION_NAME_IF = "IF";
 
+	public static final short FUNCTION_INDEX_SUM = 4;
 	public static final short FUNCTION_INDEX_EXTERNAL = 255;
 	private static FunctionMetadataRegistry _instance;
 
 	private final FunctionMetadata[] _functionDataByIndex;
-	private final Map _functionDataByName;
+	private final Map<String, FunctionMetadata> _functionDataByName;
 
 	private static FunctionMetadataRegistry getInstance() {
 		if (_instance == null) {
@@ -43,12 +44,12 @@
 		return _instance;
 	}
 
-	/* package */ FunctionMetadataRegistry(FunctionMetadata[] functionDataByIndex, Map functionDataByName) {
+	/* package */ FunctionMetadataRegistry(FunctionMetadata[] functionDataByIndex, Map<String, FunctionMetadata> functionDataByName) {
 		_functionDataByIndex = functionDataByIndex;
 		_functionDataByName = functionDataByName;
 	}
 
-	/* package */ Set getAllFunctionNames() {
+	/* package */ Set<String> getAllFunctionNames() {
 		return _functionDataByName.keySet();
 	}
 
@@ -75,7 +76,7 @@
 	}
 
 	private FunctionMetadata getFunctionByNameInternal(String name) {
-		return (FunctionMetadata) _functionDataByName.get(name);
+		return _functionDataByName.get(name);
 	}
 
 

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/FormulaParser.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/FormulaParser.java?rev=740159&r1=740158&r2=740159&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/FormulaParser.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/FormulaParser.java Mon Feb  2 23:53:22 2009
@@ -27,6 +27,7 @@
 import org.apache.poi.hssf.record.formula.Area3DPtg;
 import org.apache.poi.hssf.record.formula.AreaPtg;
 import org.apache.poi.hssf.record.formula.ArrayPtg;
+import org.apache.poi.hssf.record.formula.AttrPtg;
 import org.apache.poi.hssf.record.formula.BoolPtg;
 import org.apache.poi.hssf.record.formula.ConcatPtg;
 import org.apache.poi.hssf.record.formula.DividePtg;
@@ -592,9 +593,11 @@
         }
         boolean isVarArgs = !fm.hasFixedArgsLength();
         int funcIx = fm.getIndex();
-        if (false && funcIx == 4 && args.length == 1) {
-            // TODO - make POI behave more like Excel when summing a single argument:
-            // return new ParseNode(AttrPtg.getSumSingle(), args);
+        if (funcIx == FunctionMetadataRegistry.FUNCTION_INDEX_SUM && args.length == 1) {
+            // Excel encodes the sum of a single argument as tAttrSum
+            // POI does the same for consistency, but this is not critical
+            return new ParseNode(AttrPtg.getSumSingle(), args);
+            // The code below would encode tFuncVar(SUM) which seems to do no harm 
         }
         validateNumArgs(args.length, fm);
 

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java?rev=740159&r1=740158&r2=740159&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java Mon Feb  2 23:53:22 2009
@@ -18,7 +18,9 @@
 package org.apache.poi.ss.formula;
 
 import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
+import org.apache.poi.hssf.record.formula.AttrPtg;
 import org.apache.poi.hssf.record.formula.ControlPtg;
+import org.apache.poi.hssf.record.formula.FuncVarPtg;
 import org.apache.poi.hssf.record.formula.MemFuncPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.RangePtg;
@@ -101,6 +103,13 @@
 			return;
 		}
 		
+		if (isSingleArgSum(token)) {
+			// Need to process the argument of SUM with transformFunctionNode below
+			// so make a dummy FuncVarPtg for that call.
+			token = new FuncVarPtg("SUM", (byte)1);
+			// Note - the tAttrSum token (node.getToken()) is a base 
+			// token so does not need to have its operand class set
+		}
 		if (token instanceof ValueOperatorPtg || token instanceof ControlPtg
 				|| token instanceof MemFuncPtg
 				|| token instanceof UnionPtg) {
@@ -135,6 +144,14 @@
 		token.setClass(transformClass(token.getPtgClass(), desiredOperandClass, callerForceArrayFlag));
 	}
 
+	private static boolean isSingleArgSum(Ptg token) {
+		if (token instanceof AttrPtg) {
+			AttrPtg attrPtg = (AttrPtg) token;
+			return attrPtg.isSum(); 
+		}
+		return false;
+	}
+
 	private static boolean isSimpleValueFunction(Ptg token) {
 		if (token instanceof AbstractFunctionPtg) {
 			AbstractFunctionPtg aptg = (AbstractFunctionPtg) token;

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java?rev=740159&r1=740158&r2=740159&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java Mon Feb  2 23:53:22 2009
@@ -20,7 +20,7 @@
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
-import org.apache.poi.hssf.record.formula.FuncVarPtg;
+import org.apache.poi.hssf.record.formula.AttrPtg;
 import org.apache.poi.hssf.record.formula.NamePtg;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.usermodel.HSSFCell;
@@ -58,9 +58,8 @@
 		confirmParseFormula(workbook);
 		
 		// And make it non-contiguous
-		if (false) { // TODO (Nov 2008) - make the formula parser support area unions
-			name.setReference("A1:A2,C3");
-		}
+		// using area unions
+		name.setReference("A1:A2,C3");
 		
 		confirmParseFormula(workbook);
 	}
@@ -72,7 +71,7 @@
 		Ptg[] ptgs = HSSFFormulaParser.parse("SUM(testName)", workbook);
 		assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2);
 		assertEquals(NamePtg.class, ptgs[0].getClass());
-		assertEquals(FuncVarPtg.class, ptgs[1].getClass());
+		assertEquals(AttrPtg.class, ptgs[1].getClass());
 	}
 
 	public void testEvaluateFormulaWithRowBeyond32768_Bug44539() {



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