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