1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #ifndef INCLUDED_FORMULA_ERRORCODES_HXX 21 #define INCLUDED_FORMULA_ERRORCODES_HXX 22 23 #include <rtl/math.hxx> 24 #include <sal/mathconf.h> 25 #include <sal/types.h> 26 27 // Store as 16-bits, since error values are stored in tokens and formula results, 28 // and that can matter 29 enum class FormulaError : sal_uInt16 30 { 31 NONE = 0, 32 33 IllegalChar = 501, 34 IllegalArgument = 502, 35 IllegalFPOperation = 503, // #NUM! 36 IllegalParameter = 504, 37 Pair = 507, 38 PairExpected = 508, 39 OperatorExpected = 509, 40 VariableExpected = 510, 41 ParameterExpected = 511, 42 CodeOverflow = 512, 43 StringOverflow = 513, 44 StackOverflow = 514, 45 UnknownState = 515, 46 UnknownVariable = 516, 47 UnknownOpCode = 517, 48 UnknownStackVariable = 518, 49 NoValue = 519, // #VALUE! 50 UnknownToken = 520, 51 NoCode = 521, // #NULL! 52 CircularReference = 522, 53 NoConvergence = 523, 54 NoRef = 524, // #REF! 55 NoName = 525, // #NAME? 56 // ScInterpreter internal: no numeric value but numeric queried. If this is 57 // set as mnStringNoValueError no error is generated but 0 returned. 58 CellNoValue = 529, 59 // Interpreter: needed AddIn not found 60 NoAddin = 530, 61 // Interpreter: needed Macro not found 62 NoMacro = 531, 63 // Interpreter: Division by zero 64 DivisionByZero = 532, // #DIV/0! 65 // Compiler: a non-simple (str,err,val) value was put in an array 66 NestedArray = 533, 67 // ScInterpreter internal: no numeric value but numeric queried. If this is 68 // temporarily (!) set as mnStringNoValueError, the error is generated and can 69 // be used to distinguish that condition from all other (inherited) errors. Do 70 // not use for anything else! Never push or inherit the error otherwise! 71 NotNumericString = 534, 72 // ScInterpreter internal: jump matrix already has a result at this position, 73 // do not overwrite in case of empty code path. 74 JumpMatHasResult = 535, 75 // ScInterpreter internal: (matrix) element is not a numeric value, i.e. 76 // string or empty, to be distinguished from the general FormulaError::NoValue NAN and not 77 // to be used as result. 78 ElementNaN = 536, 79 // ScInterpreter/ScFormulaCell internal: keep dirty, retry interpreting next 80 // round. 81 RetryCircular = 537, 82 // If matrix could not be allocated. 83 MatrixSize = 538, 84 // Bad inline array content, non-value/non-string. 85 BadArrayContent = 539, 86 // Interpreter: signal result not available because updating links is not 87 // allowed (yet) and tell to try hybrid string as result. 88 LinkFormulaNeedingCheck = 540, 89 90 // Interpreter: NA() not available condition, not a real error 91 NotAvailable = 0x7fff 92 }; 93 94 /** Unconditionally construct a double value of NAN where the lower bits 95 represent an interpreter error code. */ 96 inline double CreateDoubleError( FormulaError nErr ) 97 { 98 sal_math_Double smVal; 99 ::rtl::math::setNan( &smVal.value ); 100 smVal.nan_parts.fraction_lo = static_cast<unsigned>(nErr); 101 return smVal.value; 102 } 103 104 /** Recreate the error code of a coded double error, if any. */ 105 inline FormulaError GetDoubleErrorValue( double fVal ) 106 { 107 if ( ::rtl::math::isFinite( fVal ) ) 108 return FormulaError::NONE; 109 if ( ::rtl::math::isInf( fVal ) ) 110 return FormulaError::IllegalFPOperation; // normal INF 111 sal_uInt32 nErr = reinterpret_cast< sal_math_Double * >( &fVal)->nan_parts.fraction_lo; 112 if ( nErr & 0xffff0000 ) 113 return FormulaError::NoValue; // just a normal NAN 114 if (!nErr) 115 // Another NAN, e.g. -nan(0x8000000000000) from calculating with -inf 116 return FormulaError::IllegalFPOperation; 117 // Any other error known to us as error code. 118 return static_cast<FormulaError>(nErr & 0x0000ffff); 119 } 120 121 /** Error values that are accepted as detailed "#ERRxxx!" constants. 122 123 Used in FormulaCompiler::GetErrorConstant() to prevent users from inventing 124 arbitrary values that already have or later might get a significant meaning. 125 */ 126 inline bool isPublishedFormulaError( FormulaError nErr ) 127 { 128 // Every value has to be handled explicitly, do not add a default case to 129 // let the compiler complain if a value is missing. 130 switch (nErr) 131 { 132 case FormulaError::NONE: 133 return false; 134 135 case FormulaError::IllegalChar: 136 case FormulaError::IllegalArgument: 137 case FormulaError::IllegalFPOperation: 138 case FormulaError::IllegalParameter: 139 case FormulaError::Pair: 140 case FormulaError::PairExpected: 141 case FormulaError::OperatorExpected: 142 case FormulaError::VariableExpected: 143 case FormulaError::ParameterExpected: 144 case FormulaError::CodeOverflow: 145 case FormulaError::StringOverflow: 146 case FormulaError::StackOverflow: 147 case FormulaError::UnknownState: 148 case FormulaError::UnknownVariable: 149 case FormulaError::UnknownOpCode: 150 case FormulaError::UnknownStackVariable: 151 case FormulaError::NoValue: 152 case FormulaError::UnknownToken: 153 case FormulaError::NoCode: 154 case FormulaError::CircularReference: 155 case FormulaError::NoConvergence: 156 case FormulaError::NoRef: 157 case FormulaError::NoName: 158 return true; 159 160 case FormulaError::CellNoValue: 161 return false; 162 163 case FormulaError::NoAddin: 164 case FormulaError::NoMacro: 165 case FormulaError::DivisionByZero: 166 case FormulaError::NestedArray: 167 case FormulaError::BadArrayContent: 168 return true; 169 170 case FormulaError::NotNumericString: 171 case FormulaError::JumpMatHasResult: 172 case FormulaError::ElementNaN: 173 case FormulaError::RetryCircular: 174 return false; 175 176 case FormulaError::MatrixSize: 177 case FormulaError::LinkFormulaNeedingCheck: 178 return true; 179 180 case FormulaError::NotAvailable: 181 return false; 182 } 183 return false; 184 } 185 186 #endif // INCLUDED_FORMULA_ERRORCODES_HXX 187 188 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 189
