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

Generated by: LCOV version 1.11