Author: josh
Date: Fri Dec 25 23:26:47 2009
New Revision: 893898

URL: http://svn.apache.org/viewvc?rev=893898&view=rev
Log:
Fixed FormulaParser to allow negative elements in array literals.

Modified:
    poi/trunk/src/java/org/apache/poi/ss/formula/FormulaParser.java
    poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java

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=893898&r1=893897&r2=893898&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 Fri Dec 25 
23:26:47 2009
@@ -1209,9 +1209,13 @@
                        case 'F': case 'f':
                        case 'T': case 't':
                                return parseBooleanLiteral();
+                       case '-':
+                               Match('-');
+                               SkipWhite();
+                               return convertArrayNumber(parseNumber(), false);
                }
                // else assume number
-               return convertArrayNumber(parseNumber());
+               return convertArrayNumber(parseNumber(), true);
        }
 
        private Boolean parseBooleanLiteral() {
@@ -1225,14 +1229,19 @@
                throw expected("'TRUE' or 'FALSE'");
        }
 
-       private static Double convertArrayNumber(Ptg ptg) {
+       private static Double convertArrayNumber(Ptg ptg, boolean isPositive) {
+               double value;
                if (ptg instanceof IntPtg) {
-                       return new Double(((IntPtg)ptg).getValue());
+                       value = ((IntPtg)ptg).getValue();
+               } else  if (ptg instanceof NumberPtg) {
+                       value = ((NumberPtg)ptg).getValue();
+               } else {
+                       throw new RuntimeException("Unexpected ptg (" + 
ptg.getClass().getName() + ")");
                }
-               if (ptg instanceof NumberPtg) {
-                       return new Double(((NumberPtg)ptg).getValue());
+               if (!isPositive) {
+                       value = -value;
                }
-               throw new RuntimeException("Unexpected ptg (" + 
ptg.getClass().getName() + ")");
+               return new Double(value);
        }
 
        private Ptg parseNumber() {

Modified: 
poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java?rev=893898&r1=893897&r2=893898&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java 
(original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java 
Fri Dec 25 23:26:47 2009
@@ -871,6 +871,28 @@
                confirmTokenClasses(ptgs2, ArrayPtg.class, IntPtg.class, 
FuncVarPtg.class);
        }
 
+       public void testParseArrayNegativeElement() {
+               Ptg[] ptgs;
+               try {
+                       ptgs = parseFormula("{-42}");
+               } catch (FormulaParseException e) {
+                       if (e.getMessage().equals("Parse error near char 1 '-' 
in specified formula '{-42}'. Expected Integer")) {
+                               throw new AssertionFailedError("Identified bug 
- failed to parse negative array element.");
+                       }
+                       throw e;
+               }
+               confirmTokenClasses(ptgs, ArrayPtg.class);
+               Object element = 
((ArrayPtg)ptgs[0]).getTokenArrayValues()[0][0];
+
+               assertEquals(-42.0, ((Double)element).doubleValue(), 0.0);
+
+               // Should be able to handle whitespace between unary minus and 
digits (Excel
+               // accepts this formula after presenting the user with a 
confirmation dialog).
+               ptgs = parseFormula("{- 5}");
+               element = ((ArrayPtg)ptgs[0]).getTokenArrayValues()[0][0];
+               assertEquals(-5.0, ((Double)element).doubleValue(), 0.0);
+       }
+
        public void testRangeOperator() {
 
                HSSFWorkbook wb = new HSSFWorkbook();



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

Reply via email to