summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
index cf7c8e7..19d109a 100644
--- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp
+++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp
@@ -123,21 +123,22 @@ bool BasicHTTPIOProcessor::httpRecvRequest(const HTTPServer::Request& req) {
* raises.
*/
- // this will call the const subscript operator
-// if (req.data.at("content").hasKey("_scxmleventname")) {
-// reqEvent.name = req.data.at("content").at("_scxmleventname").atom;
-// }
-// if (req.data.at("content").hasKey("content")) {
-// reqEvent.content = req.data.at("content").at("content").atom;
-// }
-
+ { // if we sent ourself an event it will end up here
+ // this will call the const subscript operator
+ if (req.data.at("content").hasKey("_scxmleventname")) {
+ reqEvent.name = req.data.at("content").at("_scxmleventname").atom;
+ }
+ if (req.data.at("content").hasKey("content")) {
+ reqEvent.content = req.data.at("content").at("content").atom;
+ }
+ }
+
+ // if we used wget, it will end up here - unify?
if (req.data.hasKey("content")) {
const Data& data = req.data["content"];
for(std::map<std::string, Data>::const_iterator compIter = data.compound.begin();
compIter!= data.compound.end(); compIter++) {
- if (compIter->first == "_scxmleventname") {
- reqEvent.name = compIter->second.atom;
- } else if (compIter->first == "content") {
+ if (compIter->first == "content") {
reqEvent.content = compIter->second.atom;
} else {
reqEvent.data[compIter->first] = compIter->second;
@@ -145,6 +146,16 @@ bool BasicHTTPIOProcessor::httpRecvRequest(const HTTPServer::Request& req) {
}
}
+ if (req.data.hasKey("header")) {
+ const Data& data = req.data["header"];
+ for(std::map<std::string, Data>::const_iterator compIter = data.compound.begin();
+ compIter!= data.compound.end(); compIter++) {
+ if (compIter->first == "_scxmleventname") {
+ reqEvent.name = compIter->second.atom;
+ }
+ }
+ }
+
// check whether we can parse it as XML
if (reqEvent.content.length() > 0) {
NameSpacingParser parser = NameSpacingParser::fromXML(reqEvent.content);
diff --git a/src/uscxml/transform/ChartToFSM.cpp b/src/uscxml/transform/ChartToFSM.cpp
index fd7491c..d55ef24 100644
--- a/src/uscxml/transform/ChartToFSM.cpp
+++ b/src/uscxml/transform/ChartToFSM.cpp
@@ -416,6 +416,9 @@ void ChartToFSM::internalDoneSend(const Arabica::DOM::Element<std::string>& stat
if (!isState(state))
return;
+// if (LOCALNAME(state) == "scxml")
+// return;
+
// if (parentIsScxmlState(state))
// return;
@@ -596,19 +599,149 @@ void ChartToFSM::annotateRaiseAndSend(const Arabica::DOM::Element<std::string>&
}
}
-void ChartToFSM::indexTransitions() {
- indexTransitions(_scxml);
+void ChartToFSM::annotateDomain() {
+ Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
+ for (int i = 0; i < allTransitions.size(); i++) {
+ Element<std::string> transition(allTransitions[i]);
+ Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition);
+ if (domain) {
+ transition.setAttribute("domain", (HAS_ATTR_CAST(domain, "id") ? ATTR_CAST(domain, "id") : DOMUtils::xPathForNode(domain)));
+ } else {
+ transition.setAttribute("domain", "#UNDEF");
+ }
+ }
+}
+
+void ChartToFSM::annotateExitSet() {
+ Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
+ for (int i = 0; i < allTransitions.size(); i++) {
+ Element<std::string> transition(allTransitions[i]);
+ Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition);
+
+ Arabica::XPath::NodeSet<std::string> allStates = getAllStates();
+ std::ostringstream exitSetStr;
+ std::string seperator = "";
+ for (int j = 0; j < allStates.size(); j++) {
+ Element<std::string> state(allStates[j]);
+ if (state.getParentNode() == domain) {
+ exitSetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state));
+ seperator = ", ";
+ }
+ }
+ transition.setAttribute("exitset", exitSetStr.str());
+ }
+}
+
+void ChartToFSM::annotateEntrySet() {
+ Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
+ for (int i = 0; i < allTransitions.size(); i++) {
+ Element<std::string> transition(allTransitions[i]);
+
+ NodeSet<std::string> tmpTransitions;
+ NodeSet<std::string> tmpStatesToEnter;
+ NodeSet<std::string> tmpStatesForDefaultEntry;
+ std::map<std::string, Arabica::DOM::Node<std::string> > tmpDefaultHistoryContent;
+
+ tmpTransitions.push_back(transition);
+ computeEntrySet(tmpTransitions, tmpStatesToEnter, tmpStatesForDefaultEntry, tmpDefaultHistoryContent);
+
+ std::ostringstream entrySetStr;
+ std::string seperator = "";
+
+ for (int j = 0; j < tmpStatesToEnter.size(); j++) {
+ Element<std::string> state(tmpStatesToEnter[j]);
+ entrySetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state));
+ seperator = ", ";
+ }
+ for (int j = 0; j < tmpStatesForDefaultEntry.size(); j++) {
+ Element<std::string> state(tmpStatesForDefaultEntry[j]);
+ entrySetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state));
+ seperator = ", ";
+ }
+ transition.setAttribute("entryset", entrySetStr.str());
- size_t index = 0;
- for (std::vector<Arabica::DOM::Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) {
- transIter->setAttribute("priority", toStr(index));
- index++;
- }
+ }
+}
+
+void ChartToFSM::annotateConflicts() {
+ Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true);
+ Arabica::XPath::NodeSet<std::string> allStates = getAllStates();
+
+ for (int i = 0; i < allTransitions.size(); i++) {
+ Element<std::string> t1(allTransitions[i]);
+ if (!isState(Element<std::string>(t1.getParentNode())))
+ continue;
+
+ Arabica::DOM::Node<std::string> d1 = getTransitionDomain(t1);
+
+ Arabica::XPath::NodeSet<std::string> exitSet1;
+ for (int k = 0; k < allStates.size(); k++) {
+ Element<std::string> state(allStates[k]);
+ if (isDescendant(state, d1)) {
+ exitSet1.push_back(state);
+ }
+ }
+
+ std::ostringstream preemptionStr;
+ std::string seperator = "";
+
+ for (int j = 0; j < allTransitions.size(); j++) {
+ if ( i == j)
+ continue;
+
+ Element<std::string> t2(allTransitions[j]);
+ if (!isState(Element<std::string>(t2.getParentNode())))
+ continue;
+
+ Arabica::DOM::Node<std::string> d2 = getTransitionDomain(t2);
+
+ Arabica::XPath::NodeSet<std::string> exitSet2;
+ for (int k = 0; k < allStates.size(); k++) {
+ Element<std::string> state(allStates[k]);
+ if (isDescendant(state, d2)) {
+ exitSet2.push_back(state);
+ }
+ }
+
+ if (hasIntersection(exitSet1, exitSet2)) {
+ preemptionStr << seperator << (HAS_ATTR(t2, "priority") ? ATTR(t2, "priority") : DOMUtils::xPathForNode(t2));
+ seperator = ", ";
+ }
+
+// if (isDescendant(d1, d2) || isDescendant(d2, d1) || d1 == d2) {
+// preemptionStr << seperator << ATTR(t2, "priority");
+// seperator = ", ";
+// }
- // reverse indices for most prior to be in front
- std::reverse(indexedTransitions.begin(), indexedTransitions.end());
+ }
+ if (preemptionStr.str().size() > 0)
+ t1.setAttribute("conflicts", preemptionStr.str());
+
+ }
+}
+
+void ChartToFSM::indexTransitions() {
+ indexedTransitions.clear();
+ indexTransitions(_scxml);
+
+#if 1
+ size_t index = indexedTransitions.size() - 1;
+ for (std::vector<Arabica::DOM::Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) {
+ transIter->setAttribute("priority", toStr(index));
+ index--;
+ }
+#else
+ size_t index = 0;
+ for (std::vector<Arabica::DOM::Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) {
+ transIter->setAttribute("priority", toStr(index));
+ index++;
+ }
+#endif
+ // reverse indices for most prior to be in front
+ //std::reverse(indexedTransitions.begin(), indexedTransitions.end());
}
+#if 0
void ChartToFSM::indexTransitions(const Arabica::DOM::Element<std::string>& root) {
// breadth first traversal of transitions
Arabica::XPath::NodeSet<std::string> levelTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", root);
@@ -624,7 +757,26 @@ void ChartToFSM::indexTransitions(const Arabica::DOM::Element<std::string>& root
indexTransitions(stateElem);
}
}
+
+#else
+
+void ChartToFSM::indexTransitions(const Arabica::DOM::Element<std::string>& root) {
+ // Post-order traversal of transitions
+ Arabica::XPath::NodeSet<std::string> childStates = getChildStates(root);
+ for (int i = 0; i < childStates.size(); i++) {
+ Element<std::string> childElem(childStates[i]);
+ indexTransitions(childElem);
+ }
+
+ Arabica::XPath::NodeSet<std::string> levelTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", root);
+ for (int i = 0; i < levelTransitions.size(); i++) {
+ // push into index starting with least prior
+ indexedTransitions.push_back(Element<std::string>(levelTransitions[i]));
+ }
+}
+
+#endif
bool GlobalTransition::operator< (const GlobalTransition& other) const {
const std::vector<Arabica::DOM::Element<std::string> >& indexedTransitions = interpreter->indexedTransitions;
NodeSet<std::string> transitions = getTransitions();
diff --git a/src/uscxml/transform/ChartToFSM.h b/src/uscxml/transform/ChartToFSM.h
index 64d1a0c..f7e00c5 100644
--- a/src/uscxml/transform/ChartToFSM.h
+++ b/src/uscxml/transform/ChartToFSM.h
@@ -242,6 +242,10 @@ public:
virtual ~ChartToFSM();
void indexTransitions();
+ void annotateDomain();
+ void annotateExitSet();
+ void annotateEntrySet();
+ void annotateConflicts();
Arabica::DOM::Document<std::string> getDocument() const; // overwrite to return flat FSM
protected:
diff --git a/src/uscxml/transform/ChartToPromela.cpp b/src/uscxml/transform/ChartToPromela.cpp
index 867092d..965eebc 100644
--- a/src/uscxml/transform/ChartToPromela.cpp
+++ b/src/uscxml/transform/ChartToPromela.cpp
@@ -384,7 +384,7 @@ std::string PromelaCodeAnalyzer::createMacroName(const std::string& literal) {
return macroName;
}
-std::string PromelaCodeAnalyzer::getTypeReset(const std::string& var, const PromelaTypedef& type, const std::string padding) {
+ std::string PromelaCodeAnalyzer::getTypeReset(const std::string& var, const PromelaTypedef& type, const std::string padding) {
std::stringstream assignment;
std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin();
@@ -1603,52 +1603,53 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
}
if (_analyzer->usesComplexEventStruct()) {
stream << padding << "{" << std::endl;
- stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), padding + " ");
- stream << padding << " tmpE.name = " << event << ";" << std::endl;
+ std::string typeReset = _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), padding + " ");
+ std::stringstream typeAssignSS;
+ typeAssignSS << padding << " tmpE.name = " << event << ";" << std::endl;
if (HAS_ATTR(nodeElem, "idlocation")) {
- stream << padding << " /* idlocation */" << std::endl;
- stream << padding << " _lastSendId = _lastSendId + 1;" << std::endl;
- stream << padding << " " << _prefix << ATTR(nodeElem, "idlocation") << " = _lastSendId;" << std::endl;
- stream << padding << " tmpE.sendid = _lastSendId;" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: _lastSendId == 2147483647 -> _lastSendId = 0;" << std::endl;
- stream << padding << " :: else -> skip;" << std::endl;
- stream << padding << " fi;" << std::endl;
+ typeAssignSS << padding << " /* idlocation */" << std::endl;
+ typeAssignSS << padding << " _lastSendId = _lastSendId + 1;" << std::endl;
+ typeAssignSS << padding << " " << _prefix << ATTR(nodeElem, "idlocation") << " = _lastSendId;" << std::endl;
+ typeAssignSS << padding << " tmpE.sendid = _lastSendId;" << std::endl;
+ typeAssignSS << padding << " if" << std::endl;
+ typeAssignSS << padding << " :: _lastSendId == 2147483647 -> _lastSendId = 0;" << std::endl;
+ typeAssignSS << padding << " :: else -> skip;" << std::endl;
+ typeAssignSS << padding << " fi;" << std::endl;
} else if (HAS_ATTR(nodeElem, "id")) {
- stream << padding << " tmpE.sendid = " << _analyzer->macroForLiteral(ATTR(nodeElem, "id")) << ";" << std::endl;
+ typeAssignSS << padding << " tmpE.sendid = " << _analyzer->macroForLiteral(ATTR(nodeElem, "id")) << ";" << std::endl;
}
if (_invokerid.length() > 0) { // do not send invokeid if we send / raise to ourself
- stream << padding << " tmpE.invokeid = " << _analyzer->macroForLiteral(_invokerid) << ";" << std::endl;
+ typeAssignSS << padding << " tmpE.invokeid = " << _analyzer->macroForLiteral(_invokerid) << ";" << std::endl;
}
if (_analyzer->usesEventField("origintype") && !boost::ends_with(targetQueue, "iQ")) {
- stream << padding << " tmpE.origintype = " << _analyzer->macroForLiteral("http://www.w3.org/TR/scxml/#SCXMLEventProcessor") << ";" << std::endl;
+ typeAssignSS << padding << " tmpE.origintype = " << _analyzer->macroForLiteral("http://www.w3.org/TR/scxml/#SCXMLEventProcessor") << ";" << std::endl;
}
if (_analyzer->usesEventField("delay")) {
#if NEW_DELAY_RESHUFFLE
#else
insertOp += "!";
- stream << padding << " _lastSeqId = _lastSeqId + 1;" << std::endl;
+ typeAssignSS << padding << " _lastSeqId = _lastSeqId + 1;" << std::endl;
#endif
if (HAS_ATTR_CAST(nodeElem, "delay")) {
- stream << padding << " tmpE.delay = " << ATTR_CAST(nodeElem, "delay") << ";" << std::endl;
+ typeAssignSS << padding << " tmpE.delay = " << ATTR_CAST(nodeElem, "delay") << ";" << std::endl;
} else if (HAS_ATTR_CAST(nodeElem, "delayexpr")) {
- stream << padding << " tmpE.delay = " << ADAPT_SRC(ATTR_CAST(nodeElem, "delayexpr")) << ";" << std::endl;
+ typeAssignSS << padding << " tmpE.delay = " << ADAPT_SRC(ATTR_CAST(nodeElem, "delayexpr")) << ";" << std::endl;
} else {
- stream << padding << " tmpE.delay = 0;" << std::endl;
+ typeAssignSS << padding << " tmpE.delay = 0;" << std::endl;
}
#if NEW_DELAY_RESHUFFLE
#else
- stream << padding << " tmpE.seqNr = _lastSeqId;" << std::endl;
+ typeAssignSS << padding << " tmpE.seqNr = _lastSeqId;" << std::endl;
#endif
}
if (_analyzer->usesEventField("type")) {
std::string eventType = (targetQueue.compare("iQ!") == 0 ? _analyzer->macroForLiteral("internal") : _analyzer->macroForLiteral("external"));
- stream << padding << " tmpE.type = " << eventType << ";" << std::endl;
+ typeAssignSS << padding << " tmpE.type = " << eventType << ";" << std::endl;
}
NodeSet<std::string> sendParams = filterChildElements(_nsInfo.xmlNSPrefix + "param", nodeElem);
@@ -1657,14 +1658,14 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
if (sendParams.size() > 0) {
for (int i = 0; i < sendParams.size(); i++) {
Element<std::string> paramElem = Element<std::string>(sendParams[i]);
- stream << padding << " tmpE.data." << ATTR(paramElem, "name") << " = " << ADAPT_SRC(ATTR(paramElem, "expr")) << ";" << std::endl;
+ typeAssignSS << padding << " tmpE.data." << ATTR(paramElem, "name") << " = " << ADAPT_SRC(ATTR(paramElem, "expr")) << ";" << std::endl;
}
}
if (sendNameList.size() > 0) {
std::list<std::string> nameListIds = tokenizeIdRefs(sendNameList);
std::list<std::string>::iterator nameIter = nameListIds.begin();
while(nameIter != nameListIds.end()) {
- stream << padding << " tmpE.data." << *nameIter << " = " << ADAPT_SRC(*nameIter) << ";" << std::endl;
+ typeAssignSS << padding << " tmpE.data." << *nameIter << " = " << ADAPT_SRC(*nameIter) << ";" << std::endl;
nameIter++;
}
}
@@ -1674,14 +1675,42 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica:
if (contentElem.hasChildNodes() && contentElem.getFirstChild().getNodeType() == Node_base::TEXT_NODE) {
std::string content = spaceNormalize(contentElem.getFirstChild().getNodeValue());
if (!isNumeric(content.c_str(), 10)) {
- stream << padding << " tmpE.data = " << _analyzer->macroForLiteral(content) << ";" << std::endl;
+ typeAssignSS << padding << " tmpE.data = " << _analyzer->macroForLiteral(content) << ";" << std::endl;
} else {
- stream << padding << " tmpE.data = " << content << ";" << std::endl;
+ typeAssignSS << padding << " tmpE.data = " << content << ";" << std::endl;
}
} else if (HAS_ATTR(contentElem, "expr")) {
- stream << padding << " tmpE.data = " << ADAPT_SRC(ATTR(contentElem, "expr")) << ";" << std::endl;
+ typeAssignSS << padding << " tmpE.data = " << ADAPT_SRC(ATTR(contentElem, "expr")) << ";" << std::endl;
}
}
+
+ // remove all fields from typeReset that are indeed set by typeAssign
+// for (std::string assigned; std::getline(typeAssignSS, assigned); ) {
+// assigned = assigned.substr(0, assigned.find('='));
+// assigned = assigned.substr(assigned.find('.'));
+// std::istringstream typeResetSS (typeReset);
+// for (std::string reset; std::getline(typeResetSS, reset); ) {
+// if (!boost::find_first(reset, assigned)) {
+// stream << reset << std::endl;
+// }
+// }
+// }
+// stream << typeAssignSS.str();
+
+ std::istringstream typeResetSS (typeReset);
+ for (std::string reset; std::getline(typeResetSS, reset); ) {
+ std::string resetField = reset.substr(0, reset.find('='));
+ resetField = resetField.substr(resetField.find('.'));
+ for (std::string assigned; std::getline(typeAssignSS, assigned); ) {
+ if (boost::find_first(resetField, assigned)) {
+ break;
+ }
+ }
+ stream << reset << std::endl;
+ }
+ stream << typeAssignSS.str();
+
+
stream << padding << " " << targetQueue << insertOp <<"tmpE;" << std::endl;
#if NEW_DELAY_RESHUFFLE
@@ -2276,7 +2305,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
PromelaInline::PROMELA_EVENT_ONLY);
stream << " atomic {" << std::endl;
- stream << " /* pop an event */" << std::endl;
+ stream << "/* pop an event */" << std::endl;
stream << " if" << std::endl;
stream << " :: len(" << _prefix << "iQ) != 0 -> " << _prefix << "iQ ? " << _prefix << "_event /* from internal queue */" << std::endl;
if (eventSources.size() > 0) {
@@ -2363,7 +2392,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
stream << " fi;" << std::endl << std::endl;
- stream << " /* terminate if we are stopped */" << std::endl;
+ stream << "/* terminate if we are stopped */" << std::endl;
stream << " if" << std::endl;
stream << " :: " << _prefix << "done -> goto " << _prefix << "terminate;" << std::endl;
if (_parent != NULL) {
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index f9890da..13b371e 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,3 +1,5 @@
+set(TEST_TIMEOUT 10)
+
function(USCXML_TEST_COMPILE)
set(options BUILD_ONLY)
set(oneValueArgs LABEL NAME)
@@ -114,10 +116,19 @@ if (NOT BUILD_MINIMAL)
string(REGEX MATCH "[^//]+/[^//]+.scxml" TEST_NAME ${W3C_TEST})
# message("TEST_NAME: ${TEST_NAME}")
if (NOT TEST_NAME MATCHES ".*sub.*")
+ if (TEST_NAME MATCHES "^null\\/.*")
+ add_test(${TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c ${W3C_TEST})
+ set_property(TEST ${TEST_NAME} PROPERTY LABELS ${TEST_NAME})
+ set_tests_properties(${TEST_NAME} PROPERTIES TIMEOUT ${TEST_TIMEOUT})
+ endif()
+
if (BUILD_TESTS_W3C_ECMA AND TEST_NAME MATCHES "^ecma\\/.*")
add_test(${TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c ${W3C_TEST})
set_property(TEST ${TEST_NAME} PROPERTY LABELS ${TEST_NAME})
+ set_tests_properties(${TEST_NAME} PROPERTIES TIMEOUT ${TEST_TIMEOUT})
+
# set_tests_properties(${TEST_NAME} PROPERTIES FAIL_REGULAR_EXPRESSION "TEST FAILED")
+
if (TEST_NAME STREQUAL "ecma/test250.scxml")
set_tests_properties(${TEST_NAME} PROPERTIES
FAIL_REGULAR_EXPRESSION "entering final state, invocation was not cancelled")
@@ -127,9 +138,10 @@ if (NOT BUILD_MINIMAL)
endif()
endif()
- if (BUILD_TESTS_FSM_ECMA AND TEST_NAME MATCHES "^ecma\\/.*")
+ if (BUILD_TESTS_FSM AND BUILD_TESTS_FSM_ECMA AND TEST_NAME MATCHES "^ecma\\/.*")
add_test("fsm/${TEST_NAME}" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c -f ${W3C_TEST})
set_property(TEST "fsm/${TEST_NAME}" PROPERTY LABELS "fsm/${TEST_NAME}")
+ set_tests_properties("fsm/${TEST_NAME}" PROPERTIES TIMEOUT ${TEST_TIMEOUT})
add_test(NAME "minimized/${TEST_NAME}"
COMMAND ${CMAKE_COMMAND}
@@ -139,51 +151,73 @@ if (NOT BUILD_MINIMAL)
-DUSCXML_W3C_TEST_BIN:FILEPATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c
-P ${CMAKE_CURRENT_SOURCE_DIR}/w3c/run_minimized_test.cmake)
set_property(TEST "minimized/${TEST_NAME}" PROPERTY LABELS "minimized/${TEST_NAME}")
+ set_tests_properties("minimized/${TEST_NAME}" PROPERTIES TIMEOUT ${TEST_TIMEOUT})
set_tests_properties(${TEST_NAME} PROPERTIES DEPENDS uscxml-transform)
set_tests_properties(${TEST_NAME} PROPERTIES DEPENDS test-w3c)
- add_test(NAME "fsm/minimized/${TEST_NAME}"
- COMMAND ${CMAKE_COMMAND}
- -DOUTDIR:FILEPATH=${CMAKE_CURRENT_BINARY_DIR}/ecma
- -DTESTFILE:FILEPATH=${W3C_TEST}
- -DUSCXML_TRANSFORM_BIN:FILEPATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uscxml-transform
- -DUSCXML_W3C_TEST_BIN:FILEPATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c
- -P ${CMAKE_CURRENT_SOURCE_DIR}/w3c/run_minimized_flat_test.cmake)
- set_property(TEST "fsm/minimized/${TEST_NAME}" PROPERTY LABELS "fsm/minimized/${TEST_NAME}")
+ # add_test(NAME "fsm/minimized/${TEST_NAME}"
+ # COMMAND ${CMAKE_COMMAND}
+ # -DOUTDIR:FILEPATH=${CMAKE_CURRENT_BINARY_DIR}/ecma
+ # -DTESTFILE:FILEPATH=${W3C_TEST}
+ # -DUSCXML_TRANSFORM_BIN:FILEPATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uscxml-transform
+ # -DUSCXML_W3C_TEST_BIN:FILEPATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c
+ # -P ${CMAKE_CURRENT_SOURCE_DIR}/w3c/run_minimized_flat_test.cmake)
+ # set_property(TEST "fsm/minimized/${TEST_NAME}" PROPERTY LABELS "fsm/minimized/${TEST_NAME}")
+ # set_tests_properties("fsm/minimized/${TEST_NAME}" PROPERTIES TIMEOUT ${TEST_TIMEOUT})
- set_tests_properties(${TEST_NAME} PROPERTIES DEPENDS uscxml-transform)
- set_tests_properties(${TEST_NAME} PROPERTIES DEPENDS test-w3c)
+ # set_tests_properties(${TEST_NAME} PROPERTIES DEPENDS uscxml-transform)
+ # set_tests_properties(${TEST_NAME} PROPERTIES DEPENDS test-w3c)
endif()
if (BUILD_TESTS_W3C_XPATH AND TEST_NAME MATCHES "^xpath\\/.*")
add_test(${TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c ${W3C_TEST})
set_property(TEST ${TEST_NAME} PROPERTY LABELS ${TEST_NAME})
+ set_tests_properties(${TEST_NAME} PROPERTIES TIMEOUT ${TEST_TIMEOUT})
# set_tests_properties(${TEST_NAME} PROPERTIES FAIL_REGULAR_EXPRESSION "TEST FAILED")
+ if (BUILD_TESTS_FSM AND BUILD_TESTS_FSM_XPATH)
+ add_test("fsm/${TEST_NAME}" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c -f ${W3C_TEST})
+ set_property(TEST "fsm/${TEST_NAME}" PROPERTY LABELS "fsm/${TEST_NAME}")
+ set_tests_properties("fsm/${TEST_NAME}" PROPERTIES TIMEOUT ${TEST_TIMEOUT})
+ endif()
endif()
- if (BUILD_TESTS_FSM_XPATH AND TEST_NAME MATCHES "^xpath\\/.*")
- add_test("fsm/${TEST_NAME}" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c -f ${W3C_TEST})
- set_property(TEST "fsm/${TEST_NAME}" PROPERTY LABELS "fsm/${TEST_NAME}")
- endif()
-
if (BUILD_DM_LUA AND LUA_FOUND AND BUILD_TESTS_W3C_LUA AND TEST_NAME MATCHES "^lua\\/.*")
add_test(${TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c ${W3C_TEST})
set_property(TEST ${TEST_NAME} PROPERTY LABELS ${TEST_NAME})
+ set_tests_properties(${TEST_NAME} PROPERTIES TIMEOUT ${TEST_TIMEOUT})
# set_tests_properties(${TEST_NAME} PROPERTIES FAIL_REGULAR_EXPRESSION "TEST FAILED")
+ if (BUILD_TESTS_FSM AND BUILD_TESTS_FSM_LUA)
+ add_test("fsm/${TEST_NAME}" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c -f ${W3C_TEST})
+ set_property(TEST "fsm/${TEST_NAME}" PROPERTY LABELS "fsm/${TEST_NAME}")
+ set_tests_properties("fsm/${TEST_NAME}" PROPERTIES TIMEOUT ${TEST_TIMEOUT})
+ endif()
+
endif()
if (BUILD_DM_PROLOG AND SWI_FOUND AND BUILD_TESTS_W3C_PROLOG AND TEST_NAME MATCHES "^prolog\\/.*")
add_test(${TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c ${W3C_TEST})
set_property(TEST ${TEST_NAME} PROPERTY LABELS ${TEST_NAME})
+ set_tests_properties(${TEST_NAME} PROPERTIES TIMEOUT ${TEST_TIMEOUT})
# set_tests_properties(${TEST_NAME} PROPERTIES FAIL_REGULAR_EXPRESSION "TEST FAILED")
+ if (BUILD_TESTS_FSM AND BUILD_TESTS_FSM_PROLOG)
+ add_test("fsm/${TEST_NAME}" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c -f ${W3C_TEST})
+ set_property(TEST "fsm/${TEST_NAME}" PROPERTY LABELS "fsm/${TEST_NAME}")
+ set_tests_properties("fsm/${TEST_NAME}" PROPERTIES TIMEOUT ${TEST_TIMEOUT})
+ endif()
endif()
if (BUILD_DM_PROMELA AND BUILD_TESTS_W3C_PROMELA AND TEST_NAME MATCHES "^promela\\/.*")
add_test(${TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c ${W3C_TEST})
set_property(TEST ${TEST_NAME} PROPERTY LABELS ${TEST_NAME})
+ set_tests_properties(${TEST_NAME} PROPERTIES TIMEOUT ${TEST_TIMEOUT})
# set_tests_properties(${TEST_NAME} PROPERTIES FAIL_REGULAR_EXPRESSION "TEST FAILED")
+ if (BUILD_TESTS_FSM AND BUILD_TESTS_FSM_PROMELA)
+ add_test("fsm/${TEST_NAME}" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-w3c -f ${W3C_TEST})
+ set_property(TEST "fsm/${TEST_NAME}" PROPERTY LABELS "fsm/${TEST_NAME}")
+ set_tests_properties("fsm/${TEST_NAME}" PROPERTIES TIMEOUT ${TEST_TIMEOUT})
+ endif()
endif()
if (GCC AND SPIN AND BUILD_DM_PROMELA AND BUILD_TESTS_W3C_PROMELA AND TEST_NAME MATCHES "^promela\\/.*")
@@ -197,6 +231,7 @@ if (NOT BUILD_MINIMAL)
-DGCC_BIN:FILEPATH=${GCC}
-P ${CMAKE_CURRENT_SOURCE_DIR}/w3c/run_promela_test.cmake)
set_property(TEST "spin/${TEST_NAME}" PROPERTY LABELS "spin/${TEST_NAME}")
+ set_tests_properties("spin/${TEST_NAME}" PROPERTIES TIMEOUT ${TEST_TIMEOUT})
set_tests_properties("spin/${TEST_NAME}" PROPERTIES PASS_REGULAR_EXPRESSION "depth reached [0-9]+, errors: 0")
set_tests_properties("spin/${TEST_NAME}" PROPERTIES FAIL_REGULAR_EXPRESSION "depth reached [0-9]+, errors: [1-9]+")
diff --git a/test/ctest/CTestCustom.ctest.in b/test/ctest/CTestCustom.ctest.in
index 3af297e..3b0243a 100644
--- a/test/ctest/CTestCustom.ctest.in
+++ b/test/ctest/CTestCustom.ctest.in
@@ -1,11 +1,20 @@
# grep -ori 'datamodel="xpath' .
-# skip xpath datamodel tests
-
+# grep -ori 'datamodel="null' .
# grep -ori 'manual' .
-# manual tests
-# grep -ori 'datamodel="null' .
-# skip xpath datamodel tests
+# manual tests:
+# "test178.scxml"
+# "test230.scxml"
+# "test250.scxml"
+# "test301.scxml" # Allowed to reject
+# "test307.scxml"
+# "test313.scxml" # Allowed to be rejected
+# "test314.scxml" # Allowed to be rejected
+# "test415.scxml"
+# "test513.txt"
+
+# null datamodel
+# "test436.scxml"
# these are manual or xpath tests generated by the ecma generator
set(CTEST_CUSTOM_TESTS_IGNORE
@@ -14,123 +23,176 @@ set(CTEST_CUSTOM_TESTS_IGNORE
"ecma/test178.scxml" # Manual - PASSED
"ecma/test230.scxml" # Manual - PASSED
"ecma/test250.scxml" # Manual - PASSED
- "ecma/test301.scxml" # Manual - PASSED
"ecma/test307.scxml" # Manual - PASSED
+ "ecma/test313.scxml" # Manual - PASSED
+ "ecma/test314.scxml" # Manual - PASSED
"ecma/test415.scxml" # Manual - PASSED
# "ecma/test513.txt" # Manual - PASSED
+
+ "ecma/test301.scxml" # Invalid script URL - PASSED
+ "ecma/test436.scxml" # Tests NULL datamodel - PASSED
+
### Ignore for flattened ECMAScript datamodel
- "fsm/ecma/test178.scxml" # manual test
- "fsm/ecma/test230.scxml" # manual test
- "fsm/ecma/test250.scxml" # manual test
- "fsm/ecma/test301.scxml" # manual test
- "fsm/ecma/test307.scxml" # manual test
- "fsm/ecma/test415.scxml" # manual test
- # "fsm/ecma/test513.txt" # manual test
+ "fsm/ecma/test178.scxml" # Manual - PASSED
+ "fsm/ecma/test230.scxml" # Manual - PASSED
+ "fsm/ecma/test250.scxml" # Manual - PASSED
+ "fsm/ecma/test307.scxml" # Manual - PASSED
+ "fsm/ecma/test313.scxml" # Manual - PASSED
+ "fsm/ecma/test314.scxml" # Manual - PASSED
+ "fsm/ecma/test415.scxml" # Manual - PASSED
+ # "fsm/ecma/test513.txt" # Manual - PASSED
+
+ "fsm/ecma/test301.scxml" # Invalid script URL - PASSED
+ "fsm/ecma/test436.scxml" # Tests NULL datamodel - PASSED
### Ignore for flattened, minimized ECMAScript datamodel
- "fsm/minimized/ecma/test178.scxml" # manual test
- "fsm/minimized/ecma/test230.scxml" # manual test
- "fsm/minimized/ecma/test250.scxml" # manual test
- "fsm/minimized/ecma/test301.scxml" # manual test
- "fsm/minimized/ecma/test307.scxml" # manual test
- "fsm/minimized/ecma/test415.scxml" # manual test
- # "fsm/ecma/test513.txt" # manual test
+ "fsm/minimized/ecma/test178.scxml" # Manual - PASSED
+ "fsm/minimized/ecma/test230.scxml" # Manual - PASSED
+ "fsm/minimized/ecma/test250.scxml" # Manual - PASSED
+ "fsm/minimized/ecma/test307.scxml" # Manual - PASSED
+ "fsm/minimized/ecma/test313.scxml" # Manual - PASSED
+ "fsm/minimized/ecma/test314.scxml" # Manual - PASSED
+ "fsm/minimized/ecma/test415.scxml" # Manual - PASSED
+ # "fsm/minimized/ecma/test513.txt" # Manual - PASSED
+
+ "fsm/minimized/ecma/test301.scxml" # Invalid script URL - PASSED
+ "fsm/minimized/ecma/test436.scxml" # Tests NULL datamodel - PASSED
+
### Just ignore the XPath datamodel tests that hang, most of the rest fails as well
- "xpath/test388.scxml" # hangs
- "xpath/test580.scxml" # hangs
+ "xpath/test178.scxml" # Manual - PASSED
+ "xpath/test230.scxml" # Manual - PASSED
+ "xpath/test250.scxml" # Manual - PASSED
+ "xpath/test307.scxml" # Manual - PASSED
+ "xpath/test313.scxml" # Manual - PASSED
+ "xpath/test314.scxml" # Manual - PASSED
+ "xpath/test415.scxml" # Manual - PASSED
+ # "xpath/test513.txt" # Manual - PASSED
+
+ "xpath/test301.scxml" # Invalid script URL - PASSED
+ "xpath/test436.scxml" # Tests NULL datamodel - PASSED
+
+
+ ### Ignore for LUA datamodel
+ "lua/test178.scxml" # Manual - PASSED
+ "lua/test230.scxml" # Manual - PASSED
+ "lua/test250.scxml" # Manual - PASSED
+ "lua/test307.scxml" # Manual - PASSED
+ "lua/test313.scxml" # Manual - PASSED
+ "lua/test314.scxml" # Manual - PASSED
+ "lua/test415.scxml" # Manual - PASSED
+ # "lua/test513.txt" # Manual - PASSED
+
+ "lua/test301.scxml" # Invalid script URL - PASSED
+ "lua/test436.scxml" # Tests NULL datamodel - PASSED
+
+ ### Ignore for Prolog datamodel
+ "prolog/test178.scxml" # Manual - PASSED
+ "prolog/test230.scxml" # Manual - PASSED
+ "prolog/test250.scxml" # Manual - PASSED
+ "prolog/test307.scxml" # Manual - PASSED
+ "prolog/test313.scxml" # Manual - PASSED
+ "prolog/test314.scxml" # Manual - PASSED
+ "prolog/test415.scxml" # Manual - PASSED
+ # "lua/test513.txt" # Manual - PASSED
+
+ "prolog/test301.scxml" # Invalid script URL - PASSED
+ "prolog/test436.scxml" # Tests NULL datamodel - PASSED
### Ignore for PROMELA datamodel
- "promela/test178.scxml" # two identical params in _event.raw - failed
- "promela/test230.scxml" # autoforwarded events are identical - passed
- "promela/test250.scxml" # no onexit in cancelled invoker - passed
- "promela/test301.scxml" # reject invalid script - passed
- "promela/test307.scxml" # declare variable via script - failed
- "promela/test415.scxml" # terminate on toplevel final - passed
- # "promela/test513.txt" # manual test
-
- "promela/test190.scxml" # string concatenation
- "promela/test224.scxml" # string operation startWith
- "promela/test280.scxml" # no runtime checks for undeclared variables
- "promela/test350.scxml" # string concatenation
- "promela/test509.scxml" # string operation contains
- "promela/test518.scxml" # string operation contains
- "promela/test519.scxml" # string operation contains
- "promela/test520.scxml" # string operation contains
- "promela/test525.scxml" # assumes unbound arrays
- "promela/test530.scxml" # assigns DOM node to variable
- "promela/test534.scxml" # string operation contains
-
-
- ### Ignore for PROMELA model checking
+ # manual tests
+ "promela/test178.scxml" # two identical params in _event.raw - FAILED
+ "promela/test230.scxml" # autoforwarded events are identical - PASSED
+ "promela/test250.scxml" # no onexit in cancelled invoker - PASSED
+ "promela/test307.scxml" # late data-binding - PASSED
+ "promela/test313.scxml" # Manual - PASSED
+ "promela/test314.scxml" # Manual - PASSED
+ "promela/test415.scxml" # terminate on toplevel final - PASSED
+ # "promela/test513.txt" # manual test - PASSED
+
+ "promela/test301.scxml" # reject invalid script - PASSED
+ "promela/test436.scxml" # Tests NULL datamodel - PASSED
+
+
+ # "promela/test190.scxml" # string concatenation
+ # "promela/test224.scxml" # string operation startWith
+ # "promela/test280.scxml" # no runtime checks for undeclared variables
+ # "promela/test350.scxml" # string concatenation
+ # "promela/test509.scxml" # string operation contains
+ # "promela/test518.scxml" # string operation contains
+ # "promela/test519.scxml" # string operation contains
+ # "promela/test520.scxml" # string operation contains
+ # "promela/test525.scxml" # assumes unbound arrays
+ # "promela/test530.scxml" # assigns DOM node to variable
+ # "promela/test534.scxml" # string operation contains
+
+
+ ### Ignore for SPIN model checking
# manual tests
- "spin/promela/test178.scxml" # two identical params in _event.raw - failed
- "spin/promela/test230.scxml" # autoforwarded events are identical - passed
- "spin/promela/test250.scxml" # no onexit in cancelled invoker - passed
- "spin/promela/test301.scxml" # reject invalid script - passed
- "spin/promela/test307.scxml" # declare variable via script - failed
- "spin/promela/test415.scxml" # terminate on toplevel final - passed
- # "spin/promela/test513.txt" # manual test
+ # "spin/promela/test178.scxml" # two identical params in _event.raw - FAILED
+ # "spin/promela/test230.scxml" # autoforwarded events are identical - PASSED
+ # "spin/promela/test250.scxml" # no onexit in cancelled invoker - PASSED
+ # "spin/promela/test307.scxml" # declare variable via script - FAILED
+ # "spin/promela/test313.scxml" # assignment of 'return'
+ # "spin/promela/test314.scxml" # assignment of 'return'
+ # "spin/promela/test415.scxml" # terminate on toplevel final - PASSED
+ # "spin/promela/test513.txt" # manual test - FAILED
+
+ # "spin/promela/test301.scxml" # reject invalid script - PASSED
+ # "spin/promela/test436.scxml" # In(s) -> _x.states[s] prevents completion as NULL dm is hardcoded
# fail for syntax
-# "spin/promela/test150.scxml" # test that foreach causes a new variable to be declared
-# "spin/promela/test151.scxml" # test that foreach causes a new variable to be declared
- "spin/promela/test152.scxml" # test that an illegal array or item value causes error.execution
- "spin/promela/test156.scxml" # test that an error causes the foreach to stop execution
- "spin/promela/test224.scxml" # string operation startWith
- "spin/promela/test277.scxml" # platform creates unbound variable if we assign an illegal value to it
- "spin/promela/test280.scxml" # late data binding / undeclared variable
- "spin/promela/test286.scxml" # assignment to a non-declared var causes an error
- "spin/promela/test294.scxml" # mixed types for event.data via donedata
-# "spin/promela/test302.scxml" # variable not declared
-# "spin/promela/test304.scxml" # variable not declared
- "spin/promela/test309.scxml" # 'return' as an invalid boolean expression ought to eval to false
- "spin/promela/test311.scxml" # assignment to a non-declared var
- "spin/promela/test312.scxml" # assignment of 'return'
- "spin/promela/test313.scxml" # assignment of 'return'
- "spin/promela/test314.scxml" # assignment of 'return'
- "spin/promela/test322.scxml" # assignment to _sessionid
- "spin/promela/test324.scxml" # assignment to _name
- "spin/promela/test325.scxml" # assignment from _ioprocessor
- "spin/promela/test326.scxml" # assignment from _ioprocessor
- "spin/promela/test329.scxml" # test that none of the system variables can be modified
- "spin/promela/test344.scxml" # 'return' as a cond
- "spin/promela/test346.scxml" # assignment to system variables
- "spin/promela/test350.scxml" # string concatenation
- "spin/promela/test354.scxml" # mixed types for event.data
- "spin/promela/test401.scxml" # variable not declared
- "spin/promela/test402.scxml" # variable not declared
- "spin/promela/test436.scxml" # In(s) -> _x.states[s] prevents completion as NULL dm is hardcoded
- "spin/promela/test487.scxml" # assignment of 'return'
- "spin/promela/test509.scxml" # string operation contains
- "spin/promela/test518.scxml" # string operation contains
- "spin/promela/test519.scxml" # string operation contains
- "spin/promela/test520.scxml" # string operation contains
- "spin/promela/test525.scxml" # assumes unbound arrays
- "spin/promela/test530.scxml" # assigns DOM node to variable
- "spin/promela/test534.scxml" # string operation contains
+ # "spin/promela/test152.scxml" # test that an illegal array or item value causes error.execution
+ # "spin/promela/test156.scxml" # test that an error causes the foreach to stop execution
+ # "spin/promela/test224.scxml" # string operation startWith
+ # "spin/promela/test277.scxml" # platform creates unbound variable if we assign an illegal value to it
+ # "spin/promela/test280.scxml" # late data binding / undeclared variable
+ # "spin/promela/test286.scxml" # assignment to a non-declared var causes an error
+ # "spin/promela/test294.scxml" # mixed types for event.data via donedata
+ # "spin/promela/test309.scxml" # 'return' as an invalid boolean expression ought to eval to false
+ # "spin/promela/test311.scxml" # assignment to a non-declared var
+ # "spin/promela/test312.scxml" # assignment of 'return'
+ # "spin/promela/test322.scxml" # assignment to _sessionid
+ # "spin/promela/test324.scxml" # assignment to _name
+ # "spin/promela/test325.scxml" # assignment from _ioprocessor
+ # "spin/promela/test326.scxml" # assignment from _ioprocessor
+ # "spin/promela/test329.scxml" # test that none of the system variables can be modified
+ # "spin/promela/test344.scxml" # 'return' as a cond
+ # "spin/promela/test346.scxml" # assignment to system variables
+ # "spin/promela/test350.scxml" # string concatenation
+ # "spin/promela/test354.scxml" # mixed types for event.data
+ # "spin/promela/test401.scxml" # variable not declared
+ # "spin/promela/test402.scxml" # variable not declared
+ # "spin/promela/test487.scxml" # assignment of 'return'
+ # "spin/promela/test509.scxml" # string operation contains
+ # "spin/promela/test518.scxml" # string operation contains
+ # "spin/promela/test519.scxml" # string operation contains
+ # "spin/promela/test520.scxml" # string operation contains
+ # "spin/promela/test525.scxml" # assumes unbound arrays
+ # "spin/promela/test530.scxml" # assigns DOM node to variable
+ # "spin/promela/test534.scxml" # string operation contains
# fail for semantics
- "spin/promela/test159.scxml" # error raised causes all subsequent elements to be skipped
- "spin/promela/test194.scxml" # illegal target for send
- "spin/promela/test199.scxml" # invalid send type
- "spin/promela/test216.scxml" # nested SCXML document with srcexpr at invoke
- "spin/promela/test298.scxml" # non-existent data model location
- "spin/promela/test331.scxml" # tests _error.type via 'error.execution'
- "spin/promela/test332.scxml" # tests _error.sendid via 'error.execution'
- "spin/promela/test343.scxml" # test that illegal <param> produces error.execution
- "spin/promela/test488.scxml" # illegal expr in <param> produces error.execution
- "spin/promela/test496.scxml" # tests error.communication with illegal target
- "spin/promela/test521.scxml" # tests error.communication with illegal target
- "spin/promela/test528.scxml" # illegal 'expr' produces error.execution
- "spin/promela/test531.scxml" # uses _ioprocessors.basichttp.location
- "spin/promela/test532.scxml" # uses _ioprocessors.basichttp.location
- "spin/promela/test553.scxml" # error in namelist
- "spin/promela/test554.scxml" # evaluation of <invoke>'s args causes an error
- "spin/promela/test577.scxml" # send without target for basichttp
+ # "spin/promela/test159.scxml" # error raised causes all subsequent elements to be skipped
+ # "spin/promela/test194.scxml" # illegal target for send
+ # "spin/promela/test199.scxml" # invalid send type
+ # "spin/promela/test216.scxml" # nested SCXML document with srcexpr at invoke
+ # "spin/promela/test298.scxml" # non-existent data model location
+ # "spin/promela/test331.scxml" # tests _error.type via 'error.execution'
+ # "spin/promela/test332.scxml" # tests _error.sendid via 'error.execution'
+ # "spin/promela/test343.scxml" # test that illegal <param> produces error.execution
+ # "spin/promela/test488.scxml" # illegal expr in <param> produces error.execution
+ # "spin/promela/test496.scxml" # tests error.communication with illegal target
+ # "spin/promela/test521.scxml" # tests error.communication with illegal target
+ # "spin/promela/test528.scxml" # illegal 'expr' produces error.execution
+ # "spin/promela/test531.scxml" # uses _ioprocessors.basichttp.location
+ # "spin/promela/test532.scxml" # uses _ioprocessors.basichttp.location
+ # "spin/promela/test553.scxml" # error in namelist
+ # "spin/promela/test554.scxml" # evaluation of <invoke>'s args causes an error
+ # "spin/promela/test577.scxml" # send without target for basichttp
)
diff --git a/test/src/test-issue-reporting.cpp b/test/src/test-issue-reporting.cpp
index 7b3d99c..9750c58 100644
--- a/test/src/test-issue-reporting.cpp
+++ b/test/src/test-issue-reporting.cpp
@@ -207,7 +207,9 @@ int main(int argc, char** argv) {
const char* xml =
"<scxml datamodel=\"ecmascript\">"
" <state id=\"start\" initial=\"foo\">"
- " <initial></initial>"
+ " <initial>"
+ " <transition target=\"foo\" />"
+ " </initial>"
" <state id=\"foo\" />"
" </state>"
"</scxml>";
@@ -216,6 +218,7 @@ int main(int argc, char** argv) {
assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
assert(issueLocations.size() == 1);
}
+
{
// initial attribute with atomic state
const char* xml =
@@ -227,23 +230,162 @@ int main(int argc, char** argv) {
assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
assert(issueLocations.size() == 1);
}
+
{
// initial child with atomic state
const char* xml =
"<scxml datamodel=\"ecmascript\">"
" <state id=\"start\">"
- " <initial />"
+ " <initial>"
+ " <transition target=\"start\" />"
+ " </initial>"
" </state>"
"</scxml>";
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
+ assert(issueLocations.size() == 2); // also invalid non-child target state in initial
+ }
+
+ // combinations of namelist, content and param
+ {
+ // send with content and namelist, not allowed
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <onentry>"
+ " <send target=\"#_external\" namelist=\"var1\">"
+ " <content>Foo!</content>"
+ " </send>"
+ " </onentry>"
+ " </state>"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
+ {
+ // send with content and params, not allowed
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <onentry>"
+ " <send target=\"#_external\">"
+ " <param name=\"foo\" expr=\"3\" />"
+ " <content>Foo!</content>"
+ " </send>"
+ " </onentry>"
+ " </state>"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
+ {
+ // send with params and namelist, perfectly acceptable
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <onentry>"
+ " <send target=\"#_external\" namelist=\"foo\">"
+ " <param name=\"foo\" expr=\"3\" />"
+ " </send>"
+ " </onentry>"
+ " </state>"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.size() == 0);
+ }
+
+ {
+ // invoke with content and src, not allowed
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <invoke type=\"scxml\" src=\"var1\">"
+ " <content>Foo!</content>"
+ " </invoke>"
+ " </state>"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
+ {
+ // invoke with namelist and param, not allowed
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <invoke type=\"scxml\" namelist=\"var1\">"
+ " <param name=\"foo\" expr=\"3\" />"
+ " </invoke>"
+ " </state>"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
+ }
+
+ {
+ // invoke with param and content, perfectly acceptable
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <invoke type=\"scxml\">"
+ " <param name=\"foo\" expr=\"3\" />"
+ " <content>Foo!</content>"
+ " </invoke>"
+ " </state>"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.size() == 0);
+ }
+
+ {
+ // invoke with namelist and content, perfectly acceptable
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <invoke type=\"scxml\" namelist=\"var1\">"
+ " <content>Foo!</content>"
+ " </invoke>"
+ " </state>"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.size() == 0);
+ }
+
+ {
+ // donedata with content and param, not allowed
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <donedata>"
+ " <param name=\"foo\" expr=\"3\" />"
+ " <content>Foo!</content>"
+ " </donedata>"
+ " </state>"
+ "</scxml>";
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]/donedata[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
}
+
+
}
-
-
+
+
if (1) {
// Transition can never be optimally enabled (conditionless, eventless)
@@ -405,6 +547,91 @@ int main(int argc, char** argv) {
assert(issueLocations.size() == 1);
}
+ if (1) {
+ // Initial with multiple transitions
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <initial>"
+ " <transition target=\"foo\" />"
+ " <transition target=\"foo\" />"
+ " </initial>"
+ " <state id=\"foo\" />"
+ " <transition event=\"e.bar\" target=\"done\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
+ if (1) {
+ // Initial with no transitions
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <initial />"
+ " <state id=\"foo\" />"
+ " <transition event=\"e.bar\" target=\"done\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
+ if (1) {
+ // History transition with event
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\" initial=\"bar\">"
+ " <history id=\"bar\">"
+ " <transition event=\"e.foo\" target=\"foo\" />"
+ " </history>"
+ " <state id=\"foo\">"
+ " <state id=\"foo.s1\">"
+ " <transition target=\"foo.s2\" />"
+ " </state>"
+ " <state id=\"foo.s2\" />"
+ " </state>"
+ " <transition event=\"e.bar\" target=\"done\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
+ if (1) {
+ // History transition with condition
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\" initial=\"bar\">"
+ " <history id=\"bar\">"
+ " <transition cond=\"false\" target=\"foo\" />"
+ " </history>"
+ " <state id=\"foo\">"
+ " <state id=\"foo.s1\">"
+ " <transition target=\"foo.s2\" />"
+ " </state>"
+ " <state id=\"foo.s2\" />"
+ " </state>"
+ " <transition event=\"e.bar\" target=\"done\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
if (1) {
// Send to unknown IO Processor
@@ -502,8 +729,10 @@ int main(int argc, char** argv) {
" <assign location=\"foo\" expr=\"%2345\" />"
" <send>"
" <param expr=\"%2345\" />"
- " <content expr=\"%2345\" />"
" </send>"
+ " <send>"
+ " <content expr=\"%2345\" />"
+ " </send>"
" </onentry>"
" </state>"
"</scxml>";
@@ -512,8 +741,8 @@ int main(int argc, char** argv) {
assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/log[1]") != issueLocations.end());
assert(issueLocations.find("//data[@id=\"foo\"]") != issueLocations.end());
assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/assign[1]") != issueLocations.end());
- assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]/content[1]") != issueLocations.end());
assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]/param[1]") != issueLocations.end());
+ assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[2]/content[1]") != issueLocations.end());
assert(issueLocations.size() == 5);
}
diff --git a/test/src/test-lifecycle.cpp b/test/src/test-lifecycle.cpp
index 3d675df..84ffbb5 100644
--- a/test/src/test-lifecycle.cpp
+++ b/test/src/test-lifecycle.cpp
@@ -45,7 +45,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/test/src/test-stress.cpp b/test/src/test-stress.cpp
index d0b4a5c..220399a 100644
--- a/test/src/test-stress.cpp
+++ b/test/src/test-stress.cpp
@@ -8,6 +8,13 @@
#include "uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.h"
#include <boost/algorithm/string.hpp>
+#ifdef _WIN32
+#include "XGetopt.h"
+#endif
+
+int startedAt;
+int lastTransitionAt;
+
#ifdef HAS_SIGNAL_H
#include <signal.h>
#endif
@@ -20,13 +27,6 @@
#include <dlfcn.h>
#endif
-#ifdef _WIN32
-#include "XGetopt.h"
-#endif
-
-int startedAt;
-int lastTransitionAt;
-
#ifdef HAS_EXECINFO_H
void printBacktrace(void** array, int size) {
char** messages = backtrace_symbols(array, size);
@@ -47,7 +47,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();
@@ -67,11 +67,11 @@ void customTerminate() {
try {
// try once to re-throw currently active exception
if (!tried_throw) {
- throw;
tried_throw = true;
+ throw;
} else {
tried_throw = false;
- };
+ }
} catch (const std::exception &e) {
std::cerr << __FUNCTION__ << " caught unhandled exception. what(): "
<< e.what() << std::endl;
diff --git a/test/src/test-w3c.cpp b/test/src/test-w3c.cpp
index c7f136d..1480ecb 100644
--- a/test/src/test-w3c.cpp
+++ b/test/src/test-w3c.cpp
@@ -23,10 +23,11 @@ static double delayFactor = 1;
static std::string documentURI;
int retCode = EXIT_FAILURE;
+uscxml::Interpreter interpreter;
class W3CStatusMonitor : public uscxml::StateTransitionMonitor {
-void beforeCompletion(uscxml::Interpreter interpreter) {
+void beforeCompletion(uscxml::Interpreter tmp) {
if (interpreter.getConfiguration().size() == 1 && interpreter.isInState("pass")) {
std::cout << "TEST SUCCEEDED" << std::endl;
retCode = EXIT_SUCCESS;
@@ -75,7 +76,6 @@ int main(int argc, char** argv) {
documentURI = argv[optind];
- Interpreter interpreter;
LOG(INFO) << "Processing " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor));
if (withFlattening) {
interpreter = Interpreter::fromURL(documentURI);
diff --git a/test/uscxml/history-stacks/history-compounds.scxml b/test/uscxml/history-stacks/history-compounds.scxml
new file mode 100644
index 0000000..0fbca92
--- /dev/null
+++ b/test/uscxml/history-stacks/history-compounds.scxml
@@ -0,0 +1,53 @@
+<scxml datamodel="ecmascript">
+ <datamodel>
+ <data id="stack">[]</data>
+ </datamodel>
+
+ <initial>
+ <transition target="main">
+ <send event="to.item1" />
+ <send event="to.item2" />
+ <send event="to.item1" />
+ <send event="back" />
+ <send event="back" />
+ <send event="back" />
+ </transition>
+ </initial>
+
+ <parallel id="main">
+ <state id="controller">
+ <transition event="to.item1"
+ target="item1.history">
+ <script>stack.push("item1");</script>
+ </transition>
+ <transition event="to.item2"
+ target="item2.history">
+ <script>stack.push("item2");</script>
+ </transition>
+
+ <transition event="back"
+ cond="stack[stack.length-1] === 'item1'"
+ target="item1">
+ <script>stack.pop();</script>
+ </transition>
+ <transition event="back"
+ cond="stack[stack.length-1] === 'item2'"
+ target="item2">
+ <script>stack.pop();</script>
+ </transition>
+ </state>
+
+ <state id="items">
+ <state id="item1">
+ <history type="deep"
+ id="item1.history" />
+ <!-- interaction would be established here -->
+ </state>
+ <state id="item2">
+ <history type="deep"
+ id="item2.history" />
+ <!-- interaction would be established here -->
+ </state>
+ </state>
+ </parallel>
+</scxml> \ No newline at end of file
diff --git a/test/uscxml/history-stacks/history-invokers.item.scxml b/test/uscxml/history-stacks/history-invokers.item.scxml
new file mode 100644
index 0000000..30f1a02
--- /dev/null
+++ b/test/uscxml/history-stacks/history-invokers.item.scxml
@@ -0,0 +1,30 @@
+<scxml datamodel="ecmascript">
+ <datamodel>
+ <data id="item" />
+ <data id="childItem" />
+ </datamodel>
+
+ <state>
+
+ <state id="show">
+ <!-- interaction would be established here -->
+ <transition event="to.item1" target="down">
+ <assign location="childItem" expr="1" />
+ </transition>
+ <transition event="to.item2" target="down">
+ <assign location="childItem" expr="2" />
+ </transition>
+ <transition event="back" target="done" />
+ </state>
+
+ <state id="down">
+ <invoke src="history-invokers.item.scxml"
+ autoforward="true">
+ <param name="item" expr="childItem" />
+ </invoke>
+ </state>
+ <transition event="done.invoke" target="show" />
+ </state>
+
+ <final id="done" />
+</scxml> \ No newline at end of file
diff --git a/test/uscxml/history-stacks/history-invokers.main.scxml b/test/uscxml/history-stacks/history-invokers.main.scxml
new file mode 100644
index 0000000..eec3e79
--- /dev/null
+++ b/test/uscxml/history-stacks/history-invokers.main.scxml
@@ -0,0 +1,24 @@
+<scxml datamodel="ecmascript">
+ <initial>
+ <transition target="main">
+ <send event="to.item1" />
+ <send event="to.item2" />
+ <send event="to.item1" />
+ <send event="back" delay="200ms"/>
+ <send event="back" delay="300ms"/>
+ <send event="back" delay="400ms"/>
+ <!-- terminate 'main' as well -->
+ <send event="back" delay="500ms"/>
+ </transition>
+ </initial>
+
+ <state id="main">
+ <invoke src="history-invokers.item.scxml"
+ autoforward="true">
+ <param name="item" expr="'main'" />
+ </invoke>
+ <transition event="done.invoke"
+ target="done" />
+ </state>
+ <final id="done" />
+</scxml> \ No newline at end of file
diff --git a/test/uscxml/test-invoke-communication-invoker.scxml b/test/uscxml/test-invoke-communication-invoker.scxml
new file mode 100644
index 0000000..98d089d
--- /dev/null
+++ b/test/uscxml/test-invoke-communication-invoker.scxml
@@ -0,0 +1,118 @@
+<scxml>
+ <!-- invoke and communicate on entry - will fail -->
+ <state id="send.onentry">
+ <invoke type="scxml" id="send.onentry.invoker">
+ <content>
+ <scxml>
+ <state>
+ <transition event="finish" target="done" />
+ </state>
+ <final id="done"/>
+ </scxml>
+ </content>
+ </invoke>
+
+ <onentry>
+ <!-- This will fail as invoker is not yet instantiated -->
+ <send target="#_send.onentry.invoker" event="finish"/>
+ </onentry>
+
+ <transition event="done.invoke.send.onentry.invoker" target="send.onentry.pass" />
+ <transition event="error.communication" target="send.onentry.fail" />
+ </state>
+
+ <state id="send.onentry.pass">
+ <transition target="external.event" />
+ </state>
+ <state id="send.onentry.fail">
+ <transition target="external.event" />
+ </state>
+
+
+ <!-- Invoke and send an event to the external queue which will trigger communication -->
+ <state id="external.event">
+ <invoke type="scxml" id="external.event.invoker">
+ <content>
+ <scxml>
+ <state>
+ <transition event="finish" target="done" />
+ </state>
+ <final id="done"/>
+ </scxml>
+ </content>
+ </invoke>
+
+ <onentry>
+ <send event="send.to.invoker"/>
+ </onentry>
+ <transition type="internal" event="send.to.invoker">
+ <!-- This will succeed as invoker was instantiated -->
+ <send target="#_external.event.invoker" event="finish"/>
+ </transition>
+
+ <transition event="done.invoke.external.event.invoker" target="external.event.pass" />
+ <transition event="error.communication" target="external.event.fail" />
+
+ </state>
+
+ <state id="external.event.pass">
+ <transition target="delayed.event" />
+ </state>
+ <state id="external.event.fail">
+ <transition target="delayed.event" />
+ </state>
+
+ <!-- invoke and communicate delayed on entry - will succeed -->
+ <state id="delayed.event">
+ <invoke type="scxml" id="delayed.event.invoker">
+ <content>
+ <scxml>
+ <state>
+ <transition event="finish" target="done" />
+ </state>
+ <final id="done"/>
+ </scxml>
+ </content>
+ </invoke>
+
+ <onentry>
+ <!-- This will succeed as the invoker will be instantiated in 1ms (invoking is synchronous) -->
+ <send target="#_delayed.event.invoker" event="finish" delay="1ms"/>
+ </onentry>
+
+ <transition event="done.invoke.delayed.event.invoker" target="delayed.event.pass" />
+ <transition event="error.communication" target="delayed.event.fail" />
+ </state>
+
+ <state id="delayed.event.pass">
+ <transition target="callback.event" />
+ </state>
+ <state id="delayed.event.fail">
+ <transition target="callback.event" />
+ </state>
+
+ <!-- invoke with callback event (out of spec, but so useful!) -->
+ <state id="callback.event">
+ <invoke type="scxml" id="callback.event.invoker" callback="init">
+ <content>
+ <scxml>
+ <state>
+ <transition event="finish" target="done" />
+ </state>
+ <final id="done"/>
+ </scxml>
+ </content>
+ </invoke>
+
+ <transition event="init.callback.event.invoker">
+ <send target="#_callback.event.invoker" event="finish" />
+ </transition>
+
+ <transition event="done.invoke.callback.event.invoker" target="callback.event.pass" />
+ <transition event="error.communication" target="callback.event.fail" />
+ </state>
+
+ <final id="callback.event.pass" />
+ <final id="callback.event.fail" />
+
+</scxml> \ No newline at end of file
diff --git a/test/uscxml/test-invoke-communication.scxml b/test/uscxml/test-invoke-communication.scxml
new file mode 100644
index 0000000..8d277ef
--- /dev/null
+++ b/test/uscxml/test-invoke-communication.scxml
@@ -0,0 +1,104 @@
+<scxml>
+ <!-- invoke and communicate on entry - will fail -->
+ <state id="send.onentry">
+ <invoke type="scxml"
+ id="send.onentry.invoker"
+ src="test-invoke-communication-invoker.scxml" />
+
+ <onentry>
+ <!-- This will fail as invoker is not yet instantiated -->
+ <send target="#_send.onentry.invoker"
+ event="finish"/>
+ </onentry>
+
+ <transition event="done.invoke.send.onentry.invoker"
+ target="send.onentry.pass" />
+ <transition event="error.communication"
+ target="send.onentry.fail" />
+ </state>
+
+ <state id="send.onentry.pass">
+ <transition target="external.event" />
+ </state>
+ <state id="send.onentry.fail">
+ <transition target="external.event" />
+ </state>
+
+
+ <!-- Invoke and send an event to the external queue which will trigger communication -->
+ <state id="external.event">
+ <invoke type="scxml"
+ id="external.event.invoker"
+ src="test-invoke-communication-invoker.scxml" />
+
+ <onentry>
+ <send event="send.to.invoker"/>
+ </onentry>
+ <transition type="internal"
+ event="send.to.invoker">
+ <!-- This will succeed as invoker was instantiated -->
+ <send target="#_external.event.invoker"
+ event="finish"/>
+ </transition>
+
+ <transition event="done.invoke.external.event.invoker"
+ target="external.event.pass" />
+ <transition event="error.communication"
+ target="external.event.fail" />
+ </state>
+
+ <state id="external.event.pass">
+ <transition target="delayed.event" />
+ </state>
+ <state id="external.event.fail">
+ <transition target="delayed.event" />
+ </state>
+
+ <!-- invoke and communicate delayed on entry - will succeed -->
+ <state id="delayed.event">
+ <invoke type="scxml"
+ id="delayed.event.invoker"
+ src="test-invoke-communication-invoker.scxml" />
+
+ <onentry>
+ <!-- This will succeed as the invoker will be instantiated in 1ms (invoking is synchronous) -->
+ <send target="#_delayed.event.invoker"
+ event="finish"
+ delay="1ms"/>
+ </onentry>
+
+ <transition event="done.invoke.delayed.event.invoker"
+ target="delayed.event.pass" />
+ <transition event="error.communication"
+ target="delayed.event.fail" />
+ </state>
+
+ <state id="delayed.event.pass">
+ <transition target="callback.event" />
+ </state>
+ <state id="delayed.event.fail">
+ <transition target="callback.event" />
+ </state>
+
+ <!-- invoke with callback event (out of spec, but so useful!) -->
+ <state id="callback.event">
+ <invoke type="scxml"
+ id="callback.event.invoker"
+ callback="init"
+ src="test-invoke-communication-invoker.scxml" />
+
+ <transition event="init.callback.event.invoker">
+ <send target="#_callback.event.invoker"
+ event="finish" />
+ </transition>
+
+ <transition event="done.invoke.callback.event.invoker"
+ target="callback.event.pass" />
+ <transition event="error.communication"
+ target="callback.event.fail" />
+ </state>
+
+ <final id="callback.event.pass" />
+ <final id="callback.event.fail" />
+
+</scxml> \ No newline at end of file
diff --git a/test/uscxml/transition-selection/test1.scxml b/test/uscxml/transition-selection/test1.scxml
new file mode 100644
index 0000000..d6f43cd
--- /dev/null
+++ b/test/uscxml/transition-selection/test1.scxml
@@ -0,0 +1,12 @@
+<scxml>
+ <parallel id="p1">
+ <state id="s1">
+ <transition target="pass" />
+ </state>
+ <state id="s2">
+ <transition target="fail" />
+ </state>
+ </parallel>
+ <final id="pass" />
+ <final id="fail" />
+</scxml> \ No newline at end of file
diff --git a/test/uscxml/transition-selection/test2.scxml b/test/uscxml/transition-selection/test2.scxml
new file mode 100644
index 0000000..4b703f8
--- /dev/null
+++ b/test/uscxml/transition-selection/test2.scxml
@@ -0,0 +1,20 @@
+<scxml>
+ <parallel id="p1">
+ <transition target="fail" />
+ <state id="s1" />
+ <state id="s2">
+ <state id="s2.s1">
+ <transition target="pass" />
+ </state>
+ </state>
+ <state id="s3">
+ <state id="s3.s1">
+ <state id="s3.s1.s1">
+ <transition target="fail" />
+ </state>
+ </state>
+ </state>
+ </parallel>
+ <final id="pass" />
+ <final id="fail" />
+</scxml> \ No newline at end of file
diff --git a/test/w3c/check-tests.pl b/test/w3c/check-tests.pl
new file mode 100755
index 0000000..7299947
--- /dev/null
+++ b/test/w3c/check-tests.pl
@@ -0,0 +1,92 @@
+#!/usr/bin/perl
+
+use strict;
+use Data::Dumper;
+use XML::Simple;
+
+
+my $manifest = XMLin("./manifest.xml");
+# print Dumper($manifest->{'assert'});
+
+my $perSpecId;
+
+my @allTests;
+my @ecmaTests;
+my @xpathTests;
+my @agnosticTests;
+my @nullTests;
+my @manualTests;
+
+for my $testNr (keys $manifest->{'assert'}) {
+ my @tests;
+ my $thisTest = $manifest->{'assert'}->{$testNr};
+ if (ref($thisTest->{'test'}->{'start'}) eq "ARRAY") {
+ push (@tests, @{$thisTest->{'test'}->{'start'}});
+ } else {
+ push (@tests, $thisTest->{'test'}->{'start'});
+ }
+ $perSpecId->{$thisTest->{'specnum'}.':'.$thisTest->{'specid'}}->{'total'} += @tests;
+ if ($thisTest->{'test'}->{'manual'} eq "true") {
+ $perSpecId->{$thisTest->{'specnum'}.':'.$thisTest->{'specid'}}->{'manual'} += @tests;
+ push @manualTests, @tests;
+
+ }
+
+ if ($thisTest->{'specid'} eq "#minimal-profile" || $thisTest->{'specid'} !~ /profile$/) {
+ push @nullTests, @tests;
+ }
+
+ if ($thisTest->{'specid'} eq "#ecma-profile" || $thisTest->{'specid'} !~ /profile$/) {
+ push @ecmaTests, @tests;
+ }
+
+ if ($thisTest->{'specid'} eq "#xpath-profile" || $thisTest->{'specid'} !~ /profile$/) {
+ push @xpathTests, @tests;
+ }
+
+ push (@allTests, @tests);
+ push @agnosticTests, @tests if ($thisTest->{'specid'} !~ /profile$/);
+}
+
+# print Dumper(@ecmaTests);
+
+my %datamodels = (
+ "ecma" => \@ecmaTests,
+ "xpath" => \@xpathTests,
+ "promela" => \@agnosticTests,
+ "prolog" => \@agnosticTests,
+ "lua" => \@ecmaTests
+);
+
+for my $datamodel (keys %datamodels) {
+ # every scxml file is a test
+ for (`ls $datamodel/*.scxml`) {
+ my $filename = $_;
+ chomp($filename);
+ if ($filename =~ /\/test(\d+\w?)\.scxml/) {
+ print("${filename} is not in mainfest\n") if (! grep $_->{'uri'} == "${1}/test${1}.scxml", @{$datamodels{$datamodel}});
+ }
+ }
+ # every test is given
+ for my $testURI (@{$datamodels{$datamodel}}) {
+ if ($testURI->{'uri'} =~ /^(\d+)\/(test\d+\w?)\.(txt|txml)$/) {
+ my $name = $2;
+ my $suffix = ($3 eq "txml" ? "scxml" : $3);
+ if (! -e "${datamodel}/${name}.${suffix}") {
+ print("${datamodel}/${name}.${suffix} is missing\n");
+ }
+ } else {
+ die ($testURI->{'uri'});
+ }
+ }
+}
+
+# print Dumper(@manualTests);
+
+print "NULL : ".@nullTests."\n";
+print "ECMA : ".@ecmaTests."\n";
+print "XPATH: ".@xpathTests."\n";
+print "\n";
+print "MAN : ".@manualTests."\n";
+print "ANY : ".@agnosticTests."\n";
+print "TOTAL: ".@allTests."\n";
diff --git a/test/w3c/convert-tests.sh b/test/w3c/convert-tests.sh
index e784a44..0e43b48 100755
--- a/test/w3c/convert-tests.sh
+++ b/test/w3c/convert-tests.sh
@@ -50,6 +50,13 @@ find ./prolog -type f -exec grep -Ili 'datamodel="xpath"' {} \; |xargs rm -fv
find ./prolog -type f -exec grep -Ili 'datamodel="ecmascript"' {} \; |xargs rm -fv
find ./prolog -type f -exec grep -Ili 'datamodel="null"' {} \; |xargs rm -fv
+# test436 is the null datamodel
+mv ./ecma/test436.scxml ./null
+rm ./xpath/test436.scxml
+rm ./promela/test436.scxml
+rm ./prolog/test436.scxml
+rm ./lua/test436.scxml
+
# format all SCXML files
SCXMLS=`find . -type f -name '*.scxml'`
for SCXML in $SCXMLS
diff --git a/test/w3c/ecma/test436.scxml b/test/w3c/ecma/test436.scxml
deleted file mode 100644
index 072370e..0000000
--- a/test/w3c/ecma/test436.scxml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- test that in() predicate works in null data model -->
-<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="null" version="1.0" initial="p">
- <parallel id="p">
- <state id="ps0">
- <transition cond="In('s1')" target="fail"/>
- <transition cond="In('ps1')" target="pass"/>
- <transition target="fail"/>
- </state>
- <state id="ps1"/>
- </parallel>
- <state id="s1"/>
- <final id="pass">
- <onentry>
- <log label="Outcome" expr="'pass'"/>
- </onentry>
- </final>
- <final id="fail">
- <onentry>
- <log label="Outcome" expr="'fail'"/>
- </onentry>
- </final>
-</scxml>
diff --git a/test/w3c/xpath/test278.scxml b/test/w3c/lua/test288.scxml
index 09ad31b..5f44351 100644
--- a/test/w3c/xpath/test278.scxml
+++ b/test/w3c/lua/test288.scxml
@@ -1,15 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
-<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="xpath">
- <!-- test that a variable can be accessed from a state that is outside its lexical scope -->
+<!-- a simple test that a legal value may be assigned to a valid data model location
+using child content -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="lua" version="1.0" initial="s0">
+ <datamodel>
+ <data id="Var1" expr="0"/>
+ </datamodel>
<state id="s0">
- <transition cond="$Var1/text() =1" target="pass"/>
+ <onentry>
+ <assign location="Var1">123</assign>
+ </onentry>
+ <transition cond="Var1 == 123" target="pass"/>
<transition target="fail"/>
</state>
- <state id="s1">
- <datamodel>
- <data id="Var1" expr="1"/>
- </datamodel>
- </state>
<final id="pass">
<onentry>
<log label="Outcome" expr="'pass'"/>
diff --git a/test/w3c/lua/test436.scxml b/test/w3c/lua/test436.scxml
deleted file mode 100644
index da5f5a6..0000000
--- a/test/w3c/lua/test436.scxml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- test that in() predicate works in null data model -->
-<scxml xmlns="http://www.w3.org/2005/07/scxml" datamodel="null" version="1.0" initial="p">
- <parallel id="p">
- <state id="ps0">
- <transition cond="In('s1')" target="fail"/>
- <transition cond="In('ps1')" target="pass"/>
- <transition target="fail"/>
- </state>
- <state id="ps1"/>
- </parallel>
- <state id="s1"/>
- <final id="pass"/>
- <final id="fail"/>
-</scxml>
diff --git a/test/w3c/xpath/test436.scxml b/test/w3c/null/test436.scxml
index 072370e..072370e 100644
--- a/test/w3c/xpath/test436.scxml
+++ b/test/w3c/null/test436.scxml
diff --git a/test/w3c/prolog/test278.scxml b/test/w3c/prolog/test278.scxml
deleted file mode 100644
index 11cae5b..0000000
--- a/test/w3c/prolog/test278.scxml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="prolog">
- <!-- test that a variable can be accessed from a state that is outside its lexical scope -->
- <state id="s0">
- <transition cond="X = 1, var1(X)" target="pass"/>
- <transition target="fail"/>
- </state>
- <state id="s1">
- <datamodel>
- <data id="var1" expr="1"/>
- </datamodel>
- </state>
- <final id="pass">
- <onentry>
- <log label="Outcome" expr="'pass'"/>
- </onentry>
- </final>
- <final id="fail">
- <onentry>
- <log label="Outcome" expr="'fail'"/>
- </onentry>
- </final>
-</scxml>
diff --git a/test/w3c/promela/test278.scxml b/test/w3c/promela/test278.scxml
deleted file mode 100644
index a2d613a..0000000
--- a/test/w3c/promela/test278.scxml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="promela">
- <!-- test that a variable can be accessed from a state that is outside its lexical scope -->
- <state id="s0">
- <transition cond="Var1==1" target="pass"/>
- <transition target="fail"/>
- </state>
- <state id="s1">
- <datamodel>
- <data id="Var1" type="int" expr="1"/>
- </datamodel>
- </state>
- <final xmlns:scxml="http://www.w3.org/2005/07/scxml" id="pass">
- <onentry>
- <log label="Outcome" expr="'pass'"/>
- </onentry>
- </final>
- <final xmlns:scxml="http://www.w3.org/2005/07/scxml" id="fail">
- <onentry>
- <log label="Outcome" expr="'fail'"/>
- </onentry>
- </final>
-</scxml>
diff --git a/test/w3c/run_manual_tests.sh b/test/w3c/run_manual_tests.sh
new file mode 100755
index 0000000..8744423
--- /dev/null
+++ b/test/w3c/run_manual_tests.sh
@@ -0,0 +1,127 @@
+#!/bin/bash
+
+USCXML_BIN=$1;
+DATA_MODEL=$2;
+
+echo
+echo
+echo "---- test178.scxml: --------"
+echo "we test that multiple key/value pairs are included, even when the keys are the"
+echo "same. This is a manual test. The tester must look at the log output and verify"
+echo "that both keys are there. (This test uses the SCXML Event I/O processor, which"
+echo "is the only one that all platforms must support. It does not specify the"
+echo "message format, so we cannot test _event.raw directly. Therefore we print it"
+echo "out for visual inspection"
+echo
+
+$USCXML_BIN -v ${DATA_MODEL}/test178.scxml
+
+
+echo
+echo
+echo "---- test230.scxml: --------"
+echo "a manual test that an autofowarded event has the same fields and values as the"
+echo "original event. the child process sends the parent process an event which is"
+echo "forwarded back to it. Both the parent and child process print out the contents"
+echo "of the event. The tester must check if they are the same and report his result."
+echo
+
+$USCXML_BIN -v ${DATA_MODEL}/test230.scxml
+
+
+echo
+echo
+echo "---- test250.scxml: --------"
+echo "test that the onexit handlers run in the invoked process if it is cancelled."
+echo "This has to be a manual test, since this process won't accept any events from"
+echo "the child process once it has been cancelled. Tester must examine log output"
+echo "from child process to determine success"
+echo
+
+$USCXML_BIN -v ${DATA_MODEL}/test250.scxml
+
+
+echo
+echo
+echo "---- test301.scxml: --------"
+echo "the processor should reject this document because it can't download the script."
+echo "Therefore we fail if it runs at all. This test is valid only for datamodels"
+echo "that support scripting"
+echo
+
+$USCXML_BIN -v ${DATA_MODEL}/test301.scxml
+
+
+echo
+echo
+echo "---- test307.scxml: --------"
+echo "with binding=late, in s0 we access a variable that isn't created until we get"
+echo "to s1. Then in s1 we access a non-existent substructure of a variable. We use"
+echo "log tags to report the values that both operations yield, and whether there are"
+echo "errors. This is a manual test, since the tester must report whether the output"
+echo "is the same in the two cases"
+echo
+
+$USCXML_BIN -v ${DATA_MODEL}/test307.scxml
+
+
+echo
+echo
+echo "---- test313.scxml: --------"
+echo "this is a manual test. The processor is allowed to reject this doc, but if it"
+echo "executes it with its illegal expression, it must raise an error"
+echo
+
+$USCXML_BIN -v ${DATA_MODEL}/test313.scxml
+
+
+echo
+echo
+echo "---- test314.scxml: --------"
+echo "this is a manual test because the processor is allowed to reject this document."
+echo "But if it executes it, it should not raise an error until it gets to s03 and"
+echo "evaluates the illegal expr"
+echo
+
+$USCXML_BIN -v ${DATA_MODEL}/test314.scxml
+
+
+echo
+echo
+echo "---- test415.scxml: --------"
+
+echo "Test that the state machine halts when it enters a top-level final state. Since"
+echo "the initial state is a final state, this machine should halt immediately"
+echo "without processing \"event1\" which is raised in the final state's on-entry"
+echo "handler. This is a manual test since there is no platform-independent way to"
+echo "test that event1 is not processed"
+echo
+
+$USCXML_BIN -v ${DATA_MODEL}/test415.scxml
+
+
+echo
+echo
+echo "---- test513.scxml: --------"
+
+echo "This is a fully manual test. You send a well formed event to the 'location' URL"
+echo "specified for your SCXML interpreter and check that you get a 200 response code"
+echo "back. One way of doing this, using wget, is shown below (you can use any event"
+echo "name you want, but you must use '_scxmleventname' to indicate the name of the"
+echo "event)"
+echo
+
+cat << 'END_TEST513' > /tmp/test513.scxml
+<scxml name="test513">
+ <state id="idle">
+ <transition event="quit" target="done" />
+ </state>
+ <final id="done" />
+</scxml>
+END_TEST513
+
+${USCXML_BIN} -v -t35001 /tmp/test513.scxml &
+sleep 1
+
+wget --post-data='key1=value1&key2=value2' --header '_scxmleventname: quit' localhost:35001/test513/basichttp
+rm basichttp*
diff --git a/test/w3c/schema/scxml-attribs.xsd b/test/w3c/schema/scxml-attribs.xsd
new file mode 100644
index 0000000..2459592
--- /dev/null
+++ b/test/w3c/schema/scxml-attribs.xsd
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema common attributes for SCXML
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This import brings in the XML namespace attributes
+ The module itself does not provide the schemaLocation
+ and expects the driver schema to provide the
+ actual SchemaLocation.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This include brings in the SCXML datatypes.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:attributeGroup name="Fetchtimeout.attrib">
+ <xsd:annotation>
+ <xsd:documentation>Used in Cache.attribs</xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="fetchtimeout" type="Duration.datatype"/>
+ </xsd:attributeGroup>
+ <xsd:attributeGroup name="Maxage.attrib">
+ <xsd:annotation>
+ <xsd:documentation>Used in Cache.attribs</xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="maxage" type="Integer.datatype"/>
+ </xsd:attributeGroup>
+ <xsd:attributeGroup name="Maxstale.attrib">
+ <xsd:annotation>
+ <xsd:documentation>Used in Cache attribs</xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="maxstale" type="Integer.datatype"/>
+ </xsd:attributeGroup>
+
+ <xsd:attributeGroup name="Cache.attribs">
+ <xsd:annotation>
+ <xsd:documentation>Cache attributes to control caching behavior</xsd:documentation>
+ </xsd:annotation>
+ <xsd:attributeGroup ref="Fetchtimeout.attrib"/>
+ <xsd:attributeGroup ref="Maxage.attrib"/>
+ <xsd:attributeGroup ref="Maxstale.attrib"/>
+ </xsd:attributeGroup>
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-contentmodels.xsd b/test/w3c/schema/scxml-contentmodels.xsd
new file mode 100644
index 0000000..2850c3a
--- /dev/null
+++ b/test/w3c/schema/scxml-contentmodels.xsd
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ XML Schema content models for SCXML
+ * scxml.extra.content
+ * content
+ * scxml.extra.attribs
+ Defines SCXML shared content models.
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+
+ <xsd:attributeGroup name="scxml.extra.attribs">
+ <xsd:annotation>
+ <xsd:documentation>group allowing attributes from other namespaces</xsd:documentation>
+ </xsd:annotation>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:attributeGroup>
+
+ <xsd:group name="scxml.extra.content">
+ <xsd:annotation>
+ <xsd:documentation>
+ group allowing elements from other namespaces
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-copyright.xsd b/test/w3c/schema/scxml-copyright.xsd
new file mode 100644
index 0000000..e322051
--- /dev/null
+++ b/test/w3c/schema/scxml-copyright.xsd
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema for SCXML 1.0, formulated as a modular XML application
+ Copyright &#169;1998-2007 World Wide Web Consortium
+ (Massachusetts Institute of Technology, European Research Consortium
+ for Informatics and Mathematics, Keio University).
+ All Rights Reserved.
+
+ Permission to use, copy, modify and distribute the SCXML Schema
+ modules and their accompanying xs:documentation for any purpose
+ and without fee is hereby granted in perpetuity, provided that the above
+ copyright notice and this paragraph appear in all copies.
+ The copyright holders make no representation about the suitability of
+ these XML Schema modules for any purpose.
+
+ They are provided "as is" without expressed or implied warranty.
+ </xsd:documentation>
+ </xsd:annotation>
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-core-strict.xsd b/test/w3c/schema/scxml-core-strict.xsd
new file mode 100644
index 0000000..b54cf8e
--- /dev/null
+++ b/test/w3c/schema/scxml-core-strict.xsd
@@ -0,0 +1,425 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema core module for SCXML
+ * scxml
+ * state
+ * initial
+ * onexit
+ * onentry
+ * transition
+ * parallel
+ * final
+ * history
+ * donedata
+ * if
+ * elsif
+ * else
+ * foreach
+ * raise
+ * log
+ The core module defines these elements and the
+ attributes.
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ Includes common SCXML datatypes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ Includes common SCXML attributes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common content model extensions for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+
+ <!-- scxml -->
+ <xsd:attributeGroup name="scxml.scxml.attlist">
+ <xsd:attribute name="initial" type="xsd:IDREFS"/>
+ <xsd:attribute name="name" type="xsd:NMTOKEN"/>
+ <xsd:attribute name="version" type="xsd:decimal" use="required" fixed="1.0"/>
+ <xsd:attribute name="datamodel" type="xsd:NMTOKEN" default="null" use="optional"/>
+ <xsd:attribute name="binding" type="Binding.datatype"/>
+ <xsd:attribute name="exmode" type="Exmode.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.scxml.mix">
+ <xsd:choice>
+ <xsd:element ref="state" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="parallel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="final" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="script" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.scxml.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.scxml.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.scxml.type">
+ <xsd:group ref="scxml.scxml.content"/>
+ <xsd:attributeGroup ref="scxml.scxml.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="scxml" type="scxml.scxml.type"/>
+
+ <!-- state -->
+ <xsd:attributeGroup name="scxml.state.attlist">
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="initial" type="xsd:IDREFS"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.state.mix">
+ <xsd:choice>
+ <xsd:element ref="onentry" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="onexit" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="transition" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="initial" minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="state" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="parallel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="final" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="history" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="invoke" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.state.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.state.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.state.type">
+ <xsd:sequence>
+ <xsd:group ref="scxml.state.content"/>
+ </xsd:sequence>
+ <xsd:attributeGroup ref="scxml.state.attlist"/>
+ <xsd:assert test="not(@initial and initial)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test="if(@initial or initial) then (state | parallel) else true()" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test="every $init in @initial satisfies (some $state in (.//state | .//parallel) satisfies ($state/@id = $init))" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test="if (initial) then (every $targ in initial/transition/@target satisfies (some $state in (.//state | .//parallel) satisfies ($state/@id = $targ))) else true()" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test="if(history/@type='shallow') then (every $targ in history/transition/@target satisfies
+ (some $state in (state |parallel) satisfies ($state/@id = $targ)))
+ else if (history/@type='deep') then (every $targ in history/transition/@target satisfies
+ (some $state in (.//state | .//parallel) satisfies ($state/@id = $targ)))
+ else true()" xpathDefaultNamespace="##targetNamespace"/>
+ </xsd:complexType>
+ <xsd:element name="state" type="scxml.state.type"/>
+
+ <!-- initial -->
+ <xsd:attributeGroup name="scxml.initial.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.initial.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="transition" minOccurs="1" maxOccurs="1"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.initial.type">
+ <xsd:group ref="scxml.initial.content"/>
+ <xsd:attributeGroup ref="scxml.initial.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="initial" type="scxml.initial.type"/>
+
+ <!-- onentry -->
+ <xsd:attributeGroup name="scxml.onentry.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.onentry.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.onentry.type">
+ <xsd:group ref="scxml.onentry.content"/>
+ <xsd:attributeGroup ref="scxml.onentry.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="onentry" type="scxml.onentry.type"/>
+
+ <!-- onexit -->
+ <xsd:attributeGroup name="scxml.onexit.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.onexit.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.onexit.type">
+ <xsd:group ref="scxml.onexit.content"/>
+ <xsd:attributeGroup ref="scxml.onexit.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="onexit" type="scxml.onexit.type"/>
+
+ <!-- transition -->
+ <xsd:attributeGroup name="scxml.transition.attlist">
+ <xsd:attribute name="event" type="EventTypes.datatype"/>
+ <xsd:attribute name="cond" type="CondLang.datatype"/>
+ <xsd:attribute name="target" type="xsd:IDREFS"/>
+ <xsd:attribute name="type" type="TransitionType.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.transition.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.transition.type">
+ <xsd:group ref="scxml.transition.content"/>
+ <xsd:attributeGroup ref="scxml.transition.attlist"/>
+ <xsd:assert test="(@event or @cond or @target)" xpathDefaultNamespace="##targetNamespace"/>
+ </xsd:complexType>
+ <xsd:element name="transition" type="scxml.transition.type"/>
+
+ <!-- parallel -->
+ <xsd:attributeGroup name="scxml.parallel.attlist">
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.parallel.mix">
+ <xsd:choice>
+ <xsd:element ref="onentry" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="onexit" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="transition" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="state" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="parallel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="history" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="invoke" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.parallel.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.parallel.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.parallel.type">
+ <xsd:group ref="scxml.parallel.content"/>
+ <xsd:attributeGroup ref="scxml.parallel.attlist"/>
+ <xsd:assert test="if(history/@type='shallow') then (every $targ in history/transition/@target satisfies
+ (some $state in (state |parallel) satisfies ($state/@id = $targ)))
+ else if (history/@type='deep') then (every $targ in history/transition/@target satisfies
+ (some $state in (.//state | .//parallel) satisfies ($state/@id = $targ)))
+ else true()" xpathDefaultNamespace="##targetNamespace"/>
+ </xsd:complexType>
+ <xsd:element name="parallel" type="scxml.parallel.type"/>
+
+ <!-- final -->
+ <xsd:attributeGroup name="scxml.final.attlist">
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.final.mix">
+ <xsd:choice>
+ <xsd:element ref="onentry" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="onexit" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="donedata" minOccurs="0" maxOccurs="1"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.final.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.final.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.final.type">
+ <xsd:group ref="scxml.final.content"/>
+ <xsd:attributeGroup ref="scxml.final.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="final" type="scxml.final.type"/>
+
+ <!-- history -->
+ <xsd:attributeGroup name="scxml.history.attlist">
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="type" type="HistoryType.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.history.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="transition" minOccurs="1" maxOccurs="1"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.history.type">
+ <xsd:group ref="scxml.history.content"/>
+ <xsd:attributeGroup ref="scxml.history.attlist"/>
+ <xsd:assert test="not(transition/@cond or transition/@event)" xpathDefaultNamespace="##targetNamespace"/>
+
+ </xsd:complexType>
+ <xsd:element name="history" type="scxml.history.type"/>
+
+
+
+ <!-- donedata -->
+ <xsd:attributeGroup name="scxml.donedata.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.donedata.content">
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element ref="content" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="param" minOccurs="1" maxOccurs="unbounded"/>
+ </xsd:choice>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.donedata.type">
+ <xsd:group ref="scxml.donedata.content"/>
+ <xsd:attributeGroup ref="scxml.donedata.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="donedata" type="scxml.donedata.type"/>
+
+ <!-- if -->
+ <xsd:attributeGroup name="scxml.if.attlist">
+ <xsd:attribute name="cond" type="CondLang.datatype" use="required"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.if.elseif.mix">
+ <xsd:sequence>
+ <xsd:element ref="elseif" />
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:group name="scxml.if.else.mix">
+ <xsd:sequence>
+ <xsd:element ref="else" />
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:group name="scxml.if.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.if.elseif.mix" minOccurs="0" maxOccurs="1"/>
+ <xsd:group ref="scxml.if.else.mix" minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.if.type">
+ <xsd:group ref="scxml.if.content"/>
+ <xsd:attributeGroup ref="scxml.if.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="if" type="scxml.if.type"/>
+
+ <!-- elseif -->
+ <xsd:attributeGroup name="scxml.elseif.attlist">
+ <xsd:attribute name="cond" type="CondLang.datatype" use="required"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.elseif.mix">
+ <xsd:choice>
+ <!-- No content for this element -->
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.elseif.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.elseif.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.elseif.type">
+ <xsd:group ref="scxml.elseif.content"/>
+ <xsd:attributeGroup ref="scxml.elseif.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="elseif" type="scxml.elseif.type"/>
+
+ <!-- else -->
+ <xsd:attributeGroup name="scxml.else.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.else.mix">
+ <xsd:choice>
+ <!-- No content for this element -->
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.else.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.else.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.else.type">
+ <xsd:group ref="scxml.else.content"/>
+ <xsd:attributeGroup ref="scxml.else.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="else" type="scxml.else.type"/>
+
+ <!-- foreach -->
+ <xsd:attributeGroup name="scxml.foreach.attlist">
+ <xsd:attribute name="array" type="ValueLang.datatype" use="required"/>
+ <xsd:attribute name="item" type="xsd:string" use="required"/>
+ <xsd:attribute name="index" type="xsd:string"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.foreach.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.foreach.type">
+ <xsd:group ref="scxml.foreach.content"/>
+ <xsd:attributeGroup ref="scxml.foreach.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="foreach" type="scxml.foreach.type"/>
+
+ <!-- raise -->
+ <xsd:attributeGroup name="scxml.raise.attlist">
+ <xsd:attribute name="event" type="xsd:NMTOKEN" use="required"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.raise.mix">
+ <xsd:choice>
+ <!-- No content for this element -->
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.raise.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.raise.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.raise.type">
+ <xsd:group ref="scxml.raise.content"/>
+ <xsd:attributeGroup ref="scxml.raise.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="raise" type="scxml.raise.type"/>
+
+ <!-- log -->
+ <xsd:attributeGroup name="scxml.log.attlist">
+ <xsd:attribute name="label" type="xsd:string"/>
+ <xsd:attribute name="expr" type="ValueLang.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.log.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.log.type">
+ <xsd:group ref="scxml.log.content"/>
+ <xsd:attributeGroup ref="scxml.log.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="log" type="scxml.log.type"/>
+
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-data-strict.xsd b/test/w3c/schema/scxml-data-strict.xsd
new file mode 100644
index 0000000..39a834d
--- /dev/null
+++ b/test/w3c/schema/scxml-data-strict.xsd
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema data module for SCXML
+ * datamodel
+ * data
+ * assign
+ * param
+ * script
+ * content
+ The data module defines these elements and their
+ attributes.
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines SCXML Attribute DataTypes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common attributes for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common content model extensions for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <!-- datamodel -->
+ <xsd:attributeGroup name="scxml.datamodel.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.datamodel.content">
+ <xsd:sequence>
+ <xsd:element ref="data" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.datamodel.type">
+ <xsd:group ref="scxml.datamodel.content"/>
+ <xsd:attributeGroup ref="scxml.datamodel.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="datamodel" type="scxml.datamodel.type"/>
+
+ <!-- data -->
+ <xsd:attributeGroup name="scxml.data.attlist">
+ <xsd:attribute name="id" type="xsd:ID" use="required"/>
+ <xsd:attribute name="src" type="URI.datatype"/>
+ <xsd:attribute name="expr" type="ValueLang.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.data.content">
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.data.type" mixed="true">
+ <xsd:group ref="scxml.data.content"/>
+ <xsd:attributeGroup ref="scxml.data.attlist"/>
+ <xsd:assert test="not(@src and @expr)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test="if(@src or @expr) then (not(text() | *)) else true()" xpathDefaultNamespace="##targetNamespace"/>
+ </xsd:complexType>
+ <xsd:element name="data" type="scxml.data.type"/>
+
+
+
+ <!-- param -->
+ <xsd:attributeGroup name="scxml.param.attlist">
+ <xsd:attribute name="name" type="xsd:NMTOKEN" use="required"/>
+ <xsd:attribute name="expr" type="ValueLang.datatype"/>
+ <xsd:attribute name="location" type="LocLang.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.param.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.param.type">
+ <xsd:group ref="scxml.param.content"/>
+ <xsd:attributeGroup ref="scxml.param.attlist"/>
+ <xsd:assert test="(@expr or @location) and not(@expr and @location)" xpathDefaultNamespace="##targetNamespace"/>
+ </xsd:complexType>
+ <xsd:element name="param" type="scxml.param.type"/>
+
+<!-- assign -->
+ <xsd:attributeGroup name="scxml.assign.attlist">
+ <xsd:attribute name="location" type="LocLang.datatype" use="required"/>
+ <xsd:attribute name="expr" type="ValueLang.datatype"/>
+ <xsd:attribute name="type" type="AssignType.datatype" default="replacechildren"/>
+ <xsd:attribute name="attr" type="xsd:NMTOKEN"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.assign.content">
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.assign.type" mixed="true">
+ <xsd:group ref="scxml.assign.content"/>
+ <xsd:attributeGroup ref="scxml.assign.attlist"/>
+ <xsd:assert test="(@expr or text() or *)" xpathDefaultNamespace="##targetNamespace"/>
+<xsd:assert test="not(@expr and (text() | *))" xpathDefaultNamespace="##targetNamespace"/>
+ </xsd:complexType>
+ <xsd:element name="assign" type="scxml.assign.type"/>
+
+
+<!-- script -->
+ <xsd:attributeGroup name="scxml.script.attlist">
+ <xsd:attribute name="src" type="URI.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.script.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.script.type" mixed="true">
+ <xsd:group ref="scxml.script.content"/>
+ <xsd:attributeGroup ref="scxml.script.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="script" type="scxml.script.type"/>
+
+ <!-- content -->
+ <xsd:attributeGroup name="scxml.content.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ <xsd:attribute name="expr" type="ValueLang.datatype"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.content.content">
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.content.type" mixed="true">
+ <xsd:group ref="scxml.content.content"/>
+ <xsd:attributeGroup ref="scxml.content.attlist"/>
+ <xsd:assert test="not(@expr and (text() or *))" xpathDefaultNamespace="##targetNamespace"/>
+ </xsd:complexType>
+ <xsd:element name="content" type="scxml.content.type"/>
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-datatypes.xsd b/test/w3c/schema/scxml-datatypes.xsd
new file mode 100644
index 0000000..7771084
--- /dev/null
+++ b/test/w3c/schema/scxml-datatypes.xsd
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+
+ <xsd:annotation>
+ <xsd:documentation>
+ XML Schema datatypes for SCXML
+
+ Defines containers for the SCXML datatypes, many of these
+ imported from other specifications and standards.
+
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+
+ <xsd:simpleType name="Exmode.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ Describes the processor execution mode for this document, being
+ either "lax" or "strict".
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="lax"/>
+ <xsd:enumeration value="strict"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Binding.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ The binding type in use for the SCXML document.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="early"/>
+ <xsd:enumeration value="late"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+
+ <xsd:simpleType name="HistoryType.datatype">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="shallow"/>
+ <xsd:enumeration value="deep"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="TransitionType.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ The type of the transition i.e. internal or external.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="internal"/>
+ <xsd:enumeration value="external"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Boolean.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ Boolean: true or false only
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKENS">
+ <xsd:enumeration value="true"/>
+ <xsd:enumeration value="false"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="AssignType.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ The assign type that allows for precise manipulation of the
+ datamodel location. Types are:
+ replacechildren (default),
+ firstchild, lastchild,
+ previoussibling, nextsibling,
+ replace, delete,
+ addattribute
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="replacechildren"/>
+ <xsd:enumeration value="firstchild"/>
+ <xsd:enumeration value="lastchild"/>
+ <xsd:enumeration value="previoussibling"/>
+ <xsd:enumeration value="nextsibling"/>
+ <xsd:enumeration value="replace"/>
+ <xsd:enumeration value="delete"/>
+ <xsd:enumeration value="addattribute"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="URI.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ The xsd:anyURI type and thus URI references in SCXML
+ documents may contain a wide array of international
+ characters. Implementers should reference RFC 3987 and
+ the "Character Model for the World Wide Web 1.0:
+ Resource Identifiers" in order to provide appropriate
+ support for these characters in VoiceXML documents and
+ when processing values of this type or mapping them to
+ URIs.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:anyURI"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Integer.datatype">
+ <xsd:annotation>
+ <xsd:documentation>Non-negative integer</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:nonNegativeInteger"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Duration.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ Duration allowing positive values ranging from milliseconds
+ to days.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="\d*(\.\d+)?(ms|s|m|h|d)"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+
+ <xsd:simpleType name="EventType.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ EventType is the name of an event.
+ Example legal values:
+ foo
+ foo.bar
+ foo.bar.baz
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:pattern value="(\i|\d|\-)+(\.(\i|\d|\-)+)*"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="EventTypes.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ Custom datatype for the event attribute in SCXML based on xsd:token.
+ Example legal values:
+ *
+ foo
+ foo.bar
+ foo.*
+ foo.bar.*
+ foo bar baz
+ foo.bar bar.* baz.foo.*
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:pattern value="\.?\*|(\i|\d|\-)+(\.(\i|\d|\-)+)*(\.\*)?(\s(\i|\d|\-)+(\.(\i|\d|\-)+)*(\.\*)?)*"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- Defines the default CondLang datatype. -->
+ <xsd:simpleType name="CondLang.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ Conditional language is expression
+ which must evaluate to Boolean True or False.
+ The expression language must define In(stateID)
+ as a valid expression.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+ <!-- Defines the default LocLang datatype. -->
+ <xsd:simpleType name="LocLang.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ Location language is expression
+ identifying a location in the datamodel.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+ <!-- Defines the default ValueLang datatype. -->
+ <xsd:simpleType name="ValueLang.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ Value language is expression
+ return a value.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-external-strict.xsd b/test/w3c/schema/scxml-external-strict.xsd
new file mode 100644
index 0000000..6219b7b
--- /dev/null
+++ b/test/w3c/schema/scxml-external-strict.xsd
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema external module for SCXML
+ * send
+ * cancel
+ * invoke
+ * finalize
+ The external module defines these elements and their
+ attributes.
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines SCXML Attribute DataTypes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common attributes for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common content model extensions for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+<!-- send -->
+ <xsd:attributeGroup name="scxml.send.attlist">
+ <xsd:attribute name="event" type="EventType.datatype"/>
+ <xsd:attribute name="eventexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="target" type="URI.datatype"/>
+ <xsd:attribute name="targetexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="type" type="xsd:string" default="scxml"/>
+ <xsd:attribute name="typeexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="idlocation" type="LocLang.datatype"/>
+ <xsd:attribute name="delay" type="Duration.datatype" default="0s"/>
+ <xsd:attribute name="delayexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="namelist" type="xsd:string"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.send.mix">
+ <xsd:choice>
+ <xsd:element ref="content" minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.send.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.send.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.send.type">
+ <xsd:group ref="scxml.send.content"/>
+ <xsd:attributeGroup ref="scxml.send.attlist"/>
+ <xsd:assert test="(@event or @eventexpr or content) and not(@expr and @eventexpr)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test="not(@namelist and (param | content))" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test="not(@target and @targetexpr)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test="not(@id and @idlocation)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test="not(@type and @typeexpr)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test="not(@delay and @delayexpr)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test="if(@delay or @delayexpr) then (not(@target eq '_internal')) else true()" xpathDefaultNamespace="##targetNamespace"/>
+ </xsd:complexType>
+ <xsd:element name="send" type="scxml.send.type"/>
+
+ <!-- cancel -->
+ <xsd:attributeGroup name="scxml.cancel.attlist">
+ <xsd:attribute name="sendid" type="xsd:IDREF"/>
+ <xsd:attribute name="sendidexpr" type="ValueLang.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.cancel.mix">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:group name="scxml.cancel.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.cancel.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.cancel.type">
+ <xsd:group ref="scxml.cancel.content"/>
+ <xsd:attributeGroup ref="scxml.cancel.attlist"/>
+ <xsd:assert test="(@sendid or @sendidexpr) and not(@sendid and @sendidexpr)" xpathDefaultNamespace="##targetNamespace"/>
+ </xsd:complexType>
+ <xsd:element name="cancel" type="scxml.cancel.type"/>
+
+
+
+ <!-- invoke -->
+ <xsd:attributeGroup name="scxml.invoke.attlist">
+ <xsd:attribute name="type" type="xsd:string" default="scxml"/>
+ <xsd:attribute name="typeexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="src" type="URI.datatype"/>
+ <xsd:attribute name="srcexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="idlocation" type="LocLang.datatype"/>
+ <xsd:attribute name="namelist" type="xsd:string"/>
+ <xsd:attribute name="autoforward" type="Boolean.datatype" use="optional" default="false"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.invoke.mix">
+ <xsd:sequence>
+ <xsd:element ref="content" minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="finalize" minOccurs="0" maxOccurs="1"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:group name="scxml.invoke.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.invoke.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.invoke.type">
+ <xsd:group ref="scxml.invoke.content"/>
+ <xsd:attributeGroup ref="scxml.invoke.attlist"/>
+ <xsd:assert test=" not(@type and @typeexpr)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test=" not(@src and @srcexpr)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test=" not((@src or @srcexpr) and (content | param))" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test=" not(@id and @idlocation)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test=" not(@namelist and param)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test=" not(param and content)" xpathDefaultNamespace="##targetNamespace"/>
+ <xsd:assert test=" not(content[2])" xpathDefaultNamespace="##targetNamespace"/>
+ </xsd:complexType>
+ <xsd:element name="invoke" type="scxml.invoke.type"/>
+
+ <!-- finalize -->
+ <xsd:attributeGroup name="scxml.finalize.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.finalize.mix">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:group name="scxml.finalize.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.finalize.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.finalize.type">
+ <xsd:group ref="scxml.finalize.content"/>
+ <xsd:attributeGroup ref="scxml.finalize.attlist"/>
+ <xsd:assert test=" not(send | raise)" xpathDefaultNamespace="##targetNamespace"/>
+ </xsd:complexType>
+ <xsd:element name="finalize" type="scxml.finalize.type"/>
+
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-message.xsd b/test/w3c/schema/scxml-message.xsd
new file mode 100644
index 0000000..de4b4b8
--- /dev/null
+++ b/test/w3c/schema/scxml-message.xsd
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ XML Schema for sending messages to SCXML processors.
+-->
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ XML Schema for sending messages to SCXML processors.
+ Version 1.0
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd" />
+ </xsd:annotation>
+
+ <xsd:attributeGroup name="scxmlmessage.extra.attribs">
+ <xsd:annotation>
+ <xsd:documentation>
+ Group allowing attributes from other namespaces
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:anyAttribute namespace="##other" processContents="lax" />
+ </xsd:attributeGroup>
+
+ <xsd:attributeGroup name="scxmlmessage.message.attlist">
+ <xsd:attribute name="version" type="xsd:string" fixed="1.0" use="required" />
+ <xsd:attribute name="source" type="xsd:anyURI" use="required" />
+ <xsd:attribute name="target" type="xsd:anyURI" use="required" />
+ <xsd:attribute name="sendid" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ Non SCXML senders are not required to specify a sendid
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="name" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ Defaults to "external.event"
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="sourcetype" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ Defaults to "scxml"
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attributeGroup ref="scxmlmessage.extra.attribs" />
+ </xsd:attributeGroup>
+
+ <xsd:group name="scxmlmessage.message.content">
+ <xsd:sequence>
+ <xsd:element ref="payload" minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:complexType name="scxmlmessage.message.type">
+ <xsd:group ref="scxmlmessage.message.content" />
+ <xsd:attributeGroup ref="scxmlmessage.message.attlist" />
+ </xsd:complexType>
+
+ <xsd:element name="message" type="scxmlmessage.message.type" />
+
+ <xsd:attributeGroup name="scxmlmessage.payload.attlist">
+ <xsd:attributeGroup ref="scxmlmessage.extra.attribs" />
+ <xsd:attribute name="contenttype" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ The mime type of the child content.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:attributeGroup>
+
+ <xsd:group name="scxmlmessage.payload.content">
+ <xsd:choice>
+ <xsd:sequence>
+ <xsd:element ref="property" minOccurs="0"
+ maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:sequence>
+ <xsd:any namespace="##other" minOccurs="1"
+ maxOccurs="unbounded" processContents="lax" />
+ </xsd:sequence>
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:complexType name="scxmlmessage.payload.type">
+ <xsd:group ref="scxmlmessage.payload.content" />
+ <xsd:attributeGroup ref="scxmlmessage.payload.attlist" />
+ </xsd:complexType>
+
+ <xsd:element name="payload" type="scxmlmessage.payload.type" />
+
+ <xsd:attributeGroup name="scxmlmessage.property.attlist">
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attributeGroup ref="scxmlmessage.extra.attribs" />
+ </xsd:attributeGroup>
+
+ <xsd:group name="scxmlmessage.property.content">
+ <xsd:sequence>
+ <xsd:element ref="hint" minOccurs="0"
+ maxOccurs="1" />
+ <xsd:any namespace="##other" minOccurs="0"
+ maxOccurs="unbounded" processContents="skip" />
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:complexType name="scxmlmessage.property.type" mixed="true">
+ <xsd:group ref="scxmlmessage.property.content" />
+ <xsd:attributeGroup ref="scxmlmessage.property.attlist" />
+ </xsd:complexType>
+
+ <xsd:element name="property" type="scxmlmessage.property.type" />
+
+ <xsd:element name="hint" type="xsd:string" />
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-messages.xsd b/test/w3c/schema/scxml-messages.xsd
new file mode 100644
index 0000000..922bc57
--- /dev/null
+++ b/test/w3c/schema/scxml-messages.xsd
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ XML Schema for sending messages to SCXML processors.
+-->
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+
+ <xsd:include schemaLocation="scxml-message.xsd"/>
+
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ XML Schema for sending messages to SCXML processors.
+ Version 1.0
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd" />
+ </xsd:annotation>
+
+ <xsd:attributeGroup name="scxmlmessages.extra.attribs">
+ <xsd:annotation>
+ <xsd:documentation>
+ Group allowing attributes from other namespaces
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:anyAttribute namespace="##other" processContents="lax" />
+ </xsd:attributeGroup>
+
+ <xsd:attributeGroup name="scxmlmessages.messages.attlist">
+ <xsd:attribute name="version" type="xsd:string" fixed="1.0"
+ use="required" />
+ <xsd:attributeGroup ref="scxmlmessages.extra.attribs" />
+ </xsd:attributeGroup>
+
+ <xsd:group name="scxmlmessages.messages.content">
+ <xsd:sequence>
+ <xsd:element ref="message" minOccurs="1"
+ maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:complexType name="scxmlmessages.messages.type">
+ <xsd:group ref="scxmlmessages.messages.content" />
+ <xsd:attributeGroup ref="scxmlmessages.messages.attlist" />
+ </xsd:complexType>
+
+ <xsd:element name="messages" type="scxmlmessages.messages.type" />
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-module-anchor.xsd b/test/w3c/schema/scxml-module-anchor.xsd
new file mode 100644
index 0000000..65ff6cc
--- /dev/null
+++ b/test/w3c/schema/scxml-module-anchor.xsd
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema anchor module for SCXML
+ * anchor
+ The anchor module defines these elements and their
+ attributes.
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines SCXML Attribute DataTypes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common attributes for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common content model extensions for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <!-- anchor -->
+ <xsd:attributeGroup name="scxml.anchor.attlist">
+ <xsd:attribute name="type" type="xsd:NMTOKEN" use="required"/>
+ <xsd:attribute name="snapshot" type="LocLang.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+
+ <xsd:group name="scxml.anchor.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:complexType name="scxml.anchor.type">
+ <xsd:group ref="scxml.anchor.content"/>
+ <xsd:attributeGroup ref="scxml.anchor.attlist"/>
+ </xsd:complexType>
+
+ <xsd:element name="anchor" type="scxml.anchor.type"/>
+ <!-- Added this in because it should be defined here and used in the profiles. -->
+ <xsd:simpleType name="Anchor.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ This defines the Anchor data type to be used for the transition element.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN"/>
+ </xsd:simpleType>
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-module-core.xsd b/test/w3c/schema/scxml-module-core.xsd
new file mode 100644
index 0000000..5245bc9
--- /dev/null
+++ b/test/w3c/schema/scxml-module-core.xsd
@@ -0,0 +1,405 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema core module for SCXML
+ * scxml
+ * state
+ * initial
+ * onexit
+ * onentry
+ * transition
+ * parallel
+ * final
+ * history
+ * donedata
+ * if
+ * elsif
+ * else
+ * foreach
+ * raise
+ * log
+ The core module defines these elements and the
+ attributes.
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ Includes common SCXML datatypes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ Includes common SCXML attributes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common content model extensions for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+
+ <!-- scxml -->
+ <xsd:attributeGroup name="scxml.scxml.attlist">
+ <xsd:attribute name="initial" type="xsd:IDREFS"/>
+ <xsd:attribute name="name" type="xsd:NMTOKEN"/>
+ <xsd:attribute name="version" type="xsd:decimal" use="required" fixed="1.0"/>
+ <xsd:attribute name="datamodel" type="xsd:NMTOKEN" default="null" use="optional"/>
+ <xsd:attribute name="binding" type="Binding.datatype"/>
+ <xsd:attribute name="exmode" type="Exmode.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.scxml.mix">
+ <xsd:choice>
+ <xsd:element ref="state" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="parallel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="final" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="script" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.scxml.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.scxml.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.scxml.type">
+ <xsd:group ref="scxml.scxml.content"/>
+ <xsd:attributeGroup ref="scxml.scxml.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="scxml" type="scxml.scxml.type"/>
+
+ <!-- state -->
+ <xsd:attributeGroup name="scxml.state.attlist">
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="initial" type="xsd:IDREFS"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.state.mix">
+ <xsd:choice>
+ <xsd:element ref="onentry" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="onexit" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="transition" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="initial" minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="state" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="parallel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="final" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="history" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="invoke" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.state.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.state.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.state.type">
+ <xsd:sequence>
+ <xsd:group ref="scxml.state.content"/>
+ </xsd:sequence>
+ <xsd:attributeGroup ref="scxml.state.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="state" type="scxml.state.type"/>
+
+ <!-- initial -->
+ <xsd:attributeGroup name="scxml.initial.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.initial.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="transition" minOccurs="1" maxOccurs="1"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.initial.type">
+ <xsd:group ref="scxml.initial.content"/>
+ <xsd:attributeGroup ref="scxml.initial.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="initial" type="scxml.initial.type"/>
+
+ <!-- onentry -->
+ <xsd:attributeGroup name="scxml.onentry.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.onentry.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.onentry.type">
+ <xsd:group ref="scxml.onentry.content"/>
+ <xsd:attributeGroup ref="scxml.onentry.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="onentry" type="scxml.onentry.type"/>
+
+ <!-- onexit -->
+ <xsd:attributeGroup name="scxml.onexit.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.onexit.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.onexit.type">
+ <xsd:group ref="scxml.onexit.content"/>
+ <xsd:attributeGroup ref="scxml.onexit.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="onexit" type="scxml.onexit.type"/>
+
+ <!-- transition -->
+ <xsd:attributeGroup name="scxml.transition.attlist">
+ <xsd:attribute name="event" type="EventTypes.datatype"/>
+ <xsd:attribute name="cond" type="CondLang.datatype"/>
+ <xsd:attribute name="target" type="xsd:IDREFS"/>
+ <xsd:attribute name="type" type="TransitionType.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.transition.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.transition.type">
+ <xsd:group ref="scxml.transition.content"/>
+ <xsd:attributeGroup ref="scxml.transition.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="transition" type="scxml.transition.type"/>
+
+ <!-- parallel -->
+ <xsd:attributeGroup name="scxml.parallel.attlist">
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.parallel.mix">
+ <xsd:choice>
+ <xsd:element ref="onentry" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="onexit" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="transition" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="state" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="parallel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="history" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="invoke" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.parallel.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.parallel.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.parallel.type">
+ <xsd:group ref="scxml.parallel.content"/>
+ <xsd:attributeGroup ref="scxml.parallel.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="parallel" type="scxml.parallel.type"/>
+
+ <!-- final -->
+ <xsd:attributeGroup name="scxml.final.attlist">
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.final.mix">
+ <xsd:choice>
+ <xsd:element ref="onentry" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="onexit" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="donedata" minOccurs="0" maxOccurs="1"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.final.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.final.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.final.type">
+ <xsd:group ref="scxml.final.content"/>
+ <xsd:attributeGroup ref="scxml.final.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="final" type="scxml.final.type"/>
+
+ <!-- history -->
+ <xsd:attributeGroup name="scxml.history.attlist">
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="type" type="HistoryType.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.history.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="transition" minOccurs="1" maxOccurs="1"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.history.type">
+ <xsd:group ref="scxml.history.content"/>
+ <xsd:attributeGroup ref="scxml.history.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="history" type="scxml.history.type"/>
+
+
+
+ <!-- donedata -->
+ <xsd:attributeGroup name="scxml.donedata.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.donedata.content">
+ <xsd:choice>
+ <xsd:element ref="content" minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:complexType name="scxml.donedata.type">
+ <xsd:group ref="scxml.donedata.content"/>
+ <xsd:attributeGroup ref="scxml.donedata.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="donedata" type="scxml.donedata.type"/>
+
+ <!-- if -->
+ <xsd:attributeGroup name="scxml.if.attlist">
+ <xsd:attribute name="cond" type="CondLang.datatype" use="required"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.if.elseif.mix">
+ <xsd:sequence>
+ <xsd:element ref="elseif" />
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:group name="scxml.if.else.mix">
+ <xsd:sequence>
+ <xsd:element ref="else" />
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:group name="scxml.if.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.if.elseif.mix" minOccurs="0" maxOccurs="1"/>
+ <xsd:group ref="scxml.if.else.mix" minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.if.type">
+ <xsd:group ref="scxml.if.content"/>
+ <xsd:attributeGroup ref="scxml.if.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="if" type="scxml.if.type"/>
+
+ <!-- elseif -->
+ <xsd:attributeGroup name="scxml.elseif.attlist">
+ <xsd:attribute name="cond" type="CondLang.datatype" use="required"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.elseif.mix">
+ <xsd:choice>
+ <!-- No content for this element -->
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.elseif.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.elseif.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.elseif.type">
+ <xsd:group ref="scxml.elseif.content"/>
+ <xsd:attributeGroup ref="scxml.elseif.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="elseif" type="scxml.elseif.type"/>
+
+ <!-- else -->
+ <xsd:attributeGroup name="scxml.else.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.else.mix">
+ <xsd:choice>
+ <!-- No content for this element -->
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.else.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.else.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.else.type">
+ <xsd:group ref="scxml.else.content"/>
+ <xsd:attributeGroup ref="scxml.else.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="else" type="scxml.else.type"/>
+
+ <!-- foreach -->
+ <xsd:attributeGroup name="scxml.foreach.attlist">
+ <xsd:attribute name="array" type="ValueLang.datatype" use="required"/>
+ <xsd:attribute name="item" type="xsd:string" use="required"/>
+ <xsd:attribute name="index" type="xsd:string"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.foreach.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.foreach.type">
+ <xsd:group ref="scxml.foreach.content"/>
+ <xsd:attributeGroup ref="scxml.foreach.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="foreach" type="scxml.foreach.type"/>
+
+ <!-- raise -->
+ <xsd:attributeGroup name="scxml.raise.attlist">
+ <xsd:attribute name="event" type="xsd:NMTOKEN" use="required"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.raise.mix">
+ <xsd:choice>
+ <!-- No content for this element -->
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.raise.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.raise.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.raise.type">
+ <xsd:group ref="scxml.raise.content"/>
+ <xsd:attributeGroup ref="scxml.raise.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="raise" type="scxml.raise.type"/>
+
+ <!-- log -->
+ <xsd:attributeGroup name="scxml.log.attlist">
+ <xsd:attribute name="label" type="xsd:string"/>
+ <xsd:attribute name="expr" type="ValueLang.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.log.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.log.type">
+ <xsd:group ref="scxml.log.content"/>
+ <xsd:attributeGroup ref="scxml.log.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="log" type="scxml.log.type"/>
+
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-module-data.xsd b/test/w3c/schema/scxml-module-data.xsd
new file mode 100644
index 0000000..ec96e71
--- /dev/null
+++ b/test/w3c/schema/scxml-module-data.xsd
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema data module for SCXML
+ * datamodel
+ * data
+ * assign
+ * param
+ * script
+ * content
+ The data module defines these elements and their
+ attributes.
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines SCXML Attribute DataTypes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common attributes for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common content model extensions for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <!-- datamodel -->
+ <xsd:attributeGroup name="scxml.datamodel.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.datamodel.content">
+ <xsd:sequence>
+ <xsd:element ref="data" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.datamodel.type">
+ <xsd:group ref="scxml.datamodel.content"/>
+ <xsd:attributeGroup ref="scxml.datamodel.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="datamodel" type="scxml.datamodel.type"/>
+
+ <!-- data -->
+ <xsd:attributeGroup name="scxml.data.attlist">
+ <xsd:attribute name="id" type="xsd:ID" use="required"/>
+ <xsd:attribute name="src" type="URI.datatype"/>
+ <xsd:attribute name="expr" type="ValueLang.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.data.content">
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.data.type" mixed="true">
+ <xsd:group ref="scxml.data.content"/>
+ <xsd:attributeGroup ref="scxml.data.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="data" type="scxml.data.type"/>
+
+
+
+ <!-- param -->
+ <xsd:attributeGroup name="scxml.param.attlist">
+ <xsd:attribute name="name" type="xsd:NMTOKEN" use="required"/>
+ <xsd:attribute name="expr" type="ValueLang.datatype"/>
+ <xsd:attribute name="location" type="LocLang.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.param.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.param.type">
+ <xsd:group ref="scxml.param.content"/>
+ <xsd:attributeGroup ref="scxml.param.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="param" type="scxml.param.type"/>
+
+<!-- assign -->
+ <xsd:attributeGroup name="scxml.assign.attlist">
+ <xsd:attribute name="location" type="LocLang.datatype" use="required"/>
+ <xsd:attribute name="expr" type="ValueLang.datatype"/>
+ <xsd:attribute name="type" type="AssignType.datatype" default="replacechildren"/>
+ <xsd:attribute name="attr" type="xsd:NMTOKEN"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.assign.content">
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.assign.type" mixed="true">
+ <xsd:group ref="scxml.assign.content"/>
+ <xsd:attributeGroup ref="scxml.assign.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="assign" type="scxml.assign.type"/>
+
+
+<!-- script -->
+ <xsd:attributeGroup name="scxml.script.attlist">
+ <xsd:attribute name="src" type="URI.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.script.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.script.type" mixed="true">
+ <xsd:group ref="scxml.script.content"/>
+ <xsd:attributeGroup ref="scxml.script.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="script" type="scxml.script.type"/>
+
+ <!-- content -->
+ <xsd:attributeGroup name="scxml.content.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ <xsd:attribute name="expr" type="ValueLang.datatype"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.content.content">
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.content.type" mixed="true">
+ <xsd:group ref="scxml.content.content"/>
+ <xsd:attributeGroup ref="scxml.content.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="content" type="scxml.content.type"/>
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-module-external.xsd b/test/w3c/schema/scxml-module-external.xsd
new file mode 100644
index 0000000..ae6ced3
--- /dev/null
+++ b/test/w3c/schema/scxml-module-external.xsd
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema external module for SCXML
+ * send
+ * cancel
+ * invoke
+ * finalize
+ The external module defines these elements and their
+ attributes.
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines SCXML Attribute DataTypes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common attributes for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common content model extensions for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+<!-- send -->
+ <xsd:attributeGroup name="scxml.send.attlist">
+ <xsd:attribute name="event" type="EventType.datatype"/>
+ <xsd:attribute name="eventexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="target" type="URI.datatype"/>
+ <xsd:attribute name="targetexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="type" type="xsd:string" default="scxml"/>
+ <xsd:attribute name="typeexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="idlocation" type="LocLang.datatype"/>
+ <xsd:attribute name="delay" type="Duration.datatype" default="0s"/>
+ <xsd:attribute name="delayexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="namelist" type="xsd:string"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.send.mix">
+ <xsd:choice>
+ <xsd:element ref="content" minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.send.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.send.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.send.type">
+ <xsd:group ref="scxml.send.content"/>
+ <xsd:attributeGroup ref="scxml.send.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="send" type="scxml.send.type"/>
+
+ <!-- cancel -->
+ <xsd:attributeGroup name="scxml.cancel.attlist">
+ <xsd:attribute name="sendid" type="xsd:IDREF"/>
+ <xsd:attribute name="sendidexpr" type="ValueLang.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.cancel.mix">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:group name="scxml.cancel.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.cancel.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.cancel.type">
+ <xsd:group ref="scxml.cancel.content"/>
+ <xsd:attributeGroup ref="scxml.cancel.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="cancel" type="scxml.cancel.type"/>
+
+
+
+ <!-- invoke -->
+ <xsd:attributeGroup name="scxml.invoke.attlist">
+ <xsd:attribute name="type" type="xsd:string" default="scxml"/>
+ <xsd:attribute name="typeexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="src" type="URI.datatype"/>
+ <xsd:attribute name="srcexpr" type="ValueLang.datatype"/>
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="idlocation" type="LocLang.datatype"/>
+ <xsd:attribute name="namelist" type="xsd:string"/>
+ <xsd:attribute name="autoforward" type="Boolean.datatype" use="optional" default="false"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.invoke.mix">
+ <xsd:sequence>
+ <xsd:element ref="content" minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="finalize" minOccurs="0" maxOccurs="1"/>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:group name="scxml.invoke.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.invoke.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.invoke.type">
+ <xsd:group ref="scxml.invoke.content"/>
+ <xsd:attributeGroup ref="scxml.invoke.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="invoke" type="scxml.invoke.type"/>
+
+ <!-- finalize -->
+ <xsd:attributeGroup name="scxml.finalize.attlist">
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.finalize.mix">
+ <xsd:sequence>
+ <xsd:group ref="scxml.core.executablecontent"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:group name="scxml.finalize.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.finalize.mix" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.finalize.type">
+ <xsd:group ref="scxml.finalize.content"/>
+ <xsd:attributeGroup ref="scxml.finalize.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="finalize" type="scxml.finalize.type"/>
+
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-module-script.xsd b/test/w3c/schema/scxml-module-script.xsd
new file mode 100644
index 0000000..5c241f2
--- /dev/null
+++ b/test/w3c/schema/scxml-module-script.xsd
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema script module for SCXML
+ * script
+ The script module defines these elements and their
+ attributes.
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ Includes common SCXML datatypes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ Includes common SCXML attributes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This module defines Common content model extensions for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:attributeGroup name="scxml.script.attlist">
+ <xsd:attribute name="src" type="URI.datatype"/>
+ <xsd:attributeGroup ref="scxml.extra.attribs"/>
+ </xsd:attributeGroup>
+ <xsd:group name="scxml.script.content">
+ <xsd:sequence>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+ <xsd:complexType name="scxml.script.type" mixed="true">
+ <xsd:group ref="scxml.script.content"/>
+ <xsd:attributeGroup ref="scxml.script.attlist"/>
+ </xsd:complexType>
+ <xsd:element name="script" type="scxml.script.type"/>
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-profile-basic.xsd b/test/w3c/schema/scxml-profile-basic.xsd
new file mode 100644
index 0000000..ebd5f26
--- /dev/null
+++ b/test/w3c/schema/scxml-profile-basic.xsd
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema driver for SCXML 1.0, basic profile.
+ Please use this namespace for SCXML 1.0 elements:
+
+ "http://www.w3.org/2005/07/scxml"
+
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the Schema Driver file for SCXML 1.0, basic profile
+
+ This schema
+ + sets the namespace for SCXML 1.0 basic profile
+ + imports external schemas (xml.xsd)
+ + imports SCXML common datatypes, attributes and common models
+ + imports schema modules
+
+ SCXML 1.0 includes the following Modules
+
+ * SCXML core module
+
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="xml.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This import brings in the XML namespace attributes
+ The XML attributes are used by various modules.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports brings in the common datatypes
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports brings in the common attributes
+ for SCXML.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the common content models.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-module-core.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the core module for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+
+ <!--
+ Defines the CondLang datatype for this
+ profile.
+ -->
+ <xsd:simpleType name="CondLang.datatype">
+ <xsd:annotation>
+ <xsd:documentation>
+ Conditional language only consists of In(ID) where ID is
+ the XML ID type identify an SCXML state. The function
+ must evaluate to Boolean True or False.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-profile-ecma.xsd b/test/w3c/schema/scxml-profile-ecma.xsd
new file mode 100644
index 0000000..852b1a2
--- /dev/null
+++ b/test/w3c/schema/scxml-profile-ecma.xsd
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema driver for SCXML 1.0, ecmascript profile.
+ Please use this namespace for SCXML 1.0 elements:
+
+ "http://www.w3.org/2005/07/scxml"
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+ <xsd:annotation>
+ <xsd:documentation>
+ This schema
+ + sets the namespace for SCXML 1.0 basic ecmascript profile
+ + imports external schemas (xml.xsd)
+ + includes SCXML common datatypes, attributes and content models
+ + includes schema modules
+ SCXML 1.0 includes the following Modules
+ SCXML core module
+ SCXML data module
+ SCXML script module
+ SCXML external module
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This import brings in the XML namespace attributes
+ The XML attributes are used by various modules.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This includes brings in the common data types for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This includes brings in the common attributes for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+ <xsd:include schemaLocation="scxml-module-data.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This includes the data module for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+ <xsd:include schemaLocation="scxml-module-script.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This includes the script module for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+ <xsd:redefine schemaLocation="scxml-module-external.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the external module for SCXML and redefines the following.
+ [1] Redefines send and invoke mix group to allow
+ param
+ [2] Redefines finalize mix group to allow:
+ executable content
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:group name="scxml.send.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.send.mix"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.invoke.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.invoke.mix"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.finalize.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.finalize.mix"/>
+ <xsd:group ref="scxml.core.executablecontent"/>
+ </xsd:choice>
+ </xsd:group>
+ </xsd:redefine>
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This includes the common content models.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+ <xsd:redefine schemaLocation="scxml-module-core.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the core module for SCXML and redefines the following.
+ [1] Redefines executable content to allow
+ send, assign, validate, cancel and script elements
+ [2] Redefines state and parallel mix group to allow
+ invoke
+ datamodel
+ [3] Redefines scxml group to allow
+ datamodel
+ script
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:group name="scxml.core.executablecontent">
+ <xsd:choice>
+ <xsd:group ref="scxml.core.executablecontent"/>
+ <xsd:element ref="send"/>
+ <xsd:element ref="assign"/>
+ <xsd:element ref="script"/>
+ <xsd:element ref="validate"/>
+ <xsd:element ref="cancel"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.scxml.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.scxml.mix"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="script" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.state.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.state.mix"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="invoke" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.parallel.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.parallel.mix"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="invoke" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.donedata.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.donedata.mix"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.raise.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.raise.mix"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ </xsd:redefine>
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-profile-minimum.xsd b/test/w3c/schema/scxml-profile-minimum.xsd
new file mode 100644
index 0000000..fa4fb4d
--- /dev/null
+++ b/test/w3c/schema/scxml-profile-minimum.xsd
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema driver for SCXML 1.0, minimum profile.
+ Please use this namespace for SCXML 1.0 elements:
+
+ "http://www.w3.org/2005/07/scxml"
+
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the Schema Driver file for SCXML 1.0, minimum profile
+
+ This schema
+ + sets the namespace for SCXML 1.0 minimum profile
+ + imports external schemas (xml.xsd)
+ + imports SCXML common datatypes, attributes and common models
+ + imports schema modules
+
+ SCXML 1.0 includes the following Modules
+
+ * SCXML core module
+
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This import brings in the XML namespace attributes
+ The XML attributes are used by various modules.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports brings in the common datatypes for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports brings in the common attributes for SCXML.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the common content models.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-module-core.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the core module for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-profile-xpath.xsd b/test/w3c/schema/scxml-profile-xpath.xsd
new file mode 100644
index 0000000..9206fea
--- /dev/null
+++ b/test/w3c/schema/scxml-profile-xpath.xsd
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema driver for SCXML 1.0, xpath profile.
+ Please use this namespace for SCXML 1.0 elements:
+
+ "http://www.w3.org/2005/07/scxml"
+
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the Schema Driver file for SCXML 1.0, xpath profile
+
+ This schema
+ + sets the namespace for SCXML 1.0 basic profile
+ + imports external schemas (xml.xsd)
+ + imports SCXML common datatypes, attributes and content models
+ + imports schema modules
+
+ SCXML 1.0 includes the following Modules
+ SCXML core module
+ SCXML data module
+ SCXML external module
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This import brings in the XML namespace attributes
+ The XML attributes are used by various modules.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+ <xsd:include schemaLocation="scxml-datatypes.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This includes brings in the common data types for SCXML
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-attribs.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This includes brings in the common attributes for SCXML.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:redefine schemaLocation="scxml-module-data.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the data module for SCXML and redefines the following.
+ [1] Redefines assign attribute group to allow dataid
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attributeGroup name="scxml.assign.attlist">
+ <xsd:attributeGroup ref="scxml.assign.attlist"/>
+ <xsd:attribute name="type" type="AssignType.datatype" default="replacechildren"/>
+ <xsd:attribute name="attr" type="xsd:NMTOKEN"/>
+ </xsd:attributeGroup>
+ </xsd:redefine>
+
+ <xsd:redefine schemaLocation="scxml-module-external.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the external module for SCXML and redefines the following.
+ [1] Redefines send and invoke mix group to allow
+ param
+ [2] Redefines finalize mix group to allow:
+ executable content
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:group name="scxml.send.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.send.mix"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.invoke.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.invoke.mix"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.finalize.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.finalize.mix"/>
+ <xsd:group ref="scxml.core.executablecontent"/>
+ </xsd:choice>
+ </xsd:group>
+ </xsd:redefine>
+
+ <xsd:include schemaLocation="scxml-contentmodels.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This includes the common content models.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+ <xsd:redefine schemaLocation="scxml-module-core.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the core module for SCXML and redefines the following.
+ [1] Redefines executable content to allow
+ send, assign, validate, and cancel elements
+ [2] Redefines state and parallel mix group to allow
+ invoke
+ datamodel
+ [3] Redefines scxml group to allow
+ datamodel
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:group name="scxml.core.executablecontent">
+ <xsd:choice>
+ <xsd:group ref="scxml.core.executablecontent"/>
+ <xsd:element ref="send"/>
+ <xsd:element ref="assign"/>
+ <xsd:element ref="validate"/>
+ <xsd:element ref="cancel"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.scxml.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.scxml.mix"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.state.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.state.mix"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="invoke" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.parallel.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.parallel.mix"/>
+ <xsd:element ref="datamodel" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="invoke" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.donedata.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.donedata.mix"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:group name="scxml.raise.mix">
+ <xsd:choice>
+ <xsd:group ref="scxml.raise.mix"/>
+ <xsd:element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:group>
+ </xsd:redefine>
+</xsd:schema>
diff --git a/test/w3c/schema/scxml-strict.xsd b/test/w3c/schema/scxml-strict.xsd
new file mode 100644
index 0000000..fa89851
--- /dev/null
+++ b/test/w3c/schema/scxml-strict.xsd
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema driver for SCXML 1.0.
+ Please use this namespace for SCXML 1.0 elements:
+
+ "http://www.w3.org/2005/07/scxml"
+
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema driver file for SCXML 1.0.
+
+ This schema:
+ + sets the namespace for SCXML 1.0
+ + imports external schemas (xml.xsd)
+ + imports SCXML common datatypes, attributes and content models
+ + imports modular schemas
+
+ SCXML 1.0 includes:
+ + SCXML core constructs
+ + SCXML executable content
+ + SCXML data model and manipulation
+ + SCXML external communications
+
+ This schema is permissive such that it accomodates all
+ datamodels, but validating documents may contain markup that
+ is ignored in certain datamodels.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This import brings in the XML namespace attributes
+ The XML attributes are used by various modules.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+
+<xsd:include schemaLocation="scxml-core-strict.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the core elements for SCXML.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-data-strict.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the data modelelements for SCXML.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-external-strict.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the external communications elements for SCXML.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+<!-- the various elements of executable content are defined in the relevant modules.
+This gathers them up into a single type -->
+ <xsd:group name="scxml.core.executablecontent">
+ <xsd:choice>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="raise"/>
+ <xsd:element ref="if"/>
+ <xsd:element ref="foreach"/>
+ <xsd:element ref="send"/>
+ <xsd:element ref="script"/>
+ <xsd:element ref="assign"/>
+ <xsd:element ref="log"/>
+ <xsd:element ref="cancel"/>
+ </xsd:choice>
+ </xsd:group>
+
+</xsd:schema>
diff --git a/test/w3c/schema/scxml.xsd b/test/w3c/schema/scxml.xsd
new file mode 100644
index 0000000..fb69c75
--- /dev/null
+++ b/test/w3c/schema/scxml.xsd
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.w3.org/2005/07/scxml"
+ xmlns="http://www.w3.org/2005/07/scxml"
+ elementFormDefault="qualified">
+
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema driver for SCXML 1.0.
+ Please use this namespace for SCXML 1.0 elements:
+
+ "http://www.w3.org/2005/07/scxml"
+
+ </xsd:documentation>
+ <xsd:documentation source="scxml-copyright.xsd"/>
+ </xsd:annotation>
+ <xsd:annotation>
+ <xsd:documentation>
+ This is the XML Schema driver file for SCXML 1.0.
+
+ This schema:
+ + sets the namespace for SCXML 1.0
+ + imports external schemas (xml.xsd)
+ + imports SCXML common datatypes, attributes and content models
+ + imports modular schemas
+
+ SCXML 1.0 includes:
+ + SCXML core constructs
+ + SCXML executable content
+ + SCXML data model and manipulation
+ + SCXML external communications
+
+ This schema is permissive such that it accomodates all
+ datamodels, but validating documents may contain markup that
+ is ignored in certain datamodels.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This import brings in the XML namespace attributes
+ The XML attributes are used by various modules.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+
+<xsd:include schemaLocation="scxml-module-core.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the core elements for SCXML.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-module-data.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the data modelelements for SCXML.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+ <xsd:include schemaLocation="scxml-module-external.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ This imports the external communications elements for SCXML.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:include>
+
+<!-- the various elements of executable content are defined in the relevant modules.
+This gathers them up into a single type -->
+ <xsd:group name="scxml.core.executablecontent">
+ <xsd:choice>
+ <xsd:group ref="scxml.extra.content" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="raise"/>
+ <xsd:element ref="if"/>
+ <xsd:element ref="foreach"/>
+ <xsd:element ref="send"/>
+ <xsd:element ref="script"/>
+ <xsd:element ref="assign"/>
+ <xsd:element ref="log"/>
+ <xsd:element ref="cancel"/>
+ </xsd:choice>
+ </xsd:group>
+
+</xsd:schema>
diff --git a/test/w3c/schema/xml.xsd b/test/w3c/schema/xml.xsd
new file mode 100644
index 0000000..069c970
--- /dev/null
+++ b/test/w3c/schema/xml.xsd
@@ -0,0 +1,117 @@
+<?xml version='1.0'?>
+<!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd" >
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
+
+ <xs:annotation>
+ <xs:documentation>
+ See http://www.w3.org/XML/1998/namespace.html and
+ http://www.w3.org/TR/REC-xml for information about this namespace.
+
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+
+ Note that local names in this namespace are intended to be defined
+ only by the World Wide Web Consortium or its subgroups. The
+ following names are currently defined in this namespace and should
+ not be used with conflicting semantics by any Working Group,
+ specification, or document instance:
+
+ base (as an attribute name): denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.
+
+ lang (as an attribute name): denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.
+
+ space (as an attribute name): denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.
+
+ Father (in any context at all): denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+
+ In appreciation for his vision, leadership and dedication
+ the W3C XML Plenary on this 10th day of February, 2000
+ reserves for Jon Bosak in perpetuity the XML name
+ xml:Father
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>This schema defines attributes and an attribute group
+ suitable for use by
+ schemas wishing to allow xml:base, xml:lang or xml:space attributes
+ on elements they define.
+
+ To enable this, such a schema must import this schema
+ for the XML namespace, e.g. as follows:
+ &lt;schema . . .>
+ . . .
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/03/xml.xsd"/>
+
+ Subsequently, qualified reference to any of the attributes
+ or the group defined below will have the desired effect, e.g.
+
+ &lt;type . . .>
+ . . .
+ &lt;attributeGroup ref="xml:specialAttrs"/>
+
+ will define a type which will schema-validate an instance
+ element with any of those attributes</xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ http://www.w3.org/2001/03/xml.xsd.
+ At the date of issue it can also be found at
+ xml.xsd.
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML Schema
+ itself. In other words, if the XML Schema namespace changes, the version
+ of this document at
+ xml.xsd will change
+ accordingly; the version at
+ http://www.w3.org/2001/03/xml.xsd will not change.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang" type="xs:language">
+ <xs:annotation>
+ <xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values . . .</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="space" default="preserve">
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI">
+ <xs:annotation>
+ <xs:documentation>See http://www.w3.org/TR/xmlbase/ for
+ information about this attribute.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+
+</xs:schema>
diff --git a/test/w3c/txml/test278.txml b/test/w3c/txml/test278.txml
index c95b329..3f64f25 100644
--- a/test/w3c/txml/test278.txml
+++ b/test/w3c/txml/test278.txml
@@ -1,5 +1,5 @@
-<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance">
+<scxml initial="s0" version="1.0" datamodel="ecmascript" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance">
<!-- test that a variable can be accessed from a state that is outside its lexical scope -->