blob: f12e9673f7a20b0fd767bfba1900ea2be2a023bf [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Created on: 8 oct. 2008
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "BaseAvmProgram.h"
#include <fml/executable/AvmProgram.h>
#include <fml/executable/ExecutableForm.h>
#include <fml/type/BaseSymbolTypeSpecifier.h>
namespace sep
{
/**
* GETTER
* any SYMBOL filtering by an optional type specifier family
*/
const BF & BaseAvmProgram::getSymbol(
const std::string & aFullyQualifiedNameID,
avm_type_specifier_kind_t typeFamily) const
{
const BF & foundSymbol =
getAllData().getByFQNameID( aFullyQualifiedNameID );
if( foundSymbol.valid() )
{
return( foundSymbol );
}
return( getDataAlias().getByFQNameID( aFullyQualifiedNameID ) );
}
const BF & BaseAvmProgram::getSymbolByQualifiedNameID(
const std::string & aQualifiedNameID,
avm_type_specifier_kind_t typeFamily) const
{
const BF & foundSymbol =
getAllData().getByQualifiedNameID( aQualifiedNameID );
if( foundSymbol.valid() )
{
return( foundSymbol );
}
return( getDataAlias().getByQualifiedNameID( aQualifiedNameID ) );
}
const BF & BaseAvmProgram::getSymbolByNameID(
const std::string & aNameID, avm_type_specifier_kind_t typeFamily) const
{
const BF & foundSymbol = getAllData().getByNameID( aNameID );
if( foundSymbol.valid() )
{
return( foundSymbol );
}
return( getDataAlias().getByNameID(aNameID) );
}
const BF & BaseAvmProgram::getSymbolByAstElement(
const ObjectElement * astElement,
avm_type_specifier_kind_t typeFamily) const
{
const BF & foundSymbol = getAllData().getByAstElement( astElement );
if( foundSymbol.valid() )
{
return( foundSymbol );
}
return( getDataAlias().getByAstElement( astElement ) );
}
/**
* GETTER
* For AvmProgram - ExecutableForm Container
*/
const AvmProgram * BaseAvmProgram::getAvmProgramContainer() const
{
BaseAvmProgram * aContainer = getContainer();
while( (aContainer != NULL) && (not aContainer->is< AvmProgram >()) )
{
aContainer = aContainer->getContainer();
}
return( static_cast< const AvmProgram * >( aContainer ) );
}
const AvmProgram * BaseAvmProgram::getAvmProgram() const
{
if( this->is< AvmProgram >() )
{
return( static_cast< const AvmProgram * >( this ) );
}
return( getAvmProgramContainer() );
}
ExecutableForm * BaseAvmProgram::getExecutableContainer() const
{
BaseAvmProgram * aContainer = getContainer();
while( (aContainer != NULL) && aContainer->isnot< ExecutableForm >() )
{
aContainer = aContainer->getContainer();
}
return( static_cast< ExecutableForm * >( aContainer ) );
}
ExecutableForm * BaseAvmProgram::getExecutable() const
{
if( this->is< ExecutableForm >() )
{
return( static_cast< ExecutableForm * >(
const_cast< BaseAvmProgram * >(this) ) );
}
return( getExecutableContainer() );
}
/**
* UPDATE DATA TABLE
* mBasicData
* mallData
*/
void BaseAvmProgram::updateDataTable()
{
if( getData().empty() )
{
return;
}
TableOfInstanceOfData::raw_iterator itData = mData.begin();
TableOfInstanceOfData::raw_iterator endData = mData.end();
for( ; itData != endData ; ++itData )
{
if( (itData)->getTypeSpecifier()->hasTypeArrayOrStructure() &&
(not (itData)->getModifier().hasNatureReference()) )
{
break;
}
}
if( itData == endData )
{
mBasicData = &mData;
mAllData = &mData;
return;
}
if( mBasicData != &mData )
{
sep::destroy( mBasicData );
}
if( mAllData != &mData )
{
sep::destroy( mAllData );
}
// InstanceOfData * anInstance = getData().last();
TableOfInstanceOfData tableofAllData;
TableOfInstanceOfData tableofBasicData;
TableOfSymbol relativeDataPath;
// begin() --> it is typed simple
TableOfInstanceOfData::const_iterator it2 = mData.begin();
for( ; it2 != itData ; ++it2 )
{
tableofAllData.append( (*it2) );
tableofBasicData.append( (*it2) );
}
BaseTypeSpecifier * aTypeSpecifier = NULL;
// Analyse for it --> end()
for( ; itData != endData ; ++itData )
{
tableofAllData.append( (*itData) );
aTypeSpecifier = (itData)->referedTypeSpecifier();
if( (itData)->getModifier().hasNatureReference() )
{
tableofBasicData.append( (*itData) );
}
else if( aTypeSpecifier->hasTypeArrayOrStructure() )
{
collectAllData(tableofAllData, tableofBasicData,
(itData), relativeDataPath, (itData) );
}
else
{
tableofBasicData.append( (*itData) );
}
}
mAllData = new TableOfInstanceOfData(tableofAllData);
mBasicData = new TableOfInstanceOfData(tableofBasicData);
}
void BaseAvmProgram::collectAllData(TableOfInstanceOfData & tableofAllData,
TableOfInstanceOfData & tableofBasicData, InstanceOfData * mainInstance,
TableOfSymbol & relativeDataPath, InstanceOfData * anInstance)
{
std::string pefixID = anInstance->getNameID();
std::ostringstream ossID;
if( anInstance->getTypeSpecifier()->hasTypeStructureOrChoiceOrUnion() )
{
TableOfSymbol::iterator itField = anInstance->getTypeSpecifier()->
to< BaseSymbolTypeSpecifier >()->getSymbolData().begin();
TableOfSymbol::iterator it = anInstance->getAttribute()->begin();
TableOfSymbol::iterator itEnd = anInstance->getAttribute()->end();
for( ; it != itEnd ; ++it , ++itField )
{
ossID.str( "" );
ossID << pefixID << "."
<< NamedElement::extractNameID(
(*it).getFullyQualifiedNameID() );
InstanceOfData * newInstance = new InstanceOfData(
IPointerDataNature::POINTER_UFI_OFFSET_NATURE,
mainInstance->getContainer(), (*it).rawData());
newInstance->setSharedData( mainInstance );
newInstance->setNameID( ossID.str() );
relativeDataPath.append( *itField );
newInstance->setDataPath( relativeDataPath );
newInstance->setAliasTarget( (*it).rawData() );
(*it).setAliasTarget( newInstance );
const BF & saveInstance = tableofAllData.save( newInstance );
if( newInstance->getTypeSpecifier()->hasTypeSimpleOrCollection() )
{
tableofBasicData.append( saveInstance );
}
collectAllData(tableofAllData, tableofBasicData , mainInstance,
relativeDataPath, (*it).rawData());
relativeDataPath.pop_last();
}
}
else if( anInstance->getTypeSpecifier()->isTypedArray() )
{
TableOfSymbol::iterator it = anInstance->getAttribute()->begin();
TableOfSymbol::iterator itEnd = anInstance->getAttribute()->end();
for( ; it != itEnd ; ++it )
{
ossID.str( "" );
ossID << pefixID << "[" << (*it).getOffset() << "]";
InstanceOfData * newInstance = new InstanceOfData(
IPointerDataNature::POINTER_UFI_OFFSET_NATURE,
mainInstance->getContainer(), (*it).rawData());
newInstance->setSharedData( mainInstance );
newInstance->setNameID( ossID.str() );
relativeDataPath.append( *it );
newInstance->setDataPath( relativeDataPath );
(*it).setAliasTarget( newInstance );
const BF & saveInstance = tableofAllData.save( newInstance );
if( newInstance->getTypeSpecifier()->hasTypeSimpleOrCollection() )
{
tableofBasicData.append( saveInstance );
}
collectAllData(tableofAllData, tableofBasicData ,
mainInstance, relativeDataPath, (*it).rawData());
relativeDataPath.pop_last();
}
}
}
/**
* Serialization
*/
void BaseAvmProgram::toStream(OutStream & os) const
{
os << TAB << getModifier().toString()
<< "avmprogram " << getFullyQualifiedNameID();
AVM_DEBUG_REF_COUNTER(os);
os << " {" << EOL;
if( hasDataAlias() )
{
os << EOL << TAB << "alias:" << EOL_INCR_INDENT;
getDataAlias().toStream(os);
os << DECR_INDENT;
}
if( hasData() )
{
os << EOL << TAB << "variable:" << EOL_INCR_INDENT;
getData().toStream(os);
os << DECR_INDENT;
AVM_IF_DEBUG_FLAG( DATA )
if( mAllData != &mData )
{
os << EOL;
os << TAB << "variable#all:" << EOL_INCR_INDENT;
getAllData().toStream(os);
os << DECR_INDENT;
}
if( mBasicData != &mData )
{
os << EOL;
os << TAB << "variable#basic:" << EOL;
TableOfInstanceOfData::const_raw_iterator itData =
getBasicData().begin();
TableOfInstanceOfData::const_raw_iterator endData =
getBasicData().end();
for( ; itData != endData ; ++itData )
{
os << TAB2 << str_header( *itData ) << ";" << EOL;
}
}
AVM_ENDIF_DEBUG_FLAG( DATA )
}
os << TAB << "}" << EOL << std::flush;
}
}