LCOV - code coverage report
Current view: top level - libreoffice/basic/source/comp - symtbl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 198 241 82.2 %
Date: 2012-12-17 Functions: 39 43 90.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10