/**
         * Used by the lazy ref evals whenever they need To Get the value of a contained cell.
         */
        /* package */
        public ValueEval EvaluateReference(IEvaluationSheet sheet, int sheetIndex, int rowIndex,
                                           int columnIndex, EvaluationTracker tracker)
        {
            IEvaluationCell cell = sheet.GetCell(rowIndex, columnIndex);

            return(EvaluateAny(cell, sheetIndex, rowIndex, columnIndex, tracker));
        }
Esempio n. 2
0
        /**
         * Dereferences a single value from any AreaEval or RefEval evaluation
         * result. If the supplied evaluationResult is just a plain value, it is
         * returned as-is.
         *
         * @return a {@link NumberEval}, {@link StringEval}, {@link BoolEval}, or
         *         {@link ErrorEval}. Never <code>null</code>. {@link BlankEval} is
         *         converted to {@link NumberEval#ZERO}
         */
        public static ValueEval DereferenceResult(ValueEval evaluationResult, OperationEvaluationContext ec)
        {
            ValueEval value;

            if (ec == null)
            {
                throw new ArgumentNullException("OperationEvaluationContext ec is null");
            }
            if (ec.GetWorkbook() == null)
            {
                throw new ArgumentNullException("OperationEvaluationContext ec.getWorkbook() is null");
            }

            IEvaluationSheet evalSheet = ec.GetWorkbook().GetSheet(ec.SheetIndex);
            IEvaluationCell  evalCell  = evalSheet.GetCell(ec.RowIndex, ec.ColumnIndex);

            if (evalCell.IsPartOfArrayFormulaGroup && evaluationResult is AreaEval)
            {
                value = OperandResolver.GetElementFromArray((AreaEval)evaluationResult, evalCell);
            }
            else
            {
                value = DereferenceResult(evaluationResult, ec.RowIndex, ec.ColumnIndex);
            }

            return(value);
        }
Esempio n. 3
0
        public static ValueEval EvaluateArrayFunction(ArrayFunction func, ValueEval[] args,
                                                      OperationEvaluationContext ec)
        {
            IEvaluationSheet evalSheet = ec.GetWorkbook().GetSheet(ec.SheetIndex);
            IEvaluationCell  evalCell  = evalSheet.GetCell(ec.RowIndex, ec.ColumnIndex);

            if (evalCell != null)
            {
                if (evalCell.IsPartOfArrayFormulaGroup)
                {
                    // array arguments must be evaluated relative to the function defining range
                    Util.CellRangeAddress ca = evalCell.ArrayFormulaRange;
                    return(func.EvaluateArray(args, ca.FirstRow, ca.FirstColumn));
                }
                else if (ec.IsArraymode)
                {
                    return(func.EvaluateArray(args, ec.RowIndex, ec.ColumnIndex));
                }
            }
            return(null);
        }
Esempio n. 4
0
        /**
         * Used by the lazy ref evals whenever they need To Get the value of a contained cell.
         */
        /* package */
        public ValueEval EvaluateReference(IEvaluationSheet sheet, int sheetIndex, int rowIndex,
            int columnIndex, EvaluationTracker tracker)
        {

            IEvaluationCell cell = sheet.GetCell(rowIndex, columnIndex);
            return EvaluateAny(cell, sheetIndex, rowIndex, columnIndex, tracker);
        }
