diff options
Diffstat (limited to '')
-rw-r--r-- | include/formula/ExternalReferenceHelper.hxx | 44 | ||||
-rw-r--r-- | include/formula/FormulaCompiler.hxx | 446 | ||||
-rw-r--r-- | include/formula/FormulaOpCodeMapperObj.hxx | 84 | ||||
-rw-r--r-- | include/formula/IControlReferenceHandler.hxx | 44 | ||||
-rw-r--r-- | include/formula/IFunctionDescription.hxx | 165 | ||||
-rw-r--r-- | include/formula/compiler.hxx | 530 | ||||
-rw-r--r-- | include/formula/errorcodes.hxx | 188 | ||||
-rw-r--r-- | include/formula/formdata.hxx | 71 | ||||
-rw-r--r-- | include/formula/formula.hxx | 126 | ||||
-rw-r--r-- | include/formula/formuladllapi.h | 34 | ||||
-rw-r--r-- | include/formula/formulahelper.hxx | 86 | ||||
-rw-r--r-- | include/formula/funcutl.hxx | 173 | ||||
-rw-r--r-- | include/formula/funcvarargs.h | 49 | ||||
-rw-r--r-- | include/formula/grammar.hxx | 234 | ||||
-rw-r--r-- | include/formula/opcode.hxx | 993 | ||||
-rw-r--r-- | include/formula/paramclass.hxx | 81 | ||||
-rw-r--r-- | include/formula/token.hxx | 466 | ||||
-rw-r--r-- | include/formula/tokenarray.hxx | 665 | ||||
-rw-r--r-- | include/formula/types.hxx | 35 | ||||
-rw-r--r-- | include/formula/vectortoken.hxx | 110 |
20 files changed, 4624 insertions, 0 deletions
diff --git a/include/formula/ExternalReferenceHelper.hxx b/include/formula/ExternalReferenceHelper.hxx new file mode 100644 index 000000000..364307f63 --- /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 000000000..ecc9e5dd3 --- /dev/null +++ b/include/formula/FormulaCompiler.hxx @@ -0,0 +1,446 @@ +/* -*- 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; + sal_uInt16 nIndex; + FormulaTokenRef mpLastToken; + 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 + + 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) ) + { + } + + /** 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; } + + /// 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, + failing silently if rAddIn name already exists. */ + 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; + + /** Get OpCodeMap for formula language. + @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; + + /** 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() {} + + 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) + +private: + void InitSymbolsNative() const; /// only SymbolsNative, on first document creation + void InitSymbolsEnglish() const; /// only SymbolsEnglish, maybe later + void InitSymbolsPODF() const; /// only SymbolsPODF, on demand + void InitSymbolsAPI() const; /// only SymbolsAPI, on demand + void InitSymbolsODFF() const; /// only SymbolsODFF, on demand + void InitSymbolsEnglishXL() const; /// only SymbolsEnglishXL, on demand + void InitSymbolsOOXML() 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 000000000..bd0595d43 --- /dev/null +++ b/include/formula/FormulaOpCodeMapperObj.hxx @@ -0,0 +1,84 @@ +/* -*- 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/Reference.hxx> +#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: + static OUString getImplementationName_Static(); + static css::uno::Sequence< OUString> getSupportedServiceNames_Static(); + static css::uno::Reference< css::uno::XInterface > create(const css::uno::Reference< css::uno::XComponentContext >& _xContext); + +protected: + 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 000000000..e1096c47a --- /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 000000000..b27907fed --- /dev/null +++ b/include/formula/IFunctionDescription.hxx @@ -0,0 +1,165 @@ +/* -*- 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/string.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: + IFunctionManager(){} + 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: + IFunctionCategory(){} + 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: + IFunctionDescription(){} + 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 OString 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: + IFormulaEditorHelper(){} + 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 000000000..baf3e23f6 --- /dev/null +++ b/include/formula/compiler.hxx @@ -0,0 +1,530 @@ +/* -*- 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_MAT_REF 17 +#define SC_OPCODE_DB_AREA 18 /* additional access operators */ +#define SC_OPCODE_TABLE_REF 19 +#define SC_OPCODE_MACRO 20 +#define SC_OPCODE_COL_ROW_NAME 21 +#define SC_OPCODE_COL_ROW_NAME_AUTO 22 +#define SC_OPCODE_PERCENT_SIGN 23 /* operator _follows_ value */ +#define SC_OPCODE_ARRAY_OPEN 24 +#define SC_OPCODE_ARRAY_CLOSE 25 +#define SC_OPCODE_ARRAY_ROW_SEP 26 +#define SC_OPCODE_ARRAY_COL_SEP 27 /* some convs use sep != col_sep */ +#define SC_OPCODE_TABLE_REF_OPEN 28 +#define SC_OPCODE_TABLE_REF_CLOSE 29 +#define SC_OPCODE_TABLE_REF_ITEM_ALL 30 +#define SC_OPCODE_TABLE_REF_ITEM_HEADERS 31 +#define SC_OPCODE_TABLE_REF_ITEM_DATA 32 +#define SC_OPCODE_TABLE_REF_ITEM_TOTALS 33 +#define SC_OPCODE_TABLE_REF_ITEM_THIS_ROW 34 +#define SC_OPCODE_STOP_DIV 35 +#define SC_OPCODE_SKIP 36 /* 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 000000000..12696bb05 --- /dev/null +++ b/include/formula/errorcodes.hxx @@ -0,0 +1,188 @@ +/* -*- 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 <rtl/math.hxx> +#include <sal/mathconf.h> +#include <sal/types.h> + +// 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; + ::rtl::math::setNan( &smVal.value ); + 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 000000000..1df42c2e9 --- /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 000000000..dd4586c29 --- /dev/null +++ b/include/formula/formula.hxx @@ -0,0 +1,126 @@ +/* -*- 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> +#include <tools/link.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 000000000..7b011a6d7 --- /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 000000000..02f757dc3 --- /dev/null +++ b/include/formula/formulahelper.hxx @@ -0,0 +1,86 @@ +/* -*- 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 <memory> +#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 + { + ::std::unique_ptr<SvtSysLocale> m_pSysLocale; + const CharClass* m_pCharClass; + 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_pCharClass; } + + 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 ( const OUString& rFormula, sal_Int32 nStart ) const; + + sal_Int32 GetArgStart ( const OUString& rFormula, sal_Int32 nStart, + sal_uInt16 nArg ) const; + + void GetArgStrings ( ::std::vector< OUString >& _rArgs, + const OUString& rFormula, + sal_Int32 nFuncPos, + sal_uInt16 nArgs ) const; + + void FillArgStrings ( const OUString& 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 000000000..02cf585a7 --- /dev/null +++ b/include/formula/funcutl.hxx @@ -0,0 +1,173 @@ +/* -*- 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; + +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; + Link<RefEdit&,void> maGetFocusHdl; + Link<RefEdit&,void> maLoseFocusHdl; + Link<RefEdit&,void> maModifyHdl; + Link<weld::Widget&,bool> maActivateHdl; + + DECL_LINK( UpdateHdl, Timer*, void ); + +protected: + DECL_LINK(KeyInputHdl, const KeyEvent&, bool); + DECL_LINK(GetFocus, weld::Widget&, void); + DECL_LINK(LoseFocus, weld::Widget&, void); + DECL_LINK(Modify, weld::Entry&, void); + + 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_LINK(KeyInput, const KeyEvent&, bool); + DECL_LINK(GetFocus, weld::Widget&, void); + DECL_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 000000000..ed529ee98 --- /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 000000000..5d7933dee --- /dev/null +++ b/include/formula/grammar.hxx @@ -0,0 +1,234 @@ +/* -*- 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 chose, 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 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 000000000..3123e8f3f --- /dev/null +++ b/include/formula/opcode.hxx @@ -0,0 +1,993 @@ +/* -*- 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, + 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 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 000000000..30773c35e --- /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 000000000..02bffd6a0 --- /dev/null +++ b/include/formula/token.hxx @@ -0,0 +1,466 @@ +/* -*- 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 <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 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 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 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( const svl::SharedString& r ); + FormulaStringToken( const FormulaStringToken& r ); + + virtual FormulaToken* Clone() const override; + virtual 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, const svl::SharedString& r ); + FormulaStringOpToken( const FormulaStringOpToken& r ); + + virtual FormulaToken* Clone() const override; + virtual 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 FormulaToken +{ +private: + OUString aExternal; + sal_uInt8 nByte; +public: + FormulaExternalToken( OpCode e, sal_uInt8 n, const OUString& r ) : + FormulaToken( svExternal, e ), aExternal( r ), + nByte( n ) {} + FormulaExternalToken( OpCode e, const OUString& r ) : + FormulaToken(svExternal, e ), aExternal( r ), + nByte( 0 ) {} + FormulaExternalToken( const FormulaExternalToken& r ) : + FormulaToken( r ), aExternal( r.aExternal ), + nByte( r.nByte ) {} + + virtual FormulaToken* Clone() const override { return new FormulaExternalToken(*this); } + virtual const OUString& GetExternal() const override; + virtual sal_uInt8 GetByte() const override; + virtual void SetByte( sal_uInt8 n ) 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 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 000000000..87377cb22 --- /dev/null +++ b/include/formula/tokenarray.hxx @@ -0,0 +1,665 @@ +/* -*- 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 ); + + /// 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& ); + 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; + + 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; } + + /** 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& ); + + /** 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 000000000..c9e29929b --- /dev/null +++ b/include/formula/types.hxx @@ -0,0 +1,35 @@ +/* -*- 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 000000000..26830bf65 --- /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( + const 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: */ |