blob: 536111af515b4ef5f5d93b3901169f78dc389f84 [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 sept. 2014
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "TraceFactory.h"
#include <fstream>
#include <boost/algorithm/string.hpp>
#include <builder/Builder.h>
#include <computer/EvaluationEnvironment.h>
#include <fml/expression/AvmCode.h>
#include <fml/expression/AvmCode.h>
#include <fml/expression/BuiltinArray.h>
#include <fml/executable/AvmTransition.h>
#include <fml/executable/ExecutableQuery.h>
#include <fml/executable/ExecutableSystem.h>
#include <fml/operator/OperatorManager.h>
#include <fml/trace/BasicTraceParser.h>
#include <fml/trace/TracePoint.h>
#include <fml/trace/TraceSequence.h>
#include <fml/workflow/Query.h>
#include <fml/workflow/WObject.h>
#include <sew/Configuration.h>
#include <util/avm_string.h>
namespace sep
{
////////////////////////////////////////////////////////////////////////////////
// CONFIGURE API
////////////////////////////////////////////////////////////////////////////////
/*
// Declaration part
section POINT
@assign = "sens";
@newfresh = "sens";
@signal#sens = "sens";
@port = "env";
@input = "env";
@output = "env";
@output = "Thermostat->dt";
@input = "Thermostat->equip";
@output2 = "Equipment->error";
endsection POINT
section TRACE
@trace = ${ && "signal#sens" "output2" };
@trace = [ "signal#sens" , "output2" ];
@point = ( "signal#sens" || "output2" );
@composite = ${ xor "signal#sens" "output2" };
@assign = "sens";
@newfresh = "sens";
@signal = "sens";
@port = "env";
@input = "env";
@output = "env";
@output = "Thermostat->dt";
@input = "Thermostat->equip";
@output = "Equipment->error";
@transition = "Thermostat->transition#2#MSGm1#in";
@routine = "Thermostat->transition#2#MSGm1#in";
@machine = "Thermostat";
@state = "Thermostat->s4";
@formula = <expression>;
endsection TRACE
*/
static ENUM_TRACE_POINT::TRACE_NATURE to_nature(const std::string & id)
{
if( id.find("composite" ) == 0 ) return ENUM_TRACE_POINT::TRACE_COMPOSITE_NATURE;
if( id.find("comp" ) == 0 ) return ENUM_TRACE_POINT::TRACE_COMPOSITE_NATURE;
if( id.find("expression") == 0 ) return ENUM_TRACE_POINT::TRACE_COMPOSITE_NATURE;
if( id.find("expr" ) == 0 ) return ENUM_TRACE_POINT::TRACE_COMPOSITE_NATURE;
if( id.find("trace" ) == 0 ) return ENUM_TRACE_POINT::TRACE_COMPOSITE_NATURE;
if( id.find("point" ) == 0 ) return ENUM_TRACE_POINT::TRACE_COMPOSITE_NATURE;
if( id.find("com" ) == 0 ) return ENUM_TRACE_POINT::TRACE_COM_NATURE;
if( id.find("inout" ) == 0 ) return ENUM_TRACE_POINT::TRACE_COM_NATURE;
if( id.find("channel" ) == 0 ) return ENUM_TRACE_POINT::TRACE_CHANNEL_NATURE;
if( id.find("message" ) == 0 ) return ENUM_TRACE_POINT::TRACE_MESSAGE_NATURE;
if( id.find("port" ) == 0 ) return ENUM_TRACE_POINT::TRACE_PORT_NATURE;
if( id.find("signal" ) == 0 ) return ENUM_TRACE_POINT::TRACE_SIGNAL_NATURE;
if( id.find("time" ) == 0 ) return ENUM_TRACE_POINT::TRACE_TIME_NATURE;
if( id.find("var" ) == 0 ) return ENUM_TRACE_POINT::TRACE_VARIABLE_NATURE;
if( id.find("variable" ) == 0 ) return ENUM_TRACE_POINT::TRACE_VARIABLE_NATURE;
// if( id.find("assign" ) == 0 ) return ENUM_TRACE_POINT::TRACE_VARIABLE_NATURE;
// if( id.find("newfresh" ) == 0 ) return ENUM_TRACE_POINT::TRACE_VARIABLE_NATURE;
if( id.find("buffer" ) == 0 ) return ENUM_TRACE_POINT::TRACE_BUFFER_NATURE;
if( id.find("formula" ) == 0 ) return ENUM_TRACE_POINT::TRACE_FORMULA_NATURE;
if( id.find("condition" ) == 0 ) return ENUM_TRACE_POINT::TRACE_CONDITION_NATURE;
if( id.find("decision" ) == 0 ) return ENUM_TRACE_POINT::TRACE_DECISION_NATURE;
if( REGEX_MATCH(id, CONS_WID2("path", "condition")) ) {
return ENUM_TRACE_POINT::TRACE_PATH_CONDITION_NATURE;
}
if( REGEX_MATCH(id, CONS_WID2("node", "condition")) ) {
return ENUM_TRACE_POINT::TRACE_NODE_CONDITION_NATURE;
}
if( REGEX_MATCH(id, CONS_WID3("path", "condition", "leaf")) ) {
return ENUM_TRACE_POINT::TRACE_PATH_CONDITION_NATURE_LEAF;
}
if( REGEX_MATCH(id, CONS_WID3("node", "condition", "leaf")) ) {
return ENUM_TRACE_POINT::TRACE_NODE_CONDITION_NATURE_LEAF;
}
if( REGEX_MATCH(id, CONS_WID3("path", "timed", "condition")) ) {
return ENUM_TRACE_POINT::TRACE_PATH_TIMED_CONDITION_NATURE;
}
if( REGEX_MATCH(id, CONS_WID3("node", "timed", "condition")) ) {
return ENUM_TRACE_POINT::TRACE_NODE_TIMED_CONDITION_NATURE;
}
if( REGEX_MATCH(id, CONS_WID4(
"path", "timed", "condition", "(leaf|end|last|tail)")) ) {
return ENUM_TRACE_POINT::TRACE_PATH_TIMED_CONDITION_NATURE_LEAF;
}
if( REGEX_MATCH(id, CONS_WID4(
"node", "timed", "condition", "(leaf|end|last|tail)")) ) {
return ENUM_TRACE_POINT::TRACE_NODE_TIMED_CONDITION_NATURE_LEAF;
}
if( id.find("statemachine") == 0 ) return ENUM_TRACE_POINT::TRACE_STATEMACHINE_NATURE;
if( id.find("machine") == 0 ) return ENUM_TRACE_POINT::TRACE_MACHINE_NATURE;
if( id.find("state" ) == 0 ) return ENUM_TRACE_POINT::TRACE_STATE_NATURE;
if( id.find("transition") == 0 ) return ENUM_TRACE_POINT::TRACE_TRANSITION_NATURE;
if( id.find("routine" ) == 0 ) return ENUM_TRACE_POINT::TRACE_ROUTINE_NATURE;
if( id.find("runnable" ) == 0 ) return ENUM_TRACE_POINT::TRACE_RUNNABLE_NATURE;
if( REGEX_MATCH(id, CONS_WID2("step", "header")) ) {
return ENUM_TRACE_POINT::TRACE_STEP_HEADER_NATURE;
}
if( REGEX_MATCH(id, CONS_WID2("step", "begin" )) ) {
return ENUM_TRACE_POINT::TRACE_STEP_BEGIN_NATURE;
}
if( REGEX_MATCH(id, CONS_WID2("step", "end" )) ) {
return ENUM_TRACE_POINT::TRACE_STEP_END_NATURE;
}
if( REGEX_MATCH(id, CONS_WID2("init", "header")) ) {
return ENUM_TRACE_POINT::TRACE_INIT_HEADER_NATURE;
}
if( REGEX_MATCH(id, CONS_WID2("init", "begin" )) ) {
return ENUM_TRACE_POINT::TRACE_INIT_BEGIN_NATURE;
}
if( REGEX_MATCH(id, CONS_WID2("init", "end" )) ) {
return ENUM_TRACE_POINT::TRACE_INIT_END_NATURE;
}
if( id.find("comment" ) == 0 ) return ENUM_TRACE_POINT::TRACE_COMMENT_NATURE;
if( id.find("separator") == 0 ) return ENUM_TRACE_POINT::TRACE_SEPARATOR_NATURE;
if( id.find("newline" ) == 0 ) return ENUM_TRACE_POINT::TRACE_NEWLINE_NATURE;
// if( not id.empty() ) return ENUM_TRACE_POINT::TRACE_COMPOSITE_NATURE;
return ENUM_TRACE_POINT::TRACE_UNDEFINED_NATURE;
}
static AVM_OPCODE to_op(const std::string & id)
{
if( id.find("time" ) == 0 ) return AVM_OPCODE_TIMED_GUARD;
if( id.find("formula" ) == 0 ) return AVM_OPCODE_GUARD;
if( id.find("guard" ) == 0 ) return AVM_OPCODE_GUARD;
if( REGEX_MATCH(id,"check.sat") ) return AVM_OPCODE_CHECK_SAT;
if( id.find("assign" ) == 0 ) return AVM_OPCODE_ASSIGN;
if( id.find("newfresh" ) == 0 ) return AVM_OPCODE_ASSIGN_NEWFRESH;
if( REGEX_MATCH(id, CONS_WID2("input", "env")) ) return AVM_OPCODE_INPUT_ENV;
if( REGEX_MATCH(id, CONS_WID2("input", "rdv")) ) return AVM_OPCODE_INPUT_RDV;
if( id.find("input" ) == 0 ) return AVM_OPCODE_INPUT;
if( REGEX_MATCH(id, CONS_WID2("output", "env")) ) return AVM_OPCODE_OUTPUT_ENV;
if( REGEX_MATCH(id, CONS_WID2("output", "rdv")) ) return AVM_OPCODE_OUTPUT_RDV;
if( id.find("output" ) == 0 ) return AVM_OPCODE_OUTPUT;
return AVM_OPCODE_NULL;
}
bool TraceFactory::configure(
TraceSequence & aTraceElement, const ExecutionData * anED)
{
WObject * thePOINT = Query::getRegexWSequence(
mParameterWObject, OR_WID2("point", "POINT"));
if( (thePOINT != WObject::_NULL_) && thePOINT->hasOwnedElement() )
{
// if( configure(thePOINT, mDeclaredPoint, anED) )
// {
// //!! NOTHING
// }
mED = anED;
WObject::const_iterator itWfO = thePOINT->owned_begin();
WObject::const_iterator endWfO = thePOINT->owned_end();
for( ; itWfO != endWfO ; ++itWfO )
{
if( (*itWfO)->isWProperty() )
{
if( configure(mDeclaredPoint, *itWfO) )
{
mDeclaredPointID.append( (*itWfO)->getNameID() );
if( mDeclaredPoint.size() != mDeclaredPointID.size() )
{
AVM_OS_FATAL_ERROR_EXIT
<< "TracePoint Declaration Error !!!"
<< SEND_EXIT;
}
}
}
}
}
WObject * theTRACE = Query::getRegexWSequence(
mParameterWObject, OR_WID2("trace", "TRACE"));
if( (theTRACE != WObject::_NULL_) && theTRACE->hasOwnedElement() )
{
if( configure(theTRACE, aTraceElement, anED) )
{
//!! NOTHING
}
}
return( true );
}
bool TraceFactory::configure(
AvmCode * aTraceExpression, const ExecutionData * anED)
{
WObject * thePOINT = Query::getRegexWSequence(
mParameterWObject, OR_WID2("point", "POINT"));
if( (thePOINT != WObject::_NULL_) && thePOINT->hasOwnedElement() )
{
mED = anED;
WObject::const_iterator itWfO = thePOINT->owned_begin();
WObject::const_iterator endWfO = thePOINT->owned_end();
for( ; itWfO != endWfO ; ++itWfO )
{
if( (*itWfO)->isWProperty() )
{
if( configure(mDeclaredPoint, *itWfO) )
{
mDeclaredPointID.append( (*itWfO)->getNameID() );
if( mDeclaredPoint.size() != mDeclaredPointID.size() )
{
AVM_OS_FATAL_ERROR_EXIT
<< "TracePoint Declaration Error !!!"
<< SEND_EXIT;
}
}
}
}
}
WObject * theTRACE = Query::getRegexWSequence(
mParameterWObject, OR_WID2("trace", "TRACE"));
if( (theTRACE != WObject::_NULL_) && theTRACE->hasOwnedElement() )
{
if( configure(theTRACE, aTraceExpression, anED) )
{
//!! NOTHING
}
}
return( true );
}
bool TraceFactory::configure(WObject * aTraceSequence,
BFCollection & tracePoints, const ExecutionData * anED)
{
if( aTraceSequence == WObject::_NULL_ )
{
return( false );
}
else if( aTraceSequence->hasnoOwnedElement() )
{
return( true );
}
mED = anED;
WObject::const_iterator itWfO = aTraceSequence->owned_begin();
WObject::const_iterator endWfO = aTraceSequence->owned_end();
for( ; itWfO != endWfO ; ++itWfO )
{
if( (*itWfO)->isWProperty() )
{
if( configure(tracePoints, *itWfO ) )
{
//!! NOTHING
}
}
}
return( true );
}
bool TraceFactory::configure(WObject * aTraceSequence,
TraceSequence & aTraceElement, const ExecutionData * anED)
{
if( aTraceSequence == NULL )
{
return( false );
}
else if( aTraceSequence->hasnoOwnedElement() )
{
return( true );
}
mED = anED;
WObject::const_iterator itWfO = aTraceSequence->owned_begin();
WObject::const_iterator endWfO = aTraceSequence->owned_end();
if( (*itWfO)->isWProperty() )
{
if( (*itWfO)->getNameID() == "combinator" )
{
aTraceElement.combinator = OperatorManager::toOperator(
(*itWfO)->toStringValue(),
OperatorManager::OPERATOR_OR );
++itWfO;
}
}
for( ; itWfO != endWfO ; ++itWfO )
{
if( (*itWfO)->isWProperty() )
{
if( configure(aTraceElement.points, *itWfO ) )
{
//!! NOTHING
}
}
}
return( true );
}
bool TraceFactory::configure(WObject * aTraceSequence,
AvmCode * aTraceExpression, const ExecutionData * anED)
{
if( aTraceSequence == NULL )
{
return( false );
}
else if( aTraceSequence->hasnoOwnedElement() )
{
return( true );
}
mED = anED;
WObject::const_iterator itWfO = aTraceSequence->owned_begin();
WObject::const_iterator endWfO = aTraceSequence->owned_end();
if( (*itWfO)->isWProperty() )
{
if( (*itWfO)->getNameID() == "combinator" )
{
// aTraceExpression->setOperator( OperatorManager::toOperator(
// wfProperty->toStringValue(), OperatorManager::OPERATOR_OR) );
AvmCode * subFTP = new AvmCode( OperatorManager::toOperator(
(*itWfO)->toStringValue(),OperatorManager::OPERATOR_OR) );
aTraceExpression->append( BF(subFTP) );
aTraceExpression = subFTP;
++itWfO;
}
}
for( ; itWfO != endWfO ; ++itWfO )
{
if( (*itWfO)->isWProperty() )
{
if( (*itWfO)->getNameID() == "combinator" )
{
AvmCode * subFTP = new AvmCode(OperatorManager::toOperator(
(*itWfO)->toStringValue(),
OperatorManager::OPERATOR_OR) );
aTraceExpression->append( BF(subFTP) );
aTraceExpression = subFTP;
}
else if( configure(aTraceExpression->getArgs(), *itWfO) )
{
//!! NOTHING
}
}
}
return( true );
}
bool TraceFactory::configure(
BFCollection & tracePoints, WObject * wfProperty)
{
ENUM_TRACE_POINT::TRACE_NATURE nature = to_nature( wfProperty->getNameID() );
AVM_OPCODE opNature = to_op( wfProperty->getNameID() );
if( (nature == ENUM_TRACE_POINT::TRACE_PATH_CONDITION_NATURE)
&& (nature == ENUM_TRACE_POINT::TRACE_PATH_TIMED_CONDITION_NATURE)
&& (nature == ENUM_TRACE_POINT::TRACE_NODE_CONDITION_NATURE)
&& (nature == ENUM_TRACE_POINT::TRACE_NODE_TIMED_CONDITION_NATURE)
&& (nature == ENUM_TRACE_POINT::TRACE_PATH_CONDITION_NATURE_LEAF)
&& (nature == ENUM_TRACE_POINT::TRACE_PATH_TIMED_CONDITION_NATURE_LEAF)
&& (nature == ENUM_TRACE_POINT::TRACE_NODE_CONDITION_NATURE_LEAF)
&& (nature == ENUM_TRACE_POINT::TRACE_NODE_TIMED_CONDITION_NATURE_LEAF) )
{
bfTP = aTracePoint = new TracePoint(nature, AVM_OPCODE_SELECT);
if( not configureNodePathCondition(tracePoints, wfProperty->getValue()) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure <Node Path Condition> with value: "
<< wfProperty->toStringValue() << std::endl;
}
}
else if( wfProperty->hasBuiltinArrayValue() )
{
if( configureArray(tracePoints, wfProperty,
wfProperty->getBuiltinArrayValue(), nature, opNature) )
{
//!! NOTHING
}
}
else if( wfProperty->hasAvmCodeValue() )
{
if( (nature == ENUM_TRACE_POINT::TRACE_FORMULA_NATURE)
|| (nature == ENUM_TRACE_POINT::TRACE_CONDITION_NATURE)
|| (nature == ENUM_TRACE_POINT::TRACE_DECISION_NATURE) )
{
bfTP = aTracePoint = new TracePoint(nature, AVM_OPCODE_CHECK_SAT);
if( not configureFormula(tracePoints, wfProperty->getValue()) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Formula > with value: "
<< wfProperty->toStringValue() << std::endl;
}
}
else if( configureExpression(tracePoints, wfProperty,
wfProperty->getAvmCodeValue(), nature, opNature) )
{
//!! NOTHING
}
}
else
{
if( nature != ENUM_TRACE_POINT::TRACE_UNDEFINED_NATURE )
{
if( configure(tracePoints, wfProperty,
nature, wfProperty->toStringValue()) )
{
//!! NOTHING
}
}
else if( opNature != AVM_OPCODE_NULL )
{
if( configure(tracePoints, wfProperty,
opNature, wfProperty->toStringValue()) )
{
//!! NOTHING
}
}
}
return( true );
}
bool TraceFactory::configure(
BFCollection & tracePoints, WObject * wfProperty,
ENUM_TRACE_POINT::TRACE_NATURE nature, const std::string & object)
{
switch( nature )
{
case ENUM_TRACE_POINT::TRACE_COM_NATURE:
case ENUM_TRACE_POINT::TRACE_CHANNEL_NATURE:
case ENUM_TRACE_POINT::TRACE_MESSAGE_NATURE:
case ENUM_TRACE_POINT::TRACE_PORT_NATURE:
case ENUM_TRACE_POINT::TRACE_SIGNAL_NATURE:
{
bfTP = aTracePoint = new TracePoint(nature, AVM_OPCODE_NULL);
if( not configurePort(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Port > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_TIME_NATURE:
{
bfTP = aTracePoint = new TracePoint(nature, AVM_OPCODE_ASSIGN);
if( not configureTime(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Time > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_VARIABLE_NATURE:
{
bfTP = aTracePoint = new TracePoint(nature, AVM_OPCODE_ASSIGN);
if( not configureVariable(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Variable > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_BUFFER_NATURE:
{
bfTP = aTracePoint = new TracePoint(nature, AVM_OPCODE_NULL);
if( not configureBuffer(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Buffer > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_FORMULA_NATURE:
case ENUM_TRACE_POINT::TRACE_CONDITION_NATURE:
case ENUM_TRACE_POINT::TRACE_DECISION_NATURE:
{
bfTP = aTracePoint = new TracePoint(nature, AVM_OPCODE_CHECK_SAT);
if( not configureFormula(tracePoints, wfProperty->getValue()) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Formula > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_PATH_CONDITION_NATURE:
case ENUM_TRACE_POINT::TRACE_NODE_CONDITION_NATURE:
case ENUM_TRACE_POINT::TRACE_PATH_TIMED_CONDITION_NATURE:
case ENUM_TRACE_POINT::TRACE_NODE_TIMED_CONDITION_NATURE:
case ENUM_TRACE_POINT::TRACE_PATH_CONDITION_NATURE_LEAF:
case ENUM_TRACE_POINT::TRACE_NODE_CONDITION_NATURE_LEAF:
case ENUM_TRACE_POINT::TRACE_PATH_TIMED_CONDITION_NATURE_LEAF:
case ENUM_TRACE_POINT::TRACE_NODE_TIMED_CONDITION_NATURE_LEAF:
{
bfTP = aTracePoint = new TracePoint(nature, AVM_OPCODE_SELECT);
if( not configureNodePathCondition(tracePoints, wfProperty->getValue()) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Node Path Condition > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_MACHINE_NATURE:
{
bfTP = aTracePoint = new TracePoint(nature, AVM_OPCODE_RUN);
if( not configureMachine(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Machine > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_STATEMACHINE_NATURE:
{
bfTP = aTracePoint = new TracePoint(nature, AVM_OPCODE_NULL);
if( not configureStatemachine(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Statemachine > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_STATE_NATURE:
{
bfTP = aTracePoint = new TracePoint(nature,
AVM_OPCODE_NULL /*AVM_OPCODE_ENABLE_SET*/);
if( not configureState(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < State > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_TRANSITION_NATURE:
{
bfTP = aTracePoint =
new TracePoint(nature, AVM_OPCODE_INVOKE_TRANSITION);
if( not configureTransition(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Transition > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_ROUTINE_NATURE:
{
bfTP = aTracePoint = new TracePoint(nature);
// new TracePoint(nature, AVM_OPCODE_INVOKE_ROUTINE);
if( not configureRoutine(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Routine > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_RUNNABLE_NATURE:
{
bfTP = aTracePoint = new TracePoint(nature);
if( not configureRunnable(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Runnable > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case ENUM_TRACE_POINT::TRACE_COMPOSITE_NATURE:
{
bfTP = aTracePoint = new TracePoint(nature, AVM_OPCODE_NULL);
if( not configureComposite(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Composite > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
default:
{
break;
}
}
if( (mED != NULL) && (aTracePoint != NULL) )
{
aTracePoint->updateRID( *mED );
}
return( true );
}
bool TraceFactory::configure(
BFCollection & tracePoints, WObject * wfProperty,
AVM_OPCODE opNature, const std::string & object)
{
switch( opNature )
{
case AVM_OPCODE_INPUT:
case AVM_OPCODE_INPUT_ENV:
case AVM_OPCODE_OUTPUT:
case AVM_OPCODE_OUTPUT_ENV:
{
bfTP = aTracePoint = new TracePoint(
ENUM_TRACE_POINT::TRACE_COM_NATURE, opNature);
if( not configurePort(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Port > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
case AVM_OPCODE_TIMED_GUARD:
{
break;
}
case AVM_OPCODE_ASSIGN:
case AVM_OPCODE_ASSIGN_NEWFRESH:
{
bfTP = aTracePoint = new TracePoint(
ENUM_TRACE_POINT::TRACE_VARIABLE_NATURE, opNature);
if( not configureVariable(tracePoints, object) )
{
wfProperty->warningLocation(AVM_OS_WARN)
<< "Failed to configure < Variable > with value: "
<< wfProperty->toStringValue() << std::endl;
}
break;
}
default:
{
break;
}
}
if( (mED != NULL) && (aTracePoint != NULL) )
{
aTracePoint->updateRID( *mED );
}
return( true );
}
bool TraceFactory::configureArray(BFCollection & tracePoints,
WObject * wfProperty, BuiltinArray * anArray,
ENUM_TRACE_POINT::TRACE_NATURE nature, AVM_OPCODE opNature)
{
BFVector tpArray;
for( avm_size_t offset = 0 ; offset < anArray->size() ; ++offset )
{
if( nature != ENUM_TRACE_POINT::TRACE_UNDEFINED_NATURE )
{
if( configure(tpArray, wfProperty, nature,
wfProperty->toStringValue(anArray, offset)) )
{
//!! NOTHING
}
}
else if( opNature != AVM_OPCODE_NULL )
{
if( configure(tpArray, wfProperty, opNature,
wfProperty->toStringValue(anArray, offset)) )
{
//!! NOTHING
}
}
}
if( tpArray.singleton() )
{
tracePoints.append( tpArray[0] );
}
else if( tpArray.populated() )
{
bfTP = aTracePoint = new TracePoint(
ENUM_TRACE_POINT::TRACE_COMPOSITE_NATURE, AVM_OPCODE_AND);
aTracePoint->tpid = ++TP_ID;
aTracePoint->value = BF( new ArrayBF(tpArray) );
tracePoints.append( bfTP );
}
return( true );
}
bool TraceFactory::configureExpression(BFCollection & tracePoints,
WObject * wfProperty, AvmCode * aCode,
ENUM_TRACE_POINT::TRACE_NATURE nature, AVM_OPCODE opNature)
{
BFVector tpArray;
AvmCode::const_iterator itArg = aCode->begin();
AvmCode::const_iterator endArg = aCode->end();
for( ; itArg != endArg ; ++itArg )
{
if( (*itArg).is< AvmCode >() )
{
if( configureExpression(tpArray, wfProperty,
(*itArg).to_ptr< AvmCode >(), nature, opNature) )
{
//!! NOTHING
}
}
else if( nature != ENUM_TRACE_POINT::TRACE_UNDEFINED_NATURE )
{
if( configure(tpArray, wfProperty,
nature, wfProperty->toStringValue(*itArg)) )
{
//!! NOTHING
}
}
else if( opNature != AVM_OPCODE_NULL )
{
if( configure(tpArray, wfProperty,
opNature, wfProperty->toStringValue(*itArg)) )
{
//!! NOTHING
}
}
}
if( tpArray.singleton() )
{
tracePoints.append( tpArray[0] );
}
else if( tpArray.populated() )
{
bfTP = aTracePoint = new TracePoint(
ENUM_TRACE_POINT::TRACE_COMPOSITE_NATURE,
aCode->getAvmOpCode());
aTracePoint->tpid = ++TP_ID;
aTracePoint->value = BF( new ArrayBF(tpArray) );
tracePoints.append( bfTP );
}
return( true );
}
bool TraceFactory::configureComposite(
BFCollection & tracePoints, const std::string & object)
{
for( avm_size_t offset = 0 ; offset < mDeclaredPoint.size() ; ++offset )
{
if( mDeclaredPointID[offset] == object )
{
tracePoints.append( mDeclaredPoint[offset] );
// if break: append first else: any Point with this ID
// break;
}
}
return( true );
}
bool TraceFactory::configurePort(
BFCollection & tracePoints, const std::string & object)
{
otherTracePoint.clear();
if( aTracePoint->configurePort(mConfiguration, object, otherTracePoint) )
{
aTracePoint->tpid = ++TP_ID;
listOfPortTracePoint.append( aTracePoint );
listOfPortTracePoint.append( otherTracePoint );
tracePoints.append( bfTP );
while( otherTracePoint.nonempty() )
{
otherTracePoint.front()->tpid = ++TP_ID;
tracePoints.append( BF(otherTracePoint.front()) );
otherTracePoint.pop_front();
}
}
else
{
return( false );
}
return( true );
}
bool TraceFactory::configureTime(
BFCollection & tracePoints, const std::string & object)
{
if( NamedElement::fqnStartsWith(object, "time" ) ||
NamedElement::fqnStartsWith(object, "$time") ||
NamedElement::fqnStartsWith(object, "#time") )
{
aTracePoint->tpid = ++TP_ID;
aTracePoint->op = AVM_OPCODE_TIMED_GUARD;
aTracePoint->object = mVarTime;
tracePoints.append( bfTP );
}
else if( aTracePoint->configureVariable(mConfiguration, object) )
{
aTracePoint->tpid = ++TP_ID;
aTracePoint->op = AVM_OPCODE_TIMED_GUARD;
mVarTime = aTracePoint->object->to< InstanceOfData >();
listOfVariableTracePoint.append( aTracePoint );
tracePoints.append( bfTP );
}
else
{
return( false );
}
return( true );
}
bool TraceFactory::configureVariable(
BFCollection & tracePoints, const std::string & object)
{
if( NamedElement::fqnStartsWith(object, "time" ) ||
NamedElement::fqnStartsWith(object, "$time") ||
NamedElement::fqnStartsWith(object, "#time") )
{
aTracePoint->tpid = ++TP_ID;
aTracePoint->nature = ENUM_TRACE_POINT::TRACE_TIME_NATURE;
aTracePoint->op = AVM_OPCODE_TIMED_GUARD;
aTracePoint->object = mVarTime;
tracePoints.append( bfTP );
}
else if( aTracePoint->configureVariable(mConfiguration, object) )
{
aTracePoint->tpid = ++TP_ID;
listOfVariableTracePoint.append( aTracePoint );
tracePoints.append( bfTP );
}
else
{
return( false );
}
return( true );
}
bool TraceFactory::configureBuffer(
BFCollection & tracePoints, const std::string & object)
{
if( aTracePoint->configureBuffer(mConfiguration, object) )
{
aTracePoint->tpid = ++TP_ID;
tracePoints.append( bfTP );
}
else
{
return( false );
}
return( true );
}
bool TraceFactory::configureFormula(
BFCollection & tracePoints, const BF & object)
{
aTracePoint->tpid = ++TP_ID;
// aTracePoint->value = ENV.getBuilder().compileExpression(
// mConfiguration.getExecutableSystem()
// .getSystemInstance().getExecutable(), object);
ENV.getBuilder().resetErrorWarning();
aTracePoint->value = ENV.getBuilder().
compileExpression(mLocalExecutableForm, object);
if( not ENV.getBuilder().hasError() )
{
tracePoints.append( bfTP );
}
return( true );
}
#define LEAF_NODE_REGEX_PATTERN "\\S?(leaf|end|last|tail)\\S?"
#define LEAF_NODE_DEFAULT_PATTERN ":leaf:"
bool TraceFactory::configureNodePathCondition(
BFCollection & tracePoints, const BF & object)
{
if( REGEX_MATCH( object.toBuiltinString() , LEAF_NODE_REGEX_PATTERN ) )
{
switch( aTracePoint->nature )
{
case ENUM_TRACE_POINT::TRACE_PATH_CONDITION_NATURE:
{
aTracePoint->nature =
ENUM_TRACE_POINT::TRACE_PATH_CONDITION_NATURE_LEAF;
break;
}
case ENUM_TRACE_POINT::TRACE_NODE_CONDITION_NATURE:
{
aTracePoint->nature =
ENUM_TRACE_POINT::TRACE_NODE_CONDITION_NATURE_LEAF;
break;
}
case ENUM_TRACE_POINT::TRACE_PATH_TIMED_CONDITION_NATURE:
{
aTracePoint->nature =
ENUM_TRACE_POINT::TRACE_PATH_TIMED_CONDITION_NATURE_LEAF;
break;
}
case ENUM_TRACE_POINT::TRACE_NODE_TIMED_CONDITION_NATURE:
{
aTracePoint->nature =
ENUM_TRACE_POINT::TRACE_NODE_TIMED_CONDITION_NATURE_LEAF;
break;
}
default:
{
break;
}
}
aTracePoint->any_object = true;
}
else if( object.toBuiltinString() == "[*]" )
{
aTracePoint->any_object = true;
}
else
{
aTracePoint->value = object;
}
aTracePoint->tpid = ++TP_ID;
tracePoints.append( bfTP );
return( true );
}
bool TraceFactory::configureMachine(
BFCollection & tracePoints, const std::string & object)
{
if( aTracePoint->configureMachine(mConfiguration, object) )
{
aTracePoint->tpid = ++TP_ID;
tracePoints.append( bfTP );
}
else
{
return( false );
}
return( true );
}
bool TraceFactory::configureState(
BFCollection & tracePoints, const std::string & object)
{
if( aTracePoint->configureMachine(mConfiguration, object) )
{
aTracePoint->tpid = ++TP_ID;
tracePoints.append( bfTP );
}
else
{
return( false );
}
return( true );
}
bool TraceFactory::configureStatemachine(
BFCollection & tracePoints, const std::string & object)
{
if( aTracePoint->configureMachine(mConfiguration, object) )
{
aTracePoint->tpid = ++TP_ID;
tracePoints.append( bfTP );
}
else
{
return( false );
}
return( true );
}
bool TraceFactory::configureTransition(
BFCollection & tracePoints, const std::string & object)
{
if( aTracePoint->configureTransition(mConfiguration, object) )
{
aTracePoint->tpid = ++TP_ID;
tracePoints.append( bfTP );
}
else
{
return( false );
}
return( true );
}
bool TraceFactory::configureRoutine(
BFCollection & tracePoints, const std::string & object)
{
if( aTracePoint->configureRoutine(mConfiguration, object) )
{
aTracePoint->tpid = ++TP_ID;
tracePoints.append( bfTP );
}
else
{
return( false );
}
return( true );
}
bool TraceFactory::configureRunnable(
BFCollection & tracePoints, const std::string & object)
{
if( aTracePoint->configureRunnable(mConfiguration, object) )
{
aTracePoint->tpid = ++TP_ID;
tracePoints.append( bfTP );
}
else
{
return( false );
}
return( true );
}
////////////////////////////////////////////////////////////////////////////////
// BASIC PARSER API
////////////////////////////////////////////////////////////////////////////////
/*
* Exemple de trace basique
1
TSI_target?1
120
RSD_ENABLED_source!1
0
PSD_ENABLED_source!1
423385
RSD_CMD_source!1
0
PSD_STATE1_target?0
3025646
DEP_AUTH1_source!1
1059822
TSI1_target?0
*/
bool TraceFactory::parseBasicTrace(TraceSequence & aTraceElement,
std::ifstream & inFile, const BF & aVarTime)
{
BasicTraceParser aParser( mConfiguration );
return( aParser.parseBasicTrace(aTraceElement, inFile, aVarTime) );
}
bool TraceFactory::parseBasicXliaTrace(TraceSequence & aTraceElement,
std::ifstream & inFile, const BF & aVarTime)
{
BasicTraceParser aParser( mConfiguration );
return( aParser.parseBasicXliaTrace(aTraceElement, inFile, aVarTime) );
}
////////////////////////////////////////////////////////////////////////////////
// OTHER API
////////////////////////////////////////////////////////////////////////////////
bool TraceFactory::appendTransitionPoint(const Configuration & aConfiguration,
TraceSequence & aTraceElement, const std::string & aTransitionUfid)
{
ExecutableQuery XQuery( aConfiguration );
const BF & foundTransition =
XQuery.getTransitionByQualifiedNameID(aTransitionUfid);
if( foundTransition.valid() )
{
BF newTransitionPoint( new TracePoint(
ENUM_TRACE_POINT::TRACE_TRANSITION_NATURE,
AVM_OPCODE_INVOKE_TRANSITION, NULL,
foundTransition.to_ptr< AvmTransition>()) );
aTraceElement.points.append( newTransitionPoint );
return( true );
}
return( false );
}
////////////////////////////////////////////////////////////////////////////////
// SERIALIZATION API
////////////////////////////////////////////////////////////////////////////////
void TraceFactory::toStream(OutStream & os, ListOfTracePoint & listofTracePoint) const
{
ListOfTracePoint::iterator itPoint = listofTracePoint.begin();
ListOfTracePoint::iterator endPoint = listofTracePoint.end();
for( ; itPoint != endPoint ; ++itPoint )
{
(*itPoint)->toStream(os);
}
}
} /* namespace sep */