summaryrefslogtreecommitdiff
path: root/formula/inc/formula/tokenarray.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'formula/inc/formula/tokenarray.hxx')
-rw-r--r--formula/inc/formula/tokenarray.hxx286
1 files changed, 286 insertions, 0 deletions
diff --git a/formula/inc/formula/tokenarray.hxx b/formula/inc/formula/tokenarray.hxx
new file mode 100644
index 000000000000..fc379fc4bb05
--- /dev/null
+++ b/formula/inc/formula/tokenarray.hxx
@@ -0,0 +1,286 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef FORMULA_TOKENARRAY_HXX
+#define FORMULA_TOKENARRAY_HXX
+
+#include "formula/token.hxx"
+#include "formula/ExternalReferenceHelper.hxx"
+#include <tools/solar.h>
+#include <com/sun/star/sheet/FormulaToken.hpp>
+
+#include <limits.h>
+
+namespace formula
+{
+
+// RecalcMode access only via TokenArray SetRecalcMode / IsRecalcMode...
+
+typedef BYTE ScRecalcMode;
+// Only one of the exclusive bits can be set,
+// handled by TokenArray SetRecalcMode... methods
+#define RECALCMODE_NORMAL 0x01 // exclusive
+#define RECALCMODE_ALWAYS 0x02 // exclusive, always
+#define RECALCMODE_ONLOAD 0x04 // exclusive, always after load
+#define RECALCMODE_ONLOAD_ONCE 0x08 // exclusive, once after load
+#define RECALCMODE_FORCED 0x10 // combined, also if cell isn't visible
+#define RECALCMODE_ONREFMOVE 0x20 // combined, if reference was moved
+#define RECALCMODE_EMASK 0x0F // mask of exclusive bits
+// If new bits are to be defined, AddRecalcMode has to be adjusted!
+
+class FormulaMissingContext;
+
+class FORMULA_DLLPUBLIC MissingConvention
+{
+ bool mbODFF; /// TRUE: ODFF, FALSE: PODF
+public:
+ explicit MissingConvention( bool bODFF ) : mbODFF(bODFF) {}
+ // Implementation and usage only in token.cxx
+ inline bool isRewriteNeeded( OpCode eOp ) const;
+ inline bool isODFF() const { return mbODFF; }
+};
+
+class FORMULA_DLLPUBLIC FormulaTokenArray
+{
+ friend class FormulaCompiler;
+ friend class FormulaTokenIterator;
+ friend class FormulaMissingContext;
+
+protected:
+ FormulaToken** pCode; // Token code array
+ FormulaToken** pRPN; // RPN array
+ USHORT nLen; // Length of token array
+ USHORT nRPN; // Length of RPN array
+ USHORT nIndex; // Current step index
+ USHORT nError; // Error code
+ short nRefs; // Count of cell references
+ ScRecalcMode nMode; // Flags to indicate when to recalc this code
+ BOOL bHyperLink; // If HYPERLINK() occurs in the formula.
+
+protected:
+ void Assign( const FormulaTokenArray& );
+
+ /// Also used by the compiler. The token MUST had been allocated with new!
+ FormulaToken* Add( FormulaToken* );
+ inline void SetCombinedBitsRecalcMode( ScRecalcMode nBits )
+ { nMode |= (nBits & ~RECALCMODE_EMASK); }
+ inline ScRecalcMode GetCombinedBitsRecalcMode() const
+ { return nMode & ~RECALCMODE_EMASK; }
+ /** Exclusive bits already set in nMode are
+ zero'ed, nVal may contain combined bits, but
+ only one exclusive bit may be set! */
+ inline void SetMaskedRecalcMode( ScRecalcMode nBits )
+ { nMode = GetCombinedBitsRecalcMode() | nBits; }
+
+public:
+ FormulaTokenArray();
+ /// Assignment with references to FormulaToken entries (not copied!)
+ FormulaTokenArray( const FormulaTokenArray& );
+ virtual ~FormulaTokenArray();
+ FormulaTokenArray* Clone() const; /// True copy!
+ void Clear();
+ void DelRPN();
+ FormulaToken* First() { nIndex = 0; return Next(); }
+ FormulaToken* Next();
+ FormulaToken* FirstNoSpaces() { nIndex = 0; return NextNoSpaces(); }
+ FormulaToken* NextNoSpaces();
+ FormulaToken* GetNextName();
+ FormulaToken* GetNextDBArea();
+ FormulaToken* GetNextReference();
+ FormulaToken* GetNextReferenceRPN();
+ FormulaToken* GetNextReferenceOrName();
+ FormulaToken* GetNextColRowName();
+ FormulaToken* GetNextOpCodeRPN( OpCode );
+ /// Peek at nIdx-1 if not out of bounds, decrements nIdx if successful. Returns NULL if not.
+ FormulaToken* PeekPrev( USHORT & nIdx );
+ FormulaToken* PeekNext();
+ FormulaToken* PeekPrevNoSpaces(); /// Only after Reset/First/Next/Last/Prev!
+ FormulaToken* PeekNextNoSpaces(); /// Only after Reset/First/Next/Last/Prev!
+ FormulaToken* FirstRPN() { nIndex = 0; return NextRPN(); }
+ FormulaToken* NextRPN();
+ FormulaToken* LastRPN() { nIndex = nRPN; return PrevRPN(); }
+ FormulaToken* PrevRPN();
+
+ BOOL HasOpCode( OpCode ) const;
+ BOOL HasOpCodeRPN( OpCode ) const;
+ /// Token of type svIndex or opcode ocColRowName
+ BOOL HasNameOrColRowName() const;
+
+ FormulaToken** GetArray() const { return pCode; }
+ FormulaToken** GetCode() const { return pRPN; }
+ USHORT GetLen() const { return nLen; }
+ USHORT GetCodeLen() const { return nRPN; }
+ void Reset() { nIndex = 0; }
+ USHORT GetCodeError() const { return nError; }
+ void SetCodeError( USHORT n ) { nError = n; }
+ short GetRefs() const { return nRefs; }
+ void IncrementRefs() { ++nRefs; }
+ void SetHyperLink( BOOL bVal ) { bHyperLink = bVal; }
+ BOOL IsHyperLink() const { return bHyperLink; }
+
+ inline ScRecalcMode GetRecalcMode() const { return nMode; }
+ /** Bits aren't set directly but validated and
+ maybe handled according to priority if more
+ than one exclusive bit was set. */
+ void AddRecalcMode( ScRecalcMode nBits );
+
+ inline void ClearRecalcMode() { nMode = RECALCMODE_NORMAL; }
+ inline void SetRecalcModeNormal()
+ { SetMaskedRecalcMode( RECALCMODE_NORMAL ); }
+ inline void SetRecalcModeAlways()
+ { SetMaskedRecalcMode( RECALCMODE_ALWAYS ); }
+ inline void SetRecalcModeOnLoad()
+ { SetMaskedRecalcMode( RECALCMODE_ONLOAD ); }
+ inline void SetRecalcModeOnLoadOnce()
+ { SetMaskedRecalcMode( RECALCMODE_ONLOAD_ONCE ); }
+ inline void SetRecalcModeForced()
+ { nMode |= RECALCMODE_FORCED; }
+ inline void ClearRecalcModeForced()
+ { nMode &= ~RECALCMODE_FORCED; }
+ inline void SetRecalcModeOnRefMove()
+ { nMode |= RECALCMODE_ONREFMOVE; }
+ inline void ClearRecalcModeOnRefMove()
+ { nMode &= ~RECALCMODE_ONREFMOVE; }
+ inline BOOL IsRecalcModeNormal() const
+ { return (nMode & RECALCMODE_NORMAL) != 0; }
+ inline BOOL IsRecalcModeAlways() const
+ { return (nMode & RECALCMODE_ALWAYS) != 0; }
+ inline BOOL IsRecalcModeOnLoad() const
+ { return (nMode & RECALCMODE_ONLOAD) != 0; }
+ inline BOOL IsRecalcModeOnLoadOnce() const
+ { return (nMode & RECALCMODE_ONLOAD_ONCE) != 0; }
+ inline BOOL IsRecalcModeForced() const
+ { return (nMode & RECALCMODE_FORCED) != 0; }
+ inline BOOL IsRecalcModeOnRefMove() const
+ { return (nMode & RECALCMODE_ONREFMOVE) != 0; }
+
+ /** Get OpCode of the most outer function */
+ inline OpCode GetOuterFuncOpCode();
+
+ /** Operators +,-,*,/,^,&,=,<>,<,>,<=,>=
+ with DoubleRef in Formula? */
+ BOOL HasMatrixDoubleRefOps();
+
+ virtual FormulaToken* AddOpCode(OpCode e);
+
+ /** Adds the single token to array.
+ Derived classes must overload it when they want to support derived classes from FormulaToken.
+ @return true when an error occurs
+ */
+ virtual bool AddFormulaToken(const com::sun::star::sheet::FormulaToken& _aToken, ExternalReferenceHelper* _pRef = NULL);
+
+ /** 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 com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& _aSequence, ExternalReferenceHelper* _pRef = NULL);
+
+ FormulaToken* AddToken( const FormulaToken& );
+ FormulaToken* AddString( const sal_Unicode* pStr );
+ FormulaToken* AddString( const String& rStr );
+ FormulaToken* AddDouble( double fVal );
+ FormulaToken* AddName( USHORT n );
+ FormulaToken* AddExternal( const sal_Unicode* pStr );
+ /** Xcl import may play dirty tricks with OpCode!=ocExternal.
+ Others don't use! */
+ FormulaToken* AddExternal( const String& rStr, OpCode eOp = ocExternal );
+ FormulaToken* AddBad( const sal_Unicode* pStr ); /// ocBad with String
+ FormulaToken* AddBad( const String& rStr ); /// ocBad with String
+
+ virtual FormulaToken* MergeArray( );
+
+ /// Assignment with references to 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). */
+ bool NeedsPofRewrite(const MissingConvention & rConv);
+
+ /** Rewrites to Plain Old Formula, substituting missing parameters. The
+ FormulaTokenArray* returned is new'ed. */
+ FormulaTokenArray* RewriteMissingToPof(const MissingConvention & rConv);
+
+ /** Determines if this formula may be followed by a reference. */
+ bool MayReferenceFollow();
+};
+
+inline OpCode FormulaTokenArray::GetOuterFuncOpCode()
+{
+ if ( pRPN && nRPN )
+ return pRPN[nRPN-1]->GetOpCode();
+ return ocNone;
+}
+
+struct ImpTokenIterator
+{
+ ImpTokenIterator* pNext;
+ const FormulaTokenArray* pArr;
+ short nPC;
+ short nStop;
+
+ DECL_FIXEDMEMPOOL_NEWDEL( ImpTokenIterator );
+};
+
+class FORMULA_DLLPUBLIC FormulaTokenIterator
+{
+ ImpTokenIterator* pCur;
+
+public:
+ FormulaTokenIterator( const FormulaTokenArray& );
+ ~FormulaTokenIterator();
+ void Reset();
+ const FormulaToken* First();
+ const FormulaToken* Next();
+ bool IsEndOfPath() const; /// if a jump or subroutine path is done
+ bool HasStacked() const { return pCur->pNext != 0; }
+ short GetPC() const { return pCur->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 ocChose
+ jumps.
+ */
+ void Jump( short nStart, short nNext, short nStop = SHRT_MAX );
+ void Push( const FormulaTokenArray* );
+ void Pop();
+};
+// =============================================================================
+} // formula
+// =============================================================================
+
+
+#endif // FORMULA_TOKENARRAY_HXX
+