// All symbol names are laid down int the symbol-pool's stringpool, so that // all symbols are handled in the same case. On saving the code-image, the // global stringpool with the respective symbols is also saved. // The local stringpool holds all the symbols that don't move to the image // (labels, constant names etc.).
SbiStringPool::SbiStringPool( )
{}
SbiStringPool::~SbiStringPool()
{}
const OUString & SbiStringPool::Find( sal_uInt32 n ) const
{ if( n == 0 || n > aData.size() ) return EMPTY_OUSTRING; else return aData[n - 1];
}
short SbiStringPool::Add( const OUString& rVal )
{
sal_uInt32 n = aData.size(); for( sal_uInt32 i = 0; i < n; ++i )
{
OUString& p = aData[i]; if( p == rVal ) return i+1;
}
short SbiStringPool::Add(double n, SbxDataType t)
{
size_t size = 0; const size_t aBufLength = 40; char buf[aBufLength]{};
// tdf#143707 - add the type character after the null termination of the string in order to // keep compatibility. After the type character has been added, the buffer contains the value // of the double n, the string termination symbol, and the type character. switch( t )
{ // tdf#142460 - properly handle boolean values in string pool case SbxBOOL:
size = snprintf(buf, sizeof(buf), "%d", static_cast<short>(n)) + 1;
buf[size++] = 'b'; break; // tdf#131296 - store numeric value including its type character // See GetSuffixType in basic/source/comp/scanner.cxx for type characters case SbxINTEGER:
size = snprintf(buf, sizeof(buf), "%d", static_cast<short>(n)) + 1;
buf[size++] = '%'; break; case SbxLONG:
size = snprintf(buf, sizeof(buf), "%" SAL_PRIdINT32, static_cast<sal_Int32>(n)) + 1;
buf[size++] = '&'; break; case SbxSINGLE:
size = snprintf(buf, sizeof(buf), "%.6g", static_cast<float>(n)) + 1;
buf[size++] = '!'; break; case SbxDOUBLE:
size = snprintf(buf, sizeof(buf), "%.16g", n) + 1;
buf[size++] = '#'; break; case SbxCURRENCY:
size = snprintf(buf, sizeof(buf), "%.16g", n) + 1;
buf[size++] = '@'; break; case SbxDATE: // tdf#168569 - support date values in string pool
size = snprintf(buf, sizeof(buf), "%.16g", n) + 1;
buf[size++] = 'd'; // Not in GetSuffixType break; default: assert(false); break; // should not happen
}
// tdf#143707 - add the content of the buffer to the string pool including its calculated length return Add(OUString::fromUtf8(std::string_view(buf, size)));
}
void SbiSymDef::SetType( SbxDataType t )
{ if( t == SbxVARIANT && pIn )
{ //See if there have been any deftype statements to set the default type //of a variable based on its starting letter
sal_Unicode cu = aName[0]; if( cu < 256 )
{ unsignedchar ch = static_cast<unsignedchar>(cu); if( ch == '_' )
{
ch = 'Z';
} int ch2 = rtl::toAsciiUpperCase( ch ); int nIndex = ch2 - 'A'; if (nIndex >= 0 && nIndex < N_DEF_TYPES)
t = pIn->pParser->eDefTypes[nIndex];
}
}
eType = t;
}
// construct a backchain, if not yet defined // the value that shall be stored as an operand is returned
// The procedure definition has three pools: // 1) aParams: is filled by the definition. Contains the // parameters' names, like they're used inside the body. // The first element is the return value. // 2) pPool: all local variables // 3) aLabels: labels
SbiProcDef::SbiProcDef( SbiParser* pParser, const OUString& rName, bool bProcDecl )
: SbiSymDef( rName )
, aParams( pParser->aGblStrings, SbPARAM, pParser ) // is dumped
, aLabels( pParser->aLclStrings, SbLOCAL, pParser ) // is not dumped
, mbProcDecl( bProcDecl )
{
aParams.SetParent( &pParser->aPublics );
pPool = std::make_unique<SbiSymPool>( pParser->aGblStrings, SbLOCAL, pParser );
pPool->SetParent( &aParams );
nLine1 =
nLine2 = 0;
mePropMode = PropertyMode::NONE;
bPublic = true;
bCdecl = false;
bStatic = false; // For return values the first element of the parameter // list is always defined with name and type of the proc
aParams.AddSym( aName );
}
void SbiProcDef::SetType( SbxDataType t )
{
SbiSymDef::SetType( t );
aParams.Get( 0 )->SetType( eType );
}
// match with a forward-declaration // if the match is OK, pOld is replaced by this in the pool // pOld is deleted in any case!
void SbiProcDef::Match( SbiProcDef* pOld )
{
SbiSymDef *pn=nullptr; // parameter 0 is the function name
sal_uInt16 i; for( i = 1; i < aParams.GetSize(); i++ )
{
SbiSymDef* po = pOld->aParams.Get( i );
pn = aParams.Get( i ); // no type matching - that is done during running // but is it maybe called with too little parameters? if( !po && !pn->IsOptional() && !pn->IsParamArray() )
{ break;
}
pOld->aParams.Next();
}
if( pn && i < aParams.GetSize() && pOld->pIn )
{ // mark the whole line
pOld->pIn->GetParser()->SetCol1( 0 );
pOld->pIn->GetParser()->Error( ERRCODE_BASIC_BAD_DECLARATION, aName );
}
if( !pIn && pOld->pIn )
{ // Replace old entry with the new one
nPos = pOld->nPos;
nId = pOld->nId;
pIn = pOld->pIn;
// don't delete pOld twice, if it's stored in m_Data if (pOld == pIn->m_Data[nPos].get())
pOld = nullptr;
pIn->m_Data[nPos].reset(this);
} delete pOld;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.