Branch data 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 : :
21 : : #include "sbcomp.hxx"
22 : : #include <stdio.h>
23 : : #include <string.h>
24 : : #include <ctype.h>
25 : :
26 : : // All symbol names are laid down int the symbol-pool's stringpool, so that
27 : : // all symbols are handled in the same case. On saving the code-image, the
28 : : // global stringpool with the respective symbols is also saved.
29 : : // The local stringpool holds all the symbols that don't move to the image
30 : : // (labels, constant names etc.).
31 : :
32 : : /***************************************************************************
33 : : |*
34 : : |* SbiStringPool
35 : : |*
36 : : ***************************************************************************/
37 : :
38 [ + - ]: 130 : SbiStringPool::SbiStringPool( SbiParser* p )
39 : : {
40 : 130 : pParser = p;
41 : 130 : }
42 : :
43 : 130 : SbiStringPool::~SbiStringPool()
44 : 130 : {}
45 : :
46 : 2980 : const rtl::OUString& SbiStringPool::Find( sal_uInt32 n ) const
47 : : {
48 [ + - ][ - + ]: 2980 : if( n == 0 || n > aData.size() )
[ - + ]
49 : 0 : return aEmpty; //hack, returning a reference to a simulation of null
50 : : else
51 : 2980 : return aData[n - 1];
52 : : }
53 : :
54 : 4797 : short SbiStringPool::Add( const rtl::OUString& rVal, bool bNoCase )
55 : : {
56 : 4797 : sal_uInt32 n = aData.size();
57 [ + + ]: 656645 : for( sal_uInt32 i = 0; i < n; ++i )
58 : : {
59 : 653974 : rtl::OUString& p = aData[i];
60 [ + + ]: 653974 : if( ( bNoCase && p == rVal )
[ - + # # ]
[ + + ][ + - ]
61 : 0 : || ( !bNoCase && p.equalsIgnoreAsciiCase( rVal ) ) )
62 : 2126 : return i+1;
63 : : }
64 : :
65 : 2671 : aData.push_back(rVal);
66 : 4797 : return (short) ++n;
67 : : }
68 : :
69 : 16 : short SbiStringPool::Add( double n, SbxDataType t )
70 : : {
71 : : char buf[ 40 ];
72 [ - + - - : 16 : switch( t )
- ]
73 : : {
74 : 0 : case SbxINTEGER: snprintf( buf, sizeof(buf), "%d", (short) n ); break;
75 : 16 : case SbxLONG: snprintf( buf, sizeof(buf), "%ld", (long) n ); break;
76 : 0 : case SbxSINGLE: snprintf( buf, sizeof(buf), "%.6g", (float) n ); break;
77 : 0 : case SbxDOUBLE: snprintf( buf, sizeof(buf), "%.16g", n ); break;
78 : 0 : default: break;
79 : : }
80 [ + - ]: 16 : return Add( rtl::OUString::createFromAscii( buf ) );
81 : : }
82 : :
83 : : /***************************************************************************
84 : : |*
85 : : |* SbiSymPool
86 : : |*
87 : : ***************************************************************************/
88 : :
89 : 2407 : SbiSymPool::SbiSymPool( SbiStringPool& r, SbiSymScope s ) : rStrings( r )
90 : : {
91 : 2407 : pParser = r.GetParser();
92 : 2407 : eScope = s;
93 : 2407 : pParent = NULL;
94 : : nCur =
95 : 2407 : nProcId = 0;
96 : 2407 : }
97 : :
98 : 2407 : SbiSymPool::~SbiSymPool()
99 : 2407 : {}
100 : :
101 : :
102 : 65 : SbiSymDef* SbiSymPool::First()
103 : : {
104 : 65 : nCur = (sal_uInt16) -1;
105 : 65 : return Next();
106 : : }
107 : :
108 : 747 : SbiSymDef* SbiSymPool::Next()
109 : : {
110 [ + + ]: 747 : if( ++nCur >= aData.size() )
111 : 67 : return NULL;
112 : : else
113 : 747 : return aData[ nCur ];
114 : : }
115 : :
116 : :
117 : 1791 : SbiSymDef* SbiSymPool::AddSym( const String& rName )
118 : : {
119 [ + - ][ + - ]: 1791 : SbiSymDef* p = new SbiSymDef( rName );
120 : 1791 : p->nPos = aData.size();
121 [ + - ][ + - ]: 1791 : p->nId = rStrings.Add( rName );
122 : 1791 : p->nProcId = nProcId;
123 : 1791 : p->pIn = this;
124 [ + - ][ + - ]: 1791 : aData.insert( aData.begin() + p->nPos, p );
125 : 1791 : return p;
126 : : }
127 : :
128 : 450 : SbiProcDef* SbiSymPool::AddProc( const String& rName )
129 : : {
130 [ + - ]: 450 : SbiProcDef* p = new SbiProcDef( pParser, rName );
131 : 450 : p->nPos = aData.size();
132 [ + - ]: 450 : p->nId = rStrings.Add( rName );
133 : : // procs are always local
134 : 450 : p->nProcId = 0;
135 : 450 : p->pIn = this;
136 [ + - ][ + - ]: 450 : aData.insert( aData.begin() + p->nPos, p );
137 : 450 : return p;
138 : : }
139 : :
140 : : // adding an externally constructed symbol definition
141 : :
142 : 1084 : void SbiSymPool::Add( SbiSymDef* pDef )
143 : : {
144 [ + - ][ + - ]: 1084 : if( pDef && pDef->pIn != this )
145 : : {
146 [ - + ]: 1084 : if( pDef->pIn )
147 : : {
148 : : #ifdef DBG_UTIL
149 : :
150 : : pParser->Error( SbERR_INTERNAL_ERROR, "Dbl Pool" );
151 : : #endif
152 : 1084 : return;
153 : : }
154 : :
155 : 1084 : pDef->nPos = aData.size();
156 [ + - ]: 1084 : if( !pDef->nId )
157 : : {
158 : : // A unique name must be created in the string pool
159 : : // for static variables (Form ProcName:VarName)
160 [ + - ]: 1084 : String aName( pDef->aName );
161 [ - + ]: 1084 : if( pDef->IsStatic() )
162 : : {
163 [ # # ][ # # ]: 0 : aName = pParser->aGblStrings.Find( nProcId );
164 [ # # ]: 0 : aName += ':';
165 [ # # ]: 0 : aName += pDef->aName;
166 : : }
167 [ + - ][ + - ]: 1084 : pDef->nId = rStrings.Add( aName );
[ + - ]
168 : : }
169 : :
170 [ + + ]: 1084 : if( !pDef->GetProcDef() )
171 : 961 : pDef->nProcId = nProcId;
172 : 1084 : pDef->pIn = this;
173 [ + - ][ + - ]: 1084 : aData.insert( aData.begin() + pDef->nPos, pDef );
174 : : }
175 : : }
176 : :
177 : :
178 : 17403 : SbiSymDef* SbiSymPool::Find( const String& rName ) const
179 : : {
180 : 17403 : sal_uInt16 nCount = aData.size();
181 [ + + ]: 232697 : for( sal_uInt16 i = 0; i < nCount; i++ )
182 : : {
183 : 220263 : SbiSymDef* p = aData[ nCount - i - 1 ];
184 [ # # + + ]: 440526 : if( ( !p->nProcId || ( p->nProcId == nProcId ) )
[ + + ][ - + ]
185 : 220263 : && ( p->aName.EqualsIgnoreCaseAscii( rName ) ) )
186 : 4969 : return p;
187 : : }
188 [ + + ]: 12434 : if( pParent )
189 : 10588 : return pParent->Find( rName );
190 : : else
191 : 17403 : return NULL;
192 : : }
193 : :
194 : :
195 : 0 : SbiSymDef* SbiSymPool::FindId( sal_uInt16 n ) const
196 : : {
197 [ # # ]: 0 : for( sal_uInt16 i = 0; i < aData.size(); i++ )
198 : : {
199 : 0 : SbiSymDef* p = aData[ i ];
200 [ # # ][ # # ]: 0 : if( p->nId == n && ( !p->nProcId || ( p->nProcId == nProcId ) ) )
[ # # ]
201 : 0 : return p;
202 : : }
203 [ # # ]: 0 : if( pParent )
204 : 0 : return pParent->FindId( n );
205 : : else
206 : 0 : return NULL;
207 : : }
208 : :
209 : : // find via position (from 0)
210 : :
211 : 1370 : SbiSymDef* SbiSymPool::Get( sal_uInt16 n ) const
212 : : {
213 [ + + ]: 1370 : if( n >= aData.size() )
214 : 2 : return NULL;
215 : : else
216 : 1370 : return aData[ n ];
217 : : }
218 : :
219 : 16 : sal_uInt32 SbiSymPool::Define( const String& rName )
220 : : {
221 : 16 : SbiSymDef* p = Find( rName );
222 [ + - ]: 16 : if( p )
223 [ - + ]: 16 : { if( p->IsDefined() )
224 [ # # ]: 0 : pParser->Error( SbERR_LABEL_DEFINED, rName );
225 : : }
226 : : else
227 : 0 : p = AddSym( rName );
228 : 16 : return p->Define();
229 : : }
230 : :
231 : 16 : sal_uInt32 SbiSymPool::Reference( const String& rName )
232 : : {
233 : 16 : SbiSymDef* p = Find( rName );
234 [ + - ]: 16 : if( !p )
235 : 16 : p = AddSym( rName );
236 : : // to be sure
237 : 16 : pParser->aGen.GenStmnt();
238 : 16 : return p->Reference();
239 : : }
240 : :
241 : :
242 : 197 : void SbiSymPool::CheckRefs()
243 : : {
244 [ + + ]: 213 : for( sal_uInt16 i = 0; i < aData.size(); i++ )
245 : : {
246 : 16 : SbiSymDef* p = aData[ i ];
247 [ - + ]: 16 : if( !p->IsDefined() )
248 [ # # ]: 0 : pParser->Error( SbERR_UNDEF_LABEL, p->GetName() );
249 : : }
250 : 197 : }
251 : :
252 : : /***************************************************************************
253 : : |*
254 : : |* symbol definitions
255 : : |*
256 : : ***************************************************************************/
257 : :
258 : 3399 : SbiSymDef::SbiSymDef( const String& rName ) : aName( rName )
259 : : {
260 : 3399 : eType = SbxEMPTY;
261 : 3399 : nDims = 0;
262 : 3399 : nTypeId = 0;
263 : 3399 : nProcId = 0;
264 : 3399 : nId = 0;
265 : 3399 : nPos = 0;
266 : 3399 : nLen = 0;
267 : 3399 : nChain = 0;
268 : : bAs =
269 : : bNew =
270 : : bStatic =
271 : : bOpt =
272 : : bParamArray =
273 : : bWithEvents =
274 : : bWithBrackets =
275 : : bByVal =
276 : : bChained =
277 : 3399 : bGlobal = false;
278 : : pIn =
279 : 3399 : pPool = NULL;
280 : 3399 : nDefaultId = 0;
281 : 3399 : nFixedStringLength = -1;
282 : 3399 : }
283 : :
284 : 3399 : SbiSymDef::~SbiSymDef()
285 : : {
286 [ + + ][ + - ]: 3399 : delete pPool;
287 [ - + ]: 5632 : }
288 : :
289 : 4645 : SbiProcDef* SbiSymDef::GetProcDef()
290 : : {
291 : 4645 : return NULL;
292 : : }
293 : :
294 : 5258 : SbiConstDef* SbiSymDef::GetConstDef()
295 : : {
296 : 5258 : return NULL;
297 : : }
298 : :
299 : :
300 : 1666 : const String& SbiSymDef::GetName()
301 : : {
302 [ + + ]: 1666 : if( pIn )
303 : 325 : aName = pIn->rStrings.Find( nId );
304 : 1666 : return aName;
305 : : }
306 : :
307 : :
308 : 4484 : void SbiSymDef::SetType( SbxDataType t )
309 : : {
310 [ + + ][ + + ]: 4484 : if( t == SbxVARIANT && pIn )
311 : : {
312 : 1684 : sal_Unicode cu = aName.GetBuffer()[0];
313 [ + - ]: 1684 : if( cu < 256 )
314 : : {
315 : 1684 : char ch = (char)aName.GetBuffer()[0];
316 [ - + ]: 1684 : if( ch == '_' ) ch = 'Z';
317 : 1684 : int ch2 = toupper( ch );
318 : 1684 : unsigned char c = (unsigned char)ch2;
319 [ + - ][ + - ]: 1684 : if( c > 0 && c < 128 )
320 : 1684 : t = pIn->pParser->eDefTypes[ ch2 - 'A' ];
321 : : }
322 : : }
323 : 4484 : eType = t;
324 : 4484 : }
325 : :
326 : : // construct a backchain, if not yet defined
327 : : // the value that shall be stored as an operand is returned
328 : :
329 : 16 : sal_uInt32 SbiSymDef::Reference()
330 : : {
331 [ + - ]: 16 : if( !bChained )
332 : : {
333 : 16 : sal_uInt32 n = nChain;
334 : 16 : nChain = pIn->pParser->aGen.GetOffset();
335 : 16 : return n;
336 : : }
337 : 16 : else return nChain;
338 : : }
339 : :
340 : :
341 : 213 : sal_uInt32 SbiSymDef::Define()
342 : : {
343 : 213 : sal_uInt32 n = pIn->pParser->aGen.GetPC();
344 : 213 : pIn->pParser->aGen.GenStmnt();
345 [ + + ]: 213 : if( nChain ) pIn->pParser->aGen.BackChain( nChain );
346 : 213 : nChain = n;
347 : 213 : bChained = true;
348 : 213 : return nChain;
349 : : }
350 : :
351 : : // A symbol definition may have its own pool. This is the caseDies ist
352 : : // for objects and procedures (local variable)
353 : :
354 : 1210 : SbiSymPool& SbiSymDef::GetPool()
355 : : {
356 [ + + ]: 1210 : if( !pPool )
357 [ + - ]: 271 : pPool = new SbiSymPool( pIn->pParser->aGblStrings, SbLOCAL ); // is dumped
358 : 1210 : return *pPool;
359 : : }
360 : :
361 : 11513 : SbiSymScope SbiSymDef::GetScope() const
362 : : {
363 [ + - ]: 11513 : return pIn ? pIn->GetScope() : SbLOCAL;
364 : : }
365 : :
366 : :
367 : : // The procedure definition has three pools:
368 : : // 1) aParams: is filled by the definition. Contains the
369 : : // parameters' names, like they're used inside the body.
370 : : // The first element is the return value.
371 : : // 2) pPool: all local variables
372 : : // 3) aLabels: labels
373 : :
374 : 647 : SbiProcDef::SbiProcDef( SbiParser* pParser, const String& rName,
375 : : bool bProcDecl )
376 : : : SbiSymDef( rName )
377 : : , aParams( pParser->aGblStrings, SbPARAM ) // is dumped
378 : : , aLabels( pParser->aLclStrings, SbLOCAL ) // is not dumped
379 [ + - ][ + - ]: 647 : , mbProcDecl( bProcDecl )
[ + - ][ + - ]
[ + - ]
380 : : {
381 : 647 : aParams.SetParent( &pParser->aPublics );
382 [ + - ][ + - ]: 647 : pPool = new SbiSymPool( pParser->aGblStrings, SbLOCAL );
383 : 647 : pPool->SetParent( &aParams );
384 : : nLine1 =
385 : 647 : nLine2 = 0;
386 : 647 : mePropMode = PROPERTY_MODE_NONE;
387 : 647 : bPublic = true;
388 : 647 : bCdecl = false;
389 : 647 : bStatic = false;
390 : : // For return values the first element of the parameter
391 : : // list is always defined with name and type of the proc
392 [ + - ]: 647 : aParams.AddSym( aName );
393 : 647 : }
394 : :
395 [ + - ][ + - ]: 647 : SbiProcDef::~SbiProcDef()
[ + - ][ + - ]
[ + - ]
396 [ - + ]: 1294 : {}
397 : :
398 : 1109 : SbiProcDef* SbiProcDef::GetProcDef()
399 : : {
400 : 1109 : return this;
401 : : }
402 : :
403 : 1070 : void SbiProcDef::SetType( SbxDataType t )
404 : : {
405 : 1070 : SbiSymDef::SetType( t );
406 : 1070 : aParams.Get( 0 )->SetType( eType );
407 : 1070 : }
408 : :
409 : : // match with a forward-declaration
410 : : // if the match is OK, pOld is replaced by this in the pool
411 : : // pOld is deleted in any case!
412 : :
413 : 74 : void SbiProcDef::Match( SbiProcDef* pOld )
414 : : {
415 : 74 : SbiSymDef* po, *pn=NULL;
416 : : // parameter 0 is the function name
417 : : sal_uInt16 i;
418 [ + + ]: 160 : for( i = 1; i < aParams.GetSize(); i++ )
419 : : {
420 : 86 : po = pOld->aParams.Get( i );
421 : 86 : pn = aParams.Get( i );
422 : : // no type matching - that is done during running
423 : : // but is it maybe called with too little parameters?
424 [ - + ][ # # ]: 86 : if( !po && !pn->IsOptional() && !pn->IsParamArray() )
[ - + ][ + + ]
425 : 0 : break;
426 : 86 : po = pOld->aParams.Next();
427 : : }
428 : :
429 [ + + ][ - + ]: 74 : if( pn && i < aParams.GetSize() && pOld->pIn )
[ # # ][ - + ]
430 : : {
431 : : // mark the whole line
432 : 0 : pOld->pIn->GetParser()->SetCol1( 0 );
433 [ # # ]: 0 : pOld->pIn->GetParser()->Error( SbERR_BAD_DECLARATION, aName );
434 : : }
435 [ + - ][ + - ]: 74 : if( !pIn && pOld->pIn )
436 : : {
437 : : // Replace old entry with the new one
438 : 74 : pOld->pIn->aData[ pOld->nPos ] = this;
439 : 74 : nPos = pOld->nPos;
440 : 74 : nId = pOld->nId;
441 : 74 : pIn = pOld->pIn;
442 : : }
443 [ + - ]: 74 : delete pOld;
444 : 74 : }
445 : :
446 : 197 : void SbiProcDef::setPropertyMode( PropertyMode ePropMode )
447 : : {
448 : 197 : mePropMode = ePropMode;
449 [ - + ]: 197 : if( mePropMode != PROPERTY_MODE_NONE )
450 : : {
451 : : // Prop name = original scanned procedure name
452 [ # # ]: 0 : maPropName = aName;
453 : :
454 : : // CompleteProcName includes "Property xxx "
455 : : // to avoid conflicts with other symbols
456 [ # # ]: 0 : String aCompleteProcName;
457 [ # # ]: 0 : aCompleteProcName.AppendAscii( "Property " );
458 [ # # # # : 0 : switch( mePropMode )
# ]
459 : : {
460 [ # # ]: 0 : case PROPERTY_MODE_GET: aCompleteProcName.AppendAscii( "Get " ); break;
461 [ # # ]: 0 : case PROPERTY_MODE_LET: aCompleteProcName.AppendAscii( "Let " ); break;
462 [ # # ]: 0 : case PROPERTY_MODE_SET: aCompleteProcName.AppendAscii( "Set " ); break;
463 : : case PROPERTY_MODE_NONE:
464 : : OSL_FAIL( "Illegal PropertyMode PROPERTY_MODE_NONE" );
465 : 0 : break;
466 : : }
467 [ # # ]: 0 : aCompleteProcName += aName;
468 [ # # ][ # # ]: 0 : aName = aCompleteProcName;
469 : : }
470 : 197 : }
471 : :
472 : :
473 : :
474 : 519 : SbiConstDef::SbiConstDef( const String& rName )
475 [ + - ]: 519 : : SbiSymDef( rName )
476 : : {
477 : 519 : nVal = 0; eType = SbxINTEGER;
478 : 519 : }
479 : :
480 : 126 : void SbiConstDef::Set( double n, SbxDataType t )
481 : : {
482 : 126 : aVal.Erase(); nVal = n; eType = t;
483 : 126 : }
484 : :
485 : 393 : void SbiConstDef::Set( const String& n )
486 : : {
487 : 393 : aVal = n; nVal = 0; eType = SbxSTRING;
488 : 393 : }
489 : :
490 [ + - ]: 519 : SbiConstDef::~SbiConstDef()
491 [ - + ]: 1038 : {}
492 : :
493 : 826 : SbiConstDef* SbiConstDef::GetConstDef()
494 : : {
495 : 826 : return this;
496 : : }
497 : :
498 : 2407 : SbiSymbols::~SbiSymbols()
499 : : {
500 [ + - ][ + - ]: 5732 : for( const_iterator it = begin(); it != end(); ++it )
[ + + ]
501 [ + - ][ + - ]: 3325 : delete *it;
502 : 2407 : };
503 : :
504 : :
505 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|