blob: 28d2b484d4252b5dbfc8979d7d18a64fadcb9a45 [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: 11 déc. 2013
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "TraceFilter.h"
#include <computer/EvaluationEnvironment.h>
#include <fml/executable/ExecutableQuery.h>
#include <fml/executable/ExecutableSystem.h>
#include <fml/expression/BuiltinArray.h>
#include <fml/operator/OperatorManager.h>
#include <fml/template/TimedMachine.h>
#include <fml/runtime/ExecutionConfiguration.h>
#include <fml/trace/TraceFactory.h>
#include <fml/trace/TraceSequence.h>
#include <fml/workflow/Query.h>
#include <fml/workflow/WObject.h>
#include <sew/Configuration.h>
namespace sep
{
/*
prototype process::trace_generator as &avm::processor.TRACE_GENERATOR is
...
section TRACE
// AND --> conjunctive
// OR --> disjunctive
// XOR --> exclusive
// NOT --> negative
@combinator = 'OR';
@time = "$delta";
@time = "$time";
@assign = "sens";
@newfresh = "sens";
@signal = "sens";
@port = "env";
@input = "env";
@output = "env";
@output = "Thermostat->dt";
@input = "Thermostat->equip";
@output = "Equipment->error";
endsection TRACE
...
endprototype
*/
////////////////////////////////////////////////////////////////////////////////
// CONFIGURE API
////////////////////////////////////////////////////////////////////////////////
#define LEAF_NODE_REGEX_PATTERN "\\S?(leaf|end|last|tail)\\S?"
#define LEAF_NODE_DEFAULT_PATTERN ":leaf:"
bool TraceFilter::configure(EvaluationEnvironment & ENV,
WObject * wfParameterObject, WObject * wfTraceObject)
{
if( TimedMachine::SYSTEM_VAR_DELTA_TIME != NULL )
{
ExecutableQuery XQuery( ENV.getConfiguration() );
objectDeltaTime = XQuery.getDataByAstElement(
TimedMachine::SYSTEM_VAR_DELTA_TIME).to_ptr< InstanceOfData >();
}
// default main combinator
mainTracePointFiter.setOperator( OperatorManager::OPERATOR_OR );
// Configuration of TRACE
TraceFactory traceFactory(ENV.getConfiguration(),
ENV, wfParameterObject, NULL, objectDeltaTime);
if( not traceFactory.configure(wfTraceObject, (& mainTracePointFiter)) )
{
// return( false );
}
listOfVariableTracePoint.append( traceFactory.getVariableTracePoints() );
// Initialize Filter Point Flags
mConditionFlag = Query::hasRegexWProperty(wfTraceObject, "condition");
mDecisionFlag = mConditionFlag
|| Query::hasRegexWProperty(wfTraceObject, "decision");
if( mConditionFlag || mDecisionFlag )
{
mPathConditionFlag = mPathTimedConditionFlag = true;
mNodeConditionFlag = mNodeTimedConditionFlag = true;
mPathConditionLeafNodeFlag = mPathTimedConditionLeafNodeFlag = true;
mNodeConditionLeafNodeFlag = mNodeTimedConditionLeafNodeFlag = true;
}
else
{
mPathConditionFlag = not REGEX_MATCH(
Query::getRegexWPropertyString(wfTraceObject,
CONS_WID2("path", "condition"), LEAF_NODE_DEFAULT_PATTERN),
LEAF_NODE_REGEX_PATTERN );
mPathConditionLeafNodeFlag = mPathConditionFlag
|| Query::hasRegexWProperty(wfTraceObject,
CONS_WID3("path", "condition", "(leaf|end|last|tail)"))
|| REGEX_MATCH(Query::getRegexWPropertyString(
wfTraceObject, CONS_WID2("path", "condition"), ""),
LEAF_NODE_REGEX_PATTERN );
mNodeConditionFlag = not REGEX_MATCH(
Query::getRegexWPropertyString(wfTraceObject,
CONS_WID2("node", "condition"), LEAF_NODE_DEFAULT_PATTERN),
LEAF_NODE_REGEX_PATTERN );
mNodeConditionLeafNodeFlag = mNodeConditionFlag
|| Query::hasRegexWProperty(wfTraceObject,
CONS_WID3("node", "condition", "(leaf|end|last|tail)"))
|| REGEX_MATCH(Query::getRegexWPropertyString(
wfTraceObject, CONS_WID2("node", "condition"), ""),
LEAF_NODE_REGEX_PATTERN );
mPathTimedConditionFlag = not REGEX_MATCH(
Query::getRegexWPropertyString(wfTraceObject,
CONS_WID3("path", "timed", "condition"),
LEAF_NODE_DEFAULT_PATTERN),
LEAF_NODE_REGEX_PATTERN );
mPathTimedConditionLeafNodeFlag = mPathTimedConditionFlag
|| Query::hasRegexWProperty(wfTraceObject, CONS_WID4(
"path", "timed", "condition", "(leaf|end|last|tail)") )
|| REGEX_MATCH(Query::getRegexWPropertyString(wfTraceObject,
CONS_WID3("path", "timed", "condition"), ""),
LEAF_NODE_REGEX_PATTERN );
mNodeTimedConditionFlag = not REGEX_MATCH(
Query::getRegexWPropertyString(wfTraceObject,
CONS_WID3("node", "timed", "condition"),
LEAF_NODE_DEFAULT_PATTERN),
LEAF_NODE_REGEX_PATTERN );
mNodeTimedConditionLeafNodeFlag = mNodeTimedConditionFlag
|| Query::hasRegexWProperty(wfTraceObject, CONS_WID4(
"node", "timed", "condition", "(leaf|end|last|tail)") )
|| REGEX_MATCH(Query::getRegexWPropertyString(wfTraceObject,
CONS_WID3("node", "timed", "condition"), ""),
LEAF_NODE_REGEX_PATTERN );
}
mTimeFilterFlag = Query::hasRegexWProperty(wfTraceObject, "\\S?time");
mAssignFilterFlag = listOfVariableTracePoint.nonempty()
|| Query::hasWPropertyString(wfTraceObject, "variable", "var")
|| Query::hasWPropertyString(wfTraceObject, "assign" );
mNewfreshFilterFlag = Query::hasWPropertyString(wfTraceObject, "newfresh");
mComFilterFlag = Query::hasRegexWProperty(wfTraceObject, "com|inout");
if( mComFilterFlag )
{
mInputFilterFlag = true;
mInputExternalFilterFlag = mInputEnvFilterFlag = true;
mInputInternalFilterFlag = mInputRdvFilterFlag = true;
mOutputFilterFlag = true;
mOutputExternalFilterFlag = mOutputEnvFilterFlag = true;
mOutputInternalFilterFlag = mOutputRdvFilterFlag = true;
}
else
{
mInputEnvFilterFlag =
Query::hasRegexWProperty(wfTraceObject,
CONS_WID2("((in(p|o)ut)|com)", "env"));
mInputRdvFilterFlag =
Query::hasRegexWProperty(wfTraceObject,
CONS_WID2("((in(p|o)ut)|com)", "rdv"));
mInputExternalFilterFlag = mInputEnvFilterFlag
|| Query::hasRegexWProperty(wfTraceObject,
CONS_WID2("((in(p|o)ut)|com)", "external"));
mInputInternalFilterFlag = mInputRdvFilterFlag
|| Query::hasRegexWProperty(wfTraceObject,
CONS_WID2("((in(p|o)ut)|com)", "internal"));
mInputFilterFlag = mInputExternalFilterFlag
|| mInputInternalFilterFlag
|| Query::hasWPropertyString(wfTraceObject, "input");
mOutputEnvFilterFlag = Query::hasRegexWProperty(
wfTraceObject, CONS_WID2("output", "env"));
mOutputRdvFilterFlag = Query::hasRegexWProperty(
wfTraceObject, CONS_WID2("output", "rdv"));
mOutputExternalFilterFlag = mOutputEnvFilterFlag
|| Query::hasRegexWProperty(wfTraceObject,
CONS_WID2("(((outp|ino)ut)|com)", "external"));
mOutputInternalFilterFlag = mOutputRdvFilterFlag
|| Query::hasRegexWProperty(wfTraceObject,
CONS_WID2("(((outp|ino)ut)|com)", "internal"));
mOutputFilterFlag =
mOutputExternalFilterFlag || mOutputInternalFilterFlag
|| Query::hasWPropertyString(wfTraceObject, "output");
mComExternalFilterFlag =
mInputExternalFilterFlag || mOutputExternalFilterFlag
|| Query::hasRegexWProperty(
wfTraceObject, CONS_WID2("(com|inout)", "external"));
mComInternalFilterFlag =
mInputInternalFilterFlag || mOutputInternalFilterFlag
|| Query::hasRegexWProperty(wfTraceObject,
CONS_WID2("(com|inout)", "internal"));
mComFilterFlag = mInputFilterFlag || mOutputFilterFlag || containsCom();
}
mMachineFilterFlag =
Query::hasWPropertyString(wfTraceObject, "machine");
mStateFilterFlag =
Query::hasWPropertyString(wfTraceObject, "state");
mStatemachineFilterFlag =
Query::hasWPropertyString(wfTraceObject, "statemachine");
mTransitionFilterFlag =
Query::hasWPropertyString(wfTraceObject, "transition");
mRoutineFilterFlag =
Query::hasWPropertyString(wfTraceObject, "routine");
mIOTraceFilterFlag = mComFilterFlag || mNewfreshFilterFlag;
mRunnableFilterFlag = mMachineFilterFlag
|| mStateFilterFlag || mStatemachineFilterFlag
|| mTransitionFilterFlag || mRoutineFilterFlag;
// Update Filter Point Flags
//updateFilterFlags();
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRACE )
AVM_OS_TRACE << "TraceFilter:> "; toStream(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRACE )
return( true );
}
bool TraceFilter::configure(EvaluationEnvironment & ENV,
WObject * wfParameterObject, const std::string & aWSequenceNameID,
const std::string & aWSequenceElseNameID)
{
WObject * theTRACE = Query::getWSequenceOrElse(
wfParameterObject, aWSequenceNameID, aWSequenceElseNameID);
// if( (theTRACE == WObject::_NULL_) || theTRACE->hasnoOwnedElement() )
// {
// return( true );
// }
return( configure(ENV, wfParameterObject, theTRACE) );
}
/**
* Update
* Filter Point Flags
*/
//void TraceFilter::updateFilterFlags()
//{
// mPathConditionFlag = contains(
// ENUM_TRACE_POINT::TRACE_PATH_CONDITION_NATURE);
//
// mPathTimedConditionFlag = contains(
// ENUM_TRACE_POINT::TRACE_PATH_TIMED_CONDITION_NATURE);
//
// mNodeConditionFlag = contains(
// ENUM_TRACE_POINT::TRACE_NODE_CONDITION_NATURE);
//
// mNodeTimedConditionFlag = contains(
// ENUM_TRACE_POINT::TRACE_NODE_TIMED_CONDITION_NATURE);
//
// mTimeFilterFlag = contains(ENUM_TRACE_POINT::TRACE_TIME_NATURE);
//
// mTimeFilterFlag = contains(ENUM_TRACE_POINT::TRACE_TIME_NATURE);
//
// mAssignFilterFlag = listOfVariableTracePoint.nonempty() ||
// contains(ENUM_TRACE_POINT::TRACE_VARIABLE_NATURE);
//
// mNewfreshFilterFlag = contains(ENUM_TRACE_POINT::TRACE_VARIABLE_NATURE,
// AVM_OPCODE_ASSIGN_NEWFRESH);
//
// mInputEnvFilterFlag = contains(AVM_OPCODE_INPUT_ENV);
// mInputFilterFlag = contains(AVM_OPCODE_INPUT);
// mOutputEnvFilterFlag = contains(AVM_OPCODE_OUTPUT_ENV);
// mOutputFilterFlag = contains(AVM_OPCODE_OUTPUT);
//
// mMachineFilterFlag = contains(ENUM_TRACE_POINT::TRACE_MACHINE_NATURE);
// mStateFilterFlag = contains( ENUM_TRACE_POINT::TRACE_STATE_NATURE);
// mStatemachineFilterFlag = contains(ENUM_TRACE_POINT::TRACE_STATEMACHINE_NATURE);
//
// mTransitionFilterFlag = contains(ENUM_TRACE_POINT::TRACE_TRANSITION_NATURE);
// mRoutineFilterFlag = contains(ENUM_TRACE_POINT::TRACE_ROUTINE_NATURE);
//
//
// mComFilterFlag = mInputFilterFlag || mOutputFilterFlag || containsCom();
//
// mIOTraceFilterFlag = mComFilterFlag || mNewfreshFilterFlag;
//
// mRunnableFilterFlag = mMachineFilterFlag
// || mStateFilterFlag || mStatemachineFilterFlag
// || mTransitionFilterFlag || mRoutineFilterFlag
// || contains(ENUM_TRACE_POINT::TRACE_RUNNABLE_NATURE);
//}
/**
* Filter Point Flags
*/
bool TraceFilter::contains(ENUM_TRACE_POINT::TRACE_NATURE nature,
AVM_OPCODE op, AvmCode * aCode) const
{
AvmCode::const_iterator it = aCode->begin();
AvmCode::const_iterator endIt = aCode->end();
for( ; it != endIt ; ++it )
{
if( contains(nature, op, (*it)) )
{
return( true );
}
}
return( false );
}
bool TraceFilter::contains(ENUM_TRACE_POINT::TRACE_NATURE nature,
AVM_OPCODE op, const BF & arg) const
{
if( arg.is< TracePoint >() )
{
return( ((nature == ENUM_TRACE_POINT::TRACE_UNDEFINED_NATURE) ||
(arg.to_ptr< TracePoint >()->nature == nature)) &&
((op == AVM_OPCODE_NULL) ||
(arg.to_ptr< TracePoint >()->op == op)) );
}
else if( arg.is< AvmCode >() )
{
return( contains(nature, op, arg.to_ptr< AvmCode >()) );
}
else if( arg.is< TraceSequence >() )
{
BFList::const_iterator it = arg.to_ptr< TraceSequence >()->points.begin();
BFList::const_iterator endIt = arg.to_ptr< TraceSequence >()->points.end();
for( ; it != endIt ; ++it )
{
if( contains(nature, op, (*it)) )
{
return( true );
}
}
}
return( false );
}
////////////////////////////////////////////////////////////////////////////////
// FILTERING API : check if TRACE POINT pass
////////////////////////////////////////////////////////////////////////////////
bool TraceFilter::pass(TracePoint * filterTP, TracePoint * aTP)
{
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
AVM_OS_TRACE << TAB;
filterTP->toStream(AVM_OS_TRACE << AVM_TAB_INDENT);
AVM_OS_TRACE << END_INDENT;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
if( aTP->isVirtual() )
{
return( true );
}
else if( (filterTP->nature != ENUM_TRACE_POINT::TRACE_UNDEFINED_NATURE) )
{
if( (filterTP->nature != aTP->nature) )
{
if( aTP->nature == ENUM_TRACE_POINT::TRACE_MACHINE_NATURE )
{
if( filterTP->nature == ENUM_TRACE_POINT::TRACE_STATE_NATURE )
{
if( (aTP->object != NULL)
&& (not aTP->object->to< InstanceOfMachine >()->
getSpecifier().isFamilyComponentState()) )
{
return( false );
}
}
else if( filterTP->nature ==
ENUM_TRACE_POINT::TRACE_STATEMACHINE_NATURE )
{
if( (aTP->object != NULL)
&& (not aTP->object->to< InstanceOfMachine >()->
getSpecifier().isComponentStatemachine()) )
// && (not aTP->object->to< InstanceOfMachine >()->
// getSpecifier().isMocStateTransitionStructure()) )
{
return( false );
}
}
}
else if( (filterTP->nature != ENUM_TRACE_POINT::TRACE_COM_NATURE)
|| (not ENUM_TRACE_POINT::is_com(aTP->nature)) )
{
return( false );
}
}
}
if( (filterTP->op != AVM_OPCODE_NULL) && (filterTP->op != aTP->op) )
{
switch( filterTP->op )
{
case AVM_OPCODE_INPUT:
{
switch( aTP->op )
{
case AVM_OPCODE_INPUT:
case AVM_OPCODE_INPUT_BROADCAST:
case AVM_OPCODE_INPUT_BUFFER:
case AVM_OPCODE_INPUT_ENV:
case AVM_OPCODE_INPUT_FLOW:
case AVM_OPCODE_INPUT_FROM:
case AVM_OPCODE_INPUT_MULTI_RDV:
case AVM_OPCODE_INPUT_RDV:
case AVM_OPCODE_INPUT_DELEGATE:
case AVM_OPCODE_INPUT_VAR:
{
break;
}
default:
{
return( false );
}
}
break;
}
case AVM_OPCODE_OUTPUT:
{
switch( aTP->op )
{
case AVM_OPCODE_OUTPUT:
case AVM_OPCODE_OUTPUT_BROADCAST:
case AVM_OPCODE_OUTPUT_BUFFER:
case AVM_OPCODE_OUTPUT_ENV:
case AVM_OPCODE_OUTPUT_FLOW:
case AVM_OPCODE_OUTPUT_MULTI_RDV:
case AVM_OPCODE_OUTPUT_RDV:
case AVM_OPCODE_OUTPUT_TO:
case AVM_OPCODE_OUTPUT_DELEGATE:
case AVM_OPCODE_OUTPUT_VAR:
{
break;
}
default:
{
return( false );
}
}
break;
}
case AVM_OPCODE_ENABLE_SET:
{
switch( aTP->op )
{
case AVM_OPCODE_RUN:
case AVM_OPCODE_IRUN:
{
break;
}
default:
{
return( false );
}
}
break;
}
default:
{
return( false );
}
}
}
if( (filterTP->machine != NULL) && (filterTP->machine != aTP->machine) )
{
if( aTP->config != NULL )
{
if( filterTP->machine->getSpecifier().isDesignModel() )
{
RuntimeID aRID = aTP->config->getRuntimeID();
while( aRID.valid()
&& (aRID.getModelInstance() != filterTP->machine) )
{
aRID = aRID.getPRID();
}
if( aRID.invalid() )
{
return( false );
}
}
else
{
RuntimeID aRID = aTP->config->getRuntimeID();
while( aRID.valid() &&
(aRID.getInstance() != filterTP->machine) )
{
aRID = aRID.getPRID();
}
if( aRID.invalid() )
{
return( false );
}
}
}
}
if( (filterTP->object != NULL) && (filterTP->object != aTP->object) )
{
return( false );
}
if( filterTP->value.valid() && filterTP->value.isEQ(aTP->value) )
{
return( false );
}
return( true );
}
////////////////////////////////////////////////////////////////////////////////
// FILTERING API : check if VARIABLE pass
////////////////////////////////////////////////////////////////////////////////
bool TraceFilter::pass(const RuntimeID & aRID, InstanceOfData * aVariable)
{
if( listOfVariableTracePoint.nonempty() )
{
ListOfTracePoint::const_iterator it = listOfVariableTracePoint.begin();
ListOfTracePoint::const_iterator itEnd = listOfVariableTracePoint.end();
for( ; it != itEnd ; ++it )
{
if( pass(*it, aRID, aVariable) )
{
return( true );
}
}
}
return( false );
}
bool TraceFilter::pass(TracePoint * filterTP,
const RuntimeID & aRID, InstanceOfData * aVariable)
{
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
AVM_OS_TRACE << TAB;
filterTP->toStream(AVM_OS_TRACE << AVM_TAB_INDENT);
AVM_OS_TRACE << END_INDENT;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
if( filterTP->nature == ENUM_TRACE_POINT::TRACE_VARIABLE_NATURE )
{
if( filterTP->op == AVM_OPCODE_ASSIGN )
{
//!! IGNORED
}
if( (filterTP->machine == NULL)
|| ( (filterTP->machine == aRID.getInstance())
&& filterTP->machine->getSpecifier().hasDesignInstance() )
|| ( (filterTP->machine->getExecutable() == aRID.getExecutable())
&& filterTP->machine->getSpecifier().hasDesignModel() ) )
{
return( filterTP->any_object ||
(filterTP->object == aVariable) );
}
}
return( false );
}
////////////////////////////////////////////////////////////////////////////
// FILTERING API : check if Execution Trace
// a.k.a. ExecutionConfiguration pass
////////////////////////////////////////////////////////////////////////////
bool TraceFilter::pass(TracePoint * filterTP,
ExecutionConfiguration * anExecConfTP)
{
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
AVM_OS_TRACE << TAB;
filterTP->toStream(AVM_OS_TRACE << AVM_TAB_INDENT);
AVM_OS_TRACE << END_INDENT;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
if( anExecConfTP->isAvmCode() )
{
return( pass(filterTP, anExecConfTP->getAvmCode()) );
}
else if( anExecConfTP->isTransition() )
{
return( pass(filterTP, anExecConfTP->getRuntimeID(),
anExecConfTP->getTransition()) );
}
else if( anExecConfTP->isOperator() && (filterTP->op != AVM_OPCODE_NULL) )
{
AVM_OPCODE opcodeTP = anExecConfTP->getOperator()->getOptimizedOpCode();
if( (filterTP->op != AVM_OPCODE_NULL) && (filterTP->op != opcodeTP ) )
{
switch( filterTP->op )
{
case AVM_OPCODE_ENABLE_SET:
{
switch( opcodeTP )
{
case AVM_OPCODE_RUN:
case AVM_OPCODE_IRUN:
{
break;
}
default:
{
return( false );
}
}
break;
}
default:
{
return( false );
}
}
}
if( (filterTP->machine == NULL)
|| ( (filterTP->machine ==
anExecConfTP->getRuntimeID().getInstance())
&& filterTP->machine->getSpecifier().hasDesignInstance() )
|| ( (filterTP->machine->getExecutable() ==
anExecConfTP->getRuntimeID().getExecutable())
&& filterTP->machine->getSpecifier().hasDesignModel() ) )
{
return( true );
}
}
return( false );
}
////////////////////////////////////////////////////////////////////////////
// FILTERING API : check if a Compiled Element pass
////////////////////////////////////////////////////////////////////////////
bool TraceFilter::pass(TracePoint * filterTP,
const RuntimeID & aRID, BaseCompiledForm * anElement)
{
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
AVM_OS_TRACE << TAB;
filterTP->toStream(AVM_OS_TRACE << AVM_TAB_INDENT);
AVM_OS_TRACE << END_INDENT;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
if( (filterTP->machine == NULL)
|| ( (filterTP->machine == aRID.getInstance())
&& filterTP->machine->getSpecifier().hasDesignInstance() )
|| ( (filterTP->machine->getExecutable() == aRID.getExecutable())
&& filterTP->machine->getSpecifier().hasDesignModel() ) )
{
return( filterTP->any_object ||
(filterTP->object == anElement) );
}
return( false );
}
////////////////////////////////////////////////////////////////////////////
// FILTERING API : check if a Runtime Machine ID pass
////////////////////////////////////////////////////////////////////////////
bool TraceFilter::pass(TracePoint * filterTP, const RuntimeID & aRID)
{
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
AVM_OS_TRACE << TAB;
filterTP->toStream(AVM_OS_TRACE << AVM_TAB_INDENT);
AVM_OS_TRACE << END_INDENT;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
switch( filterTP->nature )
{
case ENUM_TRACE_POINT::TRACE_RUNNABLE_NATURE:
case ENUM_TRACE_POINT::TRACE_MACHINE_NATURE:
{
break;
}
case ENUM_TRACE_POINT::TRACE_STATE_NATURE:
{
if( not aRID.getSpecifier().isFamilyComponentState() )
{
return( false );
}
break;
}
case ENUM_TRACE_POINT::TRACE_STATEMACHINE_NATURE:
{
if( (not aRID.getSpecifier().isComponentStatemachine()) )
// && (not aRID.getSpecifier().isMocStateTransitionStructure()) )
{
return( false );
}
break;
}
default:
{
return( false );
}
}
if( filterTP->machine == NULL )
{
return( filterTP->any_object
|| (filterTP->object == aRID.getInstance()) );
}
else
{
return( ( (filterTP->machine == aRID.getInstance())
&& filterTP->machine->getSpecifier().hasDesignInstance() )
|| ( (filterTP->machine->getExecutable() == aRID.getExecutable())
&& filterTP->machine->getSpecifier().hasDesignModel() ) );
}
return( false );
}
////////////////////////////////////////////////////////////////////////////////
// FILTERING API : check if AVM CODE pass
////////////////////////////////////////////////////////////////////////////////
bool TraceFilter::pass(TracePoint * filterTP, AvmCode * aCodeTP)
{
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
AVM_OS_TRACE << TAB;
filterTP->toStream(AVM_OS_TRACE << AVM_TAB_INDENT);
AVM_OS_TRACE << END_INDENT;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRACE )
AVM_OPCODE opcodeTP = aCodeTP->getOptimizedOpCode();
if( (filterTP->op != AVM_OPCODE_NULL) && (filterTP->op != opcodeTP ) )
{
switch( filterTP->op )
{
case AVM_OPCODE_INPUT:
{
switch( opcodeTP )
{
case AVM_OPCODE_INPUT:
case AVM_OPCODE_INPUT_BROADCAST:
case AVM_OPCODE_INPUT_BUFFER:
case AVM_OPCODE_INPUT_ENV:
case AVM_OPCODE_INPUT_FLOW:
case AVM_OPCODE_INPUT_FROM:
case AVM_OPCODE_INPUT_MULTI_RDV:
case AVM_OPCODE_INPUT_RDV:
case AVM_OPCODE_INPUT_DELEGATE:
case AVM_OPCODE_INPUT_VAR:
{
break;
}
default:
{
return( false );
}
}
break;
}
case AVM_OPCODE_OUTPUT:
{
switch( opcodeTP )
{
case AVM_OPCODE_OUTPUT:
case AVM_OPCODE_OUTPUT_BROADCAST:
case AVM_OPCODE_OUTPUT_BUFFER:
case AVM_OPCODE_OUTPUT_ENV:
case AVM_OPCODE_OUTPUT_FLOW:
case AVM_OPCODE_OUTPUT_MULTI_RDV:
case AVM_OPCODE_OUTPUT_RDV:
case AVM_OPCODE_OUTPUT_TO:
case AVM_OPCODE_OUTPUT_DELEGATE:
case AVM_OPCODE_OUTPUT_VAR:
{
break;
}
default:
{
return( false );
}
}
break;
}
case AVM_OPCODE_ENABLE_SET:
{
switch( opcodeTP )
{
case AVM_OPCODE_RUN:
case AVM_OPCODE_IRUN:
{
break;
}
default:
{
return( false );
}
}
break;
}
default:
{
return( false );
}
}
}
if( aCodeTP->empty() )
{
return( true );
}
if( (filterTP->machine != NULL)
&& (aCodeTP->first() == filterTP->machine) )
{
return( true );
}
if( (filterTP->object != NULL)
&& (aCodeTP->first() == filterTP->object) )
{
return( true );
}
if( filterTP->value.valid() && aCodeTP->populated() )
{
if( filterTP->value.is< ArrayBF >() )
{
const ArrayBF & arrayValue = filterTP->value.to_ref< ArrayBF >();
avm_size_t arraySize = arrayValue.size();
if( arraySize == aCodeTP->size() )
{
AvmCode::const_iterator itTP = aCodeTP->begin();
for( avm_size_t offset = 0 ;
(offset < arraySize) ; ++offset , ++itTP )
{
if( not (*itTP).isEQ( arrayValue[offset] ) )
{
return( false );
}
}
return( true );
}
else
{
return( false );
}
}
else
{
return( filterTP->value.isEQ( aCodeTP->second() ) );
}
}
return( true );
}
////////////////////////////////////////////////////////////////////////////////
// SERIALIZATION API
////////////////////////////////////////////////////////////////////////////////
void TraceFilter::toStream(OutStream & os) const
{
os << TAB << "filter { "
<< OperatorLib::to_string(mainTracePointFiter.getAvmOpCode())
<< EOL_INCR_INDENT;
AvmCode::const_iterator it = mainTracePointFiter.begin();
AvmCode::const_iterator endIt = mainTracePointFiter.end();
for( ; it != endIt ; ++it )
{
(*it).toStream(os);
}
os << DECR_INDENT_TAB << "}" << EOL_FLUSH;
os << TAB << "flag [ " << EOL_INCR_INDENT
<< TAB << "Condition : [ " << mConditionFlag
<< " , decision:" << mDecisionFlag
<< " ]"<< EOL
<< TAB << "Trace_cond : [ path:" << mPathConditionFlag
<< " , node:" << mNodeConditionFlag
<< " ]"<< EOL
<< TAB << "Timed_cond : [ path:" << mPathTimedConditionFlag
<< " , node:" << mNodeTimedConditionFlag
<< " ]"<< EOL
<< TAB << "Leaf_cond : [ path:" << mPathConditionLeafNodeFlag
<< " , timed:" << mPathTimedConditionLeafNodeFlag
<< " ]"<< EOL
<< TAB << "Variable : [ time:" << mTimeFilterFlag
<< " , assign:" << mAssignFilterFlag
<< " , newfresh:" << mNewfreshFilterFlag
<< " ]"<< EOL
<< TAB << "Input : [ " << mInputFilterFlag
<< " , env:" << mInputEnvFilterFlag
<< " , rdv:" << mInputRdvFilterFlag << " ]"<< EOL
<< TAB << "Output : [ " << mOutputFilterFlag
<< " , env:" << mOutputEnvFilterFlag
<< " , rdv:" << mOutputRdvFilterFlag
<< " ]"<< EOL
<< TAB << "Machine : [ " << mMachineFilterFlag
<< " , state:" << mStateFilterFlag
<< " , statemachine:" << mStatemachineFilterFlag
<< " ]"<< EOL
<< TAB << "Routine : [ " << mRoutineFilterFlag
<< " , transition:" << mTransitionFilterFlag
<< " ]"<< EOL
<< TAB << "Abstract : [ com:" << mComFilterFlag
<< " , io#trace:" << mIOTraceFilterFlag
<< " , runnable:" << mRunnableFilterFlag
<< " ]"<< EOL
<< DECR_INDENT_TAB << "]" << EOL_FLUSH;
}
} /* namespace sep */