From 8aa0c858c602a80fc359401d18d024239ebcfce5 Mon Sep 17 00:00:00 2001
From: Nick Burch The purpose of this document is to give a brief high level overview of the
HWPF document format. This document does not go into in-depth technical
- detail and is only meant as a supplement to the Microsoft Word 97 Binary
- File Format freely available at Wotsit.org.
The OLE file format is not discussed in this document. It is assumed that the reader has a working knowledge of the POIFS API.
diff --git a/src/documentation/content/xdocs/hwpf/index.xml b/src/documentation/content/xdocs/hwpf/index.xml index f5e8afb2da..c7f58122e3 100644 --- a/src/documentation/content/xdocs/hwpf/index.xml +++ b/src/documentation/content/xdocs/hwpf/index.xml @@ -87,7 +87,7 @@When you start start coding, you will not yet have write access to the +
When you start coding, you will not yet have write access to the
CVS repository. Please submit your patches to Bugzilla and nag Rainer Klute until he commits
diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml
index d29d57ff8d..6b55026c78 100644
--- a/src/documentation/content/xdocs/status.xml
+++ b/src/documentation/content/xdocs/status.xml
@@ -33,6 +33,7 @@
+ * To create a new Conditional Formatting set use the following approach:
+ *
+ *
- * TODO: MODE , this is only row specific
- * @param startRow
- * @param endRow
- * @param n
- * @param isRow
- */
- protected void shiftMerged(int startRow, int endRow, int n, boolean isRow) {
- List shiftedRegions = new ArrayList();
- //move merged regions completely if they fall within the new region boundaries when they are shifted
- for (int i = 0; i < this.getNumMergedRegions(); i++) {
- Region merged = this.getMergedRegionAt(i);
+ /**
+ * Shifts the merged regions left or right depending on mode
+ *
+ * TODO: MODE , this is only row specific
+ * @param startRow
+ * @param endRow
+ * @param n
+ * @param isRow
+ */
+ protected void shiftMerged(int startRow, int endRow, int n, boolean isRow) {
+ List shiftedRegions = new ArrayList();
+ //move merged regions completely if they fall within the new region boundaries when they are shifted
+ for (int i = 0; i < this.getNumMergedRegions(); i++) {
+ Region merged = this.getMergedRegionAt(i);
- boolean inStart = (merged.getRowFrom() >= startRow || merged.getRowTo() >= startRow);
- boolean inEnd = (merged.getRowTo() <= endRow || merged.getRowFrom() <= endRow);
+ boolean inStart = (merged.getRowFrom() >= startRow || merged.getRowTo() >= startRow);
+ boolean inEnd = (merged.getRowTo() <= endRow || merged.getRowFrom() <= endRow);
- //dont check if it's not within the shifted area
- if (! (inStart && inEnd)) continue;
+ //dont check if it's not within the shifted area
+ if (! (inStart && inEnd)) continue;
- //only shift if the region outside the shifted rows is not merged too
- if (!merged.contains(startRow-1, (short)0) && !merged.contains(endRow+1, (short)0)){
- merged.setRowFrom(merged.getRowFrom()+n);
- merged.setRowTo(merged.getRowTo()+n);
- //have to remove/add it back
- shiftedRegions.add(merged);
- this.removeMergedRegion(i);
- i = i -1; // we have to back up now since we removed one
+ //only shift if the region outside the shifted rows is not merged too
+ if (!merged.contains(startRow-1, (short)0) && !merged.contains(endRow+1, (short)0)){
+ merged.setRowFrom(merged.getRowFrom()+n);
+ merged.setRowTo(merged.getRowTo()+n);
+ //have to remove/add it back
+ shiftedRegions.add(merged);
+ this.removeMergedRegion(i);
+ i = i -1; // we have to back up now since we removed one
- }
+ }
- }
+ }
- //readd so it doesn't get shifted again
- Iterator iterator = shiftedRegions.iterator();
- while (iterator.hasNext()) {
- Region region = (Region)iterator.next();
+ //readd so it doesn't get shifted again
+ Iterator iterator = shiftedRegions.iterator();
+ while (iterator.hasNext()) {
+ Region region = (Region)iterator.next();
- this.addMergedRegion(region);
- }
+ this.addMergedRegion(region);
+ }
- }
+ }
/**
* Shifts rows between startRow and endRow n number of rows.
@@ -1174,7 +1169,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
* @param n the number of rows to shift
*/
public void shiftRows( int startRow, int endRow, int n ) {
- shiftRows(startRow, endRow, n, false, false);
+ shiftRows(startRow, endRow, n, false, false);
}
/**
@@ -1211,7 +1206,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
shiftMerged(startRow, endRow, n, true);
sheet.shiftRowBreaks(startRow, endRow, n);
-
+
for ( int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum < 65536; rowNum += inc )
{
HSSFRow row = getRow( rowNum );
@@ -1224,23 +1219,23 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
- // Removes the cells before over writting them.
+ // Removes the cells before over writting them.
for ( short col = row2Replace.getFirstCellNum(); col <= row2Replace.getLastCellNum(); col++ )
{
cell = row2Replace.getCell( col );
if ( cell != null )
row2Replace.removeCell( cell );
}
- if (row == null) continue; // Nothing to do for this row
- else {
- if (copyRowHeight) {
- row2Replace.setHeight(row.getHeight());
- }
+ if (row == null) continue; // Nothing to do for this row
+ else {
+ if (copyRowHeight) {
+ row2Replace.setHeight(row.getHeight());
+ }
- if (resetOriginalRowHeight) {
- row.setHeight((short)0xff);
- }
- }
+ if (resetOriginalRowHeight) {
+ row.setHeight((short)0xff);
+ }
+ }
for ( short col = row.getFirstCellNum(); col <= row.getLastCellNum(); col++ )
{
cell = row.getCell( col );
@@ -1262,55 +1257,55 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
}
if ( endRow == lastrow || endRow + n > lastrow ) lastrow = Math.min( endRow + n, 65535 );
if ( startRow == firstrow || startRow + n < firstrow ) firstrow = Math.max( startRow + n, 0 );
-
+
// Update any formulas on this sheet that point to
// rows which have been moved
updateFormulasAfterShift(startRow, endRow, n);
}
-
+
/**
* Called by shiftRows to update formulas on this sheet
* to point to the new location of moved rows
*/
private void updateFormulasAfterShift(int startRow, int endRow, int n) {
- // Need to look at every cell on the sheet
- // Not just those that were moved
+ // Need to look at every cell on the sheet
+ // Not just those that were moved
Iterator ri = rowIterator();
while(ri.hasNext()) {
- HSSFRow r = (HSSFRow)ri.next();
- Iterator ci = r.cellIterator();
- while(ci.hasNext()) {
- HSSFCell c = (HSSFCell)ci.next();
- if(c.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
- // Since it's a formula cell, process the
- // formula string, and look to see if
- // it contains any references
- FormulaParser fp = new FormulaParser(c.getCellFormula(), workbook.getWorkbook());
- fp.parse();
-
- // Look for references, and update if needed
- Ptg[] ptgs = fp.getRPNPtg();
- boolean changed = false;
- for(int i=0; i
- * true
, this denotes the 'StdDocumentName'
+ */
+ public boolean isStdDocumentNameIdentifier() {
+ return (field_1_option_flag & OPT_STD_DOCUMENT_NAME) != 0;
+ }
+ public boolean isOLELink() {
+ return (field_1_option_flag & OPT_OLE_LINK) != 0;
+ }
+ public boolean isIconifiedPictureLink() {
+ return (field_1_option_flag & OPT_ICONIFIED_PICTURE_LINK) != 0;
+ }
+ /**
+ * @return the standard String representation of this name
+ */
+ public String getText() {
+ return field_4_name;
}
- /**
- * For OLE and DDE, links can be either 'automatic' or 'manual'
- */
- public boolean isAutomaticLink() {
- return (field_1_option_flag & OPT_AUTOMATIC_LINK) != 0;
- }
- /**
- * only for OLE and DDE
- */
- public boolean isPicureLink() {
- return (field_1_option_flag & OPT_PICTURE_LINK) != 0;
- }
- /**
- * DDE links only. If true
, this denotes the 'StdDocumentName'
- */
- public boolean isStdDocumentNameIdentifier() {
- return (field_1_option_flag & OPT_STD_DOCUMENT_NAME) != 0;
- }
- public boolean isOLELink() {
- return (field_1_option_flag & OPT_OLE_LINK) != 0;
- }
- public boolean isIconifiedPictureLink() {
- return (field_1_option_flag & OPT_ICONIFIED_PICTURE_LINK) != 0;
- }
- /**
- * @return the standard String representation of this name
- */
- public String getText() {
- return field_4_name;
- }
- /**
- * called by constructor, should throw runtime exception in the event of a
- * record passed with a differing ID.
- *
- * @param id alleged id for this record
- */
- protected void validateSid(short id) {
- if (id != sid) {
- throw new RecordFormatException("NOT A valid ExternalName RECORD");
- }
- }
+ /**
+ * called by constructor, should throw runtime exception in the event of a
+ * record passed with a differing ID.
+ *
+ * @param id alleged id for this record
+ */
+ protected void validateSid(short id) {
+ if (id != sid) {
+ throw new RecordFormatException("NOT A valid ExternalName RECORD");
+ }
+ }
- private int getDataSize(){
- return 2 + 2 + field_4_name.length() + 2 + getNameDefinitionSize();
- }
+ private int getDataSize(){
+ return 3 * 2 // 3 short fields
+ + 2 + field_4_name.length() // nameLen and name
+ + 2 + getNameDefinitionSize(); // nameDefLen and nameDef
+ }
- /**
- * called by the class that is responsible for writing this sucker.
- * Subclasses should implement this so that their data is passed back in a
- * byte array.
- *
- * @param offset to begin writing at
- * @param data byte array containing instance data
- * @return number of bytes written
- */
- public int serialize( int offset, byte[] data ) {
- // TODO - junit tests
- int dataSize = getDataSize();
+ /**
+ * called by the class that is responsible for writing this sucker.
+ * Subclasses should implement this so that their data is passed back in a
+ * byte array.
+ *
+ * @param offset to begin writing at
+ * @param data byte array containing instance data
+ * @return number of bytes written
+ */
+ public int serialize( int offset, byte[] data ) {
+ int dataSize = getDataSize();
- LittleEndian.putShort( data, 0 + offset, sid );
+ LittleEndian.putShort( data, 0 + offset, sid );
LittleEndian.putShort( data, 2 + offset, (short) dataSize );
- LittleEndian.putShort( data, 4 + offset, field_1_option_flag );
- LittleEndian.putShort( data, 6 + offset, field_2_index );
- LittleEndian.putShort( data, 8 + offset, field_3_not_used );
- short nameLen = (short) field_4_name.length();
+ LittleEndian.putShort( data, 4 + offset, field_1_option_flag );
+ LittleEndian.putShort( data, 6 + offset, field_2_index );
+ LittleEndian.putShort( data, 8 + offset, field_3_not_used );
+ short nameLen = (short) field_4_name.length();
LittleEndian.putShort( data, 10 + offset, nameLen );
- StringUtil.putCompressedUnicode( field_4_name, data, 10 + offset );
- short defLen = (short) getNameDefinitionSize();
- LittleEndian.putShort( data, 12 + nameLen + offset, defLen );
- Ptg.serializePtgStack(field_5_name_definition, data, 12 + nameLen + offset );
+ StringUtil.putCompressedUnicode( field_4_name, data, 12 + offset );
+ short defLen = (short) getNameDefinitionSize();
+ LittleEndian.putShort( data, 12 + nameLen + offset, defLen );
+ Ptg.serializePtgStack(toStack(field_5_name_definition), data, 14 + nameLen + offset );
return dataSize + 4;
- }
+ }
- private int getNameDefinitionSize() {
- int result = 0;
- List list = field_5_name_definition;
-
- for (int k = 0; k < list.size(); k++)
- {
- Ptg ptg = ( Ptg ) list.get(k);
-
- result += ptg.getSize();
- }
- return result;
- }
+ private int getNameDefinitionSize() {
+ int result = 0;
+ for (int i = 0; i < field_5_name_definition.length; i++) {
+ result += field_5_name_definition[i].getSize();
+ }
+ return result;
+ }
- public int getRecordSize(){
- return 6 + 2 + field_4_name.length() + 2 + getNameDefinitionSize();
- }
+ public int getRecordSize(){
+ return 4 + getDataSize();
+ }
- protected void fillFields(RecordInputStream in) {
- field_1_option_flag = in.readShort();
- field_2_index = in.readShort();
- field_3_not_used = in.readShort();
- short nameLength = in.readShort();
- field_4_name = in.readCompressedUnicode(nameLength);
- short formulaLen = in.readShort();
- field_5_name_definition = Ptg.createParsedExpressionTokens(formulaLen, in);
- }
+ protected void fillFields(RecordInputStream in) {
+ field_1_option_flag = in.readShort();
+ field_2_index = in.readShort();
+ field_3_not_used = in.readShort();
+ short nameLength = in.readShort();
+ field_4_name = in.readCompressedUnicode(nameLength);
+ short formulaLen = in.readShort();
+ field_5_name_definition = toPtgArray(Ptg.createParsedExpressionTokens(formulaLen, in));
+ }
- public short getSid() {
- return sid;
- }
+ private static Ptg[] toPtgArray(Stack s) {
+ Ptg[] result = new Ptg[s.size()];
+ s.toArray(result);
+ return result;
+ }
+ private static Stack toStack(Ptg[] ptgs) {
+ Stack result = new Stack();
+ for (int i = 0; i < ptgs.length; i++) {
+ result.push(ptgs[i]);
+ }
+ return result;
+ }
+
+ public short getSid() {
+ return sid;
+ }
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append(getClass().getName()).append(" [EXTERNALNAME ");
- sb.append(" ").append(field_4_name);
- sb.append(" ix=").append(field_2_index);
- sb.append("]");
- return sb.toString();
- }
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName()).append(" [EXTERNALNAME ");
+ sb.append(" ").append(field_4_name);
+ sb.append(" ix=").append(field_2_index);
+ sb.append("]");
+ return sb.toString();
+ }
}
diff --git a/src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java
index 78d1ecbd33..d6e81c7ea2 100644
--- a/src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java
+++ b/src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java
@@ -35,54 +35,55 @@ import org.apache.poi.util.POILogger;
* @author Dmitriy Kumshayev
*
*/
-public class CFRecordsAggregate extends Record
+public final class CFRecordsAggregate extends Record
{
- public final static short sid = -2008;
+ public final static short sid = -2008; // not a real BIFF record
- private static POILogger log = POILogFactory.getLogger(CFRecordsAggregate.class);
-
- private CFHeaderRecord header;
+ private static POILogger log = POILogFactory.getLogger(CFRecordsAggregate.class);
+
+ private CFHeaderRecord header;
+
+ // List of CFRuleRecord objects
+ private final List rules;
+
+ public CFRecordsAggregate()
+ {
+ header = null;
+ rules = new ArrayList(3);
+ }
+
+ /**
+ * Create CFRecordsAggregate from a list of CF Records
+ * @param recs - list of {@link Record} objects
+ * @param offset - position of {@link CFHeaderRecord} object in the list of Record objects
+ * @return CFRecordsAggregate object
+ */
+ public static CFRecordsAggregate createCFAggregate(List recs, int pOffset)
+ {
+
+ int offset = pOffset;
+ CFRecordsAggregate cfRecords = new CFRecordsAggregate();
+ ArrayList records = new ArrayList(4);
+
+ Record rec = ( Record ) recs.get(offset++);
+
+ if (rec.getSid() == CFHeaderRecord.sid)
+ {
+ records.add(rec);
+ cfRecords.header = (CFHeaderRecord)rec;
+
+ int nRules = cfRecords.header.getNumberOfConditionalFormats();
+ int rulesCount = 0;
+ while( offsetfalse
if the name should be assumed to be an external function.
*/
public static final boolean isInternalFunctionName(String name) {
- return map.containsValue(name.toUpperCase());
+ short ix = FunctionMetadataRegistry.lookupIndexByName(name.toUpperCase());
+ return ix >= 0;
}
protected String lookupName(short index) {
- return ((String)map.get(new Integer(index)));
+ if(index == FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL) {
+ return "#external#";
+ }
+ FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(index);
+ if(fm == null) {
+ throw new RuntimeException("bad function index (" + index + ")");
+ }
+ return fm.getName();
}
/**
@@ -131,729 +135,11 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
* @return the standard worksheet function index if found, otherwise FUNCTION_INDEX_EXTERNAL
*/
protected static short lookupIndex(String name) {
- Integer index = (Integer) map.getKeyForValue(name.toUpperCase());
- if (index != null) return index.shortValue();
- return FUNCTION_INDEX_EXTERNAL;
- }
-
- /**
- * Produces the function table hashmap
- */
- private static BinaryTree produceHash() {
- BinaryTree dmap = new BinaryTree();
-
- dmap.put(new Integer(0),"COUNT");
- dmap.put(new Integer(1),FUNCTION_NAME_IF);
- dmap.put(new Integer(2),"ISNA");
- dmap.put(new Integer(3),"ISERROR");
- dmap.put(new Integer(4),"SUM");
- dmap.put(new Integer(5),"AVERAGE");
- dmap.put(new Integer(6),"MIN");
- dmap.put(new Integer(7),"MAX");
- dmap.put(new Integer(8),"ROW");
- dmap.put(new Integer(9),"COLUMN");
- dmap.put(new Integer(10),"NA");
- dmap.put(new Integer(11),"NPV");
- dmap.put(new Integer(12),"STDEV");
- dmap.put(new Integer(13),"DOLLAR");
- dmap.put(new Integer(14),"FIXED");
- dmap.put(new Integer(15),"SIN");
- dmap.put(new Integer(16),"COS");
- dmap.put(new Integer(17),"TAN");
- dmap.put(new Integer(18),"ATAN");
- dmap.put(new Integer(19),"PI");
- dmap.put(new Integer(20),"SQRT");
- dmap.put(new Integer(21),"EXP");
- dmap.put(new Integer(22),"LN");
- dmap.put(new Integer(23),"LOG10");
- dmap.put(new Integer(24),"ABS");
- dmap.put(new Integer(25),"INT");
- dmap.put(new Integer(26),"SIGN");
- dmap.put(new Integer(27),"ROUND");
- dmap.put(new Integer(28),"LOOKUP");
- dmap.put(new Integer(29),"INDEX");
- dmap.put(new Integer(30),"REPT");
- dmap.put(new Integer(31),"MID");
- dmap.put(new Integer(32),"LEN");
- dmap.put(new Integer(33),"VALUE");
- dmap.put(new Integer(34),"TRUE");
- dmap.put(new Integer(35),"FALSE");
- dmap.put(new Integer(36),"AND");
- dmap.put(new Integer(37),"OR");
- dmap.put(new Integer(38),"NOT");
- dmap.put(new Integer(39),"MOD");
- dmap.put(new Integer(40),"DCOUNT");
- dmap.put(new Integer(41),"DSUM");
- dmap.put(new Integer(42),"DAVERAGE");
- dmap.put(new Integer(43),"DMIN");
- dmap.put(new Integer(44),"DMAX");
- dmap.put(new Integer(45),"DSTDEV");
- dmap.put(new Integer(46),"VAR");
- dmap.put(new Integer(47),"DVAR");
- dmap.put(new Integer(48),"TEXT");
- dmap.put(new Integer(49),"LINEST");
- dmap.put(new Integer(50),"TREND");
- dmap.put(new Integer(51),"LOGEST");
- dmap.put(new Integer(52),"GROWTH");
- dmap.put(new Integer(53),"GOTO");
- dmap.put(new Integer(54),"HALT");
- dmap.put(new Integer(56),"PV");
- dmap.put(new Integer(57),"FV");
- dmap.put(new Integer(58),"NPER");
- dmap.put(new Integer(59),"PMT");
- dmap.put(new Integer(60),"RATE");
- dmap.put(new Integer(61),"MIRR");
- dmap.put(new Integer(62),"IRR");
- dmap.put(new Integer(63),"RAND");
- dmap.put(new Integer(64),"MATCH");
- dmap.put(new Integer(65),"DATE");
- dmap.put(new Integer(66),"TIME");
- dmap.put(new Integer(67),"DAY");
- dmap.put(new Integer(68),"MONTH");
- dmap.put(new Integer(69),"YEAR");
- dmap.put(new Integer(70),"WEEKDAY");
- dmap.put(new Integer(71),"HOUR");
- dmap.put(new Integer(72),"MINUTE");
- dmap.put(new Integer(73),"SECOND");
- dmap.put(new Integer(74),"NOW");
- dmap.put(new Integer(75),"AREAS");
- dmap.put(new Integer(76),"ROWS");
- dmap.put(new Integer(77),"COLUMNS");
- dmap.put(new Integer(78),"OFFSET");
- dmap.put(new Integer(79),"ABSREF");
- dmap.put(new Integer(80),"RELREF");
- dmap.put(new Integer(81),"ARGUMENT");
- dmap.put(new Integer(82),"SEARCH");
- dmap.put(new Integer(83),"TRANSPOSE");
- dmap.put(new Integer(84),"ERROR");
- dmap.put(new Integer(85),"STEP");
- dmap.put(new Integer(86),"TYPE");
- dmap.put(new Integer(87),"ECHO");
- dmap.put(new Integer(88),"SETNAME");
- dmap.put(new Integer(89),"CALLER");
- dmap.put(new Integer(90),"DEREF");
- dmap.put(new Integer(91),"WINDOWS");
- dmap.put(new Integer(92),"SERIES");
- dmap.put(new Integer(93),"DOCUMENTS");
- dmap.put(new Integer(94),"ACTIVECELL");
- dmap.put(new Integer(95),"SELECTION");
- dmap.put(new Integer(96),"RESULT");
- dmap.put(new Integer(97),"ATAN2");
- dmap.put(new Integer(98),"ASIN");
- dmap.put(new Integer(99),"ACOS");
- dmap.put(new Integer(100),"CHOOSE");
- dmap.put(new Integer(101),"HLOOKUP");
- dmap.put(new Integer(102),"VLOOKUP");
- dmap.put(new Integer(103),"LINKS");
- dmap.put(new Integer(104),"INPUT");
- dmap.put(new Integer(105),"ISREF");
- dmap.put(new Integer(106),"GETFORMULA");
- dmap.put(new Integer(107),"GETNAME");
- dmap.put(new Integer(108),"SETVALUE");
- dmap.put(new Integer(109),"LOG");
- dmap.put(new Integer(110),"EXEC");
- dmap.put(new Integer(111),"CHAR");
- dmap.put(new Integer(112),"LOWER");
- dmap.put(new Integer(113),"UPPER");
- dmap.put(new Integer(114),"PROPER");
- dmap.put(new Integer(115),"LEFT");
- dmap.put(new Integer(116),"RIGHT");
- dmap.put(new Integer(117),"EXACT");
- dmap.put(new Integer(118),"TRIM");
- dmap.put(new Integer(119),"REPLACE");
- dmap.put(new Integer(120),"SUBSTITUTE");
- dmap.put(new Integer(121),"CODE");
- dmap.put(new Integer(122),"NAMES");
- dmap.put(new Integer(123),"DIRECTORY");
- dmap.put(new Integer(124),"FIND");
- dmap.put(new Integer(125),"CELL");
- dmap.put(new Integer(126),"ISERR");
- dmap.put(new Integer(127),"ISTEXT");
- dmap.put(new Integer(128),"ISNUMBER");
- dmap.put(new Integer(129),"ISBLANK");
- dmap.put(new Integer(130),"T");
- dmap.put(new Integer(131),"N");
- dmap.put(new Integer(132),"FOPEN");
- dmap.put(new Integer(133),"FCLOSE");
- dmap.put(new Integer(134),"FSIZE");
- dmap.put(new Integer(135),"FREADLN");
- dmap.put(new Integer(136),"FREAD");
- dmap.put(new Integer(137),"FWRITELN");
- dmap.put(new Integer(138),"FWRITE");
- dmap.put(new Integer(139),"FPOS");
- dmap.put(new Integer(140),"DATEVALUE");
- dmap.put(new Integer(141),"TIMEVALUE");
- dmap.put(new Integer(142),"SLN");
- dmap.put(new Integer(143),"SYD");
- dmap.put(new Integer(144),"DDB");
- dmap.put(new Integer(145),"GETDEF");
- dmap.put(new Integer(146),"REFTEXT");
- dmap.put(new Integer(147),"TEXTREF");
- dmap.put(new Integer(148),"INDIRECT");
- dmap.put(new Integer(149),"REGISTER");
- dmap.put(new Integer(150),"CALL");
- dmap.put(new Integer(151),"ADDBAR");
- dmap.put(new Integer(152),"ADDMENU");
- dmap.put(new Integer(153),"ADDCOMMAND");
- dmap.put(new Integer(154),"ENABLECOMMAND");
- dmap.put(new Integer(155),"CHECKCOMMAND");
- dmap.put(new Integer(156),"RENAMECOMMAND");
- dmap.put(new Integer(157),"SHOWBAR");
- dmap.put(new Integer(158),"DELETEMENU");
- dmap.put(new Integer(159),"DELETECOMMAND");
- dmap.put(new Integer(160),"GETCHARTITEM");
- dmap.put(new Integer(161),"DIALOGBOX");
- dmap.put(new Integer(162),"CLEAN");
- dmap.put(new Integer(163),"MDETERM");
- dmap.put(new Integer(164),"MINVERSE");
- dmap.put(new Integer(165),"MMULT");
- dmap.put(new Integer(166),"FILES");
- dmap.put(new Integer(167),"IPMT");
- dmap.put(new Integer(168),"PPMT");
- dmap.put(new Integer(169),"COUNTA");
- dmap.put(new Integer(170),"CANCELKEY");
- dmap.put(new Integer(175),"INITIATE");
- dmap.put(new Integer(176),"REQUEST");
- dmap.put(new Integer(177),"POKE");
- dmap.put(new Integer(178),"EXECUTE");
- dmap.put(new Integer(179),"TERMINATE");
- dmap.put(new Integer(180),"RESTART");
- dmap.put(new Integer(181),"HELP");
- dmap.put(new Integer(182),"GETBAR");
- dmap.put(new Integer(183),"PRODUCT");
- dmap.put(new Integer(184),"FACT");
- dmap.put(new Integer(185),"GETCELL");
- dmap.put(new Integer(186),"GETWORKSPACE");
- dmap.put(new Integer(187),"GETWINDOW");
- dmap.put(new Integer(188),"GETDOCUMENT");
- dmap.put(new Integer(189),"DPRODUCT");
- dmap.put(new Integer(190),"ISNONTEXT");
- dmap.put(new Integer(191),"GETNOTE");
- dmap.put(new Integer(192),"NOTE");
- dmap.put(new Integer(193),"STDEVP");
- dmap.put(new Integer(194),"VARP");
- dmap.put(new Integer(195),"DSTDEVP");
- dmap.put(new Integer(196),"DVARP");
- dmap.put(new Integer(197),"TRUNC");
- dmap.put(new Integer(198),"ISLOGICAL");
- dmap.put(new Integer(199),"DCOUNTA");
- dmap.put(new Integer(200),"DELETEBAR");
- dmap.put(new Integer(201),"UNREGISTER");
- dmap.put(new Integer(204),"USDOLLAR");
- dmap.put(new Integer(205),"FINDB");
- dmap.put(new Integer(206),"SEARCHB");
- dmap.put(new Integer(207),"REPLACEB");
- dmap.put(new Integer(208),"LEFTB");
- dmap.put(new Integer(209),"RIGHTB");
- dmap.put(new Integer(210),"MIDB");
- dmap.put(new Integer(211),"LENB");
- dmap.put(new Integer(212),"ROUNDUP");
- dmap.put(new Integer(213),"ROUNDDOWN");
- dmap.put(new Integer(214),"ASC");
- dmap.put(new Integer(215),"DBCS");
- dmap.put(new Integer(216),"RANK");
- dmap.put(new Integer(219),"ADDRESS");
- dmap.put(new Integer(220),"DAYS360");
- dmap.put(new Integer(221),"TODAY");
- dmap.put(new Integer(222),"VDB");
- dmap.put(new Integer(227),"MEDIAN");
- dmap.put(new Integer(228),"SUMPRODUCT");
- dmap.put(new Integer(229),"SINH");
- dmap.put(new Integer(230),"COSH");
- dmap.put(new Integer(231),"TANH");
- dmap.put(new Integer(232),"ASINH");
- dmap.put(new Integer(233),"ACOSH");
- dmap.put(new Integer(234),"ATANH");
- dmap.put(new Integer(235),"DGET");
- dmap.put(new Integer(236),"CREATEOBJECT");
- dmap.put(new Integer(237),"VOLATILE");
- dmap.put(new Integer(238),"LASTERROR");
- dmap.put(new Integer(239),"CUSTOMUNDO");
- dmap.put(new Integer(240),"CUSTOMREPEAT");
- dmap.put(new Integer(241),"FORMULACONVERT");
- dmap.put(new Integer(242),"GETLINKINFO");
- dmap.put(new Integer(243),"TEXTBOX");
- dmap.put(new Integer(244),"INFO");
- dmap.put(new Integer(245),"GROUP");
- dmap.put(new Integer(246),"GETOBJECT");
- dmap.put(new Integer(247),"DB");
- dmap.put(new Integer(248),"PAUSE");
- dmap.put(new Integer(250),"RESUME");
- dmap.put(new Integer(252),"FREQUENCY");
- dmap.put(new Integer(253),"ADDTOOLBAR");
- dmap.put(new Integer(254),"DELETETOOLBAR");
- dmap.put(new Integer(FUNCTION_INDEX_EXTERNAL),"externalflag");
- dmap.put(new Integer(256),"RESETTOOLBAR");
- dmap.put(new Integer(257),"EVALUATE");
- dmap.put(new Integer(258),"GETTOOLBAR");
- dmap.put(new Integer(259),"GETTOOL");
- dmap.put(new Integer(260),"SPELLINGCHECK");
- dmap.put(new Integer(261),"ERROR.TYPE");
- dmap.put(new Integer(262),"APPTITLE");
- dmap.put(new Integer(263),"WINDOWTITLE");
- dmap.put(new Integer(264),"SAVETOOLBAR");
- dmap.put(new Integer(265),"ENABLETOOL");
- dmap.put(new Integer(266),"PRESSTOOL");
- dmap.put(new Integer(267),"REGISTERID");
- dmap.put(new Integer(268),"GETWORKBOOK");
- dmap.put(new Integer(269),"AVEDEV");
- dmap.put(new Integer(270),"BETADIST");
- dmap.put(new Integer(271),"GAMMALN");
- dmap.put(new Integer(272),"BETAINV");
- dmap.put(new Integer(273),"BINOMDIST");
- dmap.put(new Integer(274),"CHIDIST");
- dmap.put(new Integer(275),"CHIINV");
- dmap.put(new Integer(276),"COMBIN");
- dmap.put(new Integer(277),"CONFIDENCE");
- dmap.put(new Integer(278),"CRITBINOM");
- dmap.put(new Integer(279),"EVEN");
- dmap.put(new Integer(280),"EXPONDIST");
- dmap.put(new Integer(281),"FDIST");
- dmap.put(new Integer(282),"FINV");
- dmap.put(new Integer(283),"FISHER");
- dmap.put(new Integer(284),"FISHERINV");
- dmap.put(new Integer(285),"FLOOR");
- dmap.put(new Integer(286),"GAMMADIST");
- dmap.put(new Integer(287),"GAMMAINV");
- dmap.put(new Integer(288),"CEILING");
- dmap.put(new Integer(289),"HYPGEOMDIST");
- dmap.put(new Integer(290),"LOGNORMDIST");
- dmap.put(new Integer(291),"LOGINV");
- dmap.put(new Integer(292),"NEGBINOMDIST");
- dmap.put(new Integer(293),"NORMDIST");
- dmap.put(new Integer(294),"NORMSDIST");
- dmap.put(new Integer(295),"NORMINV");
- dmap.put(new Integer(296),"NORMSINV");
- dmap.put(new Integer(297),"STANDARDIZE");
- dmap.put(new Integer(298),"ODD");
- dmap.put(new Integer(299),"PERMUT");
- dmap.put(new Integer(300),"POISSON");
- dmap.put(new Integer(301),"TDIST");
- dmap.put(new Integer(302),"WEIBULL");
- dmap.put(new Integer(303),"SUMXMY2");
- dmap.put(new Integer(304),"SUMX2MY2");
- dmap.put(new Integer(305),"SUMX2PY2");
- dmap.put(new Integer(306),"CHITEST");
- dmap.put(new Integer(307),"CORREL");
- dmap.put(new Integer(308),"COVAR");
- dmap.put(new Integer(309),"FORECAST");
- dmap.put(new Integer(310),"FTEST");
- dmap.put(new Integer(311),"INTERCEPT");
- dmap.put(new Integer(312),"PEARSON");
- dmap.put(new Integer(313),"RSQ");
- dmap.put(new Integer(314),"STEYX");
- dmap.put(new Integer(315),"SLOPE");
- dmap.put(new Integer(316),"TTEST");
- dmap.put(new Integer(317),"PROB");
- dmap.put(new Integer(318),"DEVSQ");
- dmap.put(new Integer(319),"GEOMEAN");
- dmap.put(new Integer(320),"HARMEAN");
- dmap.put(new Integer(321),"SUMSQ");
- dmap.put(new Integer(322),"KURT");
- dmap.put(new Integer(323),"SKEW");
- dmap.put(new Integer(324),"ZTEST");
- dmap.put(new Integer(325),"LARGE");
- dmap.put(new Integer(326),"SMALL");
- dmap.put(new Integer(327),"QUARTILE");
- dmap.put(new Integer(328),"PERCENTILE");
- dmap.put(new Integer(329),"PERCENTRANK");
- dmap.put(new Integer(330),"MODE");
- dmap.put(new Integer(331),"TRIMMEAN");
- dmap.put(new Integer(332),"TINV");
- dmap.put(new Integer(334),"MOVIECOMMAND");
- dmap.put(new Integer(335),"GETMOVIE");
- dmap.put(new Integer(336),"CONCATENATE");
- dmap.put(new Integer(337),"POWER");
- dmap.put(new Integer(338),"PIVOTADDDATA");
- dmap.put(new Integer(339),"GETPIVOTTABLE");
- dmap.put(new Integer(340),"GETPIVOTFIELD");
- dmap.put(new Integer(341),"GETPIVOTITEM");
- dmap.put(new Integer(342),"RADIANS");
- dmap.put(new Integer(343),"DEGREES");
- dmap.put(new Integer(344),"SUBTOTAL");
- dmap.put(new Integer(345),"SUMIF");
- dmap.put(new Integer(346),"COUNTIF");
- dmap.put(new Integer(347),"COUNTBLANK");
- dmap.put(new Integer(348),"SCENARIOGET");
- dmap.put(new Integer(349),"OPTIONSLISTSGET");
- dmap.put(new Integer(350),"ISPMT");
- dmap.put(new Integer(351),"DATEDIF");
- dmap.put(new Integer(352),"DATESTRING");
- dmap.put(new Integer(353),"NUMBERSTRING");
- dmap.put(new Integer(354),"ROMAN");
- dmap.put(new Integer(355),"OPENDIALOG");
- dmap.put(new Integer(356),"SAVEDIALOG");
- dmap.put(new Integer(357),"VIEWGET");
- dmap.put(new Integer(358),"GETPIVOTDATA");
- dmap.put(new Integer(359),"HYPERLINK");
- dmap.put(new Integer(360),"PHONETIC");
- dmap.put(new Integer(361),"AVERAGEA");
- dmap.put(new Integer(362),"MAXA");
- dmap.put(new Integer(363),"MINA");
- dmap.put(new Integer(364),"STDEVPA");
- dmap.put(new Integer(365),"VARPA");
- dmap.put(new Integer(366),"STDEVA");
- dmap.put(new Integer(367),"VARA");
-
- return dmap;
- }
-
- private static Object[][] produceFunctionData() {
- Object [][] functionData = new Object[368][3];
- //return Class // Param Class //Num Params
- functionData[0][0]=new Byte(Ptg.CLASS_VALUE);functionData[0][1]=new byte[] {Ptg.CLASS_REF};functionData[0][2]=new Integer(-1);
- functionData[2][0]=new Byte(Ptg.CLASS_VALUE);functionData[2][1]=new byte[] {Ptg.CLASS_VALUE};functionData[2][2]=new Integer(1);
- functionData[3][0]=new Byte(Ptg.CLASS_VALUE);functionData[3][1]=new byte[] {Ptg.CLASS_VALUE};functionData[3][2]=new Integer(1);
- functionData[4][0]=new Byte(Ptg.CLASS_VALUE);functionData[4][1]=new byte[] {Ptg.CLASS_REF};functionData[4][2]=new Integer(-1);
- functionData[5][0]=new Byte(Ptg.CLASS_VALUE);functionData[5][1]=new byte[] {Ptg.CLASS_REF};functionData[5][2]=new Integer(-1);
- functionData[6][0]=new Byte(Ptg.CLASS_VALUE);functionData[6][1]=new byte[] {Ptg.CLASS_REF};functionData[6][2]=new Integer(-1);
- functionData[7][0]=new Byte(Ptg.CLASS_VALUE);functionData[7][1]=new byte[] {Ptg.CLASS_REF};functionData[7][2]=new Integer(-1);
- functionData[8][0]=new Byte(Ptg.CLASS_VALUE);functionData[8][1]=new byte[] {Ptg.CLASS_REF};functionData[8][2]=new Integer(-1);
- functionData[9][0]=new Byte(Ptg.CLASS_VALUE);functionData[9][1]=new byte[] {Ptg.CLASS_REF};functionData[9][2]=new Integer(-1);
- functionData[10][0]=new Byte(Ptg.CLASS_VALUE);functionData[10][1]=new byte[] {Ptg.CLASS_VALUE};functionData[10][2]=new Integer(0);
- functionData[11][0]=new Byte(Ptg.CLASS_VALUE);functionData[11][1]=new byte[] {Ptg.CLASS_REF};functionData[11][2]=new Integer(-1);
- functionData[12][0]=new Byte(Ptg.CLASS_VALUE);functionData[12][1]=new byte[] {Ptg.CLASS_REF};functionData[12][2]=new Integer(-1);
- functionData[13][0]=new Byte(Ptg.CLASS_VALUE);functionData[13][1]=new byte[] {Ptg.CLASS_VALUE};functionData[13][2]=new Integer(-1);
- functionData[14][0]=new Byte(Ptg.CLASS_VALUE);functionData[14][1]=new byte[] {Ptg.CLASS_VALUE};functionData[14][2]=new Integer(-1);
- functionData[15][0]=new Byte(Ptg.CLASS_VALUE);functionData[15][1]=new byte[] {Ptg.CLASS_VALUE};functionData[15][2]=new Integer(1);
- functionData[16][0]=new Byte(Ptg.CLASS_VALUE);functionData[16][1]=new byte[] {Ptg.CLASS_VALUE};functionData[16][2]=new Integer(1);
- functionData[17][0]=new Byte(Ptg.CLASS_VALUE);functionData[17][1]=new byte[] {Ptg.CLASS_VALUE};functionData[17][2]=new Integer(1);
- functionData[18][0]=new Byte(Ptg.CLASS_VALUE);functionData[18][1]=new byte[] {Ptg.CLASS_VALUE};functionData[18][2]=new Integer(1);
- functionData[19][0]=new Byte(Ptg.CLASS_VALUE);functionData[19][1]=new byte[] {Ptg.CLASS_VALUE};functionData[19][2]=new Integer(0);
- functionData[20][0]=new Byte(Ptg.CLASS_VALUE);functionData[20][1]=new byte[] {Ptg.CLASS_VALUE};functionData[20][2]=new Integer(1);
- functionData[21][0]=new Byte(Ptg.CLASS_VALUE);functionData[21][1]=new byte[] {Ptg.CLASS_VALUE};functionData[21][2]=new Integer(1);
- functionData[22][0]=new Byte(Ptg.CLASS_VALUE);functionData[22][1]=new byte[] {Ptg.CLASS_VALUE};functionData[22][2]=new Integer(1);
- functionData[23][0]=new Byte(Ptg.CLASS_VALUE);functionData[23][1]=new byte[] {Ptg.CLASS_VALUE};functionData[23][2]=new Integer(1);
- functionData[24][0]=new Byte(Ptg.CLASS_VALUE);functionData[24][1]=new byte[] {Ptg.CLASS_VALUE};functionData[24][2]=new Integer(1);
- functionData[25][0]=new Byte(Ptg.CLASS_VALUE);functionData[25][1]=new byte[] {Ptg.CLASS_VALUE};functionData[25][2]=new Integer(1);
- functionData[26][0]=new Byte(Ptg.CLASS_VALUE);functionData[26][1]=new byte[] {Ptg.CLASS_VALUE};functionData[26][2]=new Integer(1);
- functionData[27][0]=new Byte(Ptg.CLASS_VALUE);functionData[27][1]=new byte[] {Ptg.CLASS_VALUE};functionData[27][2]=new Integer(2);
- functionData[28][0]=new Byte(Ptg.CLASS_VALUE);functionData[28][1]=new byte[] {Ptg.CLASS_VALUE, Ptg.CLASS_REF};functionData[28][2]=new Integer(-1);
- functionData[29][0]=new Byte(Ptg.CLASS_VALUE);functionData[29][1]=new byte[] {Ptg.CLASS_REF};functionData[29][2]=new Integer(-1);
- functionData[30][0]=new Byte(Ptg.CLASS_VALUE);functionData[30][1]=new byte[] {Ptg.CLASS_VALUE};functionData[30][2]=new Integer(2);
- functionData[31][0]=new Byte(Ptg.CLASS_VALUE);functionData[31][1]=new byte[] {Ptg.CLASS_VALUE};functionData[31][2]=new Integer(3);
- functionData[32][0]=new Byte(Ptg.CLASS_VALUE);functionData[32][1]=new byte[] {Ptg.CLASS_VALUE};functionData[32][2]=new Integer(1);
- functionData[33][0]=new Byte(Ptg.CLASS_VALUE);functionData[33][1]=new byte[] {Ptg.CLASS_VALUE};functionData[33][2]=new Integer(1);
- functionData[34][0]=new Byte(Ptg.CLASS_VALUE);functionData[34][1]=new byte[] {Ptg.CLASS_VALUE};functionData[34][2]=new Integer(0);
- functionData[35][0]=new Byte(Ptg.CLASS_VALUE);functionData[35][1]=new byte[] {Ptg.CLASS_VALUE};functionData[35][2]=new Integer(0);
- functionData[36][0]=new Byte(Ptg.CLASS_VALUE);functionData[36][1]=new byte[] {Ptg.CLASS_REF};functionData[36][2]=new Integer(-1);
- functionData[37][0]=new Byte(Ptg.CLASS_VALUE);functionData[37][1]=new byte[] {Ptg.CLASS_REF};functionData[37][2]=new Integer(-1);
- functionData[38][0]=new Byte(Ptg.CLASS_VALUE);functionData[38][1]=new byte[] {Ptg.CLASS_VALUE};functionData[38][2]=new Integer(1);
- functionData[39][0]=new Byte(Ptg.CLASS_VALUE);functionData[39][1]=new byte[] {Ptg.CLASS_VALUE};functionData[39][2]=new Integer(2);
- functionData[40][0]=new Byte(Ptg.CLASS_VALUE);functionData[40][1]=new byte[] {Ptg.CLASS_REF};functionData[40][2]=new Integer(3);
- functionData[41][0]=new Byte(Ptg.CLASS_VALUE);functionData[41][1]=new byte[] {Ptg.CLASS_REF};functionData[41][2]=new Integer(3);
- functionData[42][0]=new Byte(Ptg.CLASS_VALUE);functionData[42][1]=new byte[] {Ptg.CLASS_REF};functionData[42][2]=new Integer(3);
- functionData[43][0]=new Byte(Ptg.CLASS_VALUE);functionData[43][1]=new byte[] {Ptg.CLASS_REF};functionData[43][2]=new Integer(3);
- functionData[44][0]=new Byte(Ptg.CLASS_VALUE);functionData[44][1]=new byte[] {Ptg.CLASS_REF};functionData[44][2]=new Integer(3);
- functionData[45][0]=new Byte(Ptg.CLASS_VALUE);functionData[45][1]=new byte[] {Ptg.CLASS_REF};functionData[45][2]=new Integer(3);
- functionData[46][0]=new Byte(Ptg.CLASS_VALUE);functionData[46][1]=new byte[] {Ptg.CLASS_REF};functionData[46][2]=new Integer(-1);
- functionData[47][0]=new Byte(Ptg.CLASS_VALUE);functionData[47][1]=new byte[] {Ptg.CLASS_REF};functionData[47][2]=new Integer(3);
- functionData[48][0]=new Byte(Ptg.CLASS_VALUE);functionData[48][1]=new byte[] {Ptg.CLASS_VALUE};functionData[48][2]=new Integer(2);
- functionData[49][0]=new Byte(Ptg.CLASS_VALUE);functionData[49][1]=new byte[] {Ptg.CLASS_REF};functionData[49][2]=new Integer(-1);
- functionData[50][0]=new Byte(Ptg.CLASS_VALUE);functionData[50][1]=new byte[] {Ptg.CLASS_REF};functionData[50][2]=new Integer(-1);
- functionData[51][0]=new Byte(Ptg.CLASS_VALUE);functionData[51][1]=new byte[] {Ptg.CLASS_REF};functionData[51][2]=new Integer(-1);
- functionData[52][0]=new Byte(Ptg.CLASS_VALUE);functionData[52][1]=new byte[] {Ptg.CLASS_REF};functionData[52][2]=new Integer(-1);
-
-
- functionData[56][0]=new Byte(Ptg.CLASS_VALUE);functionData[56][1]=new byte[] {Ptg.CLASS_VALUE};functionData[56][2]=new Integer(-1);
- functionData[57][0]=new Byte(Ptg.CLASS_VALUE);functionData[57][1]=new byte[] {Ptg.CLASS_VALUE};functionData[57][2]=new Integer(-1);
- functionData[58][0]=new Byte(Ptg.CLASS_VALUE);functionData[58][1]=new byte[] {Ptg.CLASS_VALUE};functionData[58][2]=new Integer(-1);
- functionData[59][0]=new Byte(Ptg.CLASS_VALUE);functionData[59][1]=new byte[] {Ptg.CLASS_VALUE};functionData[59][2]=new Integer(-1);
- functionData[60][0]=new Byte(Ptg.CLASS_VALUE);functionData[60][1]=new byte[] {Ptg.CLASS_VALUE};functionData[60][2]=new Integer(-1);
- functionData[61][0]=new Byte(Ptg.CLASS_VALUE);functionData[61][1]=new byte[] {Ptg.CLASS_VALUE};functionData[61][2]=new Integer(3);
- functionData[62][0]=new Byte(Ptg.CLASS_VALUE);functionData[62][1]=new byte[] {Ptg.CLASS_REF};functionData[62][2]=new Integer(-1);
- functionData[63][0]=new Byte(Ptg.CLASS_VALUE);functionData[63][1]=new byte[] {Ptg.CLASS_REF};functionData[63][2]=new Integer(1);
- functionData[64][0]=new Byte(Ptg.CLASS_VALUE);functionData[64][1]=new byte[] {Ptg.CLASS_VALUE, Ptg.CLASS_REF};functionData[64][2]=new Integer(-1);
- functionData[65][0]=new Byte(Ptg.CLASS_VALUE);functionData[65][1]=new byte[] {Ptg.CLASS_VALUE};functionData[65][2]=new Integer(3);
- functionData[66][0]=new Byte(Ptg.CLASS_VALUE);functionData[66][1]=new byte[] {Ptg.CLASS_VALUE};functionData[66][2]=new Integer(3);
- functionData[67][0]=new Byte(Ptg.CLASS_VALUE);functionData[67][1]=new byte[] {Ptg.CLASS_VALUE};functionData[67][2]=new Integer(1);
- functionData[68][0]=new Byte(Ptg.CLASS_VALUE);functionData[68][1]=new byte[] {Ptg.CLASS_VALUE};functionData[68][2]=new Integer(1);
- functionData[69][0]=new Byte(Ptg.CLASS_VALUE);functionData[69][1]=new byte[] {Ptg.CLASS_VALUE};functionData[69][2]=new Integer(1);
- functionData[70][0]=new Byte(Ptg.CLASS_VALUE);functionData[70][1]=new byte[] {Ptg.CLASS_VALUE};functionData[70][2]=new Integer(-1);
- functionData[71][0]=new Byte(Ptg.CLASS_VALUE);functionData[71][1]=new byte[] {Ptg.CLASS_VALUE};functionData[71][2]=new Integer(1);
- functionData[72][0]=new Byte(Ptg.CLASS_VALUE);functionData[72][1]=new byte[] {Ptg.CLASS_VALUE};functionData[72][2]=new Integer(1);
- functionData[73][0]=new Byte(Ptg.CLASS_VALUE);functionData[73][1]=new byte[] {Ptg.CLASS_VALUE};functionData[73][2]=new Integer(1);
- functionData[74][0]=new Byte(Ptg.CLASS_VALUE);functionData[74][1]=new byte[] {Ptg.CLASS_REF};functionData[74][2]=new Integer(1);
- functionData[75][0]=new Byte(Ptg.CLASS_VALUE);functionData[75][1]=new byte[] {Ptg.CLASS_REF};functionData[75][2]=new Integer(1);
- functionData[76][0]=new Byte(Ptg.CLASS_VALUE);functionData[76][1]=new byte[] {Ptg.CLASS_REF};functionData[76][2]=new Integer(1);
- functionData[77][0]=new Byte(Ptg.CLASS_VALUE);functionData[77][1]=new byte[] {Ptg.CLASS_REF};functionData[77][2]=new Integer(1);
- functionData[78][0]=new Byte(Ptg.CLASS_VALUE);functionData[78][1]=new byte[] {Ptg.CLASS_VALUE};functionData[78][2]=new Integer(-1);
-
-
-
- functionData[82][0]=new Byte(Ptg.CLASS_VALUE);functionData[82][1]=new byte[] {Ptg.CLASS_VALUE};functionData[82][2]=new Integer(-1);
- functionData[83][0]=new Byte(Ptg.CLASS_VALUE);functionData[83][1]=new byte[] {Ptg.CLASS_VALUE};functionData[83][2]=new Integer(1);
-
-
- functionData[86][0]=new Byte(Ptg.CLASS_VALUE);functionData[86][1]=new byte[] {Ptg.CLASS_VALUE};functionData[86][2]=new Integer(1);
-
-
-
-
-
-
-
-
-
-
- functionData[97][0]=new Byte(Ptg.CLASS_VALUE);functionData[97][1]=new byte[] {Ptg.CLASS_VALUE};functionData[97][2]=new Integer(2);
- functionData[98][0]=new Byte(Ptg.CLASS_VALUE);functionData[98][1]=new byte[] {Ptg.CLASS_VALUE};functionData[98][2]=new Integer(1);
- functionData[99][0]=new Byte(Ptg.CLASS_VALUE);functionData[99][1]=new byte[] {Ptg.CLASS_VALUE};functionData[99][2]=new Integer(1);
-
- functionData[101][0]=new Byte(Ptg.CLASS_VALUE);functionData[101][1]=new byte[] {Ptg.CLASS_REF};functionData[101][2]=new Integer(-1);
- functionData[102][0]=new Byte(Ptg.CLASS_VALUE);functionData[102][1]=new byte[] {Ptg.CLASS_REF};functionData[102][2]=new Integer(-1);
-
-
- functionData[105][0]=new Byte(Ptg.CLASS_VALUE);functionData[105][1]=new byte[] {Ptg.CLASS_REF};functionData[105][2]=new Integer(1);
-
-
-
- functionData[109][0]=new Byte(Ptg.CLASS_VALUE);functionData[109][1]=new byte[] {Ptg.CLASS_VALUE};functionData[109][2]=new Integer(-1);
-
- functionData[111][0]=new Byte(Ptg.CLASS_VALUE);functionData[111][1]=new byte[] {Ptg.CLASS_VALUE};functionData[111][2]=new Integer(1);
- functionData[112][0]=new Byte(Ptg.CLASS_VALUE);functionData[112][1]=new byte[] {Ptg.CLASS_VALUE};functionData[112][2]=new Integer(1);
- functionData[113][0]=new Byte(Ptg.CLASS_VALUE);functionData[113][1]=new byte[] {Ptg.CLASS_VALUE};functionData[113][2]=new Integer(1);
- functionData[114][0]=new Byte(Ptg.CLASS_VALUE);functionData[114][1]=new byte[] {Ptg.CLASS_VALUE};functionData[114][2]=new Integer(1);
- functionData[115][0]=new Byte(Ptg.CLASS_VALUE);functionData[115][1]=new byte[] {Ptg.CLASS_VALUE};functionData[115][2]=new Integer(-1);
- functionData[116][0]=new Byte(Ptg.CLASS_VALUE);functionData[116][1]=new byte[] {Ptg.CLASS_VALUE};functionData[116][2]=new Integer(-1);
- functionData[117][0]=new Byte(Ptg.CLASS_VALUE);functionData[117][1]=new byte[] {Ptg.CLASS_VALUE};functionData[117][2]=new Integer(2);
- functionData[118][0]=new Byte(Ptg.CLASS_VALUE);functionData[118][1]=new byte[] {Ptg.CLASS_VALUE};functionData[118][2]=new Integer(1);
- functionData[119][0]=new Byte(Ptg.CLASS_VALUE);functionData[119][1]=new byte[] {Ptg.CLASS_VALUE};functionData[119][2]=new Integer(4);
- functionData[120][0]=new Byte(Ptg.CLASS_VALUE);functionData[120][1]=new byte[] {Ptg.CLASS_VALUE};functionData[120][2]=new Integer(-1);
- functionData[121][0]=new Byte(Ptg.CLASS_VALUE);functionData[121][1]=new byte[] {Ptg.CLASS_VALUE};functionData[121][2]=new Integer(1);
-
-
- functionData[124][0]=new Byte(Ptg.CLASS_VALUE);functionData[124][1]=new byte[] {Ptg.CLASS_VALUE};functionData[124][2]=new Integer(-1);
- functionData[125][0]=new Byte(Ptg.CLASS_VALUE);functionData[125][1]=new byte[] {Ptg.CLASS_VALUE};functionData[125][2]=new Integer(-1);
- functionData[126][0]=new Byte(Ptg.CLASS_VALUE);functionData[126][1]=new byte[] {Ptg.CLASS_VALUE};functionData[126][2]=new Integer(1);
- functionData[127][0]=new Byte(Ptg.CLASS_VALUE);functionData[127][1]=new byte[] {Ptg.CLASS_VALUE};functionData[127][2]=new Integer(1);
- functionData[128][0]=new Byte(Ptg.CLASS_VALUE);functionData[128][1]=new byte[] {Ptg.CLASS_VALUE};functionData[128][2]=new Integer(1);
- functionData[129][0]=new Byte(Ptg.CLASS_VALUE);functionData[129][1]=new byte[] {Ptg.CLASS_VALUE};functionData[129][2]=new Integer(1);
- functionData[130][0]=new Byte(Ptg.CLASS_VALUE);functionData[130][1]=new byte[] {Ptg.CLASS_REF};functionData[130][2]=new Integer(1);
- functionData[131][0]=new Byte(Ptg.CLASS_VALUE);functionData[131][1]=new byte[] {Ptg.CLASS_REF};functionData[131][2]=new Integer(1);
-
-
-
-
-
-
-
-
- functionData[140][0]=new Byte(Ptg.CLASS_VALUE);functionData[140][1]=new byte[] {Ptg.CLASS_VALUE};functionData[140][2]=new Integer(1);
- functionData[141][0]=new Byte(Ptg.CLASS_VALUE);functionData[141][1]=new byte[] {Ptg.CLASS_VALUE};functionData[141][2]=new Integer(1);
- functionData[142][0]=new Byte(Ptg.CLASS_VALUE);functionData[142][1]=new byte[] {Ptg.CLASS_VALUE};functionData[142][2]=new Integer(3);
-
-
-
-
-
- functionData[148][0]=new Byte(Ptg.CLASS_VALUE);functionData[148][1]=new byte[] {Ptg.CLASS_VALUE};functionData[148][2]=new Integer(-1);
-
- functionData[150][0]=new Byte(Ptg.CLASS_VALUE);functionData[150][1]=new byte[] {Ptg.CLASS_VALUE};functionData[150][2]=new Integer(-1);
-
-
-
-
-
-
-
-
-
-
-
- functionData[162][0]=new Byte(Ptg.CLASS_VALUE);functionData[162][1]=new byte[] {Ptg.CLASS_VALUE};functionData[162][2]=new Integer(1);
- functionData[163][0]=new Byte(Ptg.CLASS_VALUE);functionData[163][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[163][2]=new Integer(1);
- functionData[164][0]=new Byte(Ptg.CLASS_VALUE);functionData[164][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[164][2]=new Integer(1);
- functionData[165][0]=new Byte(Ptg.CLASS_VALUE);functionData[165][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[165][2]=new Integer(2);
- functionData[166][0]=new Byte(Ptg.CLASS_VALUE);functionData[166][1]=new byte[] {Ptg.CLASS_VALUE};functionData[166][2]=new Integer(-1);
- functionData[167][0]=new Byte(Ptg.CLASS_VALUE);functionData[167][1]=new byte[] {Ptg.CLASS_VALUE};functionData[167][2]=new Integer(-1);
- functionData[168][0]=new Byte(Ptg.CLASS_VALUE);functionData[168][1]=new byte[] {Ptg.CLASS_REF};functionData[168][2]=new Integer(-1);
-
-
-
-
-
-
-
-
-
-
- functionData[183][0]=new Byte(Ptg.CLASS_VALUE);functionData[183][1]=new byte[] {Ptg.CLASS_REF};functionData[183][2]=new Integer(-1);
- functionData[184][0]=new Byte(Ptg.CLASS_VALUE);functionData[184][1]=new byte[] {Ptg.CLASS_VALUE};functionData[184][2]=new Integer(1);
-
-
-
-
- functionData[189][0]=new Byte(Ptg.CLASS_VALUE);functionData[189][1]=new byte[] {Ptg.CLASS_REF};functionData[189][2]=new Integer(3);
- functionData[190][0]=new Byte(Ptg.CLASS_VALUE);functionData[190][1]=new byte[] {Ptg.CLASS_VALUE};functionData[190][2]=new Integer(1);
-
-
- functionData[193][0]=new Byte(Ptg.CLASS_VALUE);functionData[193][1]=new byte[] {Ptg.CLASS_REF};functionData[193][2]=new Integer(-1);
- functionData[194][0]=new Byte(Ptg.CLASS_VALUE);functionData[194][1]=new byte[] {Ptg.CLASS_REF};functionData[194][2]=new Integer(-1);
- functionData[195][0]=new Byte(Ptg.CLASS_VALUE);functionData[195][1]=new byte[] {Ptg.CLASS_REF};functionData[195][2]=new Integer(3);
- functionData[196][0]=new Byte(Ptg.CLASS_VALUE);functionData[196][1]=new byte[] {Ptg.CLASS_REF};functionData[196][2]=new Integer(3);
- functionData[197][0]=new Byte(Ptg.CLASS_VALUE);functionData[197][1]=new byte[] {Ptg.CLASS_VALUE};functionData[197][2]=new Integer(-1);
- functionData[198][0]=new Byte(Ptg.CLASS_VALUE);functionData[198][1]=new byte[] {Ptg.CLASS_VALUE};functionData[198][2]=new Integer(1);
- functionData[199][0]=new Byte(Ptg.CLASS_VALUE);functionData[199][1]=new byte[] {Ptg.CLASS_REF};functionData[199][2]=new Integer(3);
-
-
- functionData[204][0]=new Byte(Ptg.CLASS_VALUE);functionData[204][1]=new byte[] {Ptg.CLASS_VALUE};functionData[204][2]=new Integer(-1);
- functionData[205][0]=new Byte(Ptg.CLASS_VALUE);functionData[205][1]=new byte[] {Ptg.CLASS_VALUE};functionData[205][2]=new Integer(-1);
- functionData[206][0]=new Byte(Ptg.CLASS_VALUE);functionData[206][1]=new byte[] {Ptg.CLASS_VALUE};functionData[206][2]=new Integer(-1);
- functionData[207][0]=new Byte(Ptg.CLASS_VALUE);functionData[207][1]=new byte[] {Ptg.CLASS_VALUE};functionData[207][2]=new Integer(3);
- functionData[208][0]=new Byte(Ptg.CLASS_VALUE);functionData[208][1]=new byte[] {Ptg.CLASS_VALUE};functionData[208][2]=new Integer(1);
- functionData[209][0]=new Byte(Ptg.CLASS_VALUE);functionData[209][1]=new byte[] {Ptg.CLASS_VALUE};functionData[209][2]=new Integer(2);
- functionData[210][0]=new Byte(Ptg.CLASS_VALUE);functionData[210][1]=new byte[] {Ptg.CLASS_VALUE};functionData[210][2]=new Integer(2);
- functionData[211][0]=new Byte(Ptg.CLASS_VALUE);functionData[211][1]=new byte[] {Ptg.CLASS_VALUE};functionData[211][2]=new Integer(1);
- functionData[212][0]=new Byte(Ptg.CLASS_VALUE);functionData[212][1]=new byte[] {Ptg.CLASS_VALUE};functionData[212][2]=new Integer(2);
- functionData[213][0]=new Byte(Ptg.CLASS_VALUE);functionData[213][1]=new byte[] {Ptg.CLASS_REF};functionData[213][2]=new Integer(2);
- functionData[214][0]=new Byte(Ptg.CLASS_VALUE);functionData[214][1]=new byte[] {Ptg.CLASS_VALUE};functionData[214][2]=new Integer(-1);
-
-
-
-
- functionData[221][0]=new Byte(Ptg.CLASS_VALUE);functionData[221][1]=new byte[] {Ptg.CLASS_REF};functionData[221][2]=new Integer(1);
- functionData[222][0]=new Byte(Ptg.CLASS_VALUE);functionData[222][1]=new byte[] {Ptg.CLASS_VALUE};functionData[222][2]=new Integer(-1);
- functionData[227][0]=new Byte(Ptg.CLASS_VALUE);functionData[227][1]=new byte[] {Ptg.CLASS_REF};functionData[227][2]=new Integer(-1);
- functionData[228][0]=new Byte(Ptg.CLASS_VALUE);functionData[228][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[228][2]=new Integer(-1);
- functionData[229][0]=new Byte(Ptg.CLASS_VALUE);functionData[229][1]=new byte[] {Ptg.CLASS_VALUE};functionData[229][2]=new Integer(1);
- functionData[230][0]=new Byte(Ptg.CLASS_VALUE);functionData[230][1]=new byte[] {Ptg.CLASS_VALUE};functionData[230][2]=new Integer(1);
- functionData[231][0]=new Byte(Ptg.CLASS_VALUE);functionData[231][1]=new byte[] {Ptg.CLASS_VALUE};functionData[231][2]=new Integer(1);
- functionData[232][0]=new Byte(Ptg.CLASS_VALUE);functionData[232][1]=new byte[] {Ptg.CLASS_VALUE};functionData[232][2]=new Integer(1);
- functionData[233][0]=new Byte(Ptg.CLASS_VALUE);functionData[233][1]=new byte[] {Ptg.CLASS_VALUE};functionData[233][2]=new Integer(1);
- functionData[234][0]=new Byte(Ptg.CLASS_VALUE);functionData[234][1]=new byte[] {Ptg.CLASS_VALUE};functionData[234][2]=new Integer(1);
- functionData[235][0]=new Byte(Ptg.CLASS_VALUE);functionData[235][1]=new byte[] {Ptg.CLASS_REF};functionData[235][2]=new Integer(3);
-
-
-
-
-
-
-
-
- functionData[244][0]=new Byte(Ptg.CLASS_VALUE);functionData[244][1]=new byte[] {Ptg.CLASS_VALUE};functionData[244][2]=new Integer(2);
-
-
-
-
-
- functionData[252][0]=new Byte(Ptg.CLASS_VALUE);functionData[252][1]=new byte[] {Ptg.CLASS_REF};functionData[252][2]=new Integer(2);
-
-
-
-
-
-
-
- functionData[261][0]=new Byte(Ptg.CLASS_VALUE);functionData[261][1]=new byte[] {Ptg.CLASS_VALUE};functionData[261][2]=new Integer(1);
-
-
-
-
-
-
-
- functionData[269][0]=new Byte(Ptg.CLASS_VALUE);functionData[269][1]=new byte[] {Ptg.CLASS_REF};functionData[269][2]=new Integer(-1);
- functionData[270][0]=new Byte(Ptg.CLASS_VALUE);functionData[270][1]=new byte[] {Ptg.CLASS_VALUE};functionData[270][2]=new Integer(-1);
- functionData[271][0]=new Byte(Ptg.CLASS_VALUE);functionData[271][1]=new byte[] {Ptg.CLASS_VALUE};functionData[271][2]=new Integer(1);
- functionData[272][0]=new Byte(Ptg.CLASS_VALUE);functionData[272][1]=new byte[] {Ptg.CLASS_VALUE};functionData[272][2]=new Integer(-1);
- functionData[273][0]=new Byte(Ptg.CLASS_VALUE);functionData[273][1]=new byte[] {Ptg.CLASS_VALUE};functionData[273][2]=new Integer(4);
- functionData[274][0]=new Byte(Ptg.CLASS_VALUE);functionData[274][1]=new byte[] {Ptg.CLASS_VALUE};functionData[274][2]=new Integer(2);
- functionData[275][0]=new Byte(Ptg.CLASS_VALUE);functionData[275][1]=new byte[] {Ptg.CLASS_VALUE};functionData[275][2]=new Integer(2);
- functionData[276][0]=new Byte(Ptg.CLASS_VALUE);functionData[276][1]=new byte[] {Ptg.CLASS_VALUE};functionData[276][2]=new Integer(2);
- functionData[277][0]=new Byte(Ptg.CLASS_VALUE);functionData[277][1]=new byte[] {Ptg.CLASS_VALUE};functionData[277][2]=new Integer(3);
- functionData[278][0]=new Byte(Ptg.CLASS_VALUE);functionData[278][1]=new byte[] {Ptg.CLASS_VALUE};functionData[278][2]=new Integer(3);
- functionData[279][0]=new Byte(Ptg.CLASS_VALUE);functionData[279][1]=new byte[] {Ptg.CLASS_VALUE};functionData[279][2]=new Integer(1);
- functionData[280][0]=new Byte(Ptg.CLASS_VALUE);functionData[280][1]=new byte[] {Ptg.CLASS_VALUE};functionData[280][2]=new Integer(3);
- functionData[281][0]=new Byte(Ptg.CLASS_VALUE);functionData[281][1]=new byte[] {Ptg.CLASS_VALUE};functionData[281][2]=new Integer(3);
- functionData[282][0]=new Byte(Ptg.CLASS_VALUE);functionData[282][1]=new byte[] {Ptg.CLASS_VALUE};functionData[282][2]=new Integer(3);
- functionData[283][0]=new Byte(Ptg.CLASS_VALUE);functionData[283][1]=new byte[] {Ptg.CLASS_VALUE};functionData[283][2]=new Integer(1);
- functionData[284][0]=new Byte(Ptg.CLASS_VALUE);functionData[284][1]=new byte[] {Ptg.CLASS_VALUE};functionData[284][2]=new Integer(1);
- functionData[285][0]=new Byte(Ptg.CLASS_VALUE);functionData[285][1]=new byte[] {Ptg.CLASS_VALUE};functionData[285][2]=new Integer(2);
- functionData[286][0]=new Byte(Ptg.CLASS_VALUE);functionData[286][1]=new byte[] {Ptg.CLASS_VALUE};functionData[286][2]=new Integer(4);
- functionData[287][0]=new Byte(Ptg.CLASS_VALUE);functionData[287][1]=new byte[] {Ptg.CLASS_VALUE};functionData[287][2]=new Integer(3);
- functionData[288][0]=new Byte(Ptg.CLASS_VALUE);functionData[288][1]=new byte[] {Ptg.CLASS_VALUE};functionData[288][2]=new Integer(2);
- functionData[289][0]=new Byte(Ptg.CLASS_VALUE);functionData[289][1]=new byte[] {Ptg.CLASS_VALUE};functionData[289][2]=new Integer(4);
- functionData[290][0]=new Byte(Ptg.CLASS_VALUE);functionData[290][1]=new byte[] {Ptg.CLASS_VALUE};functionData[290][2]=new Integer(3);
- functionData[291][0]=new Byte(Ptg.CLASS_VALUE);functionData[291][1]=new byte[] {Ptg.CLASS_VALUE};functionData[291][2]=new Integer(3);
- functionData[292][0]=new Byte(Ptg.CLASS_VALUE);functionData[292][1]=new byte[] {Ptg.CLASS_VALUE};functionData[292][2]=new Integer(3);
- functionData[293][0]=new Byte(Ptg.CLASS_VALUE);functionData[293][1]=new byte[] {Ptg.CLASS_VALUE};functionData[293][2]=new Integer(4);
- functionData[294][0]=new Byte(Ptg.CLASS_VALUE);functionData[294][1]=new byte[] {Ptg.CLASS_VALUE};functionData[294][2]=new Integer(1);
- functionData[295][0]=new Byte(Ptg.CLASS_VALUE);functionData[295][1]=new byte[] {Ptg.CLASS_VALUE};functionData[295][2]=new Integer(3);
- functionData[296][0]=new Byte(Ptg.CLASS_VALUE);functionData[296][1]=new byte[] {Ptg.CLASS_VALUE};functionData[296][2]=new Integer(1);
- functionData[297][0]=new Byte(Ptg.CLASS_VALUE);functionData[297][1]=new byte[] {Ptg.CLASS_VALUE};functionData[297][2]=new Integer(3);
- functionData[298][0]=new Byte(Ptg.CLASS_VALUE);functionData[298][1]=new byte[] {Ptg.CLASS_VALUE};functionData[298][2]=new Integer(1);
- functionData[299][0]=new Byte(Ptg.CLASS_VALUE);functionData[299][1]=new byte[] {Ptg.CLASS_VALUE};functionData[299][2]=new Integer(2);
- functionData[300][0]=new Byte(Ptg.CLASS_VALUE);functionData[300][1]=new byte[] {Ptg.CLASS_VALUE};functionData[300][2]=new Integer(3);
- functionData[301][0]=new Byte(Ptg.CLASS_VALUE);functionData[301][1]=new byte[] {Ptg.CLASS_VALUE};functionData[301][2]=new Integer(3);
- functionData[302][0]=new Byte(Ptg.CLASS_VALUE);functionData[302][1]=new byte[] {Ptg.CLASS_VALUE};functionData[302][2]=new Integer(4);
- functionData[303][0]=new Byte(Ptg.CLASS_VALUE);functionData[303][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[303][2]=new Integer(2);
- functionData[304][0]=new Byte(Ptg.CLASS_VALUE);functionData[304][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[304][2]=new Integer(2);
- functionData[305][0]=new Byte(Ptg.CLASS_VALUE);functionData[305][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[305][2]=new Integer(2);
- functionData[306][0]=new Byte(Ptg.CLASS_VALUE);functionData[306][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[306][2]=new Integer(2);
- functionData[307][0]=new Byte(Ptg.CLASS_VALUE);functionData[307][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[307][2]=new Integer(2);
- functionData[308][0]=new Byte(Ptg.CLASS_VALUE);functionData[308][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[308][2]=new Integer(2);
- functionData[309][0]=new Byte(Ptg.CLASS_VALUE);functionData[309][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[309][2]=new Integer(3);
- functionData[310][0]=new Byte(Ptg.CLASS_VALUE);functionData[310][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[310][2]=new Integer(2);
- functionData[311][0]=new Byte(Ptg.CLASS_VALUE);functionData[311][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[311][2]=new Integer(2);
- functionData[312][0]=new Byte(Ptg.CLASS_VALUE);functionData[312][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[312][2]=new Integer(2);
- functionData[313][0]=new Byte(Ptg.CLASS_VALUE);functionData[313][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[313][2]=new Integer(2);
- functionData[314][0]=new Byte(Ptg.CLASS_VALUE);functionData[314][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[314][2]=new Integer(2);
- functionData[315][0]=new Byte(Ptg.CLASS_VALUE);functionData[315][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[315][2]=new Integer(2);
- functionData[316][0]=new Byte(Ptg.CLASS_VALUE);functionData[316][1]=new byte[] {Ptg.CLASS_VALUE};functionData[316][2]=new Integer(4);
- functionData[317][0]=new Byte(Ptg.CLASS_VALUE);functionData[317][1]=new byte[] {Ptg.CLASS_VALUE};functionData[317][2]=new Integer(-1);
- functionData[318][0]=new Byte(Ptg.CLASS_VALUE);functionData[318][1]=new byte[] {Ptg.CLASS_REF};functionData[318][2]=new Integer(-1);
- functionData[319][0]=new Byte(Ptg.CLASS_VALUE);functionData[319][1]=new byte[] {Ptg.CLASS_REF};functionData[319][2]=new Integer(-1);
- functionData[320][0]=new Byte(Ptg.CLASS_VALUE);functionData[320][1]=new byte[] {Ptg.CLASS_REF};functionData[320][2]=new Integer(-1);
- functionData[321][0]=new Byte(Ptg.CLASS_VALUE);functionData[321][1]=new byte[] {Ptg.CLASS_REF};functionData[321][2]=new Integer(-1);
- functionData[322][0]=new Byte(Ptg.CLASS_VALUE);functionData[322][1]=new byte[] {Ptg.CLASS_REF};functionData[322][2]=new Integer(-1);
- functionData[323][0]=new Byte(Ptg.CLASS_VALUE);functionData[323][1]=new byte[] {Ptg.CLASS_REF};functionData[323][2]=new Integer(-1);
- functionData[324][0]=new Byte(Ptg.CLASS_VALUE);functionData[324][1]=new byte[] {Ptg.CLASS_VALUE};functionData[324][2]=new Integer(-1);
- functionData[325][0]=new Byte(Ptg.CLASS_VALUE);functionData[325][1]=new byte[] {Ptg.CLASS_VALUE};functionData[325][2]=new Integer(2);
- functionData[326][0]=new Byte(Ptg.CLASS_VALUE);functionData[326][1]=new byte[] {Ptg.CLASS_VALUE};functionData[326][2]=new Integer(2);
- functionData[327][0]=new Byte(Ptg.CLASS_VALUE);functionData[327][1]=new byte[] {Ptg.CLASS_VALUE};functionData[327][2]=new Integer(2);
- functionData[328][0]=new Byte(Ptg.CLASS_VALUE);functionData[328][1]=new byte[] {Ptg.CLASS_VALUE};functionData[328][2]=new Integer(2);
- functionData[329][0]=new Byte(Ptg.CLASS_VALUE);functionData[329][1]=new byte[] {Ptg.CLASS_VALUE};functionData[329][2]=new Integer(-1);
- functionData[330][0]=new Byte(Ptg.CLASS_VALUE);functionData[330][1]=new byte[] {Ptg.CLASS_ARRAY};functionData[330][2]=new Integer(-1);
- functionData[331][0]=new Byte(Ptg.CLASS_VALUE);functionData[331][1]=new byte[] {Ptg.CLASS_VALUE};functionData[331][2]=new Integer(2);
- functionData[332][0]=new Byte(Ptg.CLASS_VALUE);functionData[332][1]=new byte[] {Ptg.CLASS_VALUE};functionData[332][2]=new Integer(2);
-
-
- functionData[336][0]=new Byte(Ptg.CLASS_VALUE);functionData[336][1]=new byte[] {Ptg.CLASS_VALUE};functionData[336][2]=new Integer(-1);
- functionData[337][0]=new Byte(Ptg.CLASS_VALUE);functionData[337][1]=new byte[] {Ptg.CLASS_VALUE};functionData[337][2]=new Integer(2);
-
-
-
-
- functionData[342][0]=new Byte(Ptg.CLASS_VALUE);functionData[342][1]=new byte[] {Ptg.CLASS_VALUE};functionData[342][2]=new Integer(1);
- functionData[343][0]=new Byte(Ptg.CLASS_VALUE);functionData[343][1]=new byte[] {Ptg.CLASS_VALUE};functionData[343][2]=new Integer(1);
- functionData[344][0]=new Byte(Ptg.CLASS_VALUE);functionData[344][1]=new byte[] {Ptg.CLASS_REF};functionData[344][2]=new Integer(-1);
- functionData[345][0]=new Byte(Ptg.CLASS_VALUE);functionData[345][1]=new byte[] {Ptg.CLASS_REF};functionData[345][2]=new Integer(-1);
- functionData[346][0]=new Byte(Ptg.CLASS_VALUE);functionData[346][1]=new byte[] {Ptg.CLASS_VALUE};functionData[346][2]=new Integer(2);
- functionData[347][0]=new Byte(Ptg.CLASS_VALUE);functionData[347][1]=new byte[] {Ptg.CLASS_REF};functionData[347][2]=new Integer(1);
-
-
- functionData[350][0]=new Byte(Ptg.CLASS_VALUE);functionData[350][1]=new byte[] {Ptg.CLASS_VALUE};functionData[350][2]=new Integer(4);
-
- functionData[352][0]=new Byte(Ptg.CLASS_VALUE);functionData[352][1]=new byte[] {Ptg.CLASS_VALUE};functionData[352][2]=new Integer(1);
-
- functionData[354][0]=new Byte(Ptg.CLASS_VALUE);functionData[354][1]=new byte[] {Ptg.CLASS_VALUE};functionData[354][2]=new Integer(-1);
-
-
-
- functionData[358][0]=new Byte(Ptg.CLASS_VALUE);functionData[358][1]=new byte[] {Ptg.CLASS_VALUE};functionData[358][2]=new Integer(2);
- functionData[359][0]=new Byte(Ptg.CLASS_VALUE);functionData[359][1]=new byte[] {Ptg.CLASS_VALUE};functionData[359][2]=new Integer(-1);
- functionData[360][0]=new Byte(Ptg.CLASS_VALUE);functionData[360][1]=new byte[] {Ptg.CLASS_REF};functionData[360][2]=new Integer(1);
- functionData[361][0]=new Byte(Ptg.CLASS_VALUE);functionData[361][1]=new byte[] {Ptg.CLASS_REF};functionData[361][2]=new Integer(-1);
- functionData[362][0]=new Byte(Ptg.CLASS_VALUE);functionData[362][1]=new byte[] {Ptg.CLASS_REF};functionData[362][2]=new Integer(-1);
- functionData[363][0]=new Byte(Ptg.CLASS_VALUE);functionData[363][1]=new byte[] {Ptg.CLASS_REF};functionData[363][2]=new Integer(-1);
- functionData[364][0]=new Byte(Ptg.CLASS_VALUE);functionData[364][1]=new byte[] {Ptg.CLASS_REF};functionData[364][2]=new Integer(-1);
- functionData[365][0]=new Byte(Ptg.CLASS_VALUE);functionData[365][1]=new byte[] {Ptg.CLASS_REF};functionData[365][2]=new Integer(-1);
- functionData[366][0]=new Byte(Ptg.CLASS_VALUE);functionData[366][1]=new byte[] {Ptg.CLASS_REF};functionData[366][2]=new Integer(-1);
- functionData[367][0]=new Byte(Ptg.CLASS_VALUE);functionData[367][1]=new byte[] {Ptg.CLASS_REF};functionData[367][2]=new Integer(-1);
-
-
- return functionData;
+ short ix = FunctionMetadataRegistry.lookupIndexByName(name.toUpperCase());
+ if (ix < 0) {
+ return FUNCTION_INDEX_EXTERNAL;
+ }
+ return ix;
}
public byte getDefaultOperandClass() {
diff --git a/src/java/org/apache/poi/hssf/record/formula/FuncPtg.java b/src/java/org/apache/poi/hssf/record/formula/FuncPtg.java
index 1123fc803a..a94355a0f0 100644
--- a/src/java/org/apache/poi/hssf/record/formula/FuncPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/FuncPtg.java
@@ -15,17 +15,18 @@
limitations under the License.
==================================================================== */
-
package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
+import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
/**
* @author aviks
* @author Jason Height (jheight at chariot dot net dot au)
* @author Danny Mui (dmui at apache dot org) (Leftover handling)
*/
-public class FuncPtg extends AbstractFunctionPtg{
+public final class FuncPtg extends AbstractFunctionPtg {
public final static byte sid = 0x21;
public final static int SIZE = 3;
@@ -50,34 +51,24 @@ public class FuncPtg extends AbstractFunctionPtg{
//field_1_num_args = data[ offset + 0 ];
field_2_fnc_index = in.readShort();
- /*
- if (data.length - offset > 2) { //save left overs if there are any
- leftOvers = new byte[2];
- System.arraycopy(data, offset+1, leftOvers, 0, leftOvers.length);
+ FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(field_2_fnc_index);
+ if(fm == null) {
+ throw new RuntimeException("Invalid built-in function index (" + field_2_fnc_index + ")");
}
- */
- try {
- numParams = ( (Integer)functionData[field_2_fnc_index][2]).intValue();
- } catch (NullPointerException npe) {
- numParams=0;
- }
-
+ numParams = fm.getMinParams();
}
public FuncPtg(int functionIndex, int numberOfParameters) {
field_2_fnc_index = (short) functionIndex;
numParams = numberOfParameters;
+ paramClass = new byte[] { Ptg.CLASS_VALUE, }; // TODO
}
- public void writeBytes(byte[] array, int offset) {
+ public void writeBytes(byte[] array, int offset) {
array[offset+0]= (byte) (sid + ptgClass);
- //array[offset+1]=field_1_num_args;
LittleEndian.putShort(array,offset+1,field_2_fnc_index);
- /**if (leftOvers != null) {
- System.arraycopy(leftOvers, 0, array, offset+2, leftOvers.length);
- }**/
}
- public int getNumberOfOperands() {
+ public int getNumberOfOperands() {
return numParams;
}
@@ -94,13 +85,11 @@ public class FuncPtg extends AbstractFunctionPtg{
}
public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer
- .append("
+ *
+ * HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
+ * newSheet.addConditionalFormatting(cf);
+ *
+ *
+ *
+ * // Create pattern with red background
+ * HSSFPatternFormatting patternFormatting = new HSSFPatternFormatting();
+ * patternFormatting.setFillBackgroundColor(HSSFColor.RED.index);
+ *
+ * Region [] regions =
+ * {
+ * // Define a region containing first column
+ * new Region(1,(short)1,-1,(short)1)
+ * };
+ *
+ * HSSFConditionalFormattingRule[] rules =
+ * {
+ * // Define a Conditional Formatting rule, which triggers formatting
+ * // when cell's value is greater or equal than 100.0 and
+ * // applies patternFormatting defined above.
+ *
+ * sheet.createConditionalFormattingRule(
+ * HSSFConditionalFormattingRule.COMPARISON_OPERATOR_GE,
+ * "100.0", // 1st formula
+ * null, // 2nd formula is not used for comparison operator GE
+ * null, // do not override Font Formatting
+ * null, // do not override Border Formatting
+ * patternFormatting
+ * )
+ * };
+ *
+ * // Apply Conditional Formatting rules defined above to the regions
+ * sheet.addConditionalFormatting(regions, rules);
+ *
+ *
+ * @author Dmitriy Kumshayev
+ */
+public final class HSSFConditionalFormatting
{
- HSSFSheet sheet;
- CFRecordsAggregate cfAggregate;
-
- protected HSSFConditionalFormatting(HSSFSheet sheet)
- {
- this.sheet = sheet;
- this.cfAggregate = new CFRecordsAggregate();
+ private final HSSFSheet sheet;
+ private final CFRecordsAggregate cfAggregate;
+
+ HSSFConditionalFormatting(HSSFSheet sheet) {
+ this(sheet, new CFRecordsAggregate());
}
-
- protected HSSFConditionalFormatting(HSSFSheet sheet, CFRecordsAggregate cfAggregate)
+
+ HSSFConditionalFormatting(HSSFSheet sheet, CFRecordsAggregate cfAggregate)
{
+ if(sheet == null) {
+ throw new IllegalArgumentException("sheet must not be null");
+ }
+ if(cfAggregate == null) {
+ throw new IllegalArgumentException("cfAggregate must not be null");
+ }
this.sheet = sheet;
this.cfAggregate = cfAggregate;
}
-
+ CFRecordsAggregate getCFRecordsAggregate() {
+ return cfAggregate;
+ }
public void setFormattingRegions(Region[] regions)
{
@@ -52,35 +117,65 @@ public class HSSFConditionalFormatting
}
}
+ /**
+ * @return array of Regions. never null
+ */
public Region[] getFormattingRegions()
{
CFHeaderRecord cfh = cfAggregate.getHeader();
-
+
List cellRanges = cfh.getCellRanges();
-
- if (cellRanges != null)
- {
- return toRegionArray(cellRanges);
- }
- return null;
+
+ return toRegionArray(cellRanges);
}
-
- public void setConditionalFormat(int idx, HSSFConditionalFormattingRule cfRule)
+
+ /**
+ * set a Conditional Formatting rule at position idx.
+ * Excel allows to create up to 3 Conditional Formatting rules.
+ * This method can be useful to modify existing Conditional Formatting rules.
+ *
+ * @param idx position of the rule. Should be between 0 and 2.
+ * @param cfRule - Conditional Formatting rule
+ */
+ public void setRule(int idx, HSSFConditionalFormattingRule cfRule)
{
+ if (idx < 0 || idx > 2) {
+ throw new IllegalArgumentException("idx must be between 0 and 2 but was ("
+ + idx + ")");
+ }
cfAggregate.getRules().set(idx, cfRule);
}
- public void addConditionalFormat(HSSFConditionalFormattingRule cfRule)
+ /**
+ * add a Conditional Formatting rule.
+ * Excel allows to create up to 3 Conditional Formatting rules.
+ * @param cfRule - Conditional Formatting rule
+ */
+ public void addRule(HSSFConditionalFormattingRule cfRule)
{
cfAggregate.getRules().add(cfRule);
}
-
- public HSSFConditionalFormattingRule getConditionalFormat(int idx)
+
+ /**
+ * get a Conditional Formatting rule at position idx.
+ * @param idx
+ * @return a Conditional Formatting rule at position idx.
+ */
+ public HSSFConditionalFormattingRule getRule(int idx)
{
CFRuleRecord ruleRecord = (CFRuleRecord)cfAggregate.getRules().get(idx);
return new HSSFConditionalFormattingRule(sheet.workbook, ruleRecord);
}
-
+
+ /**
+ * @return number of Conditional Formatting rules.
+ */
+ public int getNumbOfRules()
+ {
+ return cfAggregate.getRules().size();
+ }
+
+
/**
* Do all possible cell merges between cells of the list so that:
*
- *
This method could be used to copy HSSFConditionalFormatting object @@ -1934,72 +1929,71 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet *
* HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index); * newSheet.addConditionalFormatting(cf); - *- * + * + * * @param cf HSSFConditionalFormatting object * @return index of the new Conditional Formatting object */ public int addConditionalFormatting( HSSFConditionalFormatting cf ) { - HSSFConditionalFormatting cfClone = new HSSFConditionalFormatting(this,cf.cfAggregate.cloneCFAggregate()); - cfClone.sheet=this; - return sheet.addConditionalFormatting(cfClone.cfAggregate); + CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate(); + + return sheet.addConditionalFormatting(cfraClone); } /** * Allows to add a new Conditional Formatting set to the sheet. - * - * @param regions - list of rectangular regions to apply conditional formatting rules + * + * @param regions - list of rectangular regions to apply conditional formatting rules * @param cfRules - set of up to three conditional formatting rules - * + * * @return index of the newly created Conditional Formatting object */ - + public int addConditionalFormatting( Region [] regions, HSSFConditionalFormattingRule [] cfRules ) { - HSSFConditionalFormatting cf = new HSSFConditionalFormatting(this); - cf.setFormattingRegions(regions); - if( cfRules != null ) - { - for( int i=0; i!= cfRules.length; i++ ) - { - cf.addConditionalFormat(cfRules[i]); - } - } - return sheet.addConditionalFormatting(cf.cfAggregate); + HSSFConditionalFormatting cf = new HSSFConditionalFormatting(this); + cf.setFormattingRegions(regions); + if( cfRules != null ) + { + for( int i=0; i!= cfRules.length; i++ ) + { + cf.addRule(cfRules[i]); + } + } + return sheet.addConditionalFormatting(cf.getCFRecordsAggregate()); } - - /** - * gets Conditional Formatting object at a particular index - * @param index of the Conditional Formatting object to fetch - * @return Conditional Formatting object - */ - - public HSSFConditionalFormatting getConditionalFormattingAt(int index) - { - CFRecordsAggregate cf = sheet.getCFRecordsAggregateAt(index); - if( cf != null ) - { - return new HSSFConditionalFormatting(this,cf); - } - return null; - } - /** - * @return number of Conditional Formatting objects of the sheet - */ - public int getNumConditionalFormattings() - { - return sheet.getNumConditionalFormattings(); - } + /** + * gets Conditional Formatting object at a particular index + * @param index of the Conditional Formatting object to fetch + * @return Conditional Formatting object + */ - /** - * removes a Conditional Formatting object by index - * @param index of a Conditional Formatting object to remove - */ - public void removeConditionalFormatting(int index) - { - sheet.removeConditionalFormatting(index); - } + public HSSFConditionalFormatting getConditionalFormattingAt(int index) + { + CFRecordsAggregate cf = sheet.getCFRecordsAggregateAt(index); + if( cf != null ) + { + return new HSSFConditionalFormatting(this,cf); + } + return null; + } + /** + * @return number of Conditional Formatting objects of the sheet + */ + public int getNumConditionalFormattings() + { + return sheet.getNumConditionalFormattings(); + } + + /** + * removes a Conditional Formatting object by index + * @param index of a Conditional Formatting object to remove + */ + public void removeConditionalFormatting(int index) + { + sheet.removeConditionalFormatting(index); + } } diff --git a/src/resources/fontmetrics/font_metrics.properties b/src/resources/main/font_metrics.properties similarity index 100% rename from src/resources/fontmetrics/font_metrics.properties rename to src/resources/main/font_metrics.properties diff --git a/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt b/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt new file mode 100644 index 0000000000..60d2f1fe8b --- /dev/null +++ b/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt @@ -0,0 +1,283 @@ +# 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. + +# Created by (org.apache.poi.hssf.record.formula.function.ExcelFileFormatDocFunctionExtractor) +# from source file 'excelfileformat.odt' (size=355750, crc=0x2FAEA65A) +# +#Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote ) + +# Built-In Sheet Functions in BIFF2 +0 COUNT 0 30 V R +1 IF 2 3 R V R R +2 ISNA 1 1 V V +3 ISERROR 1 1 V V +4 SUM 0 30 V R +5 AVERAGE 1 30 V R +6 MIN 1 30 V R +7 MAX 1 30 V R +8 ROW 0 1 V R +9 COLUMN 0 1 V R +10 NA 0 0 V – +11 NPV 2 30 V V R +12 STDEV 1 30 V R +13 DOLLAR 1 2 V V V +14 FIXED 2 2 V V V x +15 SIN 1 1 V V +16 COS 1 1 V V +17 TAN 1 1 V V +18 ARCTAN 1 1 V V +19 PI 0 0 V – +20 SQRT 1 1 V V +21 EXP 1 1 V V +22 LN 1 1 V V +23 LOG10 1 1 V V +24 ABS 1 1 V V +25 INT 1 1 V V +26 SIGN 1 1 V V +27 ROUND 2 2 V V V +28 LOOKUP 2 3 V V R R +29 INDEX 2 4 R R V V V +30 REPT 2 2 V V V +31 MID 3 3 V V V V +32 LEN 1 1 V V +33 VALUE 1 1 V V +34 TRUE 0 0 V – +35 FALSE 0 0 V – +36 AND 1 30 V R +37 OR 1 30 V R +38 NOT 1 1 V V +39 MOD 2 2 V V V +40 DCOUNT 3 3 V R R R +41 DSUM 3 3 V R R R +42 DAVERAGE 3 3 V R R R +43 DMIN 3 3 V R R R +44 DMAX 3 3 V R R R +45 DSTDEV 3 3 V R R R +46 VAR 1 30 V R +47 DVAR 3 3 V R R R +48 TEXT 2 2 V V V +49 LINEST 1 2 A R R x +50 TREND 1 3 A R R R x +51 LOGEST 1 2 A R R x +52 GROWTH 1 3 A R R R x +56 PV 3 5 V V V V V V +# Built-In Sheet Functions in BIFF2 +57 FV 3 5 V V V V V V +58 NPER 3 5 V V V V V V +59 PMT 3 5 V V V V V V +60 RATE 3 6 V V V V V V V +61 MIRR 3 3 V R V V +62 IRR 1 2 V R V +63 RAND 0 0 V – x +64 MATCH 2 3 V V R R +65 DATE 3 3 V V V V +66 TIME 3 3 V V V V +67 DAY 1 1 V V +68 MONTH 1 1 V V +69 YEAR 1 1 V V +70 WEEKDAY 1 1 V V x +71 HOUR 1 1 V V +72 MINUTE 1 1 V V +73 SECOND 1 1 V V +74 NOW 0 0 V – x +75 AREAS 1 1 V R +76 ROWS 1 1 V R +77 COLUMNS 1 1 V R +78 OFFSET 3 5 R R V V V V x +82 SEARCH 2 3 V V V V +83 TRANSPOSE 1 1 A A +86 TYPE 1 1 V V +97 ATAN2 2 2 V V V +98 ASIN 1 1 V V +99 ACOS 1 1 V V +100 CHOOSE 2 30 R V R +101 HLOOKUP 3 3 V V R R x +102 VLOOKUP 3 3 V V R R x +105 ISREF 1 1 V R +109 LOG 1 2 V V V +111 CHAR 1 1 V V +112 LOWER 1 1 V V +113 UPPER 1 1 V V +114 PROPER 1 1 V V +115 LEFT 1 2 V V V +116 RIGHT 1 2 V V V +117 EXACT 2 2 V V V +118 TRIM 1 1 V V +119 REPLACE 4 4 V V V V V +120 SUBSTITUTE 3 4 V V V V V +121 CODE 1 1 V V +124 FIND 2 3 V V V V +125 CELL 1 2 V V R x +126 ISERR 1 1 V V +127 ISTEXT 1 1 V V +128 ISNUMBER 1 1 V V +129 ISBLANK 1 1 V V +130 T 1 1 V R +131 N 1 1 V R +140 DATEVALUE 1 1 V V +141 TIMEVALUE 1 1 V V +142 SLN 3 3 V V V V +143 SYD 4 4 V V V V V +144 DDB 4 5 V V V V V V +148 INDIRECT 1 2 R V V x +162 CLEAN 1 1 V V +163 MDETERM 1 1 V A +164 MINVERSE 1 1 A A +165 MMULT 2 2 A A A +167 IPMT 4 6 V V V V V V V +168 PPMT 4 6 V V V V V V V +169 COUNTA 0 30 V R +183 PRODUCT 0 30 V R +184 FACT 1 1 V V +191 DPRODUCT 3 3 V R R R +192 ISNONTEXT 1 1 V V +193 STDEVP 1 30 V R +194 VARP 1 30 V R +195 DSTDEVP 3 3 V R R R +196 DVARP 3 3 V R R R +197 TRUNC 1 1 V V x +198 ISLOGICAL 1 1 V V +199 DCOUNTA 3 3 V R R R +# New Built-In Sheet Functions in BIFF3 +49 LINEST 1 4 A R R V V x +50 TREND 1 4 A R R R V x +51 LOGEST 1 4 A R R V V x +52 GROWTH 1 4 A R R R V x +197 TRUNC 1 2 V V V x +204 YEN 1 2 V V V x +205 FINDB 2 3 V V V V +206 SEARCHB 2 3 V V V V +207 REPLACEB 4 4 V V V V V +208 LEFTB 1 2 V V V +209 RIGHTB 1 2 V V V +210 MIDB 3 3 V V V V +211 LENB 1 1 V V +212 ROUNDUP 2 2 V V V +213 ROUNDDOWN 2 2 V V V +214 ASC 1 1 V V +215 JIS 1 1 V V x +219 ADDRESS 2 5 V V V V V V +220 DAYS360 2 2 V V V x +221 TODAY 0 0 V – x +222 VDB 5 7 V V V V V V V V +227 MEDIAN 1 30 V R … +228 SUMPRODUCT 1 30 V A … +229 SINH 1 1 V V +230 COSH 1 1 V V +231 TANH 1 1 V V +232 ASINH 1 1 V V +233 ACOSH 1 1 V V +234 ATANH 1 1 V V +235 DGET 3 3 V R R R +244 INFO 1 1 V V +# New Built-In Sheet Functions in BIFF4 +14 FIXED 2 3 V V V V x +216 RANK 2 3 V V R V +247 DB 4 5 V V V V V V +252 FREQUENCY 2 2 A R R +261 ERROR.TYPE 1 1 V V +269 AVEDEV 1 30 V R … +270 BETADIST 3 5 V V V V V V +271 GAMMALN 1 1 V V +272 BETAINV 3 5 V V V V V V +273 BINOMDIST 4 4 V V V V V +274 CHIDIST 2 2 V V V +275 CHIINV 2 2 V V V +276 COMBIN 2 2 V V V +277 CONFIDENCE 3 3 V V V V +278 CRITBINOM 3 3 V V V V +279 EVEN 1 1 V V +280 EXPONDIST 3 3 V V V V +281 FDIST 3 3 V V V V +282 FINV 3 3 V V V V +283 FISHER 1 1 V V +284 FISHERINV 1 1 V V +285 FLOOR 2 2 V V V +286 GAMMADIST 4 4 V V V V V +287 GAMMAINV 3 3 V V V V +288 CEILING 2 2 V V V +289 HYPGEOMDIST 4 4 V V V V V +290 LOGNORMDIST 3 3 V V V V +291 LOGINV 3 3 V V V V +292 NEGBINOMDIST 3 3 V V V V +293 NORMDIST 4 4 V V V V V +294 NORMSDIST 1 1 V V +295 NORMINV 3 3 V V V V +296 NORMSINV 1 1 V V +297 STANDARDIZE 3 3 V V V V +298 ODD 1 1 V V +299 PERMUT 2 2 V V V +300 POISSON 3 3 V V V V +301 TDIST 3 3 V V V V +302 WEIBULL 4 4 V V V V V +303 SUMXMY2 2 2 V A A +304 SUMX2MY2 2 2 V A A +305 SUMX2PY2 2 2 V A A +306 CHITEST 2 2 V A A +307 CORREL 2 2 V A A +308 COVAR 2 2 V A A +309 FORECAST 3 3 V V A A +310 FTEST 2 2 V A A +311 INTERCEPT 2 2 V A A +312 PEARSON 2 2 V A A +313 RSQ 2 2 V A A +314 STEYX 2 2 V A A +315 SLOPE 2 2 V A A +316 TTEST 4 4 V A A V V +317 PROB 3 4 V A A V V +318 DEVSQ 1 30 V R … +319 GEOMEAN 1 30 V R … +320 HARMEAN 1 30 V R … +321 SUMSQ 0 30 V R … +322 KURT 1 30 V R … +323 SKEW 1 30 V R … +324 ZTEST 2 3 V R V V +325 LARGE 2 2 V R V +326 SMALL 2 2 V R V +327 QUARTILE 2 2 V R V +328 PERCENTILE 2 2 V R V +329 PERCENTRANK 2 3 V R V V +330 MODE 1 30 V A +331 TRIMMEAN 2 2 V R V +332 TINV 2 2 V V V +# New Built-In Sheet Functions in BIFF5 +70 WEEKDAY 1 2 V V V x +101 HLOOKUP 3 4 V V R R V x +102 VLOOKUP 3 4 V V R R V x +220 DAYS360 2 3 V V V V x +336 CONCATENATE 0 30 V V +337 POWER 2 2 V V V +342 RADIANS 1 1 V V +343 DEGREES 1 1 V V +344 SUBTOTAL 2 30 V V R +345 SUMIF 2 3 V R V R +346 COUNTIF 2 2 V R V +347 COUNTBLANK 1 1 V R +350 ISPMT 4 4 V V V V V +351 DATEDIF 3 3 V V V V +352 DATESTRING 1 1 V V +353 NUMBERSTRING 2 2 V V V +354 ROMAN 1 2 V V V +# New Built-In Sheet Functions in BIFF8 +358 GETPIVOTDATA 2 30 +359 HYPERLINK 1 2 V V V +360 PHONETIC 1 1 V R +361 AVERAGEA 1 30 V R … +362 MAXA 1 30 V R … +363 MINA 1 30 V R … +364 STDEVPA 1 30 V R … +365 VARPA 1 30 V R … +366 STDEVA 1 30 V R … +367 VARA 1 30 V R … diff --git a/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt b/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt new file mode 100644 index 0000000000..237fbf094f --- /dev/null +++ b/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt @@ -0,0 +1,287 @@ +# 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. + +# Created by (org.apache.poi.hssf.record.formula.function.ExcelFileFormatDocFunctionExtractor) +# from source file 'excelfileformat.odt' (size=355750, crc=0x2FAEA65A) +# +#Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote ) +# +# + some manual edits ! + +# Built-In Sheet Functions in BIFF2 +0 COUNT 0 30 V R +1 IF 2 3 R V R R +2 ISNA 1 1 V V +3 ISERROR 1 1 V V +4 SUM 0 30 V R +5 AVERAGE 1 30 V R +6 MIN 1 30 V R +7 MAX 1 30 V R +8 ROW 0 1 V R +9 COLUMN 0 1 V R +10 NA 0 0 V – +11 NPV 2 30 V V R +12 STDEV 1 30 V R +13 DOLLAR 1 2 V V V +14 FIXED 2 2 V V V x +15 SIN 1 1 V V +16 COS 1 1 V V +17 TAN 1 1 V V +18 ATAN 1 1 V V +19 PI 0 0 V – +20 SQRT 1 1 V V +21 EXP 1 1 V V +22 LN 1 1 V V +23 LOG10 1 1 V V +24 ABS 1 1 V V +25 INT 1 1 V V +26 SIGN 1 1 V V +27 ROUND 2 2 V V V +28 LOOKUP 2 3 V V R R +29 INDEX 2 4 R R V V V +30 REPT 2 2 V V V +31 MID 3 3 V V V V +32 LEN 1 1 V V +33 VALUE 1 1 V V +34 TRUE 0 0 V – +35 FALSE 0 0 V – +36 AND 1 30 V R +37 OR 1 30 V R +38 NOT 1 1 V V +39 MOD 2 2 V V V +40 DCOUNT 3 3 V R R R +41 DSUM 3 3 V R R R +42 DAVERAGE 3 3 V R R R +43 DMIN 3 3 V R R R +44 DMAX 3 3 V R R R +45 DSTDEV 3 3 V R R R +46 VAR 1 30 V R +47 DVAR 3 3 V R R R +48 TEXT 2 2 V V V +49 LINEST 1 2 A R R x +50 TREND 1 3 A R R R x +51 LOGEST 1 2 A R R x +52 GROWTH 1 3 A R R R x +56 PV 3 5 V V V V V V +# Built-In Sheet Functions in BIFF2 +57 FV 3 5 V V V V V V +58 NPER 3 5 V V V V V V +59 PMT 3 5 V V V V V V +60 RATE 3 6 V V V V V V V +61 MIRR 3 3 V R V V +62 IRR 1 2 V R V +63 RAND 0 0 V – x +64 MATCH 2 3 V V R R +65 DATE 3 3 V V V V +66 TIME 3 3 V V V V +67 DAY 1 1 V V +68 MONTH 1 1 V V +69 YEAR 1 1 V V +70 WEEKDAY 1 1 V V x +71 HOUR 1 1 V V +72 MINUTE 1 1 V V +73 SECOND 1 1 V V +74 NOW 0 0 V – x +75 AREAS 1 1 V R +76 ROWS 1 1 V R +77 COLUMNS 1 1 V R +78 OFFSET 3 5 R R V V V V x +82 SEARCH 2 3 V V V V +83 TRANSPOSE 1 1 A A +86 TYPE 1 1 V V +97 ATAN2 2 2 V V V +98 ASIN 1 1 V V +99 ACOS 1 1 V V +100 CHOOSE 2 30 R V R +101 HLOOKUP 3 3 V V R R x +102 VLOOKUP 3 3 V V R R x +105 ISREF 1 1 V R +109 LOG 1 2 V V V +111 CHAR 1 1 V V +112 LOWER 1 1 V V +113 UPPER 1 1 V V +114 PROPER 1 1 V V +115 LEFT 1 2 V V V +116 RIGHT 1 2 V V V +117 EXACT 2 2 V V V +118 TRIM 1 1 V V +119 REPLACE 4 4 V V V V V +120 SUBSTITUTE 3 4 V V V V V +121 CODE 1 1 V V +124 FIND 2 3 V V V V +125 CELL 1 2 V V R x +126 ISERR 1 1 V V +127 ISTEXT 1 1 V V +128 ISNUMBER 1 1 V V +129 ISBLANK 1 1 V V +130 T 1 1 V R +131 N 1 1 V R +140 DATEVALUE 1 1 V V +141 TIMEVALUE 1 1 V V +142 SLN 3 3 V V V V +143 SYD 4 4 V V V V V +144 DDB 4 5 V V V V V V +148 INDIRECT 1 2 R V V x +162 CLEAN 1 1 V V +163 MDETERM 1 1 V A +164 MINVERSE 1 1 A A +165 MMULT 2 2 A A A +167 IPMT 4 6 V V V V V V V +168 PPMT 4 6 V V V V V V V +169 COUNTA 0 30 V R +183 PRODUCT 0 30 V R +184 FACT 1 1 V V +190 ISNONTEXT 1 1 V V +191 DPRODUCT 3 3 V R R R +193 STDEVP 1 30 V R +194 VARP 1 30 V R +195 DSTDEVP 3 3 V R R R +196 DVARP 3 3 V R R R +197 TRUNC 1 1 V V x +198 ISLOGICAL 1 1 V V +199 DCOUNTA 3 3 V R R R +# New Built-In Sheet Functions in BIFF3 +49 LINEST 1 4 A R R V V x +50 TREND 1 4 A R R R V x +51 LOGEST 1 4 A R R V V x +52 GROWTH 1 4 A R R R V x +197 TRUNC 1 2 V V V x +204 YEN 1 2 V V V x +205 FINDB 2 3 V V V V +206 SEARCHB 2 3 V V V V +207 REPLACEB 4 4 V V V V V +208 LEFTB 1 2 V V V +209 RIGHTB 1 2 V V V +210 MIDB 3 3 V V V V +211 LENB 1 1 V V +212 ROUNDUP 2 2 V V V +213 ROUNDDOWN 2 2 V V V +214 ASC 1 1 V V +215 JIS 1 1 V V x +219 ADDRESS 2 5 V V V V V V +220 DAYS360 2 2 V V V x +221 TODAY 0 0 V – x +222 VDB 5 7 V V V V V V V V +227 MEDIAN 1 30 V R … +228 SUMPRODUCT 1 30 V A … +229 SINH 1 1 V V +230 COSH 1 1 V V +231 TANH 1 1 V V +232 ASINH 1 1 V V +233 ACOSH 1 1 V V +234 ATANH 1 1 V V +235 DGET 3 3 V R R R +244 INFO 1 1 V V +# New Built-In Sheet Functions in BIFF4 +14 FIXED 2 3 V V V V x +204 USDOLLAR 1 1 V V x +215 DBCS 1 1 V V x +216 RANK 2 3 V V R V +247 DB 4 5 V V V V V V +252 FREQUENCY 2 2 A R R +261 ERROR.TYPE 1 1 V V +269 AVEDEV 1 30 V R … +270 BETADIST 3 5 V V V V V V +271 GAMMALN 1 1 V V +272 BETAINV 3 5 V V V V V V +273 BINOMDIST 4 4 V V V V V +274 CHIDIST 2 2 V V V +275 CHIINV 2 2 V V V +276 COMBIN 2 2 V V V +277 CONFIDENCE 3 3 V V V V +278 CRITBINOM 3 3 V V V V +279 EVEN 1 1 V V +280 EXPONDIST 3 3 V V V V +281 FDIST 3 3 V V V V +282 FINV 3 3 V V V V +283 FISHER 1 1 V V +284 FISHERINV 1 1 V V +285 FLOOR 2 2 V V V +286 GAMMADIST 4 4 V V V V V +287 GAMMAINV 3 3 V V V V +288 CEILING 2 2 V V V +289 HYPGEOMDIST 4 4 V V V V V +290 LOGNORMDIST 3 3 V V V V +291 LOGINV 3 3 V V V V +292 NEGBINOMDIST 3 3 V V V V +293 NORMDIST 4 4 V V V V V +294 NORMSDIST 1 1 V V +295 NORMINV 3 3 V V V V +296 NORMSINV 1 1 V V +297 STANDARDIZE 3 3 V V V V +298 ODD 1 1 V V +299 PERMUT 2 2 V V V +300 POISSON 3 3 V V V V +301 TDIST 3 3 V V V V +302 WEIBULL 4 4 V V V V V +303 SUMXMY2 2 2 V A A +304 SUMX2MY2 2 2 V A A +305 SUMX2PY2 2 2 V A A +306 CHITEST 2 2 V A A +307 CORREL 2 2 V A A +308 COVAR 2 2 V A A +309 FORECAST 3 3 V V A A +310 FTEST 2 2 V A A +311 INTERCEPT 2 2 V A A +312 PEARSON 2 2 V A A +313 RSQ 2 2 V A A +314 STEYX 2 2 V A A +315 SLOPE 2 2 V A A +316 TTEST 4 4 V A A V V +317 PROB 3 4 V A A V V +318 DEVSQ 1 30 V R … +319 GEOMEAN 1 30 V R … +320 HARMEAN 1 30 V R … +321 SUMSQ 0 30 V R … +322 KURT 1 30 V R … +323 SKEW 1 30 V R … +324 ZTEST 2 3 V R V V +325 LARGE 2 2 V R V +326 SMALL 2 2 V R V +327 QUARTILE 2 2 V R V +328 PERCENTILE 2 2 V R V +329 PERCENTRANK 2 3 V R V V +330 MODE 1 30 V A +331 TRIMMEAN 2 2 V R V +332 TINV 2 2 V V V +# New Built-In Sheet Functions in BIFF5 +70 WEEKDAY 1 2 V V V x +101 HLOOKUP 3 4 V V R R V x +102 VLOOKUP 3 4 V V R R V x +220 DAYS360 2 3 V V V V x +336 CONCATENATE 0 30 V V +337 POWER 2 2 V V V +342 RADIANS 1 1 V V +343 DEGREES 1 1 V V +344 SUBTOTAL 2 30 V V R +345 SUMIF 2 3 V R V R +346 COUNTIF 2 2 V R V +347 COUNTBLANK 1 1 V R +350 ISPMT 4 4 V V V V V +351 DATEDIF 3 3 V V V V +352 DATESTRING 1 1 V V +353 NUMBERSTRING 2 2 V V V +354 ROMAN 1 2 V V V +# New Built-In Sheet Functions in BIFF8 +358 GETPIVOTDATA 2 30 +359 HYPERLINK 1 2 V V V +360 PHONETIC 1 1 V R +361 AVERAGEA 1 30 V R … +362 MAXA 1 30 V R … +363 MINA 1 30 V R … +364 STDEVPA 1 30 V R … +365 VARPA 1 30 V R … +366 STDEVA 1 30 V R … +367 VARA 1 30 V R … diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Pmt.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Pmt.java index 0ea6a7f107..58628053c0 100644 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Pmt.java +++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Pmt.java @@ -14,61 +14,78 @@ * 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.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.EvaluationException; import org.apache.poi.hssf.record.formula.eval.NumberEval; import org.apache.poi.hssf.record.formula.eval.NumericValueEval; import org.apache.poi.hssf.record.formula.eval.ValueEval; -public class Pmt extends FinanceFunction { +/** + * Implementation for the PMT() Excel function. + * + * Syntax:
6$35LVBl)JlQVOAekG zcB+SALG`$x9?QJg*8I>hh{UTjf=O&YV{T8YQm^bpO06u;1lX zfq^Ek3hXg?RbZFQs{;F2UKJP=11l^y`U9gufq#DptBw+Hqs!?TU^KcXVuCQ_<^V!B z^ao*o&jEz4=?}snoC65m)gOcrDF+a`us;Zg;~YTf*8U*e!5b80pefio+ycx2B-lD* za{~#s4mTllkR;eT+{MfRB-lFKGS2}d*gD)l%Yfj)J(lRc)6f`f9lhym4;Q{5!Pen! zZVr+JTL&X=E+E0yiRK0pY@I2&fdpFzOX0zrqc_|AJK(h3K!U9^JvWeG>&(avB-lDL za{~#s&aB)(f~`}P2H||EUy72hc^LZ+UnHOXO)_JhTaCeMHcAw$!HZ=--Xq>1r%s(p zgA}KL_wL=BjHXh=gI4080b8XZ9<)6XQ>bc`)k1M%$K=_vyYId`OQ={ZmL-&vW(!4{ zhUONR)|8W$J&T=#;(_x5bDmt2Z-v@?E7av%;p}t;TAK!RDK>jrQjcOfDzXAr7w!tS zk3I7@r;nL)8-72L39U4#iz|JH#NZ&0y|%$YlCfZr##}(m;l{M x%2<7kC{eUkXD6f$G1Clve!xrmF*tqxIp^jKJJlxuipV;_V$Ho z^-z~t>q* >L!_zRclJ(ZJ)mLiZ`1IvY8j` zX_LWbUJjl%(Dc~A8{TZjm~1>eZCU^ur>6}xz4iEG-fYI2Y&<+|Rsb8Prwue6f8z;n zHsee-9-cNQfQ{4B2AT$rz3R !P6QVZ+qytX2XDnl#XeWOg0{#Ha&oi)6*InUpaJ}H=9b6 zjfbaI1+Z~?T0`S6Uq0;3X0pk~!_#U4*f>3{q4DUQ&w8_onru8gtv-N_)6*In4?LfW z(57vsm~1>eZC(Hyr>8YEetc}dS8Imidu}Xr)8poHW89pSEcP8MMb=#Z3vbYA8BlnX z2|C39b$SuLLs`4Z8+3XG6#ip^&M-ioJ|lAE=U?##osj{Bx0s-_4N#|ti1fDpz#DXC z1{A(wg4P $?$be1%mCYS3Jsr)7_O8yp$n|c(P(`v-^w}ex z4eJ1O<}6yVnn@6pGijRvw;>dRA{@} zemW2e%bebVWM3re7NxKNOjhFXoIbn >VSL+#>tb8CC&)+p8rhM)yy(Coz!h`!$r zLAOFcy+%+jfDSYHl06!Zu2>AobRaws8iqxN101o>1TXgh*YVE>JQ@4Zu|J|A1aEYL zBL bJe3n!N!Um(zq#-3AFmj4r%(y4r%)7K&Vs}3AWwW^dywUziu!c4d^vW2iZ1v zhI~dym(5AYNTQ!?N%WH~iGE@zJGZwGx|{A6p|B8!Sc^7yrx*TI8C`WTU3Fc1q66BR z>#kKW9OhXE??}LK)K|8*TZCAmAi5It0Auf=V4Q-W!nO6o%BfuY3)H(EM|5lLC%Ra< zoCh1phUV^0hAbUkV{So1rHIrUz@Z!c%8puIVU>fp((o;jE9Dl)Cdq!Zt{i{s0J253 z_6mr+TivZf+Zhabu6z-+*e=&956YBa588@RG=WgLKsKv0$TwmJyNR3AXmDFkXUopR zk+E{v!BTsz-t4;z$F}csykoVS;KdgH?#F?6e1^xU11o$Z^0XB}7Mb*(C7*z9rzA`i zk(NjWvQ5)J;NVk84ua1?$D0*zT5<%mBMutnx(T$K95mMEK?r@kyv%jHyfie5uT|oA zPd(UR4`IkS3;fu wW7~a*Ka6FucJ*f;M5{f z>w3I-I!s=pk-w=*-=MBDQMyf~w_-fKYTs9-QQnTtcHG~|^Q}Onb}eX`T4+@1_c8l3 zA^n&^^cy-rwRBp-!9}I@kOBoUMln$b+NzNdk432CjM~`Na3PHk7WnIznnul-G`;EP zE=OIM< SK&0t;;uAMVP}<9_~2W>6pl; zBc;-E{jVt8j}}f;dLJ%hYtLWz? Ui}SWcII_k@QP}ryd?3WasEqM;Oo23SX<2?8#fwP70}HdY!^v;`B2^fb zGlid&<8ZJZylusVft#JR_*;q{%tw@6mZ37!BFM83PQK4&;B!Nh08P=6fT7aX$Qaq` zC ext7}}BO z7bkDL 1%JG5>Jk>ZWP(PXAoS~-qPK*v#Tu;y E`FGWq9BF^2^is zTe4K&1Ld=&p!SDedj6&Ux(Q_m4x#-uAKlOP{|cFXg6&_6%qVmvG7meoBJ(gGXPRsS zC+lqYb;uRSHy~r95(Bl?&+Yg$^#M{Uo(xr3d?qH7`B@1jl!N_M%@|}TC`6=2S$acP z_x7FJ;_<{z1 s*Gc~rs{O#sUXdu%M*R-{@x5RaKj5gHQH%8Omr95y&dt2K=%*?sFfgW3T1^upW Tp?tXL=+|;q<(Yz?vj+YHqmLN~ literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java index b79236ff08..3b98aed0ae 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java +++ b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java @@ -293,7 +293,7 @@ public final class TestFormulaParser extends TestCase { assertEquals("FOO", tname.toFormulaString(w)); AbstractFunctionPtg tfunc = (AbstractFunctionPtg) ptg[1]; - assertEquals("externalflag", tfunc.getName()); + assertTrue(tfunc.isExternalFunction()); } public void testEmbeddedSlash() { @@ -888,4 +888,17 @@ public final class TestFormulaParser extends TestCase { assertTrue(e.getMessage().startsWith("Too few arguments suppled to operation token")); } } + public void testFuncPtgSelection() { + Workbook book = Workbook.createWorkbook(); + Ptg[] ptgs; + ptgs = FormulaParser.parse("countif(A1:A2, 1)", book); + assertEquals(3, ptgs.length); + if(FuncVarPtg.class == ptgs[2].getClass()) { + throw new AssertionFailedError("Identified bug 44675"); + } + assertEquals(FuncPtg.class, ptgs[2].getClass()); + ptgs = FormulaParser.parse("sin(1)", book); + assertEquals(2, ptgs.length); + assertEquals(FuncPtg.class, ptgs[1].getClass()); + } } diff --git a/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java b/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java index b1acfeafa1..9da8f45ebc 100755 --- a/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java +++ b/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java @@ -14,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - package org.apache.poi.hssf.record; @@ -28,10 +27,10 @@ import junit.framework.TestSuite; * * @author Josh Micich */ -public class AllRecordTests { +public final class AllRecordTests { public static Test suite() { - TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record"); + TestSuite result = new TestSuite(AllRecordTests.class.getName()); result.addTest(AllFormulaTests.suite()); @@ -56,6 +55,7 @@ public class AllRecordTests { result.addTestSuite(TestEmbeddedObjectRefSubRecord.class); result.addTestSuite(TestEndSubRecord.class); result.addTestSuite(TestEscherAggregate.class); + result.addTestSuite(TestExternalNameRecord.class); result.addTestSuite(TestFontBasisRecord.class); result.addTestSuite(TestFontIndexRecord.class); result.addTestSuite(TestFormulaRecord.class); diff --git a/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java b/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java new file mode 100644 index 0000000000..960627a39b --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java @@ -0,0 +1,55 @@ +/* ==================================================================== + 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; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; +/** + * + * @author Josh Micich + */ +public final class TestExternalNameRecord extends TestCase { + + private static final byte[] dataFDS = { + 0, 0, 0, 0, 0, 0, 3, 0, 70, 68, 83, 0, 0, + }; + private static ExternalNameRecord createSimpleENR() { + return new ExternalNameRecord(new TestcaseRecordInputStream((short)0x0023, dataFDS)); + } + public void testBasicDeserializeReserialize() { + + ExternalNameRecord enr = createSimpleENR(); + assertEquals( "FDS", enr.getText()); + + try { + TestcaseRecordInputStream.confirmRecordEncoding(0x0023, dataFDS, enr.serialize()); + } catch (ArrayIndexOutOfBoundsException e) { + if(e.getMessage().equals("15")) { + throw new AssertionFailedError("Identified bug 44695"); + } + } + } + + public void testBasicSize() { + ExternalNameRecord enr = createSimpleENR(); + if(enr.getRecordSize() == 13) { + throw new AssertionFailedError("Identified bug 44695"); + } + assertEquals(17, enr.getRecordSize()); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java b/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java index 92ca4ba044..b50e95fa86 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java @@ -17,6 +17,8 @@ package org.apache.poi.hssf.record.formula; +import org.apache.poi.hssf.record.formula.function.AllFormulaFunctionTests; + import junit.framework.Test; import junit.framework.TestSuite; @@ -28,12 +30,12 @@ import junit.framework.TestSuite; public class AllFormulaTests { public static Test suite() { - TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula"); + TestSuite result = new TestSuite(AllFormulaTests.class.getName()); result.addTestSuite(TestArea3DPtg.class); result.addTestSuite(TestAreaErrPtg.class); - result.addTestSuite(TestAreaPtg.class); - result.addTestSuite(TestErrPtg.class); - result.addTestSuite(TestExternalFunctionFormulas.class); + result.addTestSuite(TestAreaPtg.class); + result.addTestSuite(TestErrPtg.class); + result.addTestSuite(TestExternalFunctionFormulas.class); result.addTestSuite(TestFuncPtg.class); result.addTestSuite(TestIntersectionPtg.class); result.addTestSuite(TestPercentPtg.class); @@ -42,6 +44,7 @@ public class AllFormulaTests { result.addTestSuite(TestReferencePtg.class); result.addTestSuite(TestSheetNameFormatter.class); result.addTestSuite(TestUnionPtg.class); + result.addTest(AllFormulaFunctionTests.suite()); return result; } } diff --git a/src/testcases/org/apache/poi/hssf/record/formula/function/AllFormulaFunctionTests.java b/src/testcases/org/apache/poi/hssf/record/formula/function/AllFormulaFunctionTests.java new file mode 100644 index 0000000000..8a59095e46 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/function/AllFormulaFunctionTests.java @@ -0,0 +1,37 @@ +/* ==================================================================== + 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.function; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Collects all tests for this package. + * + * @author Josh Micich + */ +public class AllFormulaFunctionTests { + + public static Test suite() { + TestSuite result = new TestSuite(AllFormulaFunctionTests.class.getName()); + result.addTestSuite(TestFunctionMetadataRegistry.class); + result.addTestSuite(TestParseMissingBuiltInFuncs.class); + result.addTestSuite(TestReadMissingBuiltInFuncs.class); + return result; + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/function/ExcelFileFormatDocFunctionExtractor.java b/src/testcases/org/apache/poi/hssf/record/formula/function/ExcelFileFormatDocFunctionExtractor.java new file mode 100644 index 0000000000..c7d74b6f75 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/function/ExcelFileFormatDocFunctionExtractor.java @@ -0,0 +1,503 @@ +/* ==================================================================== + 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.function; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.zip.CRC32; +import java.util.zip.ZipException; +import java.util.zip.ZipFile; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +/** + * This class is not used during normal POI run-time but is used at development time to generate + * the file 'functionMetadata.txt'. There are more than 300 built-in functions in Excel and the + * intention of this class is to make it easier to maintain the metadata, by extracting it from + * a reliable source. + * + * @author Josh Micich + */ +public class ExcelFileFormatDocFunctionExtractor { + + private static final String SOURCE_DOC_FILE_NAME = "excelfileformat.odt"; + + private static final class FunctionData { + + private final int _index; + private final boolean _hasFootnote; + private final String _name; + private final int _minParams; + private final int _maxParams; + private final String _returnClass; + private final String _paramClasses; + private final boolean _isVolatile; + + public FunctionData(int funcIx, boolean hasFootnote, String funcName, int minParams, int maxParams, + String returnClass, String paramClasses, boolean isVolatile) { + _index = funcIx; + _hasFootnote = hasFootnote; + _name = funcName; + _minParams = minParams; + _maxParams = maxParams; + _returnClass = returnClass; + _paramClasses = paramClasses; + _isVolatile = isVolatile; + } + public int getIndex() { + return _index; + } + public String getName() { + return _name; + } + public boolean hasFootnote() { + return _hasFootnote; + } + public String formatAsDataLine() { + return _index + "\t" + _name + "\t" + _minParams + "\t" + + _maxParams + "\t" + _returnClass + "\t" + _paramClasses + + "\t" + checkMark(_isVolatile) + "\t" + checkMark(_hasFootnote); + } + private static String checkMark(boolean b) { + return b ? "x" : ""; + } + } + + private static final class FunctionDataCollector { + + + private final Map _allFunctionsByIndex; + private final Map _allFunctionsByName; + private final Set _groupFunctionIndexes; + private final Set _groupFunctionNames; + private final PrintStream _ps; + + public FunctionDataCollector(PrintStream ps) { + _ps = ps; + _allFunctionsByIndex = new HashMap(); + _allFunctionsByName = new HashMap(); + _groupFunctionIndexes = new HashSet(); + _groupFunctionNames = new HashSet(); + } + + public void addFuntion(int funcIx, boolean hasFootnote, String funcName, int minParams, int maxParams, + String returnClass, String paramClasses, String volatileFlagStr) { + boolean isVolatile = volatileFlagStr.length() > 0; + + Integer funcIxKey = new Integer(funcIx); + if(!_groupFunctionIndexes.add(funcIxKey)) { + throw new RuntimeException("Duplicate function index (" + funcIx + ")"); + } + if(!_groupFunctionNames.add(funcName)) { + throw new RuntimeException("Duplicate function name '" + funcName + "'"); + } + + checkRedefinedFunction(hasFootnote, funcName, funcIxKey); + FunctionData fd = new FunctionData(funcIx, hasFootnote, funcName, + minParams, maxParams, returnClass, paramClasses, isVolatile); + + _allFunctionsByIndex.put(funcIxKey, fd); + _allFunctionsByName.put(funcName, fd); + } + + private void checkRedefinedFunction(boolean hasNote, String funcName, Integer funcIxKey) { + FunctionData fdPrev; + fdPrev = (FunctionData) _allFunctionsByIndex.get(funcIxKey); + if(fdPrev != null) { + if(fdPrev.hasFootnote() && hasNote) { + // func def can change if both have a foot-note + _allFunctionsByName.remove(fdPrev.getName()); + } else { + throw new RuntimeException("changing function definition without foot-note"); + } + } + fdPrev = (FunctionData) _allFunctionsByName.get(funcName); + if(fdPrev != null) { + if(fdPrev.hasFootnote() && hasNote) { + // func def can change if both have a foot-note + _allFunctionsByIndex.remove(new Integer(fdPrev.getIndex())); + } else { + throw new RuntimeException("changing function definition without foot-note"); + } + } + } + + public void endTableGroup(String headingText) { + Integer[] keys = new Integer[_groupFunctionIndexes.size()]; + _groupFunctionIndexes.toArray(keys); + _groupFunctionIndexes.clear(); + _groupFunctionNames.clear(); + Arrays.sort(keys); + + _ps.println("# " + headingText); + for (int i = 0; i < keys.length; i++) { + FunctionData fd = (FunctionData) _allFunctionsByIndex.get(keys[i]); + _ps.println(fd.formatAsDataLine()); + } + } + } + + /** + * To avoid drag-in - parse XML using only JDK. + */ + private static class EFFDocHandler implements ContentHandler { + private static final String[] HEADING_PATH_NAMES = { + "office:document-content", "office:body", "office:text", "text:h", + }; + private static final String[] TABLE_BASE_PATH_NAMES = { + "office:document-content", "office:body", "office:text", "table:table", + }; + private static final String[] TABLE_ROW_RELPATH_NAMES = { + "table:table-row", + }; + private static final String[] TABLE_CELL_RELPATH_NAMES = { + "table:table-row", "table:table-cell", "text:p", + }; + private static final String[] NOTE_REF_RELPATH_NAMES = { + "table:table-row", "table:table-cell", "text:p", "text:span", "text:note-ref", + }; + + + private final Stack _elemNameStack; + /** true
only when parsing the target tables */ + private boolean _isInsideTable; + + private final List _rowData; + private final StringBuffer _textNodeBuffer; + private final List _rowNoteFlags; + private boolean _cellHasNote; + + private final FunctionDataCollector _fdc; + private String _lastHeadingText; + + public EFFDocHandler(FunctionDataCollector fdc) { + _fdc = fdc; + _elemNameStack = new Stack(); + _isInsideTable = false; + _rowData = new ArrayList(); + _textNodeBuffer = new StringBuffer(); + _rowNoteFlags = new ArrayList(); + } + + private boolean matchesTargetPath() { + return matchesPath(0, TABLE_BASE_PATH_NAMES); + } + private boolean matchesRelPath(String[] pathNames) { + return matchesPath(TABLE_BASE_PATH_NAMES.length, pathNames); + } + private boolean matchesPath(int baseStackIndex, String[] pathNames) { + if(_elemNameStack.size() != baseStackIndex + pathNames.length) { + return false; + } + for (int i = 0; i < pathNames.length; i++) { + if(!_elemNameStack.get(baseStackIndex + i).equals(pathNames[i])) { + return false; + } + } + return true; + } + public void characters(char[] ch, int start, int length) { + // only 2 text nodes where text is collected: + if(matchesRelPath(TABLE_CELL_RELPATH_NAMES) || matchesPath(0, HEADING_PATH_NAMES)) { + _textNodeBuffer.append(ch, start, length); + } + } + + public void endElement(String namespaceURI, String localName, String name) { + String expectedName = (String) _elemNameStack.peek(); + if(expectedName != name) { + throw new RuntimeException("close tag mismatch"); + } + if(matchesPath(0, HEADING_PATH_NAMES)) { + _lastHeadingText = _textNodeBuffer.toString().trim(); + _textNodeBuffer.setLength(0); + } + if(_isInsideTable) { + if(matchesTargetPath()) { + _fdc.endTableGroup(_lastHeadingText); + _isInsideTable = false; + } else if(matchesRelPath(TABLE_ROW_RELPATH_NAMES)) { + String[] cellData = new String[_rowData.size()]; + _rowData.toArray(cellData); + _rowData.clear(); + Boolean[] noteFlags = new Boolean[_rowNoteFlags.size()]; + _rowNoteFlags.toArray(noteFlags); + _rowNoteFlags.clear(); + processTableRow(cellData, noteFlags); + } else if(matchesRelPath(TABLE_CELL_RELPATH_NAMES)) { + _rowData.add(_textNodeBuffer.toString().trim()); + _rowNoteFlags.add(Boolean.valueOf(_cellHasNote)); + _textNodeBuffer.setLength(0); + } + } + _elemNameStack.pop(); + } + + private void processTableRow(String[] cellData, Boolean[] noteFlags) { + // each table row of the document contains data for two functions + if(cellData.length != 15) { + throw new RuntimeException("Bad table row size"); + } + processFunction(cellData, noteFlags, 0); + processFunction(cellData, noteFlags, 8); + } + public void processFunction(String[] cellData, Boolean[] noteFlags, int i) { + String funcIxStr = cellData[i + 0]; + if (funcIxStr.length() < 1) { + // empty (happens on the right hand side when there is an odd number of functions) + return; + } + int funcIx = parseInt(funcIxStr); + + boolean hasFootnote = noteFlags[i + 1].booleanValue(); + String funcName = cellData[i + 1]; + int minParams = parseInt(cellData[i + 2]); + int maxParams = parseInt(cellData[i + 3]); + + String returnClass = cellData[i + 4]; + String paramClasses = cellData[i + 5]; + String volatileFlagStr = cellData[i + 6]; + + _fdc.addFuntion(funcIx, hasFootnote, funcName, minParams, maxParams, returnClass, paramClasses, volatileFlagStr); + } + private static int parseInt(String valStr) { + try { + return Integer.parseInt(valStr); + } catch (NumberFormatException e) { + throw new RuntimeException("Value '" + valStr + "' could not be parsed as an integer"); + } + } + public void startElement(String namespaceURI, String localName, String name, Attributes atts) { + _elemNameStack.add(name); + if(matchesTargetPath()) { + String tableName = atts.getValue("table:name"); + if(tableName.startsWith("tab_fml_func") && !tableName.equals("tab_fml_func0")) { + _isInsideTable = true; + } + return; + } + if(matchesPath(0, HEADING_PATH_NAMES)) { + _textNodeBuffer.setLength(0); + } else if(matchesRelPath(TABLE_ROW_RELPATH_NAMES)) { + _rowData.clear(); + _rowNoteFlags.clear(); + } else if(matchesRelPath(TABLE_CELL_RELPATH_NAMES)) { + _textNodeBuffer.setLength(0); + _cellHasNote = false; + } else if(matchesRelPath(NOTE_REF_RELPATH_NAMES)) { + _cellHasNote = true; + } + } + + public void endDocument() { + // do nothing + } + public void endPrefixMapping(String prefix) { + // do nothing + } + public void ignorableWhitespace(char[] ch, int start, int length) { + // do nothing + } + public void processingInstruction(String target, String data) { + // do nothing + } + public void setDocumentLocator(Locator locator) { + // do nothing + } + public void skippedEntity(String name) { + // do nothing + } + public void startDocument() { + // do nothing + } + public void startPrefixMapping(String prefix, String uri) { + // do nothing + } + } + + private static void extractFunctionData(FunctionDataCollector fdc, InputStream is) { + System.setProperty("org.xml.sax.driver", "org.apache.crimson.parser.XMLReaderImpl"); + + XMLReader xr; + try { + xr = XMLReaderFactory.createXMLReader(); + } catch (SAXException e) { + throw new RuntimeException(e); + } + xr.setContentHandler(new EFFDocHandler(fdc)); + + InputSource inSrc = new InputSource(is); + + try { + xr.parse(inSrc); + is.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (SAXException e) { + throw new RuntimeException(e); + } + } + + private static void processFile(File effDocFile, File outFile) { + OutputStream os; + try { + os = new FileOutputStream(outFile); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + PrintStream ps = new PrintStream(os); + outputLicenseHeader(ps); + Class genClass = ExcelFileFormatDocFunctionExtractor.class; + ps.println("# Created by (" + genClass.getName() + ")"); + // identify the source file + ps.print("# from source file '" + SOURCE_DOC_FILE_NAME + "'"); + ps.println(" (size=" + effDocFile.length() + ", crc=" + getFileCRC(effDocFile) + ")"); + ps.println("#"); + ps.println("#Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote )"); + ps.println(""); + try { + ZipFile zf = new ZipFile(effDocFile); + InputStream is = zf.getInputStream(zf.getEntry("content.xml")); + extractFunctionData(new FunctionDataCollector(ps), is); + zf.close(); + } catch (ZipException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + ps.close(); + } + + private static void outputLicenseHeader(PrintStream ps) { + String[] lines= { + "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.", + }; + for (int i = 0; i < lines.length; i++) { + ps.print("# "); + ps.println(lines[i]); + } + ps.println(); + } + + /** + * Helps identify the source file + */ + private static String getFileCRC(File f) { + CRC32 crc = new CRC32(); + byte[]buf = new byte[2048]; + try { + InputStream is = new FileInputStream(f); + while(true) { + int bytesRead = is.read(buf); + if(bytesRead<1) { + break; + } + crc.update(buf, 0, bytesRead); + } + is.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + return "0x" + Long.toHexString(crc.getValue()).toUpperCase(); + } + + private static File getSourceFile() { + if (true) { + File dir = new File("c:/josh/ref-docs"); + File effDocFile = new File(dir, SOURCE_DOC_FILE_NAME); + return effDocFile; + } + URL url; + try { + url = new URL("http://sc.openoffice.org/" + SOURCE_DOC_FILE_NAME); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + + File result; + byte[]buf = new byte[2048]; + try { + URLConnection conn = url.openConnection(); + InputStream is = conn.getInputStream(); + System.out.println("downloading " + url.toExternalForm()); + result = File.createTempFile("excelfileformat", "odt"); + OutputStream os = new FileOutputStream(result); + while(true) { + int bytesRead = is.read(buf); + if(bytesRead<1) { + break; + } + os.write(buf, 0, bytesRead); + } + is.close(); + os.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + System.out.println("file downloaded ok"); + return result; + } + + public static void main(String[] args) { + + File effDocFile = getSourceFile(); + if(!effDocFile.exists()) { + throw new RuntimeException("file '" + effDocFile.getAbsolutePath() + "' does not exist"); + } + + File outFile = new File("functionMetadata-asGenerated.txt"); + processFile(effDocFile, outFile); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/function/TestFunctionMetadataRegistry.java b/src/testcases/org/apache/poi/hssf/record/formula/function/TestFunctionMetadataRegistry.java new file mode 100644 index 0000000000..edb215ec50 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/function/TestFunctionMetadataRegistry.java @@ -0,0 +1,43 @@ +/* ==================================================================== + 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.function; + +import junit.framework.TestCase; +/** + * + * @author Josh Micich + */ +public final class TestFunctionMetadataRegistry extends TestCase { + + public void testWellKnownFunctions() { + confirmFunction(0, "COUNT"); + confirmFunction(1, "IF"); + + } + + private static void confirmFunction(int index, String funcName) { + FunctionMetadata fm; + fm = FunctionMetadataRegistry.getFunctionByIndex(index); + assertNotNull(fm); + assertEquals(funcName, fm.getName()); + + fm = FunctionMetadataRegistry.getFunctionByName(funcName); + assertNotNull(fm); + assertEquals(index, fm.getIndex()); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/function/TestParseMissingBuiltInFuncs.java b/src/testcases/org/apache/poi/hssf/record/formula/function/TestParseMissingBuiltInFuncs.java new file mode 100644 index 0000000000..fe1b8fccc8 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/function/TestParseMissingBuiltInFuncs.java @@ -0,0 +1,79 @@ +/* ==================================================================== + 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.function; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.apache.poi.hssf.model.FormulaParser; +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.formula.AbstractFunctionPtg; +import org.apache.poi.hssf.record.formula.FuncPtg; +import org.apache.poi.hssf.record.formula.FuncVarPtg; +import org.apache.poi.hssf.record.formula.Ptg; +/** + * @author Josh Micich + */ +public final class TestParseMissingBuiltInFuncs extends TestCase { + + private static Ptg[] parse(String formula) { + Workbook book = Workbook.createWorkbook(); + return FormulaParser.parse(formula, book); + } + private static void confirmFunc(String formula, int expPtgArraySize, boolean isVarArgFunc, int funcIx) { + Ptg[] ptgs = parse(formula); + Ptg ptgF = ptgs[ptgs.length-1]; // func is last RPN token in all these formulas + + if(!(ptgF instanceof AbstractFunctionPtg)) { + throw new RuntimeException("function token missing"); + } + AbstractFunctionPtg func = (AbstractFunctionPtg) ptgF; + if(func.getFunctionIndex() == 255) { + throw new AssertionFailedError("Failed to recognise built-in function in formula '" + + formula + "'"); + } + + assertEquals(expPtgArraySize, ptgs.length); + assertEquals(funcIx, func.getFunctionIndex()); + Class expCls = isVarArgFunc ? FuncVarPtg.class : FuncPtg.class; + assertEquals(expCls, ptgF.getClass()); + } + + public void testDatedif() { + int expSize = 4; // NB would be 5 if POI added tAttrVolatile properly + confirmFunc("DATEDIF(NOW(),NOW(),\"d\")", expSize, false, 351); + } + + public void testDdb() { + confirmFunc("DDB(1,1,1,1,1)", 6, true, 144); + } + public void testAtan() { + confirmFunc("ATAN(1)", 2, false, 18); + } + + public void testUsdollar() { + confirmFunc("USDOLLAR(1)", 2, false, 204); + } + + public void testDBCS() { + confirmFunc("DBCS(\"abc\")", 2, false, 215); + } + public void testIsnontext() { + confirmFunc("ISNONTEXT(\"abc\")", 2, false, 190); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/function/TestReadMissingBuiltInFuncs.java b/src/testcases/org/apache/poi/hssf/record/formula/function/TestReadMissingBuiltInFuncs.java new file mode 100644 index 0000000000..7e1d0317ec --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/function/TestReadMissingBuiltInFuncs.java @@ -0,0 +1,142 @@ +/* ==================================================================== + 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.function; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; +/** + * Tests reading from a sample spreadsheet some built-in functions that were not properly + * registered in POI as bug #44675 (March 2008). + * + * @author Josh Micich + */ +public final class TestReadMissingBuiltInFuncs extends TestCase { + + private HSSFSheet sht; + + protected void setUp() { + String cwd = System.getProperty("HSSF.testdata.path"); + HSSFWorkbook wb; + try { + InputStream is = new FileInputStream(new File(cwd, "missingFuncs44675.xls")); + wb = new HSSFWorkbook(is); + } catch (IOException e) { + throw new RuntimeException(e); + } + sht = wb.getSheetAt(0); + } + + public void testDatedif() { + + String formula; + try { + formula = getCellFormula(0); + } catch (IllegalStateException e) { + if(e.getMessage().startsWith("Too few arguments")) { + if(e.getMessage().indexOf("AttrPtg") > 0) { + throw afe("tAttrVolatile not supported in FormulaParser.toFormulaString"); + } + throw afe("NOW() registered with 1 arg instead of 0"); + } + if(e.getMessage().startsWith("too much stuff")) { + throw afe("DATEDIF() not registered"); + } + // some other unexpected error + throw e; + } + assertEquals("DATEDIF(NOW(),NOW(),\"d\")", formula); + } + public void testDdb() { + + String formula = getCellFormula(1); + if("externalflag(1,1,1,1,1)".equals(formula)) { + throw afe("DDB() not registered"); + } + assertEquals("DDB(1,1,1,1,1)", formula); + } + public void testAtan() { + + String formula = getCellFormula(2); + if(formula.equals("ARCTAN(1)")) { + throw afe("func ix 18 registered as ARCTAN() instead of ATAN()"); + } + assertEquals("ATAN(1)", formula); + } + + public void testUsdollar() { + + String formula = getCellFormula(3); + if(formula.equals("YEN(1)")) { + throw afe("func ix 204 registered as YEN() instead of USDOLLAR()"); + } + assertEquals("USDOLLAR(1)", formula); + } + + public void testDBCS() { + + String formula; + try { + formula = getCellFormula(4); + } catch (IllegalStateException e) { + if(e.getMessage().startsWith("too much stuff")) { + throw afe("DBCS() not registered"); + } + // some other unexpected error + throw e; + } catch (NegativeArraySizeException e) { + throw afe("found err- DBCS() registered with -1 args"); + } + if(formula.equals("JIS(\"abc\")")) { + throw afe("func ix 215 registered as JIS() instead of DBCS()"); + } + assertEquals("DBCS(\"abc\")", formula); + } + public void testIsnontext() { + + String formula; + try { + formula = getCellFormula(5); + } catch (IllegalStateException e) { + if(e.getMessage().startsWith("too much stuff")) { + throw afe("ISNONTEXT() registered with wrong index"); + } + // some other unexpected error + throw e; + } + assertEquals("ISNONTEXT(\"abc\")", formula); + } + + private String getCellFormula(int rowIx) { + String result = sht.getRow(rowIx).getCell((short)0).getCellFormula(); + if (false) { + System.err.println(result); + } + return result; + } + private static AssertionFailedError afe(String msg) { + return new AssertionFailedError(msg); + } +} diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index 05ba29d09e..94c19cbc04 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -1218,6 +1218,30 @@ extends TestCase { assertEquals(1, wb.getNumberOfSheets()); } + + /** + * User reported the wrong number of rows from the + * iterator, but we can't replicate that + */ + public void test44693() throws Exception { + FileInputStream in = new FileInputStream(new File(cwd, "44693.xls")); + + HSSFWorkbook wb = new HSSFWorkbook(in); + HSSFSheet s = wb.getSheetAt(0); + + // Rows are 1 to 713 + assertEquals(0, s.getFirstRowNum()); + assertEquals(712, s.getLastRowNum()); + assertEquals(713, s.getPhysicalNumberOfRows()); + + // Now check the iterator + int rowsSeen = 0; + for(Iterator i = s.rowIterator(); i.hasNext(); ) { + HSSFRow r = (HSSFRow)i.next(); + rowsSeen++; + } + assertEquals(713, rowsSeen); + } }