/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"

#include "sbcomp.hxx"
#include <stdio.h>
#include <string.h>
#include <ctype.h>

SV_IMPL_PTRARR(SbiStrings,String*)
SV_IMPL_PTRARR(SbiSymbols,SbiSymDef*)

// Alle Symbolnamen werden im Stringpool des Symbol-Pools abgelegt, damit
// alle Symbole im gleichen Case verarbeitet werden. Beim Speichern des
// Code-Images wird der globale Stringpool mit den entsprechenden Sympools
// gespeichert. Der lokale Stringpool nimmt alle Symbole auf, die nicht
// ins Image wandern (Labels, Konstantennamen etc).

/***************************************************************************
|*
|*	SbiStringPool
|*
***************************************************************************/

SbiStringPool::SbiStringPool( SbiParser* p )
{
	pParser = p;
}

SbiStringPool::~SbiStringPool()
{}

// Suchen

const String& SbiStringPool::Find( sal_uInt16 n ) const
{
	if( !n || n > aData.Count() )
		return aEmpty;
	else
		return *aData.GetObject( n-1 );
}

// Hinzufuegen eines Strings. Der String wird Case-Insensitiv
// verglichen.

short SbiStringPool::Add( const String& rVal, sal_Bool bNoCase )
{
	sal_uInt16 n = aData.Count();
	for( sal_uInt16 i = 0; i < n; i++ )
	{
		String* p = aData.GetObject( i );
		if( (  bNoCase && p->Equals( rVal ) )
		 || ( !bNoCase && p->EqualsIgnoreCaseAscii( rVal ) ) )
			return i+1;
	}
	const String* pNew = new String( rVal );
	aData.Insert( pNew, n++ );
	return (short) n;
}

short SbiStringPool::Add( double n, SbxDataType t )
{
	char buf[ 40 ];
	switch( t )
	{
        case SbxINTEGER: snprintf( buf, sizeof(buf), "%d", (short) n ); break;
        case SbxLONG:    snprintf( buf, sizeof(buf), "%ld", (long) n ); break;
        case SbxSINGLE:  snprintf( buf, sizeof(buf), "%.6g", (float) n ); break;
        case SbxDOUBLE:  snprintf( buf, sizeof(buf), "%.16g", n ); break;
		default: break;
	}
	return Add( String::CreateFromAscii( buf ) );
}

/***************************************************************************
|*
|*	SbiSymPool
|*
***************************************************************************/

SbiSymPool::SbiSymPool( SbiStringPool& r, SbiSymScope s ) : rStrings( r )
{
	pParser	 = r.GetParser();
	eScope   = s;
	pParent  = NULL;
	nCur	 =
	nProcId  = 0;
}

SbiSymPool::~SbiSymPool()
{}

// Inhalt loeschen

void SbiSymPool::Clear()
{
	aData.DeleteAndDestroy( 0, aData.Count() );
}

SbiSymDef* SbiSymPool::First()
{
	nCur = (sal_uInt16) -1;
	return Next();
}

SbiSymDef* SbiSymPool::Next()
{
	if( ++nCur >= aData.Count() )
		return NULL;
	else
		return aData.GetObject( nCur );
}

// Hinzufuegen eines Symbols

SbiSymDef* SbiSymPool::AddSym( const String& rName )
{
	SbiSymDef* p = new SbiSymDef( rName );
	p->nPos    = aData.Count();
	p->nId	   = rStrings.Add( rName );
	p->nProcId = nProcId;
	p->pIn	   = this;
	const SbiSymDef* q = p;
	aData.Insert( q, q->nPos );
	return p;
}

SbiProcDef* SbiSymPool::AddProc( const String& rName )
{
	SbiProcDef* p = new SbiProcDef( pParser, rName );
	p->nPos    = aData.Count();
	p->nId	   = rStrings.Add( rName );
	// Procs sind immer global
	p->nProcId = 0;
	p->pIn	   = this;
	const SbiSymDef* q = p;
	aData.Insert( q, q->nPos );
	return p;
}

// Hinzufuegen einer extern aufgebauten Symboldefinition

void SbiSymPool::Add( SbiSymDef* pDef )
{
	if( pDef && pDef->pIn != this )
	{
		if( pDef->pIn )
		{
#ifdef DBG_UTIL
			// schon in einem anderen Pool drin!
			pParser->Error( SbERR_INTERNAL_ERROR, "Dbl Pool" );
#endif
			return;
		}

		pDef->nPos = aData.Count();
		if( !pDef->nId )
		{
			// Bei statischen Variablen muss ein eindeutiger Name
			// im Stringpool erzeugt werden (Form ProcName:VarName)
			String aName( pDef->aName );
			if( pDef->IsStatic() )
			{
				aName = pParser->aGblStrings.Find( nProcId );
				aName += ':';
				aName += pDef->aName;
			}
			pDef->nId = rStrings.Add( aName );
		}
		// Procs sind immer global
		if( !pDef->GetProcDef() )
			pDef->nProcId = nProcId;
		pDef->pIn = this;
		const SbiSymDef* q = pDef;
		aData.Insert( q, q->nPos );
	}
}

// Suchen eines Eintrags ueber den Namen. Es wird auch im Parent gesucht.

SbiSymDef* SbiSymPool::Find( const String& rName ) const
{
	sal_uInt16 nCount = aData.Count();
	for( sal_uInt16 i = 0; i < nCount; i++ )
	{
		SbiSymDef* p = aData.GetObject( nCount - i - 1 );
		if( ( !p->nProcId || ( p->nProcId == nProcId ) )
		 && ( p->aName.EqualsIgnoreCaseAscii( rName ) ) )
			return p;
	}
	if( pParent )
		return pParent->Find( rName );
	else
		return NULL;
}

// Suchen ueber ID-Nummer

SbiSymDef* SbiSymPool::FindId( sal_uInt16 n ) const
{
	for( sal_uInt16 i = 0; i < aData.Count(); i++ )
	{
		SbiSymDef* p = aData.GetObject( i );
		if( p->nId == n && ( !p->nProcId || ( p->nProcId == nProcId ) ) )
			return p;
	}
	if( pParent )
		return pParent->FindId( n );
	else
		return NULL;
}

// Suchen ueber Position (ab 0)

SbiSymDef* SbiSymPool::Get( sal_uInt16 n ) const
{
	if( n >= aData.Count() )
		return NULL;
	else
		return aData.GetObject( n );
}

sal_uInt32 SbiSymPool::Define( const String& rName )
{
	SbiSymDef* p = Find( rName );
	if( p )
	{	if( p->IsDefined() )
			pParser->Error( SbERR_LABEL_DEFINED, rName );
	}
	else
		p = AddSym( rName );
	return p->Define();
}

sal_uInt32 SbiSymPool::Reference( const String& rName )
{
	SbiSymDef* p = Find( rName );
	if( !p )
		p = AddSym( rName );
	//Sicherheitshalber
	pParser->aGen.GenStmnt();
	return p->Reference();
}

// Alle offenen Referenzen anmaulen

void SbiSymPool::CheckRefs()
{
	for( sal_uInt16 i = 0; i < aData.Count(); i++ )
	{
		SbiSymDef* p = aData.GetObject( i );
		if( !p->IsDefined() )
			pParser->Error( SbERR_UNDEF_LABEL, p->GetName() );
	}
}

/***************************************************************************
|*
|*	Symbol-Definitionen
|*
***************************************************************************/

SbiSymDef::SbiSymDef( const String& rName ) : aName( rName )
{
	eType	 = SbxEMPTY;
	nDims	 = 0;
	nTypeId  = 0;
	nProcId  = 0;
	nId 	 = 0;
	nPos	 = 0;
	nLen	 = 0;
	nChain	 = 0;
	bAs		 =
	bNew	 =
	bStatic	 =
	bOpt	 =
	bParamArray =
	bWithEvents =
	bWithBrackets =
	bByVal	 =
	bChained =
    bGlobal  = sal_False;
	pIn		 =
	pPool	 = NULL;
	nDefaultId = 0;
	nFixedStringLength = -1;
}

SbiSymDef::~SbiSymDef()
{
	delete pPool;
}

SbiProcDef* SbiSymDef::GetProcDef()
{
	return NULL;
}

SbiConstDef* SbiSymDef::GetConstDef()
{
	return NULL;
}

// Wenn der Name benoetigt wird, den aktuellen Namen
// aus dem Stringpool nehmen

const String& SbiSymDef::GetName()
{
	if( pIn )
		aName = pIn->rStrings.Find( nId );
	return aName;
}

// Eintragen eines Datentyps

void SbiSymDef::SetType( SbxDataType t )
{
	if( t == SbxVARIANT && pIn )
	{
		sal_Unicode cu = aName.GetBuffer()[0];
		if( cu < 256 )
		{
			char ch = (char)aName.GetBuffer()[0];
			if( ch == '_' ) ch = 'Z';
			int ch2 = toupper( ch );
			unsigned char c = (unsigned char)ch2;
			if( c > 0 && c < 128 )
				t = pIn->pParser->eDefTypes[ ch2 - 'A' ];
		}
	}
	eType = t;
}

// Aufbau einer Backchain, falls noch nicht definiert
// Es wird der Wert zurueckgeliefert, der als Operand gespeichert
// werden soll.

sal_uInt32 SbiSymDef::Reference()
{
	if( !bChained )
	{
		sal_uInt32 n = nChain;
		nChain = pIn->pParser->aGen.GetOffset();
		return n;
	}
	else return nChain;
}

// Definition eines Symbols.
// Hier wird der Backchain aufgeloest, falls vorhanden

sal_uInt32 SbiSymDef::Define()
{
	sal_uInt32 n = pIn->pParser->aGen.GetPC();
	pIn->pParser->aGen.GenStmnt();
	if( nChain ) pIn->pParser->aGen.BackChain( nChain );
	nChain = n;
	bChained = sal_True;
	return nChain;
}

// Eine Symboldefinition kann einen eigenen Pool haben. Dies ist
// der Fall bei Objekten und Prozeduren (lokale Variable)

SbiSymPool& SbiSymDef::GetPool()
{
	if( !pPool )
		pPool = new SbiSymPool( pIn->pParser->aGblStrings, SbLOCAL );	// wird gedumpt
	return *pPool;
}

SbiSymScope SbiSymDef::GetScope() const
{
	return pIn ? pIn->GetScope() : SbLOCAL;
}

////////////////////////////////////////////////////////////////////////////

// Die Prozedur-Definition hat drei Pools:
// 1) aParams: wird durch die Definition gefuellt. Enthaelt die Namen
//	  der Parameter, wie sie innerhalb des Rumpfes verwendet werden.
//	  Das erste Element ist der Returnwert.
// 2) pPool: saemtliche lokale Variable
// 3) aLabels: Labels

SbiProcDef::SbiProcDef( SbiParser* pParser, const String& rName,
					    sal_Bool bProcDecl )
		 : SbiSymDef( rName )
		 , aParams( pParser->aGblStrings, SbPARAM )  // wird gedumpt
		 , aLabels( pParser->aLclStrings, SbLOCAL )	 // wird nicht gedumpt
		 , mbProcDecl( bProcDecl )
{
	aParams.SetParent( &pParser->aPublics );
	pPool = new SbiSymPool( pParser->aGblStrings, SbLOCAL ); // Locals
	pPool->SetParent( &aParams );
	nLine1	=
	nLine2	= 0;
	mePropMode = PROPERTY_MODE_NONE;
	bPublic = sal_True;
	bCdecl	= sal_False;
	bStatic = sal_False;
	// Fuer Returnwerte ist das erste Element der Parameterliste
	// immer mit dem Namen und dem Typ der Proc definiert
	aParams.AddSym( aName );
}

SbiProcDef::~SbiProcDef()
{}

SbiProcDef* SbiProcDef::GetProcDef()
{
	return this;
}

void SbiProcDef::SetType( SbxDataType t )
{
	SbiSymDef::SetType( t );
	aParams.Get( 0 )->SetType( eType );
}

// Match mit einer Forward-Deklaration
// Falls der Match OK ist, wird pOld durch this im Pool ersetzt
// pOld wird immer geloescht!

void SbiProcDef::Match( SbiProcDef* pOld )
{
	SbiSymDef* po, *pn=NULL;
	// Parameter 0 ist der Funktionsname
	sal_uInt16 i;
	for( i = 1; i < aParams.GetSize(); i++ )
	{
		po = pOld->aParams.Get( i );
		pn = aParams.Get( i );
		// Kein Typabgleich; das wird beim Laufen erledigt
		// aber ist sie evtl. mit zu wenigen Parametern aufgerufen
		// worden?
		if( !po && !pn->IsOptional() && !pn->IsParamArray() )
			break;
		po = pOld->aParams.Next();
	}
	// Wurden zu viele Parameter angegeben?
	if( pn && i < aParams.GetSize() && pOld->pIn )
	{
		// Die ganze Zeile markieren
		pOld->pIn->GetParser()->SetCol1( 0 );
		pOld->pIn->GetParser()->Error( SbERR_BAD_DECLARATION, aName );
	}
	if( !pIn && pOld->pIn )
	{
		// Alten Eintrag durch neuen ersetzen
		SbiSymDef** pData = (SbiSymDef**) pOld->pIn->aData.GetData();
		pData[ pOld->nPos ] = this;
		nPos = pOld->nPos;
		nId  = pOld->nId;
		pIn  = pOld->pIn;
	}
	delete pOld;
}

void SbiProcDef::setPropertyMode( PropertyMode ePropMode )
{
	mePropMode = ePropMode;
	if( mePropMode != PROPERTY_MODE_NONE )
	{
		// Prop name = original scanned procedure name
		maPropName = aName;

		// CompleteProcName includes "Property xxx "
		// to avoid conflicts with other symbols
		String aCompleteProcName;
		aCompleteProcName.AppendAscii( "Property " );
		switch( mePropMode )
		{
			case PROPERTY_MODE_GET:		aCompleteProcName.AppendAscii( "Get " ); break;
			case PROPERTY_MODE_LET:		aCompleteProcName.AppendAscii( "Let " ); break;
			case PROPERTY_MODE_SET:		aCompleteProcName.AppendAscii( "Set " ); break;
			case PROPERTY_MODE_NONE:
				DBG_ERROR( "Illegal PropertyMode PROPERTY_MODE_NONE" );
				break;
		}
		aCompleteProcName += aName;
		aName = aCompleteProcName;
	}
}


//////////////////////////////////////////////////////////////////////////

SbiConstDef::SbiConstDef( const String& rName )
		   : SbiSymDef( rName )
{
	nVal = 0; eType = SbxINTEGER;
}

void SbiConstDef::Set( double n, SbxDataType t )
{
	aVal.Erase(); nVal = n; eType = t;
}

void SbiConstDef::Set( const String& n )
{
	aVal = n; nVal = 0; eType = SbxSTRING;
}

SbiConstDef::~SbiConstDef()
{}

SbiConstDef* SbiConstDef::GetConstDef()
{
	return this;
}
