summaryrefslogtreecommitdiffstats
path: root/include/formula
diff options
context:
space:
mode:
Diffstat (limited to 'include/formula')
-rw-r--r--include/formula/ExternalReferenceHelper.hxx44
-rw-r--r--include/formula/FormulaCompiler.hxx506
-rw-r--r--include/formula/FormulaOpCodeMapperObj.hxx79
-rw-r--r--include/formula/IControlReferenceHandler.hxx44
-rw-r--r--include/formula/IFunctionDescription.hxx160
-rw-r--r--include/formula/compiler.hxx531
-rw-r--r--include/formula/errorcodes.hxx190
-rw-r--r--include/formula/formdata.hxx71
-rw-r--r--include/formula/formula.hxx125
-rw-r--r--include/formula/formuladllapi.h34
-rw-r--r--include/formula/formulahelper.hxx85
-rw-r--r--include/formula/funcutl.hxx182
-rw-r--r--include/formula/funcvarargs.h49
-rw-r--r--include/formula/grammar.hxx247
-rw-r--r--include/formula/opcode.hxx995
-rw-r--r--include/formula/paramclass.hxx81
-rw-r--r--include/formula/token.hxx483
-rw-r--r--include/formula/tokenarray.hxx674
-rw-r--r--include/formula/types.hxx34
-rw-r--r--include/formula/vectortoken.hxx110
20 files changed, 4724 insertions, 0 deletions
diff --git a/include/formula/ExternalReferenceHelper.hxx b/include/formula/ExternalReferenceHelper.hxx
new file mode 100644
index 0000000000..364307f637
--- /dev/null
+++ b/include/formula/ExternalReferenceHelper.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_EXTERNALREFERENCEHELPER_HXX
+#define INCLUDED_FORMULA_EXTERNALREFERENCEHELPER_HXX
+
+#include <cstddef>
+
+#include <formula/formuladllapi.h>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+namespace formula
+{
+ class FORMULA_DLLPUBLIC SAL_NO_VTABLE ExternalReferenceHelper
+ {
+ public:
+ virtual OUString getCacheTableName(sal_uInt16 nFileId, size_t nTabIndex) const = 0;
+
+ protected:
+ ~ExternalReferenceHelper() {}
+ };
+
+} // formula
+
+#endif // INCLUDED_FORMULA_EXTERNALREFERENCEHELPER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/FormulaCompiler.hxx b/include/formula/FormulaCompiler.hxx
new file mode 100644
index 0000000000..08710f561b
--- /dev/null
+++ b/include/formula/FormulaCompiler.hxx
@@ -0,0 +1,506 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_FORMULACOMPILER_HXX
+#define INCLUDED_FORMULA_FORMULACOMPILER_HXX
+
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <formula/formuladllapi.h>
+#include <formula/grammar.hxx>
+#include <formula/opcode.hxx>
+#include <formula/tokenarray.hxx>
+#include <formula/types.hxx>
+#include <formula/paramclass.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+#include <tools/debug.hxx>
+
+#define FORMULA_MAXJUMPCOUNT 32 /* maximum number of jumps (ocChoose) */
+#define FORMULA_MAXTOKENS 8192 /* maximum number of tokens in formula */
+#define FORMULA_MAXPARAMS 255 /* maximum number of parameters per function (byte) */
+#define FORMULA_MAXPARAMSII 8 /* maximum number of parameters for functions that have implicit intersection ranges */
+
+
+namespace com::sun::star {
+ namespace sheet {
+ struct FormulaOpCodeMapEntry;
+ struct FormulaToken;
+ }
+}
+
+class CharClass;
+enum class FormulaError : sal_uInt16;
+enum class SvNumFormatType : sal_Int16;
+
+namespace formula
+{
+
+struct FormulaArrayStack
+{
+ FormulaArrayStack* pNext;
+ FormulaTokenArray* pArr;
+ FormulaTokenRef mpLastToken;
+ sal_uInt16 nIndex;
+ bool bTemp;
+};
+
+typedef std::unordered_map< OUString, OpCode > OpCodeHashMap;
+typedef std::unordered_map< OUString, OUString > ExternalHashMap;
+
+class FORMULA_DLLPUBLIC FormulaCompiler
+{
+private:
+ FormulaCompiler(const FormulaCompiler&) = delete;
+ FormulaCompiler& operator=(const FormulaCompiler&) = delete;
+public:
+ FormulaCompiler(bool bComputeII = false, bool bMatrixFlag = false);
+ FormulaCompiler(FormulaTokenArray& _rArr, bool bComputeII = false, bool bMatrixFlag = false);
+ virtual ~FormulaCompiler();
+
+ /** Mappings from strings to OpCodes and vice versa. */
+ class FORMULA_DLLPUBLIC OpCodeMap final
+ {
+ OpCodeHashMap maHashMap; /// Hash map of symbols, OUString -> OpCode
+ std::unique_ptr<OUString[]> mpTable; /// Array of symbols, OpCode -> OUString, offset==OpCode
+ ExternalHashMap maExternalHashMap; /// Hash map of ocExternal, Filter String -> AddIn String
+ ExternalHashMap maReverseExternalHashMap; /// Hash map of ocExternal, AddIn String -> Filter String
+ FormulaGrammar::Grammar meGrammar; /// Grammar, language and reference convention
+ sal_uInt16 mnSymbols; /// Count of OpCode symbols
+ bool mbCore : 1; /// If mapping was setup by core, not filters
+ bool mbEnglish : 1; /// If English symbols and external names
+ bool mbEnglishLocale : 1; /// If English locale for numbers
+
+ OpCodeMap( const OpCodeMap& ) = delete;
+ OpCodeMap& operator=( const OpCodeMap& ) = delete;
+
+ public:
+
+ OpCodeMap(sal_uInt16 nSymbols, bool bCore, FormulaGrammar::Grammar eGrammar ) :
+ maHashMap(nSymbols),
+ mpTable( new OUString[ nSymbols ]),
+ meGrammar( eGrammar),
+ mnSymbols( nSymbols),
+ mbCore( bCore),
+ mbEnglish ( FormulaGrammar::isEnglish(eGrammar) ),
+ mbEnglishLocale ( mbEnglish )
+ {
+ }
+
+ /** Copy mappings from r into this map, effectively replacing this map.
+
+ Override known legacy bad function names with
+ correct ones if the conditions can be derived from the
+ current maps.
+ */
+ void copyFrom( const OpCodeMap& r );
+
+ /// Get the symbol String -> OpCode hash map for finds.
+ const OpCodeHashMap& getHashMap() const { return maHashMap; }
+
+ /// Get the symbol String -> AddIn String hash map for finds.
+ const ExternalHashMap& getExternalHashMap() const { return maExternalHashMap; }
+
+ /// Get the AddIn String -> symbol String hash map for finds.
+ const ExternalHashMap& getReverseExternalHashMap() const { return maReverseExternalHashMap; }
+
+ /// Get the symbol string matching an OpCode.
+ const OUString& getSymbol( const OpCode eOp ) const
+ {
+ DBG_ASSERT( sal_uInt16(eOp) < mnSymbols, "OpCodeMap::getSymbol: OpCode out of range");
+ if (sal_uInt16(eOp) < mnSymbols)
+ return mpTable[ eOp ];
+ static OUString s_sEmpty;
+ return s_sEmpty;
+ }
+
+ /// Get the first character of the symbol string matching an OpCode.
+ sal_Unicode getSymbolChar( const OpCode eOp ) const { return getSymbol(eOp)[0]; };
+
+ /// Get the grammar.
+ FormulaGrammar::Grammar getGrammar() const { return meGrammar; }
+
+ /// Get the symbol count.
+ sal_uInt16 getSymbolCount() const { return mnSymbols; }
+
+ /** Are these English symbols, as opposed to native language (which may
+ be English as well)? */
+ bool isEnglish() const { return mbEnglish; }
+
+ /** Are inline numbers parsed/formatted in en-US locale, as opposed
+ to default locale? */
+ bool isEnglishLocale() const { return mbEnglishLocale; }
+
+ /// Is it an ODF 1.1 compatibility mapping?
+ bool isPODF() const { return FormulaGrammar::isPODF( meGrammar); }
+
+ /* TODO: add isAPI() once a FormulaLanguage was added. */
+
+ /// Is it an ODFF / ODF 1.2 mapping?
+ bool isODFF() const { return FormulaGrammar::isODFF( meGrammar); }
+
+ /// Is it an OOXML mapping?
+ bool isOOXML() const { return FormulaGrammar::isOOXML( meGrammar); }
+
+ /// Does it have external symbol/name mappings?
+ bool hasExternals() const { return !maExternalHashMap.empty(); }
+
+ /// Put entry of symbol String and OpCode pair.
+ void putOpCode( const OUString & rStr, const OpCode eOp, const CharClass* pCharClass );
+
+ /// Put entry of symbol String and AddIn international String pair.
+ void putExternal( const OUString & rSymbol, const OUString & rAddIn );
+
+ /** Put entry of symbol String and AddIn international String pair,
+ not warning just info as used for AddIn collection and setting up
+ alias names. */
+ void putExternalSoftly( const OUString & rSymbol, const OUString & rAddIn );
+
+ /// Core implementation of XFormulaOpCodeMapper::getMappings()
+ css::uno::Sequence< css::sheet::FormulaToken >
+ createSequenceOfFormulaTokens(const FormulaCompiler& _rCompiler,
+ const css::uno::Sequence< OUString >& rNames ) const;
+
+ /// Core implementation of XFormulaOpCodeMapper::getAvailableMappings()
+ css::uno::Sequence< css::sheet::FormulaOpCodeMapEntry >
+ createSequenceOfAvailableMappings( const FormulaCompiler& _rCompiler,const sal_Int32 nGroup ) const;
+
+ /** The value used in createSequenceOfAvailableMappings() and thus in
+ XFormulaOpCodeMapper::getMappings() for an unknown symbol. */
+ static sal_Int32 getOpCodeUnknown() { return -1; }
+
+ private:
+
+ /** Conditionally put a mapping in copyFrom() context.
+
+ Does NOT check eOp range!
+ */
+ void putCopyOpCode( const OUString& rSymbol, OpCode eOp );
+ };
+
+public:
+ typedef std::shared_ptr< const OpCodeMap > OpCodeMapPtr;
+ typedef std::shared_ptr< OpCodeMap > NonConstOpCodeMapPtr;
+
+protected:
+ /** Get finalized OpCodeMap for formula language.
+
+ Creates/returns a singleton instance of an OpCodeMap that contains
+ external AddIn mappings if the derived class supports them. Do not call
+ at this base class as it results in a permanent mapping without AddIns
+ even for derived classes (unless it is for the implementation of the
+ temporary GetOpCodeMap()).
+
+ @param nLanguage
+ One of css::sheet::FormulaLanguage constants.
+ @return Map for nLanguage. If nLanguage is unknown, a NULL map is returned.
+ */
+ OpCodeMapPtr GetFinalOpCodeMap( const sal_Int32 nLanguage ) const;
+
+public:
+ /** Get OpCodeMap for formula language.
+
+ Returns either the finalized OpCodeMap (created by GetFinalOpCodeMap()
+ of a derived class) for nLanguage if there is such, or if not then a
+ temporary map of which its singleton is reset immediately and the
+ temporary will get destroyed by the caller's scope. A temporary map
+ created at this base class does *not* contain AddIn mappings.
+
+ @param nLanguage
+ One of css::sheet::FormulaLanguage constants.
+ @return Map for nLanguage. If nLanguage is unknown, a NULL map is returned.
+ */
+ OpCodeMapPtr GetOpCodeMap( const sal_Int32 nLanguage ) const;
+
+ /** Destroy the singleton OpCodeMap for formula language.
+
+ This unconditionally destroys the underlying singleton instance of the
+ map to be reinitialized again later on the next GetOpCodeMap() call.
+ Use if the base class FormulaCompiler::GetOpCodeMap() was called and
+ created the map (i.e. HasOpCodeMap() before returned false) and later a
+ derived class like ScCompiler shall initialize it including AddIns.
+
+ @param nLanguage
+ One of css::sheet::FormulaLanguage constants.
+ */
+ void DestroyOpCodeMap( const sal_Int32 nLanguage );
+
+ /** Whether the singleton OpCodeMap for formula language exists already.
+
+ @param nLanguage
+ One of css::sheet::FormulaLanguage constants.
+ */
+ bool HasOpCodeMap( const sal_Int32 nLanguage ) const;
+
+ /** Create an internal symbol map from API mapping.
+ @param bEnglish
+ Use English number parser / formatter instead of native.
+ */
+ static OpCodeMapPtr CreateOpCodeMap(
+ const css::uno::Sequence< const css::sheet::FormulaOpCodeMapEntry > & rMapping,
+ bool bEnglish );
+
+ /** Get current OpCodeMap in effect. */
+ const OpCodeMapPtr& GetCurrentOpCodeMap() const { return mxSymbols; }
+
+ /** Get OpCode for English symbol.
+ Used in XFunctionAccess to create token array.
+ @param rName
+ Symbol to lookup. MUST be upper case.
+ */
+ OpCode GetEnglishOpCode( const OUString& rName ) const;
+
+ FormulaError GetErrorConstant( const OUString& rName ) const;
+ void AppendErrorConstant( OUStringBuffer& rBuffer, FormulaError nError ) const;
+
+ void EnableJumpCommandReorder( bool bEnable );
+ void EnableStopOnError( bool bEnable );
+
+ static bool IsOpCodeVolatile( OpCode eOp );
+ static bool IsOpCodeJumpCommand( OpCode eOp );
+
+ static bool DeQuote( OUString& rStr );
+
+
+ static const OUString& GetNativeSymbol( OpCode eOp );
+ static sal_Unicode GetNativeSymbolChar( OpCode eOp );
+ static bool IsMatrixFunction(OpCode _eOpCode); // if a function _always_ returns a Matrix
+
+ SvNumFormatType GetNumFormatType() const { return nNumFmt; }
+ bool CompileTokenArray();
+
+ void CreateStringFromTokenArray( OUString& rFormula );
+ void CreateStringFromTokenArray( OUStringBuffer& rBuffer );
+ const FormulaToken* CreateStringFromToken( OUString& rFormula, const FormulaToken* pToken );
+ const FormulaToken* CreateStringFromToken( OUStringBuffer& rBuffer, const FormulaToken* pToken,
+ bool bAllowArrAdvance = false );
+
+ void AppendBoolean( OUStringBuffer& rBuffer, bool bVal ) const;
+ void AppendDouble( OUStringBuffer& rBuffer, double fVal ) const;
+ static void AppendString( OUStringBuffer& rBuffer, const OUString & rStr );
+
+ /** Set symbol map corresponding to one of predefined formula::FormulaGrammar::Grammar,
+ including an address reference convention. */
+ FormulaGrammar::Grammar GetGrammar() const { return meGrammar; }
+
+ /** Whether current symbol set and grammar need transformation of Table
+ structured references to A1 style references when writing / exporting
+ (creating strings).
+ */
+ bool NeedsTableRefTransformation() const;
+
+ /** If a parameter nParam (0-based) is to be forced to array for OpCode
+ eOp, i.e. classified as ParamClass::ForceArray or
+ ParamClass::ReferenceOrForceArray type. */
+ virtual formula::ParamClass GetForceArrayParameter( const FormulaToken* pToken, sal_uInt16 nParam ) const;
+
+ static void UpdateSeparatorsNative( const OUString& rSep, const OUString& rArrayColSep, const OUString& rArrayRowSep );
+ static void ResetNativeSymbols();
+ static void SetNativeSymbols( const OpCodeMapPtr& xMap );
+
+ /** Sets the implicit intersection compute flag */
+ void SetComputeIIFlag(bool bSet) { mbComputeII = bSet; }
+
+ /** Sets the matrix flag for the formula*/
+ void SetMatrixFlag(bool bSet) { mbMatrixFlag = bSet; }
+
+ /** Separators mapped when loading opcodes from the resource, values other
+ than RESOURCE_BASE may override the resource strings. Used by OpCodeList
+ implementation via loadSymbols().
+ */
+ enum class SeparatorType
+ {
+ RESOURCE_BASE,
+ SEMICOLON_BASE
+ };
+
+protected:
+ virtual OUString FindAddInFunction( const OUString& rUpperName, bool bLocalFirst ) const;
+ virtual void fillFromAddInCollectionUpperName( const NonConstOpCodeMapPtr& xMap ) const;
+ virtual void fillFromAddInMap( const NonConstOpCodeMapPtr& xMap, FormulaGrammar::Grammar _eGrammar ) const;
+ virtual void fillFromAddInCollectionEnglishName( const NonConstOpCodeMapPtr& xMap ) const;
+ virtual void fillAddInToken(::std::vector< css::sheet::FormulaOpCodeMapEntry >& _rVec, bool _bIsEnglish) const;
+
+ virtual void SetError(FormulaError nError);
+ virtual FormulaTokenRef ExtendRangeReference( FormulaToken & rTok1, FormulaToken & rTok2 );
+ virtual bool HandleExternalReference(const FormulaToken& _aToken);
+ virtual bool HandleRange();
+ virtual bool HandleColRowName();
+ virtual bool HandleDbData();
+ virtual bool HandleTableRef();
+
+ virtual void CreateStringFromExternal( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const;
+ virtual void CreateStringFromSingleRef( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const;
+ virtual void CreateStringFromDoubleRef( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const;
+ virtual void CreateStringFromMatrix( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const;
+ virtual void CreateStringFromIndex( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const;
+ virtual void LocalizeString( OUString& rName ) const; // modify rName - input: exact name
+
+ bool GetToken();
+ OpCode NextToken();
+ void PutCode( FormulaTokenRef& );
+ void Factor();
+ void RangeLine();
+ void UnionLine();
+ void IntersectionLine();
+ void UnaryLine();
+ void PostOpLine();
+ void PowLine();
+ void MulDivLine();
+ void AddSubLine();
+ void ConcatLine();
+ void CompareLine();
+ OpCode Expression();
+ void PopTokenArray();
+ void PushTokenArray( FormulaTokenArray*, bool );
+
+ bool MergeRangeReference( FormulaToken * * const pCode1, FormulaToken * const * const pCode2 );
+
+ // Returns whether the opcode has implicit intersection ranges as parameters.
+ // Called for (most) opcodes to possibly handle implicit intersection for the parameters.
+ virtual void HandleIIOpCode(FormulaToken* /*token*/,
+ FormulaToken*** /*pppToken*/, sal_uInt8 /*nNumParams*/) {}
+
+ // Called from CompileTokenArray() after RPN code generation is done.
+ virtual void PostProcessCode() {}
+
+ virtual void AnnotateOperands() {}
+
+ OUString aCorrectedFormula; // autocorrected Formula
+ OUString aCorrectedSymbol; // autocorrected Symbol
+
+ OpCodeMapPtr mxSymbols; // which symbols are used
+
+ FormulaTokenRef mpToken; // current token
+ FormulaTokenRef pCurrentFactorToken; // current factor token (of Factor() method)
+ sal_uInt16 nCurrentFactorParam; // current factor token's parameter, 1-based
+ FormulaTokenArray* pArr;
+ FormulaTokenArrayPlainIterator maArrIterator;
+ FormulaTokenRef mpLastToken; // last token
+
+ FormulaToken** pCode;
+ FormulaArrayStack* pStack;
+
+ OpCode eLastOp;
+ short nRecursion; // GetToken() recursions
+ SvNumFormatType nNumFmt; // set during CompileTokenArray()
+ sal_uInt16 pc; // program counter
+
+ FormulaGrammar::Grammar meGrammar; // The grammar used, language plus convention.
+
+ bool bAutoCorrect; // whether to apply AutoCorrection
+ bool bCorrected; // AutoCorrection was applied
+ bool glSubTotal; // if code contains one or more subtotal functions
+ bool needsRPNTokenCheck; // whether to make FormulaTokenArray check all tokens at the end
+
+ bool mbJumpCommandReorder; /// Whether or not to reorder RPN for jump commands.
+ bool mbStopOnError; /// Whether to stop compilation on first encountered error.
+
+ bool mbComputeII; // whether to attempt computing implicit intersection ranges while building the RPN array.
+ bool mbMatrixFlag; // whether the formula is a matrix formula (needed for II computation)
+
+public:
+ enum InitSymbols
+ {
+ ASK = 0,
+ INIT,
+ DESTROY
+ };
+
+private:
+ bool InitSymbolsNative( InitSymbols ) const; /// only SymbolsNative, on first document creation
+ bool InitSymbolsEnglish( InitSymbols ) const; /// only SymbolsEnglish, maybe later
+ bool InitSymbolsPODF( InitSymbols ) const; /// only SymbolsPODF, on demand
+ bool InitSymbolsAPI( InitSymbols ) const; /// only SymbolsAPI, on demand
+ bool InitSymbolsODFF( InitSymbols ) const; /// only SymbolsODFF, on demand
+ bool InitSymbolsEnglishXL( InitSymbols ) const; /// only SymbolsEnglishXL, on demand
+ bool InitSymbolsOOXML( InitSymbols ) const; /// only SymbolsOOXML, on demand
+
+ void loadSymbols(const std::pair<const char*, int>* pSymbols, FormulaGrammar::Grammar eGrammar, NonConstOpCodeMapPtr& rxMap,
+ SeparatorType eSepType = SeparatorType::SEMICOLON_BASE) const;
+
+ /** Check pCurrentFactorToken for nParam's (0-based) ForceArray types and
+ set ForceArray at rCurr if so. Set nParam+1 as 1-based
+ nCurrentFactorParam for subsequent ForceArrayOperator() calls.
+ */
+ void CheckSetForceArrayParameter( FormulaTokenRef const & rCurr, sal_uInt8 nParam );
+
+ void ForceArrayOperator( FormulaTokenRef const & rCurr );
+
+ class CurrentFactor
+ {
+ FormulaTokenRef pPrevFac;
+ sal_uInt16 nPrevParam;
+ FormulaCompiler* pCompiler;
+ CurrentFactor( const CurrentFactor& ) = delete;
+ CurrentFactor& operator=( const CurrentFactor& ) = delete;
+ public:
+ explicit CurrentFactor( FormulaCompiler* pComp )
+ : pPrevFac( pComp->pCurrentFactorToken )
+ , nPrevParam( pComp->nCurrentFactorParam )
+ , pCompiler( pComp )
+ {}
+ ~CurrentFactor()
+ {
+ pCompiler->pCurrentFactorToken = pPrevFac;
+ pCompiler->nCurrentFactorParam = nPrevParam;
+ }
+ // yes, this operator= may modify the RValue
+ void operator=( FormulaTokenRef const & r )
+ {
+ pCompiler->ForceArrayOperator( r );
+ pCompiler->pCurrentFactorToken = r;
+ pCompiler->nCurrentFactorParam = 0;
+ }
+ void operator=( FormulaToken* p )
+ {
+ FormulaTokenRef xTemp( p );
+ *this = xTemp;
+ }
+ operator FormulaTokenRef&()
+ { return pCompiler->pCurrentFactorToken; }
+ FormulaToken* operator->()
+ { return pCompiler->pCurrentFactorToken.operator->(); }
+ operator FormulaToken*()
+ { return operator->(); }
+ };
+
+
+ mutable NonConstOpCodeMapPtr mxSymbolsODFF; // ODFF symbols
+ mutable NonConstOpCodeMapPtr mxSymbolsPODF; // ODF 1.1 symbols
+ mutable NonConstOpCodeMapPtr mxSymbolsAPI; // XFunctionAccess API symbols
+ mutable NonConstOpCodeMapPtr mxSymbolsNative; // native symbols
+ mutable NonConstOpCodeMapPtr mxSymbolsEnglish; // English symbols
+ mutable NonConstOpCodeMapPtr mxSymbolsEnglishXL; // English Excel symbols (for VBA formula parsing)
+ mutable NonConstOpCodeMapPtr mxSymbolsOOXML; // Excel OOXML symbols
+
+ static FormulaTokenArray smDummyTokenArray;
+};
+
+} // formula
+
+
+#endif // INCLUDED_FORMULA_FORMULACOMPILER_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/FormulaOpCodeMapperObj.hxx b/include/formula/FormulaOpCodeMapperObj.hxx
new file mode 100644
index 0000000000..7e5928a1b3
--- /dev/null
+++ b/include/formula/FormulaOpCodeMapperObj.hxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_FORMULAOPCODEMAPPEROBJ_HXX
+#define INCLUDED_FORMULA_FORMULAOPCODEMAPPEROBJ_HXX
+
+#include <memory>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/sheet/XFormulaOpCodeMapper.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <formula/formuladllapi.h>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+namespace com::sun::star {
+ namespace sheet { struct FormulaOpCodeMapEntry; }
+ namespace sheet { struct FormulaToken; }
+ namespace uno { class XComponentContext; }
+ namespace uno { class XInterface; }
+}
+
+namespace formula
+{
+
+class FormulaCompiler;
+
+class FORMULA_DLLPUBLIC FormulaOpCodeMapperObj : public cppu::WeakImplHelper<
+ css::sheet::XFormulaOpCodeMapper,
+ css::lang::XServiceInfo >
+{
+ ::std::unique_ptr<FormulaCompiler> m_pCompiler;
+
+public:
+ FormulaOpCodeMapperObj(::std::unique_ptr<FormulaCompiler> && _pCompiler);
+ virtual ~FormulaOpCodeMapperObj() override;
+
+private:
+ // XFormulaOpCodeMapper
+ // Attributes
+ virtual ::sal_Int32 SAL_CALL getOpCodeExternal() override;
+ virtual ::sal_Int32 SAL_CALL getOpCodeUnknown() override;
+ // Methods
+ virtual css::uno::Sequence< css::sheet::FormulaToken > SAL_CALL getMappings(
+ const css::uno::Sequence< OUString >& rNames,
+ sal_Int32 nLanguage ) override;
+ virtual css::uno::Sequence< css::sheet::FormulaOpCodeMapEntry > SAL_CALL getAvailableMappings(
+ sal_Int32 nLanguage, sal_Int32 nGroups ) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+};
+
+} // formula
+
+
+#endif // INCLUDED_FORMULA_FORMULAOPCODEMAPPEROBJ_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/IControlReferenceHandler.hxx b/include/formula/IControlReferenceHandler.hxx
new file mode 100644
index 0000000000..e1096c47ae
--- /dev/null
+++ b/include/formula/IControlReferenceHandler.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_FORMULA_ICONTROLREFERENCEHANDLER_HXX
+#define INCLUDED_FORMULA_ICONTROLREFERENCEHANDLER_HXX
+
+#include <formula/formuladllapi.h>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+namespace formula
+{
+ class RefEdit;
+ class RefButton;
+ class FORMULA_DLLPUBLIC SAL_NO_VTABLE IControlReferenceHandler
+ {
+ public:
+ virtual void ShowReference(const OUString& _sRef) = 0;
+ virtual void HideReference( bool bDoneRefMode = true ) = 0;
+ virtual void ReleaseFocus( RefEdit* pEdit ) = 0;
+ virtual void ToggleCollapsed( RefEdit* pEdit, RefButton* pButton ) = 0;
+
+ protected:
+ ~IControlReferenceHandler() {}
+ };
+} // formula
+#endif // INCLUDED_FORMULA_ICONTROLREFERENCEHANDLER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/IFunctionDescription.hxx b/include/formula/IFunctionDescription.hxx
new file mode 100644
index 0000000000..216389451f
--- /dev/null
+++ b/include/formula/IFunctionDescription.hxx
@@ -0,0 +1,160 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_IFUNCTIONDESCRIPTION_HXX
+#define INCLUDED_FORMULA_IFUNCTIONDESCRIPTION_HXX
+
+#include <memory>
+#include <vector>
+
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+namespace com::sun::star {
+ namespace sheet { struct FormulaToken; }
+ namespace sheet { class XFormulaOpCodeMapper; }
+ namespace sheet { class XFormulaParser; }
+}
+
+namespace com::sun::star::uno { template <class E> class Sequence; }
+
+namespace formula
+{
+ class IFunctionCategory;
+ class IFunctionDescription;
+ class FormEditData;
+ class FormulaTokenArray;
+ class FormulaCompiler;
+
+ class SAL_NO_VTABLE IFunctionManager
+ {
+ public:
+ enum EToken
+ {
+ eOk,
+ eClose,
+ eSep,
+ eArrayOpen,
+ eArrayClose
+ };
+ virtual sal_uInt32 getCount() const = 0;
+ virtual const IFunctionCategory* getCategory(sal_uInt32 nPos) const = 0;
+ virtual void fillLastRecentlyUsedFunctions(::std::vector< const IFunctionDescription*>& _rLastRUFunctions) const = 0;
+
+ virtual sal_Unicode getSingleToken(const EToken _eToken) const = 0;
+
+ protected:
+ ~IFunctionManager() {}
+ };
+
+ class SAL_NO_VTABLE IFunctionCategory
+ {
+ public:
+ virtual sal_uInt32 getCount() const = 0;
+ virtual const IFunctionDescription* getFunction(sal_uInt32 _nPos) const = 0;
+ virtual sal_uInt32 getNumber() const = 0;
+ virtual OUString getName() const = 0;
+
+ protected:
+ ~IFunctionCategory() {}
+ };
+
+ class SAL_NO_VTABLE IFunctionDescription
+ {
+ public:
+ virtual OUString getFunctionName() const = 0;
+ virtual const IFunctionCategory* getCategory() const = 0;
+ virtual OUString getDescription() const = 0;
+ // GetSuppressedArgCount
+ virtual sal_Int32 getSuppressedArgumentCount() const = 0;
+ // GetFormulaString
+ virtual OUString getFormula(const ::std::vector< OUString >& _aArguments) const = 0;
+ // GetVisibleArgMapping
+ virtual void fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const = 0;
+ virtual void initArgumentInfo() const = 0;
+ virtual OUString getSignature() const = 0;
+ virtual OUString getHelpId() const = 0;
+ virtual bool isHidden() const = 0;
+
+ // parameter
+ virtual sal_uInt32 getParameterCount() const = 0;
+ virtual sal_uInt32 getVarArgsStart() const = 0;
+ virtual sal_uInt32 getVarArgsLimit() const = 0;
+ virtual OUString getParameterName(sal_uInt32 _nPos) const = 0;
+ virtual OUString getParameterDescription(sal_uInt32 _nPos) const = 0;
+ virtual bool isParameterOptional(sal_uInt32 _nPos) const = 0;
+
+ protected:
+ ~IFunctionDescription() {}
+ };
+
+ class SAL_NO_VTABLE IFormulaEditorHelper
+ {
+ public:
+ virtual void notifyChange() = 0;
+ virtual void fill() = 0;
+
+ virtual OUString getCurrentFormula() const = 0;
+ virtual void setCurrentFormula(const OUString& _sReplacement) = 0;
+
+ virtual void getSelection(sal_Int32& _nStart, sal_Int32& _nEnd) const = 0;
+ virtual void setSelection(sal_Int32 _nStart, sal_Int32 _nEnd) = 0;
+
+ virtual FormEditData* getFormEditData() const = 0;
+ virtual bool calculateValue(const OUString& _sExpression, OUString& _rResult, bool bMatrixFormula) = 0;
+
+ /** Obtain a resident FormulaCompiler instance, created without
+ FormulaTokenArray and reused but being application specific derived.
+ */
+ virtual std::shared_ptr<FormulaCompiler> getCompiler() const = 0;
+
+ /** Create an application specific FormulaCompiler instance with
+ FormulaTokenArray. The FormulaTokenArray had to be created using
+ convertToTokenArray().
+ */
+ virtual std::unique_ptr<FormulaCompiler> createCompiler( FormulaTokenArray& rArray ) const = 0;
+
+ virtual void switchBack() = 0;
+
+ virtual void clear() = 0;
+ virtual void deleteFormData() = 0;
+
+ virtual IFunctionManager* getFunctionManager() = 0;
+ virtual ::std::unique_ptr<FormulaTokenArray> convertToTokenArray(const css::uno::Sequence< css::sheet::FormulaToken >& _aTokenList) = 0;
+
+ virtual css::uno::Reference< css::sheet::XFormulaParser> getFormulaParser() const = 0;
+ virtual css::uno::Reference< css::sheet::XFormulaOpCodeMapper> getFormulaOpCodeMapper() const = 0;
+ virtual css::table::CellAddress getReferencePosition() const = 0;
+
+ virtual void setDispatcherLock( bool bLock ) = 0;
+ virtual void dispatch(bool _bOK, bool _bMatrixChecked) = 0;
+ virtual void doClose(bool _bOk) = 0;
+ virtual void insertEntryToLRUList(const IFunctionDescription* pDesc) = 0;
+ virtual void showReference(const OUString& _sFormula) = 0;
+
+ protected:
+ ~IFormulaEditorHelper() {}
+ };
+
+}
+#endif // INCLUDED_FORMULA_IFUNCTIONDESCRIPTION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/compiler.hxx b/include/formula/compiler.hxx
new file mode 100644
index 0000000000..fcf7326d3e
--- /dev/null
+++ b/include/formula/compiler.hxx
@@ -0,0 +1,531 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef FORMULA_COMPILER_HXX
+#define FORMULA_COMPILER_HXX
+
+/* Central definition of OpCodes for spreadsheet functions */
+
+/*** Special commands ***/
+#define SC_OPCODE_PUSH 0 /* internal commands */
+#define SC_OPCODE_CALL 1
+#define SC_OPCODE_STOP 2
+#define SC_OPCODE_EXTERNAL 3
+#define SC_OPCODE_NAME 4
+#define SC_OPCODE_EXTERNAL_REF 5
+#define SC_OPCODE_IF 6 /* jump commands */
+#define SC_OPCODE_IF_ERROR 7
+#define SC_OPCODE_IF_NA 8
+#define SC_OPCODE_CHOOSE 9
+#define SC_OPCODE_OPEN 10 /* parentheses and separators */
+#define SC_OPCODE_CLOSE 11
+#define SC_OPCODE_SEP 12
+#define SC_OPCODE_MISSING 13 /* special OpCodes */
+#define SC_OPCODE_BAD 14
+#define SC_OPCODE_STRINGXML 15
+#define SC_OPCODE_SPACES 16
+#define SC_OPCODE_WHITESPACE 17
+#define SC_OPCODE_MAT_REF 18
+#define SC_OPCODE_DB_AREA 19 /* additional access operators */
+#define SC_OPCODE_TABLE_REF 20
+#define SC_OPCODE_MACRO 21
+#define SC_OPCODE_COL_ROW_NAME 22
+#define SC_OPCODE_COL_ROW_NAME_AUTO 23
+#define SC_OPCODE_PERCENT_SIGN 24 /* operator _follows_ value */
+#define SC_OPCODE_ARRAY_OPEN 25
+#define SC_OPCODE_ARRAY_CLOSE 26
+#define SC_OPCODE_ARRAY_ROW_SEP 27
+#define SC_OPCODE_ARRAY_COL_SEP 28 /* some convs use sep != col_sep */
+#define SC_OPCODE_TABLE_REF_OPEN 29
+#define SC_OPCODE_TABLE_REF_CLOSE 30
+#define SC_OPCODE_TABLE_REF_ITEM_ALL 31
+#define SC_OPCODE_TABLE_REF_ITEM_HEADERS 32
+#define SC_OPCODE_TABLE_REF_ITEM_DATA 33
+#define SC_OPCODE_TABLE_REF_ITEM_TOTALS 34
+#define SC_OPCODE_TABLE_REF_ITEM_THIS_ROW 35
+#define SC_OPCODE_STOP_DIV 36
+#define SC_OPCODE_SKIP 37 /* used to skip raw tokens during string compilation */
+
+/*** error constants #... ***/
+#define SC_OPCODE_START_ERRORS 40
+#define SC_OPCODE_ERROR_NULL 40
+#define SC_OPCODE_ERROR_DIVZERO 41
+#define SC_OPCODE_ERROR_VALUE 42
+#define SC_OPCODE_ERROR_REF 43
+#define SC_OPCODE_ERROR_NAME 44
+#define SC_OPCODE_ERROR_NUM 45
+#define SC_OPCODE_ERROR_NA 46
+#define SC_OPCODE_STOP_ERRORS 47
+
+/*** Binary operators ***/
+#define SC_OPCODE_START_BIN_OP 50
+#define SC_OPCODE_ADD 50
+#define SC_OPCODE_SUB 51
+#define SC_OPCODE_MUL 52
+#define SC_OPCODE_DIV 53
+#define SC_OPCODE_AMPERSAND 54
+#define SC_OPCODE_POW 55
+#define SC_OPCODE_EQUAL 56
+#define SC_OPCODE_NOT_EQUAL 57
+#define SC_OPCODE_LESS 58
+#define SC_OPCODE_GREATER 59
+#define SC_OPCODE_LESS_EQUAL 60
+#define SC_OPCODE_GREATER_EQUAL 61
+#define SC_OPCODE_AND 62
+#define SC_OPCODE_OR 63
+#define SC_OPCODE_INTERSECT 64
+#define SC_OPCODE_UNION 65
+#define SC_OPCODE_RANGE 66
+#define SC_OPCODE_STOP_BIN_OP 67
+
+/* NOTE: binary and unary operators must be in sequence for compiler! */
+
+/*** Unary operators ***/
+#define SC_OPCODE_START_UN_OP 70
+#define SC_OPCODE_NEG_SUB 70
+#define SC_OPCODE_STOP_UN_OP 71
+
+#define SC_OPCODE_START_FUNCTION 75
+
+/*** Functions without parameters ***/
+#define SC_OPCODE_START_NO_PAR 75
+#define SC_OPCODE_PI 75
+#define SC_OPCODE_RANDOM 76
+#define SC_OPCODE_TRUE 77
+#define SC_OPCODE_FALSE 78
+#define SC_OPCODE_GET_ACT_DATE 79
+#define SC_OPCODE_GET_ACT_TIME 80
+#define SC_OPCODE_NO_VALUE 81
+#define SC_OPCODE_CURRENT 82
+#define SC_OPCODE_RANDOM_NV 83
+#define SC_OPCODE_STOP_NO_PAR 84
+
+/*** Functions with one parameter ***/
+#define SC_OPCODE_START_1_PAR 90
+#define SC_OPCODE_DEG 90 /* trigonometric */
+#define SC_OPCODE_RAD 91
+#define SC_OPCODE_SIN 92
+#define SC_OPCODE_COS 93
+#define SC_OPCODE_TAN 94
+#define SC_OPCODE_COT 95
+#define SC_OPCODE_ARC_SIN 96
+#define SC_OPCODE_ARC_COS 97
+#define SC_OPCODE_ARC_TAN 98
+#define SC_OPCODE_ARC_COT 99
+#define SC_OPCODE_SIN_HYP 100
+#define SC_OPCODE_COS_HYP 101
+#define SC_OPCODE_TAN_HYP 102
+#define SC_OPCODE_COT_HYP 103
+#define SC_OPCODE_ARC_SIN_HYP 104 /* transcendent */
+#define SC_OPCODE_ARC_COS_HYP 105
+#define SC_OPCODE_ARC_TAN_HYP 106
+#define SC_OPCODE_ARC_COT_HYP 107
+#define SC_OPCODE_COSECANT 108
+#define SC_OPCODE_SECANT 109
+#define SC_OPCODE_COSECANT_HYP 110
+#define SC_OPCODE_SECANT_HYP 111
+#define SC_OPCODE_EXP 112
+#define SC_OPCODE_LN 113
+#define SC_OPCODE_SQRT 114
+#define SC_OPCODE_FACT 115
+#define SC_OPCODE_GET_YEAR 116 /* date and time */
+#define SC_OPCODE_GET_MONTH 117
+#define SC_OPCODE_GET_DAY 118
+#define SC_OPCODE_GET_HOUR 119
+#define SC_OPCODE_GET_MIN 120
+#define SC_OPCODE_GET_SEC 121
+#define SC_OPCODE_PLUS_MINUS 122 /* miscellaneous */
+#define SC_OPCODE_ABS 123
+#define SC_OPCODE_INT 124
+#define SC_OPCODE_PHI 125
+#define SC_OPCODE_GAUSS 126
+#define SC_OPCODE_IS_EMPTY 127 /* obtain type */
+#define SC_OPCODE_IS_STRING 128
+#define SC_OPCODE_IS_NON_STRING 129
+#define SC_OPCODE_IS_LOGICAL 130
+#define SC_OPCODE_TYPE 131
+#define SC_OPCODE_IS_REF 132
+#define SC_OPCODE_IS_VALUE 133
+#define SC_OPCODE_IS_FORMULA 134
+#define SC_OPCODE_IS_NV 135
+#define SC_OPCODE_IS_ERR 136
+#define SC_OPCODE_IS_ERROR 137
+#define SC_OPCODE_IS_EVEN 138
+#define SC_OPCODE_IS_ODD 139
+#define SC_OPCODE_N 140
+#define SC_OPCODE_GET_DATE_VALUE 141 /* string functions */
+#define SC_OPCODE_GET_TIME_VALUE 142
+#define SC_OPCODE_CODE 143
+#define SC_OPCODE_TRIM 144
+#define SC_OPCODE_UPPER 145
+#define SC_OPCODE_PROPER 146
+#define SC_OPCODE_LOWER 147
+#define SC_OPCODE_LEN 148
+#define SC_OPCODE_T 149 /* miscellaneous, part 21 */
+#define SC_OPCODE_VALUE 150
+#define SC_OPCODE_CLEAN 151
+#define SC_OPCODE_CHAR 152
+#define SC_OPCODE_LOG10 153
+#define SC_OPCODE_EVEN 154
+#define SC_OPCODE_ODD 155
+#define SC_OPCODE_STD_NORM_DIST 156
+#define SC_OPCODE_FISHER 157
+#define SC_OPCODE_FISHER_INV 158
+#define SC_OPCODE_S_NORM_INV 159
+#define SC_OPCODE_GAMMA_LN 160
+#define SC_OPCODE_ERROR_TYPE 161
+#define SC_OPCODE_FORMULA 163
+#define SC_OPCODE_ARABIC 164
+#define SC_OPCODE_INFO 165
+#define SC_OPCODE_BAHTTEXT 166
+#define SC_OPCODE_JIS 167
+#define SC_OPCODE_ASC 168
+#define SC_OPCODE_UNICODE 169
+#define SC_OPCODE_UNICHAR 170
+#define SC_OPCODE_GAMMA 171
+#define SC_OPCODE_GAMMA_LN_MS 172
+#define SC_OPCODE_ERF_MS 173
+#define SC_OPCODE_ERFC_MS 174
+#define SC_OPCODE_ERROR_TYPE_ODF 175
+#define SC_OPCODE_ENCODEURL 176
+#define SC_OPCODE_ISOWEEKNUM 177
+#define SC_OPCODE_NOT 178
+#define SC_OPCODE_NEG 179
+#define SC_OPCODE_STOP_1_PAR 180
+
+/*** Functions with more than one parameters ***/
+#define SC_OPCODE_START_2_PAR 201
+#define SC_OPCODE_ARC_TAN_2 201
+#define SC_OPCODE_CEIL 202
+#define SC_OPCODE_FLOOR 203
+#define SC_OPCODE_ROUND 204
+#define SC_OPCODE_ROUND_UP 205
+#define SC_OPCODE_ROUND_DOWN 206
+#define SC_OPCODE_TRUNC 207
+#define SC_OPCODE_LOG 208
+#define SC_OPCODE_POWER 209
+#define SC_OPCODE_GCD 210
+#define SC_OPCODE_LCM 211
+#define SC_OPCODE_MOD 212
+#define SC_OPCODE_SUM_PRODUCT 213
+#define SC_OPCODE_SUM_SQ 214
+#define SC_OPCODE_SUM_X2MY2 215
+#define SC_OPCODE_SUM_X2DY2 216
+#define SC_OPCODE_SUM_XMY2 217
+#define SC_OPCODE_GET_DATE 218
+#define SC_OPCODE_GET_TIME 219
+#define SC_OPCODE_GET_DIFF_DATE 220
+#define SC_OPCODE_GET_DIFF_DATE_360 221
+#define SC_OPCODE_MIN 222
+#define SC_OPCODE_MAX 223
+#define SC_OPCODE_SUM 224
+#define SC_OPCODE_PRODUCT 225
+#define SC_OPCODE_AVERAGE 226
+#define SC_OPCODE_COUNT 227
+#define SC_OPCODE_COUNT_2 228
+#define SC_OPCODE_NPV 229
+#define SC_OPCODE_IRR 230
+#define SC_OPCODE_VAR 231
+#define SC_OPCODE_VAR_P 232
+#define SC_OPCODE_ST_DEV 233
+#define SC_OPCODE_ST_DEV_P 234
+#define SC_OPCODE_B 235
+#define SC_OPCODE_NORM_DIST 236
+#define SC_OPCODE_EXP_DIST 237
+#define SC_OPCODE_BINOM_DIST 238
+#define SC_OPCODE_POISSON_DIST 239
+#define SC_OPCODE_COMBIN 240
+#define SC_OPCODE_COMBIN_A 241
+#define SC_OPCODE_PERMUT 242
+#define SC_OPCODE_PERMUTATION_A 243
+#define SC_OPCODE_PV 244
+#define SC_OPCODE_SYD 245
+#define SC_OPCODE_DDB 246
+#define SC_OPCODE_DB 247
+#define SC_OPCODE_VBD 248
+#define SC_OPCODE_PDURATION 249
+#define SC_OPCODE_SLN 250
+#define SC_OPCODE_PMT 251
+#define SC_OPCODE_COLUMNS 252
+#define SC_OPCODE_ROWS 253
+#define SC_OPCODE_COLUMN 254
+#define SC_OPCODE_ROW 255
+#define SC_OPCODE_RRI 256
+#define SC_OPCODE_FV 257
+#define SC_OPCODE_NPER 258
+#define SC_OPCODE_RATE 259
+#define SC_OPCODE_IPMT 260
+#define SC_OPCODE_PPMT 261
+#define SC_OPCODE_CUM_IPMT 262
+#define SC_OPCODE_CUM_PRINC 263
+#define SC_OPCODE_EFFECT 264
+#define SC_OPCODE_NOMINAL 265
+#define SC_OPCODE_SUB_TOTAL 266
+#define SC_OPCODE_DB_SUM 267 /* database functions */
+#define SC_OPCODE_DB_COUNT 268
+#define SC_OPCODE_DB_COUNT_2 269
+#define SC_OPCODE_DB_AVERAGE 270
+#define SC_OPCODE_DB_GET 271
+#define SC_OPCODE_DB_MAX 272
+#define SC_OPCODE_DB_MIN 273
+#define SC_OPCODE_DB_PRODUCT 274
+#define SC_OPCODE_DB_STD_DEV 275
+#define SC_OPCODE_DB_STD_DEV_P 276
+#define SC_OPCODE_DB_VAR 277
+#define SC_OPCODE_DB_VAR_P 278
+#define SC_OPCODE_INDIRECT 279 /* management functions */
+#define SC_OPCODE_ADDRESS 280
+#define SC_OPCODE_MATCH 281
+#define SC_OPCODE_COUNT_EMPTY_CELLS 282
+#define SC_OPCODE_COUNT_IF 283
+#define SC_OPCODE_SUM_IF 284
+#define SC_OPCODE_LOOKUP 285
+#define SC_OPCODE_V_LOOKUP 286
+#define SC_OPCODE_H_LOOKUP 287
+#define SC_OPCODE_MULTI_AREA 288
+#define SC_OPCODE_OFFSET 289
+#define SC_OPCODE_INDEX 290
+#define SC_OPCODE_AREAS 291
+#define SC_OPCODE_CURRENCY 292 /* string functions */
+#define SC_OPCODE_REPLACE 293
+#define SC_OPCODE_FIXED 294
+#define SC_OPCODE_FIND 295
+#define SC_OPCODE_EXACT 296
+#define SC_OPCODE_LEFT 297
+#define SC_OPCODE_RIGHT 298
+#define SC_OPCODE_SEARCH 299
+#define SC_OPCODE_MID 300
+#define SC_OPCODE_TEXT 301
+#define SC_OPCODE_SUBSTITUTE 302
+#define SC_OPCODE_REPT 303
+#define SC_OPCODE_CONCAT 304
+#define SC_OPCODE_MAT_VALUE 305 /* matrix functions */
+#define SC_OPCODE_MAT_DET 306
+#define SC_OPCODE_MAT_INV 307
+#define SC_OPCODE_MAT_MULT 308
+#define SC_OPCODE_MAT_TRANS 309
+#define SC_OPCODE_MATRIX_UNIT 310
+#define SC_OPCODE_BACK_SOLVER 311 /* BackSolver */
+#define SC_OPCODE_HYP_GEOM_DIST 312 /* statistical functions */
+#define SC_OPCODE_LOG_NORM_DIST 313
+#define SC_OPCODE_T_DIST 314
+#define SC_OPCODE_F_DIST 315
+#define SC_OPCODE_CHI_DIST 316
+#define SC_OPCODE_WEIBULL 317
+#define SC_OPCODE_NEG_BINOM_VERT 318
+#define SC_OPCODE_CRIT_BINOM 319
+#define SC_OPCODE_KURT 320
+#define SC_OPCODE_HAR_MEAN 321
+#define SC_OPCODE_GEO_MEAN 322
+#define SC_OPCODE_STANDARD 323
+#define SC_OPCODE_AVE_DEV 324
+#define SC_OPCODE_SKEW 325
+#define SC_OPCODE_DEV_SQ 326
+#define SC_OPCODE_MEDIAN 327
+#define SC_OPCODE_MODAL_VALUE 328
+#define SC_OPCODE_Z_TEST 329
+#define SC_OPCODE_T_TEST 330
+#define SC_OPCODE_RANK 331
+#define SC_OPCODE_PERCENTILE 332
+#define SC_OPCODE_PERCENT_RANK 333
+#define SC_OPCODE_LARGE 334
+#define SC_OPCODE_SMALL 335
+#define SC_OPCODE_FREQUENCY 336
+#define SC_OPCODE_QUARTILE 337
+#define SC_OPCODE_NORM_INV 338
+#define SC_OPCODE_CONFIDENCE 339
+#define SC_OPCODE_F_TEST 340
+#define SC_OPCODE_TRIM_MEAN 341
+#define SC_OPCODE_PROB 342
+#define SC_OPCODE_CORREL 343
+#define SC_OPCODE_COVAR 344
+#define SC_OPCODE_PEARSON 345
+#define SC_OPCODE_RSQ 346
+#define SC_OPCODE_STEYX 347
+#define SC_OPCODE_SLOPE 348
+#define SC_OPCODE_INTERCEPT 349
+#define SC_OPCODE_TREND 350
+#define SC_OPCODE_GROWTH 351
+#define SC_OPCODE_LINEST 352
+#define SC_OPCODE_LOGEST 353
+#define SC_OPCODE_FORECAST 354
+#define SC_OPCODE_CHI_INV 355
+#define SC_OPCODE_GAMMA_DIST 356
+#define SC_OPCODE_GAMMA_INV 357
+#define SC_OPCODE_T_INV 358
+#define SC_OPCODE_F_INV 359
+#define SC_OPCODE_CHI_TEST 360
+#define SC_OPCODE_LOG_INV 361
+#define SC_OPCODE_TABLE_OP 362
+#define SC_OPCODE_BETA_DIST 363
+#define SC_OPCODE_BETA_INV 364
+#define SC_OPCODE_WEEK 365 /* miscellaneous */
+#define SC_OPCODE_GET_DAY_OF_WEEK 366
+#define SC_OPCODE_NO_NAME 367
+#define SC_OPCODE_STYLE 368
+#define SC_OPCODE_DDE 369
+#define SC_OPCODE_BASE 370
+#define SC_OPCODE_SHEET 371
+#define SC_OPCODE_SHEETS 372
+#define SC_OPCODE_MIN_A 373
+#define SC_OPCODE_MAX_A 374
+#define SC_OPCODE_AVERAGE_A 375
+#define SC_OPCODE_ST_DEV_A 376
+#define SC_OPCODE_ST_DEV_P_A 377
+#define SC_OPCODE_VAR_A 378
+#define SC_OPCODE_VAR_P_A 379
+#define SC_OPCODE_EASTERSUNDAY 380
+#define SC_OPCODE_DECIMAL 381
+#define SC_OPCODE_CONVERT_OOO 382
+#define SC_OPCODE_ROMAN 383
+#define SC_OPCODE_MIRR 384
+#define SC_OPCODE_CELL 385
+#define SC_OPCODE_ISPMT 386
+#define SC_OPCODE_HYPERLINK 387
+// free: 388
+// free: 389
+#define SC_OPCODE_GET_PIVOT_DATA 390
+#define SC_OPCODE_EUROCONVERT 391
+#define SC_OPCODE_NUMBERVALUE 392
+#define SC_OPCODE_CHISQ_DIST 393
+#define SC_OPCODE_CHISQ_INV 394
+#define SC_OPCODE_BITAND 395
+#define SC_OPCODE_BITOR 396
+#define SC_OPCODE_BITXOR 397
+#define SC_OPCODE_BITRSHIFT 398
+#define SC_OPCODE_BITLSHIFT 399
+#define SC_OPCODE_GET_DATEDIF 400
+#define SC_OPCODE_XOR 401
+#define SC_OPCODE_AVERAGE_IF 402
+#define SC_OPCODE_SUM_IFS 403
+#define SC_OPCODE_AVERAGE_IFS 404
+#define SC_OPCODE_COUNT_IFS 405
+#define SC_OPCODE_SKEWP 406
+#define SC_OPCODE_LENB 407
+#define SC_OPCODE_RIGHTB 408
+#define SC_OPCODE_LEFTB 409
+#define SC_OPCODE_MIDB 410
+#define SC_OPCODE_FILTERXML 411
+#define SC_OPCODE_WEBSERVICE 412
+#define SC_OPCODE_COVARIANCE_S 413
+#define SC_OPCODE_COVARIANCE_P 414
+#define SC_OPCODE_ST_DEV_P_MS 415
+#define SC_OPCODE_ST_DEV_S 416
+#define SC_OPCODE_VAR_P_MS 417
+#define SC_OPCODE_VAR_S 418
+#define SC_OPCODE_BETA_DIST_MS 419
+#define SC_OPCODE_BETA_INV_MS 420
+#define SC_OPCODE_BINOM_DIST_MS 421
+#define SC_OPCODE_BINOM_INV 422
+#define SC_OPCODE_CHI_DIST_MS 423
+#define SC_OPCODE_CHI_INV_MS 424
+#define SC_OPCODE_CHI_TEST_MS 425
+#define SC_OPCODE_CHISQ_DIST_MS 426
+#define SC_OPCODE_CHISQ_INV_MS 427
+#define SC_OPCODE_CONFIDENCE_N 428
+#define SC_OPCODE_CONFIDENCE_T 429
+#define SC_OPCODE_F_DIST_LT 430
+#define SC_OPCODE_F_DIST_RT 431
+#define SC_OPCODE_F_INV_LT 432
+#define SC_OPCODE_F_INV_RT 433
+#define SC_OPCODE_F_TEST_MS 434
+#define SC_OPCODE_EXP_DIST_MS 435
+#define SC_OPCODE_HYP_GEOM_DIST_MS 436
+#define SC_OPCODE_POISSON_DIST_MS 437
+#define SC_OPCODE_WEIBULL_MS 438
+#define SC_OPCODE_GAMMA_DIST_MS 439
+#define SC_OPCODE_GAMMA_INV_MS 440
+#define SC_OPCODE_LOG_NORM_DIST_MS 441
+#define SC_OPCODE_LOG_INV_MS 442
+#define SC_OPCODE_NORM_DIST_MS 443
+#define SC_OPCODE_NORM_INV_MS 444
+#define SC_OPCODE_STD_NORM_DIST_MS 445
+#define SC_OPCODE_S_NORM_INV_MS 446
+#define SC_OPCODE_T_DIST_MS 447
+#define SC_OPCODE_T_DIST_RT 448
+#define SC_OPCODE_T_DIST_2T 449
+#define SC_OPCODE_T_INV_2T 450
+#define SC_OPCODE_T_INV_MS 451
+#define SC_OPCODE_T_TEST_MS 452
+#define SC_OPCODE_PERCENTILE_INC 453
+#define SC_OPCODE_PERCENT_RANK_INC 454
+#define SC_OPCODE_QUARTILE_INC 455
+#define SC_OPCODE_RANK_EQ 456
+#define SC_OPCODE_PERCENTILE_EXC 457
+#define SC_OPCODE_PERCENT_RANK_EXC 458
+#define SC_OPCODE_QUARTILE_EXC 459
+#define SC_OPCODE_RANK_AVG 460
+#define SC_OPCODE_MODAL_VALUE_MS 461
+#define SC_OPCODE_MODAL_VALUE_MULTI 462
+#define SC_OPCODE_NEG_BINOM_DIST_MS 463
+#define SC_OPCODE_Z_TEST_MS 464
+#define SC_OPCODE_CEIL_MS 465
+#define SC_OPCODE_CEIL_ISO 466
+#define SC_OPCODE_FLOOR_MS 467
+#define SC_OPCODE_NETWORKDAYS_MS 468
+#define SC_OPCODE_WORKDAY_MS 469
+#define SC_OPCODE_AGGREGATE 470
+#define SC_OPCODE_COLOR 471
+#define SC_OPCODE_CEIL_MATH 472
+#define SC_OPCODE_CEIL_PRECISE 473
+#define SC_OPCODE_NETWORKDAYS 474
+#define SC_OPCODE_FLOOR_MATH 475
+#define SC_OPCODE_FLOOR_PRECISE 476
+#define SC_OPCODE_RAWSUBTRACT 477
+#define SC_OPCODE_WEEKNUM_OOO 478
+#define SC_OPCODE_FORECAST_ETS_ADD 479
+#define SC_OPCODE_FORECAST_ETS_SEA 480
+#define SC_OPCODE_FORECAST_ETS_MUL 481
+#define SC_OPCODE_FORECAST_ETS_PIA 482
+#define SC_OPCODE_FORECAST_ETS_PIM 483
+#define SC_OPCODE_FORECAST_ETS_STA 484
+#define SC_OPCODE_FORECAST_ETS_STM 485
+#define SC_OPCODE_FORECAST_LIN 486
+#define SC_OPCODE_CONCAT_MS 487
+#define SC_OPCODE_TEXTJOIN_MS 488
+#define SC_OPCODE_IFS_MS 489
+#define SC_OPCODE_SWITCH_MS 490
+#define SC_OPCODE_MINIFS_MS 491
+#define SC_OPCODE_MAXIFS_MS 492
+#define SC_OPCODE_ROUNDSIG 493
+#define SC_OPCODE_REPLACEB 494
+#define SC_OPCODE_FINDB 495
+#define SC_OPCODE_SEARCHB 496
+#define SC_OPCODE_REGEX 497
+#define SC_OPCODE_FOURIER 498
+#define SC_OPCODE_RANDBETWEEN_NV 499
+#define SC_OPCODE_STOP_2_PAR 500 /* last function with two or more parameters' OpCode + 1 */
+
+#define SC_OPCODE_STOP_FUNCTION SC_OPCODE_STOP_2_PAR /* last function's OpCode + 1 */
+#define SC_OPCODE_LAST_OPCODE_ID (SC_OPCODE_STOP_FUNCTION - 1) /* last OpCode */
+
+/*** Internal ***/
+#define SC_OPCODE_INTERNAL_BEGIN 9999
+#define SC_OPCODE_TTT 9999
+#define SC_OPCODE_DEBUG_VAR 10000
+#define SC_OPCODE_INTERNAL_END 10000
+
+/*** from here on ExtraData contained ***/
+#define SC_OPCODE_DATA_TOKEN_1 10001
+
+#define SC_OPCODE_NONE 0xFFFF
+
+#endif /* FORMULA_COMPILER_HRC */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/errorcodes.hxx b/include/formula/errorcodes.hxx
new file mode 100644
index 0000000000..3e929bff49
--- /dev/null
+++ b/include/formula/errorcodes.hxx
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_ERRORCODES_HXX
+#define INCLUDED_FORMULA_ERRORCODES_HXX
+
+#include <sal/mathconf.h>
+#include <sal/types.h>
+
+#include <cmath>
+#include <limits>
+
+// Store as 16-bits, since error values are stored in tokens and formula results,
+// and that can matter
+enum class FormulaError : sal_uInt16
+{
+ NONE = 0,
+
+ IllegalChar = 501,
+ IllegalArgument = 502,
+ IllegalFPOperation = 503, // #NUM!
+ IllegalParameter = 504,
+ Pair = 507,
+ PairExpected = 508,
+ OperatorExpected = 509,
+ VariableExpected = 510,
+ ParameterExpected = 511,
+ CodeOverflow = 512,
+ StringOverflow = 513,
+ StackOverflow = 514,
+ UnknownState = 515,
+ UnknownVariable = 516,
+ UnknownOpCode = 517,
+ UnknownStackVariable = 518,
+ NoValue = 519, // #VALUE!
+ UnknownToken = 520,
+ NoCode = 521, // #NULL!
+ CircularReference = 522,
+ NoConvergence = 523,
+ NoRef = 524, // #REF!
+ NoName = 525, // #NAME?
+// ScInterpreter internal: no numeric value but numeric queried. If this is
+// set as mnStringNoValueError no error is generated but 0 returned.
+ CellNoValue = 529,
+// Interpreter: needed AddIn not found
+ NoAddin = 530,
+// Interpreter: needed Macro not found
+ NoMacro = 531,
+// Interpreter: Division by zero
+ DivisionByZero = 532, // #DIV/0!
+// Compiler: a non-simple (str,err,val) value was put in an array
+ NestedArray = 533,
+// ScInterpreter internal: no numeric value but numeric queried. If this is
+// temporarily (!) set as mnStringNoValueError, the error is generated and can
+// be used to distinguish that condition from all other (inherited) errors. Do
+// not use for anything else! Never push or inherit the error otherwise!
+ NotNumericString = 534,
+// ScInterpreter internal: jump matrix already has a result at this position,
+// do not overwrite in case of empty code path.
+ JumpMatHasResult = 535,
+// ScInterpreter internal: (matrix) element is not a numeric value, i.e.
+// string or empty, to be distinguished from the general FormulaError::NoValue NAN and not
+// to be used as result.
+ ElementNaN = 536,
+// ScInterpreter/ScFormulaCell internal: keep dirty, retry interpreting next
+// round.
+ RetryCircular = 537,
+// If matrix could not be allocated.
+ MatrixSize = 538,
+// Bad inline array content, non-value/non-string.
+ BadArrayContent = 539,
+// Interpreter: signal result not available because updating links is not
+// allowed (yet) and tell to try hybrid string as result.
+ LinkFormulaNeedingCheck = 540,
+
+// Interpreter: NA() not available condition, not a real error
+ NotAvailable = 0x7fff
+};
+
+/** Unconditionally construct a double value of NAN where the lower bits
+ represent an interpreter error code. */
+inline double CreateDoubleError( FormulaError nErr )
+{
+ sal_math_Double smVal;
+ smVal.value = std::numeric_limits<double>::quiet_NaN();
+ smVal.nan_parts.fraction_lo = static_cast<unsigned>(nErr);
+ return smVal.value;
+}
+
+/** Recreate the error code of a coded double error, if any. */
+inline FormulaError GetDoubleErrorValue( double fVal )
+{
+ if ( std::isfinite( fVal ) )
+ return FormulaError::NONE;
+ if ( std::isinf( fVal ) )
+ return FormulaError::IllegalFPOperation; // normal INF
+ sal_uInt32 nErr = reinterpret_cast< sal_math_Double * >( &fVal)->nan_parts.fraction_lo;
+ if ( nErr & 0xffff0000 )
+ return FormulaError::NoValue; // just a normal NAN
+ if (!nErr)
+ // Another NAN, e.g. -nan(0x8000000000000) from calculating with -inf
+ return FormulaError::IllegalFPOperation;
+ // Any other error known to us as error code.
+ return static_cast<FormulaError>(nErr & 0x0000ffff);
+}
+
+/** Error values that are accepted as detailed "#ERRxxx!" constants.
+
+ Used in FormulaCompiler::GetErrorConstant() to prevent users from inventing
+ arbitrary values that already have or later might get a significant meaning.
+ */
+inline bool isPublishedFormulaError( FormulaError nErr )
+{
+ // Every value has to be handled explicitly, do not add a default case to
+ // let the compiler complain if a value is missing.
+ switch (nErr)
+ {
+ case FormulaError::NONE:
+ return false;
+
+ case FormulaError::IllegalChar:
+ case FormulaError::IllegalArgument:
+ case FormulaError::IllegalFPOperation:
+ case FormulaError::IllegalParameter:
+ case FormulaError::Pair:
+ case FormulaError::PairExpected:
+ case FormulaError::OperatorExpected:
+ case FormulaError::VariableExpected:
+ case FormulaError::ParameterExpected:
+ case FormulaError::CodeOverflow:
+ case FormulaError::StringOverflow:
+ case FormulaError::StackOverflow:
+ case FormulaError::UnknownState:
+ case FormulaError::UnknownVariable:
+ case FormulaError::UnknownOpCode:
+ case FormulaError::UnknownStackVariable:
+ case FormulaError::NoValue:
+ case FormulaError::UnknownToken:
+ case FormulaError::NoCode:
+ case FormulaError::CircularReference:
+ case FormulaError::NoConvergence:
+ case FormulaError::NoRef:
+ case FormulaError::NoName:
+ return true;
+
+ case FormulaError::CellNoValue:
+ return false;
+
+ case FormulaError::NoAddin:
+ case FormulaError::NoMacro:
+ case FormulaError::DivisionByZero:
+ case FormulaError::NestedArray:
+ case FormulaError::BadArrayContent:
+ return true;
+
+ case FormulaError::NotNumericString:
+ case FormulaError::JumpMatHasResult:
+ case FormulaError::ElementNaN:
+ case FormulaError::RetryCircular:
+ return false;
+
+ case FormulaError::MatrixSize:
+ case FormulaError::LinkFormulaNeedingCheck:
+ return true;
+
+ case FormulaError::NotAvailable:
+ return false;
+ }
+ return false;
+}
+
+#endif // INCLUDED_FORMULA_ERRORCODES_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/formdata.hxx b/include/formula/formdata.hxx
new file mode 100644
index 0000000000..1df42c2e95
--- /dev/null
+++ b/include/formula/formdata.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_FORMDATA_HXX
+#define INCLUDED_FORMULA_FORMDATA_HXX
+
+#include <formula/formuladllapi.h>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+#include <tools/gen.hxx>
+
+namespace formula
+{
+enum class FormulaDlgMode;
+
+class FORMULA_DLLPUBLIC FormEditData
+{
+public:
+ FormEditData();
+ virtual ~FormEditData();
+
+ virtual void SaveValues();
+
+ FormulaDlgMode GetMode() const { return nMode; }
+ sal_Int32 GetFStart() const { return nFStart; }
+ sal_uInt16 GetOffset() const { return nOffset; }
+ const OUString& GetUndoStr() const { return aUndoStr; }
+ bool GetMatrixFlag()const{ return bMatrix;}
+ const Selection& GetSelection()const { return aSelection;}
+
+ void SetMode( FormulaDlgMode nNew ) { nMode = nNew; }
+ void SetFStart( sal_Int32 nNew ) { nFStart = nNew; }
+ void SetOffset( sal_uInt16 nNew ) { nOffset = nNew; }
+ void SetUndoStr( const OUString& rNew ) { aUndoStr = rNew; }
+ void SetMatrixFlag(bool bNew) { bMatrix=bNew;}
+ void SetSelection(const Selection& aSel) { aSelection=aSel;}
+protected:
+ void Reset();
+ FormEditData( const FormEditData& );
+ FormEditData& operator=( const FormEditData& r );
+
+private:
+ FormulaDlgMode nMode;
+ sal_Int32 nFStart;
+ sal_uInt16 nOffset;
+ OUString aUndoStr;
+ bool bMatrix;
+ Selection aSelection;
+};
+
+
+} // formula
+#endif // INCLUDED_FORMULA_FORMDATA_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/formula.hxx b/include/formula/formula.hxx
new file mode 100644
index 0000000000..aed0e1b0d7
--- /dev/null
+++ b/include/formula/formula.hxx
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_FORMULA_HXX
+#define INCLUDED_FORMULA_FORMULA_HXX
+
+#include <memory>
+#include <utility>
+
+#include <formula/formuladllapi.h>
+#include <formula/IFunctionDescription.hxx>
+#include <o3tl/deleter.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+#include <sfx2/basedlgs.hxx>
+#include <tools/gen.hxx>
+
+class NotifyEvent;
+class SfxBindings;
+class SfxChildWindow;
+
+namespace formula
+{
+
+#define STRUCT_END 1
+#define STRUCT_FOLDER 2
+#define STRUCT_ERROR 3
+
+enum class FormulaDlgMode { Formula, Edit };
+
+
+class FormulaDlg_Impl;
+class IControlReferenceHandler;
+class FormulaHelper;
+class RefEdit;
+class RefButton;
+class FormEditData;
+
+class FORMULA_DLLPUBLIC FormulaModalDialog
+ : public weld::GenericDialogController, public formula::IFormulaEditorHelper
+{
+ friend class FormulaDlg_Impl;
+public:
+ FormulaModalDialog(weld::Window* pParent, IFunctionManager const * _pFunctionMgr,
+ IControlReferenceHandler* _pDlg);
+ virtual ~FormulaModalDialog() override;
+
+private:
+ std::unique_ptr<FormulaDlg_Impl, o3tl::default_delete<FormulaDlg_Impl>> m_pImpl;
+
+protected:
+
+ ::std::pair<RefButton*,RefEdit*> RefInputStartBefore( RefEdit* pEdit, RefButton* pButton );
+ void RefInputStartAfter();
+ void RefInputDoneAfter();
+
+ void SetMeText(const OUString& _sText);
+ void Update();
+ void CheckMatrix(OUString& aFormula /*IN/OUT*/);
+ void Update(const OUString& _sExp);
+
+ void StoreFormEditData(FormEditData* pData);
+};
+
+class FORMULA_DLLPUBLIC FormulaDlg:
+ public SfxModelessDialogController, public IFormulaEditorHelper
+{
+ friend class FormulaDlg_Impl;
+public:
+ FormulaDlg(SfxBindings* pB, SfxChildWindow* pCW,
+ weld::Window* pParent,
+ IFunctionManager const * _pFunctionMgr,
+ IControlReferenceHandler* _pDlg);
+ virtual ~FormulaDlg() override;
+private:
+ std::unique_ptr<FormulaDlg_Impl, o3tl::default_delete<FormulaDlg_Impl>> m_pImpl;
+
+protected:
+ void disableOk();
+
+protected:
+
+ ::std::pair<RefButton*,RefEdit*> RefInputStartBefore( RefEdit* pEdit, RefButton* pButton );
+ void RefInputStartAfter();
+ void RefInputDoneAfter( bool bForced );
+
+ void SetMeText(const OUString& _sText);
+ FormulaDlgMode SetMeText(const OUString& _sText, sal_Int32 PrivStart, sal_Int32 PrivEnd, bool bMatrix, bool _bSelect, bool _bUpdate);
+ void Update();
+ bool CheckMatrix(OUString& aFormula /*IN/OUT*/);
+ OUString GetMeText() const;
+ void Update(const OUString& _sExp);
+ void DoEnter();
+ const IFunctionDescription* getCurrentFunctionDescription() const;
+ bool UpdateParaWin(Selection& _rSelection);
+ void UpdateParaWin(const Selection& _rSelection, const OUString& _sRefStr);
+ RefEdit* GetActiveEdit();
+ void SetEdSelection();
+
+ void StoreFormEditData(FormEditData* pData);
+
+ const FormulaHelper& GetFormulaHelper() const;
+};
+
+} // formula
+
+#endif // INCLUDED_FORMULA_FORMULA_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/formuladllapi.h b/include/formula/formuladllapi.h
new file mode 100644
index 0000000000..ae408fd42f
--- /dev/null
+++ b/include/formula/formuladllapi.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_FORMULADLLAPI_H
+#define INCLUDED_FORMULA_FORMULADLLAPI_H
+
+#include <sal/types.h>
+
+#if defined(FORMULA_DLLIMPLEMENTATION)
+#define FORMULA_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define FORMULA_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+#define FORMULA_DLLPRIVATE SAL_DLLPRIVATE
+
+#endif // INCLUDED_FORMULA_FORMULADLLAPI_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/formulahelper.hxx b/include/formula/formulahelper.hxx
new file mode 100644
index 0000000000..b298dfa36b
--- /dev/null
+++ b/include/formula/formulahelper.hxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_FORMULAHELPER_HXX
+#define INCLUDED_FORMULA_FORMULAHELPER_HXX
+
+#include <vector>
+
+#include <formula/formuladllapi.h>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+#include <unotools/syslocale.hxx>
+
+class CharClass;
+
+namespace formula
+{
+ class IFunctionDescription;
+ class IFunctionManager;
+
+ class FORMULA_DLLPUBLIC FormulaHelper
+ {
+ SvtSysLocale m_aSysLocale;
+ const CharClass& m_rCharClass;
+ const IFunctionManager* m_pFunctionManager;
+ const sal_Unicode open;
+ const sal_Unicode close;
+ const sal_Unicode sep;
+ const sal_Unicode arrayOpen;
+ const sal_Unicode arrayClose;
+ public:
+ FormulaHelper(const IFunctionManager* _pFunctionManager);
+
+ const CharClass& GetCharClass() const { return m_rCharClass; }
+
+ sal_Int32 GetCategoryCount() const;
+
+ bool GetNextFunc( const OUString& rFormula,
+ bool bBack,
+ sal_Int32& rFStart, // input and output
+ sal_Int32* pFEnd = nullptr,
+ const IFunctionDescription** ppFDesc = nullptr,
+ ::std::vector< OUString>* pArgs = nullptr ) const;
+
+ sal_Int32 GetFunctionStart( const OUString& rFormula, sal_Int32 nStart,
+ bool bBack, OUString* pFuncName = nullptr ) const;
+
+ sal_Int32 GetFunctionEnd ( std::u16string_view rFormula, sal_Int32 nStart ) const;
+
+ sal_Int32 GetArgStart ( std::u16string_view rFormula, sal_Int32 nStart,
+ sal_uInt16 nArg ) const;
+
+ void GetArgStrings ( ::std::vector< OUString >& _rArgs,
+ std::u16string_view rFormula,
+ sal_Int32 nFuncPos,
+ sal_uInt16 nArgs ) const;
+
+ void FillArgStrings ( std::u16string_view rFormula,
+ sal_Int32 nFuncPos,
+ sal_uInt16 nArgs,
+ ::std::vector< OUString >& _rArgs ) const;
+ };
+
+} // formula
+
+
+#endif // INCLUDED_FORMULA_FORMULAHELPER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/funcutl.hxx b/include/formula/funcutl.hxx
new file mode 100644
index 0000000000..a41f9c09a6
--- /dev/null
+++ b/include/formula/funcutl.hxx
@@ -0,0 +1,182 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_FUNCUTL_HXX
+#define INCLUDED_FORMULA_FUNCUTL_HXX
+
+#include <formula/formuladllapi.h>
+#include <rtl/ustring.hxx>
+#include <tools/link.hxx>
+#include <vcl/idle.hxx>
+#include <vcl/weld.hxx>
+
+class KeyEvent;
+struct ImplSVEvent;
+
+namespace formula {
+
+class IControlReferenceHandler;
+
+class FORMULA_DLLPUBLIC RefEdit
+{
+protected:
+ std::unique_ptr<weld::Entry> xEntry;
+
+private:
+ Idle aIdle;
+ IControlReferenceHandler* pAnyRefDlg; // parent dialog
+ weld::Label* pLabelWidget;
+ ImplSVEvent* mpFocusInEvent;
+ ImplSVEvent* mpFocusOutEvent;
+
+ Link<RefEdit&,void> maGetFocusHdl;
+ Link<RefEdit&,void> maLoseFocusHdl;
+ Link<RefEdit&,void> maModifyHdl;
+ Link<weld::Widget&,bool> maActivateHdl;
+
+ DECL_DLLPRIVATE_LINK( UpdateHdl, Timer*, void );
+
+ DECL_DLLPRIVATE_LINK(KeyInputHdl, const KeyEvent&, bool);
+ DECL_DLLPRIVATE_LINK(GetFocusHdl, weld::Widget&, void);
+ DECL_DLLPRIVATE_LINK(LoseFocusHdl, weld::Widget&, void);
+ DECL_DLLPRIVATE_LINK(AsyncFocusInHdl, void*, void);
+ DECL_DLLPRIVATE_LINK(AsyncFocusOutHdl, void*, void);
+ DECL_DLLPRIVATE_LINK(Modify, weld::Entry&, void);
+
+ void GetFocus();
+ void LoseFocus();
+
+protected:
+ virtual bool KeyInput(const KeyEvent& rKEvt);
+
+public:
+ RefEdit(std::unique_ptr<weld::Entry> xControl);
+ weld::Entry* GetWidget() const { return xEntry.get(); }
+ virtual ~RefEdit();
+
+ void SetRefString( const OUString& rStr );
+
+ /**
+ * Flag reference valid or invalid, which in turn changes the visual
+ * appearance of the control accordingly.
+ */
+ void SetRefValid(bool bValid);
+
+ void SetText(const OUString& rStr);
+ OUString GetText() const
+ {
+ return xEntry->get_text();
+ }
+
+ void StartUpdateData();
+
+ void SetReferences( IControlReferenceHandler* pDlg, weld::Label *pLabelWidget );
+
+ void DoModify()
+ {
+ Modify(*xEntry);
+ }
+
+ void GrabFocus()
+ {
+ xEntry->grab_focus();
+ }
+
+ void SelectAll()
+ {
+ xEntry->select_region(0, -1);
+ }
+
+ void SetSelection(const Selection& rSelection)
+ {
+ xEntry->select_region(rSelection.Min(), rSelection.Max());
+ }
+
+ void SetCursorAtLast()
+ {
+ xEntry->set_position(-1);
+ }
+
+ Selection GetSelection() const
+ {
+ int nStartPos, nEndPos;
+ xEntry->get_selection_bounds(nStartPos, nEndPos);
+ return Selection(nStartPos, nEndPos);
+ }
+
+ weld::Label* GetLabelWidgetForShrinkMode()
+ {
+ return pLabelWidget;
+ }
+
+ void SaveValue()
+ {
+ xEntry->save_value();
+ }
+
+ bool IsValueChangedFromSaved() const
+ {
+ return xEntry->get_value_changed_from_saved();
+ }
+
+ void SetGetFocusHdl(const Link<RefEdit&,void>& rLink) { maGetFocusHdl = rLink; }
+ void SetLoseFocusHdl(const Link<RefEdit&,void>& rLink) { maLoseFocusHdl = rLink; }
+ void SetModifyHdl(const Link<RefEdit&,void>& rLink) { maModifyHdl = rLink; }
+ const Link<RefEdit&,void>& GetModifyHdl() const { return maModifyHdl; }
+ void SetActivateHdl(const Link<weld::Widget&,bool>& rLink) { maActivateHdl = rLink; }
+};
+
+class FORMULA_DLLPUBLIC RefButton
+{
+private:
+ std::unique_ptr<weld::Button> xButton;
+ IControlReferenceHandler* pAnyRefDlg; // parent dialog
+ RefEdit* pRefEdit; // associated Edit-Control
+ Link<RefButton&,void> maGetFocusHdl;
+ Link<RefButton&,void> maLoseFocusHdl;
+ Link<weld::Widget&,bool> maActivateHdl;
+ Link<RefButton&,void> maClickHdl;
+
+ DECL_LINK(Click, weld::Button&, void);
+ DECL_DLLPRIVATE_LINK(KeyInput, const KeyEvent&, bool);
+ DECL_DLLPRIVATE_LINK(GetFocus, weld::Widget&, void);
+ DECL_DLLPRIVATE_LINK(LoseFocus, weld::Widget&, void);
+
+public:
+ RefButton(std::unique_ptr<weld::Button> xControl);
+ weld::Button* GetWidget() const { return xButton.get(); }
+ ~RefButton();
+ void SetReferences(IControlReferenceHandler* pDlg, RefEdit* pEdit);
+ void SetStartImage();
+ void SetEndImage();
+ void DoRef()
+ {
+ Click(*xButton);
+ }
+ void SetGetFocusHdl(const Link<RefButton&,void>& rLink) { maGetFocusHdl = rLink; }
+ void SetLoseFocusHdl(const Link<RefButton&,void>& rLink) { maLoseFocusHdl = rLink; }
+ void SetActivateHdl(const Link<weld::Widget&,bool>& rLink) { maActivateHdl = rLink; }
+ void SetClickHdl(const Link<RefButton&,void>& rLink) { maClickHdl = rLink; }
+};
+
+} // formula
+
+#endif // INCLUDED_FORMULA_FUNCUTL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/funcvarargs.h b/include/formula/funcvarargs.h
new file mode 100644
index 0000000000..7a1f1e4e7f
--- /dev/null
+++ b/include/formula/funcvarargs.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_FORMULA_FUNCVARARGS_H
+#define INCLUDED_FORMULA_FUNCVARARGS_H
+
+/** Used to indicate a variable number of parameters for the Function Wizard.
+
+ VAR_ARGS if variable number of parameters, or VAR_ARGS+number if number of
+ fixed parameters and variable arguments following.
+
+ @see formula::ParaWin
+ @see ScFuncDescCore
+
+ @NOTE: the value can't be easily changed. If changed then
+ reportdesign/source/ui/misc/FunctionHelper.cxx
+ FunctionDescription::getVarArgsStart() has to provide some backward
+ compatibility for implicit API stability.
+ The new VAR_ARGS value must be significantly greater than the old
+ PAIRED_VAR_ARGS (2*VAR_ARGS) value, in fact greater than any used number of
+ fixed parameters followed by optional paired parameters.
+
+ @NOTE: also
+ reportbuilder/java/org/libreoffice/report/pentaho/StarFunctionDescription.java
+ uses a hard coded value in StarFunctionDescription::getArguments() for
+ functionDescription.isInfiniteParameterCount() which though looks like it
+ could be easily adapted.
+ */
+#define VAR_ARGS 255
+
+/** Used to indicate a variable number of paired parameters for the Function Wizard.
+
+ PAIRED_VAR_ARGS if variable number of paired parameters, or
+ PAIRED_VAR_ARGS+number if number of fixed parameters and variable paired
+ arguments following.
+
+ @see VAR_ARGS
+ */
+#define PAIRED_VAR_ARGS (VAR_ARGS + VAR_ARGS)
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/include/formula/grammar.hxx b/include/formula/grammar.hxx
new file mode 100644
index 0000000000..677087d199
--- /dev/null
+++ b/include/formula/grammar.hxx
@@ -0,0 +1,247 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_GRAMMAR_HXX
+#define INCLUDED_FORMULA_GRAMMAR_HXX
+
+#include <com/sun/star/sheet/FormulaLanguage.hpp>
+#include <formula/formuladllapi.h>
+#include <sal/types.h>
+
+namespace formula
+{
+
+/** Grammars digested by ScCompiler.
+ */
+class FORMULA_DLLPUBLIC FormulaGrammar
+{
+public:
+ enum AddressConvention{
+ CONV_UNSPECIFIED = -1, /* useful when we want method to choose, must be first */
+
+ /* elements must be sequential and changes should be reflected in ScCompiler::pCharTables */
+ CONV_OOO = 0, /* 'doc'#sheet.A1:sheet2.B2 */
+ CONV_ODF, /* ['doc'#sheet.A1:sheet2.B2] */
+ CONV_XL_A1, /* [doc]sheet:sheet2!A1:B2 */
+ CONV_XL_R1C1, /* [doc]sheet:sheet2!R1C1:R2C2 */
+ CONV_XL_OOX, /* [#]sheet:sheet2!A1:B2 */
+
+ CONV_LOTUS_A1, /* external? 3d? A1.B2 <placeholder/> */
+
+ CONV_LAST, /* for loops, must always be last */
+
+ // not a real address convention, a special case for INDIRECT function interpretation
+ // only -> try using CONV_OOO, failing that CONV_XL_A1
+ CONV_A1_XL_A1
+ };
+
+ //! CONV_UNSPECIFIED is a negative value!
+ static const int kConventionOffset = - CONV_UNSPECIFIED + 1;
+ // Room for 32k hypothetical languages plus EXTERNAL.
+ static const int kConventionShift = 16;
+ // Room for 256 reference conventions.
+ static const int kEnglishBit = (1 << (kConventionShift + 8));
+ // Mask off all non-language bits.
+ static const int kFlagMask = ~((~unsigned(0)) << kConventionShift);
+
+ /** Values encoding the formula language plus address reference convention
+ plus English parsing/formatting
+ */
+ //! When adding new values adapt isSupported() below as well.
+ enum Grammar
+ {
+ /// Used only in ScCompiler ctor and in some XML import API context.
+ GRAM_UNSPECIFIED = -1,
+ /// ODFF with default ODF A1 bracketed references.
+ GRAM_ODFF = css::sheet::FormulaLanguage::ODFF |
+ ((CONV_ODF +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// ODF 1.1 with default ODF A1 bracketed references.
+ GRAM_PODF = css::sheet::FormulaLanguage::ODF_11 |
+ ((CONV_ODF +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// English with default A1 reference style.
+ GRAM_ENGLISH = css::sheet::FormulaLanguage::ENGLISH |
+ ((CONV_OOO +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// Native with default A1 reference style.
+ GRAM_NATIVE = css::sheet::FormulaLanguage::NATIVE |
+ ((CONV_OOO +
+ kConventionOffset) << kConventionShift),
+ /// ODFF with reference style as set in UI, may be A1 or R1C1.
+ GRAM_ODFF_UI = css::sheet::FormulaLanguage::ODFF |
+ ((CONV_UNSPECIFIED +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// ODFF with A1 reference style, unbracketed.
+ GRAM_ODFF_A1 = css::sheet::FormulaLanguage::ODFF |
+ ((CONV_OOO +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// ODF 1.1 with reference style as set in UI, may be A1 or R1C1.
+ GRAM_PODF_UI = css::sheet::FormulaLanguage::ODF_11 |
+ ((CONV_UNSPECIFIED +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// ODF 1.1 with A1 reference style, unbracketed.
+ GRAM_PODF_A1 = css::sheet::FormulaLanguage::ODF_11 |
+ ((CONV_OOO +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// Native with reference style as set in UI, may be A1 or R1C1.
+ GRAM_NATIVE_UI = css::sheet::FormulaLanguage::NATIVE |
+ ((CONV_UNSPECIFIED +
+ kConventionOffset) << kConventionShift),
+ /// Native with ODF A1 bracketed references. Not very useful but supported.
+ GRAM_NATIVE_ODF = css::sheet::FormulaLanguage::NATIVE |
+ ((CONV_ODF +
+ kConventionOffset) << kConventionShift),
+ /// Native with Excel A1 reference style.
+ GRAM_NATIVE_XL_A1 = css::sheet::FormulaLanguage::NATIVE |
+ ((CONV_XL_A1 +
+ kConventionOffset) << kConventionShift),
+ /// Native with Excel R1C1 reference style.
+ GRAM_NATIVE_XL_R1C1 = css::sheet::FormulaLanguage::NATIVE |
+ ((CONV_XL_R1C1 +
+ kConventionOffset) << kConventionShift),
+ /// English with Excel A1 reference style.
+ GRAM_ENGLISH_XL_A1 = css::sheet::FormulaLanguage::XL_ENGLISH |
+ ((CONV_XL_A1 +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// English with Excel R1C1 reference style.
+ GRAM_ENGLISH_XL_R1C1 = css::sheet::FormulaLanguage::XL_ENGLISH |
+ ((CONV_XL_R1C1 +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// English with Excel OOXML reference style.
+ GRAM_ENGLISH_XL_OOX = css::sheet::FormulaLanguage::XL_ENGLISH |
+ ((CONV_XL_OOX +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// Excel OOXML with Excel OOXML reference style.
+ GRAM_OOXML = css::sheet::FormulaLanguage::OOXML |
+ ((CONV_XL_OOX +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// API English with A1 reference style, unbracketed.
+ GRAM_API = css::sheet::FormulaLanguage::API |
+ ((CONV_OOO +
+ kConventionOffset) << kConventionShift) |
+ kEnglishBit,
+ /// Central definition of the default grammar to be used.
+ GRAM_DEFAULT = GRAM_NATIVE_UI,
+
+ /// Central definition of the default storage grammar to be used.
+ GRAM_STORAGE_DEFAULT = GRAM_ODFF,
+
+ /** OpCodeMap set by external filter and merged with reference
+ convention plus English bit on top. Plain value acts as
+ FormulaLanguage. */
+ GRAM_EXTERNAL = (1 << (kConventionShift - 1))
+ };
+
+ /// If English parsing/formatting is associated with a grammar.
+ static bool isEnglish( const Grammar eGrammar )
+ {
+ return (eGrammar & kEnglishBit) != 0;
+ }
+
+ /** Compatibility helper for old "bCompileEnglish, bCompileXML" API calls
+ to obtain the new grammar. */
+ static Grammar mapAPItoGrammar( const bool bEnglish, const bool bXML );
+
+ static bool isSupported( const Grammar eGrammar );
+
+ static sal_Int32 extractFormulaLanguage( const Grammar eGrammar )
+ {
+ return eGrammar & kFlagMask;
+ }
+
+ static AddressConvention extractRefConvention( const Grammar eGrammar )
+ {
+ return static_cast<AddressConvention>(
+ ((eGrammar & ~kEnglishBit) >> kConventionShift) -
+ kConventionOffset);
+ }
+
+ static Grammar setEnglishBit( const Grammar eGrammar, const bool bEnglish );
+
+ static Grammar mergeToGrammar( const Grammar eGrammar, const AddressConvention eConv );
+
+ /// If grammar is of ODF 1.1
+ static bool isPODF( const Grammar eGrammar )
+ {
+ return extractFormulaLanguage( eGrammar) ==
+ css::sheet::FormulaLanguage::ODF_11;
+ }
+
+ /// If grammar is of ODFF
+ static bool isODFF( const Grammar eGrammar )
+ {
+ return extractFormulaLanguage( eGrammar) ==
+ css::sheet::FormulaLanguage::ODFF;
+ }
+
+ /// If grammar is of OOXML
+ static bool isOOXML( const Grammar eGrammar )
+ {
+ return extractFormulaLanguage( eGrammar) ==
+ css::sheet::FormulaLanguage::OOXML;
+ }
+
+ /** If reference convention is OOXML.
+
+ Note this is not equivalent to isOOXML() as it does not have to be
+ FormulaLanguage::OOXML but can be Grammar::GRAM_EXTERNAL merged with
+ AddressConvention::CONV_XL_OOX, which is used by various parts of OOXML
+ import through the API FormulaParser.
+ */
+ static bool isRefConventionOOXML( const Grammar eGrammar )
+ {
+ return extractRefConvention( eGrammar) ==
+ FormulaGrammar::AddressConvention::CONV_XL_OOX;
+ }
+
+ /// If grammar has an Excel syntax, determined by address convention.
+ static bool isExcelSyntax( const Grammar eGrammar )
+ {
+ AddressConvention eConv = extractRefConvention( eGrammar );
+ switch (eConv)
+ {
+ case FormulaGrammar::AddressConvention::CONV_XL_A1:
+ case FormulaGrammar::AddressConvention::CONV_XL_R1C1:
+ case FormulaGrammar::AddressConvention::CONV_XL_OOX:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+};
+
+} // formula
+
+
+#endif // INCLUDED_FORMULA_GRAMMAR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/opcode.hxx b/include/formula/opcode.hxx
new file mode 100644
index 0000000000..d92ae0b1d4
--- /dev/null
+++ b/include/formula/opcode.hxx
@@ -0,0 +1,995 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_OPCODE_HXX
+#define INCLUDED_FORMULA_OPCODE_HXX
+
+#include <sstream>
+
+#include <formula/compiler.hxx>
+#include <sal/types.h>
+
+enum OpCode : sal_uInt16
+{
+ // Special commands
+ ocPush = SC_OPCODE_PUSH,
+ ocCall = SC_OPCODE_CALL,
+ ocStop = SC_OPCODE_STOP,
+ ocExternal = SC_OPCODE_EXTERNAL,
+ ocName = SC_OPCODE_NAME,
+ // Jump commands
+ ocIf = SC_OPCODE_IF,
+ ocIfError = SC_OPCODE_IF_ERROR,
+ ocIfNA = SC_OPCODE_IF_NA,
+ ocChoose = SC_OPCODE_CHOOSE,
+ // Parentheses and separators
+ ocOpen = SC_OPCODE_OPEN,
+ ocClose = SC_OPCODE_CLOSE,
+ ocTableRefOpen = SC_OPCODE_TABLE_REF_OPEN,
+ ocTableRefClose = SC_OPCODE_TABLE_REF_CLOSE,
+ ocSep = SC_OPCODE_SEP,
+ ocArrayOpen = SC_OPCODE_ARRAY_OPEN,
+ ocArrayClose = SC_OPCODE_ARRAY_CLOSE,
+ ocArrayRowSep = SC_OPCODE_ARRAY_ROW_SEP,
+ ocArrayColSep = SC_OPCODE_ARRAY_COL_SEP,
+ // Special OpCodes
+ ocMissing = SC_OPCODE_MISSING,
+ ocBad = SC_OPCODE_BAD,
+ ocStringXML = SC_OPCODE_STRINGXML,
+ ocSpaces = SC_OPCODE_SPACES,
+ ocWhitespace = SC_OPCODE_WHITESPACE,
+ ocMatRef = SC_OPCODE_MAT_REF,
+ ocTableRefItemAll = SC_OPCODE_TABLE_REF_ITEM_ALL,
+ ocTableRefItemHeaders = SC_OPCODE_TABLE_REF_ITEM_HEADERS,
+ ocTableRefItemData = SC_OPCODE_TABLE_REF_ITEM_DATA,
+ ocTableRefItemTotals = SC_OPCODE_TABLE_REF_ITEM_TOTALS,
+ ocTableRefItemThisRow = SC_OPCODE_TABLE_REF_ITEM_THIS_ROW,
+ ocSkip = SC_OPCODE_SKIP,
+ // Access commands
+ ocDBArea = SC_OPCODE_DB_AREA,
+ ocTableRef = SC_OPCODE_TABLE_REF,
+ ocMacro = SC_OPCODE_MACRO,
+ ocColRowName = SC_OPCODE_COL_ROW_NAME,
+ ocColRowNameAuto = SC_OPCODE_COL_ROW_NAME_AUTO,
+ // Percent operator _follows_ value
+ ocPercentSign = SC_OPCODE_PERCENT_SIGN,
+ // Error constants
+ ocErrNull = SC_OPCODE_ERROR_NULL,
+ ocErrDivZero = SC_OPCODE_ERROR_DIVZERO,
+ ocErrValue = SC_OPCODE_ERROR_VALUE,
+ ocErrRef = SC_OPCODE_ERROR_REF,
+ ocErrName = SC_OPCODE_ERROR_NAME,
+ ocErrNum = SC_OPCODE_ERROR_NUM,
+ ocErrNA = SC_OPCODE_ERROR_NA,
+ // Binary operators
+ ocAdd = SC_OPCODE_ADD,
+ ocSub = SC_OPCODE_SUB,
+ ocMul = SC_OPCODE_MUL,
+ ocDiv = SC_OPCODE_DIV,
+ ocAmpersand = SC_OPCODE_AMPERSAND,
+ ocPow = SC_OPCODE_POW,
+ ocEqual = SC_OPCODE_EQUAL,
+ ocNotEqual = SC_OPCODE_NOT_EQUAL,
+ ocLess = SC_OPCODE_LESS,
+ ocGreater = SC_OPCODE_GREATER,
+ ocLessEqual = SC_OPCODE_LESS_EQUAL,
+ ocGreaterEqual = SC_OPCODE_GREATER_EQUAL,
+ ocAnd = SC_OPCODE_AND,
+ ocOr = SC_OPCODE_OR,
+ ocXor = SC_OPCODE_XOR,
+ ocIntersect = SC_OPCODE_INTERSECT,
+ ocUnion = SC_OPCODE_UNION,
+ ocRange = SC_OPCODE_RANGE,
+ // Unary operators
+ ocNegSub = SC_OPCODE_NEG_SUB,
+ // Functions with no parameters
+ ocPi = SC_OPCODE_PI,
+ ocRandom = SC_OPCODE_RANDOM,
+ ocTrue = SC_OPCODE_TRUE,
+ ocFalse = SC_OPCODE_FALSE,
+ ocGetActDate = SC_OPCODE_GET_ACT_DATE,
+ ocGetActTime = SC_OPCODE_GET_ACT_TIME,
+ ocNotAvail = SC_OPCODE_NO_VALUE,
+ ocCurrent = SC_OPCODE_CURRENT,
+ ocRandomNV = SC_OPCODE_RANDOM_NV,
+ // Functions with one parameter
+ ocNot = SC_OPCODE_NOT,
+ ocNeg = SC_OPCODE_NEG,
+ ocDeg = SC_OPCODE_DEG,
+ ocRad = SC_OPCODE_RAD,
+ ocSin = SC_OPCODE_SIN,
+ ocCos = SC_OPCODE_COS,
+ ocTan = SC_OPCODE_TAN,
+ ocCot = SC_OPCODE_COT,
+ ocArcSin = SC_OPCODE_ARC_SIN,
+ ocArcCos = SC_OPCODE_ARC_COS,
+ ocArcTan = SC_OPCODE_ARC_TAN,
+ ocArcCot = SC_OPCODE_ARC_COT,
+ ocSinHyp = SC_OPCODE_SIN_HYP,
+ ocCosHyp = SC_OPCODE_COS_HYP,
+ ocTanHyp = SC_OPCODE_TAN_HYP,
+ ocCotHyp = SC_OPCODE_COT_HYP,
+ ocArcSinHyp = SC_OPCODE_ARC_SIN_HYP,
+ ocArcCosHyp = SC_OPCODE_ARC_COS_HYP,
+ ocArcTanHyp = SC_OPCODE_ARC_TAN_HYP,
+ ocArcCotHyp = SC_OPCODE_ARC_COT_HYP,
+ ocCosecant = SC_OPCODE_COSECANT,
+ ocSecant = SC_OPCODE_SECANT,
+ ocCosecantHyp = SC_OPCODE_COSECANT_HYP,
+ ocSecantHyp = SC_OPCODE_SECANT_HYP,
+ ocExp = SC_OPCODE_EXP,
+ ocLn = SC_OPCODE_LN,
+ ocSqrt = SC_OPCODE_SQRT,
+ ocFact = SC_OPCODE_FACT,
+ ocGetYear = SC_OPCODE_GET_YEAR,
+ ocGetMonth = SC_OPCODE_GET_MONTH,
+ ocGetDay = SC_OPCODE_GET_DAY,
+ ocGetHour = SC_OPCODE_GET_HOUR,
+ ocGetMin = SC_OPCODE_GET_MIN,
+ ocGetSec = SC_OPCODE_GET_SEC,
+ ocPlusMinus = SC_OPCODE_PLUS_MINUS,
+ ocAbs = SC_OPCODE_ABS,
+ ocInt = SC_OPCODE_INT,
+ ocPhi = SC_OPCODE_PHI,
+ ocGauss = SC_OPCODE_GAUSS,
+ ocIsEmpty = SC_OPCODE_IS_EMPTY,
+ ocIsString = SC_OPCODE_IS_STRING,
+ ocIsNonString = SC_OPCODE_IS_NON_STRING,
+ ocIsLogical = SC_OPCODE_IS_LOGICAL,
+ ocType = SC_OPCODE_TYPE,
+ ocCell = SC_OPCODE_CELL,
+ ocIsRef = SC_OPCODE_IS_REF,
+ ocIsValue = SC_OPCODE_IS_VALUE,
+ ocIsFormula = SC_OPCODE_IS_FORMULA,
+ ocIsNA = SC_OPCODE_IS_NV,
+ ocIsErr = SC_OPCODE_IS_ERR,
+ ocIsError = SC_OPCODE_IS_ERROR,
+ ocIsEven = SC_OPCODE_IS_EVEN,
+ ocIsOdd = SC_OPCODE_IS_ODD,
+ ocN = SC_OPCODE_N,
+ // String functions
+ ocGetDateValue = SC_OPCODE_GET_DATE_VALUE,
+ ocGetTimeValue = SC_OPCODE_GET_TIME_VALUE,
+ ocCode = SC_OPCODE_CODE,
+ ocTrim = SC_OPCODE_TRIM,
+ ocUpper = SC_OPCODE_UPPER,
+ ocProper = SC_OPCODE_PROPER,
+ ocLower = SC_OPCODE_LOWER,
+ ocLen = SC_OPCODE_LEN,
+ ocT = SC_OPCODE_T,
+ ocValue = SC_OPCODE_VALUE,
+ ocClean = SC_OPCODE_CLEAN,
+ ocChar = SC_OPCODE_CHAR,
+ ocLog10 = SC_OPCODE_LOG10,
+ ocEven = SC_OPCODE_EVEN,
+ ocOdd = SC_OPCODE_ODD,
+ ocStdNormDist = SC_OPCODE_STD_NORM_DIST,
+ ocStdNormDist_MS = SC_OPCODE_STD_NORM_DIST_MS,
+ ocFisher = SC_OPCODE_FISHER,
+ ocFisherInv = SC_OPCODE_FISHER_INV,
+ ocSNormInv = SC_OPCODE_S_NORM_INV,
+ ocSNormInv_MS = SC_OPCODE_S_NORM_INV_MS,
+ ocGammaLn = SC_OPCODE_GAMMA_LN,
+ ocGammaLn_MS = SC_OPCODE_GAMMA_LN_MS,
+ ocGamma = SC_OPCODE_GAMMA,
+ ocErrorType = SC_OPCODE_ERROR_TYPE,
+ ocErrorType_ODF = SC_OPCODE_ERROR_TYPE_ODF,
+ ocFormula = SC_OPCODE_FORMULA,
+ ocArabic = SC_OPCODE_ARABIC,
+ ocInfo = SC_OPCODE_INFO,
+ ocBahtText = SC_OPCODE_BAHTTEXT,
+ ocJis = SC_OPCODE_JIS,
+ ocAsc = SC_OPCODE_ASC,
+ ocUnicode = SC_OPCODE_UNICODE,
+ ocUnichar = SC_OPCODE_UNICHAR,
+ // Functions with more than one parameters
+ ocArcTan2 = SC_OPCODE_ARC_TAN_2,
+ ocCeil = SC_OPCODE_CEIL,
+ ocCeil_MS = SC_OPCODE_CEIL_MS,
+ ocCeil_Precise = SC_OPCODE_CEIL_PRECISE,
+ ocCeil_ISO = SC_OPCODE_CEIL_ISO,
+ ocCeil_Math = SC_OPCODE_CEIL_MATH,
+ ocFloor = SC_OPCODE_FLOOR,
+ ocFloor_MS = SC_OPCODE_FLOOR_MS,
+ ocFloor_Math = SC_OPCODE_FLOOR_MATH,
+ ocFloor_Precise = SC_OPCODE_FLOOR_PRECISE,
+ ocRound = SC_OPCODE_ROUND,
+ ocRoundUp = SC_OPCODE_ROUND_UP,
+ ocRoundDown = SC_OPCODE_ROUND_DOWN,
+ ocTrunc = SC_OPCODE_TRUNC,
+ ocLog = SC_OPCODE_LOG,
+ ocPower = SC_OPCODE_POWER,
+ ocGCD = SC_OPCODE_GCD,
+ ocLCM = SC_OPCODE_LCM,
+ ocMod = SC_OPCODE_MOD,
+ ocSumProduct = SC_OPCODE_SUM_PRODUCT,
+ ocSumSQ = SC_OPCODE_SUM_SQ,
+ ocSumX2MY2 = SC_OPCODE_SUM_X2MY2,
+ ocSumX2DY2 = SC_OPCODE_SUM_X2DY2,
+ ocSumXMY2 = SC_OPCODE_SUM_XMY2,
+ ocGetDate = SC_OPCODE_GET_DATE,
+ ocGetTime = SC_OPCODE_GET_TIME,
+ ocGetDiffDate = SC_OPCODE_GET_DIFF_DATE,
+ ocGetDiffDate360 = SC_OPCODE_GET_DIFF_DATE_360,
+ ocGetDateDif = SC_OPCODE_GET_DATEDIF,
+ ocMin = SC_OPCODE_MIN,
+ ocMax = SC_OPCODE_MAX,
+ ocSum = SC_OPCODE_SUM,
+ ocProduct = SC_OPCODE_PRODUCT,
+ ocAverage = SC_OPCODE_AVERAGE,
+ ocCount = SC_OPCODE_COUNT,
+ ocCount2 = SC_OPCODE_COUNT_2,
+ ocNPV = SC_OPCODE_NPV,
+ ocIRR = SC_OPCODE_IRR,
+ ocMIRR = SC_OPCODE_MIRR,
+ ocISPMT = SC_OPCODE_ISPMT,
+ ocVar = SC_OPCODE_VAR,
+ ocVarP = SC_OPCODE_VAR_P,
+ ocVarP_MS = SC_OPCODE_VAR_P_MS,
+ ocVarS = SC_OPCODE_VAR_S,
+ ocStDev = SC_OPCODE_ST_DEV,
+ ocStDevP = SC_OPCODE_ST_DEV_P,
+ ocStDevP_MS = SC_OPCODE_ST_DEV_P_MS,
+ ocStDevS = SC_OPCODE_ST_DEV_S,
+ ocB = SC_OPCODE_B,
+ ocNormDist = SC_OPCODE_NORM_DIST,
+ ocNormDist_MS = SC_OPCODE_NORM_DIST_MS,
+ ocExpDist = SC_OPCODE_EXP_DIST,
+ ocExpDist_MS = SC_OPCODE_EXP_DIST_MS,
+ ocBinomDist = SC_OPCODE_BINOM_DIST,
+ ocBinomDist_MS = SC_OPCODE_BINOM_DIST_MS,
+ ocBinomInv = SC_OPCODE_BINOM_INV,
+ ocPoissonDist = SC_OPCODE_POISSON_DIST,
+ ocPoissonDist_MS = SC_OPCODE_POISSON_DIST_MS,
+ ocCombin = SC_OPCODE_COMBIN,
+ ocCombinA = SC_OPCODE_COMBIN_A,
+ ocPermut = SC_OPCODE_PERMUT,
+ ocPermutationA = SC_OPCODE_PERMUTATION_A,
+ ocPV = SC_OPCODE_PV,
+ ocSYD = SC_OPCODE_SYD,
+ ocDDB = SC_OPCODE_DDB,
+ ocDB = SC_OPCODE_DB,
+ ocVBD = SC_OPCODE_VBD,
+ ocPDuration = SC_OPCODE_PDURATION,
+ ocSLN = SC_OPCODE_SLN,
+ ocPMT = SC_OPCODE_PMT,
+ ocColumns = SC_OPCODE_COLUMNS,
+ ocRows = SC_OPCODE_ROWS,
+ ocColumn = SC_OPCODE_COLUMN,
+ ocRow = SC_OPCODE_ROW,
+ ocRRI = SC_OPCODE_RRI,
+ ocFV = SC_OPCODE_FV,
+ ocNper = SC_OPCODE_NPER,
+ ocRate = SC_OPCODE_RATE,
+ ocIpmt = SC_OPCODE_IPMT,
+ ocPpmt = SC_OPCODE_PPMT,
+ ocCumIpmt = SC_OPCODE_CUM_IPMT,
+ ocCumPrinc = SC_OPCODE_CUM_PRINC,
+ ocEffect = SC_OPCODE_EFFECT,
+ ocNominal = SC_OPCODE_NOMINAL,
+ ocSubTotal = SC_OPCODE_SUB_TOTAL,
+ ocRawSubtract = SC_OPCODE_RAWSUBTRACT,
+ ocIfs_MS = SC_OPCODE_IFS_MS,
+ ocSwitch_MS = SC_OPCODE_SWITCH_MS,
+ ocMinIfs_MS = SC_OPCODE_MINIFS_MS,
+ ocMaxIfs_MS = SC_OPCODE_MAXIFS_MS,
+ ocRoundSig = SC_OPCODE_ROUNDSIG,
+ // Database functions
+ ocDBSum = SC_OPCODE_DB_SUM,
+ ocDBCount = SC_OPCODE_DB_COUNT,
+ ocDBCount2 = SC_OPCODE_DB_COUNT_2,
+ ocDBAverage = SC_OPCODE_DB_AVERAGE,
+ ocDBGet = SC_OPCODE_DB_GET,
+ ocDBMax = SC_OPCODE_DB_MAX,
+ ocDBMin = SC_OPCODE_DB_MIN,
+ ocDBProduct = SC_OPCODE_DB_PRODUCT,
+ ocDBStdDev = SC_OPCODE_DB_STD_DEV,
+ ocDBStdDevP = SC_OPCODE_DB_STD_DEV_P,
+ ocDBVar = SC_OPCODE_DB_VAR,
+ ocDBVarP = SC_OPCODE_DB_VAR_P,
+ // Management functions
+ ocIndirect = SC_OPCODE_INDIRECT,
+ ocAddress = SC_OPCODE_ADDRESS,
+ ocMatch = SC_OPCODE_MATCH,
+ ocCountEmptyCells = SC_OPCODE_COUNT_EMPTY_CELLS,
+ ocCountIf = SC_OPCODE_COUNT_IF,
+ ocSumIf = SC_OPCODE_SUM_IF,
+ ocAverageIf = SC_OPCODE_AVERAGE_IF,
+ ocSumIfs = SC_OPCODE_SUM_IFS,
+ ocAverageIfs = SC_OPCODE_AVERAGE_IFS,
+ ocCountIfs = SC_OPCODE_COUNT_IFS,
+ ocLookup = SC_OPCODE_LOOKUP,
+ ocVLookup = SC_OPCODE_V_LOOKUP,
+ ocHLookup = SC_OPCODE_H_LOOKUP,
+ ocMultiArea = SC_OPCODE_MULTI_AREA,
+ ocOffset = SC_OPCODE_OFFSET,
+ ocIndex = SC_OPCODE_INDEX,
+ ocAreas = SC_OPCODE_AREAS,
+ // String functions
+ ocCurrency = SC_OPCODE_CURRENCY,
+ ocReplace = SC_OPCODE_REPLACE,
+ ocFixed = SC_OPCODE_FIXED,
+ ocFind = SC_OPCODE_FIND,
+ ocExact = SC_OPCODE_EXACT,
+ ocLeft = SC_OPCODE_LEFT,
+ ocRight = SC_OPCODE_RIGHT,
+ ocSearch = SC_OPCODE_SEARCH,
+ ocMid = SC_OPCODE_MID,
+ ocText = SC_OPCODE_TEXT,
+ ocSubstitute = SC_OPCODE_SUBSTITUTE,
+ ocRept = SC_OPCODE_REPT,
+ ocConcat = SC_OPCODE_CONCAT,
+ ocConcat_MS = SC_OPCODE_CONCAT_MS,
+ ocTextJoin_MS = SC_OPCODE_TEXTJOIN_MS,
+ ocLenB = SC_OPCODE_LENB,
+ ocRightB = SC_OPCODE_RIGHTB,
+ ocLeftB = SC_OPCODE_LEFTB,
+ ocMidB = SC_OPCODE_MIDB,
+ ocReplaceB = SC_OPCODE_REPLACEB,
+ ocFindB = SC_OPCODE_FINDB,
+ ocSearchB = SC_OPCODE_SEARCHB,
+ ocNumberValue = SC_OPCODE_NUMBERVALUE,
+ ocRegex = SC_OPCODE_REGEX,
+ // Matrix functions
+ ocMatValue = SC_OPCODE_MAT_VALUE,
+ ocMatDet = SC_OPCODE_MAT_DET,
+ ocMatInv = SC_OPCODE_MAT_INV,
+ ocMatMult = SC_OPCODE_MAT_MULT,
+ ocMatTrans = SC_OPCODE_MAT_TRANS,
+ ocMatrixUnit = SC_OPCODE_MATRIX_UNIT,
+ // BackSolver
+ ocBackSolver = SC_OPCODE_BACK_SOLVER,
+ // Statistical functions
+ ocHypGeomDist = SC_OPCODE_HYP_GEOM_DIST,
+ ocHypGeomDist_MS = SC_OPCODE_HYP_GEOM_DIST_MS,
+ ocLogNormDist = SC_OPCODE_LOG_NORM_DIST,
+ ocLogNormDist_MS = SC_OPCODE_LOG_NORM_DIST_MS,
+ ocTDist = SC_OPCODE_T_DIST,
+ ocTDist_MS = SC_OPCODE_T_DIST_MS,
+ ocTDist_RT = SC_OPCODE_T_DIST_RT,
+ ocTDist_2T = SC_OPCODE_T_DIST_2T,
+ ocFDist = SC_OPCODE_F_DIST,
+ ocFDist_LT = SC_OPCODE_F_DIST_LT,
+ ocFDist_RT = SC_OPCODE_F_DIST_RT,
+ ocChiDist = SC_OPCODE_CHI_DIST,
+ ocChiDist_MS = SC_OPCODE_CHI_DIST_MS,
+ ocChiSqDist = SC_OPCODE_CHISQ_DIST,
+ ocChiSqDist_MS = SC_OPCODE_CHISQ_DIST_MS,
+ ocChiSqInv = SC_OPCODE_CHISQ_INV,
+ ocChiSqInv_MS = SC_OPCODE_CHISQ_INV_MS,
+ ocWeibull = SC_OPCODE_WEIBULL,
+ ocWeibull_MS = SC_OPCODE_WEIBULL_MS,
+ ocNegBinomVert = SC_OPCODE_NEG_BINOM_VERT,
+ ocNegBinomDist_MS = SC_OPCODE_NEG_BINOM_DIST_MS,
+ ocCritBinom = SC_OPCODE_CRIT_BINOM,
+ ocKurt = SC_OPCODE_KURT,
+ ocHarMean = SC_OPCODE_HAR_MEAN,
+ ocGeoMean = SC_OPCODE_GEO_MEAN,
+ ocStandard = SC_OPCODE_STANDARD,
+ ocAveDev = SC_OPCODE_AVE_DEV,
+ ocSkew = SC_OPCODE_SKEW,
+ ocSkewp = SC_OPCODE_SKEWP,
+ ocDevSq = SC_OPCODE_DEV_SQ,
+ ocMedian = SC_OPCODE_MEDIAN,
+ ocModalValue = SC_OPCODE_MODAL_VALUE,
+ ocModalValue_MS = SC_OPCODE_MODAL_VALUE_MS,
+ ocModalValue_Multi = SC_OPCODE_MODAL_VALUE_MULTI,
+ ocZTest = SC_OPCODE_Z_TEST,
+ ocZTest_MS = SC_OPCODE_Z_TEST_MS,
+ ocAggregate = SC_OPCODE_AGGREGATE,
+ ocTTest = SC_OPCODE_T_TEST,
+ ocTTest_MS = SC_OPCODE_T_TEST_MS,
+ ocRank = SC_OPCODE_RANK,
+ ocPercentile = SC_OPCODE_PERCENTILE,
+ ocPercentrank = SC_OPCODE_PERCENT_RANK,
+ ocPercentile_Inc = SC_OPCODE_PERCENTILE_INC,
+ ocPercentrank_Inc = SC_OPCODE_PERCENT_RANK_INC,
+ ocQuartile_Inc = SC_OPCODE_QUARTILE_INC,
+ ocRank_Eq = SC_OPCODE_RANK_EQ,
+ ocPercentile_Exc = SC_OPCODE_PERCENTILE_EXC,
+ ocPercentrank_Exc = SC_OPCODE_PERCENT_RANK_EXC,
+ ocQuartile_Exc = SC_OPCODE_QUARTILE_EXC,
+ ocRank_Avg = SC_OPCODE_RANK_AVG,
+ ocLarge = SC_OPCODE_LARGE,
+ ocSmall = SC_OPCODE_SMALL,
+ ocFrequency = SC_OPCODE_FREQUENCY,
+ ocQuartile = SC_OPCODE_QUARTILE,
+ ocNormInv = SC_OPCODE_NORM_INV,
+ ocNormInv_MS = SC_OPCODE_NORM_INV_MS,
+ ocConfidence = SC_OPCODE_CONFIDENCE,
+ ocConfidence_N = SC_OPCODE_CONFIDENCE_N,
+ ocConfidence_T = SC_OPCODE_CONFIDENCE_T,
+ ocFTest = SC_OPCODE_F_TEST,
+ ocFTest_MS = SC_OPCODE_F_TEST_MS,
+ ocTrimMean = SC_OPCODE_TRIM_MEAN,
+ ocProb = SC_OPCODE_PROB,
+ ocCorrel = SC_OPCODE_CORREL,
+ ocCovar = SC_OPCODE_COVAR,
+ ocCovarianceP = SC_OPCODE_COVARIANCE_P,
+ ocCovarianceS = SC_OPCODE_COVARIANCE_S,
+ ocPearson = SC_OPCODE_PEARSON,
+ ocRSQ = SC_OPCODE_RSQ,
+ ocSTEYX = SC_OPCODE_STEYX,
+ ocSlope = SC_OPCODE_SLOPE,
+ ocIntercept = SC_OPCODE_INTERCEPT,
+ ocTrend = SC_OPCODE_TREND,
+ ocGrowth = SC_OPCODE_GROWTH,
+ ocLinest = SC_OPCODE_LINEST,
+ ocLogest = SC_OPCODE_LOGEST,
+ ocForecast = SC_OPCODE_FORECAST,
+ ocForecast_ETS_ADD = SC_OPCODE_FORECAST_ETS_ADD,
+ ocForecast_ETS_SEA = SC_OPCODE_FORECAST_ETS_SEA,
+ ocForecast_ETS_MUL = SC_OPCODE_FORECAST_ETS_MUL,
+ ocForecast_ETS_PIA = SC_OPCODE_FORECAST_ETS_PIA,
+ ocForecast_ETS_PIM = SC_OPCODE_FORECAST_ETS_PIM,
+ ocForecast_ETS_STA = SC_OPCODE_FORECAST_ETS_STA,
+ ocForecast_ETS_STM = SC_OPCODE_FORECAST_ETS_STM,
+ ocForecast_LIN = SC_OPCODE_FORECAST_LIN,
+ ocChiInv = SC_OPCODE_CHI_INV,
+ ocChiInv_MS = SC_OPCODE_CHI_INV_MS,
+ ocGammaDist = SC_OPCODE_GAMMA_DIST,
+ ocGammaDist_MS = SC_OPCODE_GAMMA_DIST_MS,
+ ocGammaInv = SC_OPCODE_GAMMA_INV,
+ ocGammaInv_MS = SC_OPCODE_GAMMA_INV_MS,
+ ocTInv = SC_OPCODE_T_INV,
+ ocTInv_2T = SC_OPCODE_T_INV_2T,
+ ocTInv_MS = SC_OPCODE_T_INV_MS,
+ ocFInv = SC_OPCODE_F_INV,
+ ocFInv_LT = SC_OPCODE_F_INV_LT,
+ ocFInv_RT = SC_OPCODE_F_INV_RT,
+ ocChiTest = SC_OPCODE_CHI_TEST,
+ ocChiTest_MS = SC_OPCODE_CHI_TEST_MS,
+ ocLogInv = SC_OPCODE_LOG_INV,
+ ocLogInv_MS = SC_OPCODE_LOG_INV_MS,
+ ocTableOp = SC_OPCODE_TABLE_OP,
+ ocBetaDist = SC_OPCODE_BETA_DIST,
+ ocBetaInv = SC_OPCODE_BETA_INV,
+ ocBetaDist_MS = SC_OPCODE_BETA_DIST_MS,
+ ocBetaInv_MS = SC_OPCODE_BETA_INV_MS,
+ // Bit functions
+ ocBitAnd = SC_OPCODE_BITAND,
+ ocBitOr = SC_OPCODE_BITOR,
+ ocBitXor = SC_OPCODE_BITXOR,
+ ocBitRshift = SC_OPCODE_BITRSHIFT,
+ ocBitLshift = SC_OPCODE_BITLSHIFT,
+ // miscellaneous
+ ocWeek = SC_OPCODE_WEEK,
+ ocIsoWeeknum = SC_OPCODE_ISOWEEKNUM,
+ ocWeeknumOOo = SC_OPCODE_WEEKNUM_OOO,
+ ocGetDayOfWeek = SC_OPCODE_GET_DAY_OF_WEEK,
+ ocNetWorkdays = SC_OPCODE_NETWORKDAYS,
+ ocNetWorkdays_MS = SC_OPCODE_NETWORKDAYS_MS,
+ ocWorkday_MS = SC_OPCODE_WORKDAY_MS,
+ ocNoName = SC_OPCODE_NO_NAME,
+ ocStyle = SC_OPCODE_STYLE,
+ ocDde = SC_OPCODE_DDE,
+ ocBase = SC_OPCODE_BASE,
+ ocSheet = SC_OPCODE_SHEET,
+ ocSheets = SC_OPCODE_SHEETS,
+ ocMinA = SC_OPCODE_MIN_A,
+ ocMaxA = SC_OPCODE_MAX_A,
+ ocAverageA = SC_OPCODE_AVERAGE_A,
+ ocStDevA = SC_OPCODE_ST_DEV_A,
+ ocStDevPA = SC_OPCODE_ST_DEV_P_A,
+ ocVarA = SC_OPCODE_VAR_A,
+ ocVarPA = SC_OPCODE_VAR_P_A,
+ ocEasterSunday = SC_OPCODE_EASTERSUNDAY,
+ ocDecimal = SC_OPCODE_DECIMAL,
+ ocConvertOOo = SC_OPCODE_CONVERT_OOO,
+ ocRoman = SC_OPCODE_ROMAN,
+ ocHyperLink = SC_OPCODE_HYPERLINK,
+ ocGetPivotData = SC_OPCODE_GET_PIVOT_DATA,
+ ocEuroConvert = SC_OPCODE_EUROCONVERT,
+ ocFilterXML = SC_OPCODE_FILTERXML,
+ ocWebservice = SC_OPCODE_WEBSERVICE,
+ ocColor = SC_OPCODE_COLOR,
+ ocErf_MS = SC_OPCODE_ERF_MS,
+ ocErfc_MS = SC_OPCODE_ERFC_MS,
+ ocEncodeURL = SC_OPCODE_ENCODEURL,
+ ocFourier = SC_OPCODE_FOURIER,
+ ocRandbetweenNV = SC_OPCODE_RANDBETWEEN_NV,
+ // internal stuff
+ ocInternalBegin = SC_OPCODE_INTERNAL_BEGIN,
+ ocTTT = SC_OPCODE_TTT,
+ ocDebugVar = SC_OPCODE_DEBUG_VAR,
+ ocInternalEnd = SC_OPCODE_INTERNAL_END,
+ // from here on ExtraData
+ ocDataToken1 = SC_OPCODE_DATA_TOKEN_1,
+ // no OpCode
+ ocNone = SC_OPCODE_NONE
+};
+
+// Only to be used for debugging output. No guarantee of stability of the
+// return value.
+
+// Turn this into an operator<< when OpCode becomes a scoped enum
+
+inline std::string OpCodeEnumToString(OpCode eCode)
+{
+ switch (eCode)
+ {
+ case ocPush: return "Push";
+ case ocCall: return "Call";
+ case ocStop: return "Stop";
+ case ocExternal: return "External";
+ case ocName: return "Name";
+ case ocIf: return "If";
+ case ocIfError: return "IfError";
+ case ocIfNA: return "IfNA";
+ case ocChoose: return "Choose";
+ case ocOpen: return "Open";
+ case ocClose: return "Close";
+ case ocTableRefOpen: return "TableRefOpen";
+ case ocTableRefClose: return "TableRefClose";
+ case ocSep: return "Sep";
+ case ocArrayOpen: return "ArrayOpen";
+ case ocArrayClose: return "ArrayClose";
+ case ocArrayRowSep: return "ArrayRowSep";
+ case ocArrayColSep: return "ArrayColSep";
+ case ocMissing: return "Missing";
+ case ocBad: return "Bad";
+ case ocStringXML: return "StringXML";
+ case ocSpaces: return "Spaces";
+ case ocWhitespace: return "Whitespace";
+ case ocMatRef: return "MatRef";
+ case ocTableRefItemAll: return "TableRefItemAll";
+ case ocTableRefItemHeaders: return "TableRefItemHeaders";
+ case ocTableRefItemData: return "TableRefItemData";
+ case ocTableRefItemTotals: return "TableRefItemTotals";
+ case ocTableRefItemThisRow: return "TableRefItemThisRow";
+ case ocSkip: return "Skip";
+ case ocDBArea: return "DBArea";
+ case ocTableRef: return "TableRef";
+ case ocMacro: return "Macro";
+ case ocColRowName: return "ColRowName";
+ case ocColRowNameAuto: return "ColRowNameAuto";
+ case ocPercentSign: return "PercentSign";
+ case ocErrNull: return "ErrNull";
+ case ocErrDivZero: return "ErrDivZero";
+ case ocErrValue: return "ErrValue";
+ case ocErrRef: return "ErrRef";
+ case ocErrName: return "ErrName";
+ case ocErrNum: return "ErrNum";
+ case ocErrNA: return "ErrNA";
+ case ocAdd: return "Add";
+ case ocSub: return "Sub";
+ case ocMul: return "Mul";
+ case ocDiv: return "Div";
+ case ocAmpersand: return "Ampersand";
+ case ocPow: return "Pow";
+ case ocEqual: return "Equal";
+ case ocNotEqual: return "NotEqual";
+ case ocLess: return "Less";
+ case ocGreater: return "Greater";
+ case ocLessEqual: return "LessEqual";
+ case ocGreaterEqual: return "GreaterEqual";
+ case ocAnd: return "And";
+ case ocOr: return "Or";
+ case ocXor: return "Xor";
+ case ocIntersect: return "Intersect";
+ case ocUnion: return "Union";
+ case ocRange: return "Range";
+ case ocNot: return "Not";
+ case ocNeg: return "Neg";
+ case ocNegSub: return "NegSub";
+ case ocPi: return "Pi";
+ case ocRandom: return "Random";
+ case ocRandomNV: return "RandomNV";
+ case ocTrue: return "True";
+ case ocFalse: return "False";
+ case ocGetActDate: return "GetActDate";
+ case ocGetActTime: return "GetActTime";
+ case ocNotAvail: return "NotAvail";
+ case ocCurrent: return "Current";
+ case ocDeg: return "Deg";
+ case ocRad: return "Rad";
+ case ocSin: return "Sin";
+ case ocCos: return "Cos";
+ case ocTan: return "Tan";
+ case ocCot: return "Cot";
+ case ocArcSin: return "ArcSin";
+ case ocArcCos: return "ArcCos";
+ case ocArcTan: return "ArcTan";
+ case ocArcCot: return "ArcCot";
+ case ocSinHyp: return "SinHyp";
+ case ocCosHyp: return "CosHyp";
+ case ocTanHyp: return "TanHyp";
+ case ocCotHyp: return "CotHyp";
+ case ocArcSinHyp: return "ArcSinHyp";
+ case ocArcCosHyp: return "ArcCosHyp";
+ case ocArcTanHyp: return "ArcTanHyp";
+ case ocArcCotHyp: return "ArcCotHyp";
+ case ocCosecant: return "Cosecant";
+ case ocSecant: return "Secant";
+ case ocCosecantHyp: return "CosecantHyp";
+ case ocSecantHyp: return "SecantHyp";
+ case ocExp: return "Exp";
+ case ocLn: return "Ln";
+ case ocSqrt: return "Sqrt";
+ case ocFact: return "Fact";
+ case ocGetYear: return "GetYear";
+ case ocGetMonth: return "GetMonth";
+ case ocGetDay: return "GetDay";
+ case ocGetHour: return "GetHour";
+ case ocGetMin: return "GetMin";
+ case ocGetSec: return "GetSec";
+ case ocPlusMinus: return "PlusMinus";
+ case ocAbs: return "Abs";
+ case ocInt: return "Int";
+ case ocPhi: return "Phi";
+ case ocGauss: return "Gauss";
+ case ocIsEmpty: return "IsEmpty";
+ case ocIsString: return "IsString";
+ case ocIsNonString: return "IsNonString";
+ case ocIsLogical: return "IsLogical";
+ case ocType: return "Type";
+ case ocCell: return "Cell";
+ case ocIsRef: return "IsRef";
+ case ocIsValue: return "IsValue";
+ case ocIsFormula: return "IsFormula";
+ case ocIsNA: return "IsNA";
+ case ocIsErr: return "IsErr";
+ case ocIsError: return "IsError";
+ case ocIsEven: return "IsEven";
+ case ocIsOdd: return "IsOdd";
+ case ocN: return "N";
+ case ocGetDateValue: return "GetDateValue";
+ case ocGetTimeValue: return "GetTimeValue";
+ case ocCode: return "Code";
+ case ocTrim: return "Trim";
+ case ocUpper: return "Upper";
+ case ocProper: return "Proper";
+ case ocLower: return "Lower";
+ case ocLen: return "Len";
+ case ocT: return "T";
+ case ocValue: return "Value";
+ case ocClean: return "Clean";
+ case ocChar: return "Char";
+ case ocLog10: return "Log10";
+ case ocEven: return "Even";
+ case ocOdd: return "Odd";
+ case ocStdNormDist: return "StdNormDist";
+ case ocStdNormDist_MS: return "StdNormDist_MS";
+ case ocFisher: return "Fisher";
+ case ocFisherInv: return "FisherInv";
+ case ocSNormInv: return "SNormInv";
+ case ocSNormInv_MS: return "SNormInv_MS";
+ case ocGammaLn: return "GammaLn";
+ case ocGammaLn_MS: return "GammaLn_MS";
+ case ocGamma: return "Gamma";
+ case ocErrorType: return "ErrorType";
+ case ocErrorType_ODF: return "ErrorType_ODF";
+ case ocFormula: return "Formula";
+ case ocArabic: return "Arabic";
+ case ocInfo: return "Info";
+ case ocBahtText: return "BahtText";
+ case ocJis: return "Jis";
+ case ocAsc: return "Asc";
+ case ocUnicode: return "Unicode";
+ case ocUnichar: return "Unichar";
+ case ocArcTan2: return "ArcTan2";
+ case ocCeil: return "Ceil";
+ case ocCeil_MS: return "Ceil_MS";
+ case ocCeil_Precise: return "Ceil_Precise";
+ case ocCeil_ISO: return "Ceil_ISO";
+ case ocCeil_Math: return "Ceil_Math";
+ case ocFloor: return "Floor";
+ case ocFloor_MS: return "Floor_MS";
+ case ocFloor_Math: return "Floor_Math";
+ case ocFloor_Precise: return "Floor_Precise";
+ case ocRound: return "Round";
+ case ocRoundUp: return "RoundUp";
+ case ocRoundDown: return "RoundDown";
+ case ocTrunc: return "Trunc";
+ case ocLog: return "Log";
+ case ocPower: return "Power";
+ case ocGCD: return "GCD";
+ case ocLCM: return "LCM";
+ case ocMod: return "Mod";
+ case ocSumProduct: return "SumProduct";
+ case ocSumSQ: return "SumSQ";
+ case ocSumX2MY2: return "SumX2MY2";
+ case ocSumX2DY2: return "SumX2DY2";
+ case ocSumXMY2: return "SumXMY2";
+ case ocGetDate: return "GetDate";
+ case ocGetTime: return "GetTime";
+ case ocGetDiffDate: return "GetDiffDate";
+ case ocGetDiffDate360: return "GetDiffDate360";
+ case ocGetDateDif: return "GetDateDif";
+ case ocMin: return "Min";
+ case ocMax: return "Max";
+ case ocSum: return "Sum";
+ case ocProduct: return "Product";
+ case ocAverage: return "Average";
+ case ocCount: return "Count";
+ case ocCount2: return "Count2";
+ case ocNPV: return "NPV";
+ case ocIRR: return "IRR";
+ case ocMIRR: return "MIRR";
+ case ocISPMT: return "ISPMT";
+ case ocVar: return "Var";
+ case ocVarP: return "VarP";
+ case ocVarP_MS: return "VarP_MS";
+ case ocVarS: return "VarS";
+ case ocStDev: return "StDev";
+ case ocStDevP: return "StDevP";
+ case ocStDevP_MS: return "StDevP_MS";
+ case ocStDevS: return "StDevS";
+ case ocB: return "B";
+ case ocNormDist: return "NormDist";
+ case ocNormDist_MS: return "NormDist_MS";
+ case ocExpDist: return "ExpDist";
+ case ocExpDist_MS: return "ExpDist_MS";
+ case ocBinomDist: return "BinomDist";
+ case ocBinomDist_MS: return "BinomDist_MS";
+ case ocBinomInv: return "BinomInv";
+ case ocPoissonDist: return "PoissonDist";
+ case ocPoissonDist_MS: return "PoissonDist_MS";
+ case ocCombin: return "Combin";
+ case ocCombinA: return "CombinA";
+ case ocPermut: return "Permut";
+ case ocPermutationA: return "PermutationA";
+ case ocPV: return "PV";
+ case ocSYD: return "SYD";
+ case ocDDB: return "DDB";
+ case ocDB: return "DB";
+ case ocVBD: return "VBD";
+ case ocPDuration: return "PDuration";
+ case ocSLN: return "SLN";
+ case ocPMT: return "PMT";
+ case ocColumns: return "Columns";
+ case ocRows: return "Rows";
+ case ocColumn: return "Column";
+ case ocRow: return "Row";
+ case ocRRI: return "RRI";
+ case ocFV: return "FV";
+ case ocNper: return "Nper";
+ case ocRate: return "Rate";
+ case ocIpmt: return "Ipmt";
+ case ocPpmt: return "Ppmt";
+ case ocCumIpmt: return "CumIpmt";
+ case ocCumPrinc: return "CumPrinc";
+ case ocEffect: return "Effect";
+ case ocNominal: return "Nominal";
+ case ocSubTotal: return "SubTotal";
+ case ocRawSubtract: return "RawSubtract";
+ case ocIfs_MS: return "Ifs_MS";
+ case ocSwitch_MS: return "Switch_MS";
+ case ocMinIfs_MS: return "MinIfs_MS";
+ case ocMaxIfs_MS: return "MaxIfs_MS";
+ case ocRoundSig: return "RoundSig";
+ case ocDBSum: return "DBSum";
+ case ocDBCount: return "DBCount";
+ case ocDBCount2: return "DBCount2";
+ case ocDBAverage: return "DBAverage";
+ case ocDBGet: return "DBGet";
+ case ocDBMax: return "DBMax";
+ case ocDBMin: return "DBMin";
+ case ocDBProduct: return "DBProduct";
+ case ocDBStdDev: return "DBStdDev";
+ case ocDBStdDevP: return "DBStdDevP";
+ case ocDBVar: return "DBVar";
+ case ocDBVarP: return "DBVarP";
+ case ocIndirect: return "Indirect";
+ case ocAddress: return "Address";
+ case ocMatch: return "Match";
+ case ocCountEmptyCells: return "CountEmptyCells";
+ case ocCountIf: return "CountIf";
+ case ocSumIf: return "SumIf";
+ case ocAverageIf: return "AverageIf";
+ case ocSumIfs: return "SumIfs";
+ case ocAverageIfs: return "AverageIfs";
+ case ocCountIfs: return "CountIfs";
+ case ocLookup: return "Lookup";
+ case ocVLookup: return "VLookup";
+ case ocHLookup: return "HLookup";
+ case ocMultiArea: return "MultiArea";
+ case ocOffset: return "Offset";
+ case ocIndex: return "Index";
+ case ocAreas: return "Areas";
+ case ocCurrency: return "Currency";
+ case ocReplace: return "Replace";
+ case ocFixed: return "Fixed";
+ case ocFind: return "Find";
+ case ocExact: return "Exact";
+ case ocLeft: return "Left";
+ case ocRight: return "Right";
+ case ocSearch: return "Search";
+ case ocMid: return "Mid";
+ case ocText: return "Text";
+ case ocSubstitute: return "Substitute";
+ case ocRept: return "Rept";
+ case ocRegex: return "Regex";
+ case ocConcat: return "Concat";
+ case ocConcat_MS: return "Concat_MS";
+ case ocTextJoin_MS: return "TextJoin_MS";
+ case ocLenB: return "LenB";
+ case ocRightB: return "RightB";
+ case ocLeftB: return "LeftB";
+ case ocMidB: return "MidB";
+ case ocReplaceB: return "ReplaceB";
+ case ocFindB: return "FindB";
+ case ocSearchB: return "SearchB";
+ case ocNumberValue: return "NumberValue";
+ case ocMatValue: return "MatValue";
+ case ocMatDet: return "MatDet";
+ case ocMatInv: return "MatInv";
+ case ocMatMult: return "MatMult";
+ case ocMatTrans: return "MatTrans";
+ case ocMatrixUnit: return "MatrixUnit";
+ case ocBackSolver: return "BackSolver";
+ case ocHypGeomDist: return "HypGeomDist";
+ case ocHypGeomDist_MS: return "HypGeomDist_MS";
+ case ocLogNormDist: return "LogNormDist";
+ case ocLogNormDist_MS: return "LogNormDist_MS";
+ case ocTDist: return "TDist";
+ case ocTDist_MS: return "TDist_MS";
+ case ocTDist_RT: return "TDist_RT";
+ case ocTDist_2T: return "TDist_2T";
+ case ocFDist: return "FDist";
+ case ocFDist_LT: return "FDist_LT";
+ case ocFDist_RT: return "FDist_RT";
+ case ocChiDist: return "ChiDist";
+ case ocChiDist_MS: return "ChiDist_MS";
+ case ocChiSqDist: return "ChiSqDist";
+ case ocChiSqDist_MS: return "ChiSqDist_MS";
+ case ocChiSqInv: return "ChiSqInv";
+ case ocChiSqInv_MS: return "ChiSqInv_MS";
+ case ocWeibull: return "Weibull";
+ case ocWeibull_MS: return "Weibull_MS";
+ case ocNegBinomVert: return "NegBinomVert";
+ case ocNegBinomDist_MS: return "NegBinomDist_MS";
+ case ocCritBinom: return "CritBinom";
+ case ocKurt: return "Kurt";
+ case ocHarMean: return "HarMean";
+ case ocGeoMean: return "GeoMean";
+ case ocStandard: return "Standard";
+ case ocAveDev: return "AveDev";
+ case ocSkew: return "Skew";
+ case ocSkewp: return "Skewp";
+ case ocDevSq: return "DevSq";
+ case ocMedian: return "Median";
+ case ocModalValue: return "ModalValue";
+ case ocModalValue_MS: return "ModalValue_MS";
+ case ocModalValue_Multi: return "ModalValue_Multi";
+ case ocZTest: return "ZTest";
+ case ocZTest_MS: return "ZTest_MS";
+ case ocAggregate: return "Aggregate";
+ case ocTTest: return "TTest";
+ case ocTTest_MS: return "TTest_MS";
+ case ocRank: return "Rank";
+ case ocPercentile: return "Percentile";
+ case ocPercentrank: return "Percentrank";
+ case ocPercentile_Inc: return "Percentile_Inc";
+ case ocPercentrank_Inc: return "Percentrank_Inc";
+ case ocQuartile_Inc: return "Quartile_Inc";
+ case ocRank_Eq: return "Rank_Eq";
+ case ocPercentile_Exc: return "Percentile_Exc";
+ case ocPercentrank_Exc: return "Percentrank_Exc";
+ case ocQuartile_Exc: return "Quartile_Exc";
+ case ocRank_Avg: return "Rank_Avg";
+ case ocLarge: return "Large";
+ case ocSmall: return "Small";
+ case ocFrequency: return "Frequency";
+ case ocQuartile: return "Quartile";
+ case ocNormInv: return "NormInv";
+ case ocNormInv_MS: return "NormInv_MS";
+ case ocConfidence: return "Confidence";
+ case ocConfidence_N: return "Confidence_N";
+ case ocConfidence_T: return "Confidence_T";
+ case ocFTest: return "FTest";
+ case ocFTest_MS: return "FTest_MS";
+ case ocTrimMean: return "TrimMean";
+ case ocProb: return "Prob";
+ case ocCorrel: return "Correl";
+ case ocCovar: return "Covar";
+ case ocCovarianceP: return "CovarianceP";
+ case ocCovarianceS: return "CovarianceS";
+ case ocPearson: return "Pearson";
+ case ocRSQ: return "RSQ";
+ case ocSTEYX: return "STEYX";
+ case ocSlope: return "Slope";
+ case ocIntercept: return "Intercept";
+ case ocTrend: return "Trend";
+ case ocGrowth: return "Growth";
+ case ocLinest: return "Linest";
+ case ocLogest: return "Logest";
+ case ocForecast: return "Forecast";
+ case ocForecast_ETS_ADD: return "Forecast_ETS_ADD";
+ case ocForecast_ETS_SEA: return "Forecast_ETS_SEA";
+ case ocForecast_ETS_MUL: return "Forecast_ETS_MUL";
+ case ocForecast_ETS_PIA: return "Forecast_ETS_PIA";
+ case ocForecast_ETS_PIM: return "Forecast_ETS_PIM";
+ case ocForecast_ETS_STA: return "Forecast_ETS_STA";
+ case ocForecast_ETS_STM: return "Forecast_ETS_STM";
+ case ocForecast_LIN: return "Forecast_LIN";
+ case ocChiInv: return "ChiInv";
+ case ocChiInv_MS: return "ChiInv_MS";
+ case ocGammaDist: return "GammaDist";
+ case ocGammaDist_MS: return "GammaDist_MS";
+ case ocGammaInv: return "GammaInv";
+ case ocGammaInv_MS: return "GammaInv_MS";
+ case ocTInv: return "TInv";
+ case ocTInv_2T: return "TInv_2T";
+ case ocTInv_MS: return "TInv_MS";
+ case ocFInv: return "FInv";
+ case ocFInv_LT: return "FInv_LT";
+ case ocFInv_RT: return "FInv_RT";
+ case ocChiTest: return "ChiTest";
+ case ocChiTest_MS: return "ChiTest_MS";
+ case ocLogInv: return "LogInv";
+ case ocLogInv_MS: return "LogInv_MS";
+ case ocTableOp: return "TableOp";
+ case ocBetaDist: return "BetaDist";
+ case ocBetaInv: return "BetaInv";
+ case ocBetaDist_MS: return "BetaDist_MS";
+ case ocBetaInv_MS: return "BetaInv_MS";
+ case ocBitAnd: return "BitAnd";
+ case ocBitOr: return "BitOr";
+ case ocBitXor: return "BitXor";
+ case ocBitRshift: return "BitRshift";
+ case ocBitLshift: return "BitLshift";
+ case ocWeek: return "Week";
+ case ocIsoWeeknum: return "IsoWeeknum";
+ case ocWeeknumOOo: return "WeeknumOOo";
+ case ocGetDayOfWeek: return "GetDayOfWeek";
+ case ocNetWorkdays: return "NetWorkdays";
+ case ocNetWorkdays_MS: return "NetWorkdays_MS";
+ case ocWorkday_MS: return "Workday_MS";
+ case ocNoName: return "NoName";
+ case ocStyle: return "Style";
+ case ocDde: return "Dde";
+ case ocBase: return "Base";
+ case ocSheet: return "Sheet";
+ case ocSheets: return "Sheets";
+ case ocMinA: return "MinA";
+ case ocMaxA: return "MaxA";
+ case ocAverageA: return "AverageA";
+ case ocStDevA: return "StDevA";
+ case ocStDevPA: return "StDevPA";
+ case ocVarA: return "VarA";
+ case ocVarPA: return "VarPA";
+ case ocEasterSunday: return "EasterSunday";
+ case ocDecimal: return "Decimal";
+ case ocConvertOOo: return "ConvertOOo";
+ case ocRoman: return "Roman";
+ case ocHyperLink: return "HyperLink";
+ case ocGetPivotData: return "GetPivotData";
+ case ocEuroConvert: return "EuroConvert";
+ case ocFilterXML: return "FilterXML";
+ case ocWebservice: return "Webservice";
+ case ocColor: return "Color";
+ case ocErf_MS: return "Erf_MS";
+ case ocErfc_MS: return "Erfc_MS";
+ case ocEncodeURL: return "EncodeURL";
+ case ocFourier: return "Fourier";
+ case ocRandbetweenNV: return "RandbetweenNV";
+ case ocTTT: return "TTT";
+ case ocDebugVar: return "DebugVar";
+ case ocDataToken1: return "DataToken1";
+ case ocNone: return "None";
+ }
+ std::ostringstream os;
+ os << static_cast<int>(eCode);
+ return os.str();
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/paramclass.hxx b/include/formula/paramclass.hxx
new file mode 100644
index 0000000000..30773c35e0
--- /dev/null
+++ b/include/formula/paramclass.hxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_FORMULA_PARAMCLASS_HXX
+#define INCLUDED_FORMULA_PARAMCLASS_HXX
+
+#include <sal/config.h>
+#include <sal/types.h>
+
+namespace formula
+{
+ enum ParamClass : sal_uInt8
+ {
+ Unknown = 0, // MUST be zero for initialization mechanism!
+
+ /** Out of bounds, function doesn't expect that many parameters.
+ However, not necessarily returned if a module specific definition
+ for example returns type Value for an unlisted function. */
+ Bounds,
+
+ /** In array formula: single value to be passed. Results in JumpMatrix
+ being created and multiple calls to function. Functions handling a
+ formula::svDoubleRef by means of DoubleRefToPosSingleRef() or
+ PopDoubleRefOrSingleRef() or GetDouble() or GetString() should have
+ this. */
+ Value,
+
+ /** In array formula: area reference must stay reference. Otherwise
+ don't care. Functions handling a formula::svDoubleRef by means of
+ PopDoubleRefOrSingleRef() should not have this. */
+ Reference,
+
+ /** Like Reference but the function accepts also a list of references
+ (ocUnion svRefList) as one argument AND handles the special case of
+ an array of references in array mode. Then the resulting argument
+ for a parameter in JumpMatrix context may be an array of references
+ which then is to be preferred over a result matrix. This final
+ behaviour is the opposite of SuppressedReferenceOrForceArray. */
+ ReferenceOrRefArray,
+
+ /** In array formula: convert area reference to array. Function will be
+ called only once if no Value type is involved. Functions able to
+ handle a svMatrix parameter but not a formula::svDoubleRef parameter as area
+ should have this. */
+ Array,
+
+ /** Area reference must be converted to array in any case, and must
+ also be propagated to subsequent operators and functions being part
+ of a parameter of this function. */
+ ForceArray,
+
+ /** Area reference is not converted to array, but ForceArray must be
+ propagated to subsequent operators and functions being part of a
+ parameter of this function. Used with functions that treat
+ references separately from arrays, but need the forced array
+ calculation of parameters that are not references. */
+ ReferenceOrForceArray,
+
+ /** Same as ReferenceOrForceArray but suppressed / not inherited in the
+ compiler's ForceArray context to indicate that a result of
+ Reference in JumpMatrix context should use the result matrix
+ instead of the array of references. Never used as initial parameter
+ classification. */
+ SuppressedReferenceOrForceArray,
+
+ /** A function return forces the caller into array mode for this one
+ call, making it behave like it had ForceArray but not propagated to
+ any further operators in the same parameter. */
+ ForceArrayReturn
+ };
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/include/formula/token.hxx b/include/formula/token.hxx
new file mode 100644
index 0000000000..f534b2c5c8
--- /dev/null
+++ b/include/formula/token.hxx
@@ -0,0 +1,483 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_TOKEN_HXX
+#define INCLUDED_FORMULA_TOKEN_HXX
+
+#include <sal/config.h>
+
+#include <cstring>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include <formula/formuladllapi.h>
+#include <formula/opcode.hxx>
+#include <formula/types.hxx>
+#include <formula/paramclass.hxx>
+#include <osl/interlck.h>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+#include <svl/sharedstring.hxx>
+
+class ScJumpMatrix;
+class ScMatrix;
+struct ScComplexRefData;
+struct ScSingleRefData;
+enum class FormulaError : sal_uInt16;
+
+namespace formula
+{
+
+enum StackVar : sal_uInt8
+{
+ svByte,
+ svDouble,
+ svString,
+ svSingleRef,
+ svDoubleRef,
+ svMatrix,
+ svIndex,
+ svJump,
+ svExternal, // Byte + String
+ svFAP, // FormulaAutoPilot only, ever exported
+ svJumpMatrix,
+ svRefList, // ocUnion result
+ svEmptyCell, // Result is an empty cell, e.g. in LOOKUP()
+
+ svMatrixCell, // Result is a matrix with bells and
+ // whistles as needed for _the_ matrix
+ // formula result.
+
+ svHybridCell, // A temporary condition of a formula
+ // cell during import, having a double
+ // and/or string result and a formula
+ // string to be compiled.
+
+ svExternalSingleRef,
+ svExternalDoubleRef,
+ svExternalName,
+ svSingleVectorRef,
+ svDoubleVectorRef,
+ svError, // error token
+ svMissing, // 0 or ""
+ svSep, // separator, ocSep, ocOpen, ocClose
+ svUnknown // unknown StackType
+};
+
+// Only to be used for debugging output. No guarantee of stability of the
+// return value.
+
+// Turn this into an operator<< when StackVar becomes a scoped enum
+
+inline std::string StackVarEnumToString(StackVar const e)
+{
+ switch (e)
+ {
+ case svByte: return "Byte";
+ case svDouble: return "Double";
+ case svString: return "String";
+ case svSingleRef: return "SingleRef";
+ case svDoubleRef: return "DoubleRef";
+ case svMatrix: return "Matrix";
+ case svIndex: return "Index";
+ case svJump: return "Jump";
+ case svExternal: return "External";
+ case svFAP: return "FAP";
+ case svJumpMatrix: return "JumpMatrix";
+ case svRefList: return "RefList";
+ case svEmptyCell: return "EmptyCell";
+ case svMatrixCell: return "MatrixCell";
+ case svHybridCell: return "HybridCell";
+ case svExternalSingleRef: return "ExternalSingleRef";
+ case svExternalDoubleRef: return "ExternalDoubleRef";
+ case svExternalName: return "ExternalName";
+ case svSingleVectorRef: return "SingleVectorRef";
+ case svDoubleVectorRef: return "DoubleVectorRef";
+ case svError: return "Error";
+ case svMissing: return "Missing";
+ case svSep: return "Sep";
+ case svUnknown: return "Unknown";
+ }
+ std::ostringstream os;
+ os << static_cast<int>(e);
+ return os.str();
+}
+
+class FORMULA_DLLPUBLIC FormulaToken
+{
+ OpCode eOp;
+ const StackVar eType; // type of data
+ mutable oslInterlockedCount mnRefCnt; // reference count
+
+ FormulaToken& operator=( const FormulaToken& ) = delete;
+public:
+ FormulaToken( StackVar eTypeP,OpCode e = ocPush );
+ FormulaToken( const FormulaToken& r );
+
+ virtual ~FormulaToken();
+
+ void Delete() { delete this; }
+ void DeleteIfZeroRef() { if (mnRefCnt == 0) delete this; }
+ StackVar GetType() const { return eType; }
+ bool IsFunction() const; // pure functions, no operators
+
+ bool IsExternalRef() const;
+ bool IsRef() const;
+
+ sal_uInt8 GetParamCount() const;
+
+ void IncRef() const
+ {
+ osl_atomic_increment(&mnRefCnt);
+ }
+
+ void DecRef() const
+ {
+ if (!osl_atomic_decrement(&mnRefCnt))
+ const_cast<FormulaToken*>(this)->Delete();
+ }
+
+ oslInterlockedCount GetRef() const { return mnRefCnt; }
+ OpCode GetOpCode() const { return eOp; }
+
+ bool IsInForceArray() const;
+
+ /**
+ Dummy methods to avoid switches and casts where possible,
+ the real token classes have to override the appropriate method[s].
+ The only methods valid anytime if not overridden are:
+
+ - GetByte() since this represents the count of parameters to a function
+ which of course is 0 on non-functions. FormulaByteToken and ScExternal do
+ override it.
+
+ - GetInForceArray() since also this is only used for operators and
+ functions and is ParamClass::Unknown for other tokens.
+
+ Any other non-overridden method pops up an assertion.
+ */
+
+ virtual sal_uInt8 GetByte() const;
+ virtual void SetByte( sal_uInt8 n );
+ virtual ParamClass GetInForceArray() const;
+ virtual void SetInForceArray( ParamClass c );
+ virtual double GetDouble() const;
+ virtual double& GetDoubleAsReference();
+ virtual sal_Int16 GetDoubleType() const;
+ virtual void SetDoubleType( sal_Int16 nType );
+ virtual const svl::SharedString & GetString() const;
+ virtual void SetString( const svl::SharedString& rStr );
+ virtual sal_uInt16 GetIndex() const;
+ virtual void SetIndex( sal_uInt16 n );
+ virtual sal_Int16 GetSheet() const;
+ virtual void SetSheet( sal_Int16 n );
+ virtual sal_Unicode GetChar() const;
+ virtual short* GetJump() const;
+ virtual const OUString& GetExternal() const;
+ virtual FormulaToken* GetFAPOrigToken() const;
+ virtual FormulaError GetError() const;
+ virtual void SetError( FormulaError );
+
+ virtual const ScSingleRefData* GetSingleRef() const;
+ virtual ScSingleRefData* GetSingleRef();
+ virtual const ScComplexRefData* GetDoubleRef() const;
+ virtual ScComplexRefData* GetDoubleRef();
+ virtual const ScSingleRefData* GetSingleRef2() const;
+ virtual ScSingleRefData* GetSingleRef2();
+ virtual const ScMatrix* GetMatrix() const;
+ virtual ScMatrix* GetMatrix();
+ virtual ScJumpMatrix* GetJumpMatrix() const;
+ virtual const std::vector<ScComplexRefData>* GetRefList() const;
+ virtual std::vector<ScComplexRefData>* GetRefList();
+
+ virtual FormulaToken* Clone() const { return new FormulaToken(*this); }
+
+ virtual bool TextEqual( const formula::FormulaToken& rToken ) const;
+ virtual bool operator==( const FormulaToken& rToken ) const;
+
+ /** This is dirty and only the compiler should use it! */
+ struct PrivateAccess { friend class FormulaCompiler; private: PrivateAccess() { } };
+ void NewOpCode( OpCode e, const PrivateAccess& ) { eOp = e; }
+};
+
+inline void intrusive_ptr_add_ref(const FormulaToken* p)
+{
+ p->IncRef();
+}
+
+inline void intrusive_ptr_release(const FormulaToken* p)
+{
+ p->DecRef();
+}
+
+class FORMULA_DLLPUBLIC FormulaSpaceToken final : public FormulaToken
+{
+private:
+ sal_uInt8 nByte;
+ sal_Unicode cChar;
+public:
+ FormulaSpaceToken( sal_uInt8 n, sal_Unicode c ) :
+ FormulaToken( svByte, ocWhitespace ),
+ nByte( n ), cChar( c ) {}
+ FormulaSpaceToken( const FormulaSpaceToken& r ) :
+ FormulaToken( r ),
+ nByte( r.nByte ), cChar( r.cChar ) {}
+
+ virtual FormulaToken* Clone() const override { return new FormulaSpaceToken(*this); }
+ virtual sal_uInt8 GetByte() const override;
+ virtual sal_Unicode GetChar() const override;
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+class FORMULA_DLLPUBLIC FormulaByteToken : public FormulaToken
+{
+private:
+ sal_uInt8 nByte;
+ ParamClass eInForceArray;
+protected:
+ FormulaByteToken( OpCode e, sal_uInt8 n, StackVar v, ParamClass c ) :
+ FormulaToken( v,e ), nByte( n ),
+ eInForceArray( c ) {}
+public:
+ FormulaByteToken( OpCode e, sal_uInt8 n, ParamClass c ) :
+ FormulaToken( svByte,e ), nByte( n ),
+ eInForceArray( c ) {}
+ FormulaByteToken( OpCode e, sal_uInt8 n ) :
+ FormulaToken( svByte,e ), nByte( n ),
+ eInForceArray( ParamClass::Unknown ) {}
+ FormulaByteToken( OpCode e ) :
+ FormulaToken( svByte,e ), nByte( 0 ),
+ eInForceArray( ParamClass::Unknown ) {}
+ FormulaByteToken( const FormulaByteToken& r ) :
+ FormulaToken( r ), nByte( r.nByte ),
+ eInForceArray( r.eInForceArray ) {}
+
+ virtual FormulaToken* Clone() const override { return new FormulaByteToken(*this); }
+ virtual sal_uInt8 GetByte() const override;
+ virtual void SetByte( sal_uInt8 n ) override;
+ virtual ParamClass GetInForceArray() const override;
+ virtual void SetInForceArray( ParamClass c ) override;
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+
+// A special token for the FormulaAutoPilot only. Keeps a reference pointer of
+// the token of which it was created for comparison.
+class FORMULA_DLLPUBLIC FormulaFAPToken final : public FormulaByteToken
+{
+private:
+ FormulaTokenRef pOrigToken;
+public:
+ FormulaFAPToken( OpCode e, sal_uInt8 n, FormulaToken* p ) :
+ FormulaByteToken( e, n, svFAP, ParamClass::Unknown ),
+ pOrigToken( p ) {}
+ FormulaFAPToken( const FormulaFAPToken& r ) :
+ FormulaByteToken( r ), pOrigToken( r.pOrigToken ) {}
+
+ virtual FormulaToken* Clone() const override { return new FormulaFAPToken(*this); }
+ virtual FormulaToken* GetFAPOrigToken() const override;
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+class FORMULA_DLLPUBLIC FormulaDoubleToken : public FormulaToken
+{
+private:
+ double fDouble;
+public:
+ FormulaDoubleToken( double f ) :
+ FormulaToken( svDouble ), fDouble( f ) {}
+ FormulaDoubleToken( const FormulaDoubleToken& r ) :
+ FormulaToken( r ), fDouble( r.fDouble ) {}
+
+ virtual FormulaToken* Clone() const override { return new FormulaDoubleToken(*this); }
+ virtual double GetDouble() const override;
+ virtual double& GetDoubleAsReference() override;
+ virtual sal_Int16 GetDoubleType() const override; ///< always returns 0 for "not typed"
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+class FORMULA_DLLPUBLIC FormulaTypedDoubleToken final : public FormulaDoubleToken
+{
+private:
+ sal_Int16 mnType; /**< Can hold, for example, a value
+ of SvNumFormatType, or by
+ contract any other
+ classification. */
+public:
+ FormulaTypedDoubleToken( double f, sal_Int16 nType ) :
+ FormulaDoubleToken( f ), mnType( nType ) {}
+ FormulaTypedDoubleToken( const FormulaTypedDoubleToken& r ) :
+ FormulaDoubleToken( r ), mnType( r.mnType ) {}
+
+ virtual FormulaToken* Clone() const override { return new FormulaTypedDoubleToken(*this); }
+ virtual sal_Int16 GetDoubleType() const override;
+ virtual void SetDoubleType( sal_Int16 nType ) override;
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+
+class FORMULA_DLLPUBLIC FormulaStringToken final : public FormulaToken
+{
+ svl::SharedString maString;
+public:
+ FormulaStringToken( svl::SharedString r );
+ FormulaStringToken( const FormulaStringToken& r );
+
+ virtual FormulaToken* Clone() const override;
+ virtual const svl::SharedString & GetString() const override;
+ virtual void SetString( const svl::SharedString& rStr ) override;
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+
+/** Identical to FormulaStringToken, but with explicit OpCode instead of implicit
+ ocPush, and an optional sal_uInt8 for ocBad tokens. */
+class FORMULA_DLLPUBLIC FormulaStringOpToken final : public FormulaByteToken
+{
+ svl::SharedString maString;
+public:
+ FormulaStringOpToken( OpCode e, svl::SharedString r );
+ FormulaStringOpToken( const FormulaStringOpToken& r );
+
+ virtual FormulaToken* Clone() const override;
+ virtual const svl::SharedString & GetString() const override;
+ virtual void SetString( const svl::SharedString& rStr ) override;
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+class FORMULA_DLLPUBLIC FormulaIndexToken final : public FormulaToken
+{
+private:
+ sal_uInt16 nIndex;
+ sal_Int16 mnSheet;
+public:
+ FormulaIndexToken( OpCode e, sal_uInt16 n, sal_Int16 nSheet = -1 ) :
+ FormulaToken( svIndex, e ), nIndex( n ), mnSheet( nSheet ) {}
+ FormulaIndexToken( const FormulaIndexToken& r ) :
+ FormulaToken( r ), nIndex( r.nIndex ), mnSheet( r.mnSheet ) {}
+
+ virtual FormulaToken* Clone() const override { return new FormulaIndexToken(*this); }
+ virtual sal_uInt16 GetIndex() const override;
+ virtual void SetIndex( sal_uInt16 n ) override;
+ virtual sal_Int16 GetSheet() const override;
+ virtual void SetSheet( sal_Int16 n ) override;
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+
+class FORMULA_DLLPUBLIC FormulaExternalToken final : public FormulaByteToken
+{
+private:
+ OUString aExternal;
+public:
+ FormulaExternalToken( OpCode e, sal_uInt8 n, OUString r ) :
+ FormulaByteToken( e, n, svExternal, ParamClass::Unknown ),
+ aExternal(std::move( r )) {}
+ FormulaExternalToken( OpCode e, OUString r ) :
+ FormulaByteToken( e, 0, svExternal, ParamClass::Unknown ),
+ aExternal(std::move( r )) {}
+ FormulaExternalToken( const FormulaExternalToken& r ) :
+ FormulaByteToken( r ), aExternal( r.aExternal ) {}
+
+ virtual FormulaToken* Clone() const override { return new FormulaExternalToken(*this); }
+ virtual const OUString& GetExternal() const override;
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+
+class FORMULA_DLLPUBLIC FormulaMissingToken final : public FormulaToken
+{
+public:
+ FormulaMissingToken() :
+ FormulaToken( svMissing,ocMissing ) {}
+ FormulaMissingToken( const FormulaMissingToken& r ) :
+ FormulaToken( r ) {}
+
+ virtual FormulaToken* Clone() const override { return new FormulaMissingToken(*this); }
+ virtual double GetDouble() const override;
+ virtual const svl::SharedString & GetString() const override;
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+class FORMULA_DLLPUBLIC FormulaJumpToken final : public FormulaToken
+{
+private:
+ std::unique_ptr<short[]>
+ pJump;
+ ParamClass eInForceArray;
+public:
+ FormulaJumpToken( OpCode e, short const * p ) :
+ FormulaToken( formula::svJump , e),
+ eInForceArray( ParamClass::Unknown)
+ {
+ pJump.reset( new short[ p[0] + 1 ] );
+ memcpy( pJump.get(), p, (p[0] + 1) * sizeof(short) );
+ }
+ FormulaJumpToken( const FormulaJumpToken& r ) :
+ FormulaToken( r ),
+ eInForceArray( r.eInForceArray)
+ {
+ pJump.reset( new short[ r.pJump[0] + 1 ] );
+ memcpy( pJump.get(), r.pJump.get(), (r.pJump[0] + 1) * sizeof(short) );
+ }
+ virtual ~FormulaJumpToken() override;
+ virtual short* GetJump() const override;
+ virtual bool operator==( const formula::FormulaToken& rToken ) const override;
+ virtual FormulaToken* Clone() const override { return new FormulaJumpToken(*this); }
+ virtual ParamClass GetInForceArray() const override;
+ virtual void SetInForceArray( ParamClass c ) override;
+};
+
+
+class FORMULA_DLLPUBLIC FormulaUnknownToken final : public FormulaToken
+{
+public:
+ FormulaUnknownToken( OpCode e ) :
+ FormulaToken( svUnknown, e ) {}
+ FormulaUnknownToken( const FormulaUnknownToken& r ) :
+ FormulaToken( r ) {}
+
+ virtual FormulaToken* Clone() const override { return new FormulaUnknownToken(*this); }
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+
+class FORMULA_DLLPUBLIC FormulaErrorToken final : public FormulaToken
+{
+ FormulaError nError;
+public:
+ FormulaErrorToken( FormulaError nErr ) :
+ FormulaToken( svError ), nError( nErr) {}
+ FormulaErrorToken( const FormulaErrorToken& r ) :
+ FormulaToken( r ), nError( r.nError) {}
+
+ virtual FormulaToken* Clone() const override { return new FormulaErrorToken(*this); }
+ virtual FormulaError GetError() const override;
+ virtual void SetError( FormulaError nErr ) override;
+ virtual bool operator==( const FormulaToken& rToken ) const override;
+};
+
+
+} // formula
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
new file mode 100644
index 0000000000..330543d427
--- /dev/null
+++ b/include/formula/tokenarray.hxx
@@ -0,0 +1,674 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_TOKENARRAY_HXX
+#define INCLUDED_FORMULA_TOKENARRAY_HXX
+
+#include <climits>
+#include <memory>
+#include <ostream>
+#include <type_traits>
+#include <unordered_set>
+#include <unordered_map>
+#include <vector>
+
+#include <formula/ExternalReferenceHelper.hxx>
+#include <formula/formuladllapi.h>
+#include <formula/opcode.hxx>
+#include <formula/token.hxx>
+#include <o3tl/typed_flags_set.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+namespace com::sun::star {
+ namespace sheet { struct FormulaToken; }
+}
+
+namespace com::sun::star::uno { template <typename > class Sequence; }
+namespace formula { class FormulaTokenArray; }
+
+namespace svl {
+
+class SharedString;
+class SharedStringPool;
+
+}
+
+// RecalcMode access only via TokenArray SetExclusiveRecalcMode...() /
+// IsRecalcMode...()
+
+// Only one of the exclusive bits can be set and one must be set,
+// handled by TokenArray SetExclusiveRecalcMode...() methods.
+// Exclusive bits are ordered by priority, AddRecalcMode() relies on that.
+enum class ScRecalcMode : sal_uInt8
+{
+ ALWAYS = 0x01, // exclusive, always
+ ONLOAD_MUST = 0x02, // exclusive, always after load
+ ONLOAD_ONCE = 0x04, // exclusive, once after load, import filter
+ ONLOAD_LENIENT = 0x08, // exclusive, lenient after load (eg. macros not always, aliens, ...)
+ NORMAL = 0x10, // exclusive
+ FORCED = 0x20, // combined, also if cell isn't visible, for macros with side effects
+ ONREFMOVE = 0x40, // combined, if reference was moved
+ EMask = ALWAYS | ONLOAD_MUST | ONLOAD_LENIENT | ONLOAD_ONCE | NORMAL // mask of exclusive bits
+};
+namespace o3tl
+{
+ template<> struct typed_flags<ScRecalcMode> : is_typed_flags<ScRecalcMode, 0x7f> {};
+}
+
+namespace formula
+{
+
+class FORMULA_DLLPUBLIC MissingConvention
+{
+public:
+ enum Convention
+ {
+ FORMULA_MISSING_CONVENTION_PODF,
+ FORMULA_MISSING_CONVENTION_ODFF,
+ FORMULA_MISSING_CONVENTION_OOXML
+ };
+ explicit MissingConvention( Convention eConvention ) : meConvention(eConvention) {}
+ bool isPODF() const { return meConvention == FORMULA_MISSING_CONVENTION_PODF; }
+ bool isODFF() const { return meConvention == FORMULA_MISSING_CONVENTION_ODFF; }
+ bool isOOXML() const { return meConvention == FORMULA_MISSING_CONVENTION_OOXML; }
+ Convention getConvention() const { return meConvention; }
+private:
+ Convention meConvention;
+};
+
+class FORMULA_DLLPUBLIC MissingConventionODF : public MissingConvention
+{
+public:
+ explicit MissingConventionODF( bool bODFF ) :
+ MissingConvention( bODFF ?
+ MissingConvention::FORMULA_MISSING_CONVENTION_ODFF :
+ MissingConvention::FORMULA_MISSING_CONVENTION_PODF)
+ {
+ }
+ // Implementation and usage only in token.cxx
+ inline bool isRewriteNeeded( OpCode eOp ) const;
+};
+
+class FORMULA_DLLPUBLIC MissingConventionOOXML : public MissingConvention
+{
+public:
+ explicit MissingConventionOOXML() : MissingConvention( MissingConvention::FORMULA_MISSING_CONVENTION_OOXML) {}
+ // Implementation and usage only in token.cxx
+ static inline bool isRewriteNeeded( OpCode eOp );
+};
+
+typedef std::unordered_set<OpCode, std::hash<std::underlying_type<OpCode>::type> > unordered_opcode_set;
+
+class FORMULA_DLLPUBLIC FormulaTokenArrayStandardRange
+{
+private:
+ FormulaToken** mpBegin;
+ FormulaToken** mpEnd;
+
+public:
+ FormulaTokenArrayStandardRange(FormulaToken** pBegin, sal_uInt16 nSize) :
+ mpBegin(pBegin),
+ mpEnd(pBegin + nSize)
+ {
+ }
+
+ FormulaToken** begin() const
+ {
+ return mpBegin;
+ }
+
+ FormulaToken** end() const
+ {
+ return mpEnd;
+ }
+};
+
+class FORMULA_DLLPUBLIC FormulaTokenArrayReferencesIterator
+{
+private:
+ FormulaToken** maIter;
+ FormulaToken** maEnd;
+
+ void nextReference()
+ {
+ while (maIter != maEnd)
+ {
+ switch ((*maIter)->GetType())
+ {
+ case svSingleRef:
+ case svDoubleRef:
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ return;
+ default:
+ ++maIter;
+ }
+ }
+ }
+
+ enum class Dummy { Flag };
+
+ FormulaTokenArrayReferencesIterator(const FormulaTokenArrayStandardRange& rRange, Dummy) :
+ maIter(rRange.end()),
+ maEnd(rRange.end())
+ {
+ }
+
+public:
+ FormulaTokenArrayReferencesIterator(const FormulaTokenArrayStandardRange& rRange) :
+ maIter(rRange.begin()),
+ maEnd(rRange.end())
+ {
+ nextReference();
+ }
+
+ FormulaTokenArrayReferencesIterator operator++(int)
+ {
+ FormulaTokenArrayReferencesIterator result(*this);
+ operator++();
+ return result;
+ }
+
+ FormulaTokenArrayReferencesIterator const & operator++()
+ {
+ assert(maIter != maEnd);
+ ++maIter;
+ nextReference();
+ return *this;
+ }
+
+ FormulaToken* operator*() const
+ {
+ return *maIter;
+ }
+
+ bool operator==(const FormulaTokenArrayReferencesIterator& rhs) const
+ {
+ return maIter == rhs.maIter;
+ }
+
+ bool operator!=(const FormulaTokenArrayReferencesIterator& rhs) const
+ {
+ return !operator==(rhs);
+ }
+
+ static FormulaTokenArrayReferencesIterator endOf(const FormulaTokenArrayStandardRange& rRange)
+ {
+ return FormulaTokenArrayReferencesIterator(rRange, Dummy::Flag);
+ }
+};
+
+class FORMULA_DLLPUBLIC FormulaTokenArrayReferencesRange
+{
+private:
+ const FormulaTokenArray& mrFTA;
+
+public:
+ FormulaTokenArrayReferencesRange(const FormulaTokenArray& rFTA) :
+ mrFTA(rFTA)
+ {
+ }
+
+ FormulaTokenArrayReferencesIterator begin();
+
+ FormulaTokenArrayReferencesIterator end();
+};
+
+class FORMULA_DLLPUBLIC FormulaTokenArray
+{
+protected:
+ std::unique_ptr<FormulaToken*[]> pCode; // Token code array
+ FormulaToken** pRPN; // RPN array
+ sal_uInt16 nLen; // Length of token array
+ sal_uInt16 nRPN; // Length of RPN array
+ FormulaError nError; // Error code
+ ScRecalcMode nMode; // Flags to indicate when to recalc this code
+ bool bHyperLink :1; // If HYPERLINK() occurs in the formula.
+ bool mbFromRangeName :1; // If this array originates from a named expression
+ bool mbShareable :1; // Whether or not it can be shared with adjacent cells.
+ bool mbFinalized :1; // Whether code arrays have their final used size and no more tokens can be added.
+
+protected:
+ void Assign( const FormulaTokenArray& );
+ void Assign( sal_uInt16 nCode, FormulaToken **pTokens );
+ void Move( FormulaTokenArray&& );
+
+ /// Also used by the compiler. The token MUST had been allocated with new!
+ FormulaToken* Add( FormulaToken* );
+
+public:
+ enum ReplaceMode
+ {
+ CODE_ONLY, ///< replacement only in pCode
+ CODE_AND_RPN ///< replacement in pCode and pRPN
+ };
+
+ /** Also used by the compiler. The token MUST had been allocated with new!
+ @param nOffset
+ Absolute offset in pCode of the token to be replaced.
+ @param eMode
+ If CODE_ONLY only the token in pCode at nOffset is replaced.
+ If CODE_AND_RPN the token in pCode at nOffset is replaced;
+ if the original token was also referenced in the pRPN array
+ then that reference is replaced with a reference to the new
+ token as well.
+ */
+ FormulaToken* ReplaceToken( sal_uInt16 nOffset, FormulaToken*, ReplaceMode eMode );
+
+ /** Remove a sequence of tokens from pCode array, and pRPN array if the
+ tokens are referenced there.
+
+ nLen and nRPN are adapted.
+
+ @param nOffset
+ Start offset into pCode.
+ @param nCount
+ Count of tokens to remove.
+
+ @return Count of tokens removed.
+ */
+ sal_uInt16 RemoveToken( sal_uInt16 nOffset, sal_uInt16 nCount );
+
+ FormulaTokenArray();
+ /** Assignment with incrementing references of FormulaToken entries
+ (not copied!) */
+ FormulaTokenArray( const FormulaTokenArray& );
+ FormulaTokenArray( FormulaTokenArray&& );
+ virtual ~FormulaTokenArray();
+
+ virtual void Clear();
+
+ /**
+ * The array has its final used size and no more token can be added.
+ */
+ void Finalize();
+
+ void SetFromRangeName( bool b ) { mbFromRangeName = b; }
+ bool IsFromRangeName() const { return mbFromRangeName; }
+
+ void SetShareable( bool b ) { mbShareable = b; }
+
+ /**
+ * Check if this token array is shareable between multiple adjacent
+ * formula cells. Certain tokens may not function correctly when shared.
+ *
+ * @return true if the token array is shareable, false otherwise.
+ */
+ bool IsShareable() const { return mbShareable; }
+
+ void DelRPN();
+ FormulaToken* FirstToken() const;
+
+ /// Return pCode[nIdx], or nullptr if nIdx is out of bounds
+ FormulaToken* TokenAt( sal_uInt16 nIdx) const
+ {
+ if (nIdx >= nLen)
+ return nullptr;
+ return pCode[nIdx];
+ }
+
+ /// Peek at nIdx-1 if not out of bounds, decrements nIdx if successful. Returns NULL if not.
+ FormulaToken* PeekPrev( sal_uInt16 & nIdx ) const;
+
+ /// Return the opcode at pCode[nIdx-1], ocNone if nIdx-1 is out of bounds
+ OpCode OpCodeBefore( sal_uInt16 nIdx) const
+ {
+ if (nIdx == 0 || nIdx > nLen)
+ return ocNone;
+
+ return pCode[nIdx-1]->GetOpCode();
+ }
+
+ FormulaToken* FirstRPNToken() const;
+ FormulaToken* LastRPNToken() const;
+
+ bool HasReferences() const;
+
+ bool HasExternalRef() const;
+ bool HasOpCode( OpCode ) const;
+ bool HasOpCodeRPN( OpCode ) const;
+ /// Token of type svIndex or opcode ocColRowName
+ bool HasNameOrColRowName() const;
+
+ /**
+ * Check if the token array contains any of specified opcode tokens.
+ *
+ * @param rOpCodes collection of opcodes to check against.
+ *
+ * @return true if the token array contains at least one of the specified
+ * opcode tokens, false otherwise.
+ */
+ bool HasOpCodes( const unordered_opcode_set& rOpCodes ) const;
+
+ /// Assign pRPN to point to a newly created array filled with the data from pData
+ void CreateNewRPNArrayFromData( FormulaToken** pData, sal_uInt16 nSize )
+ {
+ pRPN = new FormulaToken*[ nSize ];
+ nRPN = nSize;
+ memcpy( pRPN, pData, nSize * sizeof( FormulaToken* ) );
+ }
+
+ FormulaToken** GetArray() const { return pCode.get(); }
+
+ FormulaTokenArrayStandardRange Tokens() const
+ {
+ return FormulaTokenArrayStandardRange(pCode.get(), nLen);
+ }
+
+ FormulaToken** GetCode() const { return pRPN; }
+
+ FormulaTokenArrayStandardRange RPNTokens() const
+ {
+ return FormulaTokenArrayStandardRange(pRPN, nRPN);
+ }
+
+ FormulaTokenArrayReferencesRange References() const
+ {
+ return FormulaTokenArrayReferencesRange(*this);
+ }
+
+ sal_uInt16 GetLen() const { return nLen; }
+ sal_uInt16 GetCodeLen() const { return nRPN; }
+ FormulaError GetCodeError() const { return nError; }
+ void SetCodeError( FormulaError n ) { nError = n; }
+ void SetHyperLink( bool bVal ) { bHyperLink = bVal; }
+ bool IsHyperLink() const { return bHyperLink; }
+
+ ScRecalcMode GetRecalcMode() const { return nMode; }
+
+ void SetCombinedBitsRecalcMode( ScRecalcMode nBits )
+ { nMode |= nBits & ~ScRecalcMode::EMask; }
+ ScRecalcMode GetCombinedBitsRecalcMode() const
+ { return nMode & ~ScRecalcMode::EMask; }
+
+ /** Exclusive bits already set in nMode are zero'ed, nBits
+ may contain combined bits, but only one exclusive bit
+ may be set! */
+ void SetMaskedRecalcMode( ScRecalcMode nBits )
+ { nMode = GetCombinedBitsRecalcMode() | nBits; }
+
+ /** Bits aren't set directly but validated and handled
+ according to priority if more than one exclusive bit
+ was set. */
+ void AddRecalcMode( ScRecalcMode nBits );
+
+ void ClearRecalcMode() { nMode = ScRecalcMode::NORMAL; }
+ void SetExclusiveRecalcModeNormal()
+ { SetMaskedRecalcMode( ScRecalcMode::NORMAL ); }
+ void SetExclusiveRecalcModeAlways()
+ { SetMaskedRecalcMode( ScRecalcMode::ALWAYS ); }
+ void SetRecalcModeForced()
+ { nMode |= ScRecalcMode::FORCED; }
+ void SetRecalcModeOnRefMove()
+ { nMode |= ScRecalcMode::ONREFMOVE; }
+ bool IsRecalcModeNormal() const
+ { return bool(nMode & ScRecalcMode::NORMAL); }
+ bool IsRecalcModeAlways() const
+ { return bool(nMode & ScRecalcMode::ALWAYS); }
+ bool IsRecalcModeForced() const
+ { return bool(nMode & ScRecalcMode::FORCED); }
+ bool IsRecalcModeOnRefMove() const
+ { return bool(nMode & ScRecalcMode::ONREFMOVE); }
+ /** Whether recalculation must happen after import, for
+ example OOXML. */
+ bool IsRecalcModeMustAfterImport() const
+ { return (nMode & ScRecalcMode::EMask) <= ScRecalcMode::ONLOAD_ONCE; }
+ void ClearRecalcModeMustAfterImport()
+ {
+ if (IsRecalcModeMustAfterImport() && !IsRecalcModeAlways())
+ SetExclusiveRecalcModeNormal();
+ }
+
+ /** Get OpCode of the most outer function */
+ inline OpCode GetOuterFuncOpCode() const;
+
+ /** Operators +,-,*,/,^,&,=,<>,<,>,<=,>=
+ with DoubleRef in Formula? */
+ bool HasMatrixDoubleRefOps() const;
+
+ virtual FormulaToken* AddOpCode(OpCode e);
+
+ /** Adds the single token to array.
+ Derived classes must override it when they want to support derived classes from FormulaToken.
+ @return true when an error occurs
+ */
+ virtual bool AddFormulaToken(
+ const css::sheet::FormulaToken& rToken, svl::SharedStringPool& rSPool,
+ ExternalReferenceHelper* pExtRef );
+
+ /** fill the array with the tokens from the sequence.
+ It calls AddFormulaToken for each token in the list.
+ @param _aSequence the token to add
+ @return true when an error occurs
+ */
+ bool Fill(
+ const css::uno::Sequence<css::sheet::FormulaToken>& rSequence,
+ svl::SharedStringPool& rSPool, ExternalReferenceHelper* pExtRef );
+
+ /**
+ * Do some checking based on the individual tokens. For now, we use this
+ * only to check whether we can vectorize the token array.
+ */
+ virtual void CheckToken( const FormulaToken& t );
+
+ /**
+ * Call CheckToken() for all RPN tokens.
+ */
+ void CheckAllRPNTokens();
+
+ /** Clones the token and then adds the clone to the pCode array.
+ For just new'ed tokens use Add() instead of cloning it again.
+ Use this AddToken() when adding a token from another origin.
+ */
+ FormulaToken* AddToken( const FormulaToken& );
+
+ FormulaToken* AddString( const svl::SharedString& rStr );
+ FormulaToken* AddDouble( double fVal );
+ void AddExternal( const sal_Unicode* pStr );
+ /** Xcl import may play dirty tricks with OpCode!=ocExternal.
+ Others don't use! */
+ FormulaToken* AddExternal( const OUString& rStr, OpCode eOp = ocExternal );
+ FormulaToken* AddBad( const OUString& rStr ); /// ocBad with OUString
+ FormulaToken* AddStringXML( const OUString& rStr ); /// ocStringXML with OUString, temporary during import
+
+ virtual FormulaToken* MergeArray( );
+
+ /** Assignment with incrementing references of FormulaToken entries
+ (not copied!) */
+ FormulaTokenArray& operator=( const FormulaTokenArray& );
+ FormulaTokenArray& operator=( FormulaTokenArray&& );
+
+ /** Determines if this formula needs any changes to convert it to something
+ previous versions of OOo could consume (Plain Old Formula, pre-ODFF, or
+ also ODFF) */
+ bool NeedsPodfRewrite( const MissingConventionODF & rConv );
+
+ /** Determines if this formula needs any changes to convert it to OOXML. */
+ bool NeedsOoxmlRewrite();
+
+ /** Rewrites to Plain Old Formula or OOXML, substituting missing parameters. The
+ FormulaTokenArray* returned is new'ed. */
+ FormulaTokenArray* RewriteMissing( const MissingConvention & rConv );
+
+ /** Determines if this formula may be followed by a reference. */
+ bool MayReferenceFollow();
+
+ /** Re-intern SharedString in case the SharedStringPool differs. */
+ void ReinternStrings( svl::SharedStringPool& rPool );
+};
+
+inline OpCode FormulaTokenArray::GetOuterFuncOpCode() const
+{
+ if ( pRPN && nRPN )
+ return pRPN[nRPN-1]->GetOpCode();
+ return ocNone;
+}
+
+inline FormulaTokenArrayReferencesIterator FormulaTokenArrayReferencesRange::begin()
+{
+ return FormulaTokenArrayReferencesIterator(mrFTA.Tokens());
+}
+
+inline FormulaTokenArrayReferencesIterator FormulaTokenArrayReferencesRange::end()
+{
+ return FormulaTokenArrayReferencesIterator::endOf(mrFTA.Tokens());
+}
+
+class FORMULA_DLLPUBLIC FormulaTokenIterator
+{
+ struct Item
+ {
+ public:
+ const FormulaTokenArray* pArr;
+ short nPC;
+ short nStop;
+
+ Item(const FormulaTokenArray* arr, short pc, short stop);
+ };
+
+ std::vector<Item> maStack;
+
+public:
+ FormulaTokenIterator( const FormulaTokenArray& );
+ ~FormulaTokenIterator();
+ void Reset();
+ const FormulaToken* Next();
+ const FormulaToken* PeekNextOperator();
+ bool IsEndOfPath() const; /// if a jump or subroutine path is done
+ bool HasStacked() const { return maStack.size() > 1; }
+ short GetPC() const { return maStack.back().nPC; }
+
+ /** Jump or subroutine call.
+ Program counter values will be incremented before code is executed =>
+ positions are to be passed with -1 offset.
+ @param nStart
+ Start on code at position nStart+1 (yes, pass with offset -1)
+ @param nNext
+ After subroutine continue with instruction at position nNext+1
+ @param nStop
+ Stop before reaching code at position nStop. If not specified the
+ default is to either run the entire code, or to stop if an ocSep or
+ ocClose is encountered, which are only present in ocIf or ocChoose
+ jumps.
+ */
+ void Jump( short nStart, short nNext, short nStop = SHRT_MAX );
+ void Push( const FormulaTokenArray* );
+ void Pop();
+
+ /** Reconstruct the iterator afresh from a token array
+ */
+ void ReInit( const FormulaTokenArray& );
+
+private:
+ const FormulaToken* GetNonEndOfPathToken( short nIdx ) const;
+};
+
+// For use in SAL_INFO, SAL_WARN etc
+
+template<typename charT, typename traits>
+inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const FormulaTokenArray& point)
+{
+ stream <<
+ static_cast<const void*>(&point) <<
+ ":{nLen=" << point.GetLen() <<
+ ",nRPN=" << point.GetCodeLen() <<
+ ",pCode=" << static_cast<void*>(point.GetArray()) <<
+ ",pRPN=" << static_cast<void*>(point.GetCode()) <<
+ "}";
+
+ return stream;
+}
+
+class FORMULA_DLLPUBLIC FormulaTokenArrayPlainIterator
+{
+private:
+ const FormulaTokenArray* mpFTA;
+ sal_uInt16 mnIndex; // Current step index
+
+public:
+ FormulaTokenArrayPlainIterator( const FormulaTokenArray& rFTA ) :
+ mpFTA( &rFTA ),
+ mnIndex( 0 )
+ {
+ }
+
+ void Reset()
+ {
+ mnIndex = 0;
+ }
+
+ sal_uInt16 GetIndex() const
+ {
+ return mnIndex;
+ }
+
+ FormulaToken* First()
+ {
+ mnIndex = 0;
+ return Next();
+ }
+
+ void Jump(sal_uInt16 nIndex)
+ {
+ mnIndex = nIndex;
+ }
+
+ void StepBack()
+ {
+ assert(mnIndex > 0);
+ mnIndex--;
+ }
+
+ FormulaToken* Next();
+ FormulaToken* NextNoSpaces();
+ FormulaToken* GetNextName();
+ FormulaToken* GetNextReference();
+ FormulaToken* GetNextReferenceRPN();
+ FormulaToken* GetNextReferenceOrName();
+ FormulaToken* GetNextColRowName();
+ FormulaToken* PeekNext();
+ FormulaToken* PeekPrevNoSpaces() const; /// Only after Reset/First/Next/Last/Prev!
+ FormulaToken* PeekNextNoSpaces() const; /// Only after Reset/First/Next/Last/Prev!
+
+ FormulaToken* FirstRPN()
+ {
+ mnIndex = 0;
+ return NextRPN();
+ }
+
+ FormulaToken* NextRPN();
+
+ FormulaToken* LastRPN()
+ {
+ mnIndex = mpFTA->GetCodeLen();
+ return PrevRPN();
+ }
+
+ FormulaToken* PrevRPN();
+
+ void AfterRemoveToken( sal_uInt16 nOffset, sal_uInt16 nCount );
+};
+
+
+} // formula
+
+#endif // INCLUDED_FORMULA_TOKENARRAY_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/types.hxx b/include/formula/types.hxx
new file mode 100644
index 0000000000..c0c8b64c24
--- /dev/null
+++ b/include/formula/types.hxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_FORMULA_TYPES_HXX
+#define INCLUDED_FORMULA_TYPES_HXX
+
+#include <boost/intrusive_ptr.hpp>
+
+namespace formula
+{
+class FormulaToken;
+typedef ::boost::intrusive_ptr<FormulaToken> FormulaTokenRef;
+typedef ::boost::intrusive_ptr<const FormulaToken> FormulaConstTokenRef;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/vectortoken.hxx b/include/formula/vectortoken.hxx
new file mode 100644
index 0000000000..046d71faf3
--- /dev/null
+++ b/include/formula/vectortoken.hxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_FORMULA_VECTORTOKEN_HXX
+#define INCLUDED_FORMULA_VECTORTOKEN_HXX
+
+#include <cstddef>
+#include <vector>
+
+#include <formula/formuladllapi.h>
+#include <formula/token.hxx>
+#include <rtl/ustring.h>
+
+namespace formula {
+
+/**
+ * Single unit of vector reference consists of two physical arrays.
+ *
+ * <p>If the whole data array consists of only numeric values, mpStringArray
+ * will be NULL, and NaN values in the numeric array represent empty
+ * cells.</p>
+ *
+ * <p>If the whole data array consists of only string values, mpNumericArray
+ * will be NULL, and NULL values in the string array represent empty
+ * cells.</p>
+ *
+ * <p>If the data array consists of numeric and string values, then both
+ * mpNumericArray and mpStringArray will be non-NULL, and a string cell will
+ * be represented by a non-NULL pointer value in the string array. If the
+ * string value is NULL, check the corresponding value in the numeric array.
+ * If the value in the numeric array is NaN, it's an empty cell, otherwise
+ * it's a numeric cell.</p>
+ */
+struct FORMULA_DLLPUBLIC VectorRefArray
+{
+ enum InitInvalid { Invalid };
+
+ const double* mpNumericArray;
+ rtl_uString** mpStringArray;
+
+ bool mbValid;
+
+ VectorRefArray();
+ VectorRefArray( InitInvalid );
+ VectorRefArray( const double* pArray );
+ VectorRefArray( rtl_uString** pArray );
+ VectorRefArray( const double* pNumArray, rtl_uString** pStrArray );
+
+ bool isValid() const;
+};
+
+/**
+ * This token represents a single cell reference in a vectorized formula
+ * calculation context.
+ */
+class FORMULA_DLLPUBLIC SingleVectorRefToken final : public FormulaToken
+{
+ VectorRefArray maArray;
+ size_t mnArrayLength;
+
+public:
+ SingleVectorRefToken( const VectorRefArray& rArray, size_t nArrayLength );
+
+ virtual FormulaToken* Clone() const override;
+
+ const VectorRefArray& GetArray() const;
+ size_t GetArrayLength() const;
+};
+
+/**
+ * This token represents a range reference in a vectorized formula
+ * calculation context.
+ */
+class FORMULA_DLLPUBLIC DoubleVectorRefToken final : public FormulaToken
+{
+ std::vector<VectorRefArray> maArrays;
+
+ size_t mnArrayLength; /// length of all arrays which does not include trailing empty region.
+ size_t mnRefRowSize; /// original reference row size. The row size may
+ /// change as it goes down the array if either the
+ /// start or end position is fixed.
+
+ bool mbStartFixed:1; /// whether or not the start row position is absolute.
+ bool mbEndFixed:1; /// whether or not the end row position is absolute.
+
+public:
+ DoubleVectorRefToken(
+ std::vector<VectorRefArray>&& rArrays, size_t nArrayLength,
+ size_t nRefRowSize, bool bStartFixed, bool bEndFixed );
+
+ virtual FormulaToken* Clone() const override;
+
+ const std::vector<VectorRefArray>& GetArrays() const;
+ size_t GetArrayLength() const;
+ size_t GetRefRowSize() const;
+ bool IsStartFixed() const;
+ bool IsEndFixed() const;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */