import java.util.List;
import java.util.regex.Pattern;
-import org.apache.poi.hssf.record.UnicodeString;
import org.apache.poi.hssf.record.constant.ErrorConstant;
import org.apache.poi.hssf.record.formula.*;
import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.CellReference.NameType;
-import org.apache.poi.ss.SpreadsheetVersion;
/**
* This class parses a formula string into a List of tokens in RPN order.
private Object parseArrayItem() {
SkipWhite();
switch(look) {
- case '"': return new UnicodeString(parseStringLiteral());
+ case '"': return parseStringLiteral();
case '#': return ErrorConstant.valueOf(parseErrorLiteral());
case 'F': case 'f':
case 'T': case 't':
package org.apache.poi.hssf.model;
+import java.util.Arrays;
+
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.record.UnicodeString;
import org.apache.poi.hssf.record.constant.ErrorConstant;
import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
import org.apache.poi.hssf.record.formula.AddPtg;
import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues;
import org.apache.poi.ss.usermodel.Name;
+import org.apache.poi.util.HexRead;
+import org.apache.poi.util.LittleEndianByteArrayInputStream;
/**
* Test the low level formula parser functionality. High level tests are to
Ptg[] ptgs;
ptgs = parseFormula("mode({1,2,2,#REF!;FALSE,3,3,2})");
confirmTokenClasses(ptgs, ArrayPtg.class, FuncVarPtg.class);
- assertEquals("{1.0,2.0,2.0,#REF!;FALSE,3.0,3.0,2.0}", ptgs[0].toFormulaString());
+ assertEquals("{1,2,2,#REF!;FALSE,3,3,2}", ptgs[0].toFormulaString());
ArrayPtg aptg = (ArrayPtg) ptgs[0];
Object[][] values = aptg.getTokenArrayValues();
assertEquals(Boolean.FALSE, values[1][0]);
}
+ public void testParseStringElementInArray() {
+ Ptg[] ptgs;
+ ptgs = parseFormula("MAX({\"5\"},3)");
+ confirmTokenClasses(ptgs, ArrayPtg.class, IntPtg.class, FuncVarPtg.class);
+ Object element = ((ArrayPtg)ptgs[0]).getTokenArrayValues()[0][0];
+ if (element instanceof UnicodeString) {
+ // this would cause ClassCastException below
+ throw new AssertionFailedError("Wrong encoding of array element value");
+ }
+ assertEquals(String.class, element.getClass());
+
+ // make sure the formula encodes OK
+ int encSize = Ptg.getEncodedSize(ptgs);
+ byte[] data = new byte[encSize];
+ Ptg.serializePtgs(ptgs, data, 0);
+ byte[] expData = HexRead.readFromString(
+ "20 00 00 00 00 00 00 00 " // tArray
+ + "1E 03 00 " // tInt(3)
+ + "42 02 07 00 " // tFuncVar(MAX) 2-arg
+ + "00 00 00 " // Array data: 1 col, 1 row
+ + "02 01 00 00 35" // elem (type=string, len=1, "5")
+ );
+ assertTrue(Arrays.equals(expData, data));
+ int initSize = Ptg.getEncodedSizeWithoutArrayData(ptgs);
+ Ptg[] ptgs2 = Ptg.readTokens(initSize, new LittleEndianByteArrayInputStream(data));
+ confirmTokenClasses(ptgs2, ArrayPtg.class, IntPtg.class, FuncVarPtg.class);
+ }
+
public void testRangeOperator() {
HSSFWorkbook wb = new HSSFWorkbook();
// The formula has an array with 3 rows and 5 columns
String formula = wb.getSheetAt(0).getRow(0).getCell(0).getCellFormula();
- // TODO - These number literals should not have '.0'. Excel has different number rendering rules
- if (formula.equals("SUM({1.0,6.0,11.0;2.0,7.0,12.0;3.0,8.0,13.0;4.0,9.0,14.0;5.0,10.0,15.0})")) {
+ if (formula.equals("SUM({1,6,11;2,7,12;3,8,13;4,9,14;5,10,15})")) {
throw new AssertionFailedError("Identified bug 42564 b");
}
- assertEquals("SUM({1.0,2.0,3.0,4.0,5.0;6.0,7.0,8.0,9.0,10.0;11.0,12.0,13.0,14.0,15.0})", formula);
+ assertEquals("SUM({1,2,3,4,5;6,7,8,9,10;11,12,13,14,15})", formula);
}
public void testToFormulaString() {
}
throw e;
}
- assertEquals("{TRUE,\"ABCD\",\"E\";0.0,FALSE,\"FG\"}", actualFormula);
+ assertEquals("{TRUE,\"ABCD\",\"E\";0,FALSE,\"FG\"}", actualFormula);
}
/**