/

s='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'> uscxml.git - SCXML interpreter and transformer/compiler written in C/C++ with bindings to Java, C#, Python and Lua
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <sradomski@mintwerk.de>2015-12-04 08:00:18 (GMT)
committerStefan Radomski <sradomski@mintwerk.de>2015-12-04 08:00:18 (GMT)
commitb8ba0e7c31f397a66f9d509ff20a85b33619475a (patch)
tree9a5adb4f891cdc29eb80f597510e0cef8ee0a47f
parent57ba362eae6e8209cf560555fd4cc4bb76dbe2a1 (diff)
downloaduscxml-b8ba0e7c31f397a66f9d509ff20a85b33619475a.zip
uscxml-b8ba0e7c31f397a66f9d509ff20a85b33619475a.tar.gz
uscxml-b8ba0e7c31f397a66f9d509ff20a85b33619475a.tar.bz2
All changes up to my dissertation
-rw-r--r--CMakeLists.txt34
-rw-r--r--apps/samples/server-push/server-push.scxml4
-rw-r--r--apps/samples/vrml/vrml-server.caching.scxml4
-rw-r--r--apps/samples/vrml/vrml-server.pre-osgjs.scxml4
-rw-r--r--apps/samples/vrml/vrml-server.scxml4
-rw-r--r--apps/uscxml-browser.cpp7
-rw-r--r--apps/uscxml-transform.cpp76
-rw-r--r--apps/w3c-mmi/im/uscxml-interaction-manager.cpp2
-rw-r--r--apps/w3c-mmi/mc/uscxml-modality-component.cpp2
-rw-r--r--config.h.in9
-rw-r--r--contrib/cmake/TryCompile.cmake23
-rw-r--r--src/bindings/CMakeLists.txt13
-rw-r--r--src/bindings/swig/php/uscxmlNativePHP.php27
-rw-r--r--src/uscxml/Interpreter.cpp164
-rw-r--r--src/uscxml/Interpreter.h13
-rw-r--r--src/uscxml/debug/InterpreterIssue.cpp40
-rw-r--r--src/uscxml/debug/InterpreterIssue.h5
-rw-r--r--src/uscxml/interpreter/InterpreterRC.cpp15
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp2
-rw-r--r--src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp6
-rw-r--r--src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp2
-rw-r--r--src/uscxml/plugins/element/fetch/FetchElement.cpp14
-rw-r--r--src/uscxml/plugins/element/fetch/FetchElement.h2
-rw-r--r--src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp12
-rw-r--r--src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp33
-rw-r--r--src/uscxml/transform/ChartToFSM.cpp170
-rw-r--r--src/uscxml/transform/ChartToFSM.h4
-rw-r--r--src/uscxml/transform/ChartToPromela.cpp83
-rw-r--r--test/CMakeLists.txt67
-rw-r--r--test/ctest/CTestCustom.ctest.in270
-rw-r--r--test/src/test-issue-reporting.cpp241
-rw-r--r--test/src/test-lifecycle.cpp2
-rw-r--r--test/src/test-stress.cpp20
-rw-r--r--test/src/test-w3c.cpp4
-rw-r--r--test/uscxml/history-stacks/history-compounds.scxml53
-rw-r--r--test/uscxml/history-stacks/history-invokers.item.scxml30
-rw-r--r--test/uscxml/history-stacks/history-invokers.main.scxml24
-rw-r--r--test/uscxml/test-invoke-communication-invoker.scxml118
-rw-r--r--test/uscxml/test-invoke-communication.scxml104
-rw-r--r--test/uscxml/transition-selection/test1.scxml12
-rw-r--r--test/uscxml/transition-selection/test2.scxml20
-rwxr-xr-xtest/w3c/check-tests.pl92
-rwxr-xr-xtest/w3c/convert-tests.sh7
-rw-r--r--test/w3c/ecma/test436.scxml23
-rw-r--r--test/w3c/lua/test288.scxml (renamed from test/w3c/xpath/test278.scxml)18
-rw-r--r--test/w3c/lua/test436.scxml15
-rw-r--r--test/w3c/null/test436.scxml (renamed from test/w3c/xpath/test436.scxml)0
-rw-r--r--test/w3c/prolog/test278.scxml23
-rw-r--r--test/w3c/promela/test278.scxml23
-rwxr-xr-xtest/w3c/run_manual_tests.sh127
-rw-r--r--test/w3c/schema/scxml-attribs.xsd57
-rw-r--r--test/w3c/schema/scxml-contentmodels.xsd35
-rw-r--r--test/w3c/schema/scxml-copyright.xsd26
-rw-r--r--test/w3c/schema/scxml-core-strict.xsd425
-rw-r--r--test/w3c/schema/scxml-data-strict.xsd157
-rw-r--r--test/w3c/schema/scxml-datatypes.xsd203
-rw-r--r--test/w3c/schema/scxml-external-strict.xsd168
-rw-r--r--test/w3c/schema/scxml-message.xsd122
-rw-r--r--test/w3c/schema/scxml-messages.xsd49
-rw-r--r--test/w3c/schema/scxml-module-anchor.xsd67
-rw-r--r--test/w3c/schema/scxml-module-core.xsd405
-rw-r--r--test/w3c/schema/scxml-module-data.xsd151
-rw-r--r--test/w3c/schema/scxml-module-external.xsd152
-rw-r--r--test/w3c/schema/scxml-module-script.xsd51
-rw-r--r--test/w3c/schema/scxml-profile-basic.xsd96
-rw-r--r--test/w3c/schema/scxml-profile-ecma.xsd159
-rw-r--r--test/w3c/schema/scxml-profile-minimum.xsd74
-rw-r--r--test/w3c/schema/scxml-profile-xpath.xsd163
-rw-r--r--test/w3c/schema/scxml-strict.xsd88
-rw-r--r--test/w3c/schema/scxml.xsd88
-rw-r--r--test/w3c/schema/xml.xsd117
-rw-r--r--test/w3c/txml/test278.txml2
72 files changed, 4555 insertions, 367 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 038d7cb..f8a6067 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,6 +18,10 @@ if(POLICY CMP0054)
# Escape variables in if
cmake_policy(SET CMP0054 OLD)
endif()
+if(POLICY CMP0059)
+ # Don't treat ``DEFINITIONS`` as a built-in directory property - required for cotire
+ cmake_policy(SET CMP0059 OLD)
+endif()
# specify USCXML version
SET(USCXML_VERSION_MAJOR "0")
@@ -41,6 +45,7 @@ include("${CMAKE_MODULE_PATH}/USCXMLMacros.cmake")
include("${CMAKE_MODULE_PATH}/FunctionExists.cmake")
include("${CMAKE_MODULE_PATH}/HeaderExists.cmake")
include("${CMAKE_MODULE_PATH}/BinaryExists.cmake")
+include("${CMAKE_MODULE_PATH}/TryCompile.cmake")
# CMake 2.8.11 reports AMD64 for Windows 64Bit, where earlier versions reported x86
# we resolve it with a 64bit check later
@@ -356,8 +361,12 @@ else()
OPTION(BUILD_TESTS_W3C_PROLOG "Create W3C Prolog tests" ON)
OPTION(BUILD_TESTS_W3C_PROMELA "Create W3C Promela tests" ON)
+ OPTION(BUILD_TESTS_FSM "Build FSM converted W3C tests" OFF)
OPTION(BUILD_TESTS_FSM_ECMA "Create FSM converted W3C ECMAScript tests" ON)
- OPTION(BUILD_TESTS_FSM_XPATH "Create FSM converted W3C XPath tests" OFF)
+ OPTION(BUILD_TESTS_FSM_XPATH "Create FSM converted W3C XPath tests" ON)
+ OPTION(BUILD_TESTS_FSM_LUA "Create FSM converted W3C Lua tests" ON)
+ OPTION(BUILD_TESTS_FSM_PROLOG "Create FSM converted W3C Prolog tests" ON)
+ OPTION(BUILD_TESTS_FSM_PROMELA "Create FSM converted W3C Promela tests" ON)
endif()
OPTION(ENABLE_GCOV "Compile with gcov support" OFF)
@@ -368,6 +377,10 @@ OPTION(BUILD_DM_PROLOG "Build with Prolog datamodel" ON)
OPTION(BUILD_DM_PROMELA "Build with Promela datamodel" ON)
OPTION(BUILD_DM_LUA "Build with Lua datamodel" ON)
+OPTION(BUILD_BINDING_JAVA "Build language bindings for Java" ON)
+OPTION(BUILD_BINDING_CSHARP "Build language bindings for CSharp" ON)
+OPTION(BUILD_BINDING_PHP "Build language bindings for PHP" OFF)
+
# a dummy target to depend on the targets needed for tests, see:
# http://stackoverflow.com/questions/733475/cmake-ctest-make-test-doesnt-build-tests
add_custom_target(ALL_TESTS COMMENT "Building all tests when BUILD_TESTS is enabled")
@@ -485,6 +498,12 @@ elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
# set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -read_only_relocs suppress")
# set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -read_only_relocs suppress")
+
+ # not too sure when this happened, 'void' has to be qualified as 'std::type_info' on __cxa_throw
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.3 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.3)
+ set(CXA_THROW_TYPEINFO_SIGNATURE ON)
+ endif()
+
else()
message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
endif()
@@ -502,10 +521,19 @@ if (APPLE AND MACOSX_VERSION VERSION_LESS "10.9")
# support leopard and above
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
foreach(FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS)
- set(${FLAGS} "${${FLAGS}} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
+ set(${FLAGS} "${${FLAGS}} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
endforeach()
endif()
+# if (APPLE AND MACOSX_VERSION VERSION_GREATER "10.9.99")
+# set(CMAKE_OSX_DEPLOYMENT_TARGET 10.10) # ?
+# foreach(FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS)
+# set(${FLAGS} "${${FLAGS}} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -arch x86_64")
+# # we get "Illegal Instruction: 4" errors without on yosemite?!
+# # set(${FLAGS} "${${FLAGS}} -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk")
+# endforeach()
+# endif()
+
if (IOS)
if (${CMAKE_GENERATOR} STREQUAL "Xcode")
else()
@@ -1315,6 +1343,8 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_BUILD_TYPE_DEBUG ON)
endif()
+
+
# enable config.h style compile time options and add as "uscxml/config.h"
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/uscxml/config.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test/ctest/CTestCustom.ctest.in ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.ctest)
diff --git a/apps/samples/server-push/server-push.scxml b/apps/samples/server-push/server-push.scxml
index a9d231e..c0f0a21 100644
--- a/apps/samples/server-push/server-push.scxml
+++ b/apps/samples/server-push/server-push.scxml
@@ -6,7 +6,7 @@
<scxml name="push" datamodel="ecmascript">
<script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" />
- <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string.endsWith.js" />
+ <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string. .js" />
<state id="main">
<!-- We will only answer http requests when the heartbeat is emitted -->
@@ -25,7 +25,7 @@
</transition>
<transition event="http.post" target="idle">
- <if cond="_event.name.endsWith('postponed')">
+ <if cond="_event.name. ('postponed')">
<!-- This is an event we postponed before the heartbeat, respond -->
<respond to="_event.origin">
<content>This is awesome!</content>
diff --git a/apps/samples/vrml/vrml-server.caching.scxml b/apps/samples/vrml/vrml-server.caching.scxml
index 70a7c3a..2d935cd 100644
--- a/apps/samples/vrml/vrml-server.caching.scxml
+++ b/apps/samples/vrml/vrml-server.caching.scxml
@@ -1,6 +1,6 @@
<scxml datamodel="ecmascript" name="vrml">
<script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" />
- <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string.endsWith.js" />
+ <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string. .js" />
<script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/array.last.js" />
<script>
var wrls = {}; // information of the wrl, vrml files
@@ -294,7 +294,7 @@
<content fileexpr="processed[_event['fileStruct'].key][_event['fileStruct'].format].path" />
</respond>
<else />
- <if cond="_event.name.endsWith('postponed')">
+ <if cond="_event.name. ('postponed')">
<!--
A postponed event we couldn't answer
-->
diff --git a/apps/samples/vrml/vrml-server.pre-osgjs.scxml b/apps/samples/vrml/vrml-server.pre-osgjs.scxml
index e08afd4..a51c5f3 100644
--- a/apps/samples/vrml/vrml-server.pre-osgjs.scxml
+++ b/apps/samples/vrml/vrml-server.pre-osgjs.scxml
@@ -1,6 +1,6 @@
<scxml datamodel="ecmascript" name="vrml">
<script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" />
- <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string.endsWith.js" />
+ <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string. .js" />
<script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/array.last.js" />
<script>
var wrls = {}; // information of the wrl, vrml files
@@ -201,7 +201,7 @@
</script>
<if cond="'context' in _event.data">
<!-- this was generated in reply to a request -->
- <if cond="_event.name.endsWith('success')">
+ <if cond="_event.name. ('success')">
<respond status="200" to="_event.data.context">
<header name="Connection" value="close" />
<header name="Content-Type" value="application/json" />
diff --git a/apps/samples/vrml/vrml-server.scxml b/apps/samples/vrml/vrml-server.scxml
index 5c65afb..529a469 100644
--- a/apps/samples/vrml/vrml-server.scxml
+++ b/apps/samples/vrml/vrml-server.scxml
@@ -1,6 +1,6 @@
<scxml datamodel="ecmascript" name="vrml">
<script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" />
- <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string.endsWith.js" />
+ <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string. .js" />
<script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/array.last.js" />
<script>
var wrls = {}; // information of the wrl, vrml files
@@ -206,7 +206,7 @@
</script>
<if cond="'context' in _event.data">
<!-- this was generated in reply to a request -->
- <if cond="_event.name.endsWith('success')">
+ <if cond="_event.name. ('success')">
<respond status="200" to="_event.data.context">
<header name="Connection" value="close" />
<header name="Access-Control-Allow-Origin" value="*" />
diff --git a/apps/uscxml-browser.cpp b/apps/uscxml-browser.cpp
index 0562ba7..ede6f06 100644
--- a/apps/uscxml-browser.cpp
+++ b/apps/uscxml-browser.cpp
@@ -35,7 +35,6 @@ void printBacktrace(void** array, int size) {
}
#ifdef HAS_DLFCN_H
-#if 0 // deactivated as we use exceptions to signal errors now
// see https://gist.github.com/nkuln/2020860
typedef void (*cxa_throw_type)(void *, void *, void (*) (void *));
cxa_throw_type orig_cxa_throw = 0;
@@ -45,7 +44,7 @@ void load_orig_throw_code() {
}
extern "C"
-void __cxa_throw (void *thrown_exception, void *pvtinfo, void (*dest)(void *)) {
+CXA_THROW_SIGNATURE {
std::cerr << __FUNCTION__ << " will throw exception from " << std::endl;
if (orig_cxa_throw == 0)
load_orig_throw_code();
@@ -57,13 +56,11 @@ void __cxa_throw (void *thrown_exception, void *pvtinfo, void (*dest)(void *)) {
}
#endif
#endif
-#endif
// see http://stackoverflow.com/questions/2443135/how-do-i-find-where-an-exception-was-thrown-in-c
void customTerminate() {
static bool tried_throw = false;
-
try {
// try once to re-throw currently active exception
if (!tried_throw) {
@@ -142,6 +139,7 @@ int main(int argc, char** argv) {
DebuggerServlet* debugger;
if (options.withDebugger) {
debugger = new DebuggerServlet();
+ debugger->copyToInvokers(true);
HTTPServer::getInstance()->registerServlet("/debug", debugger);
}
#endif
@@ -173,6 +171,7 @@ int main(int argc, char** argv) {
if (options.verbose) {
StateTransitionMonitor* vm = new StateTransitionMonitor();
+ vm->copyToInvokers(true);
interpreter.addMonitor(vm);
}
diff --git a/apps/uscxml-transform.cpp b/apps/uscxml-transform.cpp
index c2c0215..77537f5 100644
--- a/apps/uscxml-transform.cpp
+++ b/apps/uscxml-transform.cpp
@@ -75,11 +75,15 @@ void printUsageAndExit(const char* progName) {
printf("\t-t tex : write global state transition table as tex file\n");
printf("\t-a {OPTIONS} : annotate SCXML elements with comma seperated options\n");
printf("\t 'priority' - transitions with their priority for transition selection\n");
+ printf("\t 'exitset' - annotate all transitions with their exit sets\n");
+ printf("\t 'entryset' - annotate all transitions with their entry sets\n");
+ printf("\t 'conflicts' - annotate all transitions with their conflicts\n");
+ printf("\t 'domain' - annotate all transitions with their domain\n");
printf("\t 'step' - global states with their step identifier (-tflat only)\n");
printf("\t 'members' - global transitions with their member transitions per index (-tflat only)\n");
printf("\t 'sends' - transititve number of sends to external queue for global transitions (-tflat only)\n");
printf("\t 'raises' - transititve number of raises to internal queue for global transitions (-tflat only)\n");
- printf("\t 'verbose' - comments detailling state changes and transitions for content selection (-tflat only)\n");
+ printf("\t 'verbose' - comments detailling state changes and transitions for content selection (-tflat only)\n");
printf("\t 'progress' - insert comments documenting progress in dociment (-tmin only)\n");
printf("\t 'nocomment' - surpress the generation of comments in output\n");
printf("\t-v : be verbose\n");
@@ -174,6 +178,18 @@ int main(int argc, char** argv) {
if (ANNOTATE("USCXML_ANNOTATE_VERBOSE_COMMENTS", "verbose"))
setenv("USCXML_ANNOTATE_VERBOSE_COMMENTS", "YES", 1);
+ if (ANNOTATE("USCXML_ANNOTATE_TRANS_EXITSET", "exitset"))
+ setenv("USCXML_ANNOTATE_TRANS_EXITSET", "YES", 1);
+
+ if (ANNOTATE("USCXML_ANNOTATE_TRANS_DOMAIN", "domain"))
+ setenv("USCXML_ANNOTATE_TRANS_DOMAIN", "YES", 1);
+
+ if (ANNOTATE("USCXML_ANNOTATE_TRANS_CONFLICTS", "conflicts"))
+ setenv("USCXML_ANNOTATE_TRANS_CONFLICTS", "YES", 1);
+
+ if (ANNOTATE("USCXML_ANNOTATE_TRANS_ENTRYSET", "entryset"))
+ setenv("USCXML_ANNOTATE_TRANS_ENTRYSET", "YES", 1);
+
if(ANNOTATE("USCXML_ANNOTATE_GLOBAL_TRANS_MEMBERS", "members"))
setenv("USCXML_ANNOTATE_GLOBAL_TRANS_MEMBERS", "YES", 1);
@@ -202,11 +218,15 @@ int main(int argc, char** argv) {
// printUsageAndExit(argv[0]);
if (outType != "flat" &&
- outType != "scxml" &&
- outType != "pml" &&
- outType != "min" &&
- outType != "tex" &&
- std::find(annotations.begin(), annotations.end(), "priority") == annotations.end())
+ outType != "scxml" &&
+ outType != "pml" &&
+ outType != "min" &&
+ outType != "tex" &&
+ std::find(annotations.begin(), annotations.end(), "priority") == annotations.end() &&
+ std::find(annotations.begin(), annotations.end(), "domain") == annotations.end() &&
+ std::find(annotations.begin(), annotations.end(), "conflicts") == annotations.end() &&
+ std::find(annotations.begin(), annotations.end(), "exitset") == annotations.end() &&
+ std::find(annotations.begin(), annotations.end(), "entryset") == annotations.end())
printUsageAndExit(argv[0]);
// register plugins
@@ -243,7 +263,7 @@ int main(int argc, char** argv) {
std::cerr << *issueIter << std::endl;
}
}
-
+
if (outType == "pml") {
if (outputFile.size() == 0 || outputFile == "-") {
ChartToPromela::transform(interpreter).writeTo(std::cout);
@@ -292,24 +312,34 @@ int main(int argc, char** argv) {
exit(EXIT_SUCCESS);
}
+
#if 1
- if (annotations.size() > 0) {
- ChartToFSM annotater(interpreter);
- if (std::find(annotations.begin(), annotations.end(), "priority") != annotations.end())
- annotater.indexTransitions();
-
- if (outputFile.size() == 0 || outputFile == "-") {
- std::cout << annotater.getDocument();
- } else {
- std::ofstream outStream;
- outStream.open(outputFile.c_str());
- outStream << annotater.getDocument();
- outStream.close();
- }
- exit(EXIT_SUCCESS);
- }
+ if (annotations.size() > 0) {
+ ChartToFSM annotater(interpreter);
+ if (std::find(annotations.begin(), annotations.end(), "priority") != annotations.end())
+ annotater.indexTransitions();
+ if (std::find(annotations.begin(), annotations.end(), "conflicts") != annotations.end())
+ annotater.annotateConflicts();
+ if (std::find(annotations.begin(), annotations.end(), "exitset") != annotations.end())
+ annotater.annotateExitSet();
+ if (std::find(annotations.begin(), annotations.end(), "entryset") != annotations.end())
+ annotater.annotateEntrySet();
+ if (std::find(annotations.begin(), annotations.end(), "domain") != annotations.end())
+ annotater.annotateDomain();
+
+ if (outputFile.size() == 0 || outputFile == "-") {
+ std::cout << annotater.getDocument();
+ } else {
+ std::ofstream outStream;
+ outStream.open(outputFile.c_str());
+ outStream << annotater.getDocument();
+ outStream.close();
+ }
+ exit(EXIT_SUCCESS);
+ }
#endif
-
+
+
} catch (Event e) {
std::cout << e << std::endl;
}
diff --git a/apps/w3c-mmi/im/uscxml-interaction-manager.cpp b/apps/w3c-mmi/im/uscxml-interaction-manager.cpp
index 9d93a55..b6b75f6 100644
--- a/apps/w3c-mmi/im/uscxml-interaction-manager.cpp
+++ b/apps/w3c-mmi/im/uscxml-interaction-manager.cpp
@@ -62,7 +62,7 @@ void load_orig_throw_code() {
}
extern "C"
-void __cxa_throw (void *thrown_exception, void *pvtinfo, void (*dest)(void *)) {
+CXA_THROW_SIGNATURE {
std::cerr << __FUNCTION__ << " will throw exception from " << std::endl;
if (orig_cxa_throw == 0)
load_orig_throw_code();
diff --git a/apps/w3c-mmi/mc/uscxml-modality-component.cpp b/apps/w3c-mmi/mc/uscxml-modality-component.cpp
index 5b06279..4901dbd 100644
--- a/apps/w3c-mmi/mc/uscxml-modality-component.cpp
+++ b/apps/w3c-mmi/mc/uscxml-modality-component.cpp
@@ -59,7 +59,7 @@ void load_orig_throw_code() {
}
extern "C"
-void __cxa_throw (void *thrown_exception, void *pvtinfo, void (*dest)(void *)) {
+CXA_THROW_SIGNATURE {
std::cerr << __FUNCTION__ << " will throw exception from " << std::endl;
if (orig_cxa_throw == 0)
load_orig_throw_code();
diff --git a/config.h.in b/config.h.in
index 0ea3b16..9527faa 100644
--- a/config.h.in
+++ b/config.h.in
@@ -29,6 +29,15 @@
#cmakedefine PATH_SEPERATOR '@PATH_SEPERATOR@'
+// CPP headers
+#cmakedefine CXA_THROW_TYPEINFO_SIGNATURE
+#ifdef CXA_THROW_TYPEINFO_SIGNATURE
+#define CXA_THROW_SIGNATURE void __cxa_throw (void *thrown_exception, std::type_info *pvtinfo, void (*dest)(void *))
+#else
+#define CXA_THROW_SIGNATURE void __cxa_throw (void *thrown_exception, void *pvtinfo, void (*dest)(void *))
+#endif
+
+
/** version */
#cmakedefine USCXML_VERSION_MAJOR "@USCXML_VERSION_MAJOR@"
#cmakedefine USCXML_VERSION_MINOR "@USCXML_VERSION_MINOR@"
diff --git a/contrib/cmake/TryCompile.cmake b/contrib/cmake/TryCompile.cmake
new file mode 100644
index 0000000..3647dd1
--- /dev/null
+++ b/contrib/cmake/TryCompile.cmake
@@ -0,0 +1,23 @@
+include(CheckCXXSourceCompiles)
+# set(CMAKE_REQUIRED_INCLUDES ${SWI_INCLUDE_DIR} ${SWI_CPP_INCLUDE_DIR})
+# set(CMAKE_REQUIRED_LIBRARIES ${SWI_LIBRARY})
+
+check_cxx_source_compiles("
+ #include <typeinfo>
+ #include <execinfo.h>
+ #include <dlfcn.h>
+ extern \"C\"
+ void __cxa_throw (void *thrown_exception, void *pvtinfo, void (*dest)(void *)) {
+ }
+ int main() {}
+" CXA_THROW_HAS_VOID_PVTINFO_TYPE)
+
+check_cxx_source_compiles("
+ #include <typeinfo>
+ #include <execinfo.h>
+ #include <dlfcn.h>
+ extern \"C\"
+ void __cxa_throw (void *thrown_exception, std::type_info *pvtinfo, void (*dest)(void *)) {
+ }
+ int main() {}
+" CXA_THROW_HAS_TYPEINFO_PVTINFO_TYPE)
diff --git a/src/bindings/CMakeLists.txt b/src/bindings/CMakeLists.txt
index 0a258b8..89905ce 100644
--- a/src/bindings/CMakeLists.txt
+++ b/src/bindings/CMakeLists.txt
@@ -24,9 +24,16 @@ if (SWIG_FOUND)
if(SWIG_VERSION VERSION_GREATER 2.0.4)
MARK_AS_ADVANCED(SWIG_DIR SWIG_EXECUTABLE SWIG_VERSION)
INCLUDE(${SWIG_USE_FILE})
- add_subdirectory(swig/java)
- add_subdirectory(swig/csharp)
- add_subdirectory(swig/php)
+ if (BUILD_BINDING_JAVA)
+ add_subdirectory(swig/java)
+ endif()
+ if (BUILD_BINDING_CSHARP)
+ add_subdirectory(swig/csharp)
+ endif()
+ if (BUILD_BINDING_PHP)
+ add_subdirectory(swig/php)
+ endif()
+
if(SWIG_VERSION VERSION_LESS 3.0.0)
message(STATUS "SWIG version > 3.0 is recommended, found ${SWIG_VERSION}")
endif()
diff --git a/src/bindings/swig/php/uscxmlNativePHP.php b/src/bindings/swig/php/uscxmlNativePHP.php
index 12757d3..eac292b 100644
--- a/src/bindings/swig/php/uscxmlNativePHP.php
+++ b/src/bindings/swig/php/uscxmlNativePHP.php
@@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------
* This file was automatically generated by SWIG (http://www.swig.org).
- * Version 3.0.5
+ * Version 3.0.7
*
* This file is not intended to be easily readable and contains a number of
* coding conventions designed to improve portability and efficiency. Do not make
@@ -589,6 +589,14 @@ class NativeInterpreterMonitor {
return array_key_exists($var, $this->_pData);
}
+ function __construct($res=null) {
+ if (is_resource($res) && get_resource_type($res) === '_p_uscxml__InterpreterMonitor') {
+ $this->_cPtr=$res;
+ return;
+ }
+ $this->_cPtr=new_NativeInterpreterMonitor();
+ }
+
function beforeProcessingEvent($interpreter,$event) {
NativeInterpreterMonitor_beforeProcessingEvent($this->_cPtr,$interpreter,$event);
}
@@ -617,12 +625,12 @@ class NativeInterpreterMonitor {
NativeInterpreterMonitor_reportIssue($this->_cPtr,$interpreter,$issue);
}
- function __construct($res=null) {
- if (is_resource($res) && get_resource_type($res) === '_p_uscxml__InterpreterMonitor') {
- $this->_cPtr=$res;
- return;
+ function copyToInvokers($copy=null) {
+ switch (func_num_args()) {
+ case 0: $r=NativeInterpreterMonitor_copyToInvokers($this->_cPtr); break;
+ default: $r=NativeInterpreterMonitor_copyToInvokers($this->_cPtr,$copy);
}
- $this->_cPtr=new_NativeInterpreterMonitor();
+ return $r;
}
}
@@ -828,12 +836,15 @@ class InterpreterIssue {
const USCXML_ISSUE_INFO = InterpreterIssue_USCXML_ISSUE_INFO;
- function __construct($msg,$node,$severity) {
+ function __construct($msg,$node,$severity,$specRef=null) {
if (is_resource($msg) && get_resource_type($msg) === '_p_uscxml__InterpreterIssue') {
$this->_cPtr=$msg;
return;
}
- $this->_cPtr=new_InterpreterIssue($msg,$node,$severity);
+ switch (func_num_args()) {
+ case 3: $this->_cPtr=new_InterpreterIssue($msg,$node,$severity); break;
+ default: $this->_cPtr=new_InterpreterIssue($msg,$node,$severity,$specRef);
+ }
}
function toString() {
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index 72232b8..169d9f6 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -330,16 +330,19 @@ void NameSpaceInfo::init(const std::map<std::string, std::string>& namespaceInfo
}
void StateTransitionMonitor::beforeTakingTransition(uscxml::Interpreter interpreter, const Arabica::DOM::Element<std::string>& transition, bool moreComing) {
+ tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
std::cerr << "Transition: " << uscxml::DOMUtils::xPathForNode(transition) << std::endl;
}
void StateTransitionMonitor::onStableConfiguration(uscxml::Interpreter interpreter) {
+ tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
std::cerr << "Config: {";
printNodeSet(interpreter.getConfiguration());
std::cerr << "}" << std::endl;
}
void StateTransitionMonitor::beforeProcessingEvent(uscxml::Interpreter interpreter, const uscxml::Event& event) {
+ tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
switch (event.eventType) {
case uscxml::Event::INTERNAL:
std::cerr << "Internal Event: " << event.name << std::endl;
@@ -354,10 +357,12 @@ void StateTransitionMonitor::beforeProcessingEvent(uscxml::Interpreter interpret
}
void StateTransitionMonitor::beforeExecutingContent(Interpreter interpreter, const Arabica::DOM::Element<std::string>& element) {
+ tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
std::cerr << "Executable Content: " << DOMUtils::xPathForNode(element) << std::endl;
}
void StateTransitionMonitor::beforeExitingState(uscxml::Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing) {
+ tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
exitingStates.push_back(state);
if (!moreComing) {
std::cerr << "Exiting: {";
@@ -368,6 +373,7 @@ void StateTransitionMonitor::beforeExitingState(uscxml::Interpreter interpreter,
}
void StateTransitionMonitor::beforeEnteringState(uscxml::Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing) {
+ tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
enteringStates.push_back(state);
if (!moreComing) {
std::cerr << "Entering: {";
@@ -385,7 +391,8 @@ void StateTransitionMonitor::printNodeSet(const Arabica::XPath::NodeSet<std::str
seperator = ", ";
}
}
-
+tthread::recursive_mutex StateTransitionMonitor::_mutex;
+
std::map<std::string, boost::weak_ptr<InterpreterImpl> > Interpreter::_instances;
tthread::recursive_mutex Interpreter::_instanceMutex;
@@ -740,7 +747,7 @@ NodeSet<std::string> InterpreterImpl::getDocumentInitialTransitions() {
} else {
// try to get initial transition from initial element
- initialTransitions = _xpath.evaluate("/" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", _scxml).asNodeSet();
+ initialTransitions = _xpath.evaluate("/" + _nsInfo.xpathPrefix + "scxml/"+ _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", _scxml).asNodeSet();
if (initialTransitions.size() == 0) {
Arabica::XPath::NodeSet<std::string> initialStates;
// fetch per draft
@@ -791,6 +798,14 @@ InterpreterState InterpreterImpl::step(int waitForMS) {
std::cerr << std::endl;
#endif
+ // this is not mentionend in the standard, though it makes sense
+ for (int i = 0; i < initialTransitions.size(); i++) {
+ Element<std::string> transition(initialTransitions[i]);
+ USCXML_MONITOR_CALLBACK3(beforeTakingTransition, transition, (i + 1 < enabledTransitions.size()))
+ executeContent(transition);
+ USCXML_MONITOR_CALLBACK3(afterTakingTransition, transition, (i + 1 < enabledTransitions.size()))
+ }
+
enterStates(initialTransitions);
setInterpreterState(USCXML_MICROSTEPPED);
}
@@ -1050,6 +1065,8 @@ void InterpreterImpl::stabilize() {
_statesToInvoke = NodeSet<std::string>();
}
+#if 0
+
Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectTransitions(const std::string& event) {
Arabica::XPath::NodeSet<std::string> enabledTransitions;
@@ -1128,6 +1145,104 @@ LOOP:
return enabledTransitions;
}
+#else
+
+Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectTransitions(const std::string& event) {
+ Arabica::XPath::NodeSet<std::string> enabledTransitions;
+
+ NodeSet<std::string> atomicStates;
+ for (unsigned int i = 0; i < _configuration.size(); i++) {
+ if (isAtomic(Element<std::string>(_configuration[i])))
+ atomicStates.push_back(_configuration[i]);
+ }
+ atomicStates.to_document_order();
+
+ for (unsigned int i = 0; i < atomicStates.size(); i++) {
+ Element<std::string> state(atomicStates[i]);
+ while(true) {
+ NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state);
+ for (unsigned int k = 0; k < transitions.size(); k++) {
+ if (isEnabledTransition(Element<std::string>(transitions[k]), event)) {
+ enabledTransitions.push_back(transitions[k]);
+ goto NEXT_ATOMIC;
+ }
+ }
+ if (state.getParentNode() && state.getParentNode().getNodeType() == Node_base::ELEMENT_NODE) {
+ state = Element<std::string>(state.getParentNode());
+ } else {
+ goto NEXT_ATOMIC;
+ }
+ }
+ NEXT_ATOMIC:;
+ }
+
+#if 0
+ std::cerr << "Enabled transitions for '" << event << "': " << std::endl;
+ for (int i = 0; i < enabledTransitions.size(); i++) {
+ std::cerr << enabledTransitions[i] << std::endl << "----" << std::endl;
+ }
+ std::cerr << std::endl;
+#endif
+
+ enabledTransitions = removeConflictingTransitions(enabledTransitions);
+
+#if 0
+ std::cerr << "Non-conflicting transitions for '" << event << "': " << std::endl;
+ for (int i = 0; i < enabledTransitions.size(); i++) {
+ std::cerr << enabledTransitions[i] << std::endl << "----" << std::endl;
+ }
+ std::cerr << std::endl;
+#endif
+
+ return enabledTransitions;
+}
+
+
+Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectEventlessTransitions() {
+
+ Arabica::XPath::NodeSet<std::string> enabledTransitions;
+
+ NodeSet<std::string> atomicStates;
+ for (unsigned int i = 0; i < _configuration.size(); i++) {
+ if (isAtomic(Element<std::string>(_configuration[i])))
+ atomicStates.push_back(_configuration[i]);
+ }
+ atomicStates.to_document_order();
+
+ for (unsigned int i = 0; i < atomicStates.size(); i++) {
+ Element<std::string> state(atomicStates[i]);
+ while(true) {
+ NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state);
+ for (unsigned int k = 0; k < transitions.size(); k++) {
+ Element<std::string> transElem(transitions[k]);
+ if (!HAS_ATTR(transElem, "event") && hasConditionMatch(transElem)) {
+ enabledTransitions.push_back(transitions[k]);
+ goto NEXT_ATOMIC;
+ }
+ }
+ if (state.getParentNode() && state.getParentNode().getNodeType() == Node_base::ELEMENT_NODE) {
+ state = Element<std::string>(state.getParentNode());
+ } else {
+ goto NEXT_ATOMIC;
+ }
+ }
+ NEXT_ATOMIC:;
+ }
+
+#if 0
+ std::cerr << "Enabled eventless transitions: " << std::endl;
+ for (int i = 0; i < enabledTransitions.size(); i++) {
+ std::cerr << enabledTransitions[i] << std::endl << "----" << std::endl;
+ }
+ std::cerr << std::endl;
+#endif
+
+ enabledTransitions = removeConflictingTransitions(enabledTransitions);
+ return enabledTransitions;
+}
+
+
+#endif
bool InterpreterImpl::isEnabledTransition(const Element<std::string>& transition, const std::string& event) {
std::string eventName;
@@ -2151,9 +2266,15 @@ void InterpreterImpl::invoke(const Arabica::DOM::Element<std::string>& element)
USCXML_MONITOR_CALLBACK3(afterInvoking, Arabica::DOM::Element<std::string>(element), invokeReq.invokeid)
// this is out of draft but so useful to know when an invoker started
-// Event invSuccess;
-// invSuccess.name = "invoke.success." + invokeReq.invokeid;
-// receive(invSuccess);
+ if (HAS_ATTR(element, "callback")) {
+ std::string callback = ATTR(element, "callback");
+ if (callback.size() > 0) {
+ Event invSuccess;
+ invSuccess.name = callback + "." + invokeReq.invokeid;
+ receive(invSuccess);
+ }
+ }
+
} catch(boost::bad_lexical_cast e) {
LOG(ERROR) << "Exception caught while sending invoke request to invoker " << invokeReq.invokeid << ": " << e.what();
@@ -2594,7 +2715,8 @@ void InterpreterImpl::finalizeAndAutoForwardCurrentEvent() {
// do not autoforward to invokers that send to #_parent from the SCXML IO Processor!
// Yes do so, see test229!
// if (!boost::equals(_currEvent.getOriginType(), "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"))
- invokeIter->second.send(_currEvent);
+// LOG(ERROR) << _sessionId << " auto forwards " << _currEvent.name << " to " << invokeIter->first << std::endl;
+ invokeIter->second.send(_currEvent);
} catch (const std::exception &e) {
LOG(ERROR) << "Exception caught while sending event to invoker " << invokeIter->first << ": " << e.what();
} catch(...) {
@@ -2696,6 +2818,7 @@ Arabica::DOM::Node<std::string> InterpreterImpl::getAncestorElement(const Arabic
we are speaking of proper ancestor (parent or parent of a parent, etc.) the LCCA is never a member of stateList.
*/
+#define VERBOSE_FIND_LCCA 0
Arabica::DOM::Node<std::string> InterpreterImpl::findLCCA(const Arabica::XPath::NodeSet<std::string>& states) {
#if VERBOSE_FIND_LCCA
std::cerr << "findLCCA: ";
@@ -2729,7 +2852,7 @@ NEXT_ANCESTOR:
// take uppermost root as ancestor
if (!ancestor)
ancestor = _scxml;
- assert(ancestor);
+
#if VERBOSE_FIND_LCCA
std::cerr << " -> " << ATTR_CAST(ancestor, "id") << " " << ancestor.getLocalName() << std::endl;
#endif
@@ -2838,10 +2961,12 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::getInitialStates(Arabica::
// initial element as child - but not the implicit generated one
NodeSet<std::string> initElems = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state);
- if(initElems.size() == 1 && !iequals(ATTR_CAST(initElems[0], "generated"), "true")) {
+ if(initElems.size() > 0 && !iequals(ATTR_CAST(initElems[0], "generated"), "true")) {
NodeSet<std::string> initTrans = filterChildElements(_nsInfo.xmlNSPrefix + "transition", initElems[0]);
- return getTargetStates(Element<std::string>(initTrans[0]));
- }
+ if (initTrans.size() > 0) {
+ return getTargetStates(Element<std::string>(initTrans[0]));
+ }
+ }
// first child state
Arabica::XPath::NodeSet<std::string> initStates;
@@ -3096,6 +3221,14 @@ NodeSet<std::string> InterpreterImpl::filterChildType(const Node_base::Type type
return filteredChildTypes;
}
+/*
+ * If state2 is null, returns the set of all ancestors of state1 in ancestry order
+ * (state1's parent followed by the parent's parent, etc. up to an including the <scxml>
+ * element). If state2 is non-null, returns in ancestry order the set of all ancestors
+ * of state1, up to but not including state2. (A "proper ancestor" of a state is its
+ * parent, or the parent's parent, or the parent's parent's parent, etc.))If state2 is
+ * state1's parent, or equal to state1, or a descendant of state1, this returns the empty set.
+ */
NodeSet<std::string> InterpreterImpl::getProperAncestors(const Arabica::DOM::Node<std::string>& s1,
const Arabica::DOM::Node<std::string>& s2) {
@@ -3109,13 +3242,13 @@ NodeSet<std::string> InterpreterImpl::getProperAncestors(const Arabica::DOM::Nod
Arabica::DOM::Node<std::string> node = s1;
while((node = node.getParentNode())) {
if (node.getNodeType() != Node_base::ELEMENT_NODE)
- continue;
+ break;
Element<std::string> nodeElem(node);
if (!isState(nodeElem))
break;
- if (iequals(TAGNAME(nodeElem), _nsInfo.xmlNSPrefix + "scxml")) // do not return scxml root itself - this is somewhat ill-defined
- break;
+// if (iequals(TAGNAME(nodeElem), _nsInfo.xmlNSPrefix + "scxml")) // do not return scxml root itself - this is somewhat ill-defined
+// break;
if (!iequals(TAGNAME(nodeElem), _nsInfo.xmlNSPrefix + "parallel") &&
!iequals(TAGNAME(nodeElem), _nsInfo.xmlNSPrefix + "state") &&
!iequals(TAGNAME(nodeElem), _nsInfo.xmlNSPrefix + "scxml"))
@@ -3131,7 +3264,10 @@ NodeSet<std::string> InterpreterImpl::getProperAncestors(const Arabica::DOM::Nod
bool InterpreterImpl::isDescendant(const Arabica::DOM::Node<std::string>& s1,
const Arabica::DOM::Node<std::string>& s2) {
- Arabica::DOM::Node<std::string> parent = s1.getParentNode();
+ if (!s1 || !s2)
+ return false;
+
+ Arabica::DOM::Node<std::string> parent = s1.getParentNode();
while(parent) {
if (s2 == parent)
return true;
diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h
index b6719b5..4e450aa 100644
--- a/src/uscxml/Interpreter.h
+++ b/src/uscxml/Interpreter.h
@@ -859,6 +859,7 @@ protected:
class USCXML_API InterpreterMonitor {
public:
+ InterpreterMonitor() : _copyToInvokers(false) {}
virtual ~InterpreterMonitor() {}
virtual void beforeProcessingEvent(Interpreter interpreter, const Event& event) {}
@@ -891,6 +892,17 @@ public:
virtual void reportIssue(Interpreter interpreter, const InterpreterIssue& issue) {}
+ void copyToInvokers(bool copy) {
+ _copyToInvokers = copy;
+ }
+
+ bool copyToInvokers() {
+ return _copyToInvokers;
+ }
+
+protected:
+ bool _copyToInvokers;
+
};
class StateTransitionMonitor : public uscxml::InterpreterMonitor {
@@ -903,6 +915,7 @@ public:
virtual void beforeEnteringState(uscxml::Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing);
protected:
+ static tthread::recursive_mutex _mutex;
void printNodeSet(const Arabica::XPath::NodeSet<std::string>& config);
Arabica::XPath::NodeSet<std::string> exitingStates;
Arabica::XPath::NodeSet<std::string> enteringStates;
diff --git a/src/uscxml/debug/InterpreterIssue.cpp b/src/uscxml/debug/InterpreterIssue.cpp
index 103211b..49b595d 100644
--- a/src/uscxml/debug/InterpreterIssue.cpp
+++ b/src/uscxml/debug/InterpreterIssue.cpp
@@ -33,7 +33,7 @@ namespace uscxml {
using namespace Arabica::XPath;
using namespace Arabica::DOM;
-InterpreterIssue::InterpreterIssue(const std::string& msg, Arabica::DOM::Node<std::string> node, IssueSeverity severity) : message(msg), node(node), severity(severity) {
+InterpreterIssue::InterpreterIssue(const std::string& msg, Arabica::DOM::Node<std::string> node, IssueSeverity severity, const std::string& specRef) : message(msg), node(node), severity(severity), specRef(specRef) {
if (node)
xPath = DOMUtils::xPathForNode(node);
}
@@ -502,8 +502,17 @@ NEXT_TRANSITION:
// check for valid initial transition
{
NodeSet<std::string> initTrans;
- initTrans.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", initials, true));
- initTrans.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", histories, true));
+// initTrans.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", histories, true));
+
+ for (int i = 0; i < initials.size(); i++) {
+ Element<std::string> initial = Element<std::string>(initials[i]);
+ NodeSet<std::string> initTransitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", initial, true);
+ if (initTransitions.size() != 1) {
+ issues.push_back(InterpreterIssue("Initial element must define exactly one transition", initial, InterpreterIssue::USCXML_ISSUE_FATAL));
+ }
+ initTrans.push_back(initTransitions);
+
+ }
for (int i = 0; i < initTrans.size(); i++) {
Element<std::string> transition = Element<std::string>(initTrans[i]);
@@ -616,6 +625,9 @@ NEXT_TRANSITION:
if (!HAS_ATTR(element, *reqIter)) {
issues.push_back(InterpreterIssue("Element " + localName + " is missing required attribute '" + *reqIter + "'", element, InterpreterIssue::USCXML_ISSUE_WARNING));
}
+ if (HAS_ATTR(element, *reqIter) && ATTR(element, *reqIter).size() == 0) {
+ issues.push_back(InterpreterIssue("Required attribute '" + *reqIter + "' of element " + localName + " is empty", element, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
}
}
@@ -706,9 +718,18 @@ NEXT_TRANSITION:
if (HAS_ATTR(send, "delay") && HAS_ATTR(send, "target") && ATTR(send, "target")== "_internal") {
issues.push_back(InterpreterIssue("Send element cannot have delay with target _internal", send, InterpreterIssue::USCXML_ISSUE_WARNING));
}
- if (HAS_ATTR(send, "namelist") && InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", send, false).size() > 0) {
+
+ NodeSet<std::string> contentChilds = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", send, false);
+ NodeSet<std::string> paramChilds = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", send, false);
+
+ if (HAS_ATTR(send, "namelist") && contentChilds.size() > 0) {
issues.push_back(InterpreterIssue("Send element cannot have namelist attribute and content child", send, InterpreterIssue::USCXML_ISSUE_WARNING));
}
+
+ if (paramChilds.size() > 0 && contentChilds.size() > 0) {
+ issues.push_back(InterpreterIssue("Send element cannot have param child and content child", send, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+
}
for (int i = 0; i < cancels.size(); i++) {
Element<std::string> cancel = Element<std::string>(cancels[i]);
@@ -731,8 +752,19 @@ NEXT_TRANSITION:
if (HAS_ATTR(invoke, "namelist") && InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", invoke, false).size() > 0) {
issues.push_back(InterpreterIssue("Invoke element cannot have namelist attribute and param child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
}
+ if (HAS_ATTR(invoke, "src") && InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", invoke, false).size() > 0) {
+ issues.push_back(InterpreterIssue("Invoke element cannot have src attribute and content child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
+
+ }
}
+ for (int i = 0; i < doneDatas.size(); i++) {
+ Element<std::string> donedata = Element<std::string>(doneDatas[i]);
+ if (InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata, false).size() > 0 &&
+ InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", donedata, false).size() > 0) {
+ issues.push_back(InterpreterIssue("Donedata element cannot have param child and content child", donedata, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ }
}
// check that the datamodel is known if not already instantiated
diff --git a/src/uscxml/debug/InterpreterIssue.h b/src/uscxml/debug/InterpreterIssue.h
index c49233f..0e1f949 100644
--- a/src/uscxml/debug/InterpreterIssue.h
+++ b/src/uscxml/debug/InterpreterIssue.h
@@ -36,12 +36,13 @@ public:
USCXML_ISSUE_INFO
};
- InterpreterIssue(const std::string& msg, Arabica::DOM::Node<std::string> node, IssueSeverity severity);
+ InterpreterIssue(const std::string& msg, Arabica::DOM::Node<std::string> node, IssueSeverity severity, const std::string& specRef = "");
std::string xPath;
- std::string message;
+ std::string message;
Arabica::DOM::Node<std::string> node;
IssueSeverity severity;
+ std::string specRef;
private:
static std::list<InterpreterIssue> forInterpreter(InterpreterImpl* interpreter);
diff --git a/src/uscxml/interpreter/InterpreterRC.cpp b/src/uscxml/interpreter/InterpreterRC.cpp
index b933993..879c771 100644
--- a/src/uscxml/interpreter/InterpreterRC.cpp
+++ b/src/uscxml/interpreter/InterpreterRC.cpp
@@ -209,15 +209,22 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::computeExitSet(const Arabica
}
Arabica::XPath::NodeSet<std::string> InterpreterRC::computeExitSet(const Arabica::DOM::Node<std::string>& transition) {
- if (_exitSet.find(transition) != _exitSet.end()) // speed up removeConflicting
- return _exitSet[transition];
+// if (_exitSet.find(transition) != _exitSet.end()) // speed up removeConflicting
+// return _exitSet[transition];
Arabica::XPath::NodeSet<std::string> transitions;
transitions.push_back(transition);
Arabica::XPath::NodeSet<std::string> exitSet = computeExitSet(transitions);
- _exitSet[transition] = exitSet;
+ //_exitSet[transition] = exitSet;
+#if 0
+ std::cerr << "Exit set for transition '" << transition << "': " << std::endl;
+ for (int i = 0; i < exitSet.size(); i++) {
+ std::cerr << ATTR_CAST(exitSet[i], "id") << std::endl << "----" << std::endl;
+ }
+ std::cerr << std::endl;
+#endif
return exitSet;
}
@@ -303,11 +310,11 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab
// only process first donedata element
doneData = Element<std::string>(doneDatas[0]);
}
- internalDoneSend(parent, doneData);
if (parentIsScxmlState(s)) {
_topLevelFinalReached = true;
} else {
+ internalDoneSend(parent, doneData);
Element<std::string> grandParent = (Element<std::string>)parent.getParentNode();
// internalDoneSend(parent, Arabica::DOM::Element<std::string>());
diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
index 3c0b84b..dc0e281 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
@@ -556,7 +556,7 @@ void JSCDataModel::setForeach(const std::string& item,
}
bool JSCDataModel::isLocation(const std::string& expr) {
- // location needs to be RHS and ++ is only valid for RHS
+ // location needs to be LHS and ++ is only valid for LHS
return isValidSyntax(expr + "++");
}
diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp
index 2621c66..2ca2bb3 100644
--- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp
@@ -458,9 +458,9 @@ Data PromelaDataModel::evaluateExpr(void* ast) {
case PML_CMPND:
return getVariable(node);
case PML_STRING: {
-// std::string stripped = node->value.substr(1, node->value.size() - 2);
-// return Data(stripped, Data::VERBATIM);
- return Data(node->value, Data::INTERPRETED);
+ std::string stripped = node->value.substr(1, node->value.size() - 2);
+ return Data(stripped, Data::VERBATIM);
+// return Data(node->value, Data::INTERPRETED);
}
case PML_PLUS:
return dataToInt(evaluateExpr(*opIter++)) + dataToInt(evaluateExpr(*opIter++));
diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
index 06461aa..8822579 100644
--- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
@@ -793,7 +793,7 @@ NodeSetVariableResolver::resolveVariable(const std::string& namepaceUri,
const std::string& name) const {
std::map<std::string, NodeSet<std::string> >::const_iterator n = _variables.find(name);
if(n == _variables.end()) {
- ERROR_EXECUTION_THROW("No varable named '" + name + "'");
+ ERROR_EXECUTION_THROW("No variable named '" + name + "'");
}
#if VERBOSE
std::cout << std::endl << "Getting " << name << ":" << std::endl;
diff --git a/src/uscxml/plugins/element/fetch/FetchElement.cpp b/src/uscxml/plugins/element/fetch/FetchElement.cpp
index c042802..595c913 100644
--- a/src/uscxml/plugins/element/fetch/FetchElement.cpp
+++ b/src/uscxml/plugins/element/fetch/FetchElement.cpp
@@ -81,15 +81,15 @@ void FetchElement::downloadFailed(const URL& url, int errorCode) {
}
void FetchElement::enterElement(const Arabica::DOM::Element<std::string>& node) {
- if (!HAS_ATTR(node, "target") && !HAS_ATTR(node, "targetexpr")) {
- LOG(ERROR) << "Fetch element requires target or targetexpr";
+ if (!HAS_ATTR(node, "src") && !HAS_ATTR(node, "srcexpr")) {
+ LOG(ERROR) << "Fetch element requires src or srcexpr";
return;
}
- if (HAS_ATTR(node, "targetexpr") && !_interpreter->getDataModel()) {
- LOG(ERROR) << "Fetch element with targetexpr requires datamodel";
+ if (HAS_ATTR(node, "srcexpr") && !_interpreter->getDataModel()) {
+ LOG(ERROR) << "Fetch element with srcexpr requires datamodel";
return;
}
- _target = (HAS_ATTR(node, "target") ? ATTR(node, "target") : _interpreter->getDataModel().evalAsString(ATTR(node, "targetexpr")));
+ _source = (HAS_ATTR(node, "src") ? ATTR(node, "src") : _interpreter->getDataModel().evalAsString(ATTR(node, "srcexpr")));
if (!HAS_ATTR(node, "callback") && !HAS_ATTR(node, "callbackexpr")) {
LOG(ERROR) << "Fetch element requires callback or callbackexpr";
@@ -110,10 +110,10 @@ void FetchElement::enterElement(const Arabica::DOM::Element<std::string>& node)
return;
}
- _targetUrl = URL(_target);
+ _targetUrl = URL(_source);
if (!_targetUrl.isAbsolute()) {
if (!_targetUrl.toAbsolute(_interpreter->getBaseURL(node))) {
- LOG(ERROR) << "Cannot transform " << _target << " into absolute URL";
+ LOG(ERROR) << "Cannot transform " << _source << " into absolute URL";
return;
}
}
diff --git a/src/uscxml/plugins/element/fetch/FetchElement.h b/src/uscxml/plugins/element/fetch/FetchElement.h
index e3e5008..3b7628a 100644
--- a/src/uscxml/plugins/element/fetch/FetchElement.h
+++ b/src/uscxml/plugins/element/fetch/FetchElement.h
@@ -53,7 +53,7 @@ public:
protected:
URL _targetUrl;
- std::string _target;
+ std::string _source;
std::string _callback;
std::string _type;
};
diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
index 79b1829..d3aa35f 100644
--- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
+++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
@@ -64,7 +64,8 @@ Data USCXMLInvoker::getDataModelVariables() {
}
void USCXMLInvoker::send(const SendRequest& req) {
- _invokedInterpreter.receive(req);
+ if (_invokedInterpreter)
+ _invokedInterpreter.receive(req);
}
void USCXMLInvoker::cancel(const std::string sendId) {
@@ -96,6 +97,15 @@ void USCXMLInvoker::invoke(const InvokeRequest& req) {
DataModel dataModel(_invokedInterpreter.getImpl()->getDataModel());
_invokedInterpreter.getImpl()->setParentQueue(&_parentQueue);
+ // copy monitors
+ std::set<InterpreterMonitor*>::const_iterator monIter = _interpreter->_monitors.begin();
+ while(monIter != _interpreter->_monitors.end()) {
+ if ((*monIter)->copyToInvokers()) {
+ _invokedInterpreter.getImpl()->_monitors.insert(*monIter);
+ }
+ monIter++;
+ }
+
// transfer namespace prefixes
_invokedInterpreter.setNameSpaceInfo(_parentInterpreter->getNameSpaceInfo());
_invokedInterpreter.getImpl()->_sessionId = req.invokeid;
diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp