]> source.dussan.org Git - poi.git/commitdiff
Fixed FormulaParser to allow negative elements in array literals.
authorJosh Micich <josh@apache.org>
Fri, 25 Dec 2009 23:26:47 +0000 (23:26 +0000)
committerJosh Micich <josh@apache.org>
Fri, 25 Dec 2009 23:26:47 +0000 (23:26 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@893898 13f79535-47bb-0310-9956-ffa450edef68

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

index d7827b137cfb2ba0e9d97dd4b5d5021316aab06a..9e63e6f4b992a8a9b53d5ed7ca8e1f5375691211 100644 (file)
@@ -1209,9 +1209,13 @@ public final class FormulaParser {
                        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 @@ public final class FormulaParser {
                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() {
index 5891831cba503ebf9720b8cc74704fbd97e3c485..2d2784c2daeaccae2aaff2f4666893daa7f6d773 100644 (file)
@@ -871,6 +871,28 @@ public final class TestFormulaParser extends TestCase {
                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();