Esempio n. 5
0
        // visibility raised for testing
        /* package */
        public ValueEval EvaluateFormula(OperationEvaluationContext ec, Ptg[] ptgs)
        {
            String dbgIndentStr = "";           // always init. to non-null just for defensive avoiding NPE

            if (dbgEvaluationOutputForNextEval)
            {
                // first evaluation call when ouput is desired, so iit. this evaluator instance
                dbgEvaluationOutputIndent      = 1;
                dbgEvaluationOutputForNextEval = false;
            }
            if (dbgEvaluationOutputIndent > 0)
            {
                // init. indent string to needed spaces (create as substring vom very long space-only string;
                // limit indendation for deep recursions)
                dbgIndentStr = "                                                                                                    ";
                dbgIndentStr = dbgIndentStr.Substring(0, Math.Min(dbgIndentStr.Length, dbgEvaluationOutputIndent * 2));
                EVAL_LOG.Log(POILogger.WARN, dbgIndentStr
                             + "- evaluateFormula('" + ec.GetRefEvaluatorForCurrentSheet().SheetNameRange
                             + "'/" + new CellReference(ec.RowIndex, ec.ColumnIndex).FormatAsString()
                             + "): " + Arrays.ToString(ptgs).Replace("\\Qorg.apache.poi.ss.formula.ptg.\\E", ""));
                dbgEvaluationOutputIndent++;
            }

            IEvaluationSheet evalSheet      = ec.GetWorkbook().GetSheet(ec.SheetIndex);
            IEvaluationCell  evaluationCell = evalSheet.GetCell(ec.RowIndex, ec.ColumnIndex);

            Stack <ValueEval> stack = new Stack <ValueEval>();

            for (int i = 0, iSize = ptgs.Length; i < iSize; i++)
            {
                // since we don't know how To handle these yet :(
                Ptg ptg = ptgs[i];
                if (dbgEvaluationOutputIndent > 0)
                {
                    EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + "  * ptg " + i + ": " + ptg.ToString() + ", stack:" + stack);
                }
                if (ptg is AttrPtg)
                {
                    AttrPtg attrPtg = (AttrPtg)ptg;
                    if (attrPtg.IsSum)
                    {
                        // Excel prefers To encode 'SUM()' as a tAttr Token, but this evaluator
                        // expects the equivalent function Token
                        //byte nArgs = 1;  // tAttrSum always Has 1 parameter
                        ptg = FuncVarPtg.SUM;//.Create("SUM", nArgs);
                    }
                    if (attrPtg.IsOptimizedChoose)
                    {
                        ValueEval arg0      = stack.Pop();
                        int[]     jumpTable = attrPtg.JumpTable;
                        int       dist;
                        int       nChoices = jumpTable.Length;
                        try
                        {
                            int switchIndex = Choose.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex);
                            if (switchIndex < 1 || switchIndex > nChoices)
                            {
                                stack.Push(ErrorEval.VALUE_INVALID);
                                dist = attrPtg.ChooseFuncOffset + 4; // +4 for tFuncFar(CHOOSE)
                            }
                            else
                            {
                                dist = jumpTable[switchIndex - 1];
                            }
                        }
                        catch (EvaluationException e)
                        {
                            stack.Push(e.GetErrorEval());
                            dist = attrPtg.ChooseFuncOffset + 4; // +4 for tFuncFar(CHOOSE)
                        }
                        // Encoded dist for tAttrChoose includes size of jump table, but
                        // countTokensToBeSkipped() does not (it counts whole tokens).
                        dist -= nChoices * 2 + 2; // subtract jump table size
                        i    += CountTokensToBeSkipped(ptgs, i, dist);
                        continue;
                    }
                    if (attrPtg.IsOptimizedIf)
                    {
                        if (!evaluationCell.IsPartOfArrayFormulaGroup)
                        {
                            ValueEval arg0 = stack.Pop();
                            bool      evaluatedPredicate;
                            try
                            {
                                evaluatedPredicate = IfFunc.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex);
                            }
                            catch (EvaluationException e)
                            {
                                stack.Push(e.GetErrorEval());
                                int dist = attrPtg.Data;
                                i      += CountTokensToBeSkipped(ptgs, i, dist);
                                attrPtg = (AttrPtg)ptgs[i];
                                dist    = attrPtg.Data + 1;
                                i      += CountTokensToBeSkipped(ptgs, i, dist);
                                continue;
                            }
                            if (evaluatedPredicate)
                            {
                                // nothing to skip - true param folows
                            }
                            else
                            {
                                int dist = attrPtg.Data;
                                i += CountTokensToBeSkipped(ptgs, i, dist);
                                Ptg nextPtg = ptgs[i + 1];
                                if (ptgs[i] is AttrPtg && nextPtg is FuncVarPtg &&
                                    // in order to verify that there is no third param, we need to check
                                    // if we really have the IF next or some other FuncVarPtg as third param, e.g. ROW()/COLUMN()!
                                    ((FuncVarPtg)nextPtg).FunctionIndex == FunctionMetadataRegistry.FUNCTION_INDEX_IF)
                                {
                                    // this is an if statement without a false param (as opposed to MissingArgPtg as the false param)
                                    i++;
                                    stack.Push(arg0);
                                    stack.Push(BoolEval.FALSE);
                                }
                            }
                        }
                        continue;
                    }
                    if (attrPtg.IsSkip && !evaluationCell.IsPartOfArrayFormulaGroup)
                    {
                        int dist = attrPtg.Data + 1;
                        i += CountTokensToBeSkipped(ptgs, i, dist);
                        if (stack.Peek() == MissingArgEval.instance)
                        {
                            stack.Pop();
                            stack.Push(BlankEval.instance);
                        }
                        continue;
                    }
                }
                if (ptg is ControlPtg)
                {
                    // skip Parentheses, Attr, etc
                    continue;
                }
                if (ptg is MemFuncPtg || ptg is MemAreaPtg)
                {
                    // can ignore, rest of Tokens for this expression are in OK RPN order
                    continue;
                }
                if (ptg is MemErrPtg)
                {
                    continue;
                }
                if (ptg is UnionPtg)
                {
                    ValueEval v2 = stack.Pop();
                    ValueEval v1 = stack.Pop();
                    stack.Push(new RefListEval(v1, v2));
                    continue;
                }
                ValueEval opResult;
                if (ptg is OperationPtg)
                {
                    OperationPtg optg = (OperationPtg)ptg;

                    if (optg is UnionPtg)
                    {
                        continue;
                    }

                    int         numops = optg.NumberOfOperands;
                    ValueEval[] ops    = new ValueEval[numops];

                    // storing the ops in reverse order since they are popping
                    for (int j = numops - 1; j >= 0; j--)
                    {
                        ValueEval p = (ValueEval)stack.Pop();
                        ops[j] = p;
                    }
                    //				logDebug("Invoke " + operation + " (nAgs=" + numops + ")");
                    opResult = OperationEvaluatorFactory.Evaluate(optg, ops, ec);
                }
                else
                {
                    opResult = GetEvalForPtg(ptg, ec);
                }
                if (opResult == null)
                {
                    throw new Exception("Evaluation result must not be null");
                }
                //			logDebug("push " + opResult);
                stack.Push(opResult);
                if (dbgEvaluationOutputIndent > 0)
                {
                    EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + "    = " + opResult.ToString());
                }
            }

            ValueEval value = ((ValueEval)stack.Pop());

            if (stack.Count != 0)
            {
                throw new InvalidOperationException("evaluation stack not empty");
            }
            ValueEval result;

            if (ec.IsSingleValue)
            {
                result = DereferenceResult(value, ec);
            }
            else
            {
                result = value;
            }
            if (dbgEvaluationOutputIndent > 0)
            {
                EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + "finshed eval of "
                             + new CellReference(ec.RowIndex, ec.ColumnIndex).FormatAsString()
                             + ": " + result.ToString());
                dbgEvaluationOutputIndent--;
                if (dbgEvaluationOutputIndent == 1)
                {
                    // this evaluation is done, reset indent to stop logging
                    dbgEvaluationOutputIndent = -1;
                }
            } // if
            return(result);
        }