1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #ifndef INCLUDED_FORMULA_TOKENARRAY_HXX
21 #define INCLUDED_FORMULA_TOKENARRAY_HXX
22 
23 #include <climits>
24 #include <memory>
25 #include <ostream>
26 #include <type_traits>
27 #include <unordered_set>
28 #include <unordered_map>
29 #include <vector>
30 
31 #include <formula/ExternalReferenceHelper.hxx>
32 #include <formula/formuladllapi.h>
33 #include <formula/opcode.hxx>
34 #include <formula/token.hxx>
35 #include <o3tl/typed_flags_set.hxx>
36 #include <rtl/ustring.hxx>
37 #include <sal/types.h>
38 
39 namespace com { namespace sun { namespace star {
40     namespace sheet { struct FormulaToken; }
41 } } }
42 
43 namespace com::sun::star::uno { template <typename > class Sequence; }
44 namespace formula { class FormulaTokenArray; }
45 
46 namespace svl {
47 
48 class SharedString;
49 class SharedStringPool;
50 
51 }
52 
53 // RecalcMode access only via TokenArray SetExclusiveRecalcMode...() /
54 // IsRecalcMode...()
55 
56 // Only one of the exclusive bits can be set and one must be set,
57 // handled by TokenArray SetExclusiveRecalcMode...() methods.
58 // Exclusive bits are ordered by priority, AddRecalcMode() relies on that.
59 enum class ScRecalcMode : sal_uInt8
60 {
61     ALWAYS         = 0x01,  // exclusive, always
62     ONLOAD_MUST    = 0x02,  // exclusive, always after load
63     ONLOAD_ONCE    = 0x04,  // exclusive, once after load, import filter
64     ONLOAD_LENIENT = 0x08,  // exclusive, lenient after load (eg. macros not always, aliens, ...)
65     NORMAL         = 0x10,  // exclusive
66     FORCED         = 0x20,  // combined, also if cell isn't visible, for macros with side effects
67     ONREFMOVE      = 0x40,  // combined, if reference was moved
68     EMask          = ALWAYS | ONLOAD_MUST | ONLOAD_LENIENT | ONLOAD_ONCE | NORMAL   // mask of exclusive bits
69 };
70 namespace o3tl
71 {
72     template<> struct typed_flags<ScRecalcMode> : is_typed_flags<ScRecalcMode, 0x7f> {};
73 }
74 
75 namespace formula
76 {
77 
78 class FORMULA_DLLPUBLIC MissingConvention
79 {
80 public:
81     enum Convention
82     {
83         FORMULA_MISSING_CONVENTION_PODF,
84         FORMULA_MISSING_CONVENTION_ODFF,
85         FORMULA_MISSING_CONVENTION_OOXML
86     };
MissingConvention(Convention eConvention)87     explicit            MissingConvention( Convention eConvention ) : meConvention(eConvention) {}
isPODF() const88     bool        isPODF() const  { return meConvention == FORMULA_MISSING_CONVENTION_PODF; }
isODFF() const89     bool        isODFF() const  { return meConvention == FORMULA_MISSING_CONVENTION_ODFF; }
isOOXML() const90     bool        isOOXML() const  { return meConvention == FORMULA_MISSING_CONVENTION_OOXML; }
getConvention() const91     Convention  getConvention() const { return meConvention; }
92 private:
93     Convention meConvention;
94 };
95 
96 class FORMULA_DLLPUBLIC MissingConventionODF : public MissingConvention
97 {
98 public:
MissingConventionODF(bool bODFF)99     explicit    MissingConventionODF( bool bODFF ) :
100         MissingConvention( bODFF ?
101                 MissingConvention::FORMULA_MISSING_CONVENTION_ODFF :
102                 MissingConvention::FORMULA_MISSING_CONVENTION_PODF)
103         {
104         }
105     // Implementation and usage only in token.cxx
106     inline  bool    isRewriteNeeded( OpCode eOp ) const;
107 };
108 
109 class FORMULA_DLLPUBLIC MissingConventionOOXML : public MissingConvention
110 {
111 public:
MissingConventionOOXML()112     explicit    MissingConventionOOXML() : MissingConvention( MissingConvention::FORMULA_MISSING_CONVENTION_OOXML) {}
113     // Implementation and usage only in token.cxx
114     static inline bool isRewriteNeeded( OpCode eOp );
115 };
116 
117 typedef std::unordered_set<OpCode, std::hash<std::underlying_type<OpCode>::type> > unordered_opcode_set;
118 
119 class FORMULA_DLLPUBLIC FormulaTokenArrayStandardRange
120 {
121 private:
122     FormulaToken** mpBegin;
123     FormulaToken** mpEnd;
124 
125 public:
FormulaTokenArrayStandardRange(FormulaToken ** pBegin,sal_uInt16 nSize)126     FormulaTokenArrayStandardRange(FormulaToken** pBegin, sal_uInt16 nSize) :
127         mpBegin(pBegin),
128         mpEnd(pBegin + nSize)
129     {
130     }
131 
begin() const132     FormulaToken** begin() const
133     {
134         return mpBegin;
135     }
136 
end() const137     FormulaToken** end() const
138     {
139         return mpEnd;
140     }
141 };
142 
143 class FORMULA_DLLPUBLIC FormulaTokenArrayReferencesIterator
144 {
145 private:
146     FormulaToken** maIter;
147     FormulaToken** maEnd;
148 
nextReference()149     void nextReference()
150     {
151         while (maIter != maEnd)
152         {
153             switch ((*maIter)->GetType())
154             {
155             case svSingleRef:
156             case svDoubleRef:
157             case svExternalSingleRef:
158             case svExternalDoubleRef:
159                 return;
160             default:
161                 ++maIter;
162             }
163         }
164     }
165 
166     enum class Dummy { Flag };
167 
FormulaTokenArrayReferencesIterator(const FormulaTokenArrayStandardRange & rRange,Dummy)168     FormulaTokenArrayReferencesIterator(const FormulaTokenArrayStandardRange& rRange, Dummy) :
169         maIter(rRange.end()),
170         maEnd(rRange.end())
171     {
172     }
173 
174 public:
FormulaTokenArrayReferencesIterator(const FormulaTokenArrayStandardRange & rRange)175     FormulaTokenArrayReferencesIterator(const FormulaTokenArrayStandardRange& rRange) :
176         maIter(rRange.begin()),
177         maEnd(rRange.end())
178     {
179         nextReference();
180     }
181 
operator ++(int)182     FormulaTokenArrayReferencesIterator operator++(int)
183     {
184         FormulaTokenArrayReferencesIterator result(*this);
185         operator++();
186         return result;
187     }
188 
operator ++()189     FormulaTokenArrayReferencesIterator const & operator++()
190     {
191         assert(maIter != maEnd);
192         ++maIter;
193         nextReference();
194         return *this;
195     }
196 
operator *() const197     FormulaToken* operator*() const
198     {
199         return *maIter;
200     }
201 
operator ==(const FormulaTokenArrayReferencesIterator & rhs) const202     bool operator==(const FormulaTokenArrayReferencesIterator& rhs) const
203     {
204         return maIter == rhs.maIter;
205     }
206 
operator !=(const FormulaTokenArrayReferencesIterator & rhs) const207     bool operator!=(const FormulaTokenArrayReferencesIterator& rhs) const
208     {
209         return !operator==(rhs);
210     }
211 
endOf(const FormulaTokenArrayStandardRange & rRange)212     static FormulaTokenArrayReferencesIterator endOf(const FormulaTokenArrayStandardRange& rRange)
213     {
214         return FormulaTokenArrayReferencesIterator(rRange, Dummy::Flag);
215     }
216 };
217 
218 class FORMULA_DLLPUBLIC FormulaTokenArrayReferencesRange
219 {
220 private:
221     const FormulaTokenArray& mrFTA;
222 
223 public:
FormulaTokenArrayReferencesRange(const FormulaTokenArray & rFTA)224     FormulaTokenArrayReferencesRange(const FormulaTokenArray& rFTA) :
225         mrFTA(rFTA)
226     {
227     }
228 
229     FormulaTokenArrayReferencesIterator begin();
230 
231     FormulaTokenArrayReferencesIterator end();
232 };
233 
234 class FORMULA_DLLPUBLIC FormulaTokenArray
235 {
236 protected:
237     std::unique_ptr<FormulaToken*[]> pCode; // Token code array
238     FormulaToken**  pRPN;                   // RPN array
239     sal_uInt16      nLen;                   // Length of token array
240     sal_uInt16      nRPN;                   // Length of RPN array
241     FormulaError    nError;                 // Error code
242     ScRecalcMode    nMode;                  // Flags to indicate when to recalc this code
243     bool            bHyperLink      :1;     // If HYPERLINK() occurs in the formula.
244     bool            mbFromRangeName :1;     // If this array originates from a named expression
245     bool            mbShareable     :1;     // Whether or not it can be shared with adjacent cells.
246     bool            mbFinalized     :1;     // Whether code arrays have their final used size and no more tokens can be added.
247 
248 protected:
249     void                    Assign( const FormulaTokenArray& );
250     void                    Assign( sal_uInt16 nCode, FormulaToken **pTokens );
251 
252     /// Also used by the compiler. The token MUST had been allocated with new!
253     FormulaToken*           Add( FormulaToken* );
254 
255 public:
256     enum ReplaceMode
257     {
258         CODE_ONLY,      ///< replacement only in pCode
259         CODE_AND_RPN    ///< replacement in pCode and pRPN
260     };
261 
262     /** Also used by the compiler. The token MUST had been allocated with new!
263         @param  nOffset
264                 Absolute offset in pCode of the token to be replaced.
265         @param  eMode
266                 If CODE_ONLY only the token in pCode at nOffset is replaced.
267                 If CODE_AND_RPN the token in pCode at nOffset is replaced;
268                 if the original token was also referenced in the pRPN array
269                 then that reference is replaced with a reference to the new
270                 token as well.
271      */
272     FormulaToken*           ReplaceToken( sal_uInt16 nOffset, FormulaToken*, ReplaceMode eMode );
273 
274     /** Remove a sequence of tokens from pCode array, and pRPN array if the
275         tokens are referenced there.
276 
277         nLen and nRPN are adapted.
278 
279         @param  nOffset
280                 Start offset into pCode.
281         @param  nCount
282                 Count of tokens to remove.
283 
284         @return Count of tokens removed.
285      */
286     sal_uInt16              RemoveToken( sal_uInt16 nOffset, sal_uInt16 nCount );
287 
288     FormulaTokenArray();
289     /** Assignment with incrementing references of FormulaToken entries
290         (not copied!) */
291     FormulaTokenArray( const FormulaTokenArray& );
292     virtual ~FormulaTokenArray();
293 
294     virtual void Clear();
295 
296     /**
297      * The array has its final used size and no more token can be added.
298      */
299     void Finalize();
300 
SetFromRangeName(bool b)301     void SetFromRangeName( bool b ) { mbFromRangeName = b; }
IsFromRangeName() const302     bool IsFromRangeName() const { return mbFromRangeName; }
303 
SetShareable(bool b)304     void SetShareable( bool b ) { mbShareable = b; }
305 
306     /**
307      * Check if this token array is shareable between multiple adjacent
308      * formula cells. Certain tokens may not function correctly when shared.
309      *
310      * @return true if the token array is shareable, false otherwise.
311      */
IsShareable() const312     bool IsShareable() const { return mbShareable; }
313 
314     void DelRPN();
315     FormulaToken* FirstToken() const;
316 
317     /// Return pCode[nIdx], or nullptr if nIdx is out of bounds
TokenAt(sal_uInt16 nIdx) const318     FormulaToken* TokenAt( sal_uInt16 nIdx) const
319     {
320         if (nIdx >= nLen)
321             return nullptr;
322         return pCode[nIdx];
323     }
324 
325     /// Peek at nIdx-1 if not out of bounds, decrements nIdx if successful. Returns NULL if not.
326     FormulaToken* PeekPrev( sal_uInt16 & nIdx ) const;
327 
328     /// Return the opcode at pCode[nIdx-1], ocNone if nIdx-1 is out of bounds
OpCodeBefore(sal_uInt16 nIdx) const329     OpCode OpCodeBefore( sal_uInt16 nIdx) const
330     {
331         if (nIdx == 0 || nIdx > nLen)
332             return ocNone;
333 
334         return pCode[nIdx-1]->GetOpCode();
335     }
336 
337     FormulaToken* FirstRPNToken() const;
338 
339     bool HasReferences() const;
340 
341     bool    HasExternalRef() const;
342     bool    HasOpCode( OpCode ) const;
343     bool    HasOpCodeRPN( OpCode ) const;
344     /// Token of type svIndex or opcode ocColRowName
345     bool    HasNameOrColRowName() const;
346 
347     /**
348      * Check if the token array contains any of specified opcode tokens.
349      *
350      * @param rOpCodes collection of opcodes to check against.
351      *
352      * @return true if the token array contains at least one of the specified
353      *         opcode tokens, false otherwise.
354      */
355     bool HasOpCodes( const unordered_opcode_set& rOpCodes ) const;
356 
357     /// Assign pRPN to point to a newly created array filled with the data from pData
CreateNewRPNArrayFromData(FormulaToken ** pData,sal_uInt16 nSize)358     void CreateNewRPNArrayFromData( FormulaToken** pData, sal_uInt16 nSize )
359     {
360         pRPN = new FormulaToken*[ nSize ];
361         nRPN = nSize;
362         memcpy( pRPN, pData, nSize * sizeof( FormulaToken* ) );
363     }
364 
GetArray() const365     FormulaToken** GetArray() const  { return pCode.get(); }
366 
Tokens() const367     FormulaTokenArrayStandardRange Tokens() const
368     {
369         return FormulaTokenArrayStandardRange(pCode.get(), nLen);
370     }
371 
GetCode() const372     FormulaToken** GetCode()  const  { return pRPN; }
373 
RPNTokens() const374     FormulaTokenArrayStandardRange RPNTokens() const
375     {
376         return FormulaTokenArrayStandardRange(pRPN, nRPN);
377     }
378 
References() const379     FormulaTokenArrayReferencesRange References() const
380     {
381         return FormulaTokenArrayReferencesRange(*this);
382     }
383 
GetLen() const384     sal_uInt16     GetLen() const     { return nLen; }
GetCodeLen() const385     sal_uInt16     GetCodeLen() const { return nRPN; }
GetCodeError() const386     FormulaError   GetCodeError() const      { return nError; }
SetCodeError(FormulaError n)387     void      SetCodeError( FormulaError n )  { nError = n; }
SetHyperLink(bool bVal)388     void      SetHyperLink( bool bVal ) { bHyperLink = bVal; }
IsHyperLink() const389     bool      IsHyperLink() const       { return bHyperLink; }
390 
GetRecalcMode() const391     ScRecalcMode    GetRecalcMode() const { return nMode; }
392 
SetCombinedBitsRecalcMode(ScRecalcMode nBits)393     void            SetCombinedBitsRecalcMode( ScRecalcMode nBits )
394                                 { nMode |= nBits & ~ScRecalcMode::EMask; }
GetCombinedBitsRecalcMode() const395     ScRecalcMode    GetCombinedBitsRecalcMode() const
396                                 { return nMode & ~ScRecalcMode::EMask; }
397 
398                     /** Exclusive bits already set in nMode are zero'ed, nBits
399                         may contain combined bits, but only one exclusive bit
400                         may be set! */
SetMaskedRecalcMode(ScRecalcMode nBits)401     void            SetMaskedRecalcMode( ScRecalcMode nBits )
402                                 { nMode = GetCombinedBitsRecalcMode() | nBits; }
403 
404                     /** Bits aren't set directly but validated and handled
405                         according to priority if more than one exclusive bit
406                         was set. */
407     void            AddRecalcMode( ScRecalcMode nBits );
408 
ClearRecalcMode()409     void            ClearRecalcMode() { nMode = ScRecalcMode::NORMAL; }
SetExclusiveRecalcModeNormal()410     void            SetExclusiveRecalcModeNormal()
411                                 { SetMaskedRecalcMode( ScRecalcMode::NORMAL ); }
SetExclusiveRecalcModeAlways()412     void            SetExclusiveRecalcModeAlways()
413                                 { SetMaskedRecalcMode( ScRecalcMode::ALWAYS ); }
SetRecalcModeForced()414     void            SetRecalcModeForced()
415                                 { nMode |= ScRecalcMode::FORCED; }
SetRecalcModeOnRefMove()416     void            SetRecalcModeOnRefMove()
417                                 { nMode |= ScRecalcMode::ONREFMOVE; }
IsRecalcModeNormal() const418     bool            IsRecalcModeNormal() const
419                                 { return bool(nMode & ScRecalcMode::NORMAL); }
IsRecalcModeAlways() const420     bool            IsRecalcModeAlways() const
421                                 { return bool(nMode & ScRecalcMode::ALWAYS); }
IsRecalcModeForced() const422     bool            IsRecalcModeForced() const
423                                 { return bool(nMode & ScRecalcMode::FORCED); }
IsRecalcModeOnRefMove() const424     bool            IsRecalcModeOnRefMove() const
425                                 { return bool(nMode & ScRecalcMode::ONREFMOVE); }
426                     /** Whether recalculation must happen after import, for
427                         example OOXML. */
IsRecalcModeMustAfterImport() const428     bool            IsRecalcModeMustAfterImport() const
429                                 { return (nMode & ScRecalcMode::EMask) <= ScRecalcMode::ONLOAD_ONCE; }
430 
431                             /** Get OpCode of the most outer function */
432     inline OpCode           GetOuterFuncOpCode() const;
433 
434                             /** Operators +,-,*,/,^,&,=,<>,<,>,<=,>=
435                                 with DoubleRef in Formula? */
436     bool                    HasMatrixDoubleRefOps() const;
437 
438     virtual FormulaToken* AddOpCode(OpCode e);
439 
440     /** Adds the single token to array.
441         Derived classes must override it when they want to support derived classes from FormulaToken.
442         @return true        when an error occurs
443     */
444     virtual bool AddFormulaToken(
445         const css::sheet::FormulaToken& rToken, svl::SharedStringPool& rSPool,
446         ExternalReferenceHelper* pExtRef );
447 
448     /** fill the array with the tokens from the sequence.
449         It calls AddFormulaToken for each token in the list.
450         @param  _aSequence  the token to add
451         @return true        when an error occurs
452     */
453     bool Fill(
454         const css::uno::Sequence<css::sheet::FormulaToken>& rSequence,
455         svl::SharedStringPool& rSPool, ExternalReferenceHelper* pExtRef );
456 
457     /**
458      * Do some checking based on the individual tokens. For now, we use this
459      * only to check whether we can vectorize the token array.
460      */
461     virtual void CheckToken( const FormulaToken& t );
462 
463     /**
464      * Call CheckToken() for all RPN tokens.
465      */
466     void CheckAllRPNTokens();
467 
468     /** Clones the token and then adds the clone to the pCode array.
469         For just new'ed tokens use Add() instead of cloning it again.
470         Use this AddToken() when adding a token from another origin.
471      */
472     FormulaToken* AddToken( const FormulaToken& );
473 
474     FormulaToken* AddString( const svl::SharedString& rStr );
475     FormulaToken* AddDouble( double fVal );
476     void          AddExternal( const sal_Unicode* pStr );
477     /** Xcl import may play dirty tricks with OpCode!=ocExternal.
478         Others don't use! */
479     FormulaToken* AddExternal( const OUString& rStr, OpCode eOp = ocExternal );
480     FormulaToken* AddBad( const OUString& rStr );          /// ocBad with OUString
481     FormulaToken* AddStringXML( const OUString& rStr );    /// ocStringXML with OUString, temporary during import
482 
483     virtual FormulaToken* MergeArray( );
484 
485     /** Assignment with incrementing references of FormulaToken entries
486         (not copied!) */
487     FormulaTokenArray& operator=( const FormulaTokenArray& );
488 
489     /** Determines if this formula needs any changes to convert it to something
490         previous versions of OOo could consume (Plain Old Formula, pre-ODFF, or
491         also ODFF) */
492     bool                NeedsPodfRewrite( const MissingConventionODF & rConv );
493 
494     /** Determines if this formula needs any changes to convert it to OOXML. */
495     bool                NeedsOoxmlRewrite();
496 
497     /** Rewrites to Plain Old Formula or OOXML, substituting missing parameters. The
498         FormulaTokenArray* returned is new'ed. */
499     FormulaTokenArray*  RewriteMissing( const MissingConvention & rConv );
500 
501     /** Determines if this formula may be followed by a reference. */
502     bool                MayReferenceFollow();
503 
504     /** Re-intern SharedString in case the SharedStringPool differs. */
505     void ReinternStrings( svl::SharedStringPool& rPool );
506 };
507 
GetOuterFuncOpCode() const508 inline OpCode FormulaTokenArray::GetOuterFuncOpCode() const
509 {
510     if ( pRPN && nRPN )
511         return pRPN[nRPN-1]->GetOpCode();
512     return ocNone;
513 }
514 
begin()515 inline FormulaTokenArrayReferencesIterator FormulaTokenArrayReferencesRange::begin()
516 {
517     return FormulaTokenArrayReferencesIterator(mrFTA.Tokens());
518 }
519 
end()520 inline FormulaTokenArrayReferencesIterator FormulaTokenArrayReferencesRange::end()
521 {
522     return FormulaTokenArrayReferencesIterator::endOf(mrFTA.Tokens());
523 }
524 
525 class FORMULA_DLLPUBLIC FormulaTokenIterator
526 {
527     struct Item
528     {
529     public:
530         const FormulaTokenArray* pArr;
531         short nPC;
532         short nStop;
533 
534         Item(const FormulaTokenArray* arr, short pc, short stop);
535     };
536 
537     std::vector<Item> maStack;
538 
539 public:
540     FormulaTokenIterator( const FormulaTokenArray& );
541    ~FormulaTokenIterator();
542     void    Reset();
543     const   FormulaToken* Next();
544     const   FormulaToken* PeekNextOperator();
545     bool    IsEndOfPath() const;    /// if a jump or subroutine path is done
HasStacked() const546     bool    HasStacked() const { return maStack.size() > 1; }
GetPC() const547     short   GetPC() const { return maStack.back().nPC; }
548 
549     /** Jump or subroutine call.
550         Program counter values will be incremented before code is executed =>
551         positions are to be passed with -1 offset.
552         @param nStart
553             Start on code at position nStart+1 (yes, pass with offset -1)
554         @param nNext
555             After subroutine continue with instruction at position nNext+1
556         @param nStop
557             Stop before reaching code at position nStop. If not specified the
558             default is to either run the entire code, or to stop if an ocSep or
559             ocClose is encountered, which are only present in ocIf or ocChoose
560             jumps.
561       */
562     void Jump( short nStart, short nNext, short nStop = SHRT_MAX );
563     void Push( const FormulaTokenArray* );
564     void Pop();
565 
566     /** Reconstruct the iterator afresh from a token array
567     */
568     void ReInit( const FormulaTokenArray& );
569 
570 private:
571     const FormulaToken* GetNonEndOfPathToken( short nIdx ) const;
572 };
573 
574 // For use in SAL_INFO, SAL_WARN etc
575 
576 template<typename charT, typename traits>
operator <<(std::basic_ostream<charT,traits> & stream,const FormulaTokenArray & point)577 inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const FormulaTokenArray& point)
578 {
579     stream <<
580         static_cast<const void*>(&point) <<
581         ":{nLen=" << point.GetLen() <<
582         ",nRPN=" << point.GetCodeLen() <<
583         ",pCode=" << static_cast<void*>(point.GetArray()) <<
584         ",pRPN=" << static_cast<void*>(point.GetCode()) <<
585         "}";
586 
587     return stream;
588 }
589 
590 class FORMULA_DLLPUBLIC FormulaTokenArrayPlainIterator
591 {
592 private:
593     const FormulaTokenArray* mpFTA;
594     sal_uInt16 mnIndex;                 // Current step index
595 
596 public:
FormulaTokenArrayPlainIterator(const FormulaTokenArray & rFTA)597     FormulaTokenArrayPlainIterator( const FormulaTokenArray& rFTA ) :
598         mpFTA( &rFTA ),
599         mnIndex( 0 )
600     {
601     }
602 
Reset()603     void Reset()
604     {
605         mnIndex = 0;
606     }
607 
GetIndex() const608     sal_uInt16 GetIndex() const
609     {
610         return mnIndex;
611     }
612 
First()613     FormulaToken* First()
614     {
615         mnIndex = 0;
616         return Next();
617     }
618 
Jump(sal_uInt16 nIndex)619     void Jump(sal_uInt16 nIndex)
620     {
621         mnIndex = nIndex;
622     }
623 
StepBack()624     void StepBack()
625     {
626         assert(mnIndex > 0);
627         mnIndex--;
628     }
629 
630     FormulaToken* Next();
631     FormulaToken* NextNoSpaces();
632     FormulaToken* GetNextName();
633     FormulaToken* GetNextReference();
634     FormulaToken* GetNextReferenceRPN();
635     FormulaToken* GetNextReferenceOrName();
636     FormulaToken* GetNextColRowName();
637     FormulaToken* PeekNext();
638     FormulaToken* PeekPrevNoSpaces() const;    /// Only after Reset/First/Next/Last/Prev!
639     FormulaToken* PeekNextNoSpaces() const;    /// Only after Reset/First/Next/Last/Prev!
640 
FirstRPN()641     FormulaToken* FirstRPN()
642     {
643         mnIndex = 0;
644         return NextRPN();
645     }
646 
647     FormulaToken* NextRPN();
648 
LastRPN()649     FormulaToken* LastRPN()
650     {
651         mnIndex = mpFTA->GetCodeLen();
652         return PrevRPN();
653     }
654 
655     FormulaToken* PrevRPN();
656 
657     void AfterRemoveToken( sal_uInt16 nOffset, sal_uInt16 nCount );
658 };
659 
660 
661 } // formula
662 
663 #endif // INCLUDED_FORMULA_TOKENARRAY_HXX
664 
665 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
666