diff options
author | Stefan Radomski <sradomski@mintwerk.de> | 2015-12-04 08:00:18 (GMT) |
---|---|---|
committer | Stefan Radomski <sradomski@mintwerk.de> | 2015-12-04 08:00:18 (GMT) |
commit | b8ba0e7c31f397a66f9d509ff20a85b33619475a (patch) | |
tree | 9a5adb4f891cdc29eb80f597510e0cef8ee0a47f | |
parent | 57ba362eae6e8209cf560555fd4cc4bb76dbe2a1 (diff) | |
download | uscxml-b8ba0e7c31f397a66f9d509ff20a85b33619475a.zip uscxml-b8ba0e7c31f397a66f9d509ff20a85b33619475a.tar.gz uscxml-b8ba0e7c31f397a66f9d509ff20a85b33619475a.tar.bz2 |
All changes up to my dissertation
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 ©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: + <schema . . .> + . . . + <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. + + <type . . .> + . . . + <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 --> |