| /******************************************************************************* | |
| * 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 | |
| * | |
| * Contributors: | |
| * Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr | |
| * - Initial API and implementation | |
| ******************************************************************************/ | |
| #include "Workflow.h" | |
| #include <builder/primitive/CompilationEnvironment.h> | |
| #include <collection/List.h> | |
| #include <collection/Typedef.h> | |
| #include <computer/PathConditionProcessor.h> | |
| #include <fml/runtime/ExecutionContext.h> | |
| #include <parser/ParserManager.h> | |
| #include <printer/Manipulators.h> | |
| #include <printer/OutStream.h> | |
| #include <sew/Configuration.h> | |
| #include <sew/SymbexEngine.h> | |
| #include <solver/api/SolverDef.h> | |
| #include <util/avm_debug.h> | |
| #include <util/avm_util.h> | |
| #include <iostream> | |
| #include <list> | |
| #include <string> | |
| namespace sep | |
| { | |
| /** | |
| * GLOBALS | |
| */ | |
| const std::string & Workflow::SECTION_WORKSPACE_REGEX_ID = | |
| OR_WID3( "workspace" , "WORKSPACE" , "LOCATION" ); | |
| const std::string & Workflow::SECTION_CONSOLE_REGEX_ID = | |
| OR_WID3( "console" , "CONSOLE" , "AVM" ); | |
| const std::string & Workflow::SECTION_DEVELOPER_REGEX_ID = | |
| OR_WID3( "developer" , "DEVELOPER" , "TRACE"); | |
| const std::string & Workflow::SECTION_DIRECTOR_REGEX_ID = | |
| OR_WID4( "director" , "DIRECTOR" , "MOC" , "RUNTIME"); | |
| const std::string & Workflow::SECTION_SHELL_REGEX_ID = | |
| OR_WID3( "shell" , "SHELL" , "AVM"); | |
| const std::string & Workflow::SECTION_SYMBEX_REGEX_ID = | |
| OR_WID3( "symbex" , "SYMBEX" , "AVM"); | |
| const std::string & Workflow::SECTION_TDD_REGEX_ID = | |
| OR_WID2( "tdd" , "TDD"); | |
| const std::string & Workflow::SECTION_FAM_REGEX_ID = | |
| OR_WID2(OR_WID4( "controller" , "worker" , "processor" , "filter" ), | |
| OR_WID4( "CONTROLLER" , "WORKER" , "PROCESSOR" , "FILTER" )); | |
| const std::string & Workflow::SECTION_FAM_CONTAINERS_REGEX_ID = | |
| OR_WID4(OR_WID4( "controller" , "worker" , "processor" , "filter" ), | |
| OR_WID4( "CONTROLLER" , "WORKER" , "PROCESSOR" , "FILTER" ), | |
| OR_WID3( "queue" , "pre_process" , "post_process" ), | |
| OR_WID3( "QUEUE" , "PRE_PROCESS" , "POST_PROCESS" )); | |
| // Deprecated | |
| const std::string & Workflow::SECTION_FAM_QUEUE_REGEX_ID = | |
| OR_WID2( "queue" , "QUEUE" ); | |
| const std::string & Workflow::SECTION_FAM_REDUNDANCY_REGEX_ID = | |
| OR_WID2( "redundancy" , "REDUNDANCY" ); | |
| const std::string & Workflow::SECTION_FAM_PROCESSOR_REGEX_ID = | |
| OR_WID2(OR_WID3( "controller" , "worker" , "processor" ), | |
| OR_WID3( "CONTROLLER" , "WORKER" , "PROCESSOR" )); | |
| const std::string & Workflow::SECTION_FAM_FILTER_REGEX_ID = | |
| OR_WID2( "filter" , "FILTER" ); | |
| const std::string & Workflow::SECTION_FAM_PREPROCESS_REGEX_ID = | |
| OR_WID2( "pre_process" , "PRE_PROCESS" ); | |
| const std::string & Workflow::SECTION_FAM_POSTPROCESS_REGEX_ID = | |
| OR_WID2( "post_process" , "POST_PROCESS" ); | |
| /** | |
| * SINGLETON | |
| */ | |
| Workflow * Workflow::INSTANCE = NULL; | |
| /** | |
| * LOADER | |
| */ | |
| bool Workflow::load() | |
| { | |
| return( true ); | |
| } | |
| /** | |
| * DISPOSER | |
| */ | |
| void Workflow::dispose() | |
| { | |
| mCurrentSymbexEngine = mMainSymbexEngine; | |
| for( ; mCurrentSymbexEngine != NULL ; mCurrentSymbexEngine = mMainSymbexEngine ) | |
| { | |
| mMainSymbexEngine = mMainSymbexEngine->getNextCore(); | |
| sep::destroy( mCurrentSymbexEngine ); | |
| mCurrentSymbexEngine = NULL; | |
| } | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| ///// AVM CONFIGURATION PARAMETER CHECKER | |
| //////////////////////////////////////////////////////////////////////////////// | |
| bool Workflow::loadConfiguration(const std::string & aWorkflowLocation) | |
| { | |
| mSEWFileLocation = aWorkflowLocation; | |
| // Checking WORKFLOW | |
| AVM_OS_COUT << _SEW_ | |
| << "Symbolic Execution based Workflow analysis ... START" | |
| << std::endl | |
| << _SEW_ << "Location: " << mSEWFileLocation << std::endl; | |
| // Load workflow definition file | |
| if( parseConfiguration() ) | |
| { | |
| AVM_OS_COUT << _SEW_ << "Loading filename: \"" | |
| << VFS::filename( mSEWFileLocation ) | |
| << "\" ... done !" << std::endl; | |
| } | |
| else | |
| { | |
| return( false ); | |
| } | |
| bool isOK = true; | |
| StringOutStream OS_INIT_LOG; | |
| // Configure core elements | |
| isOK = loadCoreElementsConfig(OS_INIT_LOG); | |
| // Set developer debug options | |
| isOK = loadWorkspaceLocationsConfig(OS_INIT_LOG) && isOK; | |
| // Initialize log & debug trace printers | |
| isOK = isOK && OutStream::configure(this); | |
| AVM_IF_DEBUG_LEVEL_FLAG2_AND(HIGH , PARSING , CONFIGURING , | |
| (mParameterWObject != WObject::_NULL_) ) | |
| std::string parseResultFile = VFS::suffixFilename( | |
| VFS::filename( mSEWFileLocation ), "_parsed", ".sew"); | |
| parseResultFile = VFS::native_path(parseResultFile, | |
| VFS::WorkspaceDebugPath.empty() | |
| ? VFS::parent( mSEWFileLocation ) | |
| : VFS::WorkspaceDebugPath ); | |
| OS_INIT_LOG << _DBG_ << "Saving of the parsed Workflow in text format ..." | |
| << std::endl; | |
| Configuration::saveElementTextualView( | |
| OS_INIT_LOG, mParameterWObject, parseResultFile); | |
| AVM_ENDIF_DEBUG_LEVEL_FLAG_AND(ULTRA , PARSING ) | |
| if( isOK ) | |
| { | |
| AVM_OS_LOG << _SEW_ << "Symbolic Execution " | |
| "based Workflow analysis ... START" | |
| << std::endl | |
| << _SEW_ << "Location: " << mSEWFileLocation | |
| << std::endl; | |
| OS_VERBOSITY_MINIMUM_OR_DEBUG( AVM_OS_COUT ) | |
| << OS_INIT_LOG.str() << std::flush; | |
| AVM_OS_LOG << OS_INIT_LOG.str() << std::flush; | |
| } | |
| else | |
| { | |
| AVM_OS_COUT << OS_INIT_LOG.str() << std::flush; | |
| return( false ); | |
| } | |
| // Set developer debug options | |
| isOK = loadSymbexConfig() && isOK; | |
| isOK = loadShellConfig() && isOK; | |
| isOK = loadTddConfig() && isOK; | |
| isOK = loadOthersConfig() && isOK; | |
| if( isOK ) | |
| { | |
| avm_report(AVM_OS_LOG, "Workflow::loadConfiguration:> " | |
| "end of avm configuration checking !!!"); | |
| } | |
| else | |
| { | |
| avm_set_exit_code( AVM_EXIT_CONFIGURE_ERROR_CODE ); | |
| } | |
| AVM_OS_COUT << _SEW_ | |
| << "Symbolic Execution based Workflow analysis ... " | |
| << ( isOK ? "DONE" : "FAILED !" ) | |
| << std::endl << std::endl; | |
| AVM_OS_LOG << _SEW_ | |
| << "Symbolic Execution Workflow analysis ... " | |
| << ( isOK ? "DONE" : "FAILED !" ) | |
| << std::endl << std::endl; | |
| return( isOK ); | |
| } | |
| /** | |
| * Load workflow definition file | |
| */ | |
| bool Workflow::parseConfiguration() | |
| { | |
| std::ifstream anInputStream( mSEWFileLocation.c_str() ); | |
| if( anInputStream.good() ) | |
| { | |
| std::string antlrExceptionMsg; | |
| ParserManager aParser( mSEWFileLocation ); | |
| mParameterWObject = aParser.parseSEW(mWObjectManager, anInputStream ); | |
| if( aParser.hasSyntaxError() ) | |
| { | |
| AVM_OS_CERR << std::endl; | |
| if( aParser.hasExceptionMessage() ) | |
| { | |
| AVM_OS_CERR << _SEW_ << "< exception > " | |
| << aParser.getExceptionMessage() << std::endl; | |
| } | |
| AVM_OS_CERR << std::endl << _SEW_ << "< error > " | |
| << aParser.getErrorCount() << " syntax error" | |
| << ((aParser.getErrorCount() > 1)? "s" : "") | |
| << " found." << std::endl; | |
| avm_set_exit_code( AVM_EXIT_PARSING_ERROR_CODE ); | |
| return( false ); | |
| } | |
| else if( mParameterWObject == WObject::_NULL_ ) | |
| { | |
| AVM_OS_CERR << _SEW_ << "< error > No parsing result !" | |
| << std::endl; | |
| avm_set_exit_code( AVM_EXIT_PARSING_ERROR_CODE ); | |
| return( false ); | |
| } | |
| else | |
| { | |
| return( true ); | |
| } | |
| } | |
| else | |
| { | |
| AVM_OS_CERR << _SEW_ << "< error > Cannot open the file \"" | |
| << VFS::filename(mSEWFileLocation) << "\" !" | |
| << std::endl << std::endl; | |
| avm_set_exit_code( AVM_EXIT_CONFIGURE_ERROR_CODE ); | |
| return( false ); | |
| } | |
| } | |
| /** | |
| * Configure core elements | |
| * Set console verbosity level | |
| * Set developer debug level | |
| * Set developer debug flags | |
| */ | |
| /* | |
| section CONSOLE // @deprecated AVM | |
| verbosity = 'MINIMUM'; // SILENT == MINIMUM < MEDIUM < MAXIMUM | |
| endsection CONSOLE | |
| section DEVELOPER // @deprecated TRACE | |
| level = 'ZERO'; // ZERO < LOW < MEDIUM < HIGH < ULTRA | |
| flag = 'PARSING'; --> @deprecated kind = 'PARSING'; | |
| flag = 'COMPILING'; | |
| flag = 'STATEMENT'; | |
| flag = 'BYTECODE'; | |
| endsection DEVELOPER | |
| */ | |
| bool Workflow::loadCoreElementsConfig(OutStream & LOGGER) | |
| { | |
| // Set console verbosity level | |
| avm_setExecVerbosityLevel( | |
| Query::getRegexWPropertyString( | |
| getCONSOLE(), "verbos(ity|e)", "MAXIMUM") ); | |
| // DEVELOPER | |
| WObject * configDEVELOPER = getDEVELOPER(); | |
| // Set developer debug level | |
| avm_setDebugLevel( | |
| Query::getWPropertyString(configDEVELOPER, "level", "ZERO") ); | |
| // Set developer debug flags | |
| ListOfString listOfFlags; | |
| Query::getWPropertyString(configDEVELOPER, "flag", "kind",listOfFlags); | |
| if( listOfFlags.nonempty() ) | |
| { | |
| ListOfString::iterator it = listOfFlags.begin(); | |
| avm_setDebugFlag(*it); | |
| for( ++it ; it != listOfFlags.end() ; ++it ) | |
| { | |
| avm_setDebugFlag(*it); | |
| } | |
| } | |
| OS_VERBOSITY_MINIMUM_OR_DEBUG( LOGGER ) | |
| << _SEW_ << "Console verbosity level: \'" | |
| << avm_strExecVerbosityLevel() << "\'" | |
| << std::endl; | |
| AVM_IF_DEBUG_ENABLED | |
| LOGGER << _SEW_ << "Developer debug level: \'" | |
| << avm_strDebugLevel() << "\'" | |
| << std::endl; | |
| LOGGER << _SEW_ << "Developer debug flags: \'" | |
| << avm_strDebugFlag(" | ") << "\'" | |
| << std::endl; | |
| AVM_ENDIF_DEBUG_ENABLED | |
| return( true ); | |
| } | |
| /** | |
| * configure workspace location & folders | |
| * root location | |
| * source folder | |
| * output folder | |
| * log folder | |
| * debug folder | |
| * tdd folder | |
| */ | |
| /* | |
| section WORKSPACE // @deprecated LOCATION | |
| root = "<workspace-root-path>"; | |
| project = "<project-root-path>"; //# DEPRECATED | |
| source = "."; | |
| output = "output"; | |
| log = "log"; | |
| debug = "debug"; | |
| tdd = "tdd"; | |
| endsection WORKSPACE | |
| */ | |
| bool Workflow::loadWorkspaceLocationsConfig(OutStream & LOGGER) | |
| { | |
| bool isOK = true; | |
| /* | |
| * CHECKING FILE AND FOLDER | |
| */ | |
| LOGGER << _SEW_ << "The launch folder: " | |
| << VFS::LaunchPath << std::endl; | |
| WObject * configWORKSPACE = getWORKSPACE(); | |
| VFS::ProjectPath = VFS::WorkspaceRootPath = | |
| VFS::native_path( | |
| Query::getWPropertyStringOrElse( | |
| configWORKSPACE, "root", "project", "."), | |
| VFS::LaunchPath); | |
| LOGGER << _SEW_ << "The <wroot> folder: " | |
| << VFS::WorkspaceRootPath << std::endl; | |
| if( VFS::checkReadingFolder(VFS::WorkspaceRootPath) ) | |
| { | |
| VFS::ProjectSourcePath = VFS::WorkspaceSourcePath = | |
| VFS::native_path( | |
| Query::getWPropertyStringOrElse( | |
| configWORKSPACE, "source", "src", "."), | |
| VFS::WorkspaceRootPath); | |
| LOGGER << _SEW_ << "The source! folder: " | |
| << VFS::relativeWorkspacePath( VFS::WorkspaceSourcePath ) | |
| << std::endl; | |
| if( not VFS::checkWritingFolder(VFS::WorkspaceSourcePath) ) | |
| { | |
| LOGGER << _SEW_ << "< error > The source folder `" | |
| << VFS::filename( VFS::WorkspaceSourcePath ) | |
| << "' ==> doesn't exist or is not writable !!!" | |
| << std::endl << std::endl; | |
| isOK = false; | |
| } | |
| VFS::ProjectOutputPath = VFS::WorkspaceOutputPath = | |
| VFS::native_path( | |
| Query::getWPropertyStringOrElse( | |
| configWORKSPACE, "output", "out", "out"), | |
| VFS::WorkspaceRootPath); | |
| LOGGER << _SEW_ << "The output! folder: " | |
| << VFS::relativeWorkspacePath( VFS::WorkspaceOutputPath ) | |
| << std::endl; | |
| if( not VFS::checkWritingFolder(VFS::WorkspaceOutputPath) ) | |
| { | |
| LOGGER << _SEW_ << "< error > The folder `" | |
| << VFS::filename( VFS::WorkspaceOutputPath ) | |
| << "' ==> doesn't exist or is not writable !!!" | |
| << std::endl << std::endl; | |
| isOK = false; | |
| } | |
| if( needDeveloperDebugLogTraceFolder() ) | |
| { | |
| VFS::ProjectLogPath = VFS::WorkspaceLogPath = | |
| VFS::native_path( | |
| Query::getWPropertyString( | |
| configWORKSPACE, "log", "log"), | |
| VFS::WorkspaceOutputPath); | |
| LOGGER << _SEW_ << "The logger! folder: " | |
| << VFS::relativeWorkspacePath( VFS::WorkspaceLogPath ) | |
| << std::endl; | |
| if( not VFS::checkWritingFolder(VFS::WorkspaceLogPath) ) | |
| { | |
| LOGGER << _SEW_ << "< error > The folder `" | |
| << VFS::filename( VFS::WorkspaceLogPath ) | |
| << "' ==> doesn't exist or is not writable !!!" | |
| << std::endl << std::endl; | |
| isOK = false; | |
| } | |
| } | |
| else if( isOK ) | |
| { | |
| VFS::ProjectLogPath = | |
| VFS::WorkspaceLogPath = | |
| VFS::WorkspaceOutputPath; | |
| } | |
| VFS::ProjectDebugPath = | |
| VFS::WorkspaceDebugPath = | |
| VFS::WorkspaceLogPath; | |
| AVM_IF_DEBUG_ENABLED | |
| VFS::ProjectDebugPath = VFS::WorkspaceDebugPath = | |
| VFS::native_path( | |
| Query::getWPropertyStringOrElse( | |
| configWORKSPACE, "debug", "dbg", "debug"), | |
| VFS::WorkspaceOutputPath); | |
| LOGGER << _SEW_ << "The !debug! folder: " | |
| << VFS::relativeWorkspacePath( VFS::WorkspaceDebugPath ) | |
| << std::endl; | |
| if( not VFS::checkWritingFolder(VFS::WorkspaceDebugPath) ) | |
| { | |
| LOGGER << _SEW_ << "< error > The folder `" | |
| << VFS::filename( VFS::WorkspaceDebugPath ) | |
| << "' ==> doesn't exist or is not writable !!!" | |
| << std::endl << std::endl; | |
| isOK = false; | |
| } | |
| AVM_ENDIF_DEBUG_ENABLED | |
| if( hasTddReport() ) | |
| { | |
| VFS::ProjectTddPath = VFS::WorkspaceTddPath = | |
| VFS::native_path( | |
| Query::getWPropertyString( | |
| configWORKSPACE, "tdd", "tdd"), | |
| VFS::WorkspaceRootPath); | |
| LOGGER << _SEW_ << "The tdd folder : " | |
| << VFS::relativeWorkspacePath( VFS::WorkspaceTddPath ) | |
| << std::endl; | |
| if( not VFS::checkWritingFolder(VFS::WorkspaceTddPath) ) | |
| { | |
| LOGGER << _SEW_ << "< error > The folder `" | |
| << VFS::filename( VFS::WorkspaceTddPath ) | |
| << "' ==> doesn't exist or is not writable !!!" | |
| << std::endl << std::endl; | |
| isOK = false; | |
| } | |
| } | |
| } | |
| else | |
| { | |
| LOGGER << _SEW_ | |
| << "< error > The <wroot> folder location " | |
| "==> doesn't exist or is not Readable !!!" | |
| << std::endl << std::endl; | |
| isOK = false; | |
| } | |
| return( isOK ); | |
| } | |
| /* | |
| section SYMBEX // @deprecated AVM | |
| mode = 'standalone'; // standalone | server | interactive | debug | |
| multithread = false; | |
| thread = 2; | |
| endsection SYMBEX | |
| */ | |
| bool Workflow::loadSymbexConfig() | |
| { | |
| WObject * configSYMBEX = getSYMBEX(); | |
| PathConditionProcessor::checkPathcondSat = | |
| SolverDef::DEFAULT_SOLVER_USAGE_FLAG = | |
| Query::getRegexWPropertyBoolean(configSYMBEX, | |
| CONS_WID4("check", "path", "condition", "satisfiability"), | |
| false); | |
| PathConditionProcessor::separationOfPcDisjunction = | |
| Query::getWPropertyBoolean(configSYMBEX, | |
| "separation_of_pc_disjunction", false); | |
| std::string solverKind = Query::getRegexWPropertyString( | |
| configSYMBEX, CONS_WID2("constraint", "solver"), "CVC"); | |
| SolverDef::DEFAULT_SOLVER_KIND = SolverDef::toSolver(solverKind, | |
| SolverDef::SOLVER_CVC_KIND); | |
| AVM_IF_DEBUG_ENABLED | |
| AVM_OS_LOG << _SEW_ << "The default solver: < checksat=" | |
| << ( SolverDef::DEFAULT_SOLVER_USAGE_FLAG ? "true" : "false" ) | |
| << " , " << solverKind << " > |=> " | |
| << SolverDef::strSolver(SolverDef::DEFAULT_SOLVER_KIND) | |
| << std::endl; | |
| AVM_ENDIF_DEBUG_ENABLED | |
| mMultitaskingFlag = | |
| Query::getWPropertyBoolean(configSYMBEX, "multitasking", false); | |
| mThreadCount = Query::getWPropertyInt(configSYMBEX, "thread", 2); | |
| std::string evalMode = Query::getWPropertyString(configSYMBEX, "mode", ""); | |
| AVM_IF_DEBUG_ENABLED | |
| AVM_OS_LOG << _SEW_ << "Computing resource: < multitasking=" | |
| << ( ( mMultitaskingFlag ) ? "true" : "false" ) | |
| << " , thread=" << static_cast< unsigned int >( mThreadCount ) | |
| << " >" << std::endl; | |
| AVM_ENDIF_DEBUG_ENABLED | |
| return( true ); | |
| } | |
| /* | |
| section SHELL // Deprecated AVM | |
| stop = "stop.avm"; | |
| endsection SHELL | |
| */ | |
| bool Workflow::loadShellConfig() | |
| { | |
| WObject * configSHELL = getSHELL(); | |
| mInconditionalStopMarkerLocation = VFS::native_path( | |
| Query::getWPropertyString(configSHELL, "stop", "stop.sew")); | |
| mInconditionalStopMarkerLocation = VFS::native_path( | |
| mInconditionalStopMarkerLocation, VFS::WorkspaceLogPath); | |
| return( true ); | |
| } | |
| /** | |
| * Other Elements Configuration | |
| */ | |
| bool Workflow::loadTddConfig() | |
| { | |
| mTddRegressionTestingFlag = | |
| Query::getWPropertyBoolean(getTDD(), "regression", false); | |
| mTddUnitTestingFlag = Query::getWPropertyBoolean(getTDD(), "unit", false); | |
| return( true ); | |
| } | |
| /** | |
| * Other Elements Configuration | |
| */ | |
| bool Workflow::loadOthersConfig() | |
| { | |
| ExecutionContext::EXECUTION_CONTEXT_CHILD_TRACE_MAX = | |
| Query::getWPropertyLong(getCONSOLE(), "ec_size", | |
| ExecutionContext::EXECUTION_CONTEXT_CHILD_TRACE_MAX); | |
| return( true ); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // CONFIGURE API | |
| //////////////////////////////////////////////////////////////////////////////// | |
| bool Workflow::configure() | |
| { | |
| mMainSymbexEngine = NULL; | |
| WObject * sequenceDIRECTOR = getDIRECTOR(); | |
| const BF & mocRuntime = | |
| Query::getWPropertyValueOrElse(sequenceDIRECTOR, "moe", "moc"); | |
| avm_offset_t anEngineOffset = 0; | |
| if( WObjectManager::is( mocRuntime ) ) | |
| { | |
| mMainSymbexEngine = new SymbexEngine(*this, | |
| WObjectManager::from( mocRuntime ), anEngineOffset++); | |
| if(not mMainSymbexEngine->configure() ) | |
| { | |
| delete( mMainSymbexEngine ); | |
| mMainSymbexEngine = NULL; | |
| return( false ); | |
| } | |
| } | |
| else if( mocRuntime.is< AvmCode >() ) | |
| { | |
| SymbexEngine * nextEngine = NULL; | |
| SymbexEngine * prevEngine = NULL; | |
| AvmCode::iterator itEngine = mocRuntime.to_ptr< AvmCode >()->begin(); | |
| AvmCode::iterator itEnd = mocRuntime.to_ptr< AvmCode >()->end(); | |
| for( ; itEngine != itEnd ; ++itEngine ) | |
| { | |
| if( WObjectManager::is( *itEngine ) ) | |
| { | |
| nextEngine = new SymbexEngine(*this, | |
| WObjectManager::from( *itEngine ), anEngineOffset++); | |
| nextEngine->setPreviousCore( prevEngine ); | |
| if( nextEngine->configure() ) | |
| { | |
| if( mMainSymbexEngine == NULL ) | |
| { | |
| mMainSymbexEngine = nextEngine; | |
| } | |
| if( prevEngine != NULL ) | |
| { | |
| prevEngine->setNextCore( nextEngine ); | |
| } | |
| prevEngine = nextEngine; | |
| } | |
| else | |
| { | |
| delete( nextEngine ); | |
| return( false ); | |
| } | |
| } | |
| else | |
| { | |
| return( false ); | |
| } | |
| } | |
| } | |
| else | |
| { | |
| SymbexEngine * nextEngine = NULL; | |
| SymbexEngine * prevEngine = NULL; | |
| List< WObject * > engineList; | |
| Query::getListWObject(sequenceDIRECTOR, engineList); | |
| List< WObject * >::iterator itForm = engineList.begin(); | |
| for( ; itForm != engineList.end() ; ++itForm ) | |
| { | |
| nextEngine = new SymbexEngine(*this, *itForm, anEngineOffset++ ); | |
| nextEngine->setPreviousCore( prevEngine ); | |
| if( nextEngine->configure() ) | |
| { | |
| if( mMainSymbexEngine == NULL ) | |
| { | |
| mMainSymbexEngine = nextEngine; | |
| } | |
| if( prevEngine != NULL ) | |
| { | |
| prevEngine->setNextCore( nextEngine ); | |
| } | |
| prevEngine = nextEngine; | |
| } | |
| else | |
| { | |
| delete( nextEngine ); | |
| return( false ); | |
| } | |
| } | |
| } | |
| return( true ); | |
| } | |
| /** | |
| * Prologue options | |
| */ | |
| void Workflow::setPrologueOption( | |
| const std::string & id, BF value) | |
| { | |
| if( REGEX_MATCH(id, CONS_WID2("check", "type")) ) | |
| { | |
| COMPILE_CONTEXT::DEFAUL_TYPE_CHECKING_MASK = value.isNotEqualFalse(); | |
| } | |
| else if( REGEX_MATCH(id, CONS_WID2("inline", "disable")) ) | |
| { | |
| COMPILE_CONTEXT::INLINE_DISABLE_MASK = value.isNotEqualFalse(); | |
| } | |
| else if( REGEX_MATCH(id, CONS_WID2("inline", "enable")) ) | |
| { | |
| COMPILE_CONTEXT::INLINE_ENABLE_MASK = value.isNotEqualFalse(); | |
| } | |
| else if( REGEX_MATCH(id, CONS_WID2("inline", "procedure")) ) | |
| { | |
| COMPILE_CONTEXT::INLINE_PROCEDURE_MASK = value.isNotEqualFalse(); | |
| } | |
| else if( REGEX_MATCH(id, CONS_WID2("string", "delimiter")) ) | |
| { | |
| if( value.isCharacter() ) | |
| { | |
| String::_EMPTY_.to_ptr< String >()->setQuoteChar( | |
| String::DEFAULT_DELIMITER = value.toCharacter() ); | |
| } | |
| else if( value.isBuiltinString() ) | |
| { | |
| std::string delim = value.toBuiltinString(); | |
| String::_EMPTY_.to_ptr< String >()->setQuoteChar( | |
| String::DEFAULT_DELIMITER = | |
| ( delim.empty() ? '\0' : delim[0] ) ); | |
| } | |
| } | |
| } | |
| /** | |
| * START | |
| */ | |
| bool Workflow::start() | |
| { | |
| //////////////////////////////////////////////////////////////////////////// | |
| ///// START SEQUENTIALLY ENGINE CORE | |
| //////////////////////////////////////////////////////////////////////////// | |
| for( mCurrentSymbexEngine = mMainSymbexEngine ; mCurrentSymbexEngine != NULL ; | |
| mCurrentSymbexEngine = mCurrentSymbexEngine->getNextCore() ) | |
| { | |
| if( not mCurrentSymbexEngine->startComputing() ) | |
| { | |
| return( false ); | |
| } | |
| } | |
| return( true ); | |
| } | |
| /** | |
| * EXIT | |
| */ | |
| bool Workflow::exitImpl() | |
| { | |
| // bool isCasManager_OK = mAvmConfiguration.getCasManager().exit(); | |
| // | |
| // return( RunnableElement::exit() && isCasManager_OK ); | |
| return( true ); | |
| } | |
| /** | |
| * REPORT TRACE | |
| */ | |
| void Workflow::report(OutStream & os) const | |
| { | |
| // mAvmConfiguration.getCasManager().report(os); | |
| // | |
| // mAvmConfiguration.getCasManager().report(AVM_OS_COUT); | |
| } | |
| /** | |
| * COMPUTING | |
| * | |
| */ | |
| bool Workflow::startComputing() | |
| { | |
| AVM_OS_LOG << std::endl << _SEW_ << "< start > Computing ..." << std::endl; | |
| //////////////////////////////////////////////////////////////////////////// | |
| ///// INITIALIZATION | |
| //////////////////////////////////////////////////////////////////////////// | |
| if( not init() ) | |
| { | |
| avm_set_exit_code( AVM_EXIT_INITIALIZING_ERROR_CODE ); | |
| return( false ); | |
| } | |
| //////////////////////////////////////////////////////////////////////////// | |
| ///// PRE PROCESSING | |
| //////////////////////////////////////////////////////////////////////////// | |
| if( not preprocess() ) | |
| { | |
| avm_set_exit_code( AVM_EXIT_PRE_PROCESSING_ERROR_CODE ); | |
| return( false ); | |
| } | |
| //////////////////////////////////////////////////////////////////////////// | |
| ///// START | |
| //////////////////////////////////////////////////////////////////////////// | |
| if( not start() ) | |
| { | |
| avm_set_exit_code( AVM_EXIT_PROCESSING_ERROR_CODE ); | |
| return( false ); | |
| } | |
| //////////////////////////////////////////////////////////////////////////// | |
| ///// POST PROCESSING | |
| //////////////////////////////////////////////////////////////////////////// | |
| if( not postprocess() ) | |
| { | |
| avm_set_exit_code( AVM_EXIT_POST_PROCESSING_ERROR_CODE ); | |
| return( false ); | |
| } | |
| //////////////////////////////////////////////////////////////////////////// | |
| ///// EXITING | |
| //////////////////////////////////////////////////////////////////////////// | |
| if( not exit() ) | |
| { | |
| avm_set_exit_code( AVM_EXIT_FINALIZING_ERROR_CODE ); | |
| return( false ); | |
| } | |
| //////////////////////////////////////////////////////////////////////////// | |
| ///// REPORTING | |
| //////////////////////////////////////////////////////////////////////////// | |
| AVM_OS_LOG << std::endl; | |
| report(AVM_OS_LOG); | |
| AVM_OS_LOG << std::endl; | |
| //////////////////////////////////////////////////////////////////////////// | |
| ///// SERIALIZATION | |
| //////////////////////////////////////////////////////////////////////////// | |
| //serializeResult(); | |
| AVM_OS_LOG << _SEW_ << "< end >Computing ... done." << std::endl; | |
| return( true ); | |
| } | |
| /** | |
| * SERIALIZATION | |
| */ | |
| void Workflow::toStream(OutStream & os) const | |
| { | |
| os << TAB << "parameter {" << EOL; | |
| os << TAB2 << "location = " << mSEWFileLocation << ";" | |
| << EOL_INCR_INDENT; | |
| if( mParameterWObject != WObject::_NULL_ ) | |
| { | |
| mParameterWObject->toStream(os); | |
| } | |
| os << DECR_INDENT_TAB << "}" << EOL_FLUSH; | |
| } | |
| } /* namespace sep */ |