Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 849d8a46 authored by Hans Boehm's avatar Hans Boehm
Browse files

Reevaluate erroneous current result in history

Bug: 33555997

We were losing the error message by never evaluating for
HISTORY_MAIN_INDEX. But in the error case, we need to regenerate the
error notification.

We now store a special error value in the result string, so that
we can distinguish the error case.

Change-Id: I1311ce94a214da01d2e975666f6cb927fcd836f1
parent 12874e38
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -269,6 +269,9 @@ public class Evaluator implements CalculatorExpr.ExprResolver {

    public static final int INVALID_MSD = Integer.MAX_VALUE;

    // Used to represent an error result. Not displayed.
    public static final String ERRONEOUS_RESULT = "ERR";

    /**
     * An individual CalculatorExpr, together with its evaluation state.
     * Only the main expression may be changed in-place. The HISTORY_MAIN_INDEX expression is
@@ -303,6 +306,7 @@ public class Evaluator implements CalculatorExpr.ExprResolver {
        // We cache the best known decimal result in mResultString.  Whenever that is
        // non-null, it is computed to exactly mResultStringOffset, which is always > 0.
        // Valid only if mResultString is non-null and (for the main expression) !mChangedValue.
        // ERRONEOUS_RESULT indicates evaluation resulted in an error.
        public String mResultString;
        public int mResultStringOffset = 0;
        // Number of digits to which (possibly incomplete) evaluation has been requested.
@@ -613,6 +617,7 @@ public class Evaluator implements CalculatorExpr.ExprResolver {
                    }
                    mListener.onCancelled(mIndex);
                } else {
                    mExprInfo.mResultString = ERRONEOUS_RESULT;
                    mListener.onError(mIndex, result.errorResourceId);
                }
                return;
@@ -740,6 +745,7 @@ public class Evaluator implements CalculatorExpr.ExprResolver {
                // This should only be possible in the extremely rare case of encountering a
                // domain error while reevaluating or in case of a precision overflow.  We don't
                // know of a way to get the latter with a plausible amount of user input.
                mExprInfo.mResultString = ERRONEOUS_RESULT;
                mListener.onError(mIndex, R.string.error_nan);
            } else {
                if (result.newResultStringOffset < mExprInfo.mResultStringOffset) {
@@ -759,6 +765,7 @@ public class Evaluator implements CalculatorExpr.ExprResolver {
    /**
     * If necessary, start an evaluation of the expression at the given index to precOffset.
     * If we start an evaluation the listener is notified on completion.
     * Only called if prior evaluation succeeded.
     */
    private void ensureCachePrec(long index, int precOffset, EvaluationListener listener) {
        ExprInfo ei = mExprs.get(index);
@@ -1153,7 +1160,8 @@ public class Evaluator implements CalculatorExpr.ExprResolver {
            return;
        }
        ExprInfo ei = ensureExprIsCached(index);
        if (ei.mResultString != null && !(index == MAIN_INDEX && mChangedValue)) {
        if (ei.mResultString != null && ei.mResultString != ERRONEOUS_RESULT
                && !(index == MAIN_INDEX && mChangedValue)) {
            // Already done. Just notify.
            notifyImmediately(MAIN_INDEX, mMainExpr, listener, cmi);
            return;
@@ -1179,6 +1187,7 @@ public class Evaluator implements CalculatorExpr.ExprResolver {
            if (index == HISTORY_MAIN_INDEX) {
                // We don't want to compute a result for HISTORY_MAIN_INDEX that was
                // not already computed for the main expression. Pretend we timed out.
                // The error case doesn't get here.
                listener.onCancelled(index);
            } else if ((ei.mEvaluator instanceof AsyncEvaluator)
                    && ((AsyncEvaluator)(ei.mEvaluator)).mRequired) {
@@ -1188,6 +1197,10 @@ public class Evaluator implements CalculatorExpr.ExprResolver {
                cancel(ei, true);
                evaluateResult(index, listener, cmi, true);
            }
        } else if (ei.mResultString == ERRONEOUS_RESULT) {
            // Just re-evaluate to generate a new notification.
            cancel(ei, true);
            evaluateResult(index, listener, cmi, true);
        } else {
            notifyImmediately(index, ei, listener, cmi);
        }
@@ -1444,7 +1457,7 @@ public class Evaluator implements CalculatorExpr.ExprResolver {
     */
    public long preserve(boolean in_history) {
        ExprInfo ei = copy(MAIN_INDEX, true);
        if (ei.mResultString == null) {
        if (ei.mResultString == null || ei.mResultString == ERRONEOUS_RESULT) {
            throw new AssertionError("Preserving unevaluated expression");
        }
        return addToDB(in_history, ei);
@@ -1612,7 +1625,8 @@ public class Evaluator implements CalculatorExpr.ExprResolver {
     * mExpr is left alone.  Return false if result is unavailable.
     */
    private boolean copyToSaved(long index) {
        if (mExprs.get(index).mResultString == null) {
        if (mExprs.get(index).mResultString == null
                || mExprs.get(index).mResultString == ERRONEOUS_RESULT) {
            return false;
        }
        setSavedIndex((index == MAIN_INDEX) ? preserve(false) : index);