Line data Source code
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 SC_TOKSTACK_HXX
21 : #define SC_TOKSTACK_HXX
22 :
23 : #include <string.h>
24 : #include "compiler.hxx"
25 : #include "tokenarray.hxx"
26 :
27 : #include <vector>
28 :
29 : typedef OpCode DefTokenId;
30 : // in PRODUCT version: ambiguity between OpCode (being sal_uInt16) and UINT16
31 : // Unfortunately a typedef is just a dumb alias and not a real type ...
32 : //typedef sal_uInt16 TokenId;
33 : struct TokenId
34 : {
35 : sal_uInt16 nId;
36 :
37 855396 : TokenId() : nId( 0 ) {}
38 19445 : TokenId( sal_uInt16 n ) : nId( n ) {}
39 19954 : TokenId( const TokenId& r ) : nId( r.nId ) {}
40 47902 : inline TokenId& operator =( const TokenId& r ) { nId = r.nId; return *this; }
41 0 : inline TokenId& operator =( sal_uInt16 n ) { nId = n; return *this; }
42 : inline operator sal_uInt16&() { return nId; }
43 22006 : inline operator const sal_uInt16&() const { return nId; }
44 : inline sal_Bool operator <( sal_uInt16 n ) const { return nId < n; }
45 : inline sal_Bool operator >( sal_uInt16 n ) const { return nId > n; }
46 : inline sal_Bool operator <=( sal_uInt16 n ) const { return nId <= n; }
47 : inline sal_Bool operator >=( sal_uInt16 n ) const { return nId >= n; }
48 : inline sal_Bool operator ==( sal_uInt16 n ) const { return nId == n; }
49 : inline sal_Bool operator !=( sal_uInt16 n ) const { return nId != n; }
50 : };
51 :
52 :
53 : //------------------------------------------------------------------------
54 : struct ScComplexRefData;
55 : class TokenStack;
56 :
57 :
58 : enum E_TYPE
59 : {
60 : T_Id, // Id-Folge
61 : T_Str, // String
62 : T_D, // Double
63 : T_Err, // Error code
64 : T_RefC, // Cell Reference
65 : T_RefA, // Area Reference
66 : T_RN, // Range Name
67 : T_Ext, // irgendwas Unbekanntes mit Funktionsnamen
68 : T_Nlf, // token for natural language formula
69 : T_Matrix, // token for inline arrays
70 : T_ExtName, // token for external names
71 : T_ExtRefC,
72 : T_ExtRefA,
73 : T_Error // fuer Abfrage im Fehlerfall
74 : };
75 :
76 :
77 :
78 :
79 : class TokenPool
80 : {
81 : // !ACHTUNG!: externe Id-Basis ist 1, interne 0!
82 : // Ausgabe Id = 0 -> Fehlerfall
83 : private:
84 : String** ppP_Str; // Pool fuer Strings
85 : sal_uInt16 nP_Str; // ...mit Groesse
86 : sal_uInt16 nP_StrAkt; // ...und Schreibmarke
87 :
88 : double* pP_Dbl; // Pool fuer Doubles
89 : sal_uInt16 nP_Dbl;
90 : sal_uInt16 nP_DblAkt;
91 :
92 : sal_uInt16* pP_Err; // Pool for error codes
93 : sal_uInt16 nP_Err;
94 : sal_uInt16 nP_ErrAkt;
95 :
96 : ScSingleRefData** ppP_RefTr; // Pool fuer Referenzen
97 : sal_uInt16 nP_RefTr;
98 : sal_uInt16 nP_RefTrAkt;
99 :
100 : sal_uInt16* pP_Id; // Pool fuer Id-Folgen
101 : sal_uInt16 nP_Id;
102 : sal_uInt16 nP_IdAkt;
103 : sal_uInt16 nP_IdLast; // letzter Folgen-Beginn
104 :
105 1 : struct EXTCONT
106 : {
107 : DefTokenId eId;
108 : String aText;
109 1 : EXTCONT( const DefTokenId e, const String& r ) :
110 1 : eId( e ), aText( r ){}
111 : };
112 : EXTCONT** ppP_Ext;
113 : sal_uInt16 nP_Ext;
114 : sal_uInt16 nP_ExtAkt;
115 :
116 : struct NLFCONT
117 : {
118 : ScSingleRefData aRef;
119 0 : NLFCONT( const ScSingleRefData& r ) : aRef( r ) {}
120 : };
121 : NLFCONT** ppP_Nlf;
122 : sal_uInt16 nP_Nlf;
123 : sal_uInt16 nP_NlfAkt;
124 :
125 : ScMatrix** ppP_Matrix; // Pool fuer Matricies
126 : sal_uInt16 nP_Matrix;
127 : sal_uInt16 nP_MatrixAkt;
128 :
129 : /** for storage of named ranges */
130 : struct RangeName
131 : {
132 : sal_uInt16 mnIndex;
133 : bool mbGlobal;
134 : };
135 : ::std::vector<RangeName> maRangeNames;
136 :
137 : /** for storage of external names */
138 0 : struct ExtName
139 : {
140 : sal_uInt16 mnFileId;
141 : String maName;
142 : };
143 : ::std::vector<ExtName> maExtNames;
144 :
145 : /** for storage of external cell references */
146 0 : struct ExtCellRef
147 : {
148 : sal_uInt16 mnFileId;
149 : String maTabName;
150 : ScSingleRefData maRef;
151 : };
152 : ::std::vector<ExtCellRef> maExtCellRefs;
153 :
154 : /** for storage of external area references */
155 0 : struct ExtAreaRef
156 : {
157 : sal_uInt16 mnFileId;
158 : String maTabName;
159 : ScComplexRefData maRef;
160 : };
161 : ::std::vector<ExtAreaRef> maExtAreaRefs;
162 :
163 : sal_uInt16* pElement; // Array mit Indizes fuer Elemente
164 : E_TYPE* pType; // ...mit Typ-Info
165 : sal_uInt16* pSize; // ...mit Laengenangabe (Anz. sal_uInt16)
166 : sal_uInt16 nElement;
167 : sal_uInt16 nElementAkt;
168 :
169 : static const sal_uInt16 nScTokenOff;// Offset fuer SC-Token
170 : #ifdef DBG_UTIL
171 : sal_uInt16 m_nRek; // recursion counter
172 : #endif
173 : ScTokenArray* pScToken; // Tokenbastler
174 :
175 : bool GrowString( void );
176 : bool GrowDouble( void );
177 : /* TODO: in case we had FormulaTokenArray::AddError() */
178 : #if 0
179 : bool GrowError( void );
180 : #endif
181 : bool GrowTripel( sal_uInt16 nByMin = 1 );
182 : bool GrowId( void );
183 : bool GrowElement( void );
184 : bool GrowExt( void );
185 : bool GrowNlf( void );
186 : bool GrowMatrix( void );
187 : bool GetElement( const sal_uInt16 nId );
188 : bool GetElementRek( const sal_uInt16 nId );
189 : public:
190 : TokenPool( void );
191 : ~TokenPool();
192 : inline TokenPool& operator <<( const TokenId nId );
193 : inline TokenPool& operator <<( const DefTokenId eId );
194 : inline TokenPool& operator <<( TokenStack& rStack );
195 : void operator >>( TokenId& rId );
196 : inline void operator >>( TokenStack& rStack );
197 : inline const TokenId Store( void );
198 : const TokenId Store( const double& rDouble );
199 :
200 : // nur fuer Range-Names
201 : const TokenId Store( const sal_uInt16 nIndex );
202 : inline const TokenId Store( const sal_Int16 nWert );
203 : const TokenId Store( const String& rString );
204 : const TokenId Store( const ScSingleRefData& rTr );
205 : const TokenId Store( const ScComplexRefData& rTr );
206 :
207 : const TokenId Store( const DefTokenId eId, const String& rName );
208 : // 4 externals (e.g. AddIns, Makros...)
209 : const TokenId StoreNlf( const ScSingleRefData& rTr );
210 : const TokenId StoreMatrix();
211 : const TokenId StoreName( sal_uInt16 nIndex, bool bGlobal );
212 : const TokenId StoreExtName( sal_uInt16 nFileId, const String& rName );
213 : const TokenId StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
214 : const TokenId StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef );
215 :
216 : inline const TokenId LastId( void ) const;
217 : inline const ScTokenArray* operator []( const TokenId nId );
218 : void Reset( void );
219 : inline E_TYPE GetType( const TokenId& nId ) const;
220 : sal_Bool IsSingleOp( const TokenId& nId, const DefTokenId eId ) const;
221 : const String* GetExternal( const TokenId& nId ) const;
222 : ScMatrix* GetMatrix( unsigned int n ) const;
223 : };
224 :
225 :
226 :
227 :
228 : class TokenStack
229 : // Stack fuer Token-Ids: Id 0 sollte reserviert bleiben als
230 : // fehlerhafte Id, da z.B. Get() im Fehlerfall 0 liefert
231 : {
232 : private:
233 : TokenId* pStack; // Stack als Array
234 : sal_uInt16 nPos; // Schreibmarke
235 : sal_uInt16 nSize; // Erster Index ausserhalb des Stacks
236 : public:
237 : TokenStack( sal_uInt16 nNewSize = 1024 );
238 : ~TokenStack();
239 : inline TokenStack& operator <<( const TokenId nNewId );
240 : inline void operator >>( TokenId &rId );
241 :
242 : inline void Reset( void );
243 :
244 8988 : inline bool HasMoreTokens() const { return nPos > 0; }
245 : inline const TokenId Get( void );
246 : };
247 :
248 :
249 :
250 :
251 8508 : inline const TokenId TokenStack::Get( void )
252 : {
253 : OSL_ENSURE( nPos > 0,
254 : "*TokenStack::Get(): Leer ist leer, ist leer, ist leer, ist..." );
255 :
256 8508 : TokenId nRet;
257 :
258 8508 : if( nPos == 0 )
259 0 : nRet = 0;
260 : else
261 : {
262 8508 : nPos--;
263 8508 : nRet = pStack[ nPos ];
264 : }
265 :
266 8508 : return nRet;
267 : }
268 :
269 :
270 19429 : inline TokenStack &TokenStack::operator <<( const TokenId nNewId )
271 : {// Element auf Stack
272 : OSL_ENSURE( nPos < nSize, "*TokenStack::<<(): Stackueberlauf" );
273 19429 : if( nPos < nSize )
274 : {
275 19429 : pStack[ nPos ] = nNewId;
276 19429 : nPos++;
277 : }
278 :
279 19429 : return *this;
280 : }
281 :
282 :
283 10919 : inline void TokenStack::operator >>( TokenId& rId )
284 : {// Element von Stack
285 : OSL_ENSURE( nPos > 0,
286 : "*TokenStack::>>(): Leer ist leer, ist leer, ist leer, ..." );
287 10919 : if( nPos > 0 )
288 : {
289 10919 : nPos--;
290 10919 : rId = pStack[ nPos ];
291 : }
292 10919 : }
293 :
294 :
295 2645 : inline void TokenStack::Reset( void )
296 : {
297 2645 : nPos = 0;
298 2645 : }
299 :
300 :
301 :
302 :
303 10927 : inline TokenPool& TokenPool::operator <<( const TokenId nId )
304 : {
305 : // POST: nId's werden hintereinander im Pool unter einer neuen Id
306 : // abgelegt. Vorgang wird mit >> oder Store() abgeschlossen
307 : // nId -> ( sal_uInt16 ) nId - 1;
308 : OSL_ENSURE( ( sal_uInt16 ) nId < nScTokenOff,
309 : "-TokenPool::operator <<: TokenId im DefToken-Bereich!" );
310 :
311 10927 : if( nP_IdAkt >= nP_Id )
312 0 : if (!GrowId())
313 0 : return *this;
314 :
315 10927 : pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) nId ) - 1;
316 10927 : nP_IdAkt++;
317 :
318 10927 : return *this;
319 : }
320 :
321 :
322 18964 : inline TokenPool& TokenPool::operator <<( const DefTokenId eId )
323 : {
324 : OSL_ENSURE( ( sal_uInt32 ) eId + nScTokenOff < 0xFFFF,
325 : "-TokenPool::operator<<: enmum zu gross!" );
326 :
327 18964 : if( nP_IdAkt >= nP_Id )
328 0 : if (!GrowId())
329 0 : return *this;
330 :
331 18964 : pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) eId ) + nScTokenOff;
332 18964 : nP_IdAkt++;
333 :
334 18964 : return *this;
335 : }
336 :
337 :
338 5941 : inline TokenPool& TokenPool::operator <<( TokenStack& rStack )
339 : {
340 5941 : if( nP_IdAkt >= nP_Id )
341 0 : if (!GrowId())
342 0 : return *this;
343 :
344 5941 : pP_Id[ nP_IdAkt ] = ( ( sal_uInt16 ) rStack.Get() ) - 1;
345 5941 : nP_IdAkt++;
346 :
347 5941 : return *this;
348 : }
349 :
350 :
351 9026 : inline void TokenPool::operator >>( TokenStack& rStack )
352 : {
353 9026 : TokenId nId;
354 9026 : *this >> nId;
355 9026 : rStack << nId;
356 9026 : }
357 :
358 :
359 8 : inline const TokenId TokenPool::Store( void )
360 : {
361 8 : TokenId nId;
362 8 : *this >> nId;
363 8 : return nId;
364 : }
365 :
366 :
367 : inline const TokenId TokenPool::Store( const sal_Int16 nWert )
368 : {
369 : return Store( ( double ) nWert );
370 : }
371 :
372 :
373 : inline const TokenId TokenPool::LastId( void ) const
374 : {
375 : return ( TokenId ) nElementAkt; // stimmt, da Ausgabe mit Offset 1!
376 : }
377 :
378 :
379 2567 : const inline ScTokenArray* TokenPool::operator []( const TokenId nId )
380 : {
381 2567 : pScToken->Clear();
382 :
383 2567 : if( nId )
384 : {//...nur wenn nId > 0!
385 : #ifdef DBG_UTIL
386 : m_nRek = 0;
387 : #endif
388 2567 : GetElement( ( sal_uInt16 ) nId - 1 );
389 : }
390 :
391 2567 : return pScToken;
392 : }
393 :
394 :
395 : inline E_TYPE TokenPool::GetType( const TokenId& rId ) const
396 : {
397 : E_TYPE nRet;
398 :
399 : sal_uInt16 nId = (sal_uInt16) rId - 1;
400 :
401 : if( nId < nElementAkt )
402 : nRet = pType[ nId ] ;
403 : else
404 : nRet = T_Error;
405 :
406 : return nRet;
407 : }
408 :
409 :
410 : #endif
411 :
412 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|