+ *
+ *
+ *
+ * Error Code
+ *
+ * |
+ *
+ *
+ * Message
+ *
+ * |
+ *
+ *
+ * Explanation
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 501
+ *
+ * |
+ *
+ *
+ * Invalid character
+ *
+ * |
+ *
+ *
+ * Character in a formula is not valid, for example, "=1Eq" instead of
+ * "=1E2".
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 502
+ *
+ * |
+ *
+ *
+ * Invalid argument
+ *
+ * |
+ *
+ *
+ * Function argument is not valid, for example, a negative number for the root
+ * function.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 503
+ *
+ * |
+ *
+ *
+ * Invalid floating point operation
+ *
+ * |
+ *
+ *
+ * Division by 0, or another calculation that results in an overflow of the
+ * defined value range.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 504
+ *
+ * |
+ *
+ *
+ * Parameter list error
+ *
+ * |
+ *
+ *
+ * Function parameter is not valid, for example, text instead of a number, or a
+ * domain reference instead of cell reference.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 505
+ *
+ * |
+ *
+ *
+ * Internal syntax error
+ *
+ * |
+ *
+ *
+ * Not used
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 506
+ *
+ * |
+ *
+ *
+ * Invalid semicolon
+ *
+ * |
+ *
+ *
+ * Not used
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 507
+ *
+ * |
+ *
+ *
+ * Error: Pair missing
+ *
+ * |
+ *
+ *
+ * Not used
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 508
+ *
+ * |
+ *
+ *
+ * Error: Pair missing
+ *
+ * |
+ *
+ *
+ * Missing bracket, for example, closing brackets, but no opening brackets
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 509
+ *
+ * |
+ *
+ *
+ * Missing operator
+ *
+ * |
+ *
+ *
+ * Operator is missing, for example, "=2(3+4) * ", where the operator
+ * between "2" and "(" is missing.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 510
+ *
+ * |
+ *
+ *
+ * Missing variable
+ *
+ * |
+ *
+ *
+ * Variable is missing, for example when two operators are together
+ * "=1+*2".
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 511
+ *
+ * |
+ *
+ *
+ * Missing variable
+ *
+ * |
+ *
+ *
+ * Function requires more variables than are provided, for example, AND() and
+ * OR().
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 512
+ *
+ * |
+ *
+ *
+ * Formula overflow
+ *
+ * |
+ *
+ *
+ * Compiler: the total number of internal tokens, (that is, operators,
+ * variables, brackets) in the formula exceeds 512. Interpreter: the
+ * total number of matrices that the formula creates exceeds 150. This includes
+ * basic functions that receive too large an array as a parameter (max. 0xFFFE,
+ * for example, 65534 bytes).
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 513
+ *
+ * |
+ *
+ *
+ * String overflow
+ *
+ * |
+ *
+ *
+ * Compiler: an identifier in the formula exceeds 64 KB in size.
+ * Interpreter: a result of a string operation exceeds 64 KB in size.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 514
+ *
+ * |
+ *
+ *
+ * Internal overflow
+ *
+ * |
+ *
+ *
+ * Sort operation attempted on too much numerical data (max. 100000) or a
+ * calculation stack overflow.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 515
+ *
+ * |
+ *
+ *
+ * Internal syntax error
+ *
+ * |
+ *
+ *
+ * Not used
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 516
+ *
+ * |
+ *
+ *
+ * Internal syntax error
+ *
+ * |
+ *
+ *
+ * Matrix is expected on the calculation stack, but is not available.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 517
+ *
+ * |
+ *
+ *
+ * Internal syntax error
+ *
+ * |
+ *
+ *
+ * Unknown code, for example, a document with a newer function is loaded in an
+ * older version that does not contain the function.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 518
+ *
+ * |
+ *
+ *
+ * Internal syntax error
+ *
+ * |
+ *
+ *
+ * Variable is not available
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 519
+ *
+ * |
+ *
+ *
+ * No result (#VALUE is in the cell rather than Err:519!)
+ *
+ * |
+ *
+ *
+ * Formula yields a value that does not corresponds to the definition, or a cell
+ * that is referenced in the formula contains text instead of a number.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 520
+ *
+ * |
+ *
+ *
+ * Internal syntax error
+ *
+ * |
+ *
+ *
+ * Compiler creates an unknown compiler code.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 521
+ *
+ * |
+ *
+ *
+ * Internal syntax error
+ *
+ * |
+ *
+ *
+ * No result.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 522
+ *
+ * |
+ *
+ *
+ * Circular reference
+ *
+ * |
+ *
+ *
+ * Formula refers directly or indirectly to itself and the iterations option is
+ * not selected under Tools - Options - Table Document - Calculate.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 523
+ *
+ * |
+ *
+ *
+ * The calculation procedure does not converge
+ *
+ * |
+ *
+ *
+ * Financial statistics function missed a targeted value or iterations of
+ * circular references do not reach the minimum change within the maximum steps
+ * that are set.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 524
+ *
+ * |
+ *
+ *
+ * invalid references
+ * (instead of Err:524 cell contains #REF)
+ *
+ * |
+ *
+ *
+ * Compiler: a column or row description name could not be resolved.
+ * Interpreter: in a formula, the column, row, or sheet that contains a
+ * referenced cell is missing.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 525
+ *
+ * |
+ *
+ *
+ * invalid names (instead of
+ * Err:525 cell contains #NAME?)
+ *
+ * |
+ *
+ *
+ * An identifier could not be evaluated, for example, no valid reference, no
+ * valid domain name, no column/row label, no macro, incorrect decimal divider,
+ * add-in not found.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 526
+ *
+ * |
+ *
+ *
+ * Internal syntax error
+ *
+ * |
+ *
+ *
+ * Obsolete, no longer used, but could come from old documents if the result is
+ * a formula from a domain.
+ *
+ * |
+ *
+ *
+ *
+ *
+ * 527
+ *
+ * |
+ *
+ *
+ * Internal overflow
+ *
+ * |
+ *
+ *
+ * Interpreter: References, such as when a cell references a cell, are
+ * too encapsulated.
+ *
+ * |
+ *
+ *
+ *
+ */
+public class ErrorEval implements ValueEval {
+
+ private int errorCode;
+
+ // Oo std error codes
+ public static final ErrorEval ERROR_501 = new ErrorEval(501);
+
+ public static final ErrorEval ERROR_502 = new ErrorEval(502);
+
+ public static final ErrorEval ERROR_503 = new ErrorEval(503);
+
+ public static final ErrorEval ERROR_504 = new ErrorEval(504);
+
+ public static final ErrorEval ERROR_505 = new ErrorEval(505);
+
+ public static final ErrorEval ERROR_506 = new ErrorEval(506);
+
+ public static final ErrorEval ERROR_507 = new ErrorEval(507);
+
+ public static final ErrorEval ERROR_508 = new ErrorEval(508);
+
+ public static final ErrorEval ERROR_509 = new ErrorEval(509);
+
+ public static final ErrorEval ERROR_510 = new ErrorEval(510);
+
+ public static final ErrorEval ERROR_511 = new ErrorEval(511);
+
+ public static final ErrorEval ERROR_512 = new ErrorEval(512);
+
+ public static final ErrorEval ERROR_513 = new ErrorEval(513);
+
+ public static final ErrorEval ERROR_514 = new ErrorEval(514);
+
+ public static final ErrorEval ERROR_515 = new ErrorEval(515);
+
+ public static final ErrorEval ERROR_516 = new ErrorEval(516);
+
+ public static final ErrorEval ERROR_517 = new ErrorEval(517);
+
+ public static final ErrorEval ERROR_518 = new ErrorEval(518);
+
+ public static final ErrorEval ERROR_519 = new ErrorEval(519);
+
+ public static final ErrorEval ERROR_520 = new ErrorEval(520);
+
+ public static final ErrorEval ERROR_521 = new ErrorEval(521);
+
+ public static final ErrorEval ERROR_522 = new ErrorEval(522);
+
+ public static final ErrorEval ERROR_523 = new ErrorEval(523);
+
+ public static final ErrorEval ERROR_524 = new ErrorEval(524);
+
+ public static final ErrorEval ERROR_525 = new ErrorEval(525);
+
+ public static final ErrorEval ERROR_526 = new ErrorEval(526);
+
+ public static final ErrorEval ERROR_527 = new ErrorEval(527);
+
+ public static final ErrorEval NAME_INVALID = ERROR_525;
+
+ public static final ErrorEval VALUE_INVALID = ERROR_519;
+
+
+ // Non std error codes
+ public static final ErrorEval UNKNOWN_ERROR = new ErrorEval(-20);
+
+ public static final ErrorEval FUNCTION_NOT_IMPLEMENTED = new ErrorEval(-30);
+
+ public static final ErrorEval REF_INVALID = new ErrorEval(-40);
+
+ public static final ErrorEval NA = new ErrorEval(-50);
+
+ public static final ErrorEval CIRCULAR_REF_ERROR = new ErrorEval(-60);
+
+ public static final ErrorEval DIV_ZERO = new ErrorEval(-70);
+
+ public static final ErrorEval NUM_ERROR = new ErrorEval(-80);
+
+ private ErrorEval(int errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ public String getStringValue() {
+ return "Err:" + Integer.toString(errorCode);
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Eval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Eval.java
new file mode 100644
index 000000000..e60e061a6
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Eval.java
@@ -0,0 +1,13 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public interface Eval {
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java
new file mode 100644
index 000000000..a9ce8d3a6
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java
@@ -0,0 +1,44 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.functions.Function;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class FuncVarEval extends FunctionEval {
+
+ private AbstractFunctionPtg delegate;
+
+ public FuncVarEval(Ptg funcPtg) {
+ delegate = (AbstractFunctionPtg) funcPtg;
+ }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ Eval retval = null;
+ Function f = getFunction();
+ if (f != null)
+ retval = f.evaluate(operands, srcRow, srcCol);
+ else
+ retval = ErrorEval.FUNCTION_NOT_IMPLEMENTED;
+ return retval;
+ }
+
+ public int getNumberOfOperands() {
+ return delegate.getNumberOfOperands();
+ }
+
+ public int getType() {
+ return delegate.getType();
+ }
+
+ public short getFunctionIndex() {
+ return delegate.getFunctionIndex();
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FunctionEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
new file mode 100644
index 000000000..3a487f7a5
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
@@ -0,0 +1,379 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.functions.*;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public abstract class FunctionEval implements OperationEval {
+ protected static Function[] functions = produceFunctions();
+
+ public Function getFunction() {
+ short fidx = getFunctionIndex();
+ return functions[fidx];
+ }
+
+ public abstract short getFunctionIndex();
+
+ private static Function[] produceFunctions() {
+ Function[] retval = new Function[368];
+ retval[0] = new Count(); // COUNT
+ retval[1] = null; // Specialflag(); // SPECIALFLAG
+ retval[2] = new IsNa(); // ISNA
+ retval[3] = new IsError(); // ISERROR
+ retval[4] = new Sum(); // SUM
+ retval[5] = new Average(); // AVERAGE
+ retval[6] = new Min(); // MIN
+ retval[7] = new Max(); // MAX
+ retval[8] = new Row(); // ROW
+ retval[9] = new Column(); // COLUMN
+ retval[10] = new Na(); // NA
+ retval[11] = new Npv(); // NPV
+ retval[12] = new Stdev(); // STDEV
+ retval[13] = new Dollar(); // DOLLAR
+ retval[14] = new Fixed(); // FIXED
+ retval[15] = new Sin(); // SIN
+ retval[16] = new Cos(); // COS
+ retval[17] = new Tan(); // TAN
+ retval[18] = new Atan(); // ATAN
+ retval[19] = new Pi(); // PI
+ retval[20] = new Sqrt(); // SQRT
+ retval[21] = new Exp(); // EXP
+ retval[22] = new Ln(); // LN
+ retval[23] = new Log10(); // LOG10
+ retval[24] = new Abs(); // ABS
+ retval[25] = new Int(); // INT
+ retval[26] = new Sign(); // SIGN
+ retval[27] = new Round(); // ROUND
+ retval[28] = new Lookup(); // LOOKUP
+ retval[29] = new Index(); // INDEX
+ retval[30] = new Rept(); // REPT
+ retval[31] = new Mid(); // MID
+ retval[32] = new Len(); // LEN
+ retval[33] = new Value(); // VALUE
+ retval[34] = new True(); // TRUE
+ retval[35] = new False(); // FALSE
+ retval[36] = new And(); // AND
+ retval[37] = new Or(); // OR
+ retval[38] = new Not(); // NOT
+ retval[39] = new Mod(); // MOD
+ retval[40] = new Dcount(); // DCOUNT
+ retval[41] = new Dsum(); // DSUM
+ retval[42] = new Daverage(); // DAVERAGE
+ retval[43] = new Dmin(); // DMIN
+ retval[44] = new Dmax(); // DMAX
+ retval[45] = new Dstdev(); // DSTDEV
+ retval[46] = new Var(); // VAR
+ retval[47] = new Dvar(); // DVAR
+ retval[48] = new Text(); // TEXT
+ retval[49] = new Linest(); // LINEST
+ retval[50] = new Trend(); // TREND
+ retval[51] = new Logest(); // LOGEST
+ retval[52] = new Growth(); // GROWTH
+ retval[53] = new Goto(); // GOTO
+ retval[54] = new Halt(); // HALT
+ retval[56] = new Pv(); // PV
+ retval[57] = new Fv(); // FV
+ retval[58] = new Nper(); // NPER
+ retval[59] = new Pmt(); // PMT
+ retval[60] = new Rate(); // RATE
+ retval[61] = new Mirr(); // MIRR
+ retval[62] = new Irr(); // IRR
+ retval[63] = new Rand(); // RAND
+ retval[64] = new Match(); // MATCH
+ retval[65] = new Date(); // DATE
+ retval[66] = new Time(); // TIME
+ retval[67] = new Day(); // DAY
+ retval[68] = new Month(); // MONTH
+ retval[69] = new Year(); // YEAR
+ retval[70] = new Weekday(); // WEEKDAY
+ retval[71] = new Hour(); // HOUR
+ retval[72] = new Minute(); // MINUTE
+ retval[73] = new Second(); // SECOND
+ retval[74] = new Now(); // NOW
+ retval[75] = new Areas(); // AREAS
+ retval[76] = new Rows(); // ROWS
+ retval[77] = new Columns(); // COLUMNS
+ retval[78] = new Offset(); // OFFSET
+ retval[79] = new Absref(); // ABSREF
+ retval[80] = new Relref(); // RELREF
+ retval[81] = new Argument(); // ARGUMENT
+ retval[82] = new Search(); // SEARCH
+ retval[83] = new Transpose(); // TRANSPOSE
+ retval[84] = new org.apache.poi.hssf.record.formula.functions.Error(); // ERROR
+ retval[85] = new Step(); // STEP
+ retval[86] = new Type(); // TYPE
+ retval[87] = new Echo(); // ECHO
+ retval[88] = new Setname(); // SETNAME
+ retval[89] = new Caller(); // CALLER
+ retval[90] = new Deref(); // DEREF
+ retval[91] = new Windows(); // WINDOWS
+ retval[92] = new Series(); // SERIES
+ retval[93] = new Documents(); // DOCUMENTS
+ retval[94] = new Activecell(); // ACTIVECELL
+ retval[95] = new Selection(); // SELECTION
+ retval[96] = new Result(); // RESULT
+ retval[97] = new Atan2(); // ATAN2
+ retval[98] = new Asin(); // ASIN
+ retval[99] = new Acos(); // ACOS
+ retval[100] = new Choose(); // CHOOSE
+ retval[101] = new Hlookup(); // HLOOKUP
+ retval[102] = new Vlookup(); // VLOOKUP
+ retval[103] = new Links(); // LINKS
+ retval[104] = new Input(); // INPUT
+ retval[105] = new Isref(); // ISREF
+ retval[106] = new Getformula(); // GETFORMULA
+ retval[107] = new Getname(); // GETNAME
+ retval[108] = new Setvalue(); // SETVALUE
+ retval[109] = new Log(); // LOG
+ retval[110] = new Exec(); // EXEC
+ retval[111] = new Char(); // CHAR
+ retval[112] = new Lower(); // LOWER
+ retval[113] = new Upper(); // UPPER
+ retval[114] = new Proper(); // PROPER
+ retval[115] = new Left(); // LEFT
+ retval[116] = new Right(); // RIGHT
+ retval[117] = new Exact(); // EXACT
+ retval[118] = new Trim(); // TRIM
+ retval[119] = new Replace(); // REPLACE
+ retval[120] = new Substitute(); // SUBSTITUTE
+ retval[121] = new Code(); // CODE
+ retval[122] = new Names(); // NAMES
+ retval[123] = new Directory(); // DIRECTORY
+ retval[124] = new Find(); // FIND
+ retval[125] = new Cell(); // CELL
+ retval[126] = new Iserr(); // ISERR
+ retval[127] = new Istext(); // ISTEXT
+ retval[128] = new Isnumber(); // ISNUMBER
+ retval[129] = new Isblank(); // ISBLANK
+ retval[130] = new T(); // T
+ retval[131] = new N(); // N
+ retval[132] = new Fopen(); // FOPEN
+ retval[133] = new Fclose(); // FCLOSE
+ retval[134] = new Fsize(); // FSIZE
+ retval[135] = new Freadln(); // FREADLN
+ retval[136] = new Fread(); // FREAD
+ retval[137] = new Fwriteln(); // FWRITELN
+ retval[138] = new Fwrite(); // FWRITE
+ retval[139] = new Fpos(); // FPOS
+ retval[140] = new Datevalue(); // DATEVALUE
+ retval[141] = new Timevalue(); // TIMEVALUE
+ retval[142] = new Sln(); // SLN
+ retval[143] = new Syd(); // SYD
+ retval[144] = new Ddb(); // DDB
+ retval[145] = new Getdef(); // GETDEF
+ retval[146] = new Reftext(); // REFTEXT
+ retval[147] = new Textref(); // TEXTREF
+ retval[148] = new Indirect(); // INDIRECT
+ retval[149] = new Register(); // REGISTER
+ retval[150] = new Call(); // CALL
+ retval[151] = new Addbar(); // ADDBAR
+ retval[152] = new Addmenu(); // ADDMENU
+ retval[153] = new Addcommand(); // ADDCOMMAND
+ retval[154] = new Enablecommand(); // ENABLECOMMAND
+ retval[155] = new Checkcommand(); // CHECKCOMMAND
+ retval[156] = new Renamecommand(); // RENAMECOMMAND
+ retval[157] = new Showbar(); // SHOWBAR
+ retval[158] = new Deletemenu(); // DELETEMENU
+ retval[159] = new Deletecommand(); // DELETECOMMAND
+ retval[160] = new Getchartitem(); // GETCHARTITEM
+ retval[161] = new Dialogbox(); // DIALOGBOX
+ retval[162] = new Clean(); // CLEAN
+ retval[163] = new Mdeterm(); // MDETERM
+ retval[164] = new Minverse(); // MINVERSE
+ retval[165] = new Mmult(); // MMULT
+ retval[166] = new Files(); // FILES
+ retval[167] = new Ipmt(); // IPMT
+ retval[168] = new Ppmt(); // PPMT
+ retval[169] = new Counta(); // COUNTA
+ retval[170] = new Cancelkey(); // CANCELKEY
+ retval[175] = new Initiate(); // INITIATE
+ retval[176] = new Request(); // REQUEST
+ retval[177] = new Poke(); // POKE
+ retval[178] = new Execute(); // EXECUTE
+ retval[179] = new Terminate(); // TERMINATE
+ retval[180] = new Restart(); // RESTART
+ retval[181] = new Help(); // HELP
+ retval[182] = new Getbar(); // GETBAR
+ retval[183] = new Product(); // PRODUCT
+ retval[184] = new Fact(); // FACT
+ retval[185] = new Getcell(); // GETCELL
+ retval[186] = new Getworkspace(); // GETWORKSPACE
+ retval[187] = new Getwindow(); // GETWINDOW
+ retval[188] = new Getdocument(); // GETDOCUMENT
+ retval[189] = new Dproduct(); // DPRODUCT
+ retval[190] = new Isnontext(); // ISNONTEXT
+ retval[191] = new Getnote(); // GETNOTE
+ retval[192] = new Note(); // NOTE
+ retval[193] = new Stdevp(); // STDEVP
+ retval[194] = new Varp(); // VARP
+ retval[195] = new Dstdevp(); // DSTDEVP
+ retval[196] = new Dvarp(); // DVARP
+ retval[197] = new Trunc(); // TRUNC
+ retval[198] = new Islogical(); // ISLOGICAL
+ retval[199] = new Dcounta(); // DCOUNTA
+ retval[200] = new Deletebar(); // DELETEBAR
+ retval[201] = new Unregister(); // UNREGISTER
+ retval[204] = new Usdollar(); // USDOLLAR
+ retval[205] = new Findb(); // FINDB
+ retval[206] = new Searchb(); // SEARCHB
+ retval[207] = new Replaceb(); // REPLACEB
+ retval[208] = new Leftb(); // LEFTB
+ retval[209] = new Rightb(); // RIGHTB
+ retval[210] = new Midb(); // MIDB
+ retval[211] = new Lenb(); // LENB
+ retval[212] = new Roundup(); // ROUNDUP
+ retval[213] = new Rounddown(); // ROUNDDOWN
+ retval[214] = new Asc(); // ASC
+ retval[215] = new Dbcs(); // DBCS
+ retval[216] = new Rank(); // RANK
+ retval[219] = new Address(); // ADDRESS
+ retval[220] = new Days360(); // DAYS360
+ retval[221] = new Today(); // TODAY
+ retval[222] = new Vdb(); // VDB
+ retval[227] = new Median(); // MEDIAN
+ retval[228] = new Sumproduct(); // SUMPRODUCT
+ retval[229] = new Sinh(); // SINH
+ retval[230] = new Cosh(); // COSH
+ retval[231] = new Tanh(); // TANH
+ retval[232] = new Asinh(); // ASINH
+ retval[233] = new Acosh(); // ACOSH
+ retval[234] = new Atanh(); // ATANH
+ retval[235] = new Dget(); // DGET
+ retval[236] = new Createobject(); // CREATEOBJECT
+ retval[237] = new Volatile(); // VOLATILE
+ retval[238] = new Lasterror(); // LASTERROR
+ retval[239] = new Customundo(); // CUSTOMUNDO
+ retval[240] = new Customrepeat(); // CUSTOMREPEAT
+ retval[241] = new Formulaconvert(); // FORMULACONVERT
+ retval[242] = new Getlinkinfo(); // GETLINKINFO
+ retval[243] = new Textbox(); // TEXTBOX
+ retval[244] = new Info(); // INFO
+ retval[245] = new Group(); // GROUP
+ retval[246] = new Getobject(); // GETOBJECT
+ retval[247] = new Db(); // DB
+ retval[248] = new Pause(); // PAUSE
+ retval[250] = new Resume(); // RESUME
+ retval[252] = new Frequency(); // FREQUENCY
+ retval[253] = new Addtoolbar(); // ADDTOOLBAR
+ retval[254] = new Deletetoolbar(); // DELETETOOLBAR
+ retval[255] = new Externalflag(); // EXTERNALFLAG
+ retval[256] = new Resettoolbar(); // RESETTOOLBAR
+ retval[257] = new Evaluate(); // EVALUATE
+ retval[258] = new Gettoolbar(); // GETTOOLBAR
+ retval[259] = new Gettool(); // GETTOOL
+ retval[260] = new Spellingcheck(); // SPELLINGCHECK
+ retval[261] = new Errortype(); // ERRORTYPE
+ retval[262] = new Apptitle(); // APPTITLE
+ retval[263] = new Windowtitle(); // WINDOWTITLE
+ retval[264] = new Savetoolbar(); // SAVETOOLBAR
+ retval[265] = new Enabletool(); // ENABLETOOL
+ retval[266] = new Presstool(); // PRESSTOOL
+ retval[267] = new Registerid(); // REGISTERID
+ retval[268] = new Getworkbook(); // GETWORKBOOK
+ retval[269] = new Avedev(); // AVEDEV
+ retval[270] = new Betadist(); // BETADIST
+ retval[271] = new Gammaln(); // GAMMALN
+ retval[272] = new Betainv(); // BETAINV
+ retval[273] = new Binomdist(); // BINOMDIST
+ retval[274] = new Chidist(); // CHIDIST
+ retval[275] = new Chiinv(); // CHIINV
+ retval[276] = new Combin(); // COMBIN
+ retval[277] = new Confidence(); // CONFIDENCE
+ retval[278] = new Critbinom(); // CRITBINOM
+ retval[279] = new Even(); // EVEN
+ retval[280] = new Expondist(); // EXPONDIST
+ retval[281] = new Fdist(); // FDIST
+ retval[282] = new Finv(); // FINV
+ retval[283] = new Fisher(); // FISHER
+ retval[284] = new Fisherinv(); // FISHERINV
+ retval[285] = new Floor(); // FLOOR
+ retval[286] = new Gammadist(); // GAMMADIST
+ retval[287] = new Gammainv(); // GAMMAINV
+ retval[288] = new Ceiling(); // CEILING
+ retval[289] = new Hypgeomdist(); // HYPGEOMDIST
+ retval[290] = new Lognormdist(); // LOGNORMDIST
+ retval[291] = new Loginv(); // LOGINV
+ retval[292] = new Negbinomdist(); // NEGBINOMDIST
+ retval[293] = new Normdist(); // NORMDIST
+ retval[294] = new Normsdist(); // NORMSDIST
+ retval[295] = new Norminv(); // NORMINV
+ retval[296] = new Normsinv(); // NORMSINV
+ retval[297] = new Standardize(); // STANDARDIZE
+ retval[298] = new Odd(); // ODD
+ retval[299] = new Permut(); // PERMUT
+ retval[300] = new Poisson(); // POISSON
+ retval[301] = new Tdist(); // TDIST
+ retval[302] = new Weibull(); // WEIBULL
+ retval[303] = new Sumxmy2(); // SUMXMY2
+ retval[304] = new Sumx2my2(); // SUMX2MY2
+ retval[305] = new Sumx2py2(); // SUMX2PY2
+ retval[306] = new Chitest(); // CHITEST
+ retval[307] = new Correl(); // CORREL
+ retval[308] = new Covar(); // COVAR
+ retval[309] = new Forecast(); // FORECAST
+ retval[310] = new Ftest(); // FTEST
+ retval[311] = new Intercept(); // INTERCEPT
+ retval[312] = new Pearson(); // PEARSON
+ retval[313] = new Rsq(); // RSQ
+ retval[314] = new Steyx(); // STEYX
+ retval[315] = new Slope(); // SLOPE
+ retval[316] = new Ttest(); // TTEST
+ retval[317] = new Prob(); // PROB
+ retval[318] = new Devsq(); // DEVSQ
+ retval[319] = new Geomean(); // GEOMEAN
+ retval[320] = new Harmean(); // HARMEAN
+ retval[321] = new Sumsq(); // SUMSQ
+ retval[322] = new Kurt(); // KURT
+ retval[323] = new Skew(); // SKEW
+ retval[324] = new Ztest(); // ZTEST
+ retval[325] = new Large(); // LARGE
+ retval[326] = new Small(); // SMALL
+ retval[327] = new Quartile(); // QUARTILE
+ retval[328] = new Percentile(); // PERCENTILE
+ retval[329] = new Percentrank(); // PERCENTRANK
+ retval[330] = new Mode(); // MODE
+ retval[331] = new Trimmean(); // TRIMMEAN
+ retval[332] = new Tinv(); // TINV
+ retval[334] = new Moviecommand(); // MOVIECOMMAND
+ retval[335] = new Getmovie(); // GETMOVIE
+ retval[336] = new Concatenate(); // CONCATENATE
+ retval[337] = new Power(); // POWER
+ retval[338] = new Pivotadddata(); // PIVOTADDDATA
+ retval[339] = new Getpivottable(); // GETPIVOTTABLE
+ retval[340] = new Getpivotfield(); // GETPIVOTFIELD
+ retval[341] = new Getpivotitem(); // GETPIVOTITEM
+ retval[342] = new Radians(); // RADIANS
+ retval[343] = new Degrees(); // DEGREES
+ retval[344] = new Subtotal(); // SUBTOTAL
+ retval[345] = new Sumif(); // SUMIF
+ retval[346] = new Countif(); // COUNTIF
+ retval[347] = new Countblank(); // COUNTBLANK
+ retval[348] = new Scenarioget(); // SCENARIOGET
+ retval[349] = new Optionslistsget(); // OPTIONSLISTSGET
+ retval[350] = new Ispmt(); // ISPMT
+ retval[351] = new Datedif(); // DATEDIF
+ retval[352] = new Datestring(); // DATESTRING
+ retval[353] = new Numberstring(); // NUMBERSTRING
+ retval[354] = new Roman(); // ROMAN
+ retval[355] = new Opendialog(); // OPENDIALOG
+ retval[356] = new Savedialog(); // SAVEDIALOG
+ retval[357] = new Viewget(); // VIEWGET
+ retval[358] = new Getpivotdata(); // GETPIVOTDATA
+ retval[359] = new Hyperlink(); // HYPERLINK
+ retval[360] = new Phonetic(); // PHONETIC
+ retval[361] = new Averagea(); // AVERAGEA
+ retval[362] = new Maxa(); // MAXA
+ retval[363] = new Mina(); // MINA
+ retval[364] = new Stdevpa(); // STDEVPA
+ retval[365] = new Varpa(); // VARPA
+ retval[366] = new Stdeva(); // STDEVA
+ retval[367] = new Vara(); // VARA
+ return retval;
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java
new file mode 100644
index 000000000..894a7f01d
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java
@@ -0,0 +1,51 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.GreaterEqualPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class GreaterEqualEval extends RelationalOperationEval {
+
+ private GreaterEqualPtg delegate;
+
+ public GreaterEqualEval(Ptg ptg) {
+ this.delegate = (GreaterEqualPtg) ptg;
+ }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ ValueEval retval = null;
+
+ RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol);
+ retval = rvs.ee;
+ int result = 0;
+ if (retval == null) {
+ result = doComparison(rvs.bs);
+ if (result == 0) {
+ result = doComparison(rvs.ss);
+ }
+ if (result == 0) {
+ result = doComparison(rvs.ds);
+ }
+
+ retval = (result >= 0) ? BoolEval.TRUE : BoolEval.FALSE;
+ }
+
+ return retval;
+ }
+
+ public int getNumberOfOperands() {
+ return delegate.getNumberOfOperands();
+ }
+
+ public int getType() {
+ return delegate.getType();
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java
new file mode 100644
index 000000000..587c7e6ce
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java
@@ -0,0 +1,51 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.GreaterThanPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class GreaterThanEval extends RelationalOperationEval {
+
+ private GreaterThanPtg delegate;
+
+ public GreaterThanEval(Ptg ptg) {
+ this.delegate = (GreaterThanPtg) ptg;
+ }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ ValueEval retval = null;
+
+ RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol);
+ retval = rvs.ee;
+ int result = 0;
+ if (retval == null) {
+ result = doComparison(rvs.bs);
+ if (result == 0) {
+ result = doComparison(rvs.ss);
+ }
+ if (result == 0) {
+ result = doComparison(rvs.ds);
+ }
+
+ retval = (result > 0) ? BoolEval.TRUE : BoolEval.FALSE;;
+ }
+
+ return retval;
+ }
+
+ public int getNumberOfOperands() {
+ return delegate.getNumberOfOperands();
+ }
+
+ public int getType() {
+ return delegate.getType();
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java
new file mode 100644
index 000000000..3e4000f76
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java
@@ -0,0 +1,51 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.LessEqualPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class LessEqualEval extends RelationalOperationEval {
+
+ private LessEqualPtg delegate;
+
+ public LessEqualEval(Ptg ptg) {
+ this.delegate = (LessEqualPtg) ptg;
+ }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ ValueEval retval = null;
+
+ RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol);
+ retval = rvs.ee;
+ int result = 0;
+ if (retval == null) {
+ result = doComparison(rvs.bs);
+ if (result == 0) {
+ result = doComparison(rvs.ss);
+ }
+ if (result == 0) {
+ result = doComparison(rvs.ds);
+ }
+
+ retval = (result <= 0) ? BoolEval.TRUE : BoolEval.FALSE;;
+ }
+
+ return retval;
+ }
+
+ public int getNumberOfOperands() {
+ return delegate.getNumberOfOperands();
+ }
+
+ public int getType() {
+ return delegate.getType();
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessThanEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessThanEval.java
new file mode 100644
index 000000000..5b625e06e
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessThanEval.java
@@ -0,0 +1,52 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.LessThanPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class LessThanEval extends RelationalOperationEval {
+
+ private LessThanPtg delegate;
+
+ public LessThanEval(Ptg ptg) {
+ this.delegate = (LessThanPtg) ptg;
+ }
+
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ ValueEval retval = null;
+
+ RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol);
+ retval = rvs.ee;
+ int result = 0;
+ if (retval == null) {
+ result = doComparison(rvs.bs);
+ if (result == 0) {
+ result = doComparison(rvs.ss);
+ }
+ if (result == 0) {
+ result = doComparison(rvs.ds);
+ }
+
+ retval = (result < 0) ? BoolEval.TRUE : BoolEval.FALSE;;
+ }
+
+ return retval;
+ }
+
+ public int getNumberOfOperands() {
+ return delegate.getNumberOfOperands();
+ }
+
+ public int getType() {
+ return delegate.getType();
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/MultiplyEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/MultiplyEval.java
new file mode 100644
index 000000000..e55d53226
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/MultiplyEval.java
@@ -0,0 +1,84 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.MultiplyPtg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class MultiplyEval extends NumericOperationEval {
+
+ private MultiplyPtg delegate;
+
+ private static final ValueEvalToNumericXlator NUM_XLATOR =
+ new ValueEvalToNumericXlator((short)
+ ( ValueEvalToNumericXlator.BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
+ | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.STRING_IS_PARSED
+ ));
+
+ public MultiplyEval(Ptg ptg) {
+ delegate = (MultiplyPtg) ptg;
+ }
+
+ protected ValueEvalToNumericXlator getXlator() {
+ return NUM_XLATOR;
+ }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ Eval retval = null;
+ double d0 = 0;
+ double d1 = 0;
+ switch (operands.length) {
+ default: // will rarely happen. currently the parser itself fails.
+ retval = ErrorEval.UNKNOWN_ERROR;
+ break;
+ case 2:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ d0 = ((NumericValueEval) ve).getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+
+ if (retval == null) { // no error yet
+ ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ d1 = ((NumericValueEval) ve).getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+ } // end switch
+
+ if (retval == null) {
+ retval = (Double.isNaN(d0) || Double.isNaN(d1))
+ ? (ValueEval) ErrorEval.VALUE_INVALID
+ : new NumberEval(d0 * d1);
+ }
+ return retval;
+ }
+
+ public int getNumberOfOperands() {
+ return delegate.getNumberOfOperands();
+ }
+
+ public int getType() {
+ return delegate.getType();
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java
new file mode 100644
index 000000000..e868864f3
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java
@@ -0,0 +1,52 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.NotEqualPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class NotEqualEval extends RelationalOperationEval {
+
+ private NotEqualPtg delegate;
+
+ public NotEqualEval(Ptg ptg) {
+ this.delegate = (NotEqualPtg) ptg;
+ }
+
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ ValueEval retval = null;
+
+ RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol);
+ retval = rvs.ee;
+ int result = 0;
+ if (retval == null) {
+ result = doComparison(rvs.bs);
+ if (result == 0) {
+ result = doComparison(rvs.ss);
+ }
+ if (result == 0) {
+ result = doComparison(rvs.ds);
+ }
+
+ retval = (result != 0) ? BoolEval.TRUE : BoolEval.FALSE;
+ }
+
+ return retval;
+ }
+
+ public int getNumberOfOperands() {
+ return delegate.getNumberOfOperands();
+ }
+
+ public int getType() {
+ return delegate.getType();
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumberEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumberEval.java
new file mode 100644
index 000000000..764c59f20
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumberEval.java
@@ -0,0 +1,55 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.IntPtg;
+import org.apache.poi.hssf.record.formula.NumberPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class NumberEval implements NumericValueEval, StringValueEval {
+
+ private double value;
+ private String stringValue;
+
+ public NumberEval(Ptg ptg) {
+ if (ptg instanceof IntPtg) {
+ this.value = ((IntPtg) ptg).getValue();
+ }
+ else if (ptg instanceof NumberPtg) {
+ this.value = ((NumberPtg) ptg).getValue();
+ }
+ }
+
+ public NumberEval(double value) {
+ this.value = value;
+ }
+
+ public double getNumberValue() {
+ return value;
+ }
+
+ public String getStringValue() { // TODO: limit to 15 decimal places
+ if (stringValue == null)
+ makeString();
+ return stringValue;
+ }
+
+ protected void makeString() {
+ if (!Double.isNaN(value)) {
+ long lvalue = Math.round(value);
+ if (lvalue == value) {
+ stringValue = String.valueOf(lvalue);
+ }
+ else {
+ stringValue = String.valueOf(value);
+ }
+ }
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumericOperationEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumericOperationEval.java
new file mode 100644
index 000000000..8c40306b7
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumericOperationEval.java
@@ -0,0 +1,50 @@
+/*
+ * Created on May 14, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public abstract class NumericOperationEval implements OperationEval {
+
+ protected abstract ValueEvalToNumericXlator getXlator();
+
+ protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) {
+ ValueEval retval;
+ if (eval instanceof AreaEval) {
+ AreaEval ae = (AreaEval) eval;
+ if (ae.contains(srcRow, srcCol)) { // circular ref!
+ retval = ErrorEval.CIRCULAR_REF_ERROR;
+ }
+ else if (ae.isRow()) {
+ if (ae.containsColumn(srcCol)) {
+ ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
+ ve = getXlator().attemptXlateToNumeric(ve);
+ retval = getXlator().attemptXlateToNumeric(ve);
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+ else if (ae.isColumn()) {
+ if (ae.containsRow(srcRow)) {
+ ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
+ retval = getXlator().attemptXlateToNumeric(ve);
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+ else {
+ retval = getXlator().attemptXlateToNumeric((ValueEval) eval);
+ }
+ return retval;
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumericValueEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumericValueEval.java
new file mode 100644
index 000000000..06ead84f0
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumericValueEval.java
@@ -0,0 +1,14 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public interface NumericValueEval extends ValueEval {
+
+ public abstract double getNumberValue();
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/OperationEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/OperationEval.java
new file mode 100644
index 000000000..1472cb5b3
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/OperationEval.java
@@ -0,0 +1,37 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public interface OperationEval extends Eval {
+
+ /*
+ * Read this, this will make your work easier when coding
+ * an "evaluate()"
+ *
+ * Things to note when implementing evaluate():
+ * 1. Check the length of operands
+ * (use "switch(operands[x])" if possible)
+ *
+ * 2. The possible Evals that you can get as args to evaluate are one of:
+ * NumericValueEval, StringValueEval, RefEval, AreaEval
+ * 3. If it is RefEval, the innerValueEval could be one of:
+ * NumericValueEval, StringValueEval, BlankEval
+ * 4. If it is AreaEval, each of the values could be one of:
+ * NumericValueEval, StringValueEval, BlankEval, RefEval
+ *
+ * 5. For numeric functions/operations, keep the result in double
+ * till the end and before returning a new NumberEval, check to see
+ * if the double is a NaN - if NaN, return ErrorEval.ERROR_503
+ */
+ public abstract Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol);
+
+ public abstract int getNumberOfOperands();
+
+ public abstract int getType();
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/PowerEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/PowerEval.java
new file mode 100644
index 000000000..641cf10ae
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/PowerEval.java
@@ -0,0 +1,86 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.PowerPtg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class PowerEval extends NumericOperationEval {
+
+ private PowerPtg delegate;
+
+ private static final ValueEvalToNumericXlator NUM_XLATOR =
+ new ValueEvalToNumericXlator((short)
+ ( ValueEvalToNumericXlator.BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
+ | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.STRING_IS_PARSED
+ ));
+
+ public PowerEval(Ptg ptg) {
+ delegate = (PowerPtg) ptg;
+ }
+
+ protected ValueEvalToNumericXlator getXlator() {
+ return NUM_XLATOR;
+ }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ Eval retval = null;
+ double d0 = 0;
+ double d1 = 0;
+
+ switch (operands.length) {
+ default: // will rarely happen. currently the parser itself fails.
+ retval = ErrorEval.UNKNOWN_ERROR;
+ break;
+ case 2:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ d0 = ((NumericValueEval) ve).getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+
+ if (retval == null) { // no error yet
+ ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ d1 = ((NumericValueEval) ve).getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+ } // end switch
+
+ if (retval == null) {
+ double p = Math.pow(d0, d1);
+ retval = (Double.isNaN(p))
+ ? (ValueEval) ErrorEval.VALUE_INVALID
+ : new NumberEval(p);
+ }
+ return retval;
+ }
+
+ public int getNumberOfOperands() {
+ return delegate.getNumberOfOperands();
+ }
+
+ public int getType() {
+ return delegate.getType();
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java
new file mode 100644
index 000000000..410188f2b
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java
@@ -0,0 +1,44 @@
+/*
+ * Created on May 9, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.ReferencePtg;
+
+/**
+ * @author adeshmukh
+ *
+ */
+public class Ref2DEval implements RefEval {
+
+ private ValueEval value;
+
+ private ReferencePtg delegate;
+
+ private boolean evaluated;
+
+ public Ref2DEval(Ptg ptg, ValueEval value, boolean evaluated) {
+ this.value = value;
+ this.delegate = (ReferencePtg) ptg;
+ this.evaluated = evaluated;
+ }
+
+ public ValueEval getInnerValueEval() {
+ return value;
+ }
+
+ public short getRow() {
+ return delegate.getRow();
+ }
+
+ public short getColumn() {
+ return delegate.getColumn();
+ }
+
+ public boolean isEvaluated() {
+ return evaluated;
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref3DEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref3DEval.java
new file mode 100644
index 000000000..56df7a746
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref3DEval.java
@@ -0,0 +1,44 @@
+/*
+ * Created on May 9, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.Ref3DPtg;
+
+/**
+ * @author Amol S. Deshmukh
+ *
+ */
+public class Ref3DEval implements RefEval {
+
+ private ValueEval value;
+
+ private Ref3DPtg delegate;
+
+ private boolean evaluated;
+
+ public Ref3DEval(Ptg ptg, ValueEval value, boolean evaluated) {
+ this.value = value;
+ this.delegate = (Ref3DPtg) ptg;
+ this.evaluated = evaluated;
+ }
+
+ public ValueEval getInnerValueEval() {
+ return value;
+ }
+
+ public short getRow() {
+ return delegate.getRow();
+ }
+
+ public short getColumn() {
+ return delegate.getColumn();
+ }
+
+ public boolean isEvaluated() {
+ return evaluated;
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RefEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RefEval.java
new file mode 100644
index 000000000..f10a04013
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RefEval.java
@@ -0,0 +1,57 @@
+/*
+ * Created on May 9, 2005
+ *
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * @author Amol S Deshmukh < amolweb at ya hoo dot com >
+ *
+ * RefEval is the super interface for Ref2D and Ref3DEval. Basically a RefEval
+ * impl should contain reference to the original ReferencePtg or Ref3DPtg as
+ * well as the final "value" resulting from the evaluation of the cell
+ * reference. Thus if the HSSFCell has type CELL_TYPE_NUMERIC, the contained
+ * value object should be of type NumberEval; if cell type is CELL_TYPE_STRING,
+ * contained value object should be of type StringEval
+ */
+public interface RefEval extends ValueEval {
+
+ /**
+ * The (possibly evaluated) ValueEval contained
+ * in this RefEval. eg. if cell A1 contains "test"
+ * then in a formula referring to cell A1
+ * the RefEval representing
+ * A1 will return as the getInnerValueEval() the
+ * object of concrete type StringEval
+ * @return
+ */
+ public ValueEval getInnerValueEval();
+
+ /**
+ * returns the column index.
+ * @return
+ */
+ public short getColumn();
+
+ /**
+ * returns the row index.
+ * @return
+ */
+ public short getRow();
+
+ /**
+ * returns true if this RefEval contains an
+ * evaluated value instead of a direct value.
+ * eg. say cell A1 has the value: ="test"
+ * Then the RefEval representing A1 will return
+ * isEvaluated() equal to false. On the other
+ * hand, say cell A1 has the value: =B1 and
+ * B1 has the value "test", then the RefEval
+ * representing A1 will return isEvaluated()
+ * equal to true.
+ * @return
+ */
+ public boolean isEvaluated();
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java
new file mode 100644
index 000000000..de5004d92
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java
@@ -0,0 +1,200 @@
+/*
+ * Created on May 10, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public abstract class RelationalOperationEval implements OperationEval {
+
+ protected class RelationalValues {
+ public Double[] ds = new Double[2];
+ public Boolean[] bs = new Boolean[2];
+ public String[] ss = new String[3];
+ public ErrorEval ee = null;
+ }
+
+
+ /*
+ * This is a description of how the relational operators apply in MS Excel.
+ * Use this as a guideline when testing/implementing the evaluate methods
+ * for the relational operators Evals.
+ *
+ * Bool > any number. ALWAYS
+ * Bool > any string. ALWAYS
+ * Bool.TRUE > Bool.FALSE
+ *
+ * String > any number. ALWAYS
+ * String > Blank. ALWAYS
+ * String are sorted dictionary wise
+ *
+ * Blank == 0 (numeric)
+ */
+ public RelationalValues doEvaluate(Eval[] operands, int srcRow, short srcCol) {
+ RelationalValues retval = new RelationalValues();
+
+ switch (operands.length) {
+ default:
+ retval.ee = ErrorEval.ERROR_520;
+ break;
+ case 2:
+ internalDoEvaluate(operands, srcRow, srcCol, retval, 0);
+ internalDoEvaluate(operands, srcRow, srcCol, retval, 1);
+ } // end switch
+ return retval;
+ }
+
+ /**
+ * convenience method to avoid code duplication for multiple operands
+ * @param operands
+ * @param srcRow
+ * @param srcCol
+ * @param retval
+ * @param index
+ */
+ private void internalDoEvaluate(Eval[] operands, int srcRow, short srcCol, RelationalValues retval, int index) {
+ if (operands[index] instanceof BoolEval) {
+ BoolEval be = (BoolEval) operands[index];
+ retval.bs[index] = Boolean.valueOf(be.getBooleanValue());
+ }
+ else if (operands[index] instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) operands[index];
+ retval.ds[index] = new Double(ne.getNumberValue());
+ }
+ else if (operands[index] instanceof StringValueEval) {
+ StringValueEval se = (StringValueEval) operands[index];
+ retval.ss[index] = se.getStringValue();
+ }
+ else if (operands[index] instanceof RefEval) {
+ RefEval re = (RefEval) operands[index];
+ ValueEval ve = re.getInnerValueEval();
+ if (ve instanceof BoolEval) {
+ BoolEval be = (BoolEval) ve;
+ retval.bs[index] = Boolean.valueOf(be.getBooleanValue());
+ }
+ else if (ve instanceof BlankEval) {
+ retval.ds[index] = new Double(0);
+ }
+ else if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ retval.ds[index] = new Double(ne.getNumberValue());
+ }
+ else if (ve instanceof StringValueEval) {
+ StringValueEval se = (StringValueEval) ve;
+ retval.ss[index] = se.getStringValue();
+ }
+ }
+ else if (operands[index] instanceof AreaEval) {
+ AreaEval ae = (AreaEval) operands[index];
+ if (ae.isRow()) {
+ if (ae.containsColumn(srcCol)) {
+ ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
+ if (ve instanceof BoolEval) {
+ BoolEval be = (BoolEval) ve;
+ retval.bs[index] = Boolean.valueOf(be.getBooleanValue());
+ }
+ else if (ve instanceof BlankEval) {
+ retval.ds[index] = new Double(0);
+ }
+ else if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ retval.ds[index] = new Double(ne.getNumberValue());
+ }
+ else if (ve instanceof StringValueEval) {
+ StringValueEval se = (StringValueEval) ve;
+ retval.ss[index] = se.getStringValue();
+ }
+ else {
+ retval.ee = ErrorEval.VALUE_INVALID;
+ }
+ }
+ else {
+ retval.ee = ErrorEval.VALUE_INVALID;
+ }
+ }
+ else if (ae.isColumn()) {
+ if (ae.containsRow(srcRow)) {
+ ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
+ if (ve instanceof BoolEval) {
+ BoolEval be = (BoolEval) ve;
+ retval.bs[index] = Boolean.valueOf(be.getBooleanValue());
+ }
+ else if (ve instanceof BlankEval) {
+ retval.ds[index] = new Double(0);
+ }
+ else if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ retval.ds[index] = new Double(ne.getNumberValue());
+ }
+ else if (ve instanceof StringValueEval) {
+ StringValueEval se = (StringValueEval) ve;
+ retval.ss[index] = se.getStringValue();
+ }
+ else {
+ retval.ee = ErrorEval.VALUE_INVALID;
+ }
+ }
+ else {
+ retval.ee = ErrorEval.VALUE_INVALID;
+ }
+ }
+ else {
+ retval.ee = ErrorEval.VALUE_INVALID;
+ }
+ }
+ }
+
+ // if both null return 0, else non null wins, else TRUE wins
+ protected int doComparison(Boolean[] bs) {
+ int retval = 0;
+ if (bs[0] != null || bs[1] != null) {
+ retval = bs[0] != null
+ ? bs[1] != null
+ ? bs[0].booleanValue()
+ ? bs[1].booleanValue()
+ ? 0
+ : 1
+ : bs[1].booleanValue()
+ ? -1
+ : 0
+ : 1
+ : bs[1] != null
+ ? -1
+ : 0;
+ }
+ return retval;
+ }
+
+ // if both null return 0, else non null wins, else string compare
+ protected int doComparison(String[] ss) {
+ int retval = 0;
+ if (ss[0] != null || ss[1] != null) {
+ retval = ss[0] != null
+ ? ss[1] != null
+ ? ss[0].compareTo(ss[1])
+ : 1
+ : ss[1] != null
+ ? -1
+ : 0;
+ }
+ return retval;
+ }
+
+ // if both null return 0, else non null wins, else doublevalue compare
+ protected int doComparison(Double[] ds) {
+ int retval = 0;
+ if (ds[0] != null || ds[1] != null) {
+ retval = ds[0] != null
+ ? ds[1] != null
+ ? ds[0].compareTo(ds[1])
+ : 1
+ : ds[1] != null
+ ? -1
+ : 0;
+ }
+ return retval;
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringEval.java
new file mode 100644
index 000000000..f8b4cca00
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringEval.java
@@ -0,0 +1,29 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.StringPtg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class StringEval implements StringValueEval {
+
+ private String value;
+
+ public StringEval(Ptg ptg) {
+ this.value = ((StringPtg) ptg).getValue();
+ }
+
+ public StringEval(String value) {
+ this.value = value;
+ }
+
+ public String getStringValue() {
+ return value;
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringOperationEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringOperationEval.java
new file mode 100644
index 000000000..0f60740a0
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringOperationEval.java
@@ -0,0 +1,81 @@
+/*
+ * Created on May 14, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public abstract class StringOperationEval implements OperationEval {
+
+
+
+ /**
+ * Returns an instanceof StringValueEval or ErrorEval or BlankEval
+ *
+ * @param eval
+ * @param srcRow
+ * @param srcCol
+ * @return
+ */
+ protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) {
+ ValueEval retval;
+ if (eval instanceof AreaEval) {
+ AreaEval ae = (AreaEval) eval;
+ if (ae.contains(srcRow, srcCol)) { // circular ref!
+ retval = ErrorEval.CIRCULAR_REF_ERROR;
+ }
+ else if (ae.isRow()) {
+ if (ae.containsColumn(srcCol)) {
+ ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
+ retval = internalResolveEval(eval);
+ }
+ else {
+ retval = ErrorEval.NAME_INVALID;
+ }
+ }
+ else if (ae.isColumn()) {
+ if (ae.containsRow(srcRow)) {
+ ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
+ retval = internalResolveEval(eval);
+ }
+ else {
+ retval = ErrorEval.NAME_INVALID;
+ }
+ }
+ else {
+ retval = ErrorEval.NAME_INVALID;
+ }
+ }
+ else {
+ retval = internalResolveEval(eval);
+ }
+ return retval;
+ }
+
+ private ValueEval internalResolveEval(Eval eval) {
+ ValueEval retval;
+ if (eval instanceof StringValueEval) {
+ retval = (StringValueEval) eval;
+ }
+ else if (eval instanceof RefEval) {
+ RefEval re = (RefEval) eval;
+ ValueEval tve = re.getInnerValueEval();
+ if (tve instanceof StringValueEval || tve instanceof BlankEval) {
+ retval = tve;
+ }
+ else {
+ retval = ErrorEval.NAME_INVALID;
+ }
+ }
+ else if (eval instanceof BlankEval) {
+ retval = (BlankEval) eval;
+ }
+ else {
+ retval = ErrorEval.NAME_INVALID;
+ }
+ return retval;
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringValueEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringValueEval.java
new file mode 100644
index 000000000..9cadd3001
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringValueEval.java
@@ -0,0 +1,14 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public interface StringValueEval extends ValueEval {
+
+ public String getStringValue();
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/SubtractEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/SubtractEval.java
new file mode 100644
index 000000000..6b2c9899c
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/SubtractEval.java
@@ -0,0 +1,84 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.SubtractPtg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class SubtractEval extends NumericOperationEval {
+
+ private SubtractPtg delegate;
+
+ private static final ValueEvalToNumericXlator NUM_XLATOR =
+ new ValueEvalToNumericXlator((short)
+ ( ValueEvalToNumericXlator.BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
+ | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.STRING_IS_PARSED
+ ));
+
+ public SubtractEval(Ptg ptg) {
+ delegate = (SubtractPtg) ptg;
+ }
+
+ protected ValueEvalToNumericXlator getXlator() {
+ return NUM_XLATOR;
+ }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ Eval retval = null;
+ double d0 = 0;
+ double d1 = 0;
+ switch (operands.length) {
+ default: // will rarely happen. currently the parser itself fails.
+ retval = ErrorEval.UNKNOWN_ERROR;
+ break;
+ case 2:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ d0 = ((NumericValueEval) ve).getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+
+ if (retval == null) { // no error yet
+ ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ d1 = ((NumericValueEval) ve).getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+ } // end switch
+
+ if (retval == null) {
+ retval = (Double.isNaN(d0) || Double.isNaN(d1))
+ ? (ValueEval) ErrorEval.VALUE_INVALID
+ : new NumberEval(d0 - d1);
+ }
+ return retval;
+ }
+
+ public int getNumberOfOperands() {
+ return delegate.getNumberOfOperands();
+ }
+
+ public int getType() {
+ return delegate.getType();
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java
new file mode 100644
index 000000000..84eececce
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java
@@ -0,0 +1,71 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class UnaryMinusEval extends NumericOperationEval {
+
+ private UnaryMinusPtg delegate;
+ private static final ValueEvalToNumericXlator NUM_XLATOR =
+ new ValueEvalToNumericXlator((short)
+ ( ValueEvalToNumericXlator.BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
+ | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.STRING_IS_PARSED
+ ));
+
+
+ public UnaryMinusEval(Ptg ptg) {
+ this.delegate = (UnaryMinusPtg) ptg;
+ }
+
+ protected ValueEvalToNumericXlator getXlator() {
+ return NUM_XLATOR;
+ }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ ValueEval retval = null;
+ double d = 0;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.UNKNOWN_ERROR;
+ break;
+ case 1:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ d = ((NumericValueEval) ve).getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else if (ve instanceof ErrorEval) {
+ retval = ve;
+ }
+ }
+
+ if (retval == null) {
+ retval = new NumberEval(-d);
+ }
+
+ return retval;
+ }
+
+ public int getNumberOfOperands() {
+ return delegate.getNumberOfOperands();
+ }
+
+ public int getType() {
+ return delegate.getType();
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java
new file mode 100644
index 000000000..5b311661f
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java
@@ -0,0 +1,131 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class UnaryPlusEval implements OperationEval /*extends NumericOperationEval*/ {
+
+ private UnaryPlusPtg delegate;
+
+ /*
+ * COMMENT FOR COMMENTED CODE IN THIS FILE
+ *
+ * The loser who programmed this in excel didnt care to
+ * think about how strings were handled in other numeric
+ * operations when he/she was implementing this operation :P
+ *
+ * Here's what I mean:
+ *
+ * Q. If the formula -"hello" evaluates to #VALUE! in excel, what should
+ * the formula +"hello" evaluate to?
+ *
+ * A. +"hello" evaluates to "hello"
+ *
+ * DO NOT remove the commented code (In memory of the excel
+ * programmer who implemented the UnaryPlus operation :)
+ */
+
+
+// private static final ValueEvalToNumericXlator NUM_XLATOR =
+// new ValueEvalToNumericXlator((short)
+// ( ValueEvalToNumericXlator.BOOL_IS_PARSED
+// | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
+// | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
+// | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
+// | ValueEvalToNumericXlator.STRING_IS_PARSED
+// ));
+
+
+ public UnaryPlusEval(Ptg ptg) {
+ this.delegate = (UnaryPlusPtg) ptg;
+ }
+
+// protected ValueEvalToNumericXlator getXlator() {
+// return NUM_XLATOR;
+// }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ ValueEval retval = null;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.UNKNOWN_ERROR;
+ break;
+ case 1:
+
+// ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+// if (ve instanceof NumericValueEval) {
+// d = ((NumericValueEval) ve).getNumberValue();
+// }
+// else if (ve instanceof BlankEval) {
+// // do nothing
+// }
+// else if (ve instanceof ErrorEval) {
+// retval = ve;
+// }
+ if (operands[0] instanceof RefEval) {
+ RefEval re = (RefEval) operands[0];
+ retval = re.getInnerValueEval();
+ }
+ else if (operands[0] instanceof AreaEval) {
+ AreaEval ae = (AreaEval) operands[0];
+ if (ae.contains(srcRow, srcCol)) { // circular ref!
+ retval = ErrorEval.CIRCULAR_REF_ERROR;
+ }
+ else if (ae.isRow()) {
+ if (ae.containsColumn(srcCol)) {
+ ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
+ if (ve instanceof RefEval) {
+ ve = ((RefEval) ve).getInnerValueEval();
+ }
+ retval = ve;
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+ else if (ae.isColumn()) {
+ if (ae.containsRow(srcRow)) {
+ ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
+ if (ve instanceof RefEval) {
+ ve = ((RefEval) ve).getInnerValueEval();
+ }
+ retval = ve;
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ }
+ else {
+ retval = (ValueEval) operands[0];
+ }
+ }
+
+ if (retval instanceof BlankEval) {
+ retval = new NumberEval(0);
+ }
+
+ return retval;
+ }
+
+ public int getNumberOfOperands() {
+ return delegate.getNumberOfOperands();
+ }
+
+ public int getType() {
+ return delegate.getType();
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEval.java
new file mode 100644
index 000000000..44d0d6de5
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEval.java
@@ -0,0 +1,13 @@
+/*
+ * Created on May 8, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public interface ValueEval extends Eval {
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java
new file mode 100644
index 000000000..fb089227e
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java
@@ -0,0 +1,203 @@
+/*
+ * Created on May 14, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class ValueEvalToNumericXlator {
+
+ public static final short STRING_IS_PARSED = 0x0001;
+ public static final short BOOL_IS_PARSED = 0x0002;
+
+ public static final short REF_STRING_IS_PARSED = 0x0004;
+ public static final short REF_BOOL_IS_PARSED = 0x0008;
+
+ public static final short EVALUATED_REF_STRING_IS_PARSED = 0x0010;
+ public static final short EVALUATED_REF_BOOL_IS_PARSED = 0x0020;
+
+ public static final short STRING_TO_BOOL_IS_PARSED = 0x0040;
+ public static final short REF_STRING_TO_BOOL_IS_PARSED = 0x0080;
+
+ public static final short STRING_IS_INVALID_VALUE = 0x0100;
+ public static final short REF_STRING_IS_INVALID_VALUE = 0x200;
+
+ private final short flags;
+
+
+ public ValueEvalToNumericXlator(short flags) {
+ this.flags = flags;
+ }
+
+ /**
+ * returned value can be either A NumericValueEval, BlankEval or ErrorEval.
+ * The params can be either NumberEval, BoolEval, StringEval, or
+ * RefEval
+ * @param eval
+ * @return
+ */
+ public ValueEval attemptXlateToNumeric(ValueEval eval) {
+ ValueEval retval = null;
+
+ if (eval == null) {
+ retval = BlankEval.INSTANCE;
+ }
+
+ // most common case - least worries :)
+ else if (eval instanceof NumberEval) {
+ retval = (NumberEval) eval;
+ }
+
+ // booleval
+ else if (((flags | BOOL_IS_PARSED) > 0) && eval instanceof BoolEval) {
+ retval = (NumericValueEval) eval;
+ }
+
+ // stringeval
+ else if (eval instanceof StringEval) {
+ retval = handleStringEval((StringEval) eval);
+ }
+
+ // refeval
+ else if (eval instanceof RefEval) {
+ retval = handleRefEval((RefEval) eval);
+ }
+
+ //blankeval
+ else if (eval instanceof BlankEval) {
+ retval = eval;
+ }
+
+ // erroreval
+ else if (eval instanceof ErrorEval) {
+ retval = eval;
+ }
+
+ // probably AreaEval? then not acceptable.
+ else {
+ throw new RuntimeException("Invalid ValueEval type passed for conversion: " + eval.getClass());
+ }
+ return retval;
+ }
+
+ /**
+ * uses the relevant flags to decode the supplied RefVal
+ * @param eval
+ * @return
+ */
+ private ValueEval handleRefEval(RefEval reval) {
+ ValueEval retval = null;
+ ValueEval eval = (ValueEval) reval.getInnerValueEval();
+
+ // most common case - least worries :)
+ if (eval instanceof NumberEval) {
+ retval = (NumberEval) eval; // the cast is correct :)
+ }
+
+ // booleval
+ else if (((flags | REF_BOOL_IS_PARSED) > 0) && eval instanceof BoolEval) {
+ retval = (NumericValueEval) eval;
+ }
+
+ // stringeval
+ else if (eval instanceof StringEval) {
+ retval = handleRefStringEval((StringEval) eval);
+ }
+
+ //blankeval
+ else if (eval instanceof BlankEval) {
+ retval = eval;
+ }
+
+ // erroreval
+ else if (eval instanceof ErrorEval) {
+ retval = eval;
+ }
+
+ // probably AreaEval or another RefEval? then not acceptable.
+ else {
+ throw new RuntimeException("Invalid ValueEval type passed for conversion: " + eval.getClass());
+ }
+ return retval;
+ }
+
+ /**
+ * uses the relevant flags to decode the StringEval
+ * @param eval
+ * @return
+ */
+ private ValueEval handleStringEval(StringEval eval) {
+ ValueEval retval = null;
+ if ((flags | STRING_IS_PARSED) > 0) {
+ StringEval sve = (StringEval) eval;
+ String s = sve.getStringValue();
+ try {
+ double d = Double.parseDouble(s);
+ retval = new NumberEval(d);
+ }
+ catch (Exception e) { retval = ErrorEval.VALUE_INVALID; }
+ }
+ else if ((flags | STRING_TO_BOOL_IS_PARSED) > 0) {
+ StringEval sve = (StringEval) eval;
+ String s = sve.getStringValue();
+ try {
+ boolean b = Boolean.getBoolean(s);
+ retval = b ? BoolEval.TRUE : BoolEval.FALSE;
+ }
+ catch (Exception e) { retval = ErrorEval.VALUE_INVALID; }
+ }
+
+ // strings are errors?
+ else if ((flags | STRING_IS_INVALID_VALUE) > 0) {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+
+ // ignore strings
+ else {
+ retval = BlankEval.INSTANCE;
+ }
+ return retval;
+ }
+
+ /**
+ * uses the relevant flags to decode the StringEval
+ * @param eval
+ * @return
+ */
+ private ValueEval handleRefStringEval(StringEval eval) {
+ ValueEval retval = null;
+ if ((flags | REF_STRING_IS_PARSED) > 0) {
+ StringEval sve = (StringEval) eval;
+ String s = sve.getStringValue();
+ try {
+ double d = Double.parseDouble(s);
+ retval = new NumberEval(d);
+ }
+ catch (Exception e) { retval = ErrorEval.VALUE_INVALID; }
+ }
+ else if ((flags | REF_STRING_TO_BOOL_IS_PARSED) > 0) {
+ StringEval sve = (StringEval) eval;
+ String s = sve.getStringValue();
+ try {
+ boolean b = Boolean.getBoolean(s);
+ retval = retval = b ? BoolEval.TRUE : BoolEval.FALSE;;
+ }
+ catch (Exception e) { retval = ErrorEval.VALUE_INVALID; }
+ }
+
+ // strings are errors?
+ else if ((flags | REF_STRING_IS_INVALID_VALUE) > 0) {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+
+ // ignore strings
+ else {
+ retval = BlankEval.INSTANCE;
+ }
+ return retval;
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Abs.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Abs.java
new file mode 100644
index 000000000..9f29615ae
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Abs.java
@@ -0,0 +1,62 @@
+/*
+ * Created on May 6, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+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.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class Abs extends NumericFunction {
+
+ private static final ValueEvalToNumericXlator NUM_XLATOR =
+ new ValueEvalToNumericXlator((short)
+ ( ValueEvalToNumericXlator.BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
+ | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.STRING_IS_PARSED
+ ));
+
+ protected ValueEvalToNumericXlator getXlator() {
+ return NUM_XLATOR;
+ }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ double d = 0;
+ ValueEval retval = null;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.VALUE_INVALID;
+ break;
+ case 1:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ d = ne.getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.NUM_ERROR;
+ }
+ }
+
+ if (retval == null) {
+ retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(Math.abs(d));
+ }
+ return retval;
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Absref.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Absref.java
new file mode 100644
index 000000000..875e38256
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Absref.java
@@ -0,0 +1,13 @@
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+/**
+ * @author
+ *
+ */
+public class Absref extends DefaultFunctionImpl {
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acos.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acos.java
new file mode 100644
index 000000000..eb8e69301
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acos.java
@@ -0,0 +1,62 @@
+/*
+ * Created on May 6, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+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.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class Acos extends NumericFunction {
+
+ private static final ValueEvalToNumericXlator NUM_XLATOR =
+ new ValueEvalToNumericXlator((short)
+ ( ValueEvalToNumericXlator.BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
+ | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.STRING_IS_PARSED
+ ));
+
+ protected ValueEvalToNumericXlator getXlator() {
+ return NUM_XLATOR;
+ }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ double d = 0;
+ ValueEval retval = null;
+
+ switch (operands.length) {
+ default:
+ break;
+ case 1:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ d = ne.getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.NUM_ERROR;
+ }
+ }
+
+ if (retval == null) {
+ d = Math.acos(d);
+ retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+ }
+ return retval;
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acosh.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acosh.java
new file mode 100644
index 000000000..570e10932
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acosh.java
@@ -0,0 +1,60 @@
+/*
+ * Created on May 6, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+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.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ * Support for hyperbolic trig functions was added as a part of
+ * Java distribution only in JDK1.5. This class uses custom
+ * naive implementation based on formulas at:
+ * http://www.math2.org/math/trig/hyperbolics.htm
+ * These formulas seem to agree with excel's implementation.
+ *
+ */
+public class Acosh extends NumericFunction {
+
+ private static final ValueEvalToNumericXlator NUM_XLATOR =
+ new ValueEvalToNumericXlator((short)
+ ( ValueEvalToNumericXlator.BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
+ | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
+ | ValueEvalToNumericXlator.STRING_IS_PARSED
+ ));
+
+ protected ValueEvalToNumericXlator getXlator() {
+ return NUM_XLATOR;
+ }
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ double d = 0;
+ ValueEval retval = null;
+
+ switch (operands.length) {
+ default:
+ break;
+ case 1:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ d = ne.getNumberValue();
+ }
+ }
+
+ if (retval == null) {
+ d = Math.log(Math.sqrt(Math.pow(d, 2) - 1) + d);
+ retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.NUM_ERROR : new NumberEval(d);
+ }
+ return retval;
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Activecell.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Activecell.java
new file mode 100644
index 000000000..d8f08c20a
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Activecell.java
@@ -0,0 +1,13 @@
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+/**
+ * @author
+ *
+ */
+public class Activecell extends DefaultFunctionImpl {
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addbar.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addbar.java
new file mode 100644
index 000000000..70000ef0e
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addbar.java
@@ -0,0 +1,13 @@
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+/**
+ * @author
+ *
+ */
+public class Addbar extends DefaultFunctionImpl {
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addcommand.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addcommand.java
new file mode 100644
index 000000000..deab551ea
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addcommand.java
@@ -0,0 +1,13 @@
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+/**
+ * @author
+ *
+ */
+public class Addcommand extends DefaultFunctionImpl {
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addmenu.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addmenu.java
new file mode 100644
index 000000000..9027fae5c
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addmenu.java
@@ -0,0 +1,13 @@
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+/**
+ * @author
+ *
+ */
+public class Addmenu extends DefaultFunctionImpl {
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Address.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Address.java
new file mode 100644
index 000000000..402a3613a
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Address.java
@@ -0,0 +1,13 @@
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+/**
+ * @author
+ *
+ */
+public class Address extends DefaultFunctionImpl {
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addtoolbar.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addtoolbar.java
new file mode 100644
index 000000000..1d73339b5
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Addtoolbar.java
@@ -0,0 +1,13 @@
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+/**
+ * @author
+ *
+ */
+public class Addtoolbar extends DefaultFunctionImpl {
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/And.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/And.java
new file mode 100644
index 000000000..bca546390
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/And.java
@@ -0,0 +1,73 @@
+/*
+ * Created on May 9, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.AreaEval;
+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.StringEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * @author
+ *
+ */
+public class And extends BooleanFunction {
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ ValueEval retval = null;
+ boolean b = true;
+ boolean atleastOneNonBlank = false;
+
+ /*
+ * Note: do not abort the loop if b is false, since we could be
+ * dealing with errorevals later.
+ */
+ outer:
+ for (int i=0, iSize=operands.length; i