summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--apps/uscxml-browser.cpp4
-rw-r--r--contrib/cmake/FindSWI.cmake20
-rw-r--r--contrib/src/swi-pl/SWI-cpp.h16
-rw-r--r--src/uscxml/Convenience.h6
-rw-r--r--src/uscxml/Factory.cpp8
-rw-r--r--src/uscxml/Factory.h2
-rw-r--r--src/uscxml/Interpreter.cpp280
-rw-r--r--src/uscxml/Interpreter.h6
-rw-r--r--src/uscxml/debug/InterpreterIssue.cpp71
-rw-r--r--src/uscxml/debug/InterpreterIssue.h6
-rw-r--r--src/uscxml/debug/SCXMLDotWriter.cpp22
-rw-r--r--src/uscxml/debug/SCXMLDotWriter.h2
-rw-r--r--src/uscxml/interpreter/InterpreterRC.cpp100
-rw-r--r--src/uscxml/interpreter/InterpreterRC.h1
-rw-r--r--src/uscxml/messages/Event.h2
-rw-r--r--src/uscxml/messages/MMIMessages.cpp192
-rw-r--r--src/uscxml/messages/MMIMessages.h46
-rw-r--r--src/uscxml/plugins/EventHandler.h4
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp4
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/SpiderMonkey/SpiderMonkeyDataModel.cpp82
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/SpiderMonkey/SpiderMonkeyDataModel.h2
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp6
-rw-r--r--src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp6
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIConfig.h.in3
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h3
-rw-r--r--src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp442
-rw-r--r--src/uscxml/plugins/datamodel/promela/PromelaDataModel.h18
-rw-r--r--src/uscxml/plugins/datamodel/promela/PromelaParser.cpp34
-rw-r--r--src/uscxml/plugins/datamodel/promela/PromelaParser.h9
-rw-r--r--src/uscxml/plugins/datamodel/promela/parser/promela.l17
-rw-r--r--src/uscxml/plugins/datamodel/promela/parser/promela.lex.yy.cpp360
-rw-r--r--src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp733
-rw-r--r--src/uscxml/plugins/datamodel/promela/parser/promela.tab.hpp5
-rw-r--r--src/uscxml/plugins/datamodel/promela/parser/promela.ypp38
-rw-r--r--src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp141
-rw-r--r--src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.h12
-rw-r--r--src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp42
-rw-r--r--src/uscxml/plugins/invoker/xhtml/template/xhtml-invoker.inc.h1376
-rw-r--r--src/uscxml/server/HTTPServer.cpp2
-rw-r--r--src/uscxml/server/HTTPServer.h2
-rw-r--r--src/uscxml/server/Socket.cpp18
-rw-r--r--src/uscxml/server/Socket.h2
-rw-r--r--src/uscxml/transform/ChartToFSM.cpp281
-rw-r--r--src/uscxml/transform/ChartToFSM.h16
-rw-r--r--src/uscxml/transform/FSMToPromela.cpp1115
-rw-r--r--src/uscxml/transform/FSMToPromela.h120
-rw-r--r--src/uscxml/transform/FlatStateIdentifier.h67
-rw-r--r--src/uscxml/util/Trie.cpp14
-rw-r--r--src/uscxml/util/Trie.h6
-rw-r--r--test/CMakeLists.txt26
-rw-r--r--test/ctest/CTestCustom.ctest.in145
-rw-r--r--test/src/test-flat-stateid.cpp12
-rw-r--r--test/src/test-issue-reporting.cpp352
-rw-r--r--test/src/test-mmi.cpp30
-rw-r--r--test/src/test-promela-parser.cpp18
-rw-r--r--test/src/test-sockets.cpp10
-rw-r--r--test/src/test-url.cpp2
-rw-r--r--test/src/test-vxml-mmi-http.cpp65
-rw-r--r--test/src/test-vxml-mmi-socket.cpp30
-rw-r--r--test/src/test-w3c.cpp36
-rw-r--r--test/uscxml/test-jvoicexml.scxml2
-rw-r--r--test/w3c/confPromela.xsl779
-rwxr-xr-xtest/w3c/convert-tests.sh31
-rw-r--r--test/w3c/draft/calc.scxml157
-rw-r--r--test/w3c/ecma/test403c.scxml6
-rw-r--r--test/w3c/promela/robots.txt96
-rw-r--r--test/w3c/promela/test144.scxml27
-rw-r--r--test/w3c/promela/test147.scxml35
-rw-r--r--test/w3c/promela/test148.scxml36
-rw-r--r--test/w3c/promela/test149.scxml31
-rw-r--r--test/w3c/promela/test150.scxml49
-rw-r--r--test/w3c/promela/test151.scxml49
-rw-r--r--test/w3c/promela/test152.scxml55
-rw-r--r--test/w3c/promela/test153.scxml46
-rw-r--r--test/w3c/promela/test155.scxml35
-rw-r--r--test/w3c/promela/test156.scxml37
-rw-r--r--test/w3c/promela/test158.scxml29
-rw-r--r--test/w3c/promela/test159.scxml26
-rw-r--r--test/w3c/promela/test172.scxml25
-rw-r--r--test/w3c/promela/test173.scxml26
-rw-r--r--test/w3c/promela/test174.scxml26
-rw-r--r--test/w3c/promela/test175.scxml32
-rw-r--r--test/w3c/promela/test176.scxml35
-rw-r--r--test/w3c/promela/test178.scxml27
-rw-r--r--test/w3c/promela/test179.scxml23
-rw-r--r--test/w3c/promela/test183.scxml25
-rw-r--r--test/w3c/promela/test185.scxml27
-rw-r--r--test/w3c/promela/test186.scxml36
-rw-r--r--test/w3c/promela/test187.scxml38
-rw-r--r--test/w3c/promela/test189.scxml27
-rw-r--r--test/w3c/promela/test190.scxml40
-rw-r--r--test/w3c/promela/test191.scxml37
-rw-r--r--test/w3c/promela/test192.scxml52
-rw-r--r--test/w3c/promela/test193.scxml29
-rw-r--r--test/w3c/promela/test194.scxml26
-rw-r--r--test/w3c/promela/test198.scxml23
-rw-r--r--test/w3c/promela/test199.scxml22
-rw-r--r--test/w3c/promela/test200.scxml22
-rw-r--r--test/w3c/promela/test201.scxml23
-rw-r--r--test/w3c/promela/test205.scxml34
-rw-r--r--test/w3c/promela/test207.scxml55
-rw-r--r--test/w3c/promela/test208.scxml24
-rw-r--r--test/w3c/promela/test210.scxml28
-rw-r--r--test/w3c/promela/test215.scxml35
-rw-r--r--test/w3c/promela/test216.scxml28
-rw-r--r--test/w3c/promela/test216sub1.scxml5
-rw-r--r--test/w3c/promela/test220.scxml29
-rw-r--r--test/w3c/promela/test223.scxml35
-rw-r--r--test/w3c/promela/test224.scxml36
-rw-r--r--test/w3c/promela/test225.scxml42
-rw-r--r--test/w3c/promela/test226.scxml26
-rw-r--r--test/w3c/promela/test226sub1.scxml14
-rw-r--r--test/w3c/promela/test228.scxml37
-rw-r--r--test/w3c/promela/test229.scxml46
-rw-r--r--test/w3c/promela/test230.scxml60
-rw-r--r--test/w3c/promela/test232.scxml41
-rw-r--r--test/w3c/promela/test233.scxml42
-rw-r--r--test/w3c/promela/test234.scxml69
-rw-r--r--test/w3c/promela/test235.scxml29
-rw-r--r--test/w3c/promela/test236.scxml43
-rw-r--r--test/w3c/promela/test237.scxml45
-rw-r--r--test/w3c/promela/test239.scxml35
-rw-r--r--test/w3c/promela/test239sub1.scxml5
-rw-r--r--test/w3c/promela/test240.scxml71
-rw-r--r--test/w3c/promela/test241.scxml96
-rw-r--r--test/w3c/promela/test242.scxml56
-rw-r--r--test/w3c/promela/test242sub1.scxml5
-rw-r--r--test/w3c/promela/test243.scxml41
-rw-r--r--test/w3c/promela/test244.scxml45
-rw-r--r--test/w3c/promela/test245.scxml40
-rw-r--r--test/w3c/promela/test247.scxml28
-rw-r--r--test/w3c/promela/test250.scxml39
-rw-r--r--test/w3c/promela/test252.scxml48
-rw-r--r--test/w3c/promela/test253.scxml75
-rw-r--r--test/w3c/promela/test276.scxml22
-rw-r--r--test/w3c/promela/test276sub1.scxml16
-rw-r--r--test/w3c/promela/test277.scxml32
-rw-r--r--test/w3c/promela/test278.scxml23
-rw-r--r--test/w3c/promela/test279.scxml24
-rw-r--r--test/w3c/promela/test280.scxml33
-rw-r--r--test/w3c/promela/test286.scxml23
-rw-r--r--test/w3c/promela/test287.scxml24
-rw-r--r--test/w3c/promela/test288.scxml25
-rw-r--r--test/w3c/promela/test294.scxml46
-rw-r--r--test/w3c/promela/test298.scxml32
-rw-r--r--test/w3c/promela/test301.scxml19
-rw-r--r--test/w3c/promela/test302.scxml21
-rw-r--r--test/w3c/promela/test303.scxml26
-rw-r--r--test/w3c/promela/test304.scxml19
-rw-r--r--test/w3c/promela/test307.scxml35
-rw-r--r--test/w3c/promela/test309.scxml18
-rw-r--r--test/w3c/promela/test310.scxml21
-rw-r--r--test/w3c/promela/test311.scxml22
-rw-r--r--test/w3c/promela/test312.scxml25
-rw-r--r--test/w3c/promela/test313.scxml26
-rw-r--r--test/w3c/promela/test314.scxml35
-rw-r--r--test/w3c/promela/test318.scxml32
-rw-r--r--test/w3c/promela/test319.scxml25
-rw-r--r--test/w3c/promela/test321.scxml21
-rw-r--r--test/w3c/promela/test322.scxml34
-rw-r--r--test/w3c/promela/test323.scxml21
-rw-r--r--test/w3c/promela/test324.scxml25
-rw-r--r--test/w3c/promela/test325.scxml23
-rw-r--r--test/w3c/promela/test326.scxml37
-rw-r--r--test/w3c/promela/test329.scxml54
-rw-r--r--test/w3c/promela/test330.scxml28
-rw-r--r--test/w3c/promela/test331.scxml59
-rw-r--r--test/w3c/promela/test332.scxml34
-rw-r--r--test/w3c/promela/test333.scxml21
-rw-r--r--test/w3c/promela/test335.scxml21
-rw-r--r--test/w3c/promela/test336.scxml31
-rw-r--r--test/w3c/promela/test337.scxml21
-rw-r--r--test/w3c/promela/test338.scxml43
-rw-r--r--test/w3c/promela/test339.scxml21
-rw-r--r--test/w3c/promela/test342.scxml31
-rw-r--r--test/w3c/promela/test343.scxml35
-rw-r--r--test/w3c/promela/test344.scxml28
-rw-r--r--test/w3c/promela/test346.scxml54
-rw-r--r--test/w3c/promela/test347.scxml44
-rw-r--r--test/w3c/promela/test348.scxml21
-rw-r--r--test/w3c/promela/test349.scxml33
-rw-r--r--test/w3c/promela/test350.scxml28
-rw-r--r--test/w3c/promela/test351.scxml45
-rw-r--r--test/w3c/promela/test352.scxml31
-rw-r--r--test/w3c/promela/test354.scxml52
-rw-r--r--test/w3c/promela/test355.scxml20
-rw-r--r--test/w3c/promela/test364.scxml79
-rw-r--r--test/w3c/promela/test372.scxml33
-rw-r--r--test/w3c/promela/test375.scxml28
-rw-r--r--test/w3c/promela/test376.scxml28
-rw-r--r--test/w3c/promela/test377.scxml31
-rw-r--r--test/w3c/promela/test378.scxml31
-rw-r--r--test/w3c/promela/test387.scxml93
-rw-r--r--test/w3c/promela/test388.scxml74
-rw-r--r--test/w3c/promela/test396.scxml21
-rw-r--r--test/w3c/promela/test399.scxml65
-rw-r--r--test/w3c/promela/test401.scxml25
-rw-r--r--test/w3c/promela/test402.scxml42
-rw-r--r--test/w3c/promela/test403a.scxml46
-rw-r--r--test/w3c/promela/test403b.scxml40
-rw-r--r--test/w3c/promela/test403c.scxml53
-rw-r--r--test/w3c/promela/test404.scxml56
-rw-r--r--test/w3c/promela/test405.scxml66
-rw-r--r--test/w3c/promela/test406.scxml60
-rw-r--r--test/w3c/promela/test407.scxml27
-rw-r--r--test/w3c/promela/test409.scxml36
-rw-r--r--test/w3c/promela/test411.scxml36
-rw-r--r--test/w3c/promela/test412.scxml52
-rw-r--r--test/w3c/promela/test413.scxml44
-rw-r--r--test/w3c/promela/test415.scxml13
-rw-r--r--test/w3c/promela/test416.scxml27
-rw-r--r--test/w3c/promela/test417.scxml36
-rw-r--r--test/w3c/promela/test419.scxml22
-rw-r--r--test/w3c/promela/test421.scxml31
-rw-r--r--test/w3c/promela/test422.scxml81
-rw-r--r--test/w3c/promela/test423.scxml29
-rw-r--r--test/w3c/promela/test436.scxml23
-rw-r--r--test/w3c/promela/test446.txt1
-rw-r--r--test/w3c/promela/test487.scxml25
-rw-r--r--test/w3c/promela/test488.scxml35
-rw-r--r--test/w3c/promela/test495.scxml28
-rw-r--r--test/w3c/promela/test496.scxml21
-rw-r--r--test/w3c/promela/test500.scxml21
-rw-r--r--test/w3c/promela/test501.scxml25
-rw-r--r--test/w3c/promela/test503.scxml43
-rw-r--r--test/w3c/promela/test504.scxml79
-rw-r--r--test/w3c/promela/test505.scxml52
-rw-r--r--test/w3c/promela/test506.scxml56
-rw-r--r--test/w3c/promela/test509.scxml24
-rw-r--r--test/w3c/promela/test510.scxml29
-rw-r--r--test/w3c/promela/test513.txt16
-rw-r--r--test/w3c/promela/test518.scxml25
-rw-r--r--test/w3c/promela/test519.scxml25
-rw-r--r--test/w3c/promela/test520.scxml27
-rw-r--r--test/w3c/promela/test521.scxml27
-rw-r--r--test/w3c/promela/test522.scxml27
-rw-r--r--test/w3c/promela/test525.scxml36
-rw-r--r--test/w3c/promela/test527.scxml28
-rw-r--r--test/w3c/promela/test528.scxml33
-rw-r--r--test/w3c/promela/test529.scxml28
-rw-r--r--test/w3c/promela/test530.scxml34
-rw-r--r--test/w3c/promela/test531.scxml26
-rw-r--r--test/w3c/promela/test532.scxml26
-rw-r--r--test/w3c/promela/test533.scxml67
-rw-r--r--test/w3c/promela/test534.scxml24
-rw-r--r--test/w3c/promela/test539.txt4
-rw-r--r--test/w3c/promela/test540.txt3
-rw-r--r--test/w3c/promela/test550.scxml23
-rw-r--r--test/w3c/promela/test551.scxml27
-rw-r--r--test/w3c/promela/test552.scxml22
-rw-r--r--test/w3c/promela/test552.txt1
-rw-r--r--test/w3c/promela/test553.scxml27
-rw-r--r--test/w3c/promela/test554.scxml31
-rw-r--r--test/w3c/promela/test557.txt4
-rw-r--r--test/w3c/promela/test558.txt3
-rw-r--r--test/w3c/promela/test567.scxml37
-rw-r--r--test/w3c/promela/test570.scxml48
-rw-r--r--test/w3c/promela/test576.scxml43
-rw-r--r--test/w3c/promela/test577.scxml25
-rw-r--r--test/w3c/promela/test579.scxml60
-rw-r--r--test/w3c/promela/test580.scxml45
-rw-r--r--test/w3c/run_promela_test.cmake23
-rw-r--r--test/w3c/txml/test307.txml2
264 files changed, 11648 insertions, 2562 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 42c21f4..56eb4fd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -349,6 +349,8 @@ else()
OPTION(BUILD_TESTS_W3C_ECMA "Create W3C ECMAScript tests" ON)
OPTION(BUILD_TESTS_W3C_XPATH "Create W3C XPath tests" ON)
OPTION(BUILD_TESTS_W3C_LUA "Create W3C Lua tests" ON)
+ OPTION(BUILD_TESTS_W3C_PROMELA "Create W3C Promela tests" ON)
+
OPTION(BUILD_TESTS_FSM_ECMA "Create FSM converted W3C ECMAScript tests" OFF)
OPTION(BUILD_TESTS_FSM_XPATH "Create FSM converted W3C XPath tests" OFF)
endif()
diff --git a/apps/uscxml-browser.cpp b/apps/uscxml-browser.cpp
index e54735e..a3c7419 100644
--- a/apps/uscxml-browser.cpp
+++ b/apps/uscxml-browser.cpp
@@ -182,7 +182,7 @@ int main(int argc, char** argv) {
try {
Interpreter interpreter = Interpreter::fromURI(documentURL);
if (interpreter) {
-
+
if (options.checking) {
std::list<InterpreterIssue> issues = interpreter.validate();
for (std::list<InterpreterIssue>::iterator issueIter = issues.begin(); issueIter != issues.end(); issueIter++) {
@@ -190,7 +190,7 @@ int main(int argc, char** argv) {
}
}
-
+
interpreter.setCmdLineOptions(options.additionalParameters);
interpreter.setCmdLineOptions(currOptions->additionalParameters);
interpreter.setCapabilities(options.getCapabilities());
diff --git a/contrib/cmake/FindSWI.cmake b/contrib/cmake/FindSWI.cmake
index f89f705..51cfe82 100644
--- a/contrib/cmake/FindSWI.cmake
+++ b/contrib/cmake/FindSWI.cmake
@@ -53,7 +53,9 @@ if (SWI_FOUND)
FIND_PROGRAM(SWI_BINARY swipl)
FIND_PATH(SWI_CPP_INCLUDE_DIR SWI-cpp.h
- PATHS ${SWI_INCLUDE_DIRS}
+ PATHS
+ ${SWI_INCLUDE_DIRS}
+ ${PROJECT_SOURCE_DIR}/contrib/src/swi-pl
)
else()
@@ -136,7 +138,9 @@ else()
PATH_SUFFIXES
packages/cpp
lib/swipl-${SWI_VERSION}/include
- PATHS ${SWI_SEARCH_PATHS}
+ PATHS
+ ${SWI_SEARCH_PATHS}
+ ${PROJECT_SOURCE_DIR}/contrib/src/swi-pl
)
#message("SWI_CPP_INCLUDE_DIR: ${SWI_CPP_INCLUDE_DIR}")
@@ -186,15 +190,23 @@ endif()
#message(FATAL_ERROR "SWI_BINARY: ${SWI_BINARY} / SWI_LIBRARY_RELEASE: ${SWI_LIBRARY_RELEASE} / SWI_LIBRARY_DEBUG: ${SWI_LIBRARY_DEBUG} / SWI_INCLUDE_DIR: ${SWI_INCLUDE_DIR} / SWI_CPP_INCLUDE_DIR: ${SWI_CPP_INCLUDE_DIR}")
INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(SWI DEFAULT_MSG SWI_LIBRARY SWI_BINARY SWI_INCLUDE_DIR)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SWI DEFAULT_MSG SWI_LIBRARY SWI_BINARY SWI_INCLUDE_DIR SWI_CPP_INCLUDE_DIR)
if (SWI_FOUND)
include(CheckCXXSourceCompiles)
- set(CMAKE_REQUIRED_INCLUDES ${SWI_INCLUDE_DIR})
+ set(CMAKE_REQUIRED_INCLUDES ${SWI_INCLUDE_DIR} ${SWI_CPP_INCLUDE_DIR})
+
set(CMAKE_REQUIRED_LIBRARIES ${SWI_LIBRARY})
+ # check for new reinterpret_cast<void (*)()>(f) for foreign functions with in SWI 7.x and above
+ check_cxx_source_compiles("
+ #include <SWI-cpp.h>
+ int main(){
+ }
+ " SWI_REINTERPRET_FOREIGN)
+
check_cxx_source_compiles("
#include <SWI-Prolog.h>
int main(){
diff --git a/contrib/src/swi-pl/SWI-cpp.h b/contrib/src/swi-pl/SWI-cpp.h
index d32a052..22c02a8 100644
--- a/contrib/src/swi-pl/SWI-cpp.h
+++ b/contrib/src/swi-pl/SWI-cpp.h
@@ -25,6 +25,12 @@
#ifndef _SWI_CPP_H
#define _SWI_CPP_H
+#ifdef SWI_REINTERPRET_FOREIGN
+# define PL_FOREIGN_TO_FUNCTION(f) reinterpret_cast<void (*)()>(f)
+#else
+# define PL_FOREIGN_TO_FUNCTION(f) (void *)f
+#endif
+
#include <SWI-Prolog.h>
#include <string.h>
#ifndef __APPLE__
@@ -466,23 +472,23 @@ public:
PlRegister(const char *module, const char *name, int arity,
foreign_t (f)(term_t t0, int a, control_t ctx))
- { PL_register_foreign_in_module(module, name, arity, (void *)f, PL_FA_VARARGS);
+ { PL_register_foreign_in_module(module, name, arity, PL_FOREIGN_TO_FUNCTION(f), PL_FA_VARARGS);
}
PlRegister(const char *module, const char *name, foreign_t (*f)(PlTerm a0))
- { PL_register_foreign_in_module(module, name, 1, (void *)f, 0);
+ { PL_register_foreign_in_module(module, name, 1, PL_FOREIGN_TO_FUNCTION(f), 0);
}
PlRegister(const char *module, const char *name, foreign_t (*f)(PlTerm a0, PlTerm a1))
- { PL_register_foreign_in_module(module, name, 2, (void *)f, 0);
+ { PL_register_foreign_in_module(module, name, 2, PL_FOREIGN_TO_FUNCTION(f), 0);
}
PlRegister(const char *module, const char *name, foreign_t (*f)(PlTerm a0, PlTerm a1, PlTerm a2))
- { PL_register_foreign_in_module(module, name, 3, (void *)f, 0);
+ { PL_register_foreign_in_module(module, name, 3, PL_FOREIGN_TO_FUNCTION(f), 0);
}
// for non-deterministic calls
PlRegister(const char *module, const char *name, int arity,
foreign_t (f)(term_t t0, int a, control_t ctx), short flags)
- { PL_register_foreign_in_module(module, name, arity, (void *)f, flags);
+ { PL_register_foreign_in_module(module, name, arity, PL_FOREIGN_TO_FUNCTION(f), flags);
}
};
diff --git a/src/uscxml/Convenience.h b/src/uscxml/Convenience.h
index 54e62c3..86a0b52 100644
--- a/src/uscxml/Convenience.h
+++ b/src/uscxml/Convenience.h
@@ -50,6 +50,12 @@ inline bool isNumeric( const char* pszInput, int nNumberBase) {
return (input.find_first_not_of(base.substr(0, nNumberBase + 2)) == std::string::npos);
}
+inline bool isInteger( const char* pszInput, int nNumberBase) {
+ std::string base = "-0123456789ABCDEF";
+ std::string input = pszInput;
+ return (input.find_first_not_of(base.substr(0, nNumberBase + 1)) == std::string::npos);
+}
+
inline bool iequals(const std::string& a, const std::string& b) {
// this impementation beats boost::iequals 2700ms vs 2100ms for test-performance.scxml - we don't care for non-ascii yet
unsigned int size = a.size();
diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp
index 4013c58..0333b85 100644
--- a/src/uscxml/Factory.cpp
+++ b/src/uscxml/Factory.cpp
@@ -373,7 +373,7 @@ void Factory::registerPlugins() {
VoiceXMLInvoker* invoker = new VoiceXMLInvoker();
registerInvoker(invoker);
}
-
+
{
FetchElement* element = new FetchElement();
registerExecutableContent(element);
@@ -536,7 +536,7 @@ bool Factory::hasInvoker(const std::string& type) {
}
return false;
}
-
+
boost::shared_ptr<InvokerImpl> Factory::createInvoker(const std::string& type, InterpreterImpl* interpreter) {
// do we have this type ourself?
@@ -591,7 +591,7 @@ boost::shared_ptr<DataModelImpl> Factory::createDataModel(const std::string& typ
return boost::shared_ptr<DataModelImpl>();
}
-
+
bool Factory::hasIOProcessor(const std::string& type) {
if (_ioProcessorAliases.find(type) != _ioProcessorAliases.end()) {
return true;
@@ -735,7 +735,7 @@ void EventHandlerImpl::returnEvent(Event& event, bool internal) {
event.invokeid = _invokeId;
if (event.eventType == 0)
event.eventType = (internal ? Event::INTERNAL : Event::EXTERNAL);
- if (event.origin.length() == 0)
+ if (event.origin.length() == 0 && _invokeId.length() > 0)
event.origin = "#_" + _invokeId;
if (event.origintype.length() == 0)
event.origintype = _type;
diff --git a/src/uscxml/Factory.h b/src/uscxml/Factory.h
index d81747f..45f8803 100644
--- a/src/uscxml/Factory.h
+++ b/src/uscxml/Factory.h
@@ -63,7 +63,7 @@ public:
bool hasIOProcessor(const std::string& type);
bool hasInvoker(const std::string& type);
bool hasExecutableContent(const std::string& localName, const std::string& nameSpace);
-
+
std::map<std::string, IOProcessorImpl*> getIOProcessors();
void listComponents();
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index 72bbfdb..50917f3 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -376,19 +376,19 @@ Interpreter Interpreter::fromDOM(const Arabica::DOM::Document<std::string>& dom,
tthread::lock_guard<tthread::recursive_mutex> lock(_instanceMutex);
boost::shared_ptr<INTERPRETER_IMPL> interpreterImpl = boost::shared_ptr<INTERPRETER_IMPL>(new INTERPRETER_IMPL);
Interpreter interpreter(interpreterImpl);
-
+
// *copy* the given DOM to get rid of event listeners
-
+
DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
interpreterImpl->_document = domFactory.createDocument(dom.getNamespaceURI(), "", 0);
-
+
Node<std::string> child = dom.getFirstChild();
while (child) {
Node<std::string> newNode = interpreterImpl->_document.importNode(child, true);
interpreterImpl->_document.appendChild(newNode);
child = child.getNextSibling();
}
-
+
interpreterImpl->setNameSpaceInfo(nameSpaceInfo);
interpreterImpl->setupDOM();
@@ -624,7 +624,7 @@ void InterpreterImpl::exitInterpreter() {
NodeSet<std::string> statesToExit = _configuration;
statesToExit.forward(false);
statesToExit.sort();
-
+
for (int i = 0; i < statesToExit.size(); i++) {
Arabica::XPath::NodeSet<std::string> onExitElems = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", statesToExit[i]);
for (int j = 0; j < onExitElems.size(); j++) {
@@ -643,26 +643,26 @@ void InterpreterImpl::exitInterpreter() {
_configuration = NodeSet<std::string>();
}
-
+
InterpreterState InterpreterImpl::interpret() {
InterpreterState state;
while(true) {
state = step(-1);
-
+
switch (state) {
- case uscxml::USCXML_FINISHED:
- case uscxml::USCXML_DESTROYED:
- // return as we finished
- return state;
- default:
-
- // process invokers on main thread
- if(_thread == NULL) {
- runOnMainThread(200);
- }
-
- // process next step
- break;
+ case uscxml::USCXML_FINISHED:
+ case uscxml::USCXML_DESTROYED:
+ // return as we finished
+ return state;
+ default:
+
+ // process invokers on main thread
+ if(_thread == NULL) {
+ runOnMainThread(200);
+ }
+
+ // process next step
+ break;
}
}
return state;
@@ -671,35 +671,35 @@ InterpreterState InterpreterImpl::interpret() {
// setup / fetch the documents initial transitions
NodeSet<std::string> InterpreterImpl::getDocumentInitialTransitions() {
NodeSet<std::string> initialTransitions;
-
+
if (_startConfiguration.size() > 0) {
// we emulate entering a given configuration by creating a pseudo deep history
Element<std::string> initHistory = _document.createElementNS(_nsInfo.nsURL, "history");
_nsInfo.setPrefix(initHistory);
-
+
initHistory.setAttribute("id", UUID::getUUID());
initHistory.setAttribute("type", "deep");
_scxml.insertBefore(initHistory, _scxml.getFirstChild());
-
+
std::string histId = ATTR(initHistory, "id");
NodeSet<std::string> histStates;
for (std::list<std::string>::const_iterator stateIter = _startConfiguration.begin(); stateIter != _startConfiguration.end(); stateIter++) {
histStates.push_back(getState(*stateIter));
}
_historyValue[histId] = histStates;
-
+
Element<std::string> initialElem = _document.createElementNS(_nsInfo.nsURL, "initial");
_nsInfo.setPrefix(initialElem);
-
+
initialElem.setAttribute("generated", "true");
Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition");
_nsInfo.setPrefix(transitionElem);
-
+
transitionElem.setAttribute("target", histId);
initialElem.appendChild(transitionElem);
_scxml.appendChild(initialElem);
initialTransitions.push_back(transitionElem);
-
+
} else {
// try to get initial transition from initial element
initialTransitions = _xpath.evaluate("/" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", _scxml).asNodeSet();
@@ -711,11 +711,11 @@ NodeSet<std::string> InterpreterImpl::getDocumentInitialTransitions() {
for (int i = 0; i < initialStates.size(); i++) {
Element<std::string> initialElem = _document.createElementNS(_nsInfo.nsURL, "initial");
_nsInfo.setPrefix(initialElem);
-
+
initialElem.setAttribute("generated", "true");
Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition");
_nsInfo.setPrefix(transitionElem);
-
+
transitionElem.setAttribute("target", ATTR_CAST(initialStates[i], "id"));
initialElem.appendChild(transitionElem);
_scxml.appendChild(initialElem);
@@ -729,18 +729,18 @@ NodeSet<std::string> InterpreterImpl::getDocumentInitialTransitions() {
InterpreterState InterpreterImpl::step(int waitForMS) {
try {
tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
-
+
if (_state == USCXML_FINISHED || _state == USCXML_DESTROYED) {
return _state;
}
-
+
NodeSet<std::string> enabledTransitions;
-
+
// setup document and interpreter
if (!_isInitialized) {
init(); // will throw
}
-
+
if (_configuration.size() == 0) {
// goto initial configuration
NodeSet<std::string> initialTransitions = getDocumentInitialTransitions();
@@ -756,9 +756,9 @@ InterpreterState InterpreterImpl::step(int waitForMS) {
enterStates(initialTransitions);
setInterpreterState(USCXML_MICROSTEPPED);
}
-
+
assert(isLegalConfiguration(_configuration));
-
+
// are there spontaneous transitions?
if (!_stable) {
enabledTransitions = selectEventlessTransitions();
@@ -766,16 +766,16 @@ InterpreterState InterpreterImpl::step(int waitForMS) {
// test 403b
enabledTransitions.to_document_order();
microstep(enabledTransitions);
-
+
setInterpreterState(USCXML_MICROSTEPPED);
-
+
// check whether we run in cycles
FlatStateIdentifier flat(_configuration, _alreadyEntered, _historyValue);
if (_microstepConfigurations.find(flat.getStateId()) != _microstepConfigurations.end()) {
USCXML_MONITOR_CALLBACK2(reportIssue,
- InterpreterIssue("Reentering during microstep " + flat.getFlatActive() + " - possible endless loop",
- Arabica::DOM::Node<std::string>(),
- InterpreterIssue::USCXML_ISSUE_WARNING));
+ InterpreterIssue("Reentering during microstep " + flat.getFlatActive() + " - possible endless loop",
+ Arabica::DOM::Node<std::string>(),
+ InterpreterIssue::USCXML_ISSUE_WARNING));
}
_microstepConfigurations.insert(flat.getStateId());
@@ -783,46 +783,46 @@ InterpreterState InterpreterImpl::step(int waitForMS) {
}
_stable = true;
}
-
+
// test415
if (_topLevelFinalReached)
goto EXIT_INTERPRETER;
-
+
// process internal event
if (!_internalQueue.empty()) {
_currEvent = _internalQueue.front();
_internalQueue.pop_front();
_stable = false;
-
+
USCXML_MONITOR_CALLBACK2(beforeProcessingEvent, _currEvent)
-
+
_dataModel.setEvent(_currEvent);
enabledTransitions = selectTransitions(_currEvent.name);
-
+
if (!enabledTransitions.empty()) {
// test 403b
enabledTransitions.to_document_order();
microstep(enabledTransitions);
}
-
+
// test 319 - even if we do not enable transitions, consider it a microstep
setInterpreterState(USCXML_MICROSTEPPED);
return _state;
-
+
} else {
_stable = true;
_microstepConfigurations.clear();
}
-
+
if (_state != USCXML_MACROSTEPPED && _state != USCXML_IDLE)
USCXML_MONITOR_CALLBACK(onStableConfiguration)
-
+
setInterpreterState(USCXML_MACROSTEPPED);
-
+
if (_topLevelFinalReached)
goto EXIT_INTERPRETER;
-
-
+
+
// when we reach a stable configuration, invoke
for (unsigned int i = 0; i < _statesToInvoke.size(); i++) {
NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]);
@@ -834,17 +834,17 @@ InterpreterState InterpreterImpl::step(int waitForMS) {
}
}
_statesToInvoke = NodeSet<std::string>();
-
+
if (_externalQueue.isEmpty()) {
setInterpreterState(USCXML_IDLE);
-
+
if (waitForMS < 0) {
// wait blockingly for an event forever
while(_externalQueue.isEmpty()) {
_condVar.wait(_mutex);
}
}
-
+
if (waitForMS > 0) {
// wait given number of milliseconds max
uint64_t now = tthread::chrono::system_clock::now();
@@ -854,35 +854,35 @@ InterpreterState InterpreterImpl::step(int waitForMS) {
now = tthread::chrono::system_clock::now();
}
}
-
+
if (_externalQueue.isEmpty()) {
return _state;
}
-
+
setInterpreterState(USCXML_MACROSTEPPED);
}
-
+
_currEvent = _externalQueue.pop();
_currEvent.eventType = Event::EXTERNAL; // make sure it is set to external
_stable = false;
-
+
if (_topLevelFinalReached)
goto EXIT_INTERPRETER;
-
+
USCXML_MONITOR_CALLBACK2(beforeProcessingEvent, _currEvent)
-
+
if (iequals(_currEvent.name, "cancel.invoke." + _sessionId)) {
goto EXIT_INTERPRETER;
}
-
+
try {
_dataModel.setEvent(_currEvent);
} catch (Event e) {
LOG(ERROR) << "Syntax error while setting external event:" << std::endl << e << std::endl << _currEvent;
}
-
+
finalizeAndAutoForwardCurrentEvent();
-
+
// run internal processing until we reach a stable configuration again
enabledTransitions = selectTransitions(_currEvent.name);
if (!enabledTransitions.empty()) {
@@ -890,15 +890,15 @@ InterpreterState InterpreterImpl::step(int waitForMS) {
enabledTransitions.to_document_order();
microstep(enabledTransitions);
}
-
+
if (_topLevelFinalReached)
goto EXIT_INTERPRETER;
-
+
return _state;
-
- EXIT_INTERPRETER:
+
+EXIT_INTERPRETER:
USCXML_MONITOR_CALLBACK(beforeCompletion)
-
+
exitInterpreter();
if (_sendQueue) {
std::map<std::string, std::pair<InterpreterImpl*, SendRequest> >::iterator sendIter = _sendIds.begin();
@@ -907,16 +907,16 @@ InterpreterState InterpreterImpl::step(int waitForMS) {
sendIter++;
}
}
-
+
USCXML_MONITOR_CALLBACK(afterCompletion)
-
+
// assert(hasLegalConfiguration());
_mutex.unlock();
-
+
// remove datamodel
if(!_userSuppliedDataModel)
_dataModel = DataModel();
-
+
setInterpreterState(USCXML_FINISHED);
return _state;
} catch (boost::bad_weak_ptr e) {
@@ -924,41 +924,41 @@ InterpreterState InterpreterImpl::step(int waitForMS) {
setInterpreterState(USCXML_DESTROYED);
return _state;
}
-
+
// set datamodel to null from this thread
if(_dataModel)
_dataModel = DataModel();
-
+
}
void InterpreterImpl::microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
-
+
USCXML_MONITOR_CALLBACK(beforeMicroStep)
-
+
exitStates(enabledTransitions);
-
+
for (int i = 0; i < enabledTransitions.size(); i++) {
Element<std::string> transition(enabledTransitions[i]);
-
+
USCXML_MONITOR_CALLBACK3(beforeTakingTransition, transition, (i + 1 < enabledTransitions.size()))
-
+
executeContent(transition);
-
+
USCXML_MONITOR_CALLBACK3(afterTakingTransition, transition, (i + 1 < enabledTransitions.size()))
}
-
+
enterStates(enabledTransitions);
-
+
USCXML_MONITOR_CALLBACK(afterMicroStep)
-
+
}
// process transitions until we are in a stable configuration again
void InterpreterImpl::stabilize() {
-
+
NodeSet<std::string> enabledTransitions;
_stable = false;
-
+
if (_configuration.size() == 0) {
// goto initial configuration
NodeSet<std::string> initialTransitions = getDocumentInitialTransitions();
@@ -967,11 +967,11 @@ void InterpreterImpl::stabilize() {
}
std::set<std::string> configurationsSeen;
-
+
do { // process microsteps for enabled transitions until there are no more left
-
+
enabledTransitions = selectEventlessTransitions();
-
+
if (enabledTransitions.size() == 0) {
if (_internalQueue.size() == 0) {
_stable = true;
@@ -981,24 +981,24 @@ void InterpreterImpl::stabilize() {
#if VERBOSE
std::cout << "Received internal event " << _currEvent.name << std::endl;
#endif
-
+
USCXML_MONITOR_CALLBACK2(beforeProcessingEvent, _currEvent)
-
+
if (_dataModel)
_dataModel.setEvent(_currEvent);
enabledTransitions = selectTransitions(_currEvent.name);
}
}
-
+
if (!enabledTransitions.empty()) {
// test 403b
enabledTransitions.to_document_order();
microstep(enabledTransitions);
}
} while(!_internalQueue.empty() || !_stable);
-
+
USCXML_MONITOR_CALLBACK(onStableConfiguration)
-
+
// when we reach a stable configuration, invoke
for (unsigned int i = 0; i < _statesToInvoke.size(); i++) {
NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]);
@@ -1014,14 +1014,14 @@ void InterpreterImpl::stabilize() {
Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectTransitions(const std::string& event) {
Arabica::XPath::NodeSet<std::string> enabledTransitions;
-
+
NodeSet<std::string> states;
for (unsigned int i = 0; i < _configuration.size(); i++) {
if (isAtomic(Element<std::string>(_configuration[i])))
states.push_back(_configuration[i]);
}
states.to_document_order();
-
+
unsigned int index = 0;
while(states.size() > index) {
NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", states[index]);
@@ -1037,25 +1037,25 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectTransitions(const st
states.push_back(parent);
}
}
- LOOP:
+LOOP:
index++;
}
-
+
enabledTransitions = removeConflictingTransitions(enabledTransitions);
return enabledTransitions;
}
-
-
+
+
Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectEventlessTransitions() {
Arabica::XPath::NodeSet<std::string> enabledTransitions;
-
+
NodeSet<std::string> states;
for (unsigned int i = 0; i < _configuration.size(); i++) {
if (isAtomic(Element<std::string>(_configuration[i])))
states.push_back(_configuration[i]);
}
states.to_document_order();
-
+
unsigned int index = 0;
while(states.size() > index) {
bool foundTransition = false;
@@ -1074,10 +1074,10 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectEventlessTransitions
states.push_back(parent);
}
}
- LOOP:
+LOOP:
index++;
}
-
+
#if VERBOSE
std::cout << "Enabled eventless transitions: " << std::endl;
for (int i = 0; i < enabledTransitions.size(); i++) {
@@ -1085,7 +1085,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectEventlessTransitions
}
std::cout << std::endl;
#endif
-
+
enabledTransitions = removeConflictingTransitions(enabledTransitions);
return enabledTransitions;
}
@@ -1105,7 +1105,7 @@ bool InterpreterImpl::isEnabledTransition(const Element<std::string>& transition
} else {
return false;
}
-
+
std::list<std::string> eventNames = tokenizeIdRefs(eventName);
std::list<std::string>::iterator eventIter = eventNames.begin();
while(eventIter != eventNames.end()) {
@@ -1117,7 +1117,7 @@ bool InterpreterImpl::isEnabledTransition(const Element<std::string>& transition
return false;
}
-
+
InterpreterState InterpreterImpl::getInterpreterState() {
return _state;
}
@@ -1217,19 +1217,19 @@ std::list<InterpreterIssue> InterpreterImpl::validate() {
std::ostream& operator<< (std::ostream& os, const InterpreterIssue& issue) {
switch (issue.severity) {
- case InterpreterIssue::USCXML_ISSUE_FATAL:
- os << "Issue (FATAL) ";
- break;
- case InterpreterIssue::USCXML_ISSUE_WARNING:
- os << "Issue (WARNING) ";
- break;
- case InterpreterIssue::USCXML_ISSUE_INFO:
- os << "Issue (INFO) ";
- break;
- default:
- break;
+ case InterpreterIssue::USCXML_ISSUE_FATAL:
+ os << "Issue (FATAL) ";
+ break;
+ case InterpreterIssue::USCXML_ISSUE_WARNING:
+ os << "Issue (WARNING) ";
+ break;
+ case InterpreterIssue::USCXML_ISSUE_INFO:
+ os << "Issue (INFO) ";
+ break;
+ default:
+ break;
}
-
+
if (issue.xPath.size() > 0) {
os << "at " << issue.xPath << ": ";
} else {
@@ -1262,7 +1262,7 @@ void InterpreterImpl::setupDOM() {
_scxml = (Arabica::DOM::Element<std::string>)scxmls.item(0);
}
-
+
if (_nsInfo.getNSContext() != NULL)
_xpath.setNamespaceContext(*_nsInfo.getNSContext());
@@ -1675,7 +1675,7 @@ void InterpreterImpl::send(const Arabica::DOM::Element<std::string>& element) {
*/
sendReq.sendid = ATTR(getParentState(element), "id") + "." + UUID::getUUID();
if (HAS_ATTR(element, "idlocation")) {
- _dataModel.assign(ATTR(element, "idlocation"), Data("'" + sendReq.sendid + "'", Data::INTERPRETED));
+ _dataModel.assign(ATTR(element, "idlocation"), Data(sendReq.sendid, Data::VERBATIM));
} else {
sendReq.hideSendId = true;
}
@@ -1710,7 +1710,7 @@ void InterpreterImpl::send(const Arabica::DOM::Element<std::string>& element) {
LOG(ERROR) << "Syntax error in send element " << DOMUtils::xPathForNode(element) << " delayexpr:" << std::endl << e << std::endl;
return;
}
-
+
try {
// namelist
if (HAS_ATTR(element, "namelist")) {
@@ -1853,9 +1853,13 @@ void InterpreterImpl::invoke(const Arabica::DOM::Element<std::string>& element)
if (HAS_ATTR(element, "id")) {
invokeReq.invokeid = ATTR(element, "id");
} else {
- invokeReq.invokeid = ATTR(getParentState(element), "id") + "." + UUID::getUUID();
+ if (HAS_ATTR(_scxml, "flat") && DOMUtils::attributeIsTrue(ATTR(_scxml, "flat")) && HAS_ATTR(element, "parent")) {
+ invokeReq.invokeid = ATTR(element, "parent") + "." + UUID::getUUID();
+ } else {
+ invokeReq.invokeid = ATTR(getParentState(element), "id") + "." + UUID::getUUID();
+ }
if (HAS_ATTR(element, "idlocation")) {
- _dataModel.assign(ATTR(element, "idlocation"), Data("'" + invokeReq.invokeid + "'", Data::INTERPRETED));
+ _dataModel.assign(ATTR(element, "idlocation"), Data(invokeReq.invokeid, Data::VERBATIM));
}
}
} catch (Event e) {
@@ -2004,7 +2008,8 @@ void InterpreterImpl::cancelInvoke(const Arabica::DOM::Element<std::string>& ele
if (_invokers.find(invokeId) != _invokers.end()) {
LOG(INFO) << "Removed invoker at " << invokeId;
try {
- _dataModel.assign("_invokers['" + invokeId + "']", Data(std::string("''"), Data::INTERPRETED));
+ // TODO: this is datamodel specific!
+ //_dataModel.assign("_invokers['" + invokeId + "']", Data(std::string("''"), Data::INTERPRETED));
} catch (Event e) {
LOG(ERROR) << "Syntax when removing invoker:" << std::endl << e << std::endl;
}
@@ -2562,28 +2567,28 @@ Arabica::DOM::Node<std::string> InterpreterImpl::findLCCA(const Arabica::XPath::
}
std::cout << std::endl << std::flush;
#endif
-
+
Arabica::XPath::NodeSet<std::string> ancestors = getProperAncestors(states[0], Arabica::DOM::Node<std::string>());
Arabica::DOM::Node<std::string> ancestor;
-
+
for (int i = 0; i < ancestors.size(); i++) {
if (!isCompound(Element<std::string>(ancestors[i])))
continue;
for (int j = 0; j < states.size(); j++) {
-
+
#if VERBOSE_FIND_LCCA
std::cout << "Checking " << ATTR_CAST(states[j], "id") << " and " << ATTR_CAST(ancestors[i], "id") << std::endl;
#endif
-
+
if (!isDescendant(states[j], ancestors[i]))
goto NEXT_ANCESTOR;
}
ancestor = ancestors[i];
break;
- NEXT_ANCESTOR:
+NEXT_ANCESTOR:
;
}
-
+
// take uppermost root as ancestor
if (!ancestor)
ancestor = _scxml;
@@ -2681,13 +2686,13 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::getInitialStates(Arabica::
if (isAtomic(state)) {
return Arabica::XPath::NodeSet<std::string>();
}
-
+
assert(isCompound(state) || isParallel(state));
if (isParallel(state)) {
return getChildStates(state);
}
-
+
// initial attribute at element
Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state;
if (stateElem.hasAttribute("initial")) {
@@ -2873,7 +2878,10 @@ NodeSet<std::string> InterpreterImpl::filterChildElements(const std::string& tag
NodeSet<std::string> InterpreterImpl::filterChildType(const Node_base::Type type, const NodeSet<std::string>& nodeSet, bool recurse) {
NodeSet<std::string> filteredChildType;
for (unsigned int i = 0; i < nodeSet.size(); i++) {
- filteredChildType.push_back(filterChildType(type, nodeSet[i], recurse));
+ if (nodeSet[i].getNodeType() == type)
+ filteredChildType.push_back(nodeSet[i]);
+ if (recurse)
+ filteredChildType.push_back(filterChildType(type, nodeSet[i], recurse));
}
return filteredChildType;
}
@@ -3212,8 +3220,8 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet<std::string>& config) {
}
}
-
-
+
+
// When the configuration contains an atomic state, it contains all of its <state> and <parallel> ancestors.
for (int i = 0; i < config.size(); i++) {
if (isAtomic(Element<std::string>(config[i]))) {
diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h
index 7732bfb..4b6d26a 100644
--- a/src/uscxml/Interpreter.h
+++ b/src/uscxml/Interpreter.h
@@ -518,7 +518,7 @@ protected:
InterpreterWebSocketServlet* _wsServlet;
std::set<InterpreterMonitor*> _monitors;
std::set<std::string> _microstepConfigurations;
-
+
long _lastRunOnMainThread;
std::string _name;
std::string _sessionId;
@@ -635,7 +635,7 @@ public:
std::list<InterpreterIssue> validate() {
return _impl->validate();
}
-
+
InterpreterState getState() {
return _impl->getInterpreterState();
}
@@ -838,7 +838,7 @@ public:
virtual void afterCompletion(Interpreter interpreter) {}
virtual void reportIssue(Interpreter interpreter, const InterpreterIssue& issue) {}
-
+
};
}
diff --git a/src/uscxml/debug/InterpreterIssue.cpp b/src/uscxml/debug/InterpreterIssue.cpp
index fedb40f..3e207e9 100644
--- a/src/uscxml/debug/InterpreterIssue.cpp
+++ b/src/uscxml/debug/InterpreterIssue.cpp
@@ -36,7 +36,7 @@ InterpreterIssue::InterpreterIssue(const std::string& msg, Arabica::DOM::Node<st
if (node)
xPath = DOMUtils::xPathForNode(node);
}
-
+
// find all elements in the SCXML namespace in one traversal
void assembleNodeSets(const std::string nsPrefix, const Node<std::string>& node, std::map<std::string, NodeSet<std::string> >& sets) {
NodeList<std::string> childs = node.getChildNodes();
@@ -60,10 +60,10 @@ NodeSet<std::string> getReachableStates(const Node<std::string>& scxml, Interpre
reachable.push_back(scxml);
bool hasChanges = true;
-
+
while (hasChanges) {
// iterate initials and transitions until stable
-
+
hasChanges = false;
// reachable per initial attribute or document order - size will increase as we append new states
for (int i = 0; i < reachable.size(); i++) {
@@ -81,7 +81,7 @@ NodeSet<std::string> getReachableStates(const Node<std::string>& scxml, Interpre
} catch (Event e) {
}
}
-
+
// reachable per target attribute in transitions
for (int i = 0; i < reachable.size(); i++) {
Element<std::string> state = Element<std::string>(reachable[i]);
@@ -102,7 +102,7 @@ NodeSet<std::string> getReachableStates(const Node<std::string>& scxml, Interpre
}
}
}
-
+
// reachable via a reachable child state
for (int i = 0; i < reachable.size(); i++) {
Element<std::string> state = Element<std::string>(reachable[i]);
@@ -121,17 +121,17 @@ NodeSet<std::string> getReachableStates(const Node<std::string>& scxml, Interpre
}
}
}
-
+
return reachable;
}
-
+
std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* interpreter) {
// some things we need to prepare first
if (interpreter->_factory == NULL)
interpreter->_factory = Factory::getInstance();
interpreter->setupDOM();
-
+
std::list<InterpreterIssue> issues;
if (!interpreter->_scxml) {
@@ -141,23 +141,23 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
}
std::map<std::string, Arabica::DOM::Element<std::string> > seenStates;
-
+
// get some aliases
Element<std::string>& _scxml = interpreter->_scxml;
NameSpaceInfo& _nsInfo = interpreter->_nsInfo;
Factory* _factory = interpreter->_factory;
DataModel& _dataModel = interpreter->_dataModel;
-
-
+
+
std::map<std::string, NodeSet<std::string> > nodeSets;
assembleNodeSets(_nsInfo.xmlNSPrefix, _scxml, nodeSets);
-
-
+
+
NodeSet<std::string> scxmls = nodeSets["scxml"];
scxmls.push_back(_scxml);
NodeSet<std::string> reachable = getReachableStates(_scxml, interpreter, _nsInfo.xmlNSPrefix);
-
+
NodeSet<std::string>& states = nodeSets["state"];
NodeSet<std::string>& parallels = nodeSets["parallel"];
NodeSet<std::string>& transitions = nodeSets["transition"];
@@ -298,13 +298,13 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
}
}
-
+
for (int i = 0; i < allStates.size(); i++) {
Element<std::string> state = Element<std::string>(allStates[i]);
-
+
if (InterpreterImpl::isMember(state, finals) && !HAS_ATTR(state, "id")) // id is not required for finals
continue;
-
+
// check for existance of id attribute
if (!HAS_ATTR(state, "id")) {
issues.push_back(InterpreterIssue("State has no 'id' attribute", state, InterpreterIssue::USCXML_ISSUE_FATAL));
@@ -317,7 +317,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
}
-
+
// check for uniqueness of id attribute
if (seenStates.find(stateId) != seenStates.end()) {
issues.push_back(InterpreterIssue("Duplicate state with id '" + stateId + "'", state, InterpreterIssue::USCXML_ISSUE_FATAL));
@@ -325,10 +325,10 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
}
seenStates[ATTR(state, "id")] = state;
}
-
+
for (int i = 0; i < transitions.size(); i++) {
Element<std::string> transition = Element<std::string>(transitions[i]);
-
+
// check for valid target
std::list<std::string> targetIds = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "target"));
for (std::list<std::string>::iterator targetIter = targetIds.begin(); targetIter != targetIds.end(); targetIter++) {
@@ -345,7 +345,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
NodeSet<std::string> transitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", state, false);
transitions.to_document_order();
-
+
for (int j = 1; j < transitions.size(); j++) {
Element<std::string> transition = Element<std::string>(transitions[j]);
for (int k = 0; k < j; k++) {
@@ -358,7 +358,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
// earlier transition is eventless
issues.push_back(InterpreterIssue("Transition can never be optimally enabled", transition, InterpreterIssue::USCXML_ISSUE_INFO));
goto NEXT_TRANSITION;
-
+
} else if (HAS_ATTR(transition, "event")) {
// does the earlier transition match all our events?
std::list<std::string> events = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "event"));
@@ -370,7 +370,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
break;
}
}
-
+
if (allMatched) {
issues.push_back(InterpreterIssue("Transition can never be optimally enabled", transition, InterpreterIssue::USCXML_ISSUE_INFO));
goto NEXT_TRANSITION;
@@ -378,7 +378,8 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
}
}
}
- NEXT_TRANSITION:;
+NEXT_TRANSITION:
+ ;
}
}
@@ -410,7 +411,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
// unknown at factory - adhoc extension?
if (HAS_ATTR(invoke, "id") && interpreter->_invokers.find(ATTR(invoke, "id")) != interpreter->_invokers.end())
continue; // not an issue
-
+
IssueSeverity severity;
if (HAS_ATTR(invoke, "idlocation")) {
// we might still resolve at runtime
@@ -438,7 +439,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
}
}
}
-
+
// check that all custom executable content is known
{
NodeSet<std::string> allExecContentContainers;
@@ -446,7 +447,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
allExecContentContainers.push_back(onExits);
allExecContentContainers.push_back(transitions);
allExecContentContainers.push_back(finalizes);
-
+
for (int i = 0; i < allExecContentContainers.size(); i++) {
Element<std::string> block = Element<std::string>(allExecContentContainers[i]);
NodeSet<std::string> execContents = InterpreterImpl::filterChildType(Node_base::ELEMENT_NODE, block);
@@ -473,7 +474,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
issues.push_back(InterpreterIssue("Parent of " + localName + " is no element", element, InterpreterIssue::USCXML_ISSUE_WARNING));
continue;
}
-
+
Element<std::string> parent = Element<std::string>(element.getParentNode());
std::string parentName = LOCALNAME(parent);
@@ -490,13 +491,13 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
if (HAS_ATTR(_scxml, "datamodel")) {
if (!_factory->hasDataModel(ATTR(_scxml, "datamodel"))) {
issues.push_back(InterpreterIssue("SCXML document requires unknown datamodel '" + ATTR(_scxml, "datamodel") + "'", _scxml, InterpreterIssue::USCXML_ISSUE_FATAL));
-
+
// we cannot even check the rest as we require a datamodel
return issues;
}
}
}
-
+
bool instantiatedDataModel = false;
// instantiate datamodel if not explicitly set
if (!_dataModel) {
@@ -509,12 +510,12 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
}
}
-
+
// test all scripts for valid syntax
{
for (int i = 0; i < scripts.size(); i++) {
Element<std::string> script = Element<std::string>(scripts[i]);
-
+
if (script.hasChildNodes()) {
// search for the text node with the actual script
std::string scriptContent;
@@ -522,7 +523,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
if (child.getNodeType() == Node_base::TEXT_NODE || child.getNodeType() == Node_base::CDATA_SECTION_NODE)
scriptContent += child.getNodeValue();
}
-
+
if (!_dataModel.isValidSyntax(scriptContent)) {
issues.push_back(InterpreterIssue("Syntax error in script", script, InterpreterIssue::USCXML_ISSUE_WARNING));
}
@@ -536,7 +537,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
withCondAttrs.push_back(transitions);
withCondAttrs.push_back(ifs);
withCondAttrs.push_back(elseIfs);
-
+
for (int i = 0; i < withCondAttrs.size(); i++) {
Element<std::string> condAttr = Element<std::string>(withCondAttrs[i]);
if (HAS_ATTR(condAttr, "cond")) {
@@ -555,7 +556,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
withExprAttrs.push_back(assigns);
withExprAttrs.push_back(contents);
withExprAttrs.push_back(params);
-
+
for (int i = 0; i < withExprAttrs.size(); i++) {
Element<std::string> withExprAttr = Element<std::string>(withExprAttrs[i]);
if (HAS_ATTR(withExprAttr, "expr")) {
diff --git a/src/uscxml/debug/InterpreterIssue.h b/src/uscxml/debug/InterpreterIssue.h
index 3949829..c49233f 100644
--- a/src/uscxml/debug/InterpreterIssue.h
+++ b/src/uscxml/debug/InterpreterIssue.h
@@ -27,7 +27,7 @@
namespace uscxml {
class InterpreterImpl;
-
+
class USCXML_API InterpreterIssue {
public:
enum IssueSeverity {
@@ -35,14 +35,14 @@ public:
USCXML_ISSUE_WARNING,
USCXML_ISSUE_INFO
};
-
+
InterpreterIssue(const std::string& msg, Arabica::DOM::Node<std::string> node, IssueSeverity severity);
std::string xPath;
std::string message;
Arabica::DOM::Node<std::string> node;
IssueSeverity severity;
-
+
private:
static std::list<InterpreterIssue> forInterpreter(InterpreterImpl* interpreter);
friend class InterpreterImpl;
diff --git a/src/uscxml/debug/SCXMLDotWriter.cpp b/src/uscxml/debug/SCXMLDotWriter.cpp
index 5c15dbd..4f0143f 100644
--- a/src/uscxml/debug/SCXMLDotWriter.cpp
+++ b/src/uscxml/debug/SCXMLDotWriter.cpp
@@ -456,11 +456,11 @@ void SCXMLDotWriter::writePerEventPorts(std::ostream& os, const DotState& dotSta
std::string SCXMLDotWriter::htmlLabelForId(const std::string& stateId, int minRows) {
FlatStateIdentifier flatId(stateId);
-
+
std::list<std::string>::const_iterator listIter;
std::stringstream labelSS;
std::string seperator;
-
+
labelSS << "<b>active: </b>";
labelSS << "{";
for (listIter = flatId.getActive().begin(); listIter != flatId.getActive().end(); listIter++) {
@@ -468,12 +468,12 @@ std::string SCXMLDotWriter::htmlLabelForId(const std::string& stateId, int minRo
seperator = ", ";
}
labelSS << "}";
-
+
if (flatId.getVisited().size() > 0) {
minRows--;
-
+
labelSS << "<br /><b>init: </b>";
-
+
labelSS << "{";
seperator = "";
for (listIter = flatId.getVisited().begin(); listIter != flatId.getVisited().end(); listIter++) {
@@ -482,19 +482,19 @@ std::string SCXMLDotWriter::htmlLabelForId(const std::string& stateId, int minRo
}
labelSS << "}";
}
-
+
if (flatId.getHistory().size() > 0) {
minRows--;
-
+
seperator = "";
std::string histSeperator = "<br /> ";
-
+
labelSS << "<br /><b>history: </b>";
-
+
std::map<std::string, std::list<std::string> >::const_iterator histIter;
for (histIter = flatId.getHistory().begin(); histIter != flatId.getHistory().end(); histIter++) {
labelSS << histSeperator << histIter->first << ": {";
-
+
for (listIter = histIter->second.begin(); listIter != histIter->second.end(); listIter++) {
labelSS << seperator << *listIter;
seperator = ", ";
@@ -506,7 +506,7 @@ std::string SCXMLDotWriter::htmlLabelForId(const std::string& stateId, int minRo
return labelSS.str();
}
-
+
void SCXMLDotWriter::writePerTargetPorts(std::ostream& os, const DotState& dotState, int stateLines) {
// std::multimap<std::string, Arabica::DOM::Element<std::string> > targets; // key is remote node, transition is element
diff --git a/src/uscxml/debug/SCXMLDotWriter.h b/src/uscxml/debug/SCXMLDotWriter.h
index 04cd0fd..f6c8b3d 100644
--- a/src/uscxml/debug/SCXMLDotWriter.h
+++ b/src/uscxml/debug/SCXMLDotWriter.h
@@ -131,7 +131,7 @@ public:
virtual void beforeMicroStep(Interpreter interpreter);
static std::string htmlLabelForId(const std::string& stateId, int minRows = 0);
-
+
static void toDot(const std::string& filename,
Interpreter interpreter,
const Arabica::DOM::Element<std::string>& transition = Arabica::DOM::Element<std::string>()) {
diff --git a/src/uscxml/interpreter/InterpreterRC.cpp b/src/uscxml/interpreter/InterpreterRC.cpp
index d976244..8f16cb0 100644
--- a/src/uscxml/interpreter/InterpreterRC.cpp
+++ b/src/uscxml/interpreter/InterpreterRC.cpp
@@ -45,17 +45,16 @@ std::string getPadding() {
return pad;
}
#endif
-
+
Arabica::XPath::NodeSet<std::string> InterpreterRC::removeConflictingTransitions(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
Arabica::XPath::NodeSet<std::string> filteredTransitions;
-
for (unsigned int i = 0; i < enabledTransitions.size(); i++) {
Element<std::string> t1(enabledTransitions[i]);
bool t1Preempted = false;
Arabica::XPath::NodeSet<std::string> transitionsToRemove;
for (unsigned int j = 0; j < filteredTransitions.size(); j++) {
- Element<std::string> t2(enabledTransitions[j]);
+ Element<std::string> t2(filteredTransitions[j]);
if (hasIntersection(computeExitSet(t1), computeExitSet(t2))) {
if (isDescendant(getSourceState(t1), getSourceState(t2))) {
transitionsToRemove.push_back(t2);
@@ -152,7 +151,10 @@ void InterpreterRC::exitStates(const Arabica::XPath::NodeSet<std::string>& enabl
NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToExit[i]);
for (int j = 0; j < invokes.size(); j++) {
Element<std::string> invokeElem = (Element<std::string>)invokes[j];
- cancelInvoke(invokeElem);
+ if (HAS_ATTR(invokeElem, "persist") && DOMUtils::attributeIsTrue(ATTR(invokeElem, "persist"))) {
+ } else {
+ cancelInvoke(invokeElem);
+ }
}
// remove statesToExit[i] from _configuration - test409
@@ -259,7 +261,25 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab
}
USCXML_MONITOR_CALLBACK3(afterEnteringState, s, i + 1 < statesToEnter.size())
-
+
+ if (HAS_ATTR(_scxml, "flat") && DOMUtils::attributeIsTrue(ATTR(_scxml, "flat"))) {
+ // extension for flattened interpreters
+ NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", s);
+ for (unsigned int j = 0; j < invokes.size(); j++) {
+ Element<std::string> invokeElem = Element<std::string>(invokes[j]);
+ if (HAS_ATTR(invokeElem, "persist") && DOMUtils::attributeIsTrue(ATTR(invokeElem, "persist"))) {
+ invoke(invokeElem);
+ }
+ }
+
+ // extension for flattened SCXML documents, we will need an explicit uninvoke element
+ NodeSet<std::string> uninvokes = filterChildElements(_nsInfo.xmlNSPrefix + "uninvoke", s);
+ for (int j = 0; j < uninvokes.size(); j++) {
+ Element<std::string> uninvokeElem = (Element<std::string>)uninvokes[j];
+ cancelInvoke(uninvokeElem);
+ }
+ }
+
// std::cout << "HIST?: " << ATTR(s, "id") << std::endl;
if (defaultHistoryContent.find(ATTR(s, "id")) != defaultHistoryContent.end()) {
executeContent(Element<std::string>(defaultHistoryContent[ATTR(s, "id")]));
@@ -311,14 +331,14 @@ void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet<std::string>&
// add all descendants in a dedicated first step
for (int i = 0; i < transitions.size(); i++) {
Element<std::string> t(transitions[i]);
-
+
NodeSet<std::string> targets = getTargetStates(t);
for (int j = 0; j < targets.size(); j++) {
Element<std::string> s = Element<std::string>(targets[j]);
addDescendantStatesToEnter(s, statesToEnter, statesForDefaultEntry, defaultHistoryContent);
}
}
-
+
// only now add the ancestors
for (int i = 0; i < transitions.size(); i++) {
Element<std::string> t(transitions[i]);
@@ -349,7 +369,7 @@ function getEffectiveTargetStates(transition)
Arabica::XPath::NodeSet<std::string> InterpreterRC::getEffectiveTargetStates(const Arabica::DOM::Element<std::string>& transition) {
NodeSet<std::string> effectiveTargets;
-
+
NodeSet<std::string> targets;
if (isState(transition)) {
targets = getInitialStates(transition);
@@ -357,7 +377,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::getEffectiveTargetStates(con
} else {
targets = getTargetStates(transition);
}
-
+
for (int j = 0; j < targets.size(); j++) {
Element<std::string> s = Element<std::string>(targets[j]);
if (isHistory(s)) {
@@ -421,19 +441,19 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element<std::
std::cout << getPadding() << "addDescendantStatesToEnter: " << ATTR(state, "id") << std::endl;
padding++;
#endif
-
+
if (isHistory(state)) {
-
+
/*
- if historyValue[state.id]:
- for s in historyValue[state.id]:
- addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
- addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
- else:
- defaultHistoryContent[state.parent.id] = state.transition.content
- for s in state.transition.target:
- addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
- addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+ if historyValue[state.id]:
+ for s in historyValue[state.id]:
+ addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+ else:
+ defaultHistoryContent[state.parent.id] = state.transition.content
+ for s in state.transition.target:
+ addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
*/
std::string stateId = ATTR(state, "id");
if (_historyValue.find(stateId) != _historyValue.end()) {
@@ -443,7 +463,7 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element<std::
addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent);
addAncestorStatesToEnter(s, getParentState(s), statesToEnter, statesForDefaultEntry, defaultHistoryContent);
}
-
+
} else {
NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state);
if (transitions.size() > 0) {
@@ -451,7 +471,7 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element<std::
// std::cout << "HIST: " << ATTR_CAST(getParentState(state), "id") << std::endl;
defaultHistoryContent[ATTR_CAST(getParentState(state), "id")] = transitions[0];
}
-
+
for (int i = 0; i < transitions.size(); i++) {
NodeSet<std::string> targets = getTargetStates(Element<std::string>(transitions[i]));
for (int j = 0; j < targets.size(); j++) {
@@ -463,19 +483,19 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element<std::
}
} else {
/*
- statesToEnter.add(state)
- if isCompoundState(state):
- statesForDefaultEntry.add(state)
- for s in getEffectiveTargetStates(state.initial.transition):
- addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
- addAncestorStatesToEnter(s, state, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
- else:
- if isParallelState(state):
- for child in getChildStates(state):
- if not statesToEnter.some(lambda s: isDescendant(s,child)):
- addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ statesToEnter.add(state)
+ if isCompoundState(state):
+ statesForDefaultEntry.add(state)
+ for s in getEffectiveTargetStates(state.initial.transition):
+ addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ addAncestorStatesToEnter(s, state, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+ else:
+ if isParallelState(state):
+ for child in getChildStates(state):
+ if not statesToEnter.some(lambda s: isDescendant(s,child)):
+ addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
*/
-
+
if (!isMember(state, statesToEnter)) { // adding an existing element invalidates old reference
#if VERBOSE_STATE_SELECTION
std::cout << getPadding() << "adding: " << ATTR_CAST(state, "id") << std::endl;
@@ -497,19 +517,19 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element<std::
const Element<std::string>& s = Element<std::string>(targets[i]);
addAncestorStatesToEnter(s, state, statesToEnter, statesForDefaultEntry, defaultHistoryContent);
}
-
+
} else if(isParallel(state)) {
NodeSet<std::string> childStates = getChildStates(state);
-
+
for (int i = 0; i < childStates.size(); i++) {
const Element<std::string>& child = Element<std::string>(childStates[i]);
-
+
for (int j = 0; j < statesToEnter.size(); j++) {
const Node<std::string>& s = statesToEnter[j];
if (isDescendant(s, child)) {
goto BREAK_LOOP;
}
-
+
}
addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry, defaultHistoryContent);
BREAK_LOOP:
@@ -539,14 +559,14 @@ void InterpreterRC::addAncestorStatesToEnter(const Arabica::DOM::Element<std::st
std::cout << getPadding() << "addAncestorStatesToEnter: " << ATTR(state, "id") << " - " << ATTR(ancestor, "id") << std::endl;
padding++;
#endif
-
+
NodeSet<std::string> ancestors = getProperAncestors(state, ancestor);
for (int i = 0; i < ancestors.size(); i++) {
const Node<std::string>& anc = ancestors[i];
#if VERBOSE_STATE_SELECTION
std::cout << getPadding() << "adding: " << ATTR_CAST(anc, "id") << std::endl;
#endif
-
+
statesToEnter.push_back(anc);
if (isParallel(Element<std::string>(anc))) {
diff --git a/src/uscxml/interpreter/InterpreterRC.h b/src/uscxml/interpreter/InterpreterRC.h
index d65e85a..52b45ff 100644
--- a/src/uscxml/interpreter/InterpreterRC.h
+++ b/src/uscxml/interpreter/InterpreterRC.h
@@ -25,6 +25,7 @@
namespace uscxml {
class InterpreterRC : public InterpreterImpl {
+protected:
void enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
void exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
Arabica::XPath::NodeSet<std::string> removeConflictingTransitions(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
diff --git a/src/uscxml/messages/Event.h b/src/uscxml/messages/Event.h
index d282fc2..94bc386 100644
--- a/src/uscxml/messages/Event.h
+++ b/src/uscxml/messages/Event.h
@@ -202,7 +202,7 @@ public:
typedef std::multimap<std::string, Data> params_t;
typedef std::map<std::string, Data> namelist_t;
-
+
static bool getParam(const params_t& params, const std::string& name, Data& target) {
if (params.find(name) != params.end()) {
target = params.find(name)->second;
diff --git a/src/uscxml/messages/MMIMessages.cpp b/src/uscxml/messages/MMIMessages.cpp
index 9cc8ea4..35e8b66 100644
--- a/src/uscxml/messages/MMIMessages.cpp
+++ b/src/uscxml/messages/MMIMessages.cpp
@@ -74,7 +74,7 @@ while (node) {\
}\
node = node.getNextSibling();\
}\
-
+
namespace uscxml {
@@ -97,7 +97,7 @@ MMIEvent::Type MMIEvent::getType(Arabica::DOM::Node<std::string> node) {
return INVALID;
}
}
-
+
if (boost::iequals(node.getLocalName(), "NEWCONTEXTREQUEST"))
return NEWCONTEXTREQUEST;
if (boost::iequals(node.getLocalName(), "NEWCONTEXTRESPONSE"))
@@ -245,7 +245,7 @@ Arabica::DOM::Document<std::string> StatusRequest::toXML(bool encapsulateInMMI)
return doc;
}
-
+
MMIEvent MMIEvent::fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter) {
MMIEvent msg;
@@ -259,7 +259,7 @@ MMIEvent MMIEvent::fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl
msg.tagName = msgElem.getLocalName();
Element<std::string> dataElem;
-
+
// search for data element
node = msgElem.getFirstChild();
while (node) {
@@ -309,7 +309,7 @@ FROM_XML(DoneNotification, DONENOTIFICATION, StatusInfoResponse)
ContextualizedRequest ContextualizedRequest::fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter) {
ContextualizedRequest msg(MMIEvent::fromXML(node, interpreter));
FIND_EVENT_NODE(node);
-
+
Element<std::string> msgElem(node);
msg.context = STRING_ATTR_OR_EXPR(msgElem, Context);
return msg;
@@ -318,7 +318,7 @@ ContextualizedRequest ContextualizedRequest::fromXML(Arabica::DOM::Node<std::str
ExtensionNotification ExtensionNotification::fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter) {
ExtensionNotification msg(ContextualizedRequest::fromXML(node, interpreter));
FIND_EVENT_NODE(node);
-
+
Element<std::string> msgElem(node);
msg.name = STRING_ATTR_OR_EXPR(msgElem, Name);
msg.type = EXTENSIONNOTIFICATION;
@@ -347,7 +347,7 @@ ContentRequest ContentRequest::fromXML(Arabica::DOM::Node<std::string> node, Int
if(boost::iequals(contentElem.getLocalName(), "content")) {
Arabica::DOM::Node<std::string> contentChild = contentElem.getFirstChild();
std::stringstream ss;
-
+
while (contentChild) {
if (contentChild.getNodeType() == Arabica::DOM::Node_base::ELEMENT_NODE)
msg.contentDOM = contentChild;
@@ -355,7 +355,7 @@ ContentRequest ContentRequest::fromXML(Arabica::DOM::Node<std::string> node, Int
contentChild = contentChild.getNextSibling();
}
msg.content = ss.str();
-
+
} else if(boost::iequals(contentElem.getLocalName(), "contentURL")) {
msg.contentURL.href = STRING_ATTR_OR_EXPR(contentElem, href);
msg.contentURL.maxAge = STRING_ATTR_OR_EXPR(contentElem, max-age);
@@ -442,107 +442,107 @@ StatusRequest StatusRequest::fromXML(Arabica::DOM::Node<std::string> node, Inter
return msg;
}
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
-
- TO_EVENT_OPERATOR(NewContextRequest, "mmi.request.newcontext", MMIEvent);
- TO_EVENT_OPERATOR(PauseRequest, "mmi.request.pause", ContextualizedRequest);
- TO_EVENT_OPERATOR(ResumeRequest, "mmi.request.resume", ContextualizedRequest);
- TO_EVENT_OPERATOR(CancelRequest, "mmi.request.cancel", ContextualizedRequest);
- TO_EVENT_OPERATOR(ClearContextRequest, "mmi.request.clearcontext", ContextualizedRequest);
- TO_EVENT_OPERATOR(StatusRequest, "mmi.request.status", ContextualizedRequest);
-
- TO_EVENT_OPERATOR(PrepareRequest, "mmi.request.prepare", ContentRequest);
- TO_EVENT_OPERATOR(StartRequest, "mmi.request.start", ContentRequest);
-
- TO_EVENT_OPERATOR(PrepareResponse, "mmi.response.prepare", StatusInfoResponse);
- TO_EVENT_OPERATOR(StartResponse, "mmi.response.start", StatusInfoResponse);
- TO_EVENT_OPERATOR(CancelResponse, "mmi.response.cancel", StatusInfoResponse);
- TO_EVENT_OPERATOR(PauseResponse, "mmi.response.pause", StatusInfoResponse);
- TO_EVENT_OPERATOR(ResumeResponse, "mmi.response.resume", StatusInfoResponse);
- TO_EVENT_OPERATOR(ClearContextResponse, "mmi.response.clearcontext", StatusInfoResponse);
- TO_EVENT_OPERATOR(NewContextResponse, "mmi.response.newcontext", StatusInfoResponse);
- TO_EVENT_OPERATOR(DoneNotification, "mmi.notification.done", StatusInfoResponse);
-
-
- MMIEvent::operator Event() const {
- Event ev;
- ev.setOriginType("mmi.event");
- ev.setOrigin(source);
-
- if (representation == MMI_AS_DATA) {
- if (dataDOM) {
- ev.data.node = dataDOM;
- } else {
- ev.data = Data::fromJSON(data);
- if (ev.data.empty()) {
- ev.content = data;
- }
+
+TO_EVENT_OPERATOR(NewContextRequest, "mmi.request.newcontext", MMIEvent);
+TO_EVENT_OPERATOR(PauseRequest, "mmi.request.pause", ContextualizedRequest);
+TO_EVENT_OPERATOR(ResumeRequest, "mmi.request.resume", ContextualizedRequest);
+TO_EVENT_OPERATOR(CancelRequest, "mmi.request.cancel", ContextualizedRequest);
+TO_EVENT_OPERATOR(ClearContextRequest, "mmi.request.clearcontext", ContextualizedRequest);
+TO_EVENT_OPERATOR(StatusRequest, "mmi.request.status", ContextualizedRequest);
+
+TO_EVENT_OPERATOR(PrepareRequest, "mmi.request.prepare", ContentRequest);
+TO_EVENT_OPERATOR(StartRequest, "mmi.request.start", ContentRequest);
+
+TO_EVENT_OPERATOR(PrepareResponse, "mmi.response.prepare", StatusInfoResponse);
+TO_EVENT_OPERATOR(StartResponse, "mmi.response.start", StatusInfoResponse);
+TO_EVENT_OPERATOR(CancelResponse, "mmi.response.cancel", StatusInfoResponse);
+TO_EVENT_OPERATOR(PauseResponse, "mmi.response.pause", StatusInfoResponse);
+TO_EVENT_OPERATOR(ResumeResponse, "mmi.response.resume", StatusInfoResponse);
+TO_EVENT_OPERATOR(ClearContextResponse, "mmi.response.clearcontext", StatusInfoResponse);
+TO_EVENT_OPERATOR(NewContextResponse, "mmi.response.newcontext", StatusInfoResponse);
+TO_EVENT_OPERATOR(DoneNotification, "mmi.notification.done", StatusInfoResponse);
+
+
+MMIEvent::operator Event() const {
+ Event ev;
+ ev.setOriginType("mmi.event");
+ ev.setOrigin(source);
+
+ if (representation == MMI_AS_DATA) {
+ if (dataDOM) {
+ ev.data.node = dataDOM;
+ } else {
+ ev.data = Data::fromJSON(data);
+ if (ev.data.empty()) {
+ ev.content = data;
}
}
- return ev;
- }
-
- ContextualizedRequest::operator Event() const {
- Event ev = MMIEvent::operator Event();
- // do we want to represent the context? It's the interpreters name already
- return ev;
}
+ return ev;
+}
- ExtensionNotification::operator Event() const {
- Event ev = ContextualizedRequest::operator Event();
- if (name.length() > 0) {
- ev.setName(name);
- } else {
- ev.setName("mmi.notification.extension");
- }
- return ev;
+ContextualizedRequest::operator Event() const {
+ Event ev = MMIEvent::operator Event();
+ // do we want to represent the context? It's the interpreters name already
+ return ev;
+}
+
+ExtensionNotification::operator Event() const {
+ Event ev = ContextualizedRequest::operator Event();
+ if (name.length() > 0) {
+ ev.setName(name);
+ } else {
+ ev.setName("mmi.notification.extension");
}
+ return ev;
+}
- ContentRequest::operator Event() const {
- Event ev = ContextualizedRequest::operator Event();
- if (representation == MMI_AS_DATA) {
- if (content.length() > 0)
- ev.data.compound["content"] = Data(content, Data::VERBATIM);
- if (contentURL.fetchTimeout.length() > 0)
- ev.data.compound["contentURL"].compound["fetchTimeout"] = Data(contentURL.fetchTimeout, Data::VERBATIM);
- if (contentURL.href.length() > 0)
- ev.data.compound["contentURL"].compound["href"] = Data(contentURL.href, Data::VERBATIM);
- if (contentURL.maxAge.length() > 0)
- ev.data.compound["contentURL"].compound["maxAge"] = Data(contentURL.maxAge, Data::VERBATIM);
- }
- return ev;
+ContentRequest::operator Event() const {
+ Event ev = ContextualizedRequest::operator Event();
+ if (representation == MMI_AS_DATA) {
+ if (content.length() > 0)
+ ev.data.compound["content"] = Data(content, Data::VERBATIM);
+ if (contentURL.fetchTimeout.length() > 0)
+ ev.data.compound["contentURL"].compound["fetchTimeout"] = Data(contentURL.fetchTimeout, Data::VERBATIM);
+ if (contentURL.href.length() > 0)
+ ev.data.compound["contentURL"].compound["href"] = Data(contentURL.href, Data::VERBATIM);
+ if (contentURL.maxAge.length() > 0)
+ ev.data.compound["contentURL"].compound["maxAge"] = Data(contentURL.maxAge, Data::VERBATIM);
}
+ return ev;
+}
- StatusResponse::operator Event() const {
- Event ev = ContextualizedRequest::operator Event();
- ev.setName("mmi.response.status");
-
- if (representation == MMI_AS_DATA) {
- switch (status) {
- case ALIVE:
- ev.data.compound["status"] = Data("alive", Data::VERBATIM);
- break;
- case DEAD:
- ev.data.compound["status"] = Data("dead", Data::VERBATIM);
- break;
- case SUCCESS:
- ev.data.compound["status"] = Data("success", Data::VERBATIM);
- break;
- case FAILURE:
- ev.data.compound["status"] = Data("failure", Data::VERBATIM);
- break;
- default:
- ev.data.compound["status"] = Data("invalid", Data::VERBATIM);
- }
- } else {
- ev.dom = toXML();
+StatusResponse::operator Event() const {
+ Event ev = ContextualizedRequest::operator Event();
+ ev.setName("mmi.response.status");
+
+ if (representation == MMI_AS_DATA) {
+ switch (status) {
+ case ALIVE:
+ ev.data.compound["status"] = Data("alive", Data::VERBATIM);
+ break;
+ case DEAD:
+ ev.data.compound["status"] = Data("dead", Data::VERBATIM);
+ break;
+ case SUCCESS:
+ ev.data.compound["status"] = Data("success", Data::VERBATIM);
+ break;
+ case FAILURE:
+ ev.data.compound["status"] = Data("failure", Data::VERBATIM);
+ break;
+ default:
+ ev.data.compound["status"] = Data("invalid", Data::VERBATIM);
}
-
- return ev;
+ } else {
+ ev.dom = toXML();
}
+ return ev;
+}
+
#endif
diff --git a/src/uscxml/messages/MMIMessages.h b/src/uscxml/messages/MMIMessages.h
index 2cffa0f..4f3947e 100644
--- a/src/uscxml/messages/MMIMessages.h
+++ b/src/uscxml/messages/MMIMessages.h
@@ -65,17 +65,17 @@ public:
// conversion operator
operator Event() const;
#endif
-
+
std::string source;
std::string target;
std::string data;
Arabica::DOM::Node<std::string> dataDOM;
std::string requestId;
-
+
std::string tagName;
Type type;
RepresentationType representation;
-
+
static std::string nameSpace;
protected:
@@ -94,7 +94,7 @@ public:
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
-
+
std::string token; ///< special token for server-less modality components
};
@@ -102,11 +102,11 @@ class ContextualizedRequest : public MMIEvent {
public:
virtual Arabica::DOM::Document<std::string> toXML(bool encapsulateInMMI = true) const;
static ContextualizedRequest fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter = NULL);
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
-
+
std::string context;
protected:
ContextualizedRequest() {}
@@ -121,11 +121,11 @@ public:
}
PauseRequest(const ContextualizedRequest& father) : ContextualizedRequest(father) {}
static PauseRequest fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter = NULL);
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
-
+
};
class ResumeRequest : public ContextualizedRequest {
public:
@@ -135,11 +135,11 @@ public:
}
ResumeRequest(const ContextualizedRequest& father) : ContextualizedRequest(father) {}
static ResumeRequest fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter = NULL);
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
-
+
};
class CancelRequest : public ContextualizedRequest {
public:
@@ -149,7 +149,7 @@ public:
}
CancelRequest(const ContextualizedRequest& father) : ContextualizedRequest(father) {}
static CancelRequest fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter = NULL);
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
@@ -167,7 +167,7 @@ public:
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
-
+
};
class StatusRequest : public ContextualizedRequest {
public:
@@ -181,7 +181,7 @@ public:
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
-
+
bool automaticUpdate;
protected:
StatusRequest(const ContextualizedRequest& father) : ContextualizedRequest(father) {}
@@ -201,7 +201,7 @@ public:
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
-
+
std::string content;
Arabica::DOM::Node<std::string> contentDOM;
ContentURL contentURL;
@@ -251,7 +251,7 @@ public:
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
-
+
std::string name;
protected:
ExtensionNotification(const ContextualizedRequest& father) : ContextualizedRequest(father) {}
@@ -275,7 +275,7 @@ public:
}
virtual Arabica::DOM::Document<std::string> toXML(bool encapsulateInMMI = true) const;
static StatusResponse fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter = NULL);
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
@@ -303,11 +303,11 @@ public:
}
PrepareResponse(const StatusInfoResponse& father) : StatusInfoResponse(father) {}
static PrepareResponse fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter = NULL);
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
-
+
};
class StartResponse : public StatusInfoResponse {
@@ -318,7 +318,7 @@ public:
}
StartResponse(const StatusInfoResponse& father) : StatusInfoResponse(father) {}
static StartResponse fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter = NULL);
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
@@ -332,7 +332,7 @@ public:
}
CancelResponse(const StatusInfoResponse& father) : StatusInfoResponse(father) {}
static CancelResponse fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter = NULL);
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
@@ -346,7 +346,7 @@ public:
}
PauseResponse(const StatusInfoResponse& father) : StatusInfoResponse(father) {}
static PauseResponse fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter = NULL);
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
@@ -360,7 +360,7 @@ public:
}
ResumeResponse(const StatusInfoResponse& father) : StatusInfoResponse(father) {}
static ResumeResponse fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter = NULL);
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
@@ -402,7 +402,7 @@ public:
}
DoneNotification(const StatusInfoResponse& father) : StatusInfoResponse(father) {}
static DoneNotification fromXML(Arabica::DOM::Node<std::string> node, InterpreterImpl* interpreter = NULL);
-
+
#ifdef MMI_WITH_OPERATOR_EVENT
operator Event() const;
#endif
diff --git a/src/uscxml/plugins/EventHandler.h b/src/uscxml/plugins/EventHandler.h
index 8ac31b1..91703fc 100644
--- a/src/uscxml/plugins/EventHandler.h
+++ b/src/uscxml/plugins/EventHandler.h
@@ -74,8 +74,8 @@ protected:
Arabica::DOM::Element<std::string> _element;
std::string _invokeId;
std::string _type;
-
-
+
+
};
class USCXML_API EventHandler {
diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
index b8ec2cc..2f07528 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
@@ -493,13 +493,13 @@ bool JSCDataModel::isValidSyntax(const std::string& expr) {
JSValueRef exception = NULL;
bool valid = JSCheckScriptSyntax(_ctx, scriptJS, NULL, 0, &exception);
JSStringRelease(scriptJS);
-
+
if (exception || !valid) {
return false;
}
return true;
}
-
+
bool JSCDataModel::isDeclared(const std::string& expr) {
JSStringRef scriptJS = JSStringCreateWithUTF8CString(expr.c_str());
JSValueRef exception = NULL;
diff --git a/src/uscxml/plugins/datamodel/ecmascript/SpiderMonkey/SpiderMonkeyDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/SpiderMonkey/SpiderMonkeyDataModel.cpp
index 1bce2c3..c867b22 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/SpiderMonkey/SpiderMonkeyDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/SpiderMonkey/SpiderMonkeyDataModel.cpp
@@ -43,21 +43,21 @@ bool pluginConnect(pluma::Host& host) {
#endif
static JSClass global_class = { "global",
- JSCLASS_NEW_RESOLVE | JSCLASS_GLOBAL_FLAGS,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
- nullptr,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
+ JSCLASS_NEW_RESOLVE | JSCLASS_GLOBAL_FLAGS,
+ JS_PropertyStub,
+ JS_PropertyStub,
+ JS_PropertyStub,
+ JS_PropertyStub,
+ JS_EnumerateStub,
+ JS_ResolveStub,
+ JS_ConvertStub,
+ nullptr,
+ JSCLASS_NO_OPTIONAL_MEMBERS
+ };
+
-
JSRuntime* SpiderMonkeyDataModel::_jsRuntime = NULL;
-
+
SpiderMonkeyDataModel::SpiderMonkeyDataModel() {
_jsCtx = NULL;
}
@@ -66,24 +66,24 @@ SpiderMonkeyDataModel::~SpiderMonkeyDataModel() {
if (_jsCtx)
JS_DestroyContext(_jsCtx);
}
-
+
void SpiderMonkeyDataModel::reportError(JSContext *cx, const char *message, JSErrorReport *report) {
#if 0
- struct JSErrorReport {
- const char *filename; /* source file name, URL, etc., or null */
- uintN lineno; /* source line number */
- const char *linebuf; /* offending source line without final \n */
- const char *tokenptr; /* pointer to error token in linebuf */
- const jschar *uclinebuf; /* unicode (original) line buffer */
- const jschar *uctokenptr; /* unicode (original) token pointer */
- uintN flags; /* error/warning, etc. */
- uintN errorNumber; /* the error number, e.g. see js.msg */
- const jschar *ucmessage; /* the (default) error message */
- const jschar **messageArgs; /* arguments for the error message */
-};
-exceptionEvent.data.compound["stacktrace"] = Data(stackTrace, Data::VERBATIM);
+ struct JSErrorReport {
+ const char *filename; /* source file name, URL, etc., or null */
+ uintN lineno; /* source line number */
+ const char *linebuf; /* offending source line without final \n */
+ const char *tokenptr; /* pointer to error token in linebuf */
+ const jschar *uclinebuf; /* unicode (original) line buffer */
+ const jschar *uctokenptr; /* unicode (original) token pointer */
+ uintN flags; /* error/warning, etc. */
+ uintN errorNumber; /* the error number, e.g. see js.msg */
+ const jschar *ucmessage; /* the (default) error message */
+ const jschar **messageArgs; /* arguments for the error message */
+ };
+ exceptionEvent.data.compound["stacktrace"] = Data(stackTrace, Data::VERBATIM);
#endif
-
+
Event exceptionEvent;
exceptionEvent.name = "error.execution";
exceptionEvent.eventType = Event::PLATFORM;
@@ -104,12 +104,12 @@ exceptionEvent.data.compound["stacktrace"] = Data(stackTrace, Data::VERBATIM);
boost::shared_ptr<DataModelImpl> SpiderMonkeyDataModel::create(InterpreterImpl* interpreter) {
if (_jsRuntime == NULL) {
- JSRuntime *rt = JS_NewRuntime(8L * 1024L * 1024L);
- if (!rt) {
+ JSRuntime *rt = JS_NewRuntime(8L * 1024L * 1024L);
+ if (!rt) {
throw std::bad_alloc();
}
}
-
+
boost::shared_ptr<SpiderMonkeyDataModel> dm = boost::shared_ptr<SpiderMonkeyDataModel>(new SpiderMonkeyDataModel());
dm->_interpreter = interpreter;
dm->_jsCtx = JS_NewContext(_jsRuntime, 8192);
@@ -158,13 +158,13 @@ uint32_t SpiderMonkeyDataModel::getLength(const std::string& expr) {
}
void SpiderMonkeyDataModel::setForeach(const std::string& item,
- const std::string& array,
- const std::string& index,
- uint32_t iteration) {
+ const std::string& array,
+ const std::string& index,
+ uint32_t iteration) {
}
void SpiderMonkeyDataModel::eval(const Element<std::string>& scriptElem,
- const std::string& expr) {
+ const std::string& expr) {
}
bool SpiderMonkeyDataModel::isDeclared(const std::string& expr) {
@@ -187,21 +187,21 @@ double SpiderMonkeyDataModel::evalAsNumber(const std::string& expr) {
}
void SpiderMonkeyDataModel::assign(const Element<std::string>& assignElem,
- const Node<std::string>& node,
- const std::string& content) {
+ const Node<std::string>& node,
+ const std::string& content) {
}
void SpiderMonkeyDataModel::assign(const std::string& location,
- const Data& data) {
+ const Data& data) {
}
void SpiderMonkeyDataModel::init(const Element<std::string>& dataElem,
- const Node<std::string>& doc,
- const std::string& content) {
+ const Node<std::string>& doc,
+ const std::string& content) {
};
void SpiderMonkeyDataModel::init(const std::string& location,
- const Data& data) {
+ const Data& data) {
}
std::string SpiderMonkeyDataModel::andExpressions(std::list<std::string> expressions) {
diff --git a/src/uscxml/plugins/datamodel/ecmascript/SpiderMonkey/SpiderMonkeyDataModel.h b/src/uscxml/plugins/datamodel/ecmascript/SpiderMonkey/SpiderMonkeyDataModel.h
index fbbdb69..d9a5e5e 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/SpiderMonkey/SpiderMonkeyDataModel.h
+++ b/src/uscxml/plugins/datamodel/ecmascript/SpiderMonkey/SpiderMonkeyDataModel.h
@@ -91,7 +91,7 @@ public:
protected:
JSObject* _global;
-
+
JSContext* _jsCtx;
static JSRuntime* _jsRuntime;
};
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
index f8c9203..153e2c0 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
@@ -181,9 +181,9 @@ v8::Handle<v8::Value> V8DataModel::getIOProcessors(v8::Local<v8::String> propert
std::map<std::string, IOProcessor> ioProcessors = dataModel->_interpreter->getIOProcessors();
std::map<std::string, IOProcessor>::const_iterator ioProcIter = ioProcessors.begin();
while(ioProcIter != ioProcessors.end()) {
- // std::cout << ioProcIter->first << std::endl;
+ // std::cout << ioProcIter->first << std::endl;
dataModel->_ioProcessors->Set(v8::String::New(ioProcIter->first.c_str()),
- dataModel->getDataAsValue(ioProcIter->second.getDataModelVariables()));
+ dataModel->getDataAsValue(ioProcIter->second.getDataModelVariables()));
ioProcIter++;
}
dataModel->_ioProcessorsAreSet = true;
@@ -202,7 +202,7 @@ v8::Handle<v8::Value> V8DataModel::getInvokers(v8::Local<v8::String> property, c
while(invokerIter != invokers.end()) {
// std::cout << ioProcIter->first << std::endl;
dataModel->_invokers->Set(v8::String::New(invokerIter->first.c_str()),
- dataModel->getDataAsValue(invokerIter->second.getDataModelVariables()));
+ dataModel->getDataAsValue(invokerIter->second.getDataModelVariables()));
invokerIter++;
}
dataModel->_invokersAreSet = true;
diff --git a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp
index 8eb1ce1..6e9b237 100644
--- a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp
@@ -53,7 +53,7 @@ static int luaInspect(lua_State * l) {
bool _luaHasXMLParser = false;
-
+
static luabridge::LuaRef getDataAsLua(lua_State* _luaState, const Data& data) {
luabridge::LuaRef luaData (_luaState);
@@ -159,7 +159,7 @@ boost::shared_ptr<DataModelImpl> LuaDataModel::create(InterpreterImpl* interpret
} catch (luabridge::LuaException e) {
LOG(INFO) << e.what();
}
-
+
luabridge::getGlobalNamespace(dm->_luaState).beginClass<InterpreterImpl>("Interpreter").endClass();
luabridge::setGlobal(dm->_luaState, dm->_interpreter, "__interpreter");
@@ -347,7 +347,7 @@ bool LuaDataModel::isValidSyntax(const std::string& expr) {
// clean stack again
lua_pop(_luaState, lua_gettop(_luaState) - preStack);
-
+
if (err == LUA_ERRSYNTAX)
return false;
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIConfig.h.in b/src/uscxml/plugins/datamodel/prolog/swi/SWIConfig.h.in
index 2c0dc72..e3127b0 100644
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIConfig.h.in
+++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIConfig.h.in
@@ -1,3 +1,4 @@
#cmakedefine SWI_HAS_PL_NIL
#cmakedefine SWI_HAS_PL_DICT
-#cmakedefine SWI_HAS_PL_LIST_PAIR \ No newline at end of file
+#cmakedefine SWI_HAS_PL_LIST_PAIR
+#cmakedefine SWI_REINTERPRET_FOREIGN \ No newline at end of file
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
index 1bf7b6a..b53afba 100644
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
+++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
@@ -21,10 +21,11 @@
#define SWIDATAMODEL_H_KN8TWG0V
#include "uscxml/Interpreter.h"
+#include "uscxml/SWIConfig.h"
+
#include <list>
#include <SWI-cpp.h>
-#include "uscxml/SWIConfig.h"
#ifdef BUILD_AS_PLUGINS
#include "uscxml/plugins/Plugins.h"
diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp
index f83d0c8..d63c354 100644
--- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp
@@ -34,6 +34,12 @@
#include <Pluma/Connector.hpp>
#endif
+#define INVALID_ASSIGNMENT(name) \
+name.compare("_sessionid") == 0 || \
+name.compare("_name") == 0 || \
+name.compare("_ioprocessors") == 0 || \
+name.compare("_event") == 0
+
namespace uscxml {
using namespace Arabica::XPath;
@@ -56,6 +62,29 @@ PromelaDataModel::~PromelaDataModel() {
boost::shared_ptr<DataModelImpl> PromelaDataModel::create(InterpreterImpl* interpreter) {
boost::shared_ptr<PromelaDataModel> dm = boost::shared_ptr<PromelaDataModel>(new PromelaDataModel());
dm->_interpreter = interpreter;
+
+ // session id
+ Data sessionId;
+ sessionId.compound["type"] = Data("string", Data::VERBATIM);
+ sessionId.compound["value"] = Data(interpreter->getSessionId(), Data::VERBATIM);
+ dm->_variables["_sessionid"] = sessionId;
+
+ // name
+ Data name;
+ name.compound["type"] = Data("string", Data::VERBATIM);
+ name.compound["value"] = Data(interpreter->getName(), Data::VERBATIM);
+ dm->_variables["_name"] = name;
+
+ // ioprocessors
+ Data ioProcs;
+ ioProcs.compound["type"] = Data("compound", Data::VERBATIM);
+
+ std::map<std::string, IOProcessor> ioProcessors = interpreter->getIOProcessors();
+ for (std::map<std::string, IOProcessor>::iterator iter = ioProcessors.begin(); iter != ioProcessors.end(); iter++) {
+ ioProcs.compound["value"].compound[iter->first] = iter->second.getDataModelVariables();
+ }
+ dm->_variables["_ioprocessors"] = ioProcs;
+
dm->_lastMType = 0;
return dm;
}
@@ -63,14 +92,6 @@ boost::shared_ptr<DataModelImpl> PromelaDataModel::create(InterpreterImpl* inter
void PromelaDataModel::registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor) {
}
-void PromelaDataModel::setSessionId(const std::string& sessionId) {
- _sessionId = sessionId;
-}
-
-void PromelaDataModel::setName(const std::string& name) {
- _name = name;
-}
-
void PromelaDataModel::pushContext() {
// std::cout << "PromelaDataModel::pushContext" << std::endl;
}
@@ -79,17 +100,105 @@ void PromelaDataModel::popContext() {
// std::cout << "PromelaDataModel::popContext" << std::endl;
}
-void PromelaDataModel::initialize() {
-// std::cout << "PromelaDataModel::initialize" << std::endl;
+void PromelaDataModel::setEvent(const Event& event) {
+ Data variable;
+ variable.compound["type"] = Data("compound", Data::VERBATIM);
+ variable.compound["value"].compound["name"] = Data(event.name, Data::VERBATIM);
+ variable.compound["value"].compound["origin"] = Data(event.origin, Data::VERBATIM);
+ variable.compound["value"].compound["origintype"] = Data(event.origintype, Data::VERBATIM);
+ variable.compound["value"].compound["invokeid"] = Data(event.invokeid, Data::VERBATIM);
+ if (event.hideSendId) {
+ variable.compound["value"].compound["sendid"] = Data("", Data::VERBATIM);
+ } else {
+ variable.compound["value"].compound["sendid"] = Data(event.sendid, Data::VERBATIM);
+ }
+ switch (event.eventType) {
+ case Event::PLATFORM:
+ variable.compound["value"].compound["type"] = Data("platform", Data::VERBATIM);
+ break;
+ case Event::INTERNAL:
+ variable.compound["value"].compound["type"] = Data("internal", Data::VERBATIM);
+ break;
+ case Event::EXTERNAL:
+ variable.compound["value"].compound["type"] = Data("external", Data::VERBATIM);
+ break;
+ default:
+ variable.compound["value"].compound["type"] = Data("invalid", Data::VERBATIM);
+ break;
+ }
+
+ if (event.dom) {
+ // no support
+ } else if (event.content.length() > 0) {
+ // _event.data is a string or JSON
+ Data json = Data::fromJSON(event.content);
+ if (!json.empty()) {
+ variable.compound["value"].compound["data"] = json;
+ } else {
+ if (isNumeric(event.content.c_str(), 10)) {
+ variable.compound["value"].compound["data"] = Data(event.content, Data::INTERPRETED);
+ } else {
+ variable.compound["value"].compound["data"] = Data(InterpreterImpl::spaceNormalize(event.content), Data::VERBATIM);
+ }
+ }
+ } else {
+ // _event.data is KVP
+ if (!event.data.empty()) {
+ variable.compound["value"].compound["data"] = event.data;
+ } else {
+ // test 343 / test 488
+ variable.compound["value"].compound["data"];
+ }
+
+ for (Event::params_t::const_iterator start = event.params.begin(), end = event.params.end();
+ start != end; start = event.params.upper_bound(start->first)) {
+ // only set first param key
+ if (isNumeric(start->second.atom.c_str(), 10)) {
+ variable.compound["value"].compound["data"].compound[start->first] = strTo<int>(start->second.atom);
+ } else {
+ variable.compound["value"].compound["data"].compound[start->first] = start->second;
+ }
+ }
+
+ for (Event::namelist_t::const_iterator iter = event.namelist.begin(); iter != event.namelist.end(); iter++) {
+ if (isNumeric(iter->second.atom.c_str(), 10)) {
+ variable.compound["value"].compound["data"].compound[iter->first] = strTo<int>(iter->second.atom);
+ } else {
+ variable.compound["value"].compound["data"].compound[iter->first] = iter->second;
+ }
+ }
+ }
+
+ // iterate all data elements and adapt type for int if atom is integer
+ adaptType(variable.compound["value"].compound["data"]);
+
+ _variables["_event"] = variable;
}
-void PromelaDataModel::setEvent(const Event& event) {
- _event = event;
+void PromelaDataModel::adaptType(Data& data) {
+ if (data.atom.length() > 0 && isInteger(data.atom.c_str(), 10)) {
+ data.type = Data::INTERPRETED;
+ return;
+ }
+
+ if (data.array.size() > 0) {
+ for (std::list<Data>::iterator iter = data.array.begin(); iter != data.array.end(); iter++) {
+ adaptType(*iter);
+ }
+ return;
+ }
+
+ if (data.compound.size() > 0) {
+ for (std::map<std::string, Data>::iterator iter = data.compound.begin(); iter != data.compound.end(); iter++) {
+ adaptType(iter->second);
+ }
+ return;
+ }
+
}
Data PromelaDataModel::getStringAsData(const std::string& content) {
- Data data(content, Data::VERBATIM);
- return data;
+ return evaluateExpr(content);
}
@@ -122,20 +231,23 @@ void PromelaDataModel::setForeach(const std::string& item,
std::stringstream ss;
ss << array << "[" << iteration << "]";
- PromelaParser itemParser(item, PromelaParser::PROMELA_EXPR);
- PromelaParser arrayParser(ss.str(), PromelaParser::PROMELA_EXPR);
+ PromelaParser itemParser(item, 1, PromelaParser::PROMELA_EXPR);
+ if (itemParser.ast->type != PML_NAME)
+ ERROR_EXECUTION_THROW("Expression '" + item + "' is no valid item");
+
+ PromelaParser arrayParser(ss.str(), 1, PromelaParser::PROMELA_EXPR);
setVariable(itemParser.ast, getVariable(arrayParser.ast));
if (index.length() > 0) {
- PromelaParser indexParser(index, PromelaParser::PROMELA_EXPR);
+ PromelaParser indexParser(index, 1, PromelaParser::PROMELA_EXPR);
setVariable(indexParser.ast, iteration);
}
}
void PromelaDataModel::eval(const Element<std::string>& scriptElem, const std::string& expr) {
- PromelaParser parser(expr, PromelaParser::PROMELA_STMNT);
+ PromelaParser parser(expr, 1, PromelaParser::PROMELA_STMNT);
evaluateStmnt(parser.ast);
// parser.dump();
}
@@ -145,27 +257,91 @@ bool PromelaDataModel::evalAsBool(const std::string& expr) {
}
bool PromelaDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) {
- PromelaParser parser(expr, PromelaParser::PROMELA_EXPR);
+ PromelaParser parser(expr, 1, PromelaParser::PROMELA_EXPR);
// parser.dump();
- return evaluateExpr(parser.ast) > 0;
+ Data tmp = evaluateExpr(parser.ast);
+
+ if (tmp.atom.compare("false") == 0)
+ return false;
+ if (tmp.atom.compare("0") == 0)
+ return false;
+ return true;
}
std::string PromelaDataModel::evalAsString(const std::string& expr) {
- if (isDeclared(expr)) {
- return Data::toJSON(_variables[expr]);
- }
- return expr;
+ PromelaParser parser(expr);
+ return evaluateExpr(parser.ast);
}
void PromelaDataModel::assign(const Element<std::string>& assignElem,
const Node<std::string>& node,
const std::string& content) {
- PromelaParser parser(content, PromelaParser::PROMELA_DECL);
- evaluateDecl(parser.ast);
+ std::string expr;
+ std::string key;
+ std::string value;
+
+ if (node) {
+ ERROR_EXECUTION_THROW("Assigning DOM node to variable is not supported");
+ }
+
+ if (HAS_ATTR(assignElem, "id")) {
+ key = ATTR(assignElem, "id");
+ } else if (HAS_ATTR(assignElem, "location")) {
+ key = ATTR(assignElem, "location");
+ }
+
+ if (HAS_ATTR(assignElem, "expr")) {
+ if (key.length() == 0) {
+ ERROR_EXECUTION_THROW("Assign element has neither id nor location");
+ }
+ value = ATTR(assignElem, "expr");
+ } else {
+ value = content;
+ }
+
+ if (key.length() > 0) {
+ PromelaParser parser(key);
+
+ // declaration is an array?
+ if (parser.ast->operands.size() > 0 &&
+ parser.ast->operands.back()->operands.size() > 0 &&
+ parser.ast->operands.back()->operands.back()->type == PML_VAR_ARRAY) {
+ evaluateDecl(parser.ast);
+ expr = content;
+ } else if (value.length() > 0) {
+ expr = key + " = " + value + ";";
+ } else {
+ // declaration
+ expr = key + ";";
+ }
+ } else {
+ expr = content;
+ }
+
+ PromelaParser parser(expr, 2, PromelaParser::PROMELA_DECL, PromelaParser::PROMELA_STMNT);
+ if (parser.type == PromelaParser::PROMELA_DECL)
+ evaluateDecl(parser.ast);
+ if (parser.type == PromelaParser::PROMELA_STMNT)
+ evaluateStmnt(parser.ast);
// parser.dump();
// std::cout << Data::toJSON(_variables) << std::endl;
}
+void PromelaDataModel::evaluateDecl(const std::string& expr) {
+ PromelaParser parser(expr, 1, PromelaParser::PROMELA_DECL);
+ evaluateDecl(parser.ast);
+}
+
+Data PromelaDataModel::evaluateExpr(const std::string& expr) {
+ PromelaParser parser(expr, 1, PromelaParser::PROMELA_EXPR);
+ return evaluateExpr(parser.ast);
+}
+
+void PromelaDataModel::evaluateStmnt(const std::string& expr) {
+ PromelaParser parser(expr, 1, PromelaParser::PROMELA_STMNT);
+ evaluateStmnt(parser.ast);
+}
+
void PromelaDataModel::evaluateDecl(void* ast) {
PromelaParserNode* node = (PromelaParserNode*)ast;
if (false) {
@@ -209,7 +385,7 @@ void PromelaDataModel::evaluateDecl(void* ast) {
std::list<PromelaParserNode*>::iterator opIterAsgn = (*nameIter)->operands.begin();
PromelaParserNode* name = *opIterAsgn++;
- int size = evaluateExpr(*opIterAsgn++);
+ int size = dataToInt(evaluateExpr(*opIterAsgn++));
variable.compound["size"] = size;
for (int i = 0; i < size; i++) {
@@ -235,43 +411,115 @@ void PromelaDataModel::evaluateDecl(void* ast) {
}
}
-int PromelaDataModel::evaluateExpr(void* ast) {
+int PromelaDataModel::dataToInt(const Data& data) {
+ if (data.type != Data::INTERPRETED)
+ ERROR_EXECUTION_THROW("Operand is not integer");
+ int value = strTo<int>(data.atom);
+ if (data.atom.compare(toStr(value)) != 0)
+ ERROR_EXECUTION_THROW("Operand is not integer");
+ return value;
+}
+
+bool PromelaDataModel::dataToBool(const Data& data) {
+ if (data.atom.size() == 0) // empty string or undefined
+ return false;
+
+ if (data.type == Data::VERBATIM) {
+ // non-empty string is true
+ return true;
+ } else {
+ if (data.atom.compare("true") == 0) {
+ // boolean true is true
+ return true;
+ } else if (data.atom.compare("false") == 0) {
+ return false;
+ } else if (dataToInt(data) != 0) {
+ return true; // non zero values are true
+ }
+ }
+ return false;
+}
+
+Data PromelaDataModel::evaluateExpr(void* ast) {
PromelaParserNode* node = (PromelaParserNode*)ast;
std::list<PromelaParserNode*>::iterator opIter = node->operands.begin();
switch (node->type) {
case PML_CONST:
+ if (iequals(node->value, "false"))
+ return Data(false);
+ if (iequals(node->value, "true"))
+ return Data(true);
return strTo<int>(node->value);
case PML_NAME:
case PML_VAR_ARRAY:
+ 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);
+ }
case PML_PLUS:
- return evaluateExpr(*opIter++) + evaluateExpr(*opIter++);
+ return dataToInt(evaluateExpr(*opIter++)) + dataToInt(evaluateExpr(*opIter++));
case PML_MINUS:
- return evaluateExpr(*opIter++) - evaluateExpr(*opIter++);
+ return dataToInt(evaluateExpr(*opIter++)) - dataToInt(evaluateExpr(*opIter++));
case PML_DIVIDE:
- return evaluateExpr(*opIter++) / evaluateExpr(*opIter++);
+ return dataToInt(evaluateExpr(*opIter++)) / dataToInt(evaluateExpr(*opIter++));
case PML_MODULO:
- return evaluateExpr(*opIter++) % evaluateExpr(*opIter++);
- case PML_EQ:
- return evaluateExpr(*opIter++) == evaluateExpr(*opIter++);
+ return dataToInt(evaluateExpr(*opIter++)) % dataToInt(evaluateExpr(*opIter++));
+ case PML_EQ: {
+ PromelaParserNode* lhs = *opIter++;
+ PromelaParserNode* rhs = *opIter++;
+
+ Data left = evaluateExpr(lhs);
+ Data right = evaluateExpr(rhs);
+
+ if (left == right) // overloaded operator==
+ return Data(true);
+
+ // literal strings or strings in variables
+ if ((lhs->type == PML_STRING || rhs->type == PML_STRING)
+ || (left.type == Data::VERBATIM && right.type == Data::VERBATIM)) {
+ return (left.atom.compare(right.atom) == 0 ? Data(true) : Data(false));
+ }
+ return dataToInt(left) == dataToInt(right);
+ }
+ case PML_NEG:
+ return !dataToBool(evaluateExpr(*opIter++));
case PML_LT:
- return evaluateExpr(*opIter++) < evaluateExpr(*opIter++);
+ return dataToInt(evaluateExpr(*opIter++)) < dataToInt(evaluateExpr(*opIter++));
case PML_LE:
- return evaluateExpr(*opIter++) <= evaluateExpr(*opIter++);
+ return dataToInt(evaluateExpr(*opIter++)) <= dataToInt(evaluateExpr(*opIter++));
case PML_GT:
- return evaluateExpr(*opIter++) > evaluateExpr(*opIter++);
+ return dataToInt(evaluateExpr(*opIter++)) > dataToInt(evaluateExpr(*opIter++));
case PML_GE:
- return evaluateExpr(*opIter++) >= evaluateExpr(*opIter++);
+ return dataToInt(evaluateExpr(*opIter++)) >= dataToInt(evaluateExpr(*opIter++));
case PML_TIMES:
- return evaluateExpr(*opIter++) * evaluateExpr(*opIter++);
+ return dataToInt(evaluateExpr(*opIter++)) * dataToInt(evaluateExpr(*opIter++));
case PML_LSHIFT:
- return evaluateExpr(*opIter++) << evaluateExpr(*opIter++);
+ return dataToInt(evaluateExpr(*opIter++)) << dataToInt(evaluateExpr(*opIter++));
case PML_RSHIFT:
- return evaluateExpr(*opIter++) >> evaluateExpr(*opIter++);
+ return dataToInt(evaluateExpr(*opIter++)) >> dataToInt(evaluateExpr(*opIter++));
case PML_AND:
- return evaluateExpr(*opIter++) != 0 && evaluateExpr(*opIter++) != 0;
- case PML_OR:
- return evaluateExpr(*opIter++) != 0 || evaluateExpr(*opIter++) != 0;
+ case PML_OR: {
+ PromelaParserNode* lhs = *opIter++;
+ PromelaParserNode* rhs = *opIter++;
+
+ std::cout << "-----" << std::endl;
+ lhs->dump();
+ rhs->dump();
+
+ Data left = evaluateExpr(lhs);
+ Data right = evaluateExpr(rhs);
+
+ bool truthLeft = dataToBool(left);
+ bool truthRight = dataToBool(right);
+
+ if (node->type == PML_AND) {
+ return truthLeft && truthRight;
+ } else {
+ return truthLeft || truthRight;
+ }
+ }
default:
ERROR_EXECUTION_THROW("Support for " + PromelaParserNode::typeToDesc(node->type) + " expressions not implemented");
}
@@ -299,7 +547,7 @@ void PromelaDataModel::evaluateStmnt(void* ast) {
}
}
-void PromelaDataModel::setVariable(void* ast, int value) {
+void PromelaDataModel::setVariable(void* ast, Data value) {
PromelaParserNode* node = (PromelaParserNode*)ast;
std::list<PromelaParserNode*>::iterator opIter = node->operands.begin();
@@ -307,7 +555,12 @@ void PromelaDataModel::setVariable(void* ast, int value) {
case PML_VAR_ARRAY: {
PromelaParserNode* name = *opIter++;
PromelaParserNode* expr = *opIter++;
- int index = evaluateExpr(expr);
+
+ if (INVALID_ASSIGNMENT(name->value)) {
+ ERROR_EXECUTION_THROW("Cannot assign to " + name->value);
+ }
+
+ int index = dataToInt(evaluateExpr(expr));
if (_variables.compound.find(name->value) == _variables.compound.end()) {
ERROR_EXECUTION_THROW("No variable " + name->value + " was declared");
@@ -321,12 +574,15 @@ void PromelaDataModel::setVariable(void* ast, int value) {
ERROR_EXECUTION_THROW("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds");
}
- _variables.compound[name->value].compound["value"][index] = Data(value, Data::VERBATIM);
+ _variables.compound[name->value].compound["value"][index] = value;
break;
}
case PML_NAME:
- _variables.compound[node->value].compound["value"] = Data(value, Data::VERBATIM);
+ if (INVALID_ASSIGNMENT(node->value)) {
+ ERROR_EXECUTION_THROW("Cannot assign to " + node->value);
+ }
+ _variables.compound[node->value].compound["value"] = value;
break;
default:
break;
@@ -335,7 +591,7 @@ void PromelaDataModel::setVariable(void* ast, int value) {
// std::cout << Data::toJSON(_variables) << std::endl;
}
-int PromelaDataModel::getVariable(void* ast) {
+Data PromelaDataModel::getVariable(void* ast) {
PromelaParserNode* node = (PromelaParserNode*)ast;
// node->dump();
@@ -345,14 +601,14 @@ int PromelaDataModel::getVariable(void* ast) {
if (_variables.compound.find(node->value) == _variables.compound.end()) {
ERROR_EXECUTION_THROW("No variable " + node->value + " was declared");
}
- if (_variables[node->value].compound.find("size") != _variables[node->value].compound.end()) {
- ERROR_EXECUTION_THROW("Type error: Variable " + node->value + " is an array");
- }
- return strTo<int>(_variables[node->value]["value"].atom);
+// if (_variables[node->value].compound.find("size") != _variables[node->value].compound.end()) {
+// ERROR_EXECUTION_THROW("Type error: Variable " + node->value + " is an array");
+// }
+ return _variables[node->value]["value"];
case PML_VAR_ARRAY: {
PromelaParserNode* name = *opIter++;
PromelaParserNode* expr = *opIter++;
- int index = evaluateExpr(expr);
+ int index = dataToInt(evaluateExpr(expr));
if (_variables.compound.find(name->value) == _variables.compound.end()) {
ERROR_EXECUTION_THROW("No variable " + name->value + " was declared");
@@ -365,7 +621,54 @@ int PromelaDataModel::getVariable(void* ast) {
if (strTo<int>(_variables[name->value]["size"].atom) <= index) {
ERROR_EXECUTION_THROW("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds");
}
- return strTo<int>(_variables.compound[name->value].compound["value"][index].atom);
+ return _variables.compound[name->value].compound["value"][index];
+ }
+ case PML_CMPND: {
+// node->dump();
+// std::cout << Data::toJSON(_variables["_event"]);
+
+ std::stringstream idPath;
+ PromelaParserNode* name = *opIter++;
+
+ // special case for _x variables
+ if (name->value.compare("_x") == 0) {
+ PromelaParserNode* what = *opIter++;
+
+ if (what->type == PML_VAR_ARRAY) {
+ if (what->operands.size() == 2) {
+ std::string arrName = what->operands.front()->value;
+ std::string index = what->operands.back()->value;
+
+ if (what->operands.back()->type == PML_STRING) {
+ index = index.substr(1, index.size() - 2); // remove quotes
+ }
+
+ if (arrName.compare("states") == 0) {
+ return Data(_interpreter->isInState(index));
+ }
+ }
+ }
+ ERROR_EXECUTION_THROW("No variable " + name->value + " was declared");
+ }
+
+ if (_variables.compound.find(name->value) == _variables.compound.end()) {
+ ERROR_EXECUTION_THROW("No variable " + name->value + " was declared");
+ }
+
+ Data currData = _variables.compound[name->value]["value"];
+ idPath << name->value;
+ while(opIter != node->operands.end()) {
+ std::string key = (*opIter)->value;
+ idPath << "." << key;
+ if (currData.compound.find(key) == currData.compound.end()) {
+ ERROR_EXECUTION_THROW("No variable " + idPath.str() + " was declared");
+ }
+ Data tmp = currData.compound[key];
+ currData = tmp;
+
+ opIter++;
+ }
+ return currData;
}
default:
ERROR_EXECUTION_THROW("Retrieving value of " + PromelaParserNode::typeToDesc(node->type) + " variable not implemented");
@@ -395,14 +698,35 @@ std::string PromelaDataModel::andExpressions(std::list<std::string> expressions)
}
void PromelaDataModel::assign(const std::string& location, const Data& data) {
- // used for e.g. to assign command line parameters
- std::cout << "Ignoring " << location << " = " << Data::toJSON(data) << std::endl;
+ // used for e.g. to assign command line parameters and idlocation
+ PromelaParser parser(location);
+ setVariable(parser.ast, data);
}
void PromelaDataModel::init(const Element<std::string>& dataElem,
const Node<std::string>& node,
const std::string& content) {
// from <datamodel>
+ if (HAS_ATTR(dataElem, "id")) {
+ Element<std::string> dataElemCopy = dataElem;
+ std::string identifier = ATTR(dataElem, "id");
+ std::string type = (HAS_ATTR(dataElem, "type") ? ATTR(dataElem, "type") : "int");
+ std::string arrSize;
+
+ size_t bracketPos = type.find("[");
+ if (bracketPos != std::string::npos) {
+ arrSize = type.substr(bracketPos, type.length() - bracketPos);
+ type = type.substr(0, bracketPos);
+ }
+
+ dataElemCopy.setAttribute("id", type + " " + identifier + arrSize);
+
+ assign(dataElemCopy, node, content);
+ dataElemCopy.setAttribute("id", identifier);
+
+ return;
+ }
+
assign(dataElem, node, content);
}
void PromelaDataModel::init(const std::string& location, const Data& data) {
@@ -410,6 +734,10 @@ void PromelaDataModel::init(const std::string& location, const Data& data) {
}
bool PromelaDataModel::isDeclared(const std::string& expr) {
+ PromelaParser parser(expr);
+ if (parser.ast->type == PML_VAR_ARRAY)
+ return _variables.compound.find(parser.ast->operands.front()->value) != _variables.compound.end();
+
return _variables.compound.find(expr) != _variables.compound.end();
}
diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h
index 89078bd..b286f4b 100644
--- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h
+++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h
@@ -41,9 +41,6 @@ public:
return names;
}
- virtual void initialize();
- virtual void setSessionId(const std::string& sessionId);
- virtual void setName(const std::string& name);
virtual void setEvent(const Event& event);
virtual void registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor);
@@ -85,12 +82,21 @@ public:
protected:
+ int dataToInt(const Data& data);
+ bool dataToBool(const Data& data);
+
void evaluateDecl(void* ast);
- int evaluateExpr(void* ast);
+ Data evaluateExpr(void* ast);
void evaluateStmnt(void* ast);
- void setVariable(void* ast, int value);
- int getVariable(void* ast);
+ void evaluateDecl(const std::string& expr);
+ Data evaluateExpr(const std::string& expr);
+ void evaluateStmnt(const std::string& expr);
+
+ void setVariable(void* ast, Data value);
+ Data getVariable(void* ast);
+
+ void adaptType(Data& data);
int _lastMType;
diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp
index d12b7fc..9fed02c 100644
--- a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp
+++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp
@@ -46,17 +46,32 @@ PromelaParser::PromelaParser(const std::string& expr) {
init(expr);
}
-PromelaParser::PromelaParser(const std::string& expr, Type expectedType) {
+PromelaParser::PromelaParser(const std::string& expr, int nrArgs, ...) {
init(expr);
- if (type != expectedType) {
- std::stringstream ss;
- ss << "Promela syntax type mismatch: Expected " << typeToDesc(expectedType) << " but got " << typeToDesc(type);
- ERROR_EXECUTION_THROW(ss.str());
+
+ if (nrArgs == 0)
+ return;
+
+ std::stringstream errSS;
+ std::string seperator;
+ errSS << "Promela syntax type mismatch: Expected {";
+
+ va_list ap;
+ va_start(ap, nrArgs);
+ for(int i = 1; i <= nrArgs; i++) {
+ int expectedType = va_arg(ap, int);
+ if (type == expectedType)
+ return;
+ errSS << seperator << typeToDesc(expectedType);
+ seperator = ", ";
}
+ errSS << "} but got " << typeToDesc(type);
+ ERROR_EXECUTION_THROW(errSS.str());
}
void PromelaParser::init(const std::string& expr) {
ast = NULL;
+ parseInCompound = 0;
input_length = expr.length() + 2; // plus some zero terminators
input = (char*) calloc(1, input_length);
memcpy(input, expr.c_str(), expr.length());
@@ -69,6 +84,7 @@ void PromelaParser::init(const std::string& expr) {
if (pendingException.name.size() > 0) {
// parsing failed in promela_error
destroy();
+ pendingException.data.compound["code"] = Data(expr, Data::VERBATIM);
throw pendingException;
}
}
@@ -234,6 +250,14 @@ std::string PromelaParserNode::typeToDesc(int type) {
return "DECLLIST";
case PML_NAMELIST:
return "NAMELIST";
+ case PML_STRING:
+ return "STRING";
+ case PML_TYPEDEF:
+ return "TYPEDEF";
+ case PML_CMPND:
+ return "CMPND";
+ case PML_ASSERT:
+ return "ASSERT";
default:
return std::string("UNK(") + toStr(type) + ")";
diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.h b/src/uscxml/plugins/datamodel/promela/PromelaParser.h
index 5cf4483..6cf9a81 100644
--- a/src/uscxml/plugins/datamodel/promela/PromelaParser.h
+++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.h
@@ -17,14 +17,14 @@
* @endcond
*/
-// bison -v -d promela-expr.ypp && flex promela-expr.l
-// bison promela-expr.ypp && flex promela-expr.l
+// bison -v promela.ypp && flex promela.l
#ifndef PROMELA_H_9AB78YB1
#define PROMELA_H_9AB78YB1
#include <stdlib.h>
-#include <stdarg.h>
+//#include <stdarg.h>
+#include <cstdarg>
#include "uscxml/Message.h"
@@ -59,13 +59,14 @@ public:
static std::string typeToDesc(int type);
PromelaParser(const std::string& expr);
- PromelaParser(const std::string& expr, Type expectedType);
+ PromelaParser(const std::string& expr, int nrArgs, ...);
virtual ~PromelaParser();
virtual PromelaParserNode* node(int type, int nrArgs, ...);
virtual PromelaParserNode* value(int type, const char* value);
void dump();
+ int parseInCompound;
PromelaParserNode* ast;
Type type;
diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.l b/src/uscxml/plugins/datamodel/promela/parser/promela.l
index 2aaef06..faa134c 100644
--- a/src/uscxml/plugins/datamodel/promela/parser/promela.l
+++ b/src/uscxml/plugins/datamodel/promela/parser/promela.l
@@ -24,7 +24,9 @@ L [a-zA-Z_]
%%
-bit|bool|byte|int|mtype|short|unsigned {
+\/\*([^*]|\*[^/])*\*+\/ /* multiline comments */
+
+bit|bool|byte|int|mtype|short|unsigned|string {
yylval->value = strdup(yytext);
return PML_TYPE;
}
@@ -33,6 +35,8 @@ len { return PML_LEN; }
false|skip|true { yylval->value = strdup(yytext); return PML_CONST; }
printf { return PML_PRINT; }
printm { return PML_PRINTM; }
+typedef { return PML_TYPEDEF; }
+assert { return PML_ASSERT; }
"!" { return PML_NEG; }
"~" { return PML_COMPL; }
@@ -80,13 +84,18 @@ printm { return PML_PRINTM; }
"=" { return PML_ASGN; }
-L?\"(\\.|[^\\"])*\" { yylval->value = strdup(yytext); return(PML_STRING); }
+L?\"(\\.|[^\\"])*\" { yylval->value = strdup(yytext); return(PML_STRING); }
+
+
+L?'(\\.|[^\'])*\' {
+ /* Non PROMELA extension for single quoted string literals */
+ yylval->value = strdup(yytext); return(PML_STRING);
+}
{DIGIT}+ { yylval->value = strdup(yytext); return PML_CONST; }
{ID} { yylval->value = strdup(yytext); return PML_NAME; }
-\'(\\.|[^'])*\' { }
+[ \t\n]+ /* eat up whitespace */
-[ \t\n]+ /* eat up whitespace */
. { /*printf( "Unrecognized character: %s\n", yytext ); */ }
diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.lex.yy.cpp b/src/uscxml/plugins/datamodel/promela/parser/promela.lex.yy.cpp
index 5073be3..13085dc 100644
--- a/src/uscxml/plugins/datamodel/promela/parser/promela.lex.yy.cpp
+++ b/src/uscxml/plugins/datamodel/promela/parser/promela.lex.yy.cpp
@@ -433,28 +433,30 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
yyg->yy_c_buf_p = yy_cp;
/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
-#define YY_NUM_RULES 44
-#define YY_END_OF_BUFFER 45
+#define YY_NUM_RULES 47
+#define YY_END_OF_BUFFER 48
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info {
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[102] = {
+static yyconst flex_int16_t yy_accept[125] = {
0,
- 0, 0, 45, 43, 42, 42, 6, 43, 12, 23,
- 43, 31, 32, 10, 13, 29, 14, 28, 11, 39,
- 30, 19, 37, 20, 40, 40, 33, 34, 24, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 35, 25,
- 36, 7, 42, 21, 0, 38, 0, 26, 0, 41,
- 0, 8, 9, 39, 15, 17, 22, 18, 16, 40,
- 0, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 27, 0, 41, 0, 1, 40, 40,
- 40, 2, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 3, 40, 40, 40, 4, 5, 40, 40,
-
- 0
+ 0, 0, 48, 46, 45, 45, 9, 46, 15, 26,
+ 46, 34, 35, 13, 16, 32, 17, 31, 14, 43,
+ 33, 22, 40, 23, 44, 44, 36, 37, 27, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 38,
+ 28, 39, 10, 45, 24, 0, 41, 0, 29, 0,
+ 42, 0, 11, 12, 0, 43, 18, 20, 25, 21,
+ 19, 44, 0, 0, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 30,
+ 0, 42, 0, 0, 0, 44, 2, 44, 44, 44,
+ 3, 44, 44, 44, 44, 44, 44, 44, 44, 0,
+
+ 1, 44, 44, 44, 44, 44, 4, 44, 44, 44,
+ 1, 44, 44, 44, 44, 44, 8, 5, 6, 44,
+ 44, 7, 44, 0
} ;
static yyconst flex_int32_t yy_ec[256] = {
@@ -498,65 +500,72 @@ static yyconst flex_int32_t yy_meta[51] = {
2, 2, 2, 2, 2, 2, 1, 1, 1, 1
} ;
-static yyconst flex_int16_t yy_base[106] = {
+static yyconst flex_int16_t yy_base[130] = {
0,
- 0, 0, 141, 142, 49, 51, 120, 50, 142, 132,
- 48, 142, 142, 142, 126, 142, 123, 142, 142, 119,
- 142, 38, 115, 39, 0, 129, 142, 142, 142, 26,
- 105, 93, 100, 86, 87, 28, 86, 88, 142, 78,
- 142, 142, 65, 142, 58, 142, 122, 142, 57, 142,
- 66, 142, 142, 107, 142, 142, 142, 142, 142, 0,
- 65, 79, 82, 77, 83, 75, 79, 71, 81, 75,
- 79, 68, 69, 142, 63, 68, 76, 0, 74, 79,
- 66, 0, 67, 61, 57, 57, 66, 61, 64, 63,
- 48, 45, 0, 54, 48, 46, 0, 0, 50, 48,
-
- 142, 101, 103, 75, 105
+ 0, 0, 170, 171, 49, 51, 149, 50, 171, 161,
+ 48, 171, 171, 171, 155, 171, 152, 171, 154, 147,
+ 171, 38, 143, 39, 0, 56, 171, 171, 171, 119,
+ 28, 133, 121, 128, 114, 115, 33, 20, 117, 171,
+ 107, 171, 171, 68, 171, 60, 171, 151, 171, 64,
+ 171, 73, 171, 171, 142, 135, 171, 171, 171, 171,
+ 171, 0, 74, 70, 108, 106, 109, 104, 110, 102,
+ 106, 98, 108, 102, 106, 98, 94, 97, 94, 171,
+ 72, 75, 79, 125, 75, 104, 0, 97, 102, 89,
+ 0, 90, 91, 87, 87, 92, 95, 94, 89, 77,
+
+ 171, 81, 91, 90, 76, 75, 0, 79, 87, 83,
+ 104, 70, 52, 80, 72, 63, 0, 0, 0, 69,
+ 65, 0, 64, 171, 104, 106, 90, 108, 110
} ;
-static yyconst flex_int16_t yy_def[106] = {
+static yyconst flex_int16_t yy_def[130] = {
0,
- 101, 1, 101, 101, 101, 101, 101, 102, 101, 101,
- 103, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 104, 104, 101, 101, 101, 104,
- 104, 104, 104, 104, 104, 104, 104, 104, 101, 101,
- 101, 101, 101, 101, 102, 101, 102, 101, 103, 101,
- 105, 101, 101, 101, 101, 101, 101, 101, 101, 104,
- 102, 104, 104, 104, 104, 104, 104, 104, 104, 104,
- 104, 104, 104, 101, 103, 103, 105, 104, 104, 104,
- 104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
- 104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-
- 0, 101, 101, 101, 101
+ 124, 1, 124, 124, 124, 124, 124, 125, 124, 124,
+ 126, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124, 124, 127, 127, 124, 124, 124, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 124,
+ 124, 124, 124, 124, 124, 125, 124, 125, 124, 126,
+ 124, 128, 124, 124, 129, 124, 124, 124, 124, 124,
+ 124, 127, 125, 126, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 124,
+ 126, 126, 128, 129, 129, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 129,
+
+ 124, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 129, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 0, 124, 124, 124, 124, 124
} ;
-static yyconst flex_int16_t yy_nxt[193] = {
+static yyconst flex_int16_t yy_nxt[222] = {
0,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 4, 28, 29, 25, 30, 25,
- 25, 31, 25, 25, 32, 25, 33, 34, 25, 25,
- 35, 25, 36, 37, 38, 25, 39, 40, 41, 42,
- 43, 43, 43, 43, 46, 50, 55, 56, 58, 59,
- 62, 70, 46, 71, 50, 63, 43, 43, 49, 46,
- 50, 64, 51, 76, 47, 50, 60, 78, 49, 97,
- 100, 51, 47, 76, 99, 98, 96, 51, 78, 47,
- 77, 95, 51, 78, 93, 94, 93, 93, 92, 91,
-
- 77, 45, 45, 49, 49, 75, 75, 90, 89, 78,
- 78, 88, 87, 86, 85, 84, 83, 82, 78, 81,
- 80, 79, 78, 54, 101, 74, 73, 72, 69, 68,
- 67, 66, 65, 61, 57, 54, 53, 52, 48, 44,
- 101, 3, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101
-
+ 24, 25, 26, 27, 4, 28, 29, 30, 31, 25,
+ 25, 32, 25, 25, 33, 25, 34, 35, 25, 25,
+ 36, 25, 37, 38, 39, 25, 40, 41, 42, 43,
+ 44, 44, 44, 44, 47, 51, 57, 58, 60, 61,
+ 63, 77, 66, 64, 47, 78, 74, 67, 75, 44,
+ 44, 51, 52, 68, 48, 50, 76, 51, 47, 51,
+ 82, 50, 51, 118, 48, 100, 82, 85, 52, 119,
+ 101, 62, 111, 87, 52, 123, 52, 83, 48, 52,
+
+ 122, 121, 120, 83, 46, 46, 50, 50, 81, 81,
+ 84, 84, 87, 117, 85, 116, 115, 114, 87, 113,
+ 87, 107, 112, 110, 109, 107, 108, 107, 106, 105,
+ 104, 103, 87, 87, 102, 85, 99, 98, 97, 96,
+ 95, 94, 93, 92, 91, 87, 90, 89, 88, 87,
+ 86, 56, 85, 124, 80, 79, 73, 72, 71, 70,
+ 69, 65, 59, 56, 55, 54, 53, 49, 45, 124,
+ 3, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124
} ;
-static yyconst flex_int16_t yy_chk[193] = {
+static yyconst flex_int16_t yy_chk[222] = {
0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -564,31 +573,34 @@ static yyconst flex_int16_t yy_chk[193] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5, 5, 6, 6, 8, 11, 22, 22, 24, 24,
- 30, 36, 45, 36, 49, 30, 43, 43, 51, 61,
- 75, 30, 11, 51, 8, 76, 104, 100, 77, 95,
- 99, 49, 45, 77, 96, 95, 94, 75, 92, 61,
- 51, 91, 76, 90, 89, 88, 87, 86, 85, 84,
-
- 77, 102, 102, 103, 103, 105, 105, 83, 81, 80,
- 79, 73, 72, 71, 70, 69, 68, 67, 66, 65,
- 64, 63, 62, 54, 47, 40, 38, 37, 35, 34,
- 33, 32, 31, 26, 23, 20, 17, 15, 10, 7,
- 3, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101
-
+ 26, 38, 31, 26, 46, 38, 37, 31, 37, 44,
+ 44, 50, 11, 31, 8, 52, 37, 64, 63, 81,
+ 52, 83, 82, 113, 46, 85, 83, 100, 50, 113,
+ 85, 127, 100, 123, 64, 121, 81, 52, 63, 82,
+
+ 120, 116, 115, 83, 125, 125, 126, 126, 128, 128,
+ 129, 129, 114, 112, 111, 110, 109, 108, 106, 105,
+ 104, 103, 102, 99, 98, 97, 96, 95, 94, 93,
+ 92, 90, 89, 88, 86, 84, 79, 78, 77, 76,
+ 75, 74, 73, 72, 71, 70, 69, 68, 67, 66,
+ 65, 56, 55, 48, 41, 39, 36, 35, 34, 33,
+ 32, 30, 23, 20, 19, 17, 15, 10, 7, 3,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124
} ;
-static yyconst flex_int16_t yy_rule_linenum[44] = {
+static yyconst flex_int16_t yy_rule_linenum[47] = {
0,
- 27, 32, 33, 34, 35, 37, 38, 39, 40, 42,
- 43, 44, 46, 47, 49, 50, 52, 53, 54, 55,
- 57, 58, 60, 61, 62, 65, 66, 68, 69, 70,
- 72, 73, 75, 76, 78, 79, 81, 83, 85, 86,
- 88, 90, 92
+ 27, 29, 34, 35, 36, 37, 38, 39, 41, 42,
+ 43, 44, 46, 47, 48, 50, 51, 53, 54, 56,
+ 57, 58, 59, 61, 62, 64, 65, 66, 69, 70,
+ 72, 73, 74, 76, 77, 79, 80, 82, 83, 85,
+ 87, 90, 95, 96, 98, 101
} ;
/* The intent behind this definition is that it'll catch
@@ -608,7 +620,7 @@ static yyconst flex_int16_t yy_rule_linenum[44] = {
#include "promela.tab.hpp"
#define YYSTYPE PROMELA_STYPE
-#line 614 "promela.lex.yy.cpp"
+#line 626 "promela.lex.yy.cpp"
#define INITIAL 0
@@ -907,7 +919,7 @@ YY_DECL {
#line 25 "promela.l"
-#line 915 "promela.lex.yy.cpp"
+#line 927 "promela.lex.yy.cpp"
yylval = yylval_param;
@@ -967,12 +979,12 @@ yy_match:
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) {
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 102 )
+ if ( yy_current_state >= 125 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
- } while ( yy_current_state != 101 );
+ } while ( yy_current_state != 124 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
@@ -990,13 +1002,13 @@ do_action: /* This label is used only to access EOF actions. */
if ( yy_flex_debug ) {
if ( yy_act == 0 )
fprintf( stderr, "--scanner backing up\n" );
- else if ( yy_act < 44 )
+ else if ( yy_act < 47 )
fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
(long)yy_rule_linenum[yy_act], yytext );
- else if ( yy_act == 44 )
+ else if ( yy_act == 47 )
fprintf( stderr, "--accepting default rule (\"%s\")\n",
yytext );
- else if ( yy_act == 45 )
+ else if ( yy_act == 48 )
fprintf( stderr, "--(end of buffer or a NUL)\n" );
else
fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -1013,232 +1025,252 @@ do_action: /* This label is used only to access EOF actions. */
goto yy_find_action;
case 1:
+ /* rule 1 can match eol */
YY_RULE_SETUP
#line 27 "promela.l"
+ /* multiline comments */
+ YY_BREAK
+ case 2:
+ YY_RULE_SETUP
+#line 29 "promela.l"
{
yylval->value = strdup(yytext);
return PML_TYPE;
}
YY_BREAK
- case 2:
- YY_RULE_SETUP
-#line 32 "promela.l"
- { return PML_LEN; }
- YY_BREAK
case 3:
YY_RULE_SETUP
-#line 33 "promela.l"
- { yylval->value = strdup(yytext); return PML_CONST; }
+#line 34 "promela.l"
+ { return PML_LEN; }
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 34 "promela.l"
- { return PML_PRINT; }
+#line 35 "promela.l"
+ { yylval->value = strdup(yytext); return PML_CONST; }
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 35 "promela.l"
- { return PML_PRINTM; }
+#line 36 "promela.l"
+ { return PML_PRINT; }
YY_BREAK
case 6:
YY_RULE_SETUP
#line 37 "promela.l"
- { return PML_NEG; }
+ { return PML_PRINTM; }
YY_BREAK
case 7:
YY_RULE_SETUP
#line 38 "promela.l"
- { return PML_COMPL; }
+ { return PML_TYPEDEF; }
YY_BREAK
case 8:
YY_RULE_SETUP
#line 39 "promela.l"
- { return PML_INCR; }
+ { return PML_ASSERT; }
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 40 "promela.l"
- { return PML_DECR; }
+#line 41 "promela.l"
+ { return PML_NEG; }
YY_BREAK
case 10:
YY_RULE_SETUP
#line 42 "promela.l"
- { return PML_TIMES; }
+ { return PML_COMPL; }
YY_BREAK
case 11:
YY_RULE_SETUP
#line 43 "promela.l"
- { return PML_DIVIDE; }
+ { return PML_INCR; }
YY_BREAK
case 12:
YY_RULE_SETUP
#line 44 "promela.l"
- { return PML_MODULO; }
+ { return PML_DECR; }
YY_BREAK
case 13:
YY_RULE_SETUP
#line 46 "promela.l"
- { return PML_PLUS; }
+ { return PML_TIMES; }
YY_BREAK
case 14:
YY_RULE_SETUP
#line 47 "promela.l"
- { return PML_MINUS; }
+ { return PML_DIVIDE; }
YY_BREAK
case 15:
YY_RULE_SETUP
-#line 49 "promela.l"
- { return PML_LSHIFT; }
+#line 48 "promela.l"
+ { return PML_MODULO; }
YY_BREAK
case 16:
YY_RULE_SETUP
#line 50 "promela.l"
- { return PML_RSHIFT; }
+ { return PML_PLUS; }
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 52 "promela.l"
- { return PML_LE; }
+#line 51 "promela.l"
+ { return PML_MINUS; }
YY_BREAK
case 18:
YY_RULE_SETUP
#line 53 "promela.l"
- { return PML_GE; }
+ { return PML_LSHIFT; }
YY_BREAK
case 19:
YY_RULE_SETUP
#line 54 "promela.l"
- { return PML_LT; }
+ { return PML_RSHIFT; }
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 55 "promela.l"
- { return PML_GT; }
+#line 56 "promela.l"
+ { return PML_LE; }
YY_BREAK
case 21:
YY_RULE_SETUP
#line 57 "promela.l"
- { return PML_NE; }
+ { return PML_GE; }
YY_BREAK
case 22:
YY_RULE_SETUP
#line 58 "promela.l"
- { return PML_EQ; }
+ { return PML_LT; }
YY_BREAK
case 23:
YY_RULE_SETUP
-#line 60 "promela.l"
- { return PML_BITAND; }
+#line 59 "promela.l"
+ { return PML_GT; }
YY_BREAK
case 24:
YY_RULE_SETUP
#line 61 "promela.l"
- { return PML_BITXOR; }
+ { return PML_NE; }
YY_BREAK
case 25:
YY_RULE_SETUP
#line 62 "promela.l"
- { return PML_BITOR; }
+ { return PML_EQ; }
YY_BREAK
case 26:
YY_RULE_SETUP
-#line 65 "promela.l"
- { return PML_AND; }
+#line 64 "promela.l"
+ { return PML_BITAND; }
YY_BREAK
case 27:
YY_RULE_SETUP
-#line 66 "promela.l"
- { return PML_OR; }
+#line 65 "promela.l"
+ { return PML_BITXOR; }
YY_BREAK
case 28:
YY_RULE_SETUP
-#line 68 "promela.l"
- { return PML_DOT; }
+#line 66 "promela.l"
+ { return PML_BITOR; }
YY_BREAK
case 29:
YY_RULE_SETUP
#line 69 "promela.l"
- { return PML_COMMA; }
+ { return PML_AND; }
YY_BREAK
case 30:
YY_RULE_SETUP
#line 70 "promela.l"
- { return PML_SEMI; }
+ { return PML_OR; }
YY_BREAK
case 31:
YY_RULE_SETUP
#line 72 "promela.l"
- { return '('; }
+ { return PML_DOT; }
YY_BREAK
case 32:
YY_RULE_SETUP
#line 73 "promela.l"
- { return ')'; }
+ { return PML_COMMA; }
YY_BREAK
case 33:
YY_RULE_SETUP
-#line 75 "promela.l"
- { return '['; }
+#line 74 "promela.l"
+ { return PML_SEMI; }
YY_BREAK
case 34:
YY_RULE_SETUP
#line 76 "promela.l"
- { return ']'; }
+ { return '('; }
YY_BREAK
case 35:
YY_RULE_SETUP
-#line 78 "promela.l"
- { return '{'; }
+#line 77 "promela.l"
+ { return ')'; }
YY_BREAK
case 36:
YY_RULE_SETUP
#line 79 "promela.l"
- { return '}'; }
+ { return '['; }
YY_BREAK
case 37:
YY_RULE_SETUP
-#line 81 "promela.l"
- { return PML_ASGN; }
+#line 80 "promela.l"
+ { return ']'; }
YY_BREAK
case 38:
- /* rule 38 can match eol */
YY_RULE_SETUP
-#line 83 "promela.l"
- { yylval->value = strdup(yytext); return(PML_STRING); }
+#line 82 "promela.l"
+ { return '{'; }
YY_BREAK
case 39:
YY_RULE_SETUP
-#line 85 "promela.l"
- { yylval->value = strdup(yytext); return PML_CONST; }
+#line 83 "promela.l"
+ { return '}'; }
YY_BREAK
case 40:
YY_RULE_SETUP
-#line 86 "promela.l"
- { yylval->value = strdup(yytext); return PML_NAME; }
+#line 85 "promela.l"
+ { return PML_ASGN; }
YY_BREAK
case 41:
/* rule 41 can match eol */
YY_RULE_SETUP
-#line 88 "promela.l"
- { }
+#line 87 "promela.l"
+ { yylval->value = strdup(yytext); return(PML_STRING); }
YY_BREAK
case 42:
/* rule 42 can match eol */
YY_RULE_SETUP
#line 90 "promela.l"
- /* eat up whitespace */
+ {
+ /* Non PROMELA extension for single quoted string literals */
+ yylval->value = strdup(yytext);
+ return(PML_STRING);
+ }
YY_BREAK
case 43:
YY_RULE_SETUP
-#line 92 "promela.l"
- { /*printf( "Unrecognized character: %s\n", yytext ); */ }
+#line 95 "promela.l"
+ { yylval->value = strdup(yytext); return PML_CONST; }
YY_BREAK
case 44:
YY_RULE_SETUP
-#line 93 "promela.l"
+#line 96 "promela.l"
+ { yylval->value = strdup(yytext); return PML_NAME; }
+ YY_BREAK
+ case 45:
+ /* rule 45 can match eol */
+ YY_RULE_SETUP
+#line 98 "promela.l"
+ /* eat up whitespace */
+ YY_BREAK
+ case 46:
+ YY_RULE_SETUP
+#line 101 "promela.l"
+ { /*printf( "Unrecognized character: %s\n", yytext ); */ }
+ YY_BREAK
+ case 47:
+ YY_RULE_SETUP
+#line 102 "promela.l"
ECHO;
YY_BREAK
-#line 1253 "promela.lex.yy.cpp"
+#line 1284 "promela.lex.yy.cpp"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -1535,7 +1567,7 @@ static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) {
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 102 )
+ if ( yy_current_state >= 125 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1567,11 +1599,11 @@ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) {
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 102 )
+ if ( yy_current_state >= 125 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 101);
+ yy_is_jam = (yy_current_state == 124);
return yy_is_jam ? 0 : yy_current_state;
}
@@ -2489,4 +2521,4 @@ void promela_free (void * ptr , yyscan_t yyscanner) {
/* %ok-for-header */
-#line 93 "promela.l"
+#line 102 "promela.l"
diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp
index ad4581f..67501fa 100644
--- a/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp
+++ b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp
@@ -202,7 +202,8 @@ enum promela_tokentype {
PML_INCR = 326,
PML_COMPL = 327,
PML_NEG = 328,
- PML_DOT = 329
+ PML_CMPND = 329,
+ PML_DOT = 330
};
#endif
@@ -217,7 +218,7 @@ typedef union PROMELA_STYPE {
/* Line 387 of yacc.c */
-#line 222 "promela.tab.cpp"
+#line 223 "promela.tab.cpp"
} PROMELA_STYPE;
# define PROMELA_STYPE_IS_TRIVIAL 1
# define promela_stype PROMELA_STYPE /* obsolescent; will be withdrawn */
@@ -244,7 +245,7 @@ int promela_parse ();
/* Copy the second part of user declarations. */
/* Line 390 of yacc.c */
-#line 249 "promela.tab.cpp"
+#line 250 "promela.tab.cpp"
#ifdef short
# undef short
@@ -470,22 +471,22 @@ union yyalloc {
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 33
+#define YYFINAL 34
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 304
+#define YYLAST 311
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 81
+#define YYNTOKENS 82
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 23
/* YYNRULES -- Number of rules. */
-#define YYNRULES 83
+#define YYNRULES 85
/* YYNRULES -- Number of states. */
-#define YYNSTATES 146
+#define YYNSTATES 152
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 329
+#define YYMAXUTOK 330
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -524,67 +525,69 @@ static const yytype_uint8 yytranslate[] = {
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 76, 77, 78, 79, 80
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ 81
};
#if PROMELA_DEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
static const yytype_uint16 yyprhs[] = {
- 0, 0, 3, 5, 7, 9, 11, 13, 18, 19,
- 23, 24, 27, 31, 35, 39, 43, 47, 51, 55,
- 59, 63, 67, 71, 75, 79, 83, 87, 91, 95,
- 99, 103, 106, 109, 114, 116, 118, 119, 121, 123,
- 125, 129, 133, 140, 142, 145, 149, 151, 155, 157,
- 161, 163, 167, 172, 174, 177, 181, 185, 189, 193,
- 197, 201, 203, 206, 209, 211, 214, 218, 220, 224,
- 227, 230, 236, 241, 246, 249, 251, 252, 261, 262,
- 264, 265, 268, 270
+ 0, 0, 3, 5, 7, 9, 11, 13, 18, 21,
+ 22, 25, 29, 33, 37, 41, 45, 49, 53, 57,
+ 61, 65, 69, 73, 77, 81, 85, 89, 93, 97,
+ 101, 104, 107, 112, 114, 116, 118, 119, 121, 123,
+ 125, 129, 133, 140, 143, 149, 151, 154, 158, 160,
+ 164, 166, 170, 172, 176, 181, 183, 186, 190, 194,
+ 198, 202, 206, 210, 212, 215, 218, 220, 223, 227,
+ 229, 233, 236, 239, 245, 250, 255, 258, 260, 261,
+ 270, 271, 273, 274, 277, 279
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] = {
- 82, 0, -1, 91, -1, 88, -1, 97, -1, 85,
- -1, 48, -1, 48, 13, 88, 14, -1, -1, 84,
- 86, 87, -1, -1, 80, 85, -1, 11, 88, 12,
- -1, 88, 72, 88, -1, 88, 71, 88, -1, 88,
- 75, 88, -1, 88, 74, 88, -1, 88, 73, 88,
- -1, 88, 60, 88, -1, 88, 61, 88, -1, 88,
- 62, 88, -1, 88, 68, 88, -1, 88, 67, 88,
- -1, 88, 66, 88, -1, 88, 65, 88, -1, 88,
- 64, 88, -1, 88, 63, 88, -1, 88, 58, 88,
- -1, 88, 59, 88, -1, 88, 70, 88, -1, 88,
- 69, 88, -1, 79, 88, -1, 71, 88, -1, 20,
- 11, 83, 12, -1, 83, -1, 45, -1, -1, 42,
- -1, 43, -1, 44, -1, 89, 46, 92, -1, 89,
- 49, 92, -1, 89, 46, 57, 15, 96, 16, -1,
- 90, -1, 90, 31, -1, 90, 31, 91, -1, 93,
- -1, 93, 56, 92, -1, 94, -1, 94, 57, 88,
- -1, 48, -1, 48, 8, 45, -1, 48, 13, 95,
- 14, -1, 45, -1, 71, 95, -1, 11, 95, 12,
- -1, 95, 72, 95, -1, 95, 71, 95, -1, 95,
- 75, 95, -1, 95, 74, 95, -1, 95, 73, 95,
- -1, 48, -1, 96, 48, -1, 96, 56, -1, 98,
- -1, 98, 31, -1, 98, 31, 97, -1, 99, -1,
- 83, 57, 88, -1, 83, 77, -1, 83, 76, -1,
- 18, 11, 21, 102, 12, -1, 19, 11, 83, 12,
- -1, 19, 11, 45, 12, -1, 17, 88, -1, 88,
- -1, -1, 83, 57, 51, 100, 11, 101, 12, 99,
- -1, -1, 103, -1, -1, 56, 103, -1, 88, -1,
- 88, 56, 103, -1
+ 83, 0, -1, 92, -1, 88, -1, 98, -1, 86,
+ -1, 48, -1, 48, 13, 88, 14, -1, 85, 87,
+ -1, -1, 81, 86, -1, 11, 88, 12, -1, 88,
+ 72, 88, -1, 88, 71, 88, -1, 88, 75, 88,
+ -1, 88, 74, 88, -1, 88, 73, 88, -1, 88,
+ 60, 88, -1, 88, 61, 88, -1, 88, 62, 88,
+ -1, 88, 68, 88, -1, 88, 67, 88, -1, 88,
+ 66, 88, -1, 88, 65, 88, -1, 88, 64, 88,
+ -1, 88, 63, 88, -1, 88, 58, 88, -1, 88,
+ 59, 88, -1, 88, 70, 88, -1, 88, 69, 88,
+ -1, 79, 88, -1, 71, 88, -1, 20, 11, 84,
+ 12, -1, 84, -1, 45, -1, 21, -1, -1, 42,
+ -1, 43, -1, 44, -1, 89, 46, 93, -1, 89,
+ 49, 93, -1, 89, 46, 57, 15, 97, 16, -1,
+ 89, 91, -1, 22, 48, 15, 92, 16, -1, 90,
+ -1, 90, 31, -1, 90, 31, 92, -1, 94, -1,
+ 94, 56, 93, -1, 95, -1, 95, 57, 88, -1,
+ 48, -1, 48, 8, 45, -1, 48, 13, 96, 14,
+ -1, 45, -1, 71, 96, -1, 11, 96, 12, -1,
+ 96, 72, 96, -1, 96, 71, 96, -1, 96, 75,
+ 96, -1, 96, 74, 96, -1, 96, 73, 96, -1,
+ 48, -1, 97, 48, -1, 97, 56, -1, 99, -1,
+ 99, 31, -1, 99, 31, 98, -1, 100, -1, 84,
+ 57, 88, -1, 84, 77, -1, 84, 76, -1, 18,
+ 11, 21, 103, 12, -1, 19, 11, 84, 12, -1,
+ 19, 11, 45, 12, -1, 17, 88, -1, 88, -1,
+ -1, 84, 57, 51, 101, 11, 102, 12, 100, -1,
+ -1, 104, -1, -1, 56, 104, -1, 88, -1, 88,
+ 56, 104, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const yytype_uint8 yyrline[] = {
- 0, 84, 84, 88, 92, 98, 101, 102, 105, 105,
- 109, 110, 120, 121, 122, 123, 124, 125, 126, 127,
- 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
- 138, 139, 140, 142, 143, 144, 148, 149, 150, 151,
- 154, 155, 156, 159, 160, 161, 171, 172, 175, 176,
- 179, 180, 181, 184, 185, 186, 187, 188, 189, 190,
- 191, 194, 195, 204, 207, 208, 209, 212, 215, 216,
- 217, 218, 219, 220, 221, 222, 223, 223, 226, 227,
- 230, 231, 234, 235
+static const yytype_uint16 yyrline[] = {
+ 0, 84, 84, 88, 92, 98, 101, 102, 105, 132,
+ 133, 143, 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
+ 162, 163, 165, 166, 167, 168, 174, 175, 176, 177,
+ 180, 181, 182, 183, 186, 189, 190, 191, 201, 202,
+ 205, 206, 209, 210, 211, 214, 215, 216, 217, 218,
+ 219, 220, 221, 224, 225, 234, 237, 238, 239, 242,
+ 245, 246, 247, 248, 249, 250, 251, 252, 253, 253,
+ 256, 257, 260, 261, 264, 265
};
#endif
@@ -606,10 +609,10 @@ static const char *const yytname[] = {
"PML_BITOR", "PML_NE", "PML_EQ", "PML_LE", "PML_GE", "PML_LT", "PML_GT",
"PML_RSHIFT", "PML_LSHIFT", "PML_MINUS", "PML_PLUS", "PML_MODULO",
"PML_DIVIDE", "PML_TIMES", "PML_DECR", "PML_INCR", "PML_COMPL",
- "PML_NEG", "PML_DOT", "$accept", "program", "varref", "pfld", "cmpnd",
- "$@1", "sfld", "expr", "vis", "one_decl", "decl_lst", "var_list", "ivar",
- "vardcl", "const_expr", "nlst", "stmnt_lst", "stmnt", "Stmnt", "$@2",
- "args", "prargs", "arg", YY_NULL
+ "PML_NEG", "PML_CMPND", "PML_DOT", "$accept", "program", "varref",
+ "pfld", "cmpnd", "sfld", "expr", "vis", "one_decl", "utype", "decl_lst",
+ "var_list", "ivar", "vardcl", "const_expr", "nlst", "stmnt_lst", "stmnt",
+ "Stmnt", "$@1", "args", "prargs", "arg", YY_NULL
};
#endif
@@ -625,188 +628,193 @@ static const yytype_uint16 yytoknum[] = {
299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
309, 310, 311, 312, 313, 314, 315, 316, 317, 318,
319, 320, 321, 322, 323, 324, 325, 326, 327, 328,
- 329
+ 329, 330
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] = {
- 0, 81, 82, 82, 82, 83, 84, 84, 86, 85,
- 87, 87, 88, 88, 88, 88, 88, 88, 88, 88,
+ 0, 82, 83, 83, 83, 84, 85, 85, 86, 87,
+ 87, 88, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 89, 89, 89, 89,
- 90, 90, 90, 91, 91, 91, 92, 92, 93, 93,
- 94, 94, 94, 95, 95, 95, 95, 95, 95, 95,
- 95, 96, 96, 96, 97, 97, 97, 98, 99, 99,
- 99, 99, 99, 99, 99, 99, 100, 99, 101, 101,
- 102, 102, 103, 103
+ 90, 90, 90, 90, 91, 92, 92, 92, 93, 93,
+ 94, 94, 95, 95, 95, 96, 96, 96, 96, 96,
+ 96, 96, 96, 97, 97, 97, 98, 98, 98, 99,
+ 100, 100, 100, 100, 100, 100, 100, 100, 101, 100,
+ 102, 102, 103, 103, 104, 104
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const yytype_uint8 yyr2[] = {
- 0, 2, 1, 1, 1, 1, 1, 4, 0, 3,
- 0, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 0, 2, 1, 1, 1, 1, 1, 4, 2, 0,
+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 2, 2, 4, 1, 1, 0, 1, 1, 1,
- 3, 3, 6, 1, 2, 3, 1, 3, 1, 3,
- 1, 3, 4, 1, 2, 3, 3, 3, 3, 3,
- 3, 1, 2, 2, 1, 2, 3, 1, 3, 2,
- 2, 5, 4, 4, 2, 1, 0, 8, 0, 1,
- 0, 2, 1, 3
+ 2, 2, 4, 1, 1, 1, 0, 1, 1, 1,
+ 3, 3, 6, 2, 5, 1, 2, 3, 1, 3,
+ 1, 3, 1, 3, 4, 1, 2, 3, 3, 3,
+ 3, 3, 3, 1, 2, 2, 1, 2, 3, 1,
+ 3, 2, 2, 5, 4, 4, 2, 1, 0, 8,
+ 0, 1, 0, 2, 1, 3
};
/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
Performed when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint8 yydefact[] = {
- 36, 0, 0, 0, 0, 0, 37, 38, 39, 35,
- 6, 0, 0, 0, 34, 8, 5, 3, 0, 43,
- 2, 4, 64, 67, 34, 0, 74, 0, 0, 0,
- 0, 32, 31, 1, 0, 70, 69, 10, 0, 0,
+ 36, 0, 0, 0, 0, 0, 35, 37, 38, 39,
+ 34, 6, 0, 0, 0, 33, 9, 5, 3, 0,
+ 45, 2, 4, 66, 69, 33, 0, 76, 0, 0,
+ 0, 0, 31, 30, 1, 0, 72, 71, 0, 8,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 36, 65,
- 12, 80, 0, 0, 0, 0, 76, 68, 0, 9,
- 27, 28, 18, 19, 20, 26, 25, 24, 23, 22,
- 21, 30, 29, 14, 13, 17, 16, 15, 50, 0,
- 40, 46, 48, 41, 45, 75, 66, 0, 0, 73,
- 72, 33, 7, 0, 11, 0, 0, 0, 0, 0,
- 82, 81, 71, 78, 51, 0, 53, 0, 0, 61,
- 0, 47, 49, 0, 0, 79, 0, 54, 52, 0,
- 0, 0, 0, 0, 42, 62, 63, 83, 0, 55,
- 57, 56, 60, 59, 58, 77
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 43, 36, 67, 11, 82, 0, 0, 0, 0,
+ 78, 70, 10, 26, 27, 17, 18, 19, 25, 24,
+ 23, 22, 21, 20, 29, 28, 13, 12, 16, 15,
+ 14, 0, 52, 0, 40, 48, 50, 41, 47, 77,
+ 68, 0, 0, 75, 74, 32, 7, 0, 36, 0,
+ 0, 0, 0, 0, 84, 83, 73, 80, 0, 53,
+ 0, 55, 0, 0, 63, 0, 49, 51, 0, 0,
+ 81, 44, 0, 56, 54, 0, 0, 0, 0, 0,
+ 42, 64, 65, 85, 0, 57, 59, 58, 62, 61,
+ 60, 79
};
/* YYDEFGOTO[NTERM-NUM]. */
-static const yytype_int8 yydefgoto[] = {
- -1, 13, 24, 15, 16, 37, 69, 110, 18, 19,
- 20, 90, 91, 92, 118, 120, 21, 22, 23, 103,
- 124, 98, 111
+static const yytype_int16 yydefgoto[] = {
+ -1, 14, 25, 16, 17, 39, 114, 19, 20, 61,
+ 21, 94, 95, 96, 123, 125, 22, 23, 24, 107,
+ 129, 102, 115
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -109
+#define YYPACT_NINF -112
static const yytype_int16 yypact[] = {
- 46, 65, 65, -5, 7, 9, -109, -109, -109, -109,
- 8, 65, 65, 33, -53, -109, -109, 155, -36, 5,
- -109, -109, 6, -109, -109, 87, 193, 54, -29, 36,
- 65, -1, -109, -109, 60, -109, -109, 13, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, -40, 38, 35, 50,
- -109, 25, 71, 75, 84, 110, -109, 193, 36, -109,
- 209, 209, 222, 222, 222, 170, 170, 229, 229, 229,
- 229, -46, -46, -1, -1, -109, -109, -109, 1, 82,
- -109, 51, 49, -109, -109, 193, -109, 65, 100, -109,
- -109, -109, -109, 103, -109, 70, 11, 68, 38, 65,
- 136, -109, -109, 65, -109, 11, -109, 11, 116, -109,
- 44, -109, 193, 65, 106, -109, 92, 28, -109, 11,
- 11, 11, 11, 11, -109, -109, -109, -109, 50, -109,
- 28, 28, -109, -109, -109, -109
+ 50, 66, 66, 5, 8, 25, -112, -112, -112, -112,
+ -112, 26, 66, 66, 62, -52, -8, -112, 159, -12,
+ 45, -112, -112, 57, -112, -112, 91, 200, 70, -37,
+ 41, 66, 10, -112, -112, 54, -112, -112, 41, -112,
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 48, -39,
+ 49, -112, 193, 61, -112, 51, 88, 89, 92, 114,
+ -112, 200, -112, 216, 216, 229, 229, 229, 133, 133,
+ 236, 236, 236, 236, -45, -45, 10, 10, -112, -112,
+ -112, 95, 7, 97, -112, 64, 67, -112, -112, 200,
+ -112, 66, 111, -112, -112, -112, -112, 115, -21, 82,
+ -7, 83, 49, 66, 182, -112, -112, 66, 118, -112,
+ -7, -112, -7, 44, -112, 74, -112, 200, 66, 123,
+ -112, -112, 96, 68, -112, -7, -7, -7, -7, -7,
+ -112, -112, -112, -112, 61, -112, 68, 68, -112, -112,
+ -112, -112
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] = {
- -109, -109, 3, -109, 52, -109, -109, 0, -109, -109,
- 61, -50, -109, -109, 117, -109, 63, -109, -15, -109,
- -109, -109, -108
+ -112, -112, 3, -112, 98, -112, 0, -112, -112, -112,
+ -48, -53, -112, -112, 75, -112, 76, -112, -6, -112,
+ -112, -112, -111
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -76
+#define YYTABLE_NINF -78
static const yytype_int16 yytable[] = {
- 17, 25, 26, 14, 34, 125, 27, 93, 88, 105,
- 56, 31, 32, 57, 106, 137, 62, 89, 28, 10,
- 29, 30, 115, 35, 36, 51, 52, 53, 54, 55,
- 65, 63, 64, 33, 67, -44, 58, 59, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
- 82, 83, 84, 85, 86, 87, 116, 1, 121, 95,
- 134, 1, 14, 2, 3, 4, 5, 2, 3, 4,
- 5, 1, 53, 54, 55, 61, 1, 6, 7, 8,
- 5, 97, 117, 99, 10, 5, 88, 100, 6, 7,
- 8, 9, 135, 68, 10, 9, 101, 107, 10, 60,
- 136, 131, 132, 133, 139, 9, 109, 108, 10, 122,
- 9, 66, 112, 10, 113, 114, 119, 11, 138, 94,
- 104, 11, 96, 145, 102, 12, 0, 0, 0, 12,
- 128, 11, 0, 0, 0, 0, 11, 0, 95, 12,
- 0, 14, 0, 0, 12, 38, 39, 40, 41, 42,
+ 18, 26, 27, 15, 120, 35, 130, 97, 66, 92,
+ 58, 11, 32, 33, 98, 109, 28, 143, 93, 29,
+ 110, 7, 8, 9, 36, 37, 53, 54, 55, 56,
+ 57, 69, 67, 68, 59, 71, 30, 60, 121, 31,
+ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 90, 134, 126,
+ 118, 1, 34, 99, 122, 1, 15, 2, 3, 4,
+ 5, 6, 1, 38, 5, 6, 62, 1, 2, 3,
+ 4, 5, 6, 55, 56, 57, 5, 6, 63, 11,
+ 140, 65, 7, 8, 9, 10, 91, 92, 11, 10,
+ 103, 104, 11, 64, 105, 70, 10, 101, 145, 11,
+ 108, 10, 111, 127, 11, 135, 136, 137, 138, 139,
+ 112, 12, 141, 116, 113, 12, 117, 119, 106, 13,
+ 142, 124, 12, 13, 131, 144, 72, 12, 151, 100,
+ 13, 137, 138, 139, 99, 13, 0, 15, 0, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 135, 136, 137,
+ 138, 139, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ -77, 0, 0, -46, 0, 132, 0, 133, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, -46,
+ 146, 147, 148, 149, 150, 0, 0, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 129, 130, 131, 132, 133, 38, 39,
+ 53, 54, 55, 56, 57, 7, 8, 9, 128, 0,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, -75, 129, 130, 131,
- 132, 133, 123, 0, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 0, 38, 39, 40, 41, 42, 43, 44,
- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 0, 126, 0, 127, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, 140, 141, 142, 143,
- 144, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54, 55, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 55, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 49, 50,
- 51, 52, 53, 54, 55
+ 50, 51, 52, 53, 54, 55, 56, 57, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 51, 52, 53, 54, 55,
+ 56, 57
};
#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-109)))
+ (!!((Yystate) == (-112)))
#define yytable_value_is_error(Yytable_value) \
YYID (0)
static const yytype_int16 yycheck[] = {
- 0, 1, 2, 0, 57, 113, 11, 57, 48, 8,
- 46, 11, 12, 49, 13, 123, 45, 57, 11, 48,
- 11, 13, 11, 76, 77, 71, 72, 73, 74, 75,
- 30, 28, 29, 0, 34, 0, 31, 31, 38, 39,
+ 0, 1, 2, 0, 11, 57, 117, 60, 45, 48,
+ 22, 48, 12, 13, 62, 8, 11, 128, 57, 11,
+ 13, 42, 43, 44, 76, 77, 71, 72, 73, 74,
+ 75, 31, 29, 30, 46, 35, 11, 49, 45, 13,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, 45, 11, 108, 59,
- 16, 11, 59, 17, 18, 19, 20, 17, 18, 19,
- 20, 11, 73, 74, 75, 21, 11, 42, 43, 44,
- 20, 56, 71, 12, 48, 20, 48, 12, 42, 43,
- 44, 45, 48, 80, 48, 45, 12, 15, 48, 12,
- 56, 73, 74, 75, 12, 45, 57, 56, 48, 109,
- 45, 51, 12, 48, 11, 45, 48, 71, 12, 58,
- 68, 71, 59, 138, 14, 79, -1, -1, -1, 79,
- 14, 71, -1, -1, -1, -1, 71, -1, 138, 79,
- -1, 138, -1, -1, 79, 58, 59, 60, 61, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, 71, 72, 73, 74, 75, 58, 59,
+ 50, 51, 52, 53, 54, 55, 56, 57, 14, 112,
+ 108, 11, 0, 63, 71, 11, 63, 17, 18, 19,
+ 20, 21, 11, 81, 20, 21, 31, 11, 17, 18,
+ 19, 20, 21, 73, 74, 75, 20, 21, 31, 48,
+ 16, 21, 42, 43, 44, 45, 48, 48, 48, 45,
+ 12, 12, 48, 12, 12, 51, 45, 56, 12, 48,
+ 15, 45, 15, 113, 48, 71, 72, 73, 74, 75,
+ 56, 71, 48, 12, 57, 71, 11, 45, 14, 79,
+ 56, 48, 71, 79, 16, 12, 38, 71, 144, 63,
+ 79, 73, 74, 75, 144, 79, -1, 144, -1, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74, 75, 71, 72, 73,
+ 74, 75, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 31, -1, -1, 0, -1, 120, -1, 122, 65, 66,
+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 16,
+ 135, 136, 137, 138, 139, -1, -1, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 42, 43, 44, 56, -1,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 75, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, 31, 71, 72, 73,
- 74, 75, 56, -1, 58, 59, 60, 61, 62, 63,
+ 70, 71, 72, 73, 74, 75, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, -1, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, -1, 115, -1, 117, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, 129, 130, 131, 132,
- 133, 58, 59, 60, 61, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, 60,
- 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 72, 73, 74, 75, 69, 70,
- 71, 72, 73, 74, 75
+ 74, 75, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 69, 70, 71, 72, 73,
+ 74, 75
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] = {
- 0, 11, 17, 18, 19, 20, 42, 43, 44, 45,
- 48, 71, 79, 82, 83, 84, 85, 88, 89, 90,
- 91, 97, 98, 99, 83, 88, 88, 11, 11, 11,
- 13, 88, 88, 0, 57, 76, 77, 86, 58, 59,
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, 46, 49, 31, 31,
- 12, 21, 45, 83, 83, 88, 51, 88, 80, 87,
+ 0, 11, 17, 18, 19, 20, 21, 42, 43, 44,
+ 45, 48, 71, 79, 83, 84, 85, 86, 88, 89,
+ 90, 92, 98, 99, 100, 84, 88, 88, 11, 11,
+ 11, 13, 88, 88, 0, 57, 76, 77, 81, 87,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 75, 22, 46,
+ 49, 91, 31, 31, 12, 21, 45, 84, 84, 88,
+ 51, 88, 86, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88, 48, 57,
- 92, 93, 94, 92, 91, 88, 97, 56, 102, 12,
- 12, 12, 14, 100, 85, 8, 13, 15, 56, 57,
- 88, 103, 12, 11, 45, 11, 45, 71, 95, 48,
- 96, 92, 88, 56, 101, 103, 95, 95, 14, 71,
- 72, 73, 74, 75, 16, 48, 56, 103, 12, 12,
- 95, 95, 95, 95, 95, 99
+ 88, 48, 48, 57, 93, 94, 95, 93, 92, 88,
+ 98, 56, 103, 12, 12, 12, 14, 101, 15, 8,
+ 13, 15, 56, 57, 88, 104, 12, 11, 92, 45,
+ 11, 45, 71, 96, 48, 97, 93, 88, 56, 102,
+ 104, 16, 96, 96, 14, 71, 72, 73, 74, 75,
+ 16, 48, 56, 104, 12, 12, 96, 96, 96, 96,
+ 96, 100
};
#define yyerrok (yyerrstatus = 0)
@@ -1632,7 +1640,9 @@ yyreduce:
case 5:
/* Line 1787 of yacc.c */
#line 98 "promela.ypp"
- {}
+ {
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ }
break;
case 6:
@@ -1655,222 +1665,257 @@ yyreduce:
case 8:
/* Line 1787 of yacc.c */
-#line 105 "promela.ypp"
- {}
+#line 106 "promela.ypp"
+ {
+ if ((yyvsp[(2) - (2)].node) != NULL) {
+ if ((yyvsp[(2) - (2)].node)->type == PML_CMPND) {
+ (yyval.node) = ctx->node(PML_CMPND, 1, (yyvsp[(1) - (2)].node));
+ (yyval.node)->merge((yyvsp[(2) - (2)].node));
+ delete (yyvsp[(2) - (2)].node);
+ } else {
+ (yyval.node) = ctx->node(PML_CMPND, 2, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
+ }
+ } else {
+ /* $$ = ctx->node(PML_CMPND, 1, $1);*/
+ (yyval.node) = (yyvsp[(1) - (2)].node);
+ }
+ /* if ($2 != NULL) {
+ $$ = ctx->node(PML_CMPND, 1, $1);
+ if ($2->operands.size() > 0) {
+ $$->merge($2);
+ delete $2;
+ } else {
+ $$->push($2);
+ }
+ } else {
+ $$ = $1;
+ }
+ */
+ }
break;
case 9:
/* Line 1787 of yacc.c */
-#line 106 "promela.ypp"
- {}
+#line 132 "promela.ypp"
+ {
+ (yyval.node) = NULL;
+ }
break;
case 10:
/* Line 1787 of yacc.c */
-#line 109 "promela.ypp"
- {}
+#line 133 "promela.ypp"
+ {
+ (yyval.node) = (yyvsp[(2) - (2)].node);
+ }
break;
case 11:
/* Line 1787 of yacc.c */
-#line 110 "promela.ypp"
- {}
+#line 143 "promela.ypp"
+ {
+ (yyval.node) = (yyvsp[(2) - (3)].node);
+ }
break;
case 12:
/* Line 1787 of yacc.c */
-#line 120 "promela.ypp"
+#line 144 "promela.ypp"
{
- (yyval.node) = (yyvsp[(2) - (3)].node);
+ (yyval.node) = ctx->node(PML_PLUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 13:
/* Line 1787 of yacc.c */
-#line 121 "promela.ypp"
+#line 145 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_PLUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_MINUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 14:
/* Line 1787 of yacc.c */
-#line 122 "promela.ypp"
+#line 146 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_MINUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_TIMES, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 15:
/* Line 1787 of yacc.c */
-#line 123 "promela.ypp"
+#line 147 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_TIMES, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_DIVIDE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 16:
/* Line 1787 of yacc.c */
-#line 124 "promela.ypp"
+#line 148 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_DIVIDE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_MODULO, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 17:
/* Line 1787 of yacc.c */
-#line 125 "promela.ypp"
+#line 149 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_MODULO, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_BITAND, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 18:
/* Line 1787 of yacc.c */
-#line 126 "promela.ypp"
+#line 150 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_BITAND, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_BITXOR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 19:
/* Line 1787 of yacc.c */
-#line 127 "promela.ypp"
+#line 151 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_BITXOR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_BITOR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 20:
/* Line 1787 of yacc.c */
-#line 128 "promela.ypp"
+#line 152 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_BITOR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_GT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 21:
/* Line 1787 of yacc.c */
-#line 129 "promela.ypp"
+#line 153 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_GT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_LT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 22:
/* Line 1787 of yacc.c */
-#line 130 "promela.ypp"
+#line 154 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_LT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_GE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 23:
/* Line 1787 of yacc.c */
-#line 131 "promela.ypp"
+#line 155 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_GE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_LE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 24:
/* Line 1787 of yacc.c */
-#line 132 "promela.ypp"
+#line 156 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_LE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_EQ, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 25:
/* Line 1787 of yacc.c */
-#line 133 "promela.ypp"
+#line 157 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_EQ, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_NE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 26:
/* Line 1787 of yacc.c */
-#line 134 "promela.ypp"
+#line 158 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_NE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_AND, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 27:
/* Line 1787 of yacc.c */
-#line 135 "promela.ypp"
+#line 159 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_AND, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_OR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 28:
/* Line 1787 of yacc.c */
-#line 136 "promela.ypp"
+#line 160 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_OR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_LSHIFT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 29:
/* Line 1787 of yacc.c */
-#line 137 "promela.ypp"
+#line 161 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_LSHIFT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_RSHIFT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 30:
/* Line 1787 of yacc.c */
-#line 138 "promela.ypp"
+#line 162 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_RSHIFT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ (yyval.node) = ctx->node(PML_NEG, 1, (yyvsp[(2) - (2)].node));
}
break;
case 31:
/* Line 1787 of yacc.c */
-#line 139 "promela.ypp"
+#line 163 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_NEG, 1, (yyvsp[(2) - (2)].node));
+ (yyval.node) = ctx->node(PML_MINUS, 1, (yyvsp[(2) - (2)].node));
}
break;
case 32:
/* Line 1787 of yacc.c */
-#line 140 "promela.ypp"
+#line 165 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_MINUS, 1, (yyvsp[(2) - (2)].node));
+ (yyval.node) = ctx->node(PML_LEN, 1, (yyvsp[(3) - (4)].node));
}
break;
case 33:
/* Line 1787 of yacc.c */
-#line 142 "promela.ypp"
+#line 166 "promela.ypp"
{
- (yyval.node) = ctx->node(PML_LEN, 1, (yyvsp[(3) - (4)].node));
+ (yyval.node) = (yyvsp[(1) - (1)].node);
}
break;
case 34:
/* Line 1787 of yacc.c */
-#line 143 "promela.ypp"
- { }
+#line 167 "promela.ypp"
+ {
+ (yyval.node) = ctx->value(PML_CONST, (yyvsp[(1) - (1)].value));
+ free((yyvsp[(1) - (1)].value));
+ }
break;
case 35:
/* Line 1787 of yacc.c */
-#line 144 "promela.ypp"
+#line 168 "promela.ypp"
{
- (yyval.node) = ctx->value(PML_CONST, (yyvsp[(1) - (1)].value));
+ /* Non standard promela for string literals */
+ (yyval.node) = ctx->value(PML_STRING, (yyvsp[(1) - (1)].value));
free((yyvsp[(1) - (1)].value));
}
break;
case 36:
/* Line 1787 of yacc.c */
-#line 148 "promela.ypp"
+#line 174 "promela.ypp"
{
(yyval.node) = ctx->node(PML_SHOW, 0);
}
@@ -1878,7 +1923,7 @@ yyreduce:
case 37:
/* Line 1787 of yacc.c */
-#line 149 "promela.ypp"
+#line 175 "promela.ypp"
{
(yyval.node) = ctx->node(PML_HIDDEN, 0);
}
@@ -1886,7 +1931,7 @@ yyreduce:
case 38:
/* Line 1787 of yacc.c */
-#line 150 "promela.ypp"
+#line 176 "promela.ypp"
{
(yyval.node) = ctx->node(PML_SHOW, 0);
}
@@ -1894,7 +1939,7 @@ yyreduce:
case 39:
/* Line 1787 of yacc.c */
-#line 151 "promela.ypp"
+#line 177 "promela.ypp"
{
(yyval.node) = ctx->node(PML_ISLOCAL, 0);
}
@@ -1902,7 +1947,7 @@ yyreduce:
case 40:
/* Line 1787 of yacc.c */
-#line 154 "promela.ypp"
+#line 180 "promela.ypp"
{
(yyval.node) = ctx->node(PML_DECL, 3, (yyvsp[(1) - (3)].node), ctx->value(PML_TYPE, (yyvsp[(2) - (3)].value)), (yyvsp[(3) - (3)].node));
free((yyvsp[(2) - (3)].value));
@@ -1911,7 +1956,7 @@ yyreduce:
case 41:
/* Line 1787 of yacc.c */
-#line 155 "promela.ypp"
+#line 181 "promela.ypp"
{
(yyval.node) = ctx->node(PML_UNAME, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
@@ -1919,7 +1964,7 @@ yyreduce:
case 42:
/* Line 1787 of yacc.c */
-#line 156 "promela.ypp"
+#line 182 "promela.ypp"
{
(yyval.node) = ctx->node(PML_DECL, 3, (yyvsp[(1) - (6)].node), ctx->value(PML_TYPE, (yyvsp[(2) - (6)].value)), (yyvsp[(5) - (6)].node));
free((yyvsp[(2) - (6)].value));
@@ -1928,23 +1973,39 @@ yyreduce:
case 43:
/* Line 1787 of yacc.c */
-#line 159 "promela.ypp"
+#line 183 "promela.ypp"
{
- (yyval.node) = (yyvsp[(1) - (1)].node);
+ (yyval.node) = (yyvsp[(2) - (2)].node);
}
break;
case 44:
/* Line 1787 of yacc.c */
-#line 160 "promela.ypp"
+#line 186 "promela.ypp"
{
- (yyval.node) = (yyvsp[(1) - (2)].node);
+ (yyval.node) = ctx->node(PML_TYPEDEF, 2, ctx->value(PML_NAME, (yyvsp[(2) - (5)].value)), (yyvsp[(4) - (5)].node));
}
break;
case 45:
/* Line 1787 of yacc.c */
-#line 161 "promela.ypp"
+#line 189 "promela.ypp"
+ {
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ }
+ break;
+
+ case 46:
+ /* Line 1787 of yacc.c */
+#line 190 "promela.ypp"
+ {
+ (yyval.node) = (yyvsp[(1) - (2)].node);
+ }
+ break;
+
+ case 47:
+ /* Line 1787 of yacc.c */
+#line 191 "promela.ypp"
{
(yyval.node) = ctx->node(PML_DECLLIST, 1, (yyvsp[(1) - (3)].node));
if((yyvsp[(3) - (3)].node)->type == PML_DECLLIST) {
@@ -1956,17 +2017,17 @@ yyreduce:
}
break;
- case 46:
+ case 48:
/* Line 1787 of yacc.c */
-#line 171 "promela.ypp"
+#line 201 "promela.ypp"
{
(yyval.node) = ctx->node(PML_VARLIST, 1, (yyvsp[(1) - (1)].node));
}
break;
- case 47:
+ case 49:
/* Line 1787 of yacc.c */
-#line 172 "promela.ypp"
+#line 202 "promela.ypp"
{
(yyval.node) = ctx->node(PML_VARLIST, 1, (yyvsp[(1) - (3)].node));
(yyval.node)->merge((yyvsp[(3) - (3)].node));
@@ -1974,34 +2035,34 @@ yyreduce:
}
break;
- case 48:
+ case 50:
/* Line 1787 of yacc.c */
-#line 175 "promela.ypp"
+#line 205 "promela.ypp"
{
(yyval.node) = (yyvsp[(1) - (1)].node);
}
break;
- case 49:
+ case 51:
/* Line 1787 of yacc.c */
-#line 176 "promela.ypp"
+#line 206 "promela.ypp"
{
(yyval.node) = ctx->node(PML_ASGN, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 50:
+ case 52:
/* Line 1787 of yacc.c */
-#line 179 "promela.ypp"
+#line 209 "promela.ypp"
{
(yyval.node) = ctx->value(PML_NAME, (yyvsp[(1) - (1)].value));
free((yyvsp[(1) - (1)].value));
}
break;
- case 51:
+ case 53:
/* Line 1787 of yacc.c */
-#line 180 "promela.ypp"
+#line 210 "promela.ypp"
{
(yyval.node) = ctx->node(PML_COLON, 2, ctx->value(PML_NAME, (yyvsp[(1) - (3)].value)), ctx->value(PML_CONST, (yyvsp[(3) - (3)].value)));
free((yyvsp[(1) - (3)].value));
@@ -2009,92 +2070,92 @@ yyreduce:
}
break;
- case 52:
+ case 54:
/* Line 1787 of yacc.c */
-#line 181 "promela.ypp"
+#line 211 "promela.ypp"
{
(yyval.node) = ctx->node(PML_VAR_ARRAY, 2, ctx->value(PML_NAME, (yyvsp[(1) - (4)].value)), (yyvsp[(3) - (4)].node));
free((yyvsp[(1) - (4)].value));
}
break;
- case 53:
+ case 55:
/* Line 1787 of yacc.c */
-#line 184 "promela.ypp"
+#line 214 "promela.ypp"
{
(yyval.node) = ctx->value(PML_CONST, (yyvsp[(1) - (1)].value));
free((yyvsp[(1) - (1)].value));
}
break;
- case 54:
+ case 56:
/* Line 1787 of yacc.c */
-#line 185 "promela.ypp"
+#line 215 "promela.ypp"
{
(yyval.node) = ctx->node(PML_MINUS, 1, (yyvsp[(2) - (2)].node));
}
break;
- case 55:
+ case 57:
/* Line 1787 of yacc.c */
-#line 186 "promela.ypp"
+#line 216 "promela.ypp"
{
(yyval.node) = (yyvsp[(2) - (3)].node);
}
break;
- case 56:
+ case 58:
/* Line 1787 of yacc.c */
-#line 187 "promela.ypp"
+#line 217 "promela.ypp"
{
(yyval.node) = ctx->node(PML_PLUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 57:
+ case 59:
/* Line 1787 of yacc.c */
-#line 188 "promela.ypp"
+#line 218 "promela.ypp"
{
(yyval.node) = ctx->node(PML_MINUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 58:
+ case 60:
/* Line 1787 of yacc.c */
-#line 189 "promela.ypp"
+#line 219 "promela.ypp"
{
(yyval.node) = ctx->node(PML_TIMES, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 59:
+ case 61:
/* Line 1787 of yacc.c */
-#line 190 "promela.ypp"
+#line 220 "promela.ypp"
{
(yyval.node) = ctx->node(PML_DIVIDE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 60:
+ case 62:
/* Line 1787 of yacc.c */
-#line 191 "promela.ypp"
+#line 221 "promela.ypp"
{
(yyval.node) = ctx->node(PML_MODULO, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 61:
+ case 63:
/* Line 1787 of yacc.c */
-#line 194 "promela.ypp"
+#line 224 "promela.ypp"
{
(yyval.node) = ctx->value(PML_NAME, (yyvsp[(1) - (1)].value));
free((yyvsp[(1) - (1)].value));
}
break;
- case 62:
+ case 64:
/* Line 1787 of yacc.c */
-#line 195 "promela.ypp"
+#line 225 "promela.ypp"
{
if ((yyvsp[(1) - (2)].node)->type == PML_NAME) {
(yyval.node) = ctx->node(PML_NAMELIST, 1, (yyvsp[(1) - (2)].node));
@@ -2106,161 +2167,163 @@ yyreduce:
}
break;
- case 63:
+ case 65:
/* Line 1787 of yacc.c */
-#line 204 "promela.ypp"
+#line 234 "promela.ypp"
{
(yyval.node) = (yyvsp[(1) - (2)].node);
}
break;
- case 64:
+ case 66:
/* Line 1787 of yacc.c */
-#line 207 "promela.ypp"
+#line 237 "promela.ypp"
{
(yyval.node) = (yyvsp[(1) - (1)].node);
}
break;
- case 65:
+ case 67:
/* Line 1787 of yacc.c */
-#line 208 "promela.ypp"
+#line 238 "promela.ypp"
{
(yyval.node) = (yyvsp[(1) - (2)].node);
}
break;
- case 66:
+ case 68:
/* Line 1787 of yacc.c */
-#line 209 "promela.ypp"
+#line 239 "promela.ypp"
{
(yyval.node) = ctx->node(PML_STMNT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 67:
+ case 69:
/* Line 1787 of yacc.c */
-#line 212 "promela.ypp"
+#line 242 "promela.ypp"
{
(yyval.node) = (yyvsp[(1) - (1)].node);
}
break;
- case 68:
+ case 70:
/* Line 1787 of yacc.c */
-#line 215 "promela.ypp"
+#line 245 "promela.ypp"
{
(yyval.node) = ctx->node(PML_ASGN, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
- case 69:
+ case 71:
/* Line 1787 of yacc.c */
-#line 216 "promela.ypp"
+#line 246 "promela.ypp"
{
(yyval.node) = ctx->node(PML_INCR, 1, (yyvsp[(1) - (2)].node));
}
break;
- case 70:
+ case 72:
/* Line 1787 of yacc.c */
-#line 217 "promela.ypp"
+#line 247 "promela.ypp"
{
(yyval.node) = ctx->node(PML_DECR, 1, (yyvsp[(1) - (2)].node));
}
break;
- case 71:
+ case 73:
/* Line 1787 of yacc.c */
-#line 218 "promela.ypp"
+#line 248 "promela.ypp"
{
(yyval.node) = ctx->node(PML_PRINT, 2, ctx->value(PML_STRING, (yyvsp[(3) - (5)].value)), (yyvsp[(4) - (5)].node));
free((yyvsp[(3) - (5)].value));
}
break;
- case 72:
+ case 74:
/* Line 1787 of yacc.c */
-#line 219 "promela.ypp"
+#line 249 "promela.ypp"
{
(yyval.node) = ctx->node(PML_PRINTM, 1, (yyvsp[(3) - (4)].node));
}
break;
- case 73:
+ case 75:
/* Line 1787 of yacc.c */
-#line 220 "promela.ypp"
+#line 250 "promela.ypp"
{
(yyval.node) = ctx->node(PML_PRINTM, 1, ctx->value(PML_CONST, (yyvsp[(3) - (4)].value)));
free((yyvsp[(3) - (4)].value));
}
break;
- case 74:
+ case 76:
/* Line 1787 of yacc.c */
-#line 221 "promela.ypp"
- { }
+#line 251 "promela.ypp"
+ {
+ (yyval.node) = ctx->node(PML_ASSERT, 1, (yyvsp[(2) - (2)].node));
+ }
break;
- case 75:
+ case 77:
/* Line 1787 of yacc.c */
-#line 222 "promela.ypp"
+#line 252 "promela.ypp"
{
(yyval.node) = (yyvsp[(1) - (1)].node);
}
break;
- case 76:
+ case 78:
/* Line 1787 of yacc.c */
-#line 223 "promela.ypp"
+#line 253 "promela.ypp"
{ }
break;
- case 77:
+ case 79:
/* Line 1787 of yacc.c */
-#line 223 "promela.ypp"
+#line 253 "promela.ypp"
{ }
break;
- case 78:
+ case 80:
/* Line 1787 of yacc.c */
-#line 226 "promela.ypp"
+#line 256 "promela.ypp"
{ }
break;
- case 79:
+ case 81:
/* Line 1787 of yacc.c */
-#line 227 "promela.ypp"
+#line 257 "promela.ypp"
{ }
break;
- case 80:
+ case 82:
/* Line 1787 of yacc.c */
-#line 230 "promela.ypp"
+#line 260 "promela.ypp"
{
(yyval.node) = ctx->value(0, "");
}
break;
- case 81:
+ case 83:
/* Line 1787 of yacc.c */
-#line 231 "promela.ypp"
+#line 261 "promela.ypp"
{
(yyval.node) = (yyvsp[(2) - (2)].node);
}
break;
- case 82:
+ case 84:
/* Line 1787 of yacc.c */
-#line 234 "promela.ypp"
+#line 264 "promela.ypp"
{
(yyval.node) = (yyvsp[(1) - (1)].node);
}
break;
- case 83:
+ case 85:
/* Line 1787 of yacc.c */
-#line 235 "promela.ypp"
+#line 265 "promela.ypp"
{
(yyval.node) = ctx->node(0, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
@@ -2268,7 +2331,7 @@ yyreduce:
/* Line 1787 of yacc.c */
-#line 2162 "promela.tab.cpp"
+#line 2207 "promela.tab.cpp"
default:
break;
}
@@ -2487,6 +2550,6 @@ yyreturn:
/* Line 2050 of yacc.c */
-#line 239 "promela.ypp"
+#line 269 "promela.ypp"
diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.tab.hpp b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.hpp
index b8381cf..e6eb572 100644
--- a/src/uscxml/plugins/datamodel/promela/parser/promela.tab.hpp
+++ b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.hpp
@@ -125,7 +125,8 @@ extern int promela_debug;
PML_INCR = 326,
PML_COMPL = 327,
PML_NEG = 328,
- PML_DOT = 329
+ PML_CMPND = 329,
+ PML_DOT = 330
};
#endif
@@ -141,7 +142,7 @@ typedef union PROMELA_STYPE
/* Line 2053 of yacc.c */
-#line 145 "promela.tab.hpp"
+#line 146 "promela.tab.hpp"
} PROMELA_STYPE;
# define PROMELA_STYPE_IS_TRIVIAL 1
# define promela_stype PROMELA_STYPE /* obsolescent; will be withdrawn */
diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.ypp b/src/uscxml/plugins/datamodel/promela/parser/promela.ypp
index cf8deea..45767ed 100644
--- a/src/uscxml/plugins/datamodel/promela/parser/promela.ypp
+++ b/src/uscxml/plugins/datamodel/promela/parser/promela.ypp
@@ -43,8 +43,8 @@ using namespace uscxml;
%error-verbose
/* %type <node> expr_lst */
-%type <node> expr pfld varref decl_lst stmnt_lst vardcl ivar var_list one_decl prargs
-%type <node> stmnt Stmnt const_expr nlst vis arg
+%type <node> expr pfld sfld varref decl_lst stmnt_lst vardcl ivar var_list one_decl prargs utype cmpnd
+%type <node> stmnt Stmnt const_expr nlst vis arg
%token PML_VAR_ARRAY PML_VARLIST PML_DECL PML_DECLLIST PML_STMNT PML_COLON PML_EXPR PML_NAMELIST
@@ -73,7 +73,7 @@ using namespace uscxml;
%left PML_INCR PML_DECR
%left PML_COMPL
%right PML_NEG
-%left PML_DOT
+%left PML_DOT PML_CMPND
%%
@@ -95,19 +95,30 @@ program :
}
;
-varref : cmpnd {}
+varref : cmpnd { $$ = $1; }
;
pfld : PML_NAME { $$ = ctx->value(PML_NAME, $1); free($1); }
| PML_NAME '[' expr ']' { $$ = ctx->node(PML_VAR_ARRAY, 2, ctx->value(PML_NAME, $1), $3); free($1); }
;
-cmpnd : pfld {}
- sfld {}
+cmpnd : pfld
+ sfld {
+ if ($2 != NULL) {
+ if ($2->type == PML_CMPND) {
+ $$ = ctx->node(PML_CMPND, 1, $1);
+ $$->merge($2); delete $2;
+ } else {
+ $$ = ctx->node(PML_CMPND, 2, $1, $2);
+ }
+ } else {
+ $$ = $1;
+ }
+ }
;
-sfld : /* empty */ {}
- | PML_DOT cmpnd %prec PML_DOT {}
+sfld : /* empty */ { $$ = NULL; }
+ | PML_DOT cmpnd %prec PML_DOT { $$ = $2; }
;
/*
@@ -140,8 +151,11 @@ expr : '(' expr ')' { $$ = $2; }
| PML_MINUS expr %prec PML_MINUS { $$ = ctx->node(PML_MINUS, 1, $2); }
| PML_LEN '(' varref ')' { $$ = ctx->node(PML_LEN, 1, $3); }
- | varref { }
+ | varref { $$ = $1; }
| PML_CONST { $$ = ctx->value(PML_CONST, $1); free($1); }
+ | PML_STRING {
+ /* Non standard promela for string literals */
+ $$ = ctx->value(PML_STRING, $1); free($1); }
;
@@ -154,6 +168,10 @@ vis : /* empty */ { $$ = ctx->node(PML_SHOW, 0); }
one_decl: vis PML_TYPE var_list { $$ = ctx->node(PML_DECL, 3, $1, ctx->value(PML_TYPE, $2), $3); free($2); }
| vis PML_UNAME var_list { $$ = ctx->node(PML_UNAME, 2, $1, $3); }
| vis PML_TYPE PML_ASGN '{' nlst '}' { $$ = ctx->node(PML_DECL, 3, $1, ctx->value(PML_TYPE, $2), $5); free($2); }
+ | vis utype { $$ = $2; }
+ ;
+
+utype : PML_TYPEDEF PML_NAME '{' decl_lst '}' { $$ = ctx->node(PML_TYPEDEF, 2, ctx->value(PML_NAME, $2), $4); }
;
decl_lst: one_decl { $$ = $1; }
@@ -218,7 +236,7 @@ Stmnt : varref PML_ASGN expr { $$ = ctx->node(PML_ASGN, 2, $1, $3); }
| PML_PRINT '(' PML_STRING prargs ')' { $$ = ctx->node(PML_PRINT, 2, ctx->value(PML_STRING, $3), $4); free($3); }
| PML_PRINTM '(' varref ')' { $$ = ctx->node(PML_PRINTM, 1, $3); }
| PML_PRINTM '(' PML_CONST ')' { $$ = ctx->node(PML_PRINTM, 1, ctx->value(PML_CONST, $3)); free($3); }
- | PML_ASSERT expr { }
+ | PML_ASSERT expr { $$ = ctx->node(PML_ASSERT, 1, $2); }
| expr { $$ = $1; }
| varref PML_ASGN PML_INAME { } '(' args ')' Stmnt { }
;
diff --git a/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp b/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp
index fc18e18..4c56a14 100644
--- a/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp
+++ b/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.cpp
@@ -70,76 +70,76 @@ bool VoiceXMLInvoker::httpRecvRequest(const HTTPServer::Request& request) {
reply.status = 500;
HTTPServer::reply(reply);
}
-
+
const Arabica::DOM::Node<std::string>& node = request.data.at("content").node;
// std::cout << "RCVD: " << node << std::endl;
switch(MMIEvent::getType(node)) {
- case MMIEvent::NEWCONTEXTRESPONSE: {
- NewContextResponse resp = NewContextResponse::fromXML(node);
- if (_context.size() == 0) {
- _compState = MMI_IDLE;
- _context = resp.context;
-
- StartRequest startReq;
- startReq.context = _context;
- startReq.source = _url;
- startReq.target = _target;
- startReq.requestId = uscxml::UUID::getUUID();
-
- if (_invokeReq.src.size() > 0) {
- startReq.contentURL.href = _invokeReq.src;
- } else if(_invokeReq.content.size()) {
- startReq.content = _invokeReq.content;
- } else if(_invokeReq.dom) {
- std::stringstream contentSS;
- startReq.contentDOM = _invokeReq.dom;
- }
- ISSUE_REQUEST(startReq, false);
-
- } else {
- // already got a context!
- }
- break;
- }
- case MMIEvent::STARTRESPONSE: {
- StartResponse resp = StartResponse::fromXML(node);
- _compState = MMI_RUNNING;
- break;
- }
-
- case MMIEvent::DONENOTIFICATION: {
- DoneNotification resp = DoneNotification::fromXML(node);
+ case MMIEvent::NEWCONTEXTRESPONSE: {
+ NewContextResponse resp = NewContextResponse::fromXML(node);
+ if (_context.size() == 0) {
_compState = MMI_IDLE;
- break;
- }
+ _context = resp.context;
+
+ StartRequest startReq;
+ startReq.context = _context;
+ startReq.source = _url;
+ startReq.target = _target;
+ startReq.requestId = uscxml::UUID::getUUID();
- case MMIEvent::STATUSRESPONSE: {
- StatusResponse resp = StatusResponse::fromXML(node);
- switch (resp.status) {
- case StatusResponse::DEAD:
- _compState = MMI_DEAD;
- case StatusResponse::FAILURE: {
- Event ev = resp;
- returnEvent(ev);
- break;
- }
- default:
- break;
+ if (_invokeReq.src.size() > 0) {
+ startReq.contentURL.href = _invokeReq.src;
+ } else if(_invokeReq.content.size()) {
+ startReq.content = _invokeReq.content;
+ } else if(_invokeReq.dom) {
+ std::stringstream contentSS;
+ startReq.contentDOM = _invokeReq.dom;
}
- break;
+ ISSUE_REQUEST(startReq, false);
+
+ } else {
+ // already got a context!
}
+ break;
+ }
+ case MMIEvent::STARTRESPONSE: {
+ StartResponse resp = StartResponse::fromXML(node);
+ _compState = MMI_RUNNING;
+ break;
+ }
- case MMIEvent::EXTENSIONNOTIFICATION: {
- Event resp = ExtensionNotification::fromXML(node);
- returnEvent(resp);
+ case MMIEvent::DONENOTIFICATION: {
+ DoneNotification resp = DoneNotification::fromXML(node);
+ _compState = MMI_IDLE;
+ break;
+ }
+
+ case MMIEvent::STATUSRESPONSE: {
+ StatusResponse resp = StatusResponse::fromXML(node);
+ switch (resp.status) {
+ case StatusResponse::DEAD:
+ _compState = MMI_DEAD;
+ case StatusResponse::FAILURE: {
+ Event ev = resp;
+ returnEvent(ev);
+ break;
}
-
default:
break;
+ }
+ break;
}
-
-
+
+ case MMIEvent::EXTENSIONNOTIFICATION: {
+ Event resp = ExtensionNotification::fromXML(node);
+ returnEvent(resp);
+ }
+
+ default:
+ break;
+ }
+
+
HTTPServer::Reply reply(request);
HTTPServer::reply(reply);
return true;
@@ -147,6 +147,7 @@ bool VoiceXMLInvoker::httpRecvRequest(const HTTPServer::Request& request) {
void VoiceXMLInvoker::setURL(const std::string& url) {
_url = url;
+// boost::replace_first(_url, "epikur-2.local", "178.4.230.252");
}
Data VoiceXMLInvoker::getDataModelVariables() {
@@ -162,15 +163,15 @@ void VoiceXMLInvoker::invoke(const InvokeRequest& req) {
tthread::lock_guard<tthread::mutex> lock(_mutex);
HTTPServer::getInstance()->registerServlet(req.invokeid, this);
-
+
Event::getParam(req.params, "target", _target);
if (_target.size() == 0) {
LOG(ERROR) << "No target parameter given!";
return;
}
-
+
_invokeReq = req;
-
+
NewContextRequest newCtxReq;
newCtxReq.source = _url;
newCtxReq.target = _target;
@@ -183,7 +184,7 @@ void VoiceXMLInvoker::invoke(const InvokeRequest& req) {
}
void VoiceXMLInvoker::uninvoke() {
-
+
ClearContextRequest clrCtxReq;
clrCtxReq.source = _url;
clrCtxReq.target = _target;
@@ -192,11 +193,11 @@ void VoiceXMLInvoker::uninvoke() {
if (_isRunning)
_isRunning = false;
-
+
// unblock queue
SendRequest req;
_workQueue.push(req);
-
+
if (_thread) {
_thread->join();
delete _thread;
@@ -223,19 +224,19 @@ void VoiceXMLInvoker::process(SendRequest& req) {
tthread::lock_guard<tthread::mutex> lock(_mutex);
while(_context.size() == 0 && _isRunning)
_cond.wait_for(_mutex, 200);
-
+
if (_context.size() == 0) {
// we never acquired a context
return;
}
-
+
if (_compState != MMI_RUNNING)
// remote component is not running
return;
-
+
// dispatch over send request
// Is there something special to do here?
-
+
// if we did nothing else, send as ExtensionNotification
ExtensionNotification extNotif;
extNotif.context = _context;
@@ -253,7 +254,7 @@ void VoiceXMLInvoker::process(SendRequest& req) {
Event::getParam(req.params, it->first, req.data.compound[it->first]);
}
}
-
+
if (req.dom) {
extNotif.dataDOM = req.dom;
} else if (req.content.size() > 0) {
@@ -261,8 +262,8 @@ void VoiceXMLInvoker::process(SendRequest& req) {
} else if (!req.data.empty()) {
extNotif.data = Data::toJSON(req.data);
}
-
+
ISSUE_REQUEST(extNotif, false);
}
-
+
} \ No newline at end of file
diff --git a/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.h b/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.h
index 4ad5023..d6078cd 100644
--- a/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.h
+++ b/src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.h
@@ -40,7 +40,7 @@ public:
MMI_RUNNING,
MMI_DEAD
};
-
+
VoiceXMLInvoker();
virtual ~VoiceXMLInvoker();
virtual boost::shared_ptr<InvokerImpl> create(InterpreterImpl* interpreter);
@@ -56,10 +56,10 @@ public:
bool deleteOnUninvoke() {
return false;
}
-
+
bool httpRecvRequest(const HTTPServer::Request& request);
void setURL(const std::string& url);
-
+
virtual Data getDataModelVariables();
virtual void send(const SendRequest& req);
virtual void invoke(const InvokeRequest& req);
@@ -72,11 +72,11 @@ protected:
std::string _url;
std::string _context;
std::string _target;
-
+
InvokeRequest _invokeReq;
-
+
ComponentState _compState;
-
+
tthread::thread* _thread;
tthread::condition_variable _cond;
tthread::mutex _mutex;
diff --git a/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp b/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp
index e2b32df..196d6d2 100644
--- a/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp
+++ b/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp
@@ -73,7 +73,7 @@ bool XHTMLInvoker::httpRecvRequest(const HTTPServer::Request& req) {
evhttp_send_error(_longPoll.evhttpReq, 204, NULL);
_longPoll.evhttpReq = NULL;
}
-
+
_longPoll = req;
if (!_outQueue.empty()) {
// do we have some send requests pending?
@@ -84,7 +84,7 @@ bool XHTMLInvoker::httpRecvRequest(const HTTPServer::Request& req) {
_longPoll.evhttpReq = NULL;
}
return true;
-
+
} else {
// an incomping event per POST request
Event ev(req);
@@ -93,14 +93,14 @@ bool XHTMLInvoker::httpRecvRequest(const HTTPServer::Request& req) {
} else {
ev.name = req.data.at("type").atom;
}
-
+
// initialize data
ev.data = req.data.at("content");
ev.eventType = Event::EXTERNAL;
-
+
HTTPServer::Reply reply(req);
HTTPServer::reply(reply);
-
+
returnEvent(ev);
return true;
}
@@ -108,35 +108,35 @@ bool XHTMLInvoker::httpRecvRequest(const HTTPServer::Request& req) {
// initial request for a document
if (!req.data.hasKey("query") && // no query parameters
- iequals(req.data.at("type").atom, "get") && // request type is GET
- req.content.length() == 0) { // no content
-
+ iequals(req.data.at("type").atom, "get") && // request type is GET
+ req.content.length() == 0) { // no content
+
// send template to establish long polling
HTTPServer::Reply reply(req);
// _invokeReq.content will contain the actual content as we needed to replace expressions in the interpreter thread
-
+
if (!_invokeReq.data.empty()) {
// just reply with given data as json, this time and for ever
reply.content = _invokeReq.content;
reply.headers["Content-type"] = "application/json";
HTTPServer::reply(reply);
return true;
-
+
} else if (_invokeReq.dom) {
// there is some XML given with the content
if (HAS_ATTR_CAST(_invokeReq.dom, "type")) {
// it's special XML to send per Comet later on, default to sending template and enqueue
_longPoll.evhttpReq = NULL;
_outQueue = std::deque<HTTPServer::Reply>();
-
+
HTTPServer::Reply reply;
reply.content = _invokeReq.content;
reply.headers["Content-type"] = "application/xml";
_outQueue.push_back(reply);
// no return here - we wan to send the template below
-
+
} else {
// it's plain XML now and forever
reply.content = _invokeReq.content;
@@ -145,7 +145,7 @@ bool XHTMLInvoker::httpRecvRequest(const HTTPServer::Request& req) {
return true;
}
} else if (_invokeReq.content.size() > 0) {
-
+
// just reply as text this time and for ever
reply.content = _invokeReq.content;
reply.headers["Content-type"] = "text/plain";
@@ -158,9 +158,9 @@ bool XHTMLInvoker::httpRecvRequest(const HTTPServer::Request& req) {
* If we want to replace expressions in the temaplte, we have to do it in invoke()
* for thread safety of the datamodel.
*/
-
+
// this file is generated from template/xhtml-invoker.xhtml via xxd
- #include "template/xhtml-invoker.inc.h"
+#include "template/xhtml-invoker.inc.h"
// aggressive caching in IE will return all XHR get requests instantenously otherwise
reply.headers["Cache-Control"] = "no-cache";
@@ -184,7 +184,7 @@ void XHTMLInvoker::send(const SendRequest& req) {
tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
HTTPServer::Reply reply;
-
+
if (req.dom) {
// XML
std::stringstream ss;
@@ -198,11 +198,11 @@ void XHTMLInvoker::send(const SendRequest& req) {
if (HAS_ATTR(contentElem, "attr"))
reply.headers["X-SCXML-Attr"] = ATTR(contentElem, "attr");
}
-
+
ss << req.dom;
reply.content = ss.str();
reply.headers["Content-Type"] = "application/xml";
-
+
} else if (!req.data.empty()) {
// JSON
reply.content = Data::toJSON(req.data);
@@ -213,7 +213,7 @@ void XHTMLInvoker::send(const SendRequest& req) {
}
// TODO: Params to set variables?
-
+
_interpreter->getDataModel().replaceExpressions(reply.content);
if (!_longPoll) {
@@ -224,14 +224,14 @@ void XHTMLInvoker::send(const SendRequest& req) {
HTTPServer::reply(reply);
_longPoll.evhttpReq = NULL;
}
-
+
void XHTMLInvoker::cancel(const std::string sendId) {
HTTPServer::unregisterServlet(this);
}
void XHTMLInvoker::invoke(const InvokeRequest& req) {
_invokeReq = req;
-
+
// make sure _invokeReq.content contains correct and substituted string
if (!_invokeReq.data.empty()) {
_invokeReq.content = Data::toJSON(_invokeReq.data);
diff --git a/src/uscxml/plugins/invoker/xhtml/template/xhtml-invoker.inc.h b/src/uscxml/plugins/invoker/xhtml/template/xhtml-invoker.inc.h
index c5a5798..971260b 100644
--- a/src/uscxml/plugins/invoker/xhtml/template/xhtml-invoker.inc.h
+++ b/src/uscxml/plugins/invoker/xhtml/template/xhtml-invoker.inc.h
@@ -1,691 +1,691 @@
unsigned char template_xhtml_invoker_html[] = {
- 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3d,
- 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
- 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f,
- 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x0a, 0x09, 0x3c, 0x68, 0x65,
- 0x61, 0x64, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20,
- 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22,
- 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65,
- 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x74,
- 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x63, 0x68, 0x61,
- 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x20,
- 0x2f, 0x3e, 0x0a, 0x0a, 0x09, 0x09, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x47,
- 0x65, 0x74, 0x20, 0x64, 0x6f, 0x6d, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64,
- 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73,
- 0x73, 0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x73, 0x20, 0x2d,
- 0x2d, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f,
- 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x3e,
- 0x0a, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x6f,
- 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x31, 0x32,
- 0x30, 0x36, 0x39, 0x33, 0x37, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63,
- 0x72, 0x69, 0x70, 0x74, 0x2d, 0x64, 0x6f, 0x6d, 0x72, 0x65, 0x61, 0x64,
- 0x79, 0x0a, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x6d,
- 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61,
- 0x63, 0x6b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a,
- 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x45, 0x78,
- 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x2f, 0x2a, 0x40, 0x63, 0x63, 0x5f, 0x6f, 0x6e, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x40, 0x69, 0x66, 0x20, 0x28, 0x40, 0x5f, 0x77, 0x69,
- 0x6e, 0x33, 0x32, 0x20, 0x7c, 0x7c, 0x20, 0x40, 0x5f, 0x77, 0x69, 0x6e,
- 0x36, 0x34, 0x29, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x77,
- 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70,
- 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 0x65, 0x53, 0x63, 0x72, 0x69,
- 0x70, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x22, 0x20, 0x64, 0x65, 0x66, 0x65,
- 0x72, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x2f, 0x3a, 0x22, 0x3e,
- 0x3c, 0x5c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x27, 0x29,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d,
- 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65,
- 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x69, 0x65, 0x53, 0x63,
- 0x72, 0x69, 0x70, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x27, 0x29, 0x2e, 0x6f,
- 0x6e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x63,
- 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e,
- 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d,
- 0x3d, 0x20, 0x27, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x27,
- 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76,
- 0x61, 0x72, 0x20, 0x68, 0x65, 0x61, 0x64, 0x3d, 0x20, 0x64, 0x6f, 0x63,
- 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65,
- 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61,
- 0x6d, 0x65, 0x28, 0x27, 0x68, 0x65, 0x61, 0x64, 0x27, 0x29, 0x5b, 0x30,
- 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61,
- 0x72, 0x20, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3d, 0x20, 0x64, 0x6f,
- 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74,
- 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x27, 0x73, 0x63,
- 0x72, 0x69, 0x70, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2e, 0x74, 0x79,
- 0x70, 0x65, 0x3d, 0x20, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61,
- 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, 0x3b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x2e, 0x73, 0x72, 0x63, 0x3d, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a,
- 0x2f, 0x2f, 0x77, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x2d, 0x67, 0x6f, 0x6f,
- 0x64, 0x2d, 0x78, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
- 0x6c, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66,
- 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x77, 0x67, 0x78, 0x70, 0x61, 0x74, 0x68,
- 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x2e, 0x6a, 0x73, 0x27,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x68, 0x65, 0x61,
- 0x64, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c,
- 0x64, 0x28, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x29, 0x3b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x77, 0x67, 0x78, 0x70, 0x61, 0x74,
- 0x68, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x28, 0x29, 0x3b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x6f,
- 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x31, 0x38,
- 0x31, 0x31, 0x31, 0x31, 0x36, 0x2f, 0x69, 0x65, 0x2d, 0x73, 0x75, 0x70,
- 0x70, 0x6f, 0x72, 0x74, 0x2d, 0x66, 0x6f, 0x72, 0x2d, 0x64, 0x6f, 0x6d,
- 0x2d, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d,
- 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4e, 0x6f,
- 0x64, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x43,
- 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x29, 0x20, 0x7b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x73, 0x77, 0x69, 0x74,
- 0x63, 0x68, 0x20, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64,
- 0x65, 0x54, 0x79, 0x70, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65,
- 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x4c,
- 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x3a, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65,
- 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
- 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
- 0x74, 0x4e, 0x53, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x61, 0x6d,
- 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x55, 0x52, 0x49, 0x2c, 0x20, 0x6e,
- 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65,
- 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
- 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x20, 0x26,
- 0x26, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69,
- 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
- 0x20, 0x3e, 0x20, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72,
- 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20,
- 0x69, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x74,
- 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e,
- 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x69, 0x6c, 0x3b,
- 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e,
- 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74,
- 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65,
- 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5b,
- 0x69, 0x5d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x2c,
- 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74,
- 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
- 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5b, 0x69,
- 0x5d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x29, 0x29,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x61, 0x6c, 0x6c, 0x43, 0x68, 0x69,
- 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x20, 0x26, 0x26, 0x20, 0x6e, 0x6f, 0x64,
- 0x65, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73,
- 0x20, 0x26, 0x26, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x68, 0x69,
- 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67,
- 0x74, 0x68, 0x20, 0x3e, 0x20, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66,
- 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30,
- 0x2c, 0x20, 0x69, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
- 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x6c,
- 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x69,
- 0x6c, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x70,
- 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x64, 0x6f, 0x63,
- 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74,
- 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x68,
- 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2c,
- 0x20, 0x61, 0x6c, 0x6c, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e,
- 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
- 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x3b, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72,
- 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63,
- 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x4e,
- 0x4f, 0x44, 0x45, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63,
- 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5f,
- 0x53, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x44, 0x45,
- 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20,
- 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65,
- 0x6e, 0x74, 0x2e, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4e,
- 0x4f, 0x44, 0x45, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
- 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x72,
- 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x78, 0x74, 0x4e, 0x6f, 0x64, 0x65,
- 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x7d,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x3b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x40, 0x65, 0x6e,
- 0x64, 0x20, 0x40, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a,
- 0x20, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2c, 0x20, 0x43, 0x68,
- 0x72, 0x6f, 0x6d, 0x65, 0x2c, 0x20, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x20,
- 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x64,
- 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x45,
- 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72,
- 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63,
- 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65,
- 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x27,
- 0x44, 0x4f, 0x4d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x6f,
- 0x61, 0x64, 0x65, 0x64, 0x27, 0x2c, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62,
- 0x61, 0x63, 0x6b, 0x2c, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x3b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x2f, 0x2a, 0x20, 0x53, 0x61, 0x66, 0x61, 0x72, 0x69, 0x2c, 0x20, 0x69,
- 0x43, 0x61, 0x62, 0x2c, 0x20, 0x4b, 0x6f, 0x6e, 0x71, 0x75, 0x65, 0x72,
- 0x6f, 0x72, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66,
- 0x20, 0x28, 0x2f, 0x4b, 0x48, 0x54, 0x4d, 0x4c, 0x7c, 0x57, 0x65, 0x62,
- 0x4b, 0x69, 0x74, 0x7c, 0x69, 0x43, 0x61, 0x62, 0x2f, 0x69, 0x2e, 0x74,
- 0x65, 0x73, 0x74, 0x28, 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x6f,
- 0x72, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x29,
- 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72,
- 0x20, 0x44, 0x4f, 0x4d, 0x4c, 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65,
- 0x72, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72,
- 0x76, 0x61, 0x6c, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
- 0x20, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x69, 0x66, 0x20, 0x28, 0x2f, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x7c,
- 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x69, 0x2e, 0x74,
- 0x65, 0x73, 0x74, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
- 0x2e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x29,
- 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63,
- 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x3b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x49,
- 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x28, 0x44, 0x4f, 0x4d, 0x4c,
- 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x29, 0x3b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x7d, 0x2c, 0x20, 0x31, 0x30, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, 0x20, 0x4f, 0x74,
- 0x68, 0x65, 0x72, 0x20, 0x77, 0x65, 0x62, 0x20, 0x62, 0x72, 0x6f, 0x77,
- 0x73, 0x65, 0x72, 0x73, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x6c, 0x6f, 0x61,
- 0x64, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x3c,
- 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x0a, 0x09, 0x09,
- 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65,
- 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73,
- 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x0a,
- 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
- 0x43, 0x6f, 0x6d, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
- 0x28, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x7b, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, 0x2a, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x20, 0x2a, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66,
- 0x6f, 0x72, 0x20, 0x74, 0x77, 0x6f, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x6e,
- 0x65, 0x6c, 0x20, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e,
- 0x6f, 0x75, 0x73, 0x20, 0x68, 0x74, 0x74, 0x70, 0x20, 0x63, 0x6f, 0x6d,
- 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x66,
- 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x20,
- 0x69, 0x6e, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20,
- 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28,
- 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x68, 0x61, 0x73, 0x4f,
- 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6b,
- 0x65, 0x79, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20,
- 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x6b, 0x65, 0x79, 0x5d,
- 0x20, 0x3d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x6b,
- 0x65, 0x79, 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x7d,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76,
- 0x61, 0x72, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x3d, 0x20, 0x74, 0x68,
- 0x69, 0x73, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x78, 0x68, 0x72, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f,
- 0x77, 0x2e, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x20, 0x3f, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x58,
- 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
- 0x74, 0x28, 0x29, 0x20, 0x3a, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x63,
- 0x74, 0x69, 0x76, 0x65, 0x58, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28,
- 0x22, 0x4d, 0x53, 0x58, 0x4d, 0x4c, 0x32, 0x2e, 0x58, 0x4d, 0x4c, 0x48,
- 0x54, 0x54, 0x50, 0x2e, 0x33, 0x2e, 0x30, 0x22, 0x29, 0x29, 0x3b, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d,
- 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x20, 0x3d, 0x20, 0x28, 0x77, 0x69,
- 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x3f, 0x20, 0x6e, 0x65,
- 0x77, 0x20, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x28, 0x29, 0x20, 0x3a, 0x20, 0x6e, 0x65, 0x77,
- 0x20, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x58, 0x4f, 0x62, 0x6a, 0x65,
- 0x63, 0x74, 0x28, 0x22, 0x4d, 0x53, 0x58, 0x4d, 0x4c, 0x32, 0x2e, 0x58,
- 0x4d, 0x4c, 0x48, 0x54, 0x54, 0x50, 0x2e, 0x33, 0x2e, 0x30, 0x22, 0x29,
- 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55,
- 0x55, 0x49, 0x44, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x2f, 0x2f, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
- 0x77, 0x2e, 0x69, 0x65, 0x74, 0x66, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x72,
- 0x66, 0x63, 0x2f, 0x72, 0x66, 0x63, 0x34, 0x31, 0x32, 0x32, 0x2e, 0x74,
- 0x78, 0x74, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20,
- 0x73, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x76, 0x61, 0x72, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69, 0x67, 0x69,
- 0x74, 0x73, 0x20, 0x3d, 0x20, 0x22, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
- 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x22, 0x3b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76,
- 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20,
- 0x3c, 0x20, 0x33, 0x36, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b, 0x69, 0x5d, 0x20,
- 0x3d, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69, 0x67, 0x69, 0x74, 0x73, 0x2e,
- 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e,
- 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72,
- 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x20, 0x2a, 0x20, 0x30, 0x78,
- 0x31, 0x30, 0x29, 0x2c, 0x20, 0x31, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b, 0x31,
- 0x34, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x34, 0x22, 0x3b, 0x20, 0x20, 0x2f,
- 0x2f, 0x20, 0x62, 0x69, 0x74, 0x73, 0x20, 0x31, 0x32, 0x2d, 0x31, 0x35,
- 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65,
- 0x5f, 0x68, 0x69, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x74, 0x6f,
- 0x20, 0x30, 0x30, 0x31, 0x30, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73,
- 0x5b, 0x31, 0x39, 0x5d, 0x20, 0x3d, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69,
- 0x67, 0x69, 0x74, 0x73, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28,
- 0x28, 0x73, 0x5b, 0x31, 0x39, 0x5d, 0x20, 0x26, 0x20, 0x30, 0x78, 0x33,
- 0x29, 0x20, 0x7c, 0x20, 0x30, 0x78, 0x38, 0x2c, 0x20, 0x31, 0x29, 0x3b,
- 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x62, 0x69, 0x74, 0x73, 0x20, 0x36, 0x2d,
- 0x37, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x6f,
- 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x68, 0x69, 0x5f, 0x61, 0x6e,
- 0x64, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x20, 0x74,
- 0x6f, 0x20, 0x30, 0x31, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b,
- 0x38, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x5b, 0x31, 0x33, 0x5d, 0x20, 0x3d,
- 0x20, 0x73, 0x5b, 0x31, 0x38, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x5b, 0x32,
- 0x33, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x2d, 0x22, 0x3b, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x75, 0x75, 0x69, 0x64, 0x20,
- 0x3d, 0x20, 0x73, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72,
- 0x6e, 0x20, 0x75, 0x75, 0x69, 0x64, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74,
- 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x6c,
- 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
- 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c,
- 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e,
- 0x6f, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65,
- 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66,
- 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x72,
- 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x3d,
- 0x3d, 0x20, 0x34, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63,
- 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x74, 0x61,
- 0x74, 0x75, 0x73, 0x20, 0x21, 0x3d, 0x3d, 0x20, 0x32, 0x30, 0x30, 0x29,
- 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73,
- 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x6c,
- 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6f, 0x6e, 0x52, 0x63, 0x76, 0x64, 0x28,
- 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f,
- 0x6c, 0x6c, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c,
- 0x6c, 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x6b,
- 0x65, 0x6e, 0x20, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20, 0x77, 0x65, 0x20,
- 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65,
- 0x78, 0x74, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66,
- 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x6f,
- 0x70, 0x65, 0x6e, 0x28, 0x22, 0x47, 0x45, 0x54, 0x22, 0x2c, 0x20, 0x73,
- 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b,
- 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79,
- 0x20, 0x3f, 0x20, 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c,
- 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22,
- 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c,
- 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e,
- 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65,
- 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74, 0x68, 0x27, 0x2c,
- 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6d,
- 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28,
- 0x22, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22,
- 0x2c, 0x20, 0x22, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x22, 0x29, 0x3b, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f,
- 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x6e, 0x64,
- 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x74, 0x68, 0x69, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e,
- 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x6f, 0x70, 0x65,
- 0x6e, 0x28, 0x22, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x2c, 0x20, 0x73, 0x65,
- 0x6c, 0x66, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b, 0x20,
- 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20,
- 0x3f, 0x20, 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66,
- 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22, 0x29,
- 0x2c, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e,
- 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65,
- 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74, 0x68, 0x27, 0x2c,
- 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65,
- 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64,
- 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d,
- 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x2c, 0x20, 0x22, 0x64, 0x6f, 0x6e, 0x65,
- 0x2e, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72,
- 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x4e, 0x55, 0x4c, 0x4c, 0x29, 0x3b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x6f,
- 0x73, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61,
- 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
- 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65,
- 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x28,
- 0x22, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66,
- 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x73,
- 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3f, 0x20,
- 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71,
- 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22, 0x29, 0x29, 0x3b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78,
- 0x68, 0x72, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
- 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74,
- 0x68, 0x27, 0x2c, 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72,
- 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48,
- 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x53, 0x43, 0x58,
- 0x4d, 0x4c, 0x2d, 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x2c, 0x20, 0x6e, 0x61,
- 0x6d, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66,
- 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
- 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73,
- 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65, 0x74, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
- 0x28, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
- 0x70, 0x65, 0x27, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
- 0x54, 0x79, 0x70, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e,
- 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x64, 0x61, 0x74,
- 0x61, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65,
- 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f,
- 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20,
- 0x73, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69,
- 0x73, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20,
- 0x74, 0x68, 0x69, 0x6e, 0x67, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20,
- 0x61, 0x6c, 0x73, 0x6f, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
- 0x2f, 0x2f, 0x72, 0x61, 0x77, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x75, 0x67, 0x6c, 0x61, 0x73,
- 0x63, 0x72, 0x6f, 0x63, 0x6b, 0x66, 0x6f, 0x72, 0x64, 0x2f, 0x4a, 0x53,
- 0x4f, 0x4e, 0x2d, 0x6a, 0x73, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72,
- 0x2f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2e, 0x6a, 0x73, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74,
- 0x63, 0x68, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x69, 0x6e,
- 0x67, 0x79, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x68, 0x65, 0x72, 0x65,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x79,
- 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x3d,
- 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x29,
- 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72,
- 0x20, 0x73, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x3b, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x77, 0x69, 0x6c,
- 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x6f,
- 0x6e, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x20, 0x61, 0x73, 0x20, 0x74,
- 0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x63, 0x68, 0x65, 0x63,
- 0x6b, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x79, 0x63, 0x6c,
- 0x65, 0x73, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x4a, 0x53,
- 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x66, 0x79,
- 0x28, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6b, 0x65, 0x79, 0x2c, 0x20, 0x76, 0x61,
- 0x6c, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x69, 0x66, 0x20, 0x28, 0x69, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x76,
- 0x61, 0x6c, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
- 0x20, 0x61, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
- 0x20, 0x6f, 0x66, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
- 0x65, 0x73, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72,
- 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x64, 0x3a, 0x20, 0x76, 0x61, 0x6c,
- 0x2e, 0x69, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x76,
- 0x61, 0x6c, 0x2e, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x2c, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63,
- 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x76, 0x61, 0x6c, 0x2e,
- 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x69, 0x66, 0x20, 0x28, 0x69, 0x73, 0x57, 0x69, 0x6e, 0x64, 0x6f,
- 0x77, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x79,
- 0x70, 0x65, 0x6f, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x3d, 0x3d,
- 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x29, 0x20, 0x7b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20,
- 0x28, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f,
- 0x66, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x3e, 0x3d, 0x20, 0x30, 0x29,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65,
- 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28,
- 0x76, 0x61, 0x6c, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74,
- 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d,
- 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69,
- 0x6e, 0x67, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x6f, 0x73,
- 0x74, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61,
- 0x2c, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x29, 0x3b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x20,
- 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20,
- 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68,
- 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68,
- 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x68, 0x74, 0x6d,
- 0x6c, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76,
- 0x61, 0x72, 0x20, 0x69, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20,
- 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6f, 0x29, 0x7b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
- 0x6e, 0x20, 0x28, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20,
- 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x20,
- 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22,
- 0x20, 0x3f, 0x20, 0x6f, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
- 0x65, 0x6f, 0x66, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x3a, 0x20, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x20, 0x26, 0x26,
- 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x20, 0x3d, 0x3d,
- 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x20, 0x26,
- 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x2e, 0x6e,
- 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x3d, 0x20,
- 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x20, 0x26, 0x26, 0x20,
- 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x2e, 0x6e, 0x6f, 0x64,
- 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x73, 0x74, 0x72,
- 0x69, 0x6e, 0x67, 0x22, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x29,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x2f, 0x2f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x20, 0x66,
- 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x64,
- 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x65,
- 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69,
- 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x77, 0x69, 0x6e, 0x64,
- 0x6f, 0x77, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x69,
- 0x73, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x66, 0x75,
- 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6f, 0x29, 0x7b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
- 0x28, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79,
- 0x70, 0x65, 0x6f, 0x66, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20,
- 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22,
- 0x20, 0x3f, 0x20, 0x6f, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
- 0x65, 0x6f, 0x66, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3a,
- 0x20, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x20,
- 0x26, 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x20,
- 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22,
- 0x20, 0x26, 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f,
- 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x3d,
- 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x20, 0x20, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09,
- 0x09, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x3e, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x63, 0x72, 0x69,
- 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78,
- 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x22, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x6d, 0x4c, 0x6f, 0x61,
- 0x64, 0x65, 0x64, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
- 0x20, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63,
- 0x78, 0x6d, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x43, 0x6f,
- 0x6d, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x7b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x65, 0x6c, 0x65, 0x6d,
- 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e,
- 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
- 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x24, 0x7b, 0x73, 0x63, 0x78, 0x6d,
- 0x6c, 0x2e, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x49, 0x64, 0x7d, 0x22,
- 0x29, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x72, 0x76,
- 0x65, 0x72, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
- 0x2e, 0x55, 0x52, 0x4c, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6f,
- 0x6e, 0x52, 0x63, 0x76, 0x64, 0x20, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x64,
- 0x61, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x58, 0x4d, 0x4c, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d,
- 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28,
- 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d, 0x54, 0x79, 0x70,
- 0x65, 0x22, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6c,
- 0x61, 0x63, 0x65, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72,
- 0x20, 0x64, 0x6f, 0x6d, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x20, 0x3d,
- 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28,
- 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d, 0x58, 0x50, 0x61,
- 0x74, 0x68, 0x22, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x22, 0x2f, 0x68, 0x74,
- 0x6d, 0x6c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x3b, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x6d,
- 0x41, 0x74, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e,
- 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48,
- 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58,
- 0x4d, 0x4c, 0x2d, 0x41, 0x74, 0x74, 0x72, 0x22, 0x29, 0x3b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65,
- 0x73, 0x75, 0x6c, 0x74, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d,
- 0x65, 0x6e, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65,
- 0x28, 0x64, 0x6f, 0x6d, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2c, 0x20,
- 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x6e, 0x75,
- 0x6c, 0x6c, 0x2c, 0x20, 0x58, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73,
- 0x75, 0x6c, 0x74, 0x2e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x45, 0x44, 0x5f,
- 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f,
- 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x2c, 0x20, 0x6e, 0x75, 0x6c, 0x6c,
- 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x66,
- 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20,
- 0x30, 0x2c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c,
- 0x74, 0x2e, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4c, 0x65,
- 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x6c, 0x3b,
- 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x69, 0x74, 0x65, 0x6d,
- 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x73, 0x6e,
- 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x28, 0x69,
- 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76,
- 0x61, 0x72, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x64, 0x6f,
- 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72,
- 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72,
- 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x58, 0x4d, 0x4c, 0x2e, 0x66,
- 0x69, 0x72, 0x73, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x20, 0x74,
- 0x72, 0x75, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x28, 0x74, 0x79,
- 0x70, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x66, 0x69, 0x72,
- 0x73, 0x74, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0x3a, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d,
- 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72,
- 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d,
- 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x29,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62,
- 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6c, 0x61, 0x73,
- 0x74, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e,
- 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28,
- 0x6e, 0x6f, 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65,
- 0x20, 0x22, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x73, 0x69,
- 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70,
- 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x69, 0x6e,
- 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x28, 0x6e,
- 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65,
- 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6e, 0x65, 0x78, 0x74, 0x73,
- 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e,
- 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x69,
- 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x28,
- 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6e,
- 0x65, 0x78, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x29, 0x3b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72,
- 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6c,
- 0x61, 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70, 0x61, 0x72,
- 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x6c,
- 0x61, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6e, 0x6f, 0x64,
- 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63,
- 0x61, 0x73, 0x65, 0x20, 0x22, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x22,
- 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e,
- 0x6f, 0x64, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68,
- 0x69, 0x6c, 0x64, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61,
- 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x61, 0x64, 0x64, 0x61, 0x74, 0x74,
- 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e,
- 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
- 0x28, 0x64, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x2c, 0x20, 0x6e, 0x6f,
- 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22,
- 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x63, 0x68, 0x69, 0x6c, 0x64,
- 0x72, 0x65, 0x6e, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x69, 0x74,
- 0x65, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x4e,
- 0x6f, 0x64, 0x65, 0x73, 0x28, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65,
- 0x6d, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x69, 0x6c,
- 0x64, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74,
- 0x43, 0x68, 0x69, 0x6c, 0x64, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x61,
- 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6e,
- 0x6f, 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65,
- 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x73, 0x63, 0x78, 0x6d, 0x6c, 0x2e, 0x6c, 0x6f, 0x6e, 0x67,
- 0x70, 0x6f, 0x6c, 0x6c, 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x63,
- 0x78, 0x6d, 0x6c, 0x3b, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x77, 0x69,
- 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x62, 0x65, 0x66, 0x6f, 0x72,
- 0x65, 0x75, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75,
- 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b,
- 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63, 0x78, 0x6d, 0x6c, 0x2e,
- 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x28, 0x29,
- 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x72, 0x65,
- 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x59, 0x6f, 0x75, 0x20, 0x68, 0x61,
- 0x76, 0x65, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x76, 0x65, 0x64, 0x20, 0x63,
- 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x21, 0x27, 0x3b, 0x0a, 0x09, 0x09,
- 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a,
- 0x09, 0x09, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a,
- 0x0a, 0x09, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x09, 0x3c,
- 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
- 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a
+ 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3d,
+ 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
+ 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f,
+ 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x0a, 0x09, 0x3c, 0x68, 0x65,
+ 0x61, 0x64, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20,
+ 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22,
+ 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65,
+ 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x74,
+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x63, 0x68, 0x61,
+ 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x20,
+ 0x2f, 0x3e, 0x0a, 0x0a, 0x09, 0x09, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x47,
+ 0x65, 0x74, 0x20, 0x64, 0x6f, 0x6d, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64,
+ 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73,
+ 0x73, 0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x73, 0x20, 0x2d,
+ 0x2d, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f,
+ 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x3e,
+ 0x0a, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x6f,
+ 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x31, 0x32,
+ 0x30, 0x36, 0x39, 0x33, 0x37, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x2d, 0x64, 0x6f, 0x6d, 0x72, 0x65, 0x61, 0x64,
+ 0x79, 0x0a, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x6d,
+ 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61,
+ 0x63, 0x6b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a,
+ 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x45, 0x78,
+ 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x2f, 0x2a, 0x40, 0x63, 0x63, 0x5f, 0x6f, 0x6e, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x40, 0x69, 0x66, 0x20, 0x28, 0x40, 0x5f, 0x77, 0x69,
+ 0x6e, 0x33, 0x32, 0x20, 0x7c, 0x7c, 0x20, 0x40, 0x5f, 0x77, 0x69, 0x6e,
+ 0x36, 0x34, 0x29, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x77,
+ 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70,
+ 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 0x65, 0x53, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x22, 0x20, 0x64, 0x65, 0x66, 0x65,
+ 0x72, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x2f, 0x3a, 0x22, 0x3e,
+ 0x3c, 0x5c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x27, 0x29,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d,
+ 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65,
+ 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x69, 0x65, 0x53, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x27, 0x29, 0x2e, 0x6f,
+ 0x6e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x63,
+ 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d,
+ 0x3d, 0x20, 0x27, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x27,
+ 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76,
+ 0x61, 0x72, 0x20, 0x68, 0x65, 0x61, 0x64, 0x3d, 0x20, 0x64, 0x6f, 0x63,
+ 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65,
+ 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61,
+ 0x6d, 0x65, 0x28, 0x27, 0x68, 0x65, 0x61, 0x64, 0x27, 0x29, 0x5b, 0x30,
+ 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61,
+ 0x72, 0x20, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3d, 0x20, 0x64, 0x6f,
+ 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74,
+ 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x27, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2e, 0x74, 0x79,
+ 0x70, 0x65, 0x3d, 0x20, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61,
+ 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, 0x3b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x2e, 0x73, 0x72, 0x63, 0x3d, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x77, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x2d, 0x67, 0x6f, 0x6f,
+ 0x64, 0x2d, 0x78, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66,
+ 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x77, 0x67, 0x78, 0x70, 0x61, 0x74, 0x68,
+ 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x2e, 0x6a, 0x73, 0x27,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x68, 0x65, 0x61,
+ 0x64, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c,
+ 0x64, 0x28, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x29, 0x3b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x77, 0x67, 0x78, 0x70, 0x61, 0x74,
+ 0x68, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x28, 0x29, 0x3b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x6f,
+ 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x31, 0x38,
+ 0x31, 0x31, 0x31, 0x31, 0x36, 0x2f, 0x69, 0x65, 0x2d, 0x73, 0x75, 0x70,
+ 0x70, 0x6f, 0x72, 0x74, 0x2d, 0x66, 0x6f, 0x72, 0x2d, 0x64, 0x6f, 0x6d,
+ 0x2d, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x0a,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d,
+ 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4e, 0x6f,
+ 0x64, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x43,
+ 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x29, 0x20, 0x7b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x73, 0x77, 0x69, 0x74,
+ 0x63, 0x68, 0x20, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64,
+ 0x65, 0x54, 0x79, 0x70, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65,
+ 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x4c,
+ 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x3a, 0x0a,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65,
+ 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
+ 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
+ 0x74, 0x4e, 0x53, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x61, 0x6d,
+ 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x55, 0x52, 0x49, 0x2c, 0x20, 0x6e,
+ 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65,
+ 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
+ 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x20, 0x26,
+ 0x26, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69,
+ 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
+ 0x20, 0x3e, 0x20, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72,
+ 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20,
+ 0x69, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x74,
+ 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e,
+ 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x69, 0x6c, 0x3b,
+ 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e,
+ 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74,
+ 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65,
+ 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5b,
+ 0x69, 0x5d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x2c,
+ 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74,
+ 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
+ 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5b, 0x69,
+ 0x5d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x29, 0x29,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x61, 0x6c, 0x6c, 0x43, 0x68, 0x69,
+ 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x20, 0x26, 0x26, 0x20, 0x6e, 0x6f, 0x64,
+ 0x65, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73,
+ 0x20, 0x26, 0x26, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x68, 0x69,
+ 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67,
+ 0x74, 0x68, 0x20, 0x3e, 0x20, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66,
+ 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30,
+ 0x2c, 0x20, 0x69, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
+ 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x6c,
+ 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x69,
+ 0x6c, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x70,
+ 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x64, 0x6f, 0x63,
+ 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74,
+ 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x68,
+ 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2c,
+ 0x20, 0x61, 0x6c, 0x6c, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e,
+ 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
+ 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x3b, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72,
+ 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63,
+ 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x4e,
+ 0x4f, 0x44, 0x45, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63,
+ 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5f,
+ 0x53, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x44, 0x45,
+ 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20,
+ 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65,
+ 0x6e, 0x74, 0x2e, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4e,
+ 0x4f, 0x44, 0x45, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
+ 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x72,
+ 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x78, 0x74, 0x4e, 0x6f, 0x64, 0x65,
+ 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x7d,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x3b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x40, 0x65, 0x6e,
+ 0x64, 0x20, 0x40, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a,
+ 0x20, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2c, 0x20, 0x43, 0x68,
+ 0x72, 0x6f, 0x6d, 0x65, 0x2c, 0x20, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x20,
+ 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x64,
+ 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x45,
+ 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72,
+ 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63,
+ 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65,
+ 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x27,
+ 0x44, 0x4f, 0x4d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x6f,
+ 0x61, 0x64, 0x65, 0x64, 0x27, 0x2c, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62,
+ 0x61, 0x63, 0x6b, 0x2c, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x3b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x2f, 0x2a, 0x20, 0x53, 0x61, 0x66, 0x61, 0x72, 0x69, 0x2c, 0x20, 0x69,
+ 0x43, 0x61, 0x62, 0x2c, 0x20, 0x4b, 0x6f, 0x6e, 0x71, 0x75, 0x65, 0x72,
+ 0x6f, 0x72, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66,
+ 0x20, 0x28, 0x2f, 0x4b, 0x48, 0x54, 0x4d, 0x4c, 0x7c, 0x57, 0x65, 0x62,
+ 0x4b, 0x69, 0x74, 0x7c, 0x69, 0x43, 0x61, 0x62, 0x2f, 0x69, 0x2e, 0x74,
+ 0x65, 0x73, 0x74, 0x28, 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x6f,
+ 0x72, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x29,
+ 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72,
+ 0x20, 0x44, 0x4f, 0x4d, 0x4c, 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65,
+ 0x72, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72,
+ 0x76, 0x61, 0x6c, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x69, 0x66, 0x20, 0x28, 0x2f, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x7c,
+ 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x69, 0x2e, 0x74,
+ 0x65, 0x73, 0x74, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
+ 0x2e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x29,
+ 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63,
+ 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x3b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x49,
+ 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x28, 0x44, 0x4f, 0x4d, 0x4c,
+ 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x29, 0x3b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x7d, 0x2c, 0x20, 0x31, 0x30, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, 0x20, 0x4f, 0x74,
+ 0x68, 0x65, 0x72, 0x20, 0x77, 0x65, 0x62, 0x20, 0x62, 0x72, 0x6f, 0x77,
+ 0x73, 0x65, 0x72, 0x73, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x6c, 0x6f, 0x61,
+ 0x64, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x3c,
+ 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x0a, 0x09, 0x09,
+ 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65,
+ 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x0a,
+ 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+ 0x43, 0x6f, 0x6d, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+ 0x28, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x7b, 0x0a,
+ 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, 0x2a, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x20, 0x2a, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66,
+ 0x6f, 0x72, 0x20, 0x74, 0x77, 0x6f, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x6e,
+ 0x65, 0x6c, 0x20, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e,
+ 0x6f, 0x75, 0x73, 0x20, 0x68, 0x74, 0x74, 0x70, 0x20, 0x63, 0x6f, 0x6d,
+ 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x66,
+ 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x20,
+ 0x69, 0x6e, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20,
+ 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28,
+ 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x68, 0x61, 0x73, 0x4f,
+ 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6b,
+ 0x65, 0x79, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20,
+ 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x6b, 0x65, 0x79, 0x5d,
+ 0x20, 0x3d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x6b,
+ 0x65, 0x79, 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x7d,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76,
+ 0x61, 0x72, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x3d, 0x20, 0x74, 0x68,
+ 0x69, 0x73, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x78, 0x68, 0x72, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f,
+ 0x77, 0x2e, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x20, 0x3f, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x58,
+ 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x28, 0x29, 0x20, 0x3a, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x63,
+ 0x74, 0x69, 0x76, 0x65, 0x58, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28,
+ 0x22, 0x4d, 0x53, 0x58, 0x4d, 0x4c, 0x32, 0x2e, 0x58, 0x4d, 0x4c, 0x48,
+ 0x54, 0x54, 0x50, 0x2e, 0x33, 0x2e, 0x30, 0x22, 0x29, 0x29, 0x3b, 0x0a,
+ 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x20, 0x3d, 0x20, 0x28, 0x77, 0x69,
+ 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x3f, 0x20, 0x6e, 0x65,
+ 0x77, 0x20, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x28, 0x29, 0x20, 0x3a, 0x20, 0x6e, 0x65, 0x77,
+ 0x20, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x58, 0x4f, 0x62, 0x6a, 0x65,
+ 0x63, 0x74, 0x28, 0x22, 0x4d, 0x53, 0x58, 0x4d, 0x4c, 0x32, 0x2e, 0x58,
+ 0x4d, 0x4c, 0x48, 0x54, 0x54, 0x50, 0x2e, 0x33, 0x2e, 0x30, 0x22, 0x29,
+ 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55,
+ 0x55, 0x49, 0x44, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x2f, 0x2f, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
+ 0x77, 0x2e, 0x69, 0x65, 0x74, 0x66, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x72,
+ 0x66, 0x63, 0x2f, 0x72, 0x66, 0x63, 0x34, 0x31, 0x32, 0x32, 0x2e, 0x74,
+ 0x78, 0x74, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20,
+ 0x73, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x76, 0x61, 0x72, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69, 0x67, 0x69,
+ 0x74, 0x73, 0x20, 0x3d, 0x20, 0x22, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x22, 0x3b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76,
+ 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20,
+ 0x3c, 0x20, 0x33, 0x36, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b, 0x69, 0x5d, 0x20,
+ 0x3d, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69, 0x67, 0x69, 0x74, 0x73, 0x2e,
+ 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e,
+ 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72,
+ 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x20, 0x2a, 0x20, 0x30, 0x78,
+ 0x31, 0x30, 0x29, 0x2c, 0x20, 0x31, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b, 0x31,
+ 0x34, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x34, 0x22, 0x3b, 0x20, 0x20, 0x2f,
+ 0x2f, 0x20, 0x62, 0x69, 0x74, 0x73, 0x20, 0x31, 0x32, 0x2d, 0x31, 0x35,
+ 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65,
+ 0x5f, 0x68, 0x69, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x74, 0x6f,
+ 0x20, 0x30, 0x30, 0x31, 0x30, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73,
+ 0x5b, 0x31, 0x39, 0x5d, 0x20, 0x3d, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69,
+ 0x67, 0x69, 0x74, 0x73, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28,
+ 0x28, 0x73, 0x5b, 0x31, 0x39, 0x5d, 0x20, 0x26, 0x20, 0x30, 0x78, 0x33,
+ 0x29, 0x20, 0x7c, 0x20, 0x30, 0x78, 0x38, 0x2c, 0x20, 0x31, 0x29, 0x3b,
+ 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x62, 0x69, 0x74, 0x73, 0x20, 0x36, 0x2d,
+ 0x37, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x6f,
+ 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x68, 0x69, 0x5f, 0x61, 0x6e,
+ 0x64, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x20, 0x74,
+ 0x6f, 0x20, 0x30, 0x31, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b,
+ 0x38, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x5b, 0x31, 0x33, 0x5d, 0x20, 0x3d,
+ 0x20, 0x73, 0x5b, 0x31, 0x38, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x5b, 0x32,
+ 0x33, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x2d, 0x22, 0x3b, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x75, 0x75, 0x69, 0x64, 0x20,
+ 0x3d, 0x20, 0x73, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72,
+ 0x6e, 0x20, 0x75, 0x75, 0x69, 0x64, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x6c,
+ 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28,
+ 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c,
+ 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e,
+ 0x6f, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65,
+ 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x72,
+ 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x3d,
+ 0x3d, 0x20, 0x34, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x20, 0x21, 0x3d, 0x3d, 0x20, 0x32, 0x30, 0x30, 0x29,
+ 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73,
+ 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x6c,
+ 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6f, 0x6e, 0x52, 0x63, 0x76, 0x64, 0x28,
+ 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f,
+ 0x6c, 0x6c, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c,
+ 0x6c, 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x6b,
+ 0x65, 0x6e, 0x20, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20, 0x77, 0x65, 0x20,
+ 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+ 0x78, 0x74, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x6f,
+ 0x70, 0x65, 0x6e, 0x28, 0x22, 0x47, 0x45, 0x54, 0x22, 0x2c, 0x20, 0x73,
+ 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b,
+ 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79,
+ 0x20, 0x3f, 0x20, 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c,
+ 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22,
+ 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c,
+ 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e,
+ 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65,
+ 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74, 0x68, 0x27, 0x2c,
+ 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28,
+ 0x22, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22,
+ 0x2c, 0x20, 0x22, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x22, 0x29, 0x3b, 0x0a,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x6e, 0x64,
+ 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e,
+ 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x6f, 0x70, 0x65,
+ 0x6e, 0x28, 0x22, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x2c, 0x20, 0x73, 0x65,
+ 0x6c, 0x66, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b, 0x20,
+ 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20,
+ 0x3f, 0x20, 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66,
+ 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22, 0x29,
+ 0x2c, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e,
+ 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65,
+ 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74, 0x68, 0x27, 0x2c,
+ 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65,
+ 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64,
+ 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d,
+ 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x2c, 0x20, 0x22, 0x64, 0x6f, 0x6e, 0x65,
+ 0x2e, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72,
+ 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x4e, 0x55, 0x4c, 0x4c, 0x29, 0x3b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x6f,
+ 0x73, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61,
+ 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
+ 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65,
+ 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x28,
+ 0x22, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66,
+ 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x73,
+ 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3f, 0x20,
+ 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71,
+ 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22, 0x29, 0x29, 0x3b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78,
+ 0x68, 0x72, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74,
+ 0x68, 0x27, 0x2c, 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72,
+ 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48,
+ 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x53, 0x43, 0x58,
+ 0x4d, 0x4c, 0x2d, 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x2c, 0x20, 0x6e, 0x61,
+ 0x6d, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66,
+ 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
+ 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73,
+ 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65, 0x74, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
+ 0x28, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
+ 0x70, 0x65, 0x27, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+ 0x54, 0x79, 0x70, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e,
+ 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x64, 0x61, 0x74,
+ 0x61, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65,
+ 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f,
+ 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20,
+ 0x73, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20,
+ 0x74, 0x68, 0x69, 0x6e, 0x67, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x0a,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20,
+ 0x61, 0x6c, 0x73, 0x6f, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
+ 0x2f, 0x2f, 0x72, 0x61, 0x77, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x75, 0x67, 0x6c, 0x61, 0x73,
+ 0x63, 0x72, 0x6f, 0x63, 0x6b, 0x66, 0x6f, 0x72, 0x64, 0x2f, 0x4a, 0x53,
+ 0x4f, 0x4e, 0x2d, 0x6a, 0x73, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72,
+ 0x2f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2e, 0x6a, 0x73, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74,
+ 0x63, 0x68, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x69, 0x6e,
+ 0x67, 0x79, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x68, 0x65, 0x72, 0x65,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x79,
+ 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x3d,
+ 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x29,
+ 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72,
+ 0x20, 0x73, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x3b, 0x0a,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x77, 0x69, 0x6c,
+ 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x6f,
+ 0x6e, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x20, 0x61, 0x73, 0x20, 0x74,
+ 0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x63, 0x68, 0x65, 0x63,
+ 0x6b, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x79, 0x63, 0x6c,
+ 0x65, 0x73, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x4a, 0x53,
+ 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x66, 0x79,
+ 0x28, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6b, 0x65, 0x79, 0x2c, 0x20, 0x76, 0x61,
+ 0x6c, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x69, 0x66, 0x20, 0x28, 0x69, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x76,
+ 0x61, 0x6c, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
+ 0x20, 0x61, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x6f, 0x66, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
+ 0x65, 0x73, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72,
+ 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x64, 0x3a, 0x20, 0x76, 0x61, 0x6c,
+ 0x2e, 0x69, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x76,
+ 0x61, 0x6c, 0x2e, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x2c, 0x0a,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63,
+ 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x76, 0x61, 0x6c, 0x2e,
+ 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x69, 0x66, 0x20, 0x28, 0x69, 0x73, 0x57, 0x69, 0x6e, 0x64, 0x6f,
+ 0x77, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x79,
+ 0x70, 0x65, 0x6f, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x3d, 0x3d,
+ 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x29, 0x20, 0x7b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20,
+ 0x28, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f,
+ 0x66, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x3e, 0x3d, 0x20, 0x30, 0x29,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65,
+ 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28,
+ 0x76, 0x61, 0x6c, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74,
+ 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d,
+ 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69,
+ 0x6e, 0x67, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x6f, 0x73,
+ 0x74, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61,
+ 0x2c, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x29, 0x3b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x20,
+ 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20,
+ 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68,
+ 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68,
+ 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x68, 0x74, 0x6d,
+ 0x6c, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76,
+ 0x61, 0x72, 0x20, 0x69, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20,
+ 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6f, 0x29, 0x7b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
+ 0x6e, 0x20, 0x28, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20,
+ 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x20,
+ 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22,
+ 0x20, 0x3f, 0x20, 0x6f, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
+ 0x65, 0x6f, 0x66, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x3a, 0x20, 0x0a,
+ 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x20, 0x26, 0x26,
+ 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x20, 0x3d, 0x3d,
+ 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x20, 0x26,
+ 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x2e, 0x6e,
+ 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x3d, 0x20,
+ 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x20, 0x26, 0x26, 0x20,
+ 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x2e, 0x6e, 0x6f, 0x64,
+ 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x73, 0x74, 0x72,
+ 0x69, 0x6e, 0x67, 0x22, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x29,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x2f, 0x2f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x20, 0x66,
+ 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x64,
+ 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x65,
+ 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69,
+ 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x77, 0x69, 0x6e, 0x64,
+ 0x6f, 0x77, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x69,
+ 0x73, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x66, 0x75,
+ 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6f, 0x29, 0x7b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
+ 0x28, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79,
+ 0x70, 0x65, 0x6f, 0x66, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20,
+ 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22,
+ 0x20, 0x3f, 0x20, 0x6f, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
+ 0x65, 0x6f, 0x66, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3a,
+ 0x20, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x20,
+ 0x26, 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x20,
+ 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22,
+ 0x20, 0x26, 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f,
+ 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x3d,
+ 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x20, 0x20, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09,
+ 0x09, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x3e, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78,
+ 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x22, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x6d, 0x4c, 0x6f, 0x61,
+ 0x64, 0x65, 0x64, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63,
+ 0x78, 0x6d, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x43, 0x6f,
+ 0x6d, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x7b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x65, 0x6c, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e,
+ 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x24, 0x7b, 0x73, 0x63, 0x78, 0x6d,
+ 0x6c, 0x2e, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x49, 0x64, 0x7d, 0x22,
+ 0x29, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x72, 0x76,
+ 0x65, 0x72, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
+ 0x2e, 0x55, 0x52, 0x4c, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6f,
+ 0x6e, 0x52, 0x63, 0x76, 0x64, 0x20, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x64,
+ 0x61, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x58, 0x4d, 0x4c, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d,
+ 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28,
+ 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d, 0x54, 0x79, 0x70,
+ 0x65, 0x22, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6c,
+ 0x61, 0x63, 0x65, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72,
+ 0x20, 0x64, 0x6f, 0x6d, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x20, 0x3d,
+ 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28,
+ 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d, 0x58, 0x50, 0x61,
+ 0x74, 0x68, 0x22, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x22, 0x2f, 0x68, 0x74,
+ 0x6d, 0x6c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x3b, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x6d,
+ 0x41, 0x74, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e,
+ 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48,
+ 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58,
+ 0x4d, 0x4c, 0x2d, 0x41, 0x74, 0x74, 0x72, 0x22, 0x29, 0x3b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65,
+ 0x73, 0x75, 0x6c, 0x74, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d,
+ 0x65, 0x6e, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65,
+ 0x28, 0x64, 0x6f, 0x6d, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2c, 0x20,
+ 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x6e, 0x75,
+ 0x6c, 0x6c, 0x2c, 0x20, 0x58, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73,
+ 0x75, 0x6c, 0x74, 0x2e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x45, 0x44, 0x5f,
+ 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f,
+ 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x2c, 0x20, 0x6e, 0x75, 0x6c, 0x6c,
+ 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x66,
+ 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20,
+ 0x30, 0x2c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c,
+ 0x74, 0x2e, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4c, 0x65,
+ 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x6c, 0x3b,
+ 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x69, 0x74, 0x65, 0x6d,
+ 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x73, 0x6e,
+ 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x28, 0x69,
+ 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76,
+ 0x61, 0x72, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x64, 0x6f,
+ 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72,
+ 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x58, 0x4d, 0x4c, 0x2e, 0x66,
+ 0x69, 0x72, 0x73, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x20, 0x74,
+ 0x72, 0x75, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x28, 0x74, 0x79,
+ 0x70, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x66, 0x69, 0x72,
+ 0x73, 0x74, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0x3a, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d,
+ 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72,
+ 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d,
+ 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x29,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62,
+ 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6c, 0x61, 0x73,
+ 0x74, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e,
+ 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28,
+ 0x6e, 0x6f, 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65,
+ 0x20, 0x22, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x73, 0x69,
+ 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70,
+ 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x69, 0x6e,
+ 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x28, 0x6e,
+ 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65,
+ 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6e, 0x65, 0x78, 0x74, 0x73,
+ 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e,
+ 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x69,
+ 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x28,
+ 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6e,
+ 0x65, 0x78, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x29, 0x3b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72,
+ 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6c,
+ 0x61, 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70, 0x61, 0x72,
+ 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x6c,
+ 0x61, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6e, 0x6f, 0x64,
+ 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63,
+ 0x61, 0x73, 0x65, 0x20, 0x22, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x22,
+ 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e,
+ 0x6f, 0x64, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68,
+ 0x69, 0x6c, 0x64, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61,
+ 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x61, 0x64, 0x64, 0x61, 0x74, 0x74,
+ 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e,
+ 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+ 0x28, 0x64, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x2c, 0x20, 0x6e, 0x6f,
+ 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22,
+ 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x63, 0x68, 0x69, 0x6c, 0x64,
+ 0x72, 0x65, 0x6e, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x69, 0x74,
+ 0x65, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x4e,
+ 0x6f, 0x64, 0x65, 0x73, 0x28, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65,
+ 0x6d, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x69, 0x6c,
+ 0x64, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74,
+ 0x43, 0x68, 0x69, 0x6c, 0x64, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x61,
+ 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6e,
+ 0x6f, 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x0a,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65,
+ 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x73, 0x63, 0x78, 0x6d, 0x6c, 0x2e, 0x6c, 0x6f, 0x6e, 0x67,
+ 0x70, 0x6f, 0x6c, 0x6c, 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09,
+ 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x63,
+ 0x78, 0x6d, 0x6c, 0x3b, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x77, 0x69,
+ 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x62, 0x65, 0x66, 0x6f, 0x72,
+ 0x65, 0x75, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75,
+ 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b,
+ 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63, 0x78, 0x6d, 0x6c, 0x2e,
+ 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x28, 0x29,
+ 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x72, 0x65,
+ 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x59, 0x6f, 0x75, 0x20, 0x68, 0x61,
+ 0x76, 0x65, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x76, 0x65, 0x64, 0x20, 0x63,
+ 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x21, 0x27, 0x3b, 0x0a, 0x09, 0x09,
+ 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a,
+ 0x09, 0x09, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a,
+ 0x0a, 0x09, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x09, 0x3c,
+ 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
+ 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a
};
unsigned int template_xhtml_invoker_html_len = 8253;
diff --git a/src/uscxml/server/HTTPServer.cpp b/src/uscxml/server/HTTPServer.cpp
index 1b92203..37be5a9 100644
--- a/src/uscxml/server/HTTPServer.cpp
+++ b/src/uscxml/server/HTTPServer.cpp
@@ -115,7 +115,7 @@ HTTPServer::HTTPServer(unsigned short port, unsigned short wsPort, SSLConfig* ss
LOG(ERROR) << "WebSocket server cannot bind to tcp/" << _wsPort;
}
}
-
+
#if (defined EVENT_SSL_FOUND && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES)
// have another look here https://github.com/ppelleti/https-example/blob/master/https-server.c
_sslHandle = NULL;
diff --git a/src/uscxml/server/HTTPServer.h b/src/uscxml/server/HTTPServer.h
index dc9af53..7fedd83 100644
--- a/src/uscxml/server/HTTPServer.h
+++ b/src/uscxml/server/HTTPServer.h
@@ -78,7 +78,7 @@ public:
type = req.data.compound["type"].atom;
evhttpReq = req.evhttpReq;
}
-
+
int status;
std::string type;
std::map<std::string, std::string> headers;
diff --git a/src/uscxml/server/Socket.cpp b/src/uscxml/server/Socket.cpp
index fc79357..35b416e 100644
--- a/src/uscxml/server/Socket.cpp
+++ b/src/uscxml/server/Socket.cpp
@@ -92,7 +92,7 @@ void Socket::parseAddress(const std::string& address, std::string& protocol, std
protocol = "tcp";
protEnd = 0;
}
-
+
size_t hostEnd = address.find(":", protEnd);
if (hostEnd != std::string::npos) {
hostName = address.substr(protEnd, hostEnd - protEnd);
@@ -109,7 +109,7 @@ void Socket::parseAddress(const std::string& address, std::string& protocol, std
}
}
-
+
ClientSocket::ClientSocket(int domain, int type, int protocol) : Socket(domain, type, protocol), _clientEvent(NULL) {
}
@@ -149,7 +149,7 @@ void ClientSocket::connect(const std::string& address) {
parseAddress(address, _prot, _address, _port);
connect(_address, _port);
}
-
+
void ClientSocket::connect(const std::string& address, int port) {
// tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
@@ -166,7 +166,7 @@ void ClientSocket::connect(const std::string& address, int port) {
int ClientSocket::write(const std::string& data) {
return write(data.data(), data.size());
}
-
+
int ClientSocket::write(const char* data, size_t size) {
// tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
bufferevent_write(_clientEvent, data, size);
@@ -182,7 +182,7 @@ void ClientSocket::readCallback(struct bufferevent *bev, void *ctx) {
char* data = (char*)malloc(instance->_blockSizeRead);
input = bufferevent_get_input(bev);
-
+
while((n = evbuffer_remove(input, data, instance->_blockSizeRead)) > 0) {
instance->readCallback(data, n);
}
@@ -357,8 +357,8 @@ void ServerSocket::Connection::reply(const char* data, size_t size) {
PacketServerSocket::~PacketServerSocket() {
for(std::map<Connection, std::stringstream*>::iterator fragIter = _fragments.begin();
- fragIter != _fragments.end();
- fragIter++) {
+ fragIter != _fragments.end();
+ fragIter++) {
delete fragIter->second;
}
}
@@ -366,10 +366,10 @@ PacketServerSocket::~PacketServerSocket() {
void PacketServerSocket::readCallback(const char* data, size_t size, Connection& conn) {
if (_fragments.find(conn) == _fragments.end())
_fragments[conn] = new std::stringstream();
-
+
std::stringstream* fragment = _fragments[conn];
*fragment << std::string(data, size);
-
+
size_t startPos = 0;
size_t endPos;
const std::string& buffer = fragment->str();
diff --git a/src/uscxml/server/Socket.h b/src/uscxml/server/Socket.h
index 7bb8ebe..01e91b2 100644
--- a/src/uscxml/server/Socket.h
+++ b/src/uscxml/server/Socket.h
@@ -112,7 +112,7 @@ protected:
std::string _sep;
std::map<Connection, std::stringstream*> _fragments;
};
-
+
class USCXML_API ClientSocket : public Socket {
public:
ClientSocket(int domain, int type, int protocol);
diff --git a/src/uscxml/transform/ChartToFSM.cpp b/src/uscxml/transform/ChartToFSM.cpp
index 1971ae2..2c5aacd 100644
--- a/src/uscxml/transform/ChartToFSM.cpp
+++ b/src/uscxml/transform/ChartToFSM.cpp
@@ -33,17 +33,27 @@
#undef max
#include <limits>
+#define DUMP_TRANSSET(where) \
+{\
+std::cout << std::endl;\
+std::cout << "** " << transitions.size() << " ** " << where << std::endl;\
+ for (int m = 0; m < transitions.size(); m++) {\
+ std::cout << transitions[m] << std::endl;\
+ }\
+}
namespace uscxml {
using namespace Arabica::DOM;
using namespace Arabica::XPath;
-#define CREATE_TRANSIENT_STATE_WITH_CHILDS \
+#define CREATE_TRANSIENT_STATE_WITH_CHILDS(stateId) \
if (childs.size() > 0) { \
Element<std::string> transientState = _flatDoc.createElementNS(_nsInfo.nsURL, "state"); \
_nsInfo.setPrefix(transientState);\
transientState.setAttribute("transient", "true"); \
+ if (stateId.length() > 0) \
+ transientState.setAttribute("id", stateId); \
for (int i = 0; i < childs.size(); i++) { \
Node<std::string> imported = _flatDoc.importNode(childs[i], true); \
transientState.appendChild(imported); \
@@ -52,6 +62,15 @@ if (childs.size() > 0) { \
} \
childs = NodeSet<std::string>();
+#define DETAIL_EXEC_CONTENT(field, actPtr) \
+std::cerr << " " << #field << " / " << TAGNAME_CAST(actPtr->field) << " ("; \
+NodeSet<std::string> contents = filterChildType(Node_base::ELEMENT_NODE, actPtr->field, true); \
+for (int i = 0; i < contents.size(); i++) { \
+ std::cerr << " " << TAGNAME_CAST(contents[i]); \
+} \
+std::cerr << ")";
+
+
Interpreter ChartToFSM::flatten(const Interpreter& other) {
// instantiate a new InterpreterImpl to do the flattening
@@ -132,7 +151,7 @@ FlatteningInterpreter::FlatteningInterpreter(const Document<std::string>& doc) {
_lastTimeStamp = tthread::chrono::system_clock::now();
_currGlobalTransition = NULL;
_lastTransientStateId = 0;
-
+
// just copy given doc into _document an create _flatDoc for the FSM
DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
_document = domFactory.createDocument(doc.getNamespaceURI(), "", 0);
@@ -199,6 +218,12 @@ InterpreterState FlatteningInterpreter::interpret() {
_binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY);
+ // set invokeid for all invokers to parent state if none given
+ NodeSet<std::string> invokers = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true);
+ for (int i = 0; i < invokers.size(); i++) {
+ Element<std::string> invokerElem = Element<std::string>(invokers[i]);
+ invokerElem.setAttribute("parent", ATTR_CAST(invokerElem.getParentNode(), "id"));
+ }
// reset
_globalConf.clear();
_currGlobalTransition = NULL;
@@ -208,7 +233,7 @@ InterpreterState FlatteningInterpreter::interpret() {
_start = new GlobalState(_configuration, _alreadyEntered, _historyValue, _nsInfo.xmlNSPrefix);
_globalConf[_start->stateId] = _start;
_globalConf[_start->stateId]->index = toStr(GlobalState::gIndex++);
-
+
NodeSet<std::string> initialTransitions;
// enter initial configuration
@@ -229,7 +254,7 @@ InterpreterState FlatteningInterpreter::interpret() {
labelTransitions();
// weightTransitions();
indexTransitions(_scxml);
-
+
// std::cerr << _scxml << std::endl;
GlobalTransition* globalTransition = new GlobalTransition(initialTransitions, _dataModel, this);
@@ -251,7 +276,9 @@ InterpreterState FlatteningInterpreter::interpret() {
#endif
createDocument();
-
+
+// std::cout << _scxml << std::endl;
+
NodeSet<std::string> elements = InterpreterImpl::filterChildType(Node_base::ELEMENT_NODE, _scxml, true);
uint64_t nrStates = 0;
for (int i = 0; i < elements.size(); i++) {
@@ -279,7 +306,9 @@ void FlatteningInterpreter::executeContent(const Arabica::DOM::Element<std::stri
} else if (TAGNAME(content) == "onexit") {
action.onExit = content;
} else if (TAGNAME(content) == "onentry") {
- action.onExit = content;
+ action.onEntry = content;
+ } else if (TAGNAME(content) == "history") {
+ assert(false);
} else { // e.g. global script elements
return;
}
@@ -410,7 +439,7 @@ void FlatteningInterpreter::indexTransitions(const Arabica::DOM::Element<std::st
for (int i = levelTransitions.size() - 1; i >= 0; i--) {
indexedTransitions.push_back(Element<std::string>(levelTransitions[i]));
}
-
+
Arabica::XPath::NodeSet<std::string> nextLevel = filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, root);
for (int i = nextLevel.size() - 1; i >= 0; i--) {
Element<std::string> stateElem = Element<std::string>(nextLevel[i]);
@@ -424,7 +453,7 @@ bool GlobalTransition::operator< (const GlobalTransition& other) const {
const std::list<Arabica::DOM::Element<std::string> >& indexedTransitions = interpreter->indexedTransitions;
for (std::list<Element<std::string> >::const_reverse_iterator transIter = indexedTransitions.rbegin(); transIter != indexedTransitions.rend(); transIter++) {
const Element<std::string>& refTrans = *transIter;
-
+
if (InterpreterImpl::isMember(refTrans, transitions) && !InterpreterImpl::isMember(refTrans, other.transitions)) {
return true;
}
@@ -434,7 +463,7 @@ bool GlobalTransition::operator< (const GlobalTransition& other) const {
}
return true; // actually, they are equal
}
-
+
void FlatteningInterpreter::explode() {
@@ -467,14 +496,14 @@ void FlatteningInterpreter::explode() {
delete globalState;
return; // we have already been here
}
-
+
_globalConf[globalState->stateId] = globalState;
_globalConf[globalState->stateId]->index = toStr(GlobalState::gIndex++);
- assert(isLegalConfiguration(configuration));
+// assert(isLegalConfiguration(configuration));
if(_globalConf[globalState->stateId]->isFinal)
return; // done in this branch
-
+
// get all transition elements from states in the current configuration
NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", configuration);
@@ -534,7 +563,7 @@ void FlatteningInterpreter::explode() {
std::map<std::string, GlobalTransition*> transitionSets;
while(1) {
- // create the power set of all potential transitions
+ // create the power set of all potential transitions - this is expensive!
// see: http://www.programminglogic.com/powerset-algorithm-in-c/
if (stack[k] < nrElements) {
@@ -558,6 +587,19 @@ void FlatteningInterpreter::explode() {
}
// std::cerr << std::endl;
+// transitions.push_back(allTransitions[0]);
+// transitions.push_back(allTransitions[4]);
+// transitions.push_back(allTransitions[5]);
+// transitions.push_back(allTransitions[7]);
+
+ bool dump = false;
+
+// if (k == 4 && stack[1] == 1 && stack[2] == 5 && stack[3] == 6 && stack[4] == 8) {
+// dump = true;
+// }
+
+ if (dump) DUMP_TRANSSET("at start");
+
_perfTotal++;
_perfProcessed++;
@@ -574,13 +616,17 @@ void FlatteningInterpreter::explode() {
// remove transitions in the same state
if(!filterSameState(transitions))
continue;
+ if (dump) DUMP_TRANSSET("after same state filtered");
// remove those transitions with a child transition
if(!filterChildEnabled(transitions))
continue;
+ if (dump) DUMP_TRANSSET("after child enabled filtered");
// reduce to conflict-free subset
+ // transitions.to_document_order();
transitions = removeConflictingTransitions(transitions);
+ if (dump) DUMP_TRANSSET("after conflicting filtered");
// algorithm can never reduce to empty set
assert(transitions.size() > 0);
@@ -600,49 +646,6 @@ void FlatteningInterpreter::explode() {
continue;
}
-#if 0
- for (int currDepth = 0; currDepth <= maxDepth; currDepth++) {
- int lowestOrder = std::numeric_limits<int32_t>::max();
- int nrDepth = 0;
- int prioPerLevel = 0;
- for (int i = 0; i < transitions.size(); i++) {
- int depth = strTo<int>(ATTR_CAST(transitions[i], "depth"));
- if (depth != currDepth)
- continue;
- nrDepth++;
- int order = strTo<int>(ATTR_CAST(transitions[i], "order"));
- if (order < lowestOrder)
- lowestOrder = order;
- prioPerLevel += pow(static_cast<double>(maxOrder), maxOrder - order);
- }
- transition->nrElemPerLevel.push_back(nrDepth);
- transition->firstElemPerLevel.push_back(lowestOrder);
- transition->prioPerLevel.push_back(prioPerLevel);
- }
-#endif
-#if 0
- // calculate priority
- transition->priority = 0;
- for (int currDepth = maxDepth; currDepth >= 0; currDepth--) {
- // what's the deepest depth of this set?
- for (int i = 0; i < transitions.size(); i++) {
- int depth = strTo<int>(ATTR(transitions[i], "depth"));
- if (depth == currDepth) {
- int highestOrder = 0;
- // what's the highest order at this depth?
- for (int j = 0; j < transitions.size(); j++) {
- int order = strTo<int>(ATTR(transitions[j], "order"));
- if (order > highestOrder)
- highestOrder = order;
- }
- transition->priority += pow(maxOrder + 1, currDepth); // + (maxOrder - highestOrder);
- goto NEXT_DEPTH;
- }
- }
-NEXT_DEPTH:
- ;
- }
-#endif
// remember this conflict-free set
// std::cerr << "New conflict-free subset: " << transition->transitionId << ":" << transition->eventDesc << std::endl;
transitionSets[transition->transitionId] = transition;
@@ -666,19 +669,19 @@ NEXT_DEPTH:
_currGlobalTransition = *transListIter;
microstep((*transListIter)->transitions);
- if (!isLegalConfiguration(_configuration)) {
- FlatStateIdentifier fromState(configuration, alreadyEntered, historyValue);
- FlatStateIdentifier toState(_configuration, _alreadyEntered, _historyValue);
- std::cerr << "invalid configuration after transition " << std::endl
- << "from \t" << fromState.getStateId() << std::endl
- << "to \t" << toState.getStateId() << std::endl
- << "via ------" << std::endl;
- for (int i = 0; i < (*transListIter)->transitions.size(); i++) {
- std::cerr << (*transListIter)->transitions[i] << std::endl;
- }
- std::cerr << "----------" << std::endl;
- assert(false);
- }
+// if (!isLegalConfiguration(_configuration)) {
+// FlatStateIdentifier fromState(configuration, alreadyEntered, historyValue);
+// FlatStateIdentifier toState(_configuration, _alreadyEntered, _historyValue);
+// std::cerr << "invalid configuration after transition " << std::endl
+// << "from \t" << fromState.getStateId() << std::endl
+// << "to \t" << toState.getStateId() << std::endl
+// << "via ------" << std::endl;
+// for (int i = 0; i < (*transListIter)->transitions.size(); i++) {
+// std::cerr << (*transListIter)->transitions[i] << std::endl;
+// }
+// std::cerr << "----------" << std::endl;
+// assert(false);
+// }
explode();
// reset state for next transition set
@@ -706,6 +709,10 @@ void FlatteningInterpreter::createDocument() {
_scxml.setAttribute("datamodel", ATTR(_origSCXML, "datamodel"));
}
+ if (HAS_ATTR(_origSCXML, "name")) {
+ _scxml.setAttribute("name", ATTR(_origSCXML, "name"));
+ }
+
if (HAS_ATTR(_origSCXML, "binding")) {
_scxml.setAttribute("binding", ATTR(_origSCXML, "binding"));
}
@@ -743,14 +750,14 @@ void FlatteningInterpreter::createDocument() {
std::vector<std::pair<std::string,GlobalState*> > sortedStates;
sortedStates.insert(sortedStates.begin(), _globalConf.begin(), _globalConf.end());
std::sort(sortedStates.begin(), sortedStates.end(), sortStatesByIndex);
-
+
int index = 0;
for (std::list<Element<std::string> >::reverse_iterator transIter = indexedTransitions.rbegin(); transIter != indexedTransitions.rend(); transIter++) {
const Element<std::string>& refTrans = *transIter;
std::cerr << index++ << ": " << refTrans << std::endl;
}
std::cerr << std::endl;
-
+
for (std::vector<std::pair<std::string,GlobalState*> >::iterator confIter = sortedStates.begin();
confIter != sortedStates.end();
confIter++) {
@@ -761,8 +768,7 @@ void FlatteningInterpreter::createDocument() {
}
-template <typename T> bool PtrComp(const T * const & a, const T * const & b)
-{
+template <typename T> bool PtrComp(const T * const & a, const T * const & b) {
return *a < *b;
}
@@ -794,17 +800,17 @@ bool hasEarlierUnconditionalMatch(GlobalTransition* first, GlobalTransition* sec
// for some reason, unique is not quite up to the task
std::list<GlobalTransition*> reapplyUniquePredicates(std::list<GlobalTransition*> list) {
-
+
for (std::list<GlobalTransition*>::iterator outerIter = list.begin();
- outerIter != list.end();
- outerIter++) {
+ outerIter != list.end();
+ outerIter++) {
for (std::list<GlobalTransition*>::iterator innerIter = outerIter;
- innerIter != list.end();
- innerIter++) {
-
+ innerIter != list.end();
+ innerIter++) {
+
if (innerIter == outerIter)
continue;
-
+
GlobalTransition* t1 = *outerIter;
GlobalTransition* t2 = *innerIter;
@@ -874,7 +880,8 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition
#if 1
transition.setAttribute("members", globalTransition->members);
#endif
-
+ // transition.setAttribute("priority", toStr(globalTransition->priority));
+
if (!globalTransition->isEventless) {
transition.setAttribute("event", globalTransition->eventDesc);
}
@@ -883,50 +890,28 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition
transition.setAttribute("cond", globalTransition->condition);
}
-// transition.setAttribute("priority", toStr(globalTransition->priority));
-
-#if 0
- std::stringstream feSS;
- std::string seperator = "";
- for (int i = 0; i < globalTransition->firstElemPerLevel.size(); i++) {
- feSS << seperator << globalTransition->firstElemPerLevel[i];
- seperator = ", ";
- }
- transition.setAttribute("firstPerLevel", feSS.str());
-
- std::stringstream nrSS;
- seperator = "";
- for (int i = 0; i < globalTransition->nrElemPerLevel.size(); i++) {
- nrSS << seperator << globalTransition->nrElemPerLevel[i];
- seperator = ", ";
+ if (globalTransition->destination.size() > 0) {
+ transition.setAttribute("final-target", globalTransition->destination);
}
- transition.setAttribute("numberPerLevel", nrSS.str());
-
- std::stringstream prSS;
- seperator = "";
- for (int i = 0; i < globalTransition->prioPerLevel.size(); i++) {
- prSS << seperator << globalTransition->prioPerLevel[i];
- seperator = ", ";
- }
- transition.setAttribute("prioPerLevel", nrSS.str());
-#endif
+ NodeSet<std::string> transientStateChain;
-// std::cerr << " firstPerLevel:" << feSS.str() << " " << globalTransition->transitionId << std::endl;
-// std::cerr << "event: " << globalTransition->eventDesc << " firstPerLevel:" << feSS.str() << " numberPerLevel:" << nrSS.str() << " prioPerLevel:" << prSS.str() << " " << globalTransition->transitionId << std::endl;
-// std::cerr << globalTransition->transitionId << std::endl;
+ // current active state set
+ FlatStateIdentifier flatId(globalTransition->source);
+ std::list<std::string> currActiveStates = flatId.getActive();
- NodeSet<std::string> transientStateChain;
+// std::cerr << "From " << globalTransition->source << " to " << globalTransition->destination << ":" << std::endl;
// gather content for new transient state
NodeSet<std::string> childs;
-
// iterate all actions taken during the transition
for (std::list<GlobalTransition::Action>::iterator actionIter = globalTransition->actions.begin();
actionIter != globalTransition->actions.end();
actionIter++) {
if (actionIter->transition) {
+// DETAIL_EXEC_CONTENT(transition, actionIter);
+
Element<std::string> onexit = _flatDoc.createElementNS(_nsInfo.nsURL, "onexit");
_nsInfo.setPrefix(onexit);
Node<std::string> child = actionIter->transition.getFirstChild();
@@ -935,24 +920,31 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition
onexit.appendChild(imported);
child = child.getNextSibling();
}
+ // only append if there is something done
if (onexit.hasChildNodes())
childs.push_back(onexit);
+
continue;
}
if (actionIter->onExit) {
+// DETAIL_EXEC_CONTENT(onExit, actionIter);
+
childs.push_back(actionIter->onExit);
continue;
}
if (actionIter->onEntry) {
+// DETAIL_EXEC_CONTENT(onEntry, actionIter);
+
childs.push_back(actionIter->onEntry);
continue;
}
if (actionIter->invoke) {
+// DETAIL_EXEC_CONTENT(invoke, actionIter);
if (!globalTransition->isTargetless) {
- CREATE_TRANSIENT_STATE_WITH_CHILDS
+// CREATE_TRANSIENT_STATE_WITH_CHILDS(FlatStateIdentifier::toStateId(currActiveStates));
}
Element<std::string> invokeElem = Element<std::string>(actionIter->invoke);
invokeElem.setAttribute("persist", "true");
@@ -961,6 +953,7 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition
}
if (actionIter->uninvoke) {
+// DETAIL_EXEC_CONTENT(uninvoke, actionIter);
Element<std::string> uninvokeElem = _flatDoc.createElementNS(_nsInfo.nsURL, "uninvoke");
_nsInfo.setPrefix(uninvokeElem);
@@ -980,7 +973,20 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition
continue;
}
+ if (actionIter->exited) {
+// std::cerr << " exited(" << ATTR_CAST(actionIter->exited, "id") << ")";
+ currActiveStates.remove(ATTR_CAST(actionIter->exited, "id"));
+ if (childs.size() > 0) {
+ CREATE_TRANSIENT_STATE_WITH_CHILDS(FlatStateIdentifier::toStateId(currActiveStates)); // create a new transient state to update its id
+ }
+ }
+
if (actionIter->entered) {
+// std::cerr << " entered(" << ATTR_CAST(actionIter->entered, "id") << ")";
+ if (childs.size() > 0)
+ CREATE_TRANSIENT_STATE_WITH_CHILDS(FlatStateIdentifier::toStateId(currActiveStates)); // create a new transient state to update its id
+ currActiveStates.push_back(ATTR_CAST(actionIter->entered, "id"));
+
// we entered a new child - check if it has a datamodel and we entered for the first time
if (_binding == InterpreterImpl::LATE) {
NodeSet<std::string> datamodel = filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", actionIter->entered);
@@ -990,46 +996,58 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition
}
}
if (!globalTransition->isTargetless) {
- CREATE_TRANSIENT_STATE_WITH_CHILDS
+// CREATE_TRANSIENT_STATE_WITH_CHILDS(FlatStateIdentifier::toStateId(currActiveStates))
}
}
- if (globalTransition->isTargetless) {
- for (int i = 0; i < childs.size(); i++) {
- Node<std::string> imported = _flatDoc.importNode(childs[i], true);
- transition.appendChild(imported);
- }
- return transition;
- }
+// std::cerr << std::endl;
+
+// if (globalTransition->isTargetless) {
+// for (int i = 0; i < childs.size(); i++) {
+// Node<std::string> imported = _flatDoc.importNode(childs[i], true);
+// transition.appendChild(imported);
+// // CREATE_TRANSIENT_STATE_WITH_CHILDS(FlatStateIdentifier::toStateId(currActiveStates))
+// }
+// return transition;
+// }
- CREATE_TRANSIENT_STATE_WITH_CHILDS
+ CREATE_TRANSIENT_STATE_WITH_CHILDS(FlatStateIdentifier::toStateId(currActiveStates))
if (transientStateChain.size() > 0) {
+ Element<std::string> prevExitTransitionElem;
+
for (int i = 0; i < transientStateChain.size(); i++) {
Element<std::string> transientStateElem = Element<std::string>(transientStateChain[i]);
-// transientStateElem.setAttribute("id", "transient-" + globalTransition->transitionId + "-" + globalTransition->source + "-" + toStr(i));
- transientStateElem.setAttribute("id", globalTransition->destination + "-via-" + toStr(_lastTransientStateId++));
+ transientStateElem.setAttribute("id", transientStateElem.getAttribute("id") + "-via-" + toStr(_lastTransientStateId++));
Element<std::string> exitTransition = _flatDoc.createElementNS(_nsInfo.nsURL, "transition");
_nsInfo.setPrefix(exitTransition);
- if (i == transientStateChain.size() - 1) {
- exitTransition.setAttribute("target", globalTransition->destination);
+ if (prevExitTransitionElem) {
+ // point previous to this one
+ prevExitTransitionElem.setAttribute("target", transientStateElem.getAttribute("id"));
} else {
-// exitTransition.setAttribute("target", "transient-" + globalTransition->transitionId + "-" + globalTransition->source + "-" + toStr(i + 1));
- exitTransition.setAttribute("target", globalTransition->destination + "-via-" + toStr(_lastTransientStateId));
+ // update globalTransition->source target
}
+
transientStateElem.appendChild(exitTransition);
+ prevExitTransitionElem = exitTransition;
if (i == 0)
transition.setAttribute("target", transientStateElem.getAttribute("id"));
_scxml.appendChild(transientStateElem);
}
+
+ // last one points to actual target
+ assert(prevExitTransitionElem);
+ prevExitTransitionElem.setAttribute("target", globalTransition->destination);
+
} else {
transition.setAttribute("target", globalTransition->destination);
}
+ assert(HAS_ATTR_CAST(transition, "target"));
return transition;
}
@@ -1101,7 +1119,7 @@ int GlobalState::gIndex = 0;
GlobalState::GlobalState(const Arabica::XPath::NodeSet<std::string>& activeStates_,
const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates_, // we need to remember for binding=late
const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates_,
- const std::string& xmlNSPrefix) {
+ const std::string& xmlNSPrefix) {
// make copies and sort
activeStates = activeStates_;
@@ -1117,7 +1135,7 @@ GlobalState::GlobalState(const Arabica::XPath::NodeSet<std::string>& activeState
break;
}
}
-
+
// sort configuration
activeStates.to_document_order();
alreadyEnteredStates.to_document_order();
@@ -1176,6 +1194,9 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t
index++;
}
+// if (members == " 4 6 7 ")
+// std::cout << "asdfadf";
+
/**
* Can these events event occur together? They can't if:
* 1. event / eventless is mixed
diff --git a/src/uscxml/transform/ChartToFSM.h b/src/uscxml/transform/ChartToFSM.h
index a60985d..2f97a24 100644
--- a/src/uscxml/transform/ChartToFSM.h
+++ b/src/uscxml/transform/ChartToFSM.h
@@ -21,7 +21,7 @@
#define CHARTTOFSM_H_IOKPYEBY
#include "uscxml/DOMUtils.h"
-#include "uscxml/interpreter/InterpreterDraft6.h"
+#include "uscxml/interpreter/InterpreterRC.h"
#include <DOM/Document.hpp>
#include <DOM/Node.hpp>
#include <XPath/XPath.hpp>
@@ -32,7 +32,7 @@ namespace uscxml {
class GlobalState;
class GlobalTransition;
class FlatteningInterpreter;
-
+
class USCXML_API GlobalState {
public:
@@ -40,7 +40,7 @@ public:
GlobalState(const Arabica::XPath::NodeSet<std::string>& activeStates,
const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates, // we need to remember for binding=late
const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates,
- const std::string& xmlNSPrefix);
+ const std::string& xmlNSPrefix);
Arabica::XPath::NodeSet<std::string> activeStates;
Arabica::XPath::NodeSet<std::string> alreadyEnteredStates;
@@ -51,7 +51,7 @@ public:
std::string stateId;
static int gIndex;
-
+
std::string index;
bool isFinal;
};
@@ -103,14 +103,14 @@ public:
std::string index;
FlatteningInterpreter* interpreter;
-
+
bool operator< (const GlobalTransition& other) const;
-
+
protected:
std::list<std::string> getCommonEvents(const Arabica::XPath::NodeSet<std::string>& transitions);
};
-class USCXML_API FlatteningInterpreter : public InterpreterDraft6, public InterpreterMonitor {
+class USCXML_API FlatteningInterpreter : public InterpreterRC, public InterpreterMonitor {
public:
FlatteningInterpreter(const Arabica::DOM::Document<std::string>& doc);
virtual ~FlatteningInterpreter();
@@ -161,7 +161,7 @@ protected:
int maxOrder;
size_t _lastTransientStateId;
-
+
Arabica::DOM::Document<std::string> _flatDoc;
std::map<std::string, GlobalState*> _globalConf;
};
diff --git a/src/uscxml/transform/FSMToPromela.cpp b/src/uscxml/transform/FSMToPromela.cpp
index 238e40f..8c2836f 100644
--- a/src/uscxml/transform/FSMToPromela.cpp
+++ b/src/uscxml/transform/FSMToPromela.cpp
@@ -19,7 +19,10 @@
#include "uscxml/transform/ChartToFSM.h"
#include "uscxml/transform/FSMToPromela.h"
+#include "uscxml/transform/FlatStateIdentifier.h"
#include "uscxml/plugins/datamodel/promela/PromelaParser.h"
+#include "uscxml/plugins/datamodel/promela/parser/promela.tab.hpp"
+
#include <DOM/io/Stream.hpp>
#include <iostream>
#include "uscxml/UUID.h"
@@ -27,6 +30,15 @@
#include <boost/algorithm/string.hpp>
#include <glog/logging.h>
+#define MAX_MACRO_CHARS 64
+#define MIN_COMMENT_PADDING 60
+
+#define BIT_WIDTH(number) (number > 1 ? (int)ceil(log((double)number) / log((double)2.0)) : 1)
+
+#define INDENT_MIN(stream, start, cols) \
+for (int indentIndex = start; indentIndex < cols; indentIndex++) \
+ stream << " ";
+
namespace uscxml {
using namespace Arabica::DOM;
@@ -39,7 +51,7 @@ void FSMToPromela::writeProgram(std::ostream& stream,
promelaWriter.writeProgram(stream);
}
-FSMToPromela::FSMToPromela() : _eventTrie(".") {
+FSMToPromela::FSMToPromela() {
}
void PromelaEventSource::writeStartEventSources(std::ostream& stream, int indent) {
@@ -126,16 +138,18 @@ void PromelaEventSource::writeEventSource(std::ostream& stream) {
stream << " " << ":: " << sourceName << "EventSourceDone -> skip;" << std::endl;
stream << " " << ":: else { " << std::endl;
+ Trie& trie = analyzer->getTrie();
+
if (sourceIter->type == PromelaInline::PROMELA_EVENT_SOURCE_CUSTOM) {
std::string content = sourceIter->content;
boost::replace_all(content, "#REDO#", sourceName + "NewEvent");
boost::replace_all(content, "#DONE#", sourceName + "Done");
- std::list<TrieNode*> eventNames = trie->getChildsWithWords(trie->getNodeWithPrefix(""));
+ std::list<TrieNode*> eventNames = trie.getChildsWithWords(trie.getNodeWithPrefix(""));
std::list<TrieNode*>::iterator eventNameIter = eventNames.begin();
while(eventNameIter != eventNames.end()) {
- boost::replace_all(content, "#" + (*eventNameIter)->value + "#", "e" + toStr((*eventNameIter)->identifier));
+ boost::replace_all(content, "#" + (*eventNameIter)->value + "#", (*eventNameIter)->identifier);
eventNameIter++;
}
@@ -150,7 +164,7 @@ void PromelaEventSource::writeEventSource(std::ostream& stream) {
stream << " " << ":: ";
std::list<std::string>::const_iterator evIter = seqIter->begin();
while(evIter != seqIter->end()) {
- TrieNode* node = trie->getNodeWithPrefix(*evIter);
+ TrieNode* node = trie.getNodeWithPrefix(*evIter);
stream << "eQ!" << node->identifier << "; ";
evIter++;
}
@@ -173,54 +187,409 @@ void PromelaEventSource::writeEventSource(std::ostream& stream) {
PromelaEventSource::PromelaEventSource() {
type = PROMELA_EVENT_SOURCE_INVALID;
- trie = NULL;
+ analyzer = NULL;
}
PromelaEventSource::PromelaEventSource(const PromelaInlines& sources, const Arabica::DOM::Node<std::string>& parent) {
type = PROMELA_EVENT_SOURCE_INVALID;
- trie = NULL;
+ analyzer = NULL;
eventSources = sources;
container = parent;
}
+void PromelaCodeAnalyzer::addCode(const std::string& code) {
+ PromelaParser parser(code);
+
+ // find all strings
+ std::list<PromelaParserNode*> astNodes;
+ astNodes.push_back(parser.ast);
+
+ while(astNodes.size() > 0) {
+ PromelaParserNode* node = astNodes.front();
+ astNodes.pop_front();
+
+ switch (node->type) {
+ case PML_STRING: {
+ std::string unquoted = node->value;
+ if (boost::starts_with(unquoted, "'")) {
+ unquoted = unquoted.substr(1, unquoted.size() - 2);
+ }
+ addLiteral(unquoted);
+ break;
+ }
+ case PML_CMPND: {
+ std::string nameOfType;
+ std::list<PromelaParserNode*>::iterator opIter = node->operands.begin();
+ assert((*opIter)->type == PML_NAME);
+
+ PromelaTypedef* td = &_typeDefs;
+ std::string seperator;
+
+ while(opIter != node->operands.end()) {
+ switch ((*opIter)->type) {
+ case PML_NAME:
+ td = &td->types[(*opIter)->value];
+ nameOfType += seperator + (*opIter)->value;
+ if (nameOfType.compare("_x") == 0)
+ _usesPlatformVars = true;
+ seperator = "_";
+ td->name = nameOfType + "_t";
+ break;
+ case PML_VAR_ARRAY: {
+ PromelaParserNode* name = (*opIter)->operands.front();
+ PromelaParserNode* subscript = *(++(*opIter)->operands.begin());
+ td = &td->types[name->value];
+ nameOfType += seperator + name->value;
+ td->name = nameOfType + "_t";
+
+ if (isInteger(subscript->value.c_str(), 10)) {
+ td->arraySize = strTo<int>(subscript->value);
+ }
+ break;
+ }
+ default:
+ node->dump();
+ assert(false);
+ break;
+ }
+
+ if (nameOfType.compare("_x_states") == 0) {
+ _usesInPredicate = true;
+ }
+ if (nameOfType.compare("_event_type") == 0) {
+ addLiteral("internal");
+ addLiteral("external");
+ addLiteral("platform");
+ }
+ if (nameOfType.compare("_event_origintype") == 0) {
+ addLiteral("http://www.w3.org/TR/scxml/#SCXMLEventProcessor");
+ }
+ opIter++;
+ }
+ break;
+ }
+ case PML_NAME: {
+ }
+ default:
+ break;
+// node->dump();
+// assert(false);
+ }
+
+ astNodes.merge(node->operands);
+ }
+}
+
+void PromelaCodeAnalyzer::addEvent(const std::string& eventName) {
+ if (_events.find(eventName) != _events.end())
+ return;
+
+ addLiteral(eventName, _lastEventIndex);
+ assert(_strIndex.find(eventName) != _strIndex.end());
+
+ _eventTrie.addWord(eventName);
+ _events[eventName] = _strIndex[eventName];
+ _lastEventIndex++;
+}
+
+void PromelaCodeAnalyzer::addState(const std::string& stateName) {
+ if (_states.find(stateName) != _states.end())
+ return;
+
+ createMacroName(stateName);
+
+// addLiteral(stateName);
+// _states[stateName] = enumerateLiteral(stateName);
+ if (_origStateMap.find(stateName) == _origStateMap.end()) {
+ FlatStateIdentifier flatId(stateName);
+ _origStateMap[stateName] = flatId.getActive();
+ for (std::list<std::string>::iterator origIter = _origStateMap[stateName].begin(); origIter != _origStateMap[stateName].end(); origIter++) {
+ //addLiteral(*origIter); // add original state names as string literals
+ if (_origStateIndex.find(*origIter) == _origStateIndex.end()) {
+ _origStateIndex[*origIter] = _lastStateIndex++;
+ createMacroName(*origIter);
+ }
+ }
+ }
+}
+
+int PromelaCodeAnalyzer::arrayIndexForOrigState(const std::string& stateName) {
+ if (_origStateIndex.find(stateName) == _origStateIndex.end())
+ throw std::runtime_error("No original state " + stateName + " known");
+ return _origStateIndex[stateName];
+}
+
+void PromelaCodeAnalyzer::addLiteral(const std::string& literal, int forceIndex) {
+ if (boost::starts_with(literal, "'"))
+ throw std::runtime_error("Literal " + literal + " passed with quotes");
+
+ if (_strLiterals.find(literal) != _strLiterals.end())
+ return;
+
+ _strLiterals.insert(literal);
+ createMacroName(literal);
+ enumerateLiteral(literal, forceIndex);
+}
+
+int PromelaCodeAnalyzer::enumerateLiteral(const std::string& literal, int forceIndex) {
+ if (forceIndex >= 0) {
+ _strIndex[literal] = forceIndex;
+ return forceIndex;
+ }
+
+ if (_strIndex.find(literal) != _strIndex.end())
+ return _strIndex[literal];
+
+ _strIndex[literal] = ++_lastStrIndex;
+ return _lastStrIndex + 1;
+}
+
+std::string PromelaCodeAnalyzer::createMacroName(const std::string& literal) {
+ if (_strMacroNames.find(literal) != _strMacroNames.end())
+ return _strMacroNames[literal];
+
+ // find a suitable macro name for the strings
+ std::string macroName = literal; //literal.substr(1, literal.size() - 2);
+
+ // cannot start with digit
+ if (isInteger(macroName.substr(0,1).c_str(), 10))
+ macroName = "_" + macroName;
+
+ macroName = macroName.substr(0, MAX_MACRO_CHARS);
+ boost::to_upper(macroName);
+
+ std::string illegalChars = "#\\/:?\"<>| \n\t()[]{}',.-";
+ std::string tmp;
+ std::string::iterator it = macroName.begin();
+ while (it < macroName.end()) {
+ bool found = illegalChars.find(*it) != std::string::npos;
+ if(found) {
+ tmp += '_';
+ it++;
+ while(it < macroName.end() && illegalChars.find(*it) != std::string::npos) {
+ it++;
+ }
+ } else {
+ tmp += *it++;
+ }
+ }
+ macroName = tmp;
+
+ unsigned int index = 2;
+ while (_macroNameSet.find(macroName) != _macroNameSet.end()) {
+ std::string suffix = toStr(index);
+ if (macroName.size() > suffix.size()) {
+ macroName = macroName.substr(0, macroName.size() - suffix.size()) + suffix;
+ } else {
+ macroName = suffix;
+ }
+ index++;
+ }
+
+ _macroNameSet.insert(macroName);
+ _strMacroNames[literal] = macroName;
+ return macroName;
+}
+
+std::string PromelaCodeAnalyzer::macroForLiteral(const std::string& literal) {
+ if (boost::starts_with(literal, "'"))
+ throw std::runtime_error("Literal " + literal + " passed with quotes");
+
+ if (_strMacroNames.find(literal) == _strMacroNames.end())
+ throw std::runtime_error("No macro for literal " + literal + " known");
+ return _strMacroNames[literal];
+}
+
+int PromelaCodeAnalyzer::indexForLiteral(const std::string& literal) {
+ if (boost::starts_with(literal, "'"))
+ throw std::runtime_error("Literal " + literal + " passed with quotes");
+
+ if (_strIndex.find(literal) == _strIndex.end())
+ throw std::runtime_error("No index for literal " + literal + " known");
+ return _strIndex[literal];
+}
+
+std::string PromelaCodeAnalyzer::replaceLiterals(const std::string code) {
+ std::string replaced = code;
+ for (std::map<std::string, std::string>::const_iterator litIter = _strMacroNames.begin(); litIter != _strMacroNames.end(); litIter++) {
+ boost::replace_all(replaced, "'" + litIter->first + "'", litIter->second);
+ }
+ return replaced;
+}
+
+std::set<std::string> PromelaCodeAnalyzer::getEventsWithPrefix(const std::string& prefix) {
+ std::set<std::string> eventNames;
+ std::list<TrieNode*> trieNodes = _eventTrie.getWordsWithPrefix(prefix);
+
+ std::list<TrieNode*>::iterator trieIter = trieNodes.begin();
+ while(trieIter != trieNodes.end()) {
+ eventNames.insert((*trieIter)->value);
+ trieIter++;
+ }
+
+ return eventNames;
+}
+
+
void FSMToPromela::writeEvents(std::ostream& stream) {
- std::list<TrieNode*> eventNames = _eventTrie.getWordsWithPrefix("");
- std::list<TrieNode*>::iterator eventIter = eventNames.begin();
- stream << "// event name identifiers" << std::endl;
- while(eventIter != eventNames.end()) {
- stream << "#define " << "e" << (*eventIter)->identifier << " " << (*eventIter)->identifier;
- stream << " // from \"" << (*eventIter)->value << "\"" << std::endl;
+ std::map<std::string, int> events = _analyzer.getEvents();
+ std::map<std::string, int>::iterator eventIter = events.begin();
+ stream << "/* event name identifiers */" << std::endl;
+ while(eventIter != events.end()) {
+ if (eventIter->first.length() > 0) {
+ stream << "#define " << _analyzer.macroForLiteral(eventIter->first) << " " << _analyzer.indexForLiteral(eventIter->first);
+ stream << " /* from \"" << eventIter->first << "\" */" << std::endl;
+ }
eventIter++;
}
}
void FSMToPromela::writeStates(std::ostream& stream) {
- stream << "// state name identifiers" << std::endl;
+ stream << "/* state name identifiers */" << std::endl;
for (int i = 0; i < _globalStates.size(); i++) {
stream << "#define " << "s" << i << " " << i;
- stream << " // from \"" << ATTR_CAST(_globalStates[i], "id") << "\"" << std::endl;
+ stream << " /* from \"" << ATTR_CAST(_globalStates[i], "id") << "\" */" << std::endl;
+ }
+}
+
+void FSMToPromela::writeStateMap(std::ostream& stream) {
+ stream << "/* macros for original state names */" << std::endl;
+ std::map<std::string, int> origStates = _analyzer.getOrigStates();
+ for (std::map<std::string, int>::iterator origIter = origStates.begin(); origIter != origStates.end(); origIter++) {
+ stream << "#define " << _analyzer.macroForLiteral(origIter->first) << " " << origIter->second;
+ stream << " /* from \"" << origIter->first << "\" */" << std::endl;
}
+// std::map<std::string, int> states = _analyzer.getStates();
+// size_t stateIndex = 0;
+// for (std::map<std::string, int>::iterator stateIter = states.begin(); stateIter != states.end(); stateIter++) {
+// stream << "_x"
+// std::list<std::string> origStates = _analyzer.getOrigState(stateIter->first);
+// size_t origIndex = 0;
+// for (std::list<std::string>::iterator origIter = origStates.begin(); origIter != origStates.end(); origIter++) {
+//
+// }
+// }
}
-Arabica::XPath::NodeSet<std::string> FSMToPromela::getTransientContent(const Arabica::DOM::Element<std::string>& state) {
+void FSMToPromela::writeTypeDefs(std::ostream& stream) {
+ stream << "/* typedefs */" << std::endl;
+ PromelaCodeAnalyzer::PromelaTypedef typeDefs = _analyzer.getTypes();
+ if (typeDefs.types.size() == 0)
+ return;
+
+ std::list<PromelaCodeAnalyzer::PromelaTypedef> individualDefs;
+ std::list<PromelaCodeAnalyzer::PromelaTypedef> currDefs;
+ currDefs.push_back(typeDefs);
+
+ while(currDefs.size() > 0) {
+ if (std::find(individualDefs.begin(), individualDefs.end(), currDefs.front()) == individualDefs.end()) {
+ individualDefs.push_back(currDefs.front());
+ for (std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator typeIter = currDefs.front().types.begin(); typeIter != currDefs.front().types.end(); typeIter++) {
+ currDefs.push_back(typeIter->second);
+ }
+ }
+ currDefs.pop_front();
+ }
+ individualDefs.pop_front();
+
+ for (std::list<PromelaCodeAnalyzer::PromelaTypedef>::reverse_iterator rIter = individualDefs.rbegin(); rIter != individualDefs.rend(); rIter++) {
+ PromelaCodeAnalyzer::PromelaTypedef currDef = *rIter;
+ if (currDef.types.size() == 0 || currDef.name.size() == 0)
+ continue;
+// if (currDef.name.compare("_x_t") == 0) {
+// stream << "typedef platform_t {" << std::endl;
+// if (_analyzer.usesInPredicate()) {
+// stream << " bool states[" << _analyzer.getOrigStates().size() << "];" << std::endl;
+// }
+// stream << "};" << std::endl;
+//
+// continue;
+// }
+ stream << "typedef " << currDef.name << " {" << std::endl;
+ if (currDef.name.compare("_event_t") == 0 && currDef.types.find("name") == currDef.types.end()) { // special treatment for _event
+ stream << " int name;" << std::endl;
+ }
+ for (std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator tIter = currDef.types.begin(); tIter != currDef.types.end(); tIter++) {
+ if (currDef.name.compare("_x_t") == 0 && tIter->first.compare("states") == 0) {
+ stream << " bool states[" << _analyzer.getOrigStates().size() << "];" << std::endl;
+ continue;
+ }
+ if (tIter->second.types.size() == 0) {
+ stream << " int " << tIter->first << ";" << std::endl; // not further nested
+ } else {
+ stream << " " << tIter->second.name << " " << tIter->first << ";" << std::endl;
+ }
+ }
+ stream << "};" << std::endl << std::endl;
+ }
+
+ stream << "/* typedef instances */" << std::endl;
+ PromelaCodeAnalyzer::PromelaTypedef allTypes = _analyzer.getTypes();
+ std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator typeIter = allTypes.types.begin();
+ while(typeIter != allTypes.types.end()) {
+ stream << typeIter->second.name << " " << typeIter->first << ";" << std::endl;
+ typeIter++;
+ }
+
+}
+
+Arabica::XPath::NodeSet<std::string> FSMToPromela::getTransientContent(const Arabica::DOM::Element<std::string>& state, const std::string& source) {
Arabica::XPath::NodeSet<std::string> content;
Arabica::DOM::Element<std::string> currState = state;
+ FlatStateIdentifier prevFlatId(source);
for (;;) {
- if (!HAS_ATTR(currState, "transient") || !DOMUtils::attributeIsTrue(ATTR(currState, "transient")))
+ if (_analyzer.usesInPredicate()) {
+ // insert state assignments into executable content
+
+ std::stringstream stateSetPromela;
+ stateSetPromela << "#promela-inline " << std::endl;
+ FlatStateIdentifier currFlatId(ATTR(currState, "id"));
+ stateSetPromela << " /* from " << prevFlatId.getFlatActive() << " to " << currFlatId.getFlatActive() << " */" << std::endl;
+
+ // add all that are missing from prevFlatId
+ std::map<std::string, int> allOrigStates = _analyzer.getOrigStates();
+ for (std::map<std::string, int>::iterator allOrigIter = allOrigStates.begin(); allOrigIter != allOrigStates.end(); allOrigIter++) {
+ if (std::find(currFlatId.getActive().begin(), currFlatId.getActive().end(), allOrigIter->first) != currFlatId.getActive().end() &&
+ std::find(prevFlatId.getActive().begin(), prevFlatId.getActive().end(), allOrigIter->first) == prevFlatId.getActive().end()) {
+ // active now but not previously
+ stateSetPromela << " _x.states[" << _analyzer.macroForLiteral(allOrigIter->first) << "] = true; " << std::endl;
+ } else if (std::find(currFlatId.getActive().begin(), currFlatId.getActive().end(), allOrigIter->first) == currFlatId.getActive().end() &&
+ std::find(prevFlatId.getActive().begin(), prevFlatId.getActive().end(), allOrigIter->first) != prevFlatId.getActive().end()) {
+ // previously active but not now
+ stateSetPromela << " _x.states[" << _analyzer.macroForLiteral(allOrigIter->first) << "] = false; " << std::endl;
+ }
+ }
+ Comment<std::string> comment = _document.createComment(stateSetPromela.str());
+ _document.importNode(comment, true);
+ currState.insertBefore(comment, currState.getFirstChild());
+ prevFlatId = currFlatId;
+ }
+
+ content.push_back(filterChildType(Node_base::COMMENT_NODE, currState));
+ if (_analyzer.usesInPredicate()) assert(content.size() > 0);
+
+ if (!HAS_ATTR(currState, "transient") || !DOMUtils::attributeIsTrue(ATTR(currState, "transient"))) {
+ // breaking here causes final state assignment to be written
break;
+ }
+
content.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "invoke", currState));
content.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "onentry", currState));
content.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "onexit", currState));
+
NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", currState);
currState = _states[ATTR_CAST(transitions[0], "target")];
}
-
return content;
}
Node<std::string> FSMToPromela::getUltimateTarget(const Arabica::DOM::Element<std::string>& transition) {
+ if (!HAS_ATTR(transition, "target")) {
+ return transition.getParentNode();
+ }
+
Arabica::DOM::Element<std::string> currState = _states[ATTR_CAST(transition, "target")];
for (;;) {
@@ -237,7 +606,7 @@ void FSMToPromela::writeInlineComment(std::ostream& stream, const Arabica::DOM::
std::string comment = node.getNodeValue();
boost::trim(comment);
- if (!boost::starts_with(comment, "promela-inline:"))
+ if (!boost::starts_with(comment, "#promela-inline"))
return;
std::stringstream ssLine(comment);
@@ -250,18 +619,25 @@ void FSMToPromela::writeInlineComment(std::ostream& stream, const Arabica::DOM::
}
}
-void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::DOM::Element<std::string>& node, int indent) {
+void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent) {
+
+// std::cout << std::endl << node << std::endl;
+ if (!node)
+ return;
std::string padding;
for (int i = 0; i < indent; i++) {
padding += " ";
}
+// std::cerr << node << std::endl;
+
if (node.getNodeType() == Node_base::COMMENT_NODE) {
+ // we cannot have labels in an atomic block, just process inline promela
std::string comment = node.getNodeValue();
boost::trim(comment);
std::stringstream inlinePromela;
- if (!boost::starts_with(comment, "promela-inline:"))
+ if (!boost::starts_with(comment, "#promela-inline"))
return;
std::stringstream ssLine(comment);
std::string line;
@@ -278,81 +654,166 @@ void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::D
if (node.getNodeType() != Node_base::ELEMENT_NODE)
return;
+ Arabica::DOM::Element<std::string> nodeElem = Arabica::DOM::Element<std::string>(node);
+
if (false) {
- } else if(TAGNAME(node) == "state") {
- if (HAS_ATTR(node, "transient") && DOMUtils::attributeIsTrue(ATTR(node, "transient"))) {
- Arabica::XPath::NodeSet<std::string> execContent = getTransientContent(node);
- for (int i = 0; i < execContent.size(); i++) {
- writeExecutableContent(stream, Arabica::DOM::Element<std::string>(execContent[i]), indent);
- }
- } else {
- Arabica::DOM::Node<std::string> child = node.getFirstChild();
- while(child) {
- writeExecutableContent(stream, Arabica::DOM::Element<std::string>(child), indent);
- child = child.getNextSibling();
- }
- }
- } else if(TAGNAME(node) == "transition") {
- stream << "t" << _transitions[node] << ":" << std::endl;
+// } else if(TAGNAME(nodeElem) == "state") {
+// if (HAS_ATTR(nodeElem, "transient") && DOMUtils::attributeIsTrue(ATTR(nodeElem, "transient"))) {
+// Arabica::XPath::NodeSet<std::string> execContent = getTransientContent(nodeElem);
+// for (int i = 0; i < execContent.size(); i++) {
+// writeExecutableContent(stream, execContent[i], indent);
+// }
+// }
+ } else if(TAGNAME(nodeElem) == "transition") {
+ stream << "t" << _transitions[nodeElem] << ":";
+
+ int number = _transitions[nodeElem];
+ int digits = 0;
+ do {
+ number /= 10;
+ digits++;
+ } while (number != 0);
+
+ INDENT_MIN(stream, 2 + digits, MIN_COMMENT_PADDING);
+
+ Node<std::string> source = node.getParentNode();
+ stream << " /* from state " << ATTR_CAST(source, "id") << " */" << std::endl;
+
+ // gather all executable content
+ NodeSet<std::string> execContent = getTransientContent(_states[ATTR(nodeElem, "target")], ATTR_CAST(source, "id"));
// check for special promela labels
- PromelaInlines promInls = getInlinePromela(getTransientContent(_states[ATTR(node, "target")]), true);
-
- if (promInls.acceptLabels > 0)
- stream << padding << "acceptLabelT" << _transitions[node] << ":" << std::endl;
- if (promInls.endLabels > 0)
- stream << padding << "endLabelT" << _transitions[node] << ":" << std::endl;
- if (promInls.progressLabels > 0)
- stream << padding << "progressLabelT" << _transitions[node] << ":" << std::endl;
+ if (HAS_ATTR(nodeElem, "target")) {
+ PromelaInlines promInls = getInlinePromela(execContent, true);
+
+ if (promInls.acceptLabels > 0)
+ stream << padding << "acceptLabelT" << _transitions[nodeElem] << ":" << std::endl;
+ if (promInls.endLabels > 0)
+ stream << padding << "endLabelT" << _transitions[nodeElem] << ":" << std::endl;
+ if (promInls.progressLabels > 0)
+ stream << padding << "progressLabelT" << _transitions[nodeElem] << ":" << std::endl;
+ }
stream << padding << "atomic {" << std::endl;
- writeExecutableContent(stream, _states[ATTR(node, "target")], indent+1);
+// writeExecutableContent(stream, _states[ATTR(nodeElem, "target")], indent+1);
+ for (int i = 0; i < execContent.size(); i++) {
+ writeExecutableContent(stream, execContent[i], indent+1);
+ }
stream << padding << " skip;" << std::endl;
- Node<std::string> newState = getUltimateTarget(node);
+ Node<std::string> newState = getUltimateTarget(nodeElem);
for (int i = 0; i < _globalStates.size(); i++) {
if (newState != _globalStates[i])
continue;
- stream << padding << " s = s" << i << ";" << std::endl;
+
+ std::string stateId = ATTR_CAST(_globalStates[i], "id");
+
+ stream << padding << " s = s" << i << ";";
+
+ int number = i;
+ int digits = 0;
+ do {
+ number /= 10;
+ digits++;
+ } while (number != 0);
+
+ INDENT_MIN(stream, 10 + digits, MIN_COMMENT_PADDING);
+
+ stream << " /* to state " << stateId << " */" << std::endl;
+
+// if (_analyzer.usesInPredicate()) {
+// FlatStateIdentifier flatId(stateId);
+// std::map<std::string, int> allOrigStates = _analyzer.getOrigStates();
+// for (std::map<std::string, int>::iterator allOrigIter = allOrigStates.begin(); allOrigIter != allOrigStates.end(); allOrigIter++) {
+// stream << padding << " _x.states[" << _analyzer.macroForLiteral(allOrigIter->first) << "] = ";
+// if (std::find(flatId.getActive().begin(), flatId.getActive().end(), allOrigIter->first) != flatId.getActive().end()) {
+// stream << "true;" << std::endl;
+// } else {
+// stream << "false;" << std::endl;
+// }
+// }
+// }
+
}
stream << padding << "}" << std::endl;
if (isFinal(Element<std::string>(newState))) {
- stream << padding << "goto terminate;" << std::endl;
+ stream << padding << "goto terminate;";
+ INDENT_MIN(stream, padding.length() + 14, MIN_COMMENT_PADDING);
+ stream << "/* final state */" << std::endl;
+ } else if (!HAS_ATTR_CAST(node, "event")) {
+ stream << padding << "goto nextTransition;";
+ INDENT_MIN(stream, padding.length() + 19, MIN_COMMENT_PADDING);
+ stream << "/* spontaneous transition, check for more transitions */" << std::endl;
} else {
- stream << padding << "goto nextStep;" << std::endl;
+ stream << padding << "eventLess = true;" << std::endl;
+ stream << padding << "goto nextTransition;";
+ INDENT_MIN(stream, padding.length() + 21, MIN_COMMENT_PADDING);
+ stream << "/* ordinary transition, check for spontaneous transitions */" << std::endl;
}
- } else if(TAGNAME(node) == "onentry" || TAGNAME(node) == "onexit") {
+ } else if(TAGNAME(nodeElem) == "onentry" || TAGNAME(nodeElem) == "onexit") {
Arabica::DOM::Node<std::string> child = node.getFirstChild();
while(child) {
- writeExecutableContent(stream, Arabica::DOM::Element<std::string>(child), indent);
+// std::cerr << node << std::endl;
+ if (child.getNodeType() == Node_base::TEXT_NODE) {
+ if (boost::trim_copy(child.getNodeValue()).length() > 0)
+ stream << beautifyIndentation(_analyzer.replaceLiterals(child.getNodeValue()), indent) << std::endl;
+ }
+ if (child.getNodeType() == Node_base::ELEMENT_NODE) {
+ writeExecutableContent(stream, child, indent);
+ }
child = child.getNextSibling();
}
- } else if(TAGNAME(node) == "script") {
+ } else if(TAGNAME(nodeElem) == "script") {
NodeSet<std::string> scriptText = filterChildType(Node_base::TEXT_NODE, node, true);
for (int i = 0; i < scriptText.size(); i++) {
- stream << beautifyIndentation(scriptText[i].getNodeValue(), indent) << std::endl;
+ stream << _analyzer.replaceLiterals(beautifyIndentation(scriptText[i].getNodeValue(), indent)) << std::endl;
}
- } else if(TAGNAME(node) == "log") {
- // ignore
+ } else if(TAGNAME(nodeElem) == "log") {
+ std::string label = (HAS_ATTR(nodeElem, "label") ? ATTR(nodeElem, "label") : "");
+ std::string expr = (HAS_ATTR(nodeElem, "expr") ? ATTR(nodeElem, "expr") : "");
+ std::string trimmedExpr = boost::trim_copy(expr);
+ bool isStringLiteral = (boost::starts_with(trimmedExpr, "\"") || boost::starts_with(trimmedExpr, "'"));
+
+ std::string formatString;
+ std::string varString;
+ std::string seperator;
- } else if(TAGNAME(node) == "foreach") {
- if (HAS_ATTR(node, "index"))
- stream << padding << ATTR(node, "index") << " = 0;" << std::endl;
- stream << padding << "for (" << ATTR(node, "item") << " in " << ATTR(node, "array") << ") {" << std::endl;
+ if (label.size() > 0) {
+ formatString += label + ": ";
+ }
+
+ if (isStringLiteral) {
+ formatString += expr;
+ } else {
+ formatString += "%d";
+ varString += seperator + expr;
+ }
+
+ if (varString.length() > 0) {
+ stream << padding << "printf(\"" + formatString + "\", " + varString + ");" << std::endl;
+ } else {
+ stream << padding << "printf(\"" + formatString + "\");" << std::endl;
+ }
+
+ } else if(TAGNAME(nodeElem) == "foreach") {
+ stream << padding << "for (" << (HAS_ATTR(nodeElem, "index") ? ATTR(nodeElem, "index") : "_index") << " in " << ATTR(nodeElem, "array") << ") {" << std::endl;
+ if (HAS_ATTR(nodeElem, "item")) {
+ stream << padding << " " << ATTR(nodeElem, "item") << " = " << ATTR(nodeElem, "array") << "[" << (HAS_ATTR(nodeElem, "index") ? ATTR(nodeElem, "index") : "_index") << "];" << std::endl;
+ }
Arabica::DOM::Node<std::string> child = node.getFirstChild();
while(child) {
- writeExecutableContent(stream, Arabica::DOM::Element<std::string>(child), indent + 1);
+ writeExecutableContent(stream, child, indent + 1);
child = child.getNextSibling();
}
- if (HAS_ATTR(node, "index"))
- stream << padding << " " << ATTR(node, "index") << "++;" << std::endl;
+ if (HAS_ATTR(nodeElem, "index"))
+ stream << padding << " " << ATTR(nodeElem, "index") << "++;" << std::endl;
stream << padding << "}" << std::endl;
- } else if(TAGNAME(node) == "if") {
+ } else if(TAGNAME(nodeElem) == "if") {
NodeSet<std::string> condChain;
condChain.push_back(node);
condChain.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "elseif", node));
@@ -360,22 +821,102 @@ void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::D
writeIfBlock(stream, condChain, indent);
- } else if(TAGNAME(node) == "raise") {
- TrieNode* trieNode = _eventTrie.getNodeWithPrefix(ATTR(node, "event"));
- stream << padding << "iQ!e" << trieNode->identifier << ";" << std::endl;
- } else if(TAGNAME(node) == "send") {
- if (!HAS_ATTR(node, "target")) {
+ } else if(TAGNAME(nodeElem) == "assign") {
+ if (HAS_ATTR(nodeElem, "location")) {
+ stream << padding << ATTR(nodeElem, "location") << " = ";
+ }
+ if (HAS_ATTR(nodeElem, "expr")) {
+ stream << _analyzer.replaceLiterals(ATTR(nodeElem, "expr")) << ";" << std::endl;
+ } else {
+ NodeSet<std::string> assignTexts = filterChildType(Node_base::TEXT_NODE, nodeElem, true);
+ if (assignTexts.size() > 0) {
+ stream << _analyzer.replaceLiterals(boost::trim_copy(assignTexts[0].getNodeValue())) << ";" << std::endl;
+ }
+ }
+ } else if(TAGNAME(nodeElem) == "send" || TAGNAME(nodeElem) == "raise") {
+ std::string targetQueue;
+ if (TAGNAME(nodeElem) == "raise") {
+ targetQueue = "iQ!";
+ } else if (!HAS_ATTR(nodeElem, "target")) {
+ targetQueue = "tmpQ!";
+ } else if (ATTR(nodeElem, "target").compare("#_internal") == 0) {
+ targetQueue = "iQ!";
+ }
+ if (targetQueue.length() > 0) {
// this is for our external queue
- TrieNode* trieNode = _eventTrie.getNodeWithPrefix(ATTR(node, "event"));
- stream << padding << "tmpQ!e" << trieNode->identifier << ";" << std::endl;
+ std::string event;
+
+ if (HAS_ATTR(nodeElem, "event")) {
+ event = _analyzer.macroForLiteral(ATTR(nodeElem, "event"));
+ } else if (HAS_ATTR(nodeElem, "eventexpr")) {
+ event = ATTR(nodeElem, "eventexpr");
+ }
+ if (_analyzer.usesComplexEventStruct()) {
+ stream << padding << "{" << std::endl;
+ stream << padding << " _event_t tmpEvent;" << std::endl;
+ stream << padding << " tmpEvent.name = " << event << ";" << std::endl;
+
+ if (HAS_ATTR(nodeElem, "idlocation")) {
+ stream << padding << " /* idlocation */" << std::endl;
+ stream << padding << " _lastSendId = _lastSendId + 1;" << std::endl;
+ stream << padding << " " << ATTR(nodeElem, "idlocation") << " = _lastSendId;" << std::endl;
+ stream << padding << " tmpEvent.sendid = _lastSendId;" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: _lastSendId == 2147483647 -> _lastSendId = 0;" << std::endl;
+ stream << padding << " :: timeout -> skip;" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ } else if (HAS_ATTR(nodeElem, "id")) {
+ stream << padding << " tmpEvent.sendid = " << _analyzer.macroForLiteral(ATTR(nodeElem, "id")) << ";" << std::endl;
+ }
+
+ if (_analyzer.usesEventField("origintype") && targetQueue.compare("iQ!") != 0) {
+ stream << padding << " tmpEvent.origintype = " << _analyzer.macroForLiteral("http://www.w3.org/TR/scxml/#SCXMLEventProcessor") << ";" << std::endl;
+ }
+
+ if (_analyzer.usesEventField("type")) {
+ std::string eventType = (targetQueue.compare("iQ!") == 0 ? _analyzer.macroForLiteral("internal") : _analyzer.macroForLiteral("external"));
+ stream << padding << " tmpEvent.type = " << eventType << ";" << std::endl;
+ }
+
+ NodeSet<std::string> sendParams = filterChildElements(_nsInfo.xmlNSPrefix + "param", nodeElem);
+ NodeSet<std::string> sendContents = filterChildElements(_nsInfo.xmlNSPrefix + "content", nodeElem);
+ std::string sendNameList = ATTR(nodeElem, "namelist");
+ if (sendParams.size() > 0) {
+ for (int i = 0; i < sendParams.size(); i++) {
+ Element<std::string> paramElem = Element<std::string>(sendParams[i]);
+ stream << padding << " tmpEvent.data." << ATTR(paramElem, "name") << " = " << 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 << " tmpEvent.data." << *nameIter << " = " << *nameIter << ";" << std::endl;
+ nameIter++;
+ }
+ }
+
+ if (sendParams.size() == 0 && sendNameList.size() == 0 && sendContents.size() > 0) {
+ Element<std::string> contentElem = Element<std::string>(sendContents[0]);
+ if (contentElem.hasChildNodes() && contentElem.getFirstChild().getNodeType() == Node_base::TEXT_NODE) {
+ stream << padding << " tmpEvent.data = " << spaceNormalize(contentElem.getFirstChild().getNodeValue()) << ";" << std::endl;
+ } else if (HAS_ATTR(contentElem, "expr")) {
+ stream << padding << " tmpEvent.data = " << _analyzer.replaceLiterals(ATTR(contentElem, "expr")) << ";" << std::endl;
+ }
+ }
+ stream << padding << " " << targetQueue << "tmpEvent;" << std::endl;
+ stream << padding << "}" << std::endl;
+ } else {
+ stream << padding << targetQueue << event << ";" << std::endl;
+ }
}
- } else if(TAGNAME(node) == "invoke") {
- _invokers[ATTR(node, "invokeid")].writeStartEventSources(stream, indent);
- } else if(TAGNAME(node) == "uninvoke") {
- stream << padding << ATTR(node, "invokeid") << "EventSourceDone" << "= 1;" << std::endl;
+ } else if(TAGNAME(nodeElem) == "invoke") {
+ _invokers[ATTR(nodeElem, "invokeid")].writeStartEventSources(stream, indent);
+ } else if(TAGNAME(nodeElem) == "uninvoke") {
+ stream << padding << ATTR(nodeElem, "invokeid") << "EventSourceDone" << "= 1;" << std::endl;
} else {
- std::cerr << "'" << TAGNAME(node) << "'" << std::endl << node << std::endl;
+ std::cerr << "'" << TAGNAME(nodeElem) << "'" << std::endl << nodeElem << std::endl;
assert(false);
}
@@ -492,31 +1033,34 @@ void FSMToPromela::writeIfBlock(std::ostream& stream, const Arabica::XPath::Node
stream << padding << "if" << std::endl;
// we need to nest the elseifs to resolve promela if semantics
- stream << padding << ":: (" << ATTR(ifNode, "cond") << ") -> {" << std::endl;
+ stream << padding << ":: (" << _analyzer.replaceLiterals(ATTR(ifNode, "cond")) << ") -> {" << std::endl;
- Arabica::DOM::Element<std::string> child;
+ Arabica::DOM::Node<std::string> child;
if (TAGNAME(ifNode) == "if") {
- child = Arabica::DOM::Element<std::string>(ifNode.getFirstChild());
+ child = ifNode.getFirstChild();
} else {
- child = Arabica::DOM::Element<std::string>(ifNode.getNextSibling());
+ child = ifNode.getNextSibling();
}
while(child) {
if (child.getNodeType() == Node_base::ELEMENT_NODE) {
- if (TAGNAME(child) == "elseif" || TAGNAME(child) == "else")
+ Arabica::DOM::Element<std::string> childElem = Arabica::DOM::Element<std::string>(child);
+ if (TAGNAME(childElem) == "elseif" || TAGNAME_CAST(childElem) == "else")
break;
+ writeExecutableContent(stream, childElem, indent + 1);
}
- writeExecutableContent(stream, child, indent + 1);
- child = Arabica::DOM::Element<std::string>(child.getNextSibling());
+ child = child.getNextSibling();
}
stream << padding << "}" << std::endl;
stream << padding << ":: else -> ";
if (nextIsElse) {
- child = Arabica::DOM::Element<std::string>(condChain[1].getNextSibling());
+ child = condChain[1].getNextSibling();
stream << "{" << std::endl;
while(child) {
- writeExecutableContent(stream, child, indent + 1);
- child = Arabica::DOM::Element<std::string>(child.getNextSibling());
+ if (child.getNodeType() == Node_base::ELEMENT_NODE) {
+ writeExecutableContent(stream, child, indent + 1);
+ }
+ child = child.getNextSibling();
}
stream << padding << "}" << std::endl;
@@ -569,30 +1113,115 @@ std::string FSMToPromela::beautifyIndentation(const std::string& code, int inden
return beautifiedSS.str();
}
+void FSMToPromela::writeStrings(std::ostream& stream) {
+ stream << "/* string literals */" << std::endl;
+ std::set<std::string> literals = _analyzer.getLiterals();
+ std::map<std::string, int> events = _analyzer.getEvents();
+ std::map<std::string, int> origStates = _analyzer.getOrigStates();
+
+ for (std::set<std::string>::const_iterator litIter = literals.begin(); litIter != literals.end(); litIter++) {
+ if (events.find(*litIter) == events.end() && (origStates.find(*litIter) == origStates.end() || !_analyzer.usesInPredicate()))
+ stream << "#define " << _analyzer.macroForLiteral(*litIter) << " " << _analyzer.indexForLiteral(*litIter) << " /* " << *litIter << " */" << std::endl;
+ }
+}
+
void FSMToPromela::writeDeclarations(std::ostream& stream) {
// get all data elements
NodeSet<std::string> datas = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "data", _scxml).asNodeSet();
- NodeSet<std::string> dataText = filterChildType(Node_base::TEXT_NODE, datas, true);
+// NodeSet<std::string> dataText = filterChildType(Node_base::TEXT_NODE, datas, true);
// write their text content
- stream << "// datamodel variables" << std::endl;
- for (int i = 0; i < dataText.size(); i++) {
- Node<std::string> data = dataText[i];
- stream << beautifyIndentation(data.getNodeValue()) << std::endl;
+ stream << "/* datamodel variables */" << std::endl;
+ std::set<std::string> processedIdentifiers;
+ for (int i = 0; i < datas.size(); i++) {
+
+ Node<std::string> data = datas[i];
+ if (isInEmbeddedDocument(data))
+ continue;
+
+ std::string identifier = (HAS_ATTR_CAST(data, "id") ? ATTR_CAST(data, "id") : "");
+ std::string expression = (HAS_ATTR_CAST(data, "expr") ? ATTR_CAST(data, "expr") : "");
+ std::string type = boost::trim_copy(HAS_ATTR_CAST(data, "type") ? ATTR_CAST(data, "type") : "");
+
+ if (processedIdentifiers.find(identifier) != processedIdentifiers.end())
+ continue;
+ processedIdentifiers.insert(identifier);
+
+ if (boost::starts_with(type, "string")) {
+ type = "int" + type.substr(6, type.length() - 6);
+ }
+ std::string arrSize;
+
+ NodeSet<std::string> dataText = filterChildType(Node_base::TEXT_NODE, data, true);
+ std::string value;
+ if (dataText.size() > 0) {
+ value = dataText[0].getNodeValue();
+ boost::trim(value);
+ }
+
+ if (identifier.length() > 0) {
+
+ size_t bracketPos = type.find("[");
+ if (bracketPos != std::string::npos) {
+ arrSize = type.substr(bracketPos, type.length() - bracketPos);
+ type = type.substr(0, bracketPos);
+ }
+ std::string decl = type + " " + identifier + arrSize;
+
+ if (arrSize.length() > 0) {
+ stream << decl << ";" << std::endl;
+ _varInitializers.push_back(value);
+ } else {
+ stream << decl;
+ if (expression.length() > 0) {
+ // id and expr given
+ stream << " = " << _analyzer.replaceLiterals(boost::trim_copy(expression)) << ";" << std::endl;
+ } else if (value.length() > 0) {
+ // id and text content given
+ stream << " = " << _analyzer.replaceLiterals(value) << ";" << std::endl;
+ } else {
+ // only id given
+ stream << ";" << std::endl;
+ }
+ }
+ } else if (value.length() > 0) {
+ // no id but text content given
+ stream << beautifyIndentation(value) << std::endl;
+ }
}
stream << std::endl;
- stream << "// global variables" << std::endl;
- stream << "int e; /* current event */" << std::endl;
- stream << "int s; /* current state */" << std::endl;
- stream << "chan iQ = [100] of {int} /* internal queue */" << std::endl;
- stream << "chan eQ = [100] of {int} /* external queue */" << std::endl;
- stream << "chan tmpQ = [100] of {int} /* temporary queue for external events in transitions */" << std::endl;
- stream << "int tmpQItem;" << std::endl;
+ stream << "/* global variables */" << std::endl;
+
+ if (_analyzer.usesComplexEventStruct()) {
+ // event is defined with the typedefs
+ stream << "unsigned s : " << BIT_WIDTH(_globalStates.size() + 1) << "; /* current state */" << std::endl;
+ stream << "chan iQ = [10] of {_event_t} /* internal queue */" << std::endl;
+ stream << "chan eQ = [10] of {_event_t} /* external queue */" << std::endl;
+ stream << "chan tmpQ = [10] of {_event_t} /* temporary queue for external events in transitions */" << std::endl;
+ stream << "_event_t tmpQItem;" << std::endl;
+ } else {
+ stream << "unsigned _event : " << BIT_WIDTH(_analyzer.getEvents().size() + 1) << "; /* current event */" << std::endl;
+ stream << "unsigned s : " << BIT_WIDTH(_globalStates.size() + 1) << "; /* current state */" << std::endl;
+ stream << "chan iQ = [10] of {int} /* internal queue */" << std::endl;
+ stream << "chan eQ = [10] of {int} /* external queue */" << std::endl;
+ stream << "chan tmpQ = [10] of {int} /* temporary queue for external events in transitions */" << std::endl;
+ stream << "unsigned tmpQItem : " << BIT_WIDTH(_analyzer.getEvents().size() + 1) << ";" << std::endl;
+ }
+ stream << "bool eventLess = true; /* whether to process event-less only n this step */" << std::endl;
+ stream << "hidden int _index; /* helper for indexless foreach loops */" << std::endl;
+
+ if (_analyzer.usesEventField("sendid")) {
+ stream << "hidden int _lastSendId = 0; /* sequential counter for send ids */";
+ }
+
+// if (_analyzer.usesPlatformVars()) {
+// stream << "_x_t _x;" << std::endl;
+// }
stream << std::endl;
- stream << "// event sources" << std::endl;
+ stream << "/* event sources */" << std::endl;
if (_globalEventSource) {
_globalEventSource.writeDeclarations(stream);
@@ -618,10 +1247,8 @@ void FSMToPromela::writeEventSources(std::ostream& stream) {
invIter->second.writeEventSource(stream);
invIter++;
}
-
}
-
void FSMToPromela::writeFSM(std::ostream& stream) {
NodeSet<std::string> transitions;
@@ -629,37 +1256,38 @@ void FSMToPromela::writeFSM(std::ostream& stream) {
// write initial transition
transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _startState);
assert(transitions.size() == 1);
- stream << " // transition's executable content" << std::endl;
- writeExecutableContent(stream, Arabica::DOM::Element<std::string>(transitions[0]), 1);
+ stream << " /* transition's executable content */" << std::endl;
+ writeExecutableContent(stream, transitions[0], 1);
for (int i = 0; i < _globalStates.size(); i++) {
if (_globalStates[i] == _startState)
continue;
NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _globalStates[i]);
for (int j = 0; j < transitions.size(); j++) {
- writeExecutableContent(stream, Arabica::DOM::Element<std::string>(transitions[j]), 1);
+ writeExecutableContent(stream, transitions[j], 1);
}
}
stream << std::endl;
stream << "nextStep:" << std::endl;
- stream << " // push send events to external queue" << std::endl;
+ stream << " /* push send events to external queue */" << std::endl;
stream << " if" << std::endl;
- stream << " :: len(tmpQ) != 0 -> { tmpQ?e; eQ!e }" << std::endl;
+ stream << " :: len(tmpQ) != 0 -> { tmpQ?_event; eQ!_event }" << std::endl;
stream << " :: else -> skip;" << std::endl;
stream << " fi;" << std::endl << std::endl;
stream << " /* pop an event */" << std::endl;
stream << " if" << std::endl;
- stream << " :: len(iQ) != 0 -> iQ ? e /* from internal queue */" << std::endl;
- stream << " :: else -> eQ ? e /* from external queue */" << std::endl;
- stream << " fi;" << std::endl;
+ stream << " :: len(iQ) != 0 -> iQ ? _event /* from internal queue */" << std::endl;
+ stream << " :: else -> eQ ? _event /* from external queue */" << std::endl;
+ stream << " fi;" << std::endl << std::endl;
stream << " /* event dispatching per state */" << std::endl;
+ stream << "nextTransition:" << std::endl;
stream << " if" << std::endl;
writeEventDispatching(stream);
- stream << " :: else -> goto nextStep;" << std::endl;
+ stream << " :: else -> assert(false); /* this is an error as we dispatched all valid states */" << std::endl;
stream << " fi;" << std::endl;
stream << "terminate: skip;" << std::endl;
@@ -681,50 +1309,105 @@ void FSMToPromela::writeEventDispatching(std::ostream& stream) {
if (_globalStates[i] == _startState)
continue;
- stream << " :: (s == s" << i << ") -> {" << std::endl;
+ int number = i;
+ int digits = 0;
+ do {
+ number /= 10;
+ digits++;
+ } while (number != 0);
+ stream << " :: (s == s" << i << ") -> {";
+
+ INDENT_MIN(stream, 18 + digits, MIN_COMMENT_PADDING);
+
+ stream << " /* from state " << ATTR_CAST(_globalStates[i], "id") << " */" << std::endl;
NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _globalStates[i]);
writeDispatchingBlock(stream, transitions, 2);
- stream << " goto nextStep;" << std::endl;
+// stream << " goto nextStep;";
stream << " }" << std::endl;
}
}
void FSMToPromela::writeDispatchingBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& transChain, int indent) {
- if (transChain.size() == 0)
- return;
-
std::string padding;
for (int i = 0; i < indent; i++) {
padding += " ";
}
- stream << padding << "if" << std::endl;
- stream << padding << ":: ((0";
+ if (transChain.size() == 0) {
+ stream << padding << "eventLess = false;" << std::endl;
+ stream << padding << "goto nextStep;";
+ INDENT_MIN(stream, padding.size() + 13, MIN_COMMENT_PADDING);
+ stream << "/* no transition applicable */" << std::endl;
+ return;
+ }
+
Element<std::string> currTrans = Element<std::string>(transChain[0]);
- std::string eventDesc = ATTR(currTrans, "event");
- if (boost::ends_with(eventDesc, "*"))
- eventDesc = eventDesc.substr(0, eventDesc.size() - 1);
- if (boost::ends_with(eventDesc, "."))
- eventDesc = eventDesc.substr(0, eventDesc.size() - 1);
-
- if (eventDesc.size() == 0) {
- stream << " || 1";
+ std::stringstream tmpSS;
+
+ tmpSS << padding << "if" << std::endl;
+ size_t lineStart = tmpSS.tellp();
+
+ if (HAS_ATTR(currTrans, "cond")) {
+ tmpSS << padding << ":: ((";
} else {
- std::list<TrieNode*> trieNodes = _eventTrie.getWordsWithPrefix(eventDesc);
+ tmpSS << padding << ":: (";
+ }
- std::list<TrieNode*>::iterator trieIter = trieNodes.begin();
- while(trieIter != trieNodes.end()) {
- stream << " || e == e" << (*trieIter)->identifier;
- trieIter++;
+ if (!HAS_ATTR(currTrans, "event")) {
+ tmpSS << "eventLess";
+ } else {
+ std::string eventDescs = ATTR(currTrans, "event");
+
+ std::list<std::string> eventNames = tokenizeIdRefs(eventDescs);
+ std::set<std::string> eventPrefixes;
+ std::list<std::string>::iterator eventNameIter = eventNames.begin();
+ while(eventNameIter != eventNames.end()) {
+ std::string eventDesc = *eventNameIter;
+ if (boost::ends_with(eventDesc, "*"))
+ eventDesc = eventDesc.substr(0, eventDesc.size() - 1);
+ if (boost::ends_with(eventDesc, "."))
+ eventDesc = eventDesc.substr(0, eventDesc.size() - 1);
+ if (eventDesc.length() > 0) {
+ std::set<std::string> tmp = _analyzer.getEventsWithPrefix(*eventNameIter);
+ eventPrefixes.insert(tmp.begin(), tmp.end());
+ }
+ eventNameIter++;
}
+
+ if (eventPrefixes.size() > 0) {
+ tmpSS << "!eventLess && ";
+ } else {
+ tmpSS << "!eventLess";
+ }
+
+ std::string seperator;
+ std::set<std::string>::iterator eventIter = eventPrefixes.begin();
+ while(eventIter != eventPrefixes.end()) {
+ if (_analyzer.usesComplexEventStruct()) {
+ tmpSS << seperator << "_event.name == " << _analyzer.macroForLiteral(*eventIter);
+ } else {
+ tmpSS << seperator << "_event == " << _analyzer.macroForLiteral(*eventIter);
+ }
+ seperator = " || ";
+ eventIter++;
+ }
+ }
+
+ tmpSS << ")";
+ if (HAS_ATTR(currTrans, "cond")) {
+ tmpSS << (HAS_ATTR(currTrans, "cond") ? " && " + _analyzer.replaceLiterals(ATTR(currTrans, "cond")) + ")": "");
}
+ tmpSS << " -> goto t" << _transitions[currTrans] << ";";
+ size_t lineEnd = tmpSS.tellp();
+ size_t lineLength = lineEnd - lineStart;
- stream << ") && ";
- stream << (HAS_ATTR(currTrans, "cond") ? ATTR(currTrans, "cond") : "1");
- stream << ") -> goto t" << _transitions[currTrans] << ";" << std::endl;
- ;
+ for (int i = lineLength; i < MIN_COMMENT_PADDING; i++)
+ tmpSS << " ";
+
+ tmpSS << " /* transition to " << ATTR_CAST(getUltimateTarget(currTrans), "id") << " */" << std::endl;
+ stream << tmpSS.str();
stream << padding << ":: else {" << std::endl;
@@ -734,7 +1417,6 @@ void FSMToPromela::writeDispatchingBlock(std::ostream& stream, const Arabica::XP
}
writeDispatchingBlock(stream, cdrTransChain, indent + 1);
- stream << padding << " goto nextStep;" << std::endl;
stream << padding << "}" << std::endl;
stream << padding << "fi;" << std::endl;
}
@@ -743,6 +1425,14 @@ void FSMToPromela::writeDispatchingBlock(std::ostream& stream, const Arabica::XP
void FSMToPromela::writeMain(std::ostream& stream) {
stream << std::endl;
stream << "init {" << std::endl;
+ if (_varInitializers.size() > 0) {
+ std::list<std::string>::iterator initIter = _varInitializers.begin();
+ while(initIter != _varInitializers.end()) {
+ stream << beautifyIndentation(*initIter);
+ initIter++;
+ }
+ stream << std::endl;
+ }
if (_globalEventSource)
_globalEventSource.writeStartEventSources(stream, 1);
stream << " run step();" << std::endl;
@@ -750,11 +1440,15 @@ void FSMToPromela::writeMain(std::ostream& stream) {
}
+
void FSMToPromela::initNodes() {
// get all states
NodeSet<std::string> states = filterChildElements(_nsInfo.xmlNSPrefix + "state", _scxml);
for (int i = 0; i < states.size(); i++) {
+ if (InterpreterImpl::isInEmbeddedDocument(states[i]))
+ continue;
_states[ATTR_CAST(states[i], "id")] = Element<std::string>(states[i]);
+ _analyzer.addState(ATTR_CAST(states[i], "id"));
if (HAS_ATTR_CAST(states[i], "transient") && DOMUtils::attributeIsTrue(ATTR_CAST(states[i], "transient")))
continue;
_globalStates.push_back(states[i]);
@@ -778,11 +1472,33 @@ void FSMToPromela::initNodes() {
eventName = eventName.substr(0, eventName.size() - 1);
if (boost::ends_with(eventName, "."))
eventName = eventName.substr(0, eventName.size() - 1);
- _eventTrie.addWord(eventName);
+ if (eventName.size() > 0)
+ _analyzer.addEvent(eventName);
}
}
}
+ // do we need sendid / invokeid?
+ {
+ NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true);
+ NodeSet<std::string> sends = filterChildElements(_nsInfo.xmlNSPrefix + "send", _scxml, true);
+
+ for (int i = 0; i < invokes.size(); i++) {
+ if (HAS_ATTR_CAST(invokes[i], "idlocation")) {
+ }
+ }
+
+ for (int i = 0; i < sends.size(); i++) {
+ if (HAS_ATTR_CAST(sends[i], "idlocation")) {
+ _analyzer.addCode("_event.sendid");
+ }
+ if (HAS_ATTR_CAST(sends[i], "id")) {
+ _analyzer.addLiteral(ATTR_CAST(sends[i], "id"));
+ _analyzer.addCode("_event.sendid");
+ }
+ }
+
+ }
// external event names from comments
NodeSet<std::string> promelaEventSourceComments;
NodeSet<std::string> invokers = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "invoke", _scxml).asNodeSet();
@@ -795,7 +1511,7 @@ void FSMToPromela::initNodes() {
if (TAGNAME_CAST(promelaEventSourceComments[i].getParentNode()) == "scxml") {
promES.type = PromelaEventSource::PROMELA_EVENT_SOURCE_GLOBAL;
- promES.trie = &_eventTrie;
+ promES.analyzer = &_analyzer;
promES.name = "global";
_globalEventSource = promES;
} else if (TAGNAME_CAST(promelaEventSourceComments[i].getParentNode()) == "invoke") {
@@ -805,7 +1521,7 @@ void FSMToPromela::initNodes() {
}
std::string invokeId = ATTR_CAST(promelaEventSourceComments[i].getParentNode(), "invokeid");
promES.type = PromelaEventSource::PROMELA_EVENT_SOURCE_INVOKER;
- promES.trie = &_eventTrie;
+ promES.analyzer = &_analyzer;
promES.name = invokeId;
_invokers[invokeId] = promES;
}
@@ -817,6 +1533,101 @@ void FSMToPromela::initNodes() {
for (int i = 0; i < transitions.size(); i++) {
_transitions[Element<std::string>(transitions[i])] = index++;
}
+
+ // add platform variables as string literals
+ _analyzer.addLiteral("_sessionid");
+ _analyzer.addLiteral("_name");
+
+ if (HAS_ATTR(_scxml, "name")) {
+ _analyzer.addLiteral(ATTR(_scxml, "name"), _analyzer.indexForLiteral("_sessionid"));
+ }
+
+ NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", _scxml, true);
+ for (int i = 0; i < contents.size(); i++) {
+ Element<std::string> contentElem = Element<std::string>(contents[i]);
+ if (contentElem.hasChildNodes() && contentElem.getFirstChild().getNodeType() == Node_base::TEXT_NODE) {
+ _analyzer.addLiteral(spaceNormalize(contentElem.getFirstChild().getNodeValue()));
+ }
+ }
+
+
+ // extract and analyze source code
+ std::set<std::string> allCode;
+ std::set<std::string> allStrings;
+ {
+ NodeSet<std::string> withCond;
+ withCond.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true));
+ withCond.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "if", _scxml, true));
+ withCond.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "elseif", _scxml, true));
+ for (int i = 0; i < withCond.size(); i++) {
+ Element<std::string> elem = Element<std::string>(withCond[i]);
+ if (HAS_ATTR(elem, "cond")) {
+ std::string code = ATTR(elem, "cond");
+ code = sanitizeCode(code);
+ elem.setAttribute("cond", code);
+ allCode.insert(code);
+ }
+ }
+ }
+ {
+ NodeSet<std::string> withExpr;
+ withExpr.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "log", _scxml, true));
+ withExpr.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "data", _scxml, true));
+ withExpr.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "assign", _scxml, true));
+ withExpr.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "content", _scxml, true));
+ withExpr.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "param", _scxml, true));
+ for (int i = 0; i < withExpr.size(); i++) {
+ Element<std::string> elem = Element<std::string>(withExpr[i]);
+ if (HAS_ATTR(elem, "expr")) {
+ std::string code = ATTR(elem, "expr");
+ code = sanitizeCode(code);
+ elem.setAttribute("expr", code);
+ allCode.insert(code);
+ }
+ }
+ }
+ {
+ NodeSet<std::string> withLocation;
+ withLocation.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "assign", _scxml, true));
+ for (int i = 0; i < withLocation.size(); i++) {
+ Element<std::string> elem = Element<std::string>(withLocation[i]);
+ if (HAS_ATTR(elem, "location")) {
+ std::string code = ATTR(elem, "location");
+ code = sanitizeCode(code);
+ elem.setAttribute("location", code);
+ allCode.insert(code);
+ }
+ }
+ }
+ {
+ NodeSet<std::string> withText;
+ withText.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "script", _scxml, true));
+ withText.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "data", _scxml, true));
+ for (int i = 0; i < withText.size(); i++) {
+ NodeSet<std::string> texts = filterChildType(Node_base::TEXT_NODE, withText[i], true);
+ for (int j = 0; j < texts.size(); j++) {
+ if (texts[j].getNodeValue().size() > 0) {
+ Text<std::string> elem = Text<std::string>(texts[j]);
+ std::string code = elem.getNodeValue();
+ code = sanitizeCode(code);
+ elem.setNodeValue(code);
+ allCode.insert(code);
+ }
+ }
+ }
+ }
+ for (std::set<std::string>::const_iterator codeIter = allCode.begin(); codeIter != allCode.end(); codeIter++) {
+ _analyzer.addCode(*codeIter);
+ }
+
+}
+
+std::string FSMToPromela::sanitizeCode(const std::string& code) {
+ std::string replaced = code;
+ boost::replace_all(replaced, "\"", "'");
+ boost::replace_all(replaced, "_sessionid", "_SESSIONID");
+ boost::replace_all(replaced, "_name", "_NAME");
+ return replaced;
}
void PromelaInline::dump() {
@@ -849,12 +1660,22 @@ void FSMToPromela::writeProgram(std::ostream& stream) {
return;
}
+// std::cerr << _scxml << std::endl;
+
initNodes();
writeEvents(stream);
stream << std::endl;
writeStates(stream);
stream << std::endl;
+ if (_analyzer.usesInPredicate()) {
+ writeStateMap(stream);
+ stream << std::endl;
+ }
+ writeTypeDefs(stream);
+ stream << std::endl;
+ writeStrings(stream);
+ stream << std::endl;
writeDeclarations(stream);
stream << std::endl;
writeEventSources(stream);
@@ -864,6 +1685,28 @@ void FSMToPromela::writeProgram(std::ostream& stream) {
writeMain(stream);
stream << std::endl;
+ // write ltl expression for success
+ std::stringstream acceptingStates;
+ std::string seperator;
+ for (int i = 0; i < _globalStates.size(); i++) {
+ FlatStateIdentifier flatId(ATTR_CAST(_globalStates[i], "id"));
+ if (std::find(flatId.getActive().begin(), flatId.getActive().end(), "pass") != flatId.getActive().end()) {
+ acceptingStates << seperator << "s == s" << i;
+ seperator = " || ";
+ }
+ }
+ if (acceptingStates.str().size() > 0) {
+ stream << "ltl { eventually (" << acceptingStates.str() << ") }" << std::endl;
+ }
+
+// if (_states.find("active:{pass}") != _states.end()) {
+// for (int i = 0; i < _globalStates.size(); i++) {
+// if (_states["active:{pass}"] != _globalStates[i])
+// continue;
+// stream << "ltl { eventually (s == s" << i << ") }";
+// break;
+// }
+// }
}
} \ No newline at end of file
diff --git a/src/uscxml/transform/FSMToPromela.h b/src/uscxml/transform/FSMToPromela.h
index 62381cd..3a9e263 100644
--- a/src/uscxml/transform/FSMToPromela.h
+++ b/src/uscxml/transform/FSMToPromela.h
@@ -84,6 +84,108 @@ public:
int codes;
};
+class USCXML_API PromelaCodeAnalyzer {
+public:
+ class PromelaTypedef {
+ public:
+ PromelaTypedef() : arraySize(0) {}
+ std::string name;
+ std::string type;
+ size_t arraySize;
+ std::map<std::string, PromelaTypedef> types;
+
+ bool operator==(const PromelaTypedef& other) const {
+ return name == other.name;
+ }
+
+ };
+
+ PromelaCodeAnalyzer() : _eventTrie("."), _lastStrIndex(1), _lastStateIndex(0), _lastEventIndex(1), _usesInPredicate(false), _usesPlatformVars(false) {
+ }
+
+ void addCode(const std::string& code);
+ void addEvent(const std::string& eventName);
+ void addState(const std::string& stateName);
+ void addLiteral(const std::string& stateName, int forceIndex = -1);
+
+ bool usesComplexEventStruct() {
+ return _typeDefs.types.find("_event") != _typeDefs.types.end();
+ }
+ bool usesEventField(const std::string& fieldName) {
+ if (usesComplexEventStruct() && _typeDefs.types["_event"].types.find(fieldName) != _typeDefs.types["_event"].types.end())
+ return true;
+ return false;
+ }
+
+ bool usesInPredicate() {
+ return _usesInPredicate;
+ }
+ bool usesPlatformVars() {
+ return _usesPlatformVars;
+ }
+
+ std::string macroForLiteral(const std::string& literal);
+ int indexForLiteral(const std::string& literal);
+ int arrayIndexForOrigState(const std::string& stateName);
+
+ std::set<std::string> getLiterals() {
+ return _strLiterals;
+ }
+ std::set<std::string> getEventsWithPrefix(const std::string& prefix);
+ std::map<std::string, int>& getEvents() {
+ return _events;
+ }
+
+ std::map<std::string, int>& getStates() {
+ return _states;
+ }
+
+ std::map<std::string, int>& getOrigStates() {
+ return _origStateIndex;
+ }
+
+ std::list<std::string>& getOrigStates(const std::string& state) {
+ if (_origStateMap.find(state) == _origStateMap.end())
+ throw std::runtime_error("No original states known for " + state);
+ return _origStateMap[state];
+ }
+
+ Trie& getTrie() {
+ return _eventTrie;
+ }
+
+ std::string replaceLiterals(const std::string code);
+
+ PromelaTypedef getTypes() {
+ return _typeDefs;
+ }
+
+protected:
+ std::string createMacroName(const std::string& literal);
+ int enumerateLiteral(const std::string& literal, int forceIndex = -1);
+
+ std::set<std::string> _strLiterals; // all string literals
+ std::map<std::string, std::string> _strMacroNames; // macronames for string literals
+ std::map<std::string, int> _strIndex; // integer enumeration for string
+ std::map<std::string, int> _origStateIndex; // state enumeration for original states
+
+ std::map<std::string, int> _states;
+ std::map<std::string, std::list<std::string> > _origStateMap; // states from the original state chart
+ std::map<std::string, int> _events;
+
+ PromelaTypedef _typeDefs;
+
+ Trie _eventTrie;
+
+private:
+ std::set<std::string> _macroNameSet; // helper set for uniqueness of macros
+ int _lastStrIndex;
+ int _lastStateIndex;
+ int _lastEventIndex;
+ bool _usesInPredicate;
+ bool _usesPlatformVars;
+};
+
class USCXML_API PromelaEventSource {
public:
@@ -109,7 +211,7 @@ public:
PromelaInlines eventSources;
Arabica::DOM::Node<std::string> container;
PromelaEventSourceType type;
- Trie* trie;
+ PromelaCodeAnalyzer* analyzer;
};
class USCXML_API FSMToPromela : public InterpreterDraft6 {
@@ -127,9 +229,12 @@ protected:
void writeEvents(std::ostream& stream);
void writeStates(std::ostream& stream);
+ void writeStateMap(std::ostream& stream);
+ void writeTypeDefs(std::ostream& stream);
+ void writeStrings(std::ostream& stream);
void writeDeclarations(std::ostream& stream);
void writeEventSources(std::ostream& stream);
- void writeExecutableContent(std::ostream& stream, const Arabica::DOM::Element<std::string>& node, int indent = 0);
+ void writeExecutableContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent = 0);
void writeInlineComment(std::ostream& stream, const Arabica::DOM::Node<std::string>& node);
void writeFSM(std::ostream& stream);
void writeEventDispatching(std::ostream& stream);
@@ -138,19 +243,26 @@ protected:
void writeIfBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& condChain, int indent = 0);
void writeDispatchingBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& transChain, int indent = 0);
- Arabica::XPath::NodeSet<std::string> getTransientContent(const Arabica::DOM::Element<std::string>& state);
+ Arabica::XPath::NodeSet<std::string> getTransientContent(const Arabica::DOM::Element<std::string>& state, const std::string& source = "");
Arabica::DOM::Node<std::string> getUltimateTarget(const Arabica::DOM::Element<std::string>& transition);
static PromelaInlines getInlinePromela(const std::string&);
static PromelaInlines getInlinePromela(const Arabica::XPath::NodeSet<std::string>& elements, bool recurse = false);
static PromelaInlines getInlinePromela(const Arabica::DOM::Node<std::string>& elements);
- Trie _eventTrie;
+// std::string replaceStringsInExpression(const std::string& expr);
+
+ std::string sanitizeCode(const std::string& code);
+
Arabica::XPath::NodeSet<std::string> _globalStates;
Arabica::DOM::Node<std::string> _startState;
std::map<std::string, Arabica::DOM::Element<std::string> > _states;
std::map<Arabica::DOM::Element<std::string>, int> _transitions;
+ std::list<std::string> _varInitializers;
+
+ PromelaCodeAnalyzer _analyzer;
+
std::map<std::string, PromelaEventSource> _invokers;
PromelaEventSource _globalEventSource;
};
diff --git a/src/uscxml/transform/FlatStateIdentifier.h b/src/uscxml/transform/FlatStateIdentifier.h
index 0957e34..5cbd5f2 100644
--- a/src/uscxml/transform/FlatStateIdentifier.h
+++ b/src/uscxml/transform/FlatStateIdentifier.h
@@ -37,9 +37,14 @@ namespace uscxml {
class USCXML_API FlatStateIdentifier {
public:
+
+ operator bool() const {
+ return stateId.length() > 0;
+ }
+
FlatStateIdentifier(const Arabica::XPath::NodeSet<std::string>& activeStates,
- const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates,
- const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates) {
+ const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates,
+ const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates) {
for (int i = 0; i < activeStates.size(); i++) {
active.push_back(ATTR_CAST(activeStates[i], "id"));
}
@@ -65,17 +70,24 @@ public:
histories[histIter->first].push_back(ATTR_CAST(histIter->second[i], "id"));
}
}
-
+
initStateId();
}
-
-
+
+
FlatStateIdentifier(const std::list<std::string>& active,
- const std::list<std::string>& visited,
- const std::map<std::string, std::list<std::string> >& histories) : active(active), visited(visited), histories(histories) {
+ const std::list<std::string>& visited,
+ const std::map<std::string, std::list<std::string> >& histories) : active(active), visited(visited), histories(histories) {
initStateId();
}
-
+
+ static std::string toStateId(const std::list<std::string> active,
+ const std::list<std::string> visited = std::list<std::string>(),
+ const std::map<std::string, std::list<std::string> > histories = std::map<std::string, std::list<std::string> >()) {
+ FlatStateIdentifier tmp(active, visited, histories);
+ return tmp.getStateId();
+ }
+
FlatStateIdentifier(const std::string& identifier) : stateId(identifier) {
std::string parsedName;
// parse unique state identifier
@@ -87,6 +99,10 @@ public:
std::stringstream stateSS(section.substr(8, section.size() - 9));
std::string state;
while(std::getline(stateSS, state, ',')) {
+ size_t closingBracketPos = state.find("}");
+ if (closingBracketPos != std::string::npos) {
+ state = state.substr(0, closingBracketPos);
+ }
if (state.length() > 0) {
active.push_back(state);
}
@@ -96,6 +112,10 @@ public:
std::stringstream stateSS(section.substr(9, section.size() - 10));
std::string state;
while(std::getline(stateSS, state, ',')) {
+ size_t closingBracketPos = state.find("}");
+ if (closingBracketPos != std::string::npos) {
+ state = state.substr(0, closingBracketPos);
+ }
if (state.length() > 0) {
visited.push_back(state);
}
@@ -107,31 +127,36 @@ public:
std::string state;
size_t start = 0;
size_t history = 0;
-
+
while((history = histEntries.find(":", start)) != std::string::npos) {
std::string histName = histEntries.substr(start, history - start);
history++;
-
+
size_t end = histEntries.find("}", start);
if (end == std::string::npos)
continue;
-
+
std::stringstream stateSS(histEntries.substr(history + 1, end - history - 1));
std::string state;
while(std::getline(stateSS, state, ',')) {
+ size_t closingBracketPos = state.find("}");
+ if (closingBracketPos != std::string::npos) {
+ state = state.substr(0, closingBracketPos);
+ }
histories[histName].push_back(state);
}
-
+
start = end + 2;
}
}
}
+ initStateId();
}
const std::string& getStateId() {
return stateId;
}
-
+
const std::list<std::string>& getActive() {
return active;
}
@@ -157,17 +182,17 @@ protected:
std::list<std::string> active;
std::list<std::string> visited;
std::map<std::string, std::list<std::string> > histories;
-
+
std::string flatActive;
std::string flatVisited;
std::string flatHistories;
-
+
std::string stateId;
void initStateId() {
std::stringstream stateIdSS;
std::string seperator;
-
+
std::stringstream flatActiveSS;
flatActiveSS << "active:{";
for (std::list<std::string>::const_iterator actIter = active.begin(); actIter != active.end(); actIter++) {
@@ -177,7 +202,7 @@ protected:
flatActiveSS << "}";
flatActive = flatActiveSS.str();
stateIdSS << flatActive;
-
+
if (visited.size() > 0) {
std::stringstream flatVisitedSS;
seperator = "";
@@ -190,7 +215,7 @@ protected:
flatVisited = flatVisitedSS.str();
stateIdSS << ";" << flatVisited;
}
-
+
if (histories.size() > 0) {
std::stringstream flatHistorySS;
seperator = "";
@@ -209,10 +234,10 @@ protected:
flatHistories = flatHistorySS.str();
stateIdSS << ";" << flatHistories;
}
-
+
stateId = stateIdSS.str();
}
-
+
#if 0
std::string activeId() {
std::stringstream activeSS;
@@ -224,7 +249,7 @@ protected:
}
#endif
-
+
};
}
diff --git a/src/uscxml/util/Trie.cpp b/src/uscxml/util/Trie.cpp
index ebcc3ef..8934c73 100644
--- a/src/uscxml/util/Trie.cpp
+++ b/src/uscxml/util/Trie.cpp
@@ -19,17 +19,18 @@
#include "Trie.h"
#include <iostream>
+#include <boost/algorithm/string.hpp>
namespace uscxml {
Trie::Trie() {
root = new TrieNode();
- lastIdentifier = 0;
+ lastIndex = 0;
}
Trie::Trie(const std::string& seperator) : seperator(seperator) {
root = new TrieNode();
- lastIdentifier = 0;
+ lastIndex = 0;
}
Trie::~Trie() {
@@ -67,6 +68,12 @@ size_t Trie::getNextToken(const std::string& word, size_t offset, std::string& t
return offset + 1;
}
+std::string Trie::escapeWord(const std::string& word) {
+ std::string identifier = word;
+ boost::replace_all(identifier, ".", "_");
+ return identifier;
+}
+
void Trie::addWord(const std::string& word) {
TrieNode* currNode = root;
@@ -86,8 +93,9 @@ void Trie::addWord(const std::string& word) {
break;
}
if (!currNode->hasWord) {
- currNode->identifier = lastIdentifier++;
+ currNode->index = lastIndex++;
currNode->value = word;
+ currNode->identifier = escapeWord(word);
currNode->hasWord = true;
}
}
diff --git a/src/uscxml/util/Trie.h b/src/uscxml/util/Trie.h
index 1f8b201..73d75e7 100644
--- a/src/uscxml/util/Trie.h
+++ b/src/uscxml/util/Trie.h
@@ -32,7 +32,8 @@ struct USCXML_API TrieNode {
virtual ~TrieNode();
bool hasWord;
- int identifier;
+ int index;
+ std::string identifier;
std::string value;
std::map<std::string, TrieNode*> childs;
void dump(int indent = 0);
@@ -45,6 +46,7 @@ struct USCXML_API Trie {
void addWord(const std::string& word);
size_t getNextToken(const std::string& word, size_t offset, std::string& token);
+ std::string escapeWord(const std::string& word);
TrieNode* getNodeWithPrefix(const std::string& prefix);
std::list<TrieNode*> getWordsWithPrefix(const std::string& prefix);
@@ -53,7 +55,7 @@ struct USCXML_API Trie {
TrieNode* root;
std::string seperator;
- int lastIdentifier;
+ int lastIndex;
};
}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 7a0ad3a..035f22e 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -68,6 +68,8 @@ add_test(test-execution ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uscxml-browser ${CMAKE
add_test(test-communication ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uscxml-browser -t5493 ${CMAKE_SOURCE_DIR}/test/uscxml/test-communication.scxml)
add_test(test-done-data ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uscxml-browser ${CMAKE_SOURCE_DIR}/test/uscxml/test-donedata.scxml)
+find_program(SPIN spin)
+find_program(GCC gcc)
if (NOT BUILD_MINIMAL)
add_executable(test-w3c src/test-w3c.cpp)
@@ -117,6 +119,30 @@ if (NOT BUILD_MINIMAL)
# set_tests_properties(${TEST_NAME} PROPERTIES FAIL_REGULAR_EXPRESSION "TEST FAILED")
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 FAIL_REGULAR_EXPRESSION "TEST FAILED")
+ endif()
+
+ if (GCC AND SPIN AND BUILD_DM_PROMELA AND BUILD_TESTS_W3C_PROMELA AND TEST_NAME MATCHES "^promela\\/.*")
+
+ add_test(NAME "spin/${TEST_NAME}"
+ COMMAND ${CMAKE_COMMAND}
+ -DOUTDIR:FILEPATH=${CMAKE_CURRENT_BINARY_DIR}
+ -DTESTFILE:FILEPATH=${W3C_TEST}
+ -DUSCXML_TRANSFORM_BIN:FILEPATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uscxml-transform
+ -DSPIN_BIN:FILEPATH=${SPIN}
+ -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 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]+")
+
+ set_tests_properties(${TEST_NAME} PROPERTIES DEPENDS uscxml-transform)
+ # set_tests_properties(${TEST_NAME} PROPERTIES FAIL_REGULAR_EXPRESSION "TEST FAILED")
+ endif()
+
endif()
endforeach()
endif() \ No newline at end of file
diff --git a/test/ctest/CTestCustom.ctest.in b/test/ctest/CTestCustom.ctest.in
index 6b5fd3c..e26bbf2 100644
--- a/test/ctest/CTestCustom.ctest.in
+++ b/test/ctest/CTestCustom.ctest.in
@@ -17,24 +17,145 @@ set(CTEST_CUSTOM_TESTS_IGNORE
"ecma/test415.scxml" # Manual - PASSED
"fsm/ecma/test178.scxml" # manual test
- "fsm/ecma/test224.scxml" # automatically generated id has the form stateid.platformid
+ # "fsm/ecma/test224.scxml" # automatically generated id has the form stateid.platformid
"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/test324.scxml" # _name can be assigned
- "fsm/ecma/test329.scxml" # system variables can be modified
- "fsm/ecma/test346.scxml" # change the value of a system variable
- "fsm/ecma/test409.scxml" # In predicate
- "fsm/ecma/test411.scxml" # In predicate
"fsm/ecma/test415.scxml" # manual test
- "fsm/ecma/test436.scxml" # In predicate
- "fsm/ecma/test519.scxml" # unspecified basichttp format
- "fsm/ecma/test520.scxml" # unspecified basichttp format
- "fsm/ecma/test531.scxml" # unspecified basichttp format
- "fsm/ecma/test534.scxml" # unspecified basichttp format
- "fsm/ecma/test567.scxml" # unspecified basichttp format
"xpath/test580.scxml" # hangs
+
+ "promela/test178.scxml" # manual test
+ "promela/test190.scxml" # string concatenation
+ "promela/test224.scxml" # string operation startWith
+ "promela/test230.scxml" # manual test
+ "promela/test250.scxml" # manual test
+ "promela/test277.scxml" # no runtime checks for undeclared variables
+ "promela/test280.scxml" # no runtime checks for undeclared variables
+ "promela/test301.scxml" # manual test
+ "promela/test307.scxml" # manual test
+# "promela/test330.scxml" # no "defined" operator in promela
+# "promela/test333.scxml" # no typeof or "defined" operator in promela
+# "promela/test335.scxml" # no typeof or "defined" operator in promela
+# "promela/test337.scxml" # no typeof or "defined" operator in promela
+ "promela/test350.scxml" # string concatenation
+ "promela/test415.scxml" # manual test
+ "promela/test436.scxml" # In(s) -> _x.states[s] prevents completion as NULL dm is hardcoded
+ "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
+
+ # 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/test172.scxml" # targetexpr _internal - can we support?
+ "spin/promela/test224.scxml" # string operation startWith
+ "spin/promela/test224.scxml" # string operation startWith
+ "spin/promela/test277.scxml" # 'return' as a literal
+ "spin/promela/test280.scxml" # late data binding
+ "spin/promela/test286.scxml" # assigment to a non-declared var
+ "spin/promela/test294.scxml" # mixed types for event.data
+ "spin/promela/test301.scxml" # manual test
+ "spin/promela/test302.scxml" # variable not declared
+ "spin/promela/test304.scxml" # variable not declared
+ "spin/promela/test307.scxml" # manual test
+ "spin/promela/test309.scxml" # 'return' as an invalid boolean expression ought to eval to false
+ "spin/promela/test311.scxml" # assigment 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" # several assignment to constants
+ "spin/promela/test331.scxml" # assigment to a non-declared var
+ "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/test415.scxml" # manual test
+ "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
+
+ # fail for semantics
+ "spin/promela/test159.scxml" # error raised causes all subsequent elements to be skipped
+ "spin/promela/test175.scxml" # delay used
+ "spin/promela/test178.scxml" # manual test with two identical params - failed
+ "spin/promela/test185.scxml" # delay used
+ "spin/promela/test191.scxml" # nested SCXML document
+ "spin/promela/test192.scxml" # delay used and nested SCXML document
+ "spin/promela/test194.scxml" # illegal target for send
+ "spin/promela/test199.scxml" # invalid send type
+ "spin/promela/test207.scxml" # delay / cancel
+ "spin/promela/test208.scxml" # delay / cancel
+ "spin/promela/test210.scxml" # sendidexpr works with cancel
+ "spin/promela/test215.scxml" # nested SCXML document
+ "spin/promela/test216.scxml" # assignment from file and nested SCXML document
+ "spin/promela/test220.scxml" # nested SCXML document
+ "spin/promela/test223.scxml" # nested SCXML document
+ "spin/promela/test225.scxml" # nested SCXML document - can't we just copy as nested states with event prefixes?
+ "spin/promela/test226.scxml" # assignment from file and nested SCXML document
+ "spin/promela/test228.scxml" # nested SCXML document and invokeid
+ "spin/promela/test229.scxml" # nested SCXML document with autoforward
+ "spin/promela/test230.scxml" # nested SCXML document with manual test
+ "spin/promela/test232.scxml" # nested SCXML document sends events
+ "spin/promela/test233.scxml" # nested SCXML document with finalize
+ "spin/promela/test234.scxml" # nested SCXML document with finalize
+ "spin/promela/test235.scxml" # nested SCXML document sends done.invoke
+ "spin/promela/test236.scxml" # nested SCXML document sends done.invoke as last event
+ "spin/promela/test239.scxml" # nested SCXML document from content and src
+ "spin/promela/test240.scxml" # nested SCXML document with namelist
+ "spin/promela/test241.scxml" # nested SCXML document with namelist and param
+ "spin/promela/test243.scxml" # nested SCXML document with param
+ "spin/promela/test244.scxml" # nested SCXML document with namelist
+ "spin/promela/test245.scxml" # nested SCXML document with unbound vars
+ "spin/promela/test247.scxml" # nested SCXML document with done.invoke
+ "spin/promela/test253.scxml" # nested SCXML document with bidirectional SCXML ioprocessor
+ "spin/promela/test276.scxml" # nested SCXML document overriding var defaults
+ "spin/promela/test298.scxml" # non-existent data model location
+ "spin/promela/test332.scxml" # sendid is present in error events
+ "spin/promela/test338.scxml" # test that invokeid is set correctly
+ "spin/promela/test343.scxml" # test that illegal <param> produces error.execution
+ "spin/promela/test347.scxml" # nested SCXML document with bidirectional SCXML ioprocessor
+ "spin/promela/test351.scxml" # timeout with delay
+ "spin/promela/test342.scxml" # timeout with delay
+ "spin/promela/test388.scxml" # timeout with delay
+ "spin/promela/test399.scxml" # timeout with delay
+ # "spin/promela/test409.scxml" # entering states order - In
+ # "spin/promela/test411.scxml" # entering states order - In
+ "spin/promela/test422.scxml" # nested SCXML document
+ "spin/promela/test488.scxml" # illegal expr in <param> produces error.execution
+ "spin/promela/test496.scxml" # tests error.communication with illegal target
+ "spin/promela/test500.scxml" # uses _ioprocessors.scxml.location
+ "spin/promela/test510.scxml" # uses _ioprocessors.basichttp.location
+ "spin/promela/test521.scxml" # tests error.communication with illegal target
+ "spin/promela/test522.scxml" # uses _ioprocessors.basichttp.location
+ "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/test552.scxml" # initialize data from file
+ "spin/promela/test567.scxml" # uses _ioprocessors.basichttp.location
+ "spin/promela/test577.scxml" # send without target for basichttp
+ "spin/promela/test580.scxml" # timeout with delay
+
+
)
diff --git a/test/src/test-flat-stateid.cpp b/test/src/test-flat-stateid.cpp
index 719e4ee..7820d61 100644
--- a/test/src/test-flat-stateid.cpp
+++ b/test/src/test-flat-stateid.cpp
@@ -10,7 +10,7 @@ int main(int argc, char** argv) {
assert(flat1.getActive().size() == 0);
assert(flat1.getVisited().size() == 0);
assert(flat1.getHistory().size() == 0);
-
+
uscxml::FlatStateIdentifier flat2(flat1.getActive(), flat1.getVisited(), flat1.getHistory());
assert(flat2.getStateId() == stateId);
}
@@ -21,26 +21,26 @@ int main(int argc, char** argv) {
assert(flat1.getActive().size() == 1);
assert(flat1.getVisited().size() == 2);
assert(flat1.getHistory().size() == 0);
-
+
uscxml::FlatStateIdentifier flat2(flat1.getActive(), flat1.getVisited(), flat1.getHistory());
assert(flat2.getStateId() == stateId);
}
{
-
+
std::string stateId = "active:{s0,s1,s2};visited:{s0,s1,s2};history:{h0:{s1,s2},h1:{s2,s3}}";
uscxml::FlatStateIdentifier flat1(stateId);
-
+
listIter = flat1.getActive().begin();
assert(*listIter++ == "s0");
assert(*listIter++ == "s1");
assert(*listIter++ == "s2");
-
+
listIter = flat1.getVisited().begin();
assert(*listIter++ == "s0");
assert(*listIter++ == "s1");
assert(*listIter++ == "s2");
-
+
assert(flat1.getHistory().find("h0") != flat1.getHistory().end());
listIter = flat1.getHistory().at("h0").begin();
assert(*listIter++ == "s1");
diff --git a/test/src/test-issue-reporting.cpp b/test/src/test-issue-reporting.cpp
index cd1687c..39dad05 100644
--- a/test/src/test-issue-reporting.cpp
+++ b/test/src/test-issue-reporting.cpp
@@ -7,9 +7,9 @@ using namespace uscxml;
std::set<std::string> issueLocationsForXML(const std::string xml) {
Interpreter interpreter = Interpreter::fromXML(xml);
std::list<InterpreterIssue> issues = interpreter.validate();
-
+
std::set<std::string> issueLocations;
-
+
for (std::list<InterpreterIssue>::iterator issueIter = issues.begin(); issueIter != issues.end(); issueIter++) {
std::cout << *issueIter << std::endl;
issueLocations.insert(issueIter->xPath);
@@ -20,7 +20,9 @@ std::set<std::string> issueLocationsForXML(const std::string xml) {
size_t runtimeIssues;
class IssueMonitor : public InterpreterMonitor {
public:
- IssueMonitor() { runtimeIssues = 0; }
+ IssueMonitor() {
+ runtimeIssues = 0;
+ }
void reportIssue(Interpreter interpreter, const InterpreterIssue& issue) {
runtimeIssues++;
}
@@ -37,42 +39,42 @@ int main(int argc, char** argv) {
if (1) {
// Potential endless loop
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <datamodel><data id=\"counter\" expr=\"5\" /></datamodel>"
- " <state id=\"foo\">"
- " <onentry><script>counter--;</script></onentry>"
- " <transition target=\"foo\" cond=\"counter > 0\" />"
- " <transition target=\"bar\" cond=\"counter == 0\" />"
- " </state>"
- " <state id=\"bar\" final=\"true\" />"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <datamodel><data id=\"counter\" expr=\"5\" /></datamodel>"
+ " <state id=\"foo\">"
+ " <onentry><script>counter--;</script></onentry>"
+ " <transition target=\"foo\" cond=\"counter > 0\" />"
+ " <transition target=\"bar\" cond=\"counter == 0\" />"
+ " </state>"
+ " <state id=\"bar\" final=\"true\" />"
+ "</scxml>";
+
IssueMonitor monitor;
Interpreter interpreter = Interpreter::fromXML(xml);
interpreter.addMonitor(&monitor);
interpreter.interpret();
-
+
// first reiteration is not counted as it might be valid when raising internal errors
assert(runtimeIssues == 3);
}
if (1) {
// Unreachable states
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"foo\">"
- " <parallel id=\"foz\">"
- " <state id=\"s0\" />"
- " <state id=\"s1\" />"
- " <state id=\"s2\" />"
- " </parallel>"
- " </state>"
- " <state id=\"bar\" />"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"foo\">"
+ " <parallel id=\"foz\">"
+ " <state id=\"s0\" />"
+ " <state id=\"s1\" />"
+ " <state id=\"s2\" />"
+ " </parallel>"
+ " </state>"
+ " <state id=\"bar\" />"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"bar\"]") != issueLocations.end());
assert(issueLocations.size() == 1);
@@ -80,14 +82,14 @@ int main(int argc, char** argv) {
if (1) {
// Invalid parents
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <onentry>"
- " <cancel sendidexpr=\"foo\" />"
- " </onentry>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <onentry>"
+ " <cancel sendidexpr=\"foo\" />"
+ " </onentry>"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("/scxml[1]/onentry[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
@@ -96,11 +98,11 @@ int main(int argc, char** argv) {
if (1) {
// State has no 'id' attribute
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state>"
- " <transition/>"
- " </state>"
- "</scxml>";
+ "<scxml datamodel=\"ecmascript\">"
+ " <state>"
+ " <transition/>"
+ " </state>"
+ "</scxml>";
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("/scxml[1]/state[1]") != issueLocations.end());
@@ -110,11 +112,11 @@ int main(int argc, char** argv) {
if (1) {
// Duplicate state with id
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\" />"
- " <state id=\"start\" />"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\" />"
+ " <state id=\"start\" />"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
assert(issueLocations.size() == 1);
@@ -122,32 +124,32 @@ int main(int argc, char** argv) {
if (1) {
// Transition has non-existant target state
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <transition target=\"done\" />"
- " </state>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <transition target=\"done\" />"
+ " </state>"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
}
-
+
if (1) {
// Transition can never be optimally enabled (conditionless, eventless)
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <transition target=\"done\" />"
- " <transition target=\"done\" />"
- " </state>"
- " <final id=\"done\" />"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <transition target=\"done\" />"
+ " <transition target=\"done\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]/transition[2]") != issueLocations.end());
assert(issueLocations.size() == 1);
@@ -155,29 +157,29 @@ int main(int argc, char** argv) {
if (1) {
// Transition can never be optimally enabled (conditionless, more events)
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <transition event=\"error\" target=\"done\" />"
- " <transition event=\"error.bar error.foo\" />"
- " </state>"
- " <final id=\"done\" />"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <transition event=\"error\" target=\"done\" />"
+ " <transition event=\"error.bar error.foo\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]/transition[2]") != issueLocations.end());
assert(issueLocations.size() == 1);
}
-
+
if (1) {
// Initial attribute has invalid target state
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\" initial=\"foo\">"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\" initial=\"foo\">"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("/scxml[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
@@ -185,14 +187,14 @@ int main(int argc, char** argv) {
if (1) {
// Invoke with unknown type
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <invoke type=\"non-existant\" />"
- " </state>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <invoke type=\"non-existant\" />"
+ " </state>"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
@@ -200,16 +202,16 @@ int main(int argc, char** argv) {
if (1) {
// Send to unknown IO Processor
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <onentry>"
- " <send type=\"non-existant\" />"
- " </onentry>"
- " </state>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <onentry>"
+ " <send type=\"non-existant\" />"
+ " </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);
@@ -217,11 +219,11 @@ int main(int argc, char** argv) {
if (1) {
// SCXML document requires unknown datamodel
-
+
const char* xml =
- "<scxml datamodel=\"non-existant\">"
- "</scxml>";
-
+ "<scxml datamodel=\"non-existant\">"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("/scxml[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
@@ -229,16 +231,16 @@ int main(int argc, char** argv) {
if (1) {
// Unknown executable content element
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <onentry>"
- " <nonexistant />"
- " </onentry>"
- " </state>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <onentry>"
+ " <nonexistant />"
+ " </onentry>"
+ " </state>"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/nonexistant[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
@@ -246,14 +248,14 @@ int main(int argc, char** argv) {
if (1) {
// Syntax error in script
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <script>"
- " $wfwegr^ "
- " </script>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <script>"
+ " $wfwegr^ "
+ " </script>"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("/scxml[1]/script[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
@@ -261,19 +263,19 @@ int main(int argc, char** argv) {
if (1) {
// Syntax error in cond attribute
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <onentry>"
- " <if cond=\"%2345\">"
- " <elseif cond=\"%2345\" />"
- " </if>"
- " </onentry>"
- " <transition cond=\"%2345\" />"
- " </state>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <onentry>"
+ " <if cond=\"%2345\">"
+ " <elseif cond=\"%2345\" />"
+ " </if>"
+ " </onentry>"
+ " <transition cond=\"%2345\" />"
+ " </state>"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end());
assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/if[1]") != issueLocations.end());
@@ -283,24 +285,24 @@ int main(int argc, char** argv) {
if (1) {
// Syntax error in expr attribute
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <datamodel>"
- " <data id=\"foo\" expr=\"%2345\" />"
- " </datamodel>"
- " <state id=\"start\">"
- " <onentry>"
- " <log expr=\"%2345\" />"
- " <assign location=\"foo\" expr=\"%2345\" />"
- " <send>"
- " <param expr=\"%2345\" />"
- " <content expr=\"%2345\" />"
- " </send>"
- " </onentry>"
- " </state>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <datamodel>"
+ " <data id=\"foo\" expr=\"%2345\" />"
+ " </datamodel>"
+ " <state id=\"start\">"
+ " <onentry>"
+ " <log expr=\"%2345\" />"
+ " <assign location=\"foo\" expr=\"%2345\" />"
+ " <send>"
+ " <param expr=\"%2345\" />"
+ " <content expr=\"%2345\" />"
+ " </send>"
+ " </onentry>"
+ " </state>"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/log[1]") != issueLocations.end());
assert(issueLocations.find("//data[@id=\"foo\"]") != issueLocations.end());
@@ -312,17 +314,17 @@ int main(int argc, char** argv) {
if (1) {
// Syntax error with foreach
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <onentry>"
- " <foreach item=\"%2345\" index=\"%2345\" array=\"%2345\">"
- " </foreach>"
- " </onentry>"
- " </state>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <onentry>"
+ " <foreach item=\"%2345\" index=\"%2345\" array=\"%2345\">"
+ " </foreach>"
+ " </onentry>"
+ " </state>"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/foreach[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
@@ -330,16 +332,16 @@ int main(int argc, char** argv) {
if (1) {
// Syntax error with send
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <onentry>"
- " <send eventexpr=\"%2345\" targetexpr=\"%2345\" typeexpr=\"%2345\" idlocation=\"%2345\" delayexpr=\"%2345\" />"
- " </onentry>"
- " </state>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <onentry>"
+ " <send eventexpr=\"%2345\" targetexpr=\"%2345\" typeexpr=\"%2345\" idlocation=\"%2345\" delayexpr=\"%2345\" />"
+ " </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);
@@ -347,14 +349,14 @@ int main(int argc, char** argv) {
if (1) {
// Syntax error with invoke
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <invoke typeexpr=\"%2345\" srcexpr=\"%2345\" idlocation=\"%2345\" />"
- " </state>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <invoke typeexpr=\"%2345\" srcexpr=\"%2345\" idlocation=\"%2345\" />"
+ " </state>"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
@@ -362,16 +364,16 @@ int main(int argc, char** argv) {
if (1) {
// Syntax error with cancel
-
+
const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <onentry>"
- " <cancel sendidexpr=\"%2345\" />"
- " </onentry>"
- " </state>"
- "</scxml>";
-
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <onentry>"
+ " <cancel sendidexpr=\"%2345\" />"
+ " </onentry>"
+ " </state>"
+ "</scxml>";
+
std::set<std::string> issueLocations = issueLocationsForXML(xml);
assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/cancel[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
diff --git a/test/src/test-mmi.cpp b/test/src/test-mmi.cpp
index eeb71ee..52deeef 100644
--- a/test/src/test-mmi.cpp
+++ b/test/src/test-mmi.cpp
@@ -30,14 +30,14 @@ int main(int argc, char** argv) {
// --- NewContextRequest
std::stringstream ss;
ss << "<mmi:mmi xmlns:mmi=\"http://www.w3.org/2008/04/mmi-arch\" version=\"1.0\"><mmi:NewContextRequest mmi:Source=\"someURI\" mmi:Target=\"someOtherURI\" mmi:RequestID=\"request-1\"></mmi:NewContextRequest></mmi:mmi>";
-
+
NewContextRequest msg = NewContextRequest::fromXML(xmlToDoc(ss.str()));
assert(boost::iequals(msg.tagName, "NewContextRequest"));
assert(boost::iequals(msg.source, "someURI"));
assert(boost::iequals(msg.target, "someOtherURI"));
assert(boost::iequals(msg.requestId, "request-1"));
assert(boost::iequals(msg.data, ""));
-
+
NewContextRequest msg2 = NewContextRequest::fromXML(msg.toXML());
assert(boost::iequals(msg2.tagName, "NewContextRequest"));
assert(boost::iequals(msg2.source, "someURI"));
@@ -50,7 +50,7 @@ int main(int argc, char** argv) {
xml1SS << msg.toXML();
xml2SS << msg2.toXML();
assert(xml1SS.str() == xml2SS.str());
-
+
Event ev = msg;
assert(ev.name == "mmi.request.newcontext");
assert(ev.origin == msg.source);
@@ -143,7 +143,7 @@ int main(int argc, char** argv) {
assert(boost::iequals(msg.requestId, "request-1"));
assert(boost::iequals(msg.context, "URI-1"));
assert(msg.contentDOM);
-
+
PrepareRequest msg2 = PrepareRequest::fromXML(msg.toXML());
assert(boost::iequals(msg2.tagName, "PrepareRequest"));
assert(boost::iequals(msg2.source, "someURI"));
@@ -270,29 +270,29 @@ int main(int argc, char** argv) {
assert(boost::iequals(msg.target, "someOtherURI"));
assert(boost::iequals(msg.requestId, "request-1"));
assert(boost::iequals(msg.context, "URI-1"));
-
+
StartRequest msg2 = StartRequest::fromXML(msg.toXML());
assert(boost::iequals(msg2.tagName, "StartRequest"));
assert(boost::iequals(msg2.source, "someURI"));
assert(boost::iequals(msg2.target, "someOtherURI"));
assert(boost::iequals(msg2.requestId, "request-1"));
assert(boost::iequals(msg2.context, "URI-1"));
-
+
std::stringstream xml1SS;
std::stringstream xml2SS;
xml1SS << msg.toXML();
xml2SS << msg2.toXML();
assert(xml1SS.str() == xml2SS.str());
-
+
Event ev = msg;
assert(ev.name == "mmi.request.start");
assert(ev.data.compound["foo"] == 12);
assert(ev.origin == msg.source);
-
+
}
-
-
+
+
{
// --- StartResponse
std::stringstream ss;
@@ -516,7 +516,7 @@ int main(int argc, char** argv) {
Event ev = msg;
assert(ev.name == "mmi.response.pause");
assert(ev.origin == msg.source);
-
+
}
{
@@ -624,7 +624,7 @@ int main(int argc, char** argv) {
assert(boost::iequals(msg.requestId, "request-1"));
assert(boost::iequals(msg.context, "someURI"));
assert(boost::iequals(msg.name, "appEvent"));
-
+
ExtensionNotification msg2 = ExtensionNotification::fromXML(msg.toXML());
assert(boost::iequals(msg2.tagName, "ExtensionNotification"));
assert(boost::iequals(msg2.source, "someURI"));
@@ -632,18 +632,18 @@ int main(int argc, char** argv) {
assert(boost::iequals(msg2.requestId, "request-1"));
assert(boost::iequals(msg2.context, "someURI"));
assert(boost::iequals(msg2.name, "appEvent"));
-
+
std::stringstream xml1SS;
std::stringstream xml2SS;
xml1SS << msg.toXML();
xml2SS << msg2.toXML();
assert(xml1SS.str() == xml2SS.str());
-
+
Event ev = msg;
assert(ev.name == "appEvent");
assert(ev.data.compound["foo"] == 12);
assert(ev.origin == msg.source);
-
+
}
{
diff --git a/test/src/test-promela-parser.cpp b/test/src/test-promela-parser.cpp
index 61e6b3f..261b8c9 100644
--- a/test/src/test-promela-parser.cpp
+++ b/test/src/test-promela-parser.cpp
@@ -165,8 +165,6 @@ void testInlinePromela() {
assert(prmInls.inlines.front().sequences.size() == 0);
assert(boost::trim_copy(prmInls.inlines.front().content) == "This is foo!");
}
-
- exit(0);
}
void testPromelaParser() {
@@ -188,6 +186,18 @@ void testPromelaParser() {
expressions.push_back("bool busy[3];");
expressions.push_back("bool busy[3], us[4];");
expressions.push_back("mtype = {\nred, white, blue,\nabort, accept, ack, sync_ack, close, connect,\ncreate, data, eof, open, reject, sync, transfer,\nFATAL, NON_FATAL, COMPLETE\n}");
+ expressions.push_back("typedef D { short f; byte g }; ");
+ expressions.push_back("x = 1");
+ expressions.push_back("x = foo.bar[2].baz; ");
+ expressions.push_back("_event.data[1].aParam.key1.key2[1].key3.key4");
+ expressions.push_back("_event.data.aParam");
+ expressions.push_back("_event.data");
+ expressions.push_back("_event");
+ expressions.push_back("states");
+ expressions.push_back("states[1]");
+ expressions.push_back("_x.states[1]");
+ expressions.push_back("_x.states[1].foo");
+ expressions.push_back("_event.data[1].aParam.key1.key2[1].key3.key4");
/* expressions */
expressions.push_back("i+1");
@@ -203,8 +213,8 @@ void testPromelaParser() {
expressions.push_back("c++");
expressions.push_back("state = state - 1");
expressions.push_back("printf(\"hello world\\n\")");
- expressions.push_back("printf(\"result %d: %d\n\", id, res, foo, bar)");
- expressions.push_back("printf(\"x = %d\n\", x)");
+ expressions.push_back("printf(\"result %d: %d\\n\", id, res, foo, bar)");
+ expressions.push_back("printf(\"x = %d\\n\", x)");
expressions.push_back("(n <= 1)");
expressions.push_back("res = (a*a+b)/2*a;");
expressions.push_back("assert(0) /* a forced stop, (Chapter 6) */");
diff --git a/test/src/test-sockets.cpp b/test/src/test-sockets.cpp
index 993aaff..16234ee 100644
--- a/test/src/test-sockets.cpp
+++ b/test/src/test-sockets.cpp
@@ -74,10 +74,10 @@ int main(int argc, char** argv) {
// LogServer server(PF_INET, SOCK_STREAM, 0);
server.listen("*", 1235);
server.setBlockSizeRead(1);
-
+
TestClient client(PF_INET, SOCK_STREAM, 0);
client.connect("127.0.0.1", 1235);
-
+
int iterations = 1000;
std::stringstream contentSS;
for (int i = 0; i < iterations; i++) {
@@ -94,7 +94,7 @@ int main(int argc, char** argv) {
packetSeq = 0;
CountingPacketServer server(PF_INET, SOCK_STREAM, 0, std::string("\0", 1));
server.listen("*", 1235);
-
+
TestClient client(PF_INET, SOCK_STREAM, 0);
client.connect("127.0.0.1", 1235);
@@ -107,9 +107,9 @@ int main(int argc, char** argv) {
while(packetSeq != iterations)
tthread::this_thread::sleep_for(tthread::chrono::milliseconds(20));
}
-
+
exit(0);
-
+
if (1) {
// start server socket and connect
int iterations = 100;
diff --git a/test/src/test-url.cpp b/test/src/test-url.cpp
index b3f9e28..5e5f4ea 100644
--- a/test/src/test-url.cpp
+++ b/test/src/test-url.cpp
@@ -49,7 +49,7 @@ int main(int argc, char** argv) {
#endif
HTTPServer::getInstance(8099, 8100);
-
+
std::string exeName = argv[0];
exeName = exeName.substr(exeName.find_last_of("\\/") + 1);
diff --git a/test/src/test-vxml-mmi-http.cpp b/test/src/test-vxml-mmi-http.cpp
index 2b2cd25..35dc5d6 100644
--- a/test/src/test-vxml-mmi-http.cpp
+++ b/test/src/test-vxml-mmi-http.cpp
@@ -50,28 +50,29 @@ public:
bool httpRecvRequest(const HTTPServer::Request& request) {
std::cout << "RCVD:" << std::endl << request << std::flush;
tthread::lock_guard<tthread::mutex> lock(Mutex);
-
+
const Arabica::DOM::Document<std::string>& doc = request.data.at("content").node.getOwnerDocument();
// NameSpacingParser parser = NameSpacingParser::fromXML(request.content);
switch(MMIEvent::getType(doc.getDocumentElement())) {
- case MMIEvent::NEWCONTEXTRESPONSE: {
- NewContextResponse* resp = new NewContextResponse(NewContextResponse::fromXML(doc.getDocumentElement()));
- context = resp->context;
- Replies[resp->requestId] = resp;
- break;
- }
- case MMIEvent::STARTRESPONSE: {
- StartResponse* resp = new StartResponse(StartResponse::fromXML(doc.getDocumentElement()));
- Replies[resp->requestId] = resp;
- }
- default: ;
+ case MMIEvent::NEWCONTEXTRESPONSE: {
+ NewContextResponse* resp = new NewContextResponse(NewContextResponse::fromXML(doc.getDocumentElement()));
+ context = resp->context;
+ Replies[resp->requestId] = resp;
+ break;
+ }
+ case MMIEvent::STARTRESPONSE: {
+ StartResponse* resp = new StartResponse(StartResponse::fromXML(doc.getDocumentElement()));
+ Replies[resp->requestId] = resp;
+ }
+ default:
+ ;
}
-
+
Cond.notify_all();
-
+
HTTPServer::Reply reply(request);
HTTPServer::reply(reply);
-
+
return true;
}
void setURL(const std::string& url) {
@@ -86,7 +87,7 @@ void printUsageAndExit(const char* progName) {
if (progStr.find_last_of(PATH_SEPERATOR) != std::string::npos) {
progStr = progStr.substr(progStr.find_last_of(PATH_SEPERATOR) + 1, progStr.length() - (progStr.find_last_of(PATH_SEPERATOR) + 1));
}
-
+
printf("%s version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n", progStr.c_str());
printf("Usage\n");
printf("\t%s", progStr.c_str());
@@ -105,26 +106,26 @@ int main(int argc, char** argv) {
std::string target;
std::string document;
-
+
if (argc < 2)
printUsageAndExit(argv[0]);
int option;
while ((option = getopt(argc, argv, "t:")) != -1) {
switch(option) {
- case 't':
- target = optarg;
- break;
- default:
- printUsageAndExit(argv[0]);
+ case 't':
+ target = optarg;
+ break;
+ default:
+ printUsageAndExit(argv[0]);
}
}
-
+
if (argc < optind)
printUsageAndExit(argv[0]);
-
+
document = argv[optind];
-
+
if (!boost::starts_with(document, "http"))
document = "http://" + document;
@@ -134,11 +135,11 @@ int main(int argc, char** argv) {
// target = "http://130.83.163.167:9090/mmi";
// target = "http://localhost:9090/mmi";
-
+
MMIServlet servlet;
HTTPServer::getInstance(4344, 0);
HTTPServer::getInstance()->registerServlet("/mmi", &servlet);
-
+
std::string source = servlet.url;
NewContextRequest newCtxReq;
@@ -147,12 +148,12 @@ int main(int argc, char** argv) {
newCtxReq.requestId = uscxml::UUID::getUUID();
Requests[newCtxReq.requestId] = &newCtxReq;
-
+
ISSUE_REQUEST(newCtxReq, false);
while(Replies.find(newCtxReq.requestId) == Replies.end())
Cond.wait(Mutex);
-
+
StartRequest startReq;
startReq.context = context;
startReq.source = source;
@@ -160,7 +161,7 @@ int main(int argc, char** argv) {
startReq.requestId = uscxml::UUID::getUUID();
startReq.contentURL.href = document;
//"https://raw.githubusercontent.com/Roland-Taizun-Azhar/TaskAssistance-Project/master/WebContent/hello.vxml";
-
+
Requests[startReq.requestId] = &startReq;
ISSUE_REQUEST(startReq, false);
@@ -173,6 +174,6 @@ int main(int argc, char** argv) {
} catch (std::exception e) {
std::cout << e.what() << std::endl;
}
-
-
+
+
} \ No newline at end of file
diff --git a/test/src/test-vxml-mmi-socket.cpp b/test/src/test-vxml-mmi-socket.cpp
index 99662c9..4db7109 100644
--- a/test/src/test-vxml-mmi-socket.cpp
+++ b/test/src/test-vxml-mmi-socket.cpp
@@ -23,18 +23,18 @@ bool testAddressParsing() {
std::string protocol;
std::string hostName;
uint16_t port;
-
+
{
Socket::parseAddress("4343", protocol, hostName, port);
assert(protocol == "tcp");
assert(hostName == "127.0.0.1");
assert(port == 4343);
-
+
Socket::parseAddress("localhost:4343", protocol, hostName, port);
assert(protocol == "tcp");
assert(hostName == "localhost");
assert(port == 4343);
-
+
Socket::parseAddress("tcp://localhost:4343", protocol, hostName, port);
assert(protocol == "tcp");
assert(hostName == "localhost");
@@ -52,16 +52,16 @@ bool testMMIEvents() {
Arabica::DOM::Document<std::string> newCtxReqXML1 = newCtxReq.toXML();
Arabica::DOM::Document<std::string> newCtxReqXML2 = newCtxReq.toXML(true);
-
+
// std::cout << newCtxReqXML1 << std::endl;
// std::cout << newCtxReqXML2 << std::endl;
-
+
NewContextRequest newCtxReq1 = NewContextRequest::fromXML(newCtxReqXML1.getDocumentElement());
NewContextRequest newCtxReq2 = NewContextRequest::fromXML(newCtxReqXML2.getDocumentElement());
-
+
assert(MMIEvent::getType(newCtxReqXML1.getDocumentElement()) == MMIEvent::NEWCONTEXTREQUEST);
assert(MMIEvent::getType(newCtxReqXML2.getDocumentElement()) == MMIEvent::NEWCONTEXTREQUEST);
-
+
assert(newCtxReq1.source == "localhost:3434");
assert(newCtxReq2.source == "localhost:3434");
assert(newCtxReq1.target == "localhost:1212");
@@ -109,28 +109,28 @@ int main(int argc, char** argv) {
#endif
testAddressParsing();
testMMIEvents();
-
+
// TestClient client(PF_INET, SOCK_STREAM, 0);
// client.connect("epikur.local", 4343);
std::string target = "localhost:4343";
std::string source = "localhost:4344";
-
+
TestServer server(PF_INET, SOCK_STREAM, 0);
server.listen(source);
-
+
// while(true)
// sleep(1000);
-
+
TestClient client(PF_INET, SOCK_STREAM, 0);
client.connect(source);
-
+
NewContextRequest newCtxReq;
newCtxReq.source = source;
newCtxReq.target = target;
newCtxReq.requestId = UUID::getUUID();
-
+
_requests[newCtxReq.requestId] = &newCtxReq;
-
+
Arabica::DOM::Document<std::string> newCtxReqXML = newCtxReq.toXML(true);
std::stringstream newCtxReqXMLSS;
newCtxReqXMLSS << newCtxReqXML;
@@ -141,7 +141,7 @@ int main(int argc, char** argv) {
// client.write(newCtxReqXMLSS.str().data(), newCtxReqXMLSS.str().size());
// client.write("\0", 1);
}
-
+
while(true)
sleep(1000);
diff --git a/test/src/test-w3c.cpp b/test/src/test-w3c.cpp
index 3c20e76..27c69b2 100644
--- a/test/src/test-w3c.cpp
+++ b/test/src/test-w3c.cpp
@@ -98,10 +98,10 @@ int main(int argc, char** argv) {
using namespace uscxml;
try {
-
- #if defined(HAS_SIGNAL_H) && !defined(WIN32)
+
+#if defined(HAS_SIGNAL_H) && !defined(WIN32)
signal(SIGPIPE, SIG_IGN);
- #endif
+#endif
if (argc < 2) {
exit(EXIT_FAILURE);
@@ -116,23 +116,23 @@ int main(int argc, char** argv) {
if (dfEnv) {
delayFactor = strTo<double>(dfEnv);
}
-
+
int option;
while ((option = getopt(argc, argv, "fd:")) != -1) {
switch(option) {
- case 'f':
- withFlattening = true;
- break;
- case 'd':
- delayFactor = strTo<double>(optarg);
- break;
- default:
- break;
+ case 'f':
+ withFlattening = true;
+ break;
+ case 'd':
+ delayFactor = strTo<double>(optarg);
+ break;
+ default:
+ break;
}
}
documentURI = argv[optind];
-
+
Interpreter interpreter;
LOG(INFO) << "Processing " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor));
if (withFlattening) {
@@ -147,7 +147,7 @@ int main(int argc, char** argv) {
Arabica::DOM::Document<std::string> document = interpreter.getDocument();
Arabica::DOM::Element<std::string> root = document.getDocumentElement();
Arabica::XPath::NodeSet<std::string> sends = InterpreterImpl::filterChildElements(interpreter.getNameSpaceInfo().xmlNSPrefix + "send", root, true);
-
+
for (int i = 0; i < sends.size(); i++) {
Arabica::DOM::Element<std::string> send = Arabica::DOM::Element<std::string>(sends[i]);
if (HAS_ATTR(send, "delay")) {
@@ -161,9 +161,9 @@ int main(int argc, char** argv) {
} else if (HAS_ATTR(send, "delayexpr")) {
std::string delayExpr = ATTR(send, "delayexpr");
send.setAttribute("delayexpr",
- "(" + delayExpr + ".indexOf('ms', " + delayExpr + ".length - 2) !== -1 ? "
- "(" + delayExpr + ".slice(0,-2) * " + toStr(delayFactor) + ") + \"ms\" : "
- "(" + delayExpr + ".slice(0,-1) * 1000 * " + toStr(delayFactor) + ") + \"ms\")");
+ "(" + delayExpr + ".indexOf('ms', " + delayExpr + ".length - 2) !== -1 ? "
+ "(" + delayExpr + ".slice(0,-2) * " + toStr(delayFactor) + ") + \"ms\" : "
+ "(" + delayExpr + ".slice(0,-1) * 1000 * " + toStr(delayFactor) + ") + \"ms\")");
std::cout << ATTR(send, "delayexpr") << std::endl;
}
}
@@ -172,7 +172,7 @@ int main(int argc, char** argv) {
std::cout << *issueIter << std::endl;
}
}
-
+
if (interpreter) {
W3CStatusMonitor* vm = new W3CStatusMonitor();
interpreter.addMonitor(vm);
diff --git a/test/uscxml/test-jvoicexml.scxml b/test/uscxml/test-jvoicexml.scxml
index 2e60cf3..706541b 100644
--- a/test/uscxml/test-jvoicexml.scxml
+++ b/test/uscxml/test-jvoicexml.scxml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:vxml="http://www.w3.org/2001/vxml" datamodel="ecmascript">
<!-- get dump() function into datamodel -->
- <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js"/>
+ <script src="file:///Users/sradomski/Desktop/dump.js"/>
<script>
vxmlTargetURL = "http://localhost:9090/mmi";
</script>
diff --git a/test/w3c/confPromela.xsl b/test/w3c/confPromela.xsl
new file mode 100644
index 0000000..1204d33
--- /dev/null
+++ b/test/w3c/confPromela.xsl
@@ -0,0 +1,779 @@
+<?xml version="1.0"?>
+<!-- Copyright 1998-2003 W3C (MIT, ERCIM, Keio), All Rights Reserved. See http://www.w3.org/Consortium/Legal/. -->
+<!-- Stefan Radomski 2014 -->
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:conf="http://www.w3.org/2005/scxml-conformance"
+ xmlns:scxml="http://www.w3.org/2005/07/scxml"
+ version="2.0">
+
+
+
+
+<!-- Copy everything that doesn't match other rules -->
+<xsl:template match="/ | @* | node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@* | node()"/>
+ </xsl:copy>
+</xsl:template>
+
+<!-- Success criteria -->
+
+<xsl:template match="//@conf:targetpass">
+ <xsl:attribute name="target">pass</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="conf:pass">
+ <final xmlns="http://www.w3.org/2005/07/scxml" id="pass">
+ <onentry>
+ <log label="Outcome" expr="'pass'"/>
+ </onentry>
+ </final>
+</xsl:template>
+
+<!-- Failure criteria -->
+
+<xsl:template match="//@conf:targetfail">
+ <xsl:attribute name="target">fail</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="conf:fail">
+ <final xmlns="http://www.w3.org/2005/07/scxml" id="fail">
+ <onentry>
+ <log label="Outcome" expr="'fail'"/>
+ </onentry>
+</final>
+</xsl:template>
+
+<!-- datamodel -->
+<xsl:template match="//@conf:datamodel">
+ <xsl:attribute name="datamodel">promela</xsl:attribute>
+</xsl:template>
+
+
+<!-- creates id for <data> element, etc. -->
+<!-- xsl:template match="//scxml:data[conf:array123]" -->
+<xsl:template match="//@conf:id[../conf:array123]" priority="5">
+ <xsl:attribute name="id">Var<xsl:value-of select="." /></xsl:attribute>
+ <xsl:attribute name="type">int[3]</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:id[../@conf:quoteExpr]" priority="5">
+ <xsl:attribute name="id">Var<xsl:value-of select="." /></xsl:attribute>
+ <xsl:attribute name="type">string</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:id[../@conf:systemVarExpr]" priority="5">
+ <xsl:attribute name="id">Var<xsl:value-of select="." /></xsl:attribute>
+ <xsl:attribute name="type">string</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:id[//@conf:idQuoteVal='1=internal']" priority="5">
+ <xsl:attribute name="id">Var<xsl:value-of select="." /></xsl:attribute>
+ <xsl:attribute name="type">string</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:id">
+ <xsl:attribute name="id">Var<xsl:value-of select="." /></xsl:attribute>
+ <xsl:attribute name="type">int</xsl:attribute>
+</xsl:template>
+
+<!-- creates name for <param>, etc. -->
+<xsl:template match="//@conf:name">
+ <xsl:attribute name="name">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+
+<!-- creates location for <assign>, etc. -->
+<xsl:template match="//@conf:location">
+ <xsl:attribute name="location">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- names an invalid location for <assign>, etc. -->
+<xsl:template match="//@conf:invalidLocation">
+ <xsl:attribute name="location">foo.bar.baz </xsl:attribute>
+</xsl:template>
+
+<!-- uses system var as location for <assign>, etc. -->
+<xsl:template match="//@conf:systemVarLocation">
+ <xsl:attribute name="location"><xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+
+
+
+<!-- expr is evaluated -->
+<xsl:template match="//@conf:expr">
+ <xsl:attribute name="expr"><xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- targetexpr is the corresponding ID -->
+<xsl:template match="//@conf:targetVar">
+ <xsl:attribute name="targetexpr">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- expr is quoted -->
+<xsl:template match="//@conf:quoteExpr">
+ <xsl:attribute name="expr">'<xsl:value-of select="." />'</xsl:attribute>
+</xsl:template>
+
+<!-- an expr that is the value of a variable -->
+<xsl:template match="//@conf:varExpr">
+ <xsl:attribute name="expr">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- in EcmaScript, this is the same as varExpr -->
+<xsl:template match="//@conf:varChildExpr">
+ <xsl:attribute name="expr">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- an expr that is the value of a system variable -->
+<xsl:template match="//@conf:systemVarExpr">
+ <xsl:attribute name="expr"><xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+
+<!-- an expr that is the value of a non-existent substructure of a variable -->
+<xsl:template match="//@conf:varNonexistentStruct">
+ <xsl:attribute name="expr">Var<xsl:value-of select="." />.bar</xsl:attribute>
+</xsl:template>
+
+
+<!-- this should return a value that cannot be assigned to a var. -->
+<xsl:template match="//@conf:illegalExpr">
+ <xsl:attribute name="expr">return</xsl:attribute>
+</xsl:template>
+
+<!-- this should add 1 to the value of the specified variable -->
+<xsl:template match="conf:incrementID">
+ <assign xmlns="http://www.w3.org/2005/07/scxml">
+ <xsl:attribute name="location">Var<xsl:value-of select="@id"/></xsl:attribute>
+ <xsl:attribute name="expr">Var<xsl:value-of select="@id"/> + 1</xsl:attribute>
+ </assign>
+ </xsl:template>
+
+<!-- this should concatenate the value of the id2 to id1 and assign the result to id1 -->
+<xsl:template match="conf:concatVars">
+ <assign xmlns="http://www.w3.org/2005/07/scxml">
+ <xsl:attribute name="location">Var<xsl:value-of select="@id1"/></xsl:attribute>
+ <xsl:attribute name="expr">Var<xsl:value-of select="@id1"/> + Var<xsl:value-of select="@id2"/></xsl:attribute>
+ </assign>
+ </xsl:template>
+
+<!-- assigns the sum of the values of two vars to thefirst var-->
+<xsl:template match="//conf:sumVars">
+ <assign xmlns="http://www.w3.org/2005/07/scxml">
+<xsl:attribute name="location">Var<xsl:value-of select="@id1"/></xsl:attribute>
+<xsl:attribute name="expr">Var<xsl:value-of select="@id1"/> + Var<xsl:value-of select="@id2"/></xsl:attribute>
+ </assign>
+ </xsl:template>
+
+<!-- this should return an illegal target for <send> causing a send error to be raised -->
+<xsl:template match="//@conf:illegalTarget">
+ <xsl:attribute name="target">baz</xsl:attribute>
+</xsl:template>
+
+<!-- this returns an legal, but unreachable, target for <send> causing a send error to be raised -->
+<xsl:template match="//@conf:unreachableTarget">
+ <xsl:attribute name="target">#_scxml_foo</xsl:attribute>
+</xsl:template>
+
+<!-- this produces illegal content for <send> causing the message to be rejected -->
+<xsl:template match="//conf:illegalContent">
+ <content xmlns="http://www.w3.org/2005/07/scxml"> xyz </content>
+</xsl:template>
+
+<!-- a content element whose value is the string 'foo' -->
+<xsl:template match="//conf:contentFoo">
+ <content xmlns="http://www.w3.org/2005/07/scxml">foo</content>
+</xsl:template>
+
+<xsl:template match="//conf:someInlineVal">123</xsl:template>
+
+<!-- this returns something that is guaranteed not to be the ID of the current session -->
+<xsl:template match="//@conf:invalidSessionID">
+ <xsl:attribute name="expr">27</xsl:attribute>
+</xsl:template>
+
+<!-- this returns something that is guaranteed not to be a valid event I/O processor -->
+<xsl:template match="//@conf:invalidSendType">
+ <xsl:attribute name="type">27</xsl:attribute>
+</xsl:template>
+
+<!-- same value in an expr -->
+<xsl:template match="//@conf:invalidSendTypeExpr">
+ <xsl:attribute name="expr">27</xsl:attribute>
+</xsl:template>
+
+<!-- exprs that return the value of the event fields -->
+
+<xsl:template match="//@conf:eventName">
+ <xsl:attribute name="expr">_event.name</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:eventType">
+ <xsl:attribute name="expr">_event.type</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:eventSendid">
+ <xsl:attribute name="expr">_event.sendid</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:eventField">
+ <xsl:attribute name="expr">_event.<xsl:value-of select="."/></xsl:attribute>
+</xsl:template>
+
+<!-- returns the raw message structure as a string -->
+<xsl:template match="//@conf:eventRaw">
+ <xsl:attribute name="expr">_event.raw</xsl:attribute>
+</xsl:template>
+
+
+<!-- returns the value of the specified item in _event.data -->
+<xsl:template match="//@conf:eventDataFieldValue">
+ <xsl:attribute name="expr">_event.data.<xsl:value-of select="."/></xsl:attribute>
+</xsl:template>
+
+<!-- returns the value of a KVP specified by <param> from _event.data -->
+<xsl:template match="//@conf:eventDataParamValue">
+ <xsl:attribute name="expr">_event.data.<xsl:value-of select="."/></xsl:attribute>
+</xsl:template>
+<!-- returns the value of a KVP specified by <param> from _event.data -->
+<xsl:template match="//@conf:eventDataNamelistValue">
+ <xsl:attribute name="expr">_event.data.Var<xsl:value-of select="."/></xsl:attribute>
+</xsl:template>
+
+<!-- returns the location of the scxml event i/o processor -->
+<xsl:template match="//@conf:scxmlEventIOLocation">
+ <xsl:attribute name="expr">_ioprocessors.scxml.location</xsl:attribute>
+</xsl:template>
+
+<!-- templates for the expr versions of the send attributes -->
+
+<!-- eventexpr takes the value of the specified variable -->
+<xsl:template match="//@conf:eventExpr">
+ <xsl:attribute name="eventexpr">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- targetexpr takes the value of the specified variable -->
+<xsl:template match="//@conf:targetExpr">
+ <xsl:attribute name="targetexpr">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- typeexpr takes the value of the specified variable -->
+<xsl:template match="//@conf:typeExpr">
+ <xsl:attribute name="typeexpr">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- delayexpr takes the value of the specified variable -->
+<xsl:template match="//@conf:delayFromVar">
+ <xsl:attribute name="delayexpr">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- computes a delayexpr based on the value passed in. this lets platforms determine how long to delay timeout
+events which cause the test to fail. The default value provided here is pretty long -->
+<xsl:template match="//@conf:delay">
+ <xsl:attribute name="delayexpr">'<xsl:value-of select="."/>s'</xsl:attribute>
+</xsl:template>
+
+<!-- the specified variable is used as idlocation -->
+<xsl:template match="//@conf:idlocation">
+ <xsl:attribute name="idlocation">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- the specified variable is used as sendidexpr -->
+<xsl:template match="//@conf:sendIDExpr">
+ <xsl:attribute name="sendidexpr">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- the specified variable is used as srcexpr -->
+<xsl:template match="//@conf:srcExpr">
+ <xsl:attribute name="srcexpr">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- the specified variable is used as namelist -->
+<xsl:template match="//@conf:namelist">
+ <xsl:attribute name="namelist">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- this produces a reference to an invalid namelist, i.e. on that should cause an error -->
+<xsl:template match="//@conf:invalidNamelist">
+ <xsl:attribute name="namelist">&#34;foo</xsl:attribute>
+</xsl:template>
+
+
+
+
+<!-- transition conditions -->
+<!-- the value is evaluated -->
+<xsl:template match="//@conf:idVal">
+ <xsl:attribute name="cond">
+ <xsl:analyze-string select="."
+ regex="([0-9]+)([=&lt;&gt;]=?)(.*)">
+ <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/>
+ <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$op='='">==</xsl:when>
+ <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise>
+ </xsl:choose>
+ <xsl:value-of select="regex-group(3)"/>
+ </xsl:matching-substring>
+
+ </xsl:analyze-string>
+ </xsl:attribute>
+</xsl:template>
+<!-- compare two variables -->
+<xsl:template match="//@conf:varIdVal">
+ <xsl:attribute name="cond">
+ <xsl:analyze-string select="."
+ regex="([0-9]+)([=&lt;&gt;]=?)(.*)">
+ <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/>
+ <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$op='='">==</xsl:when>
+ <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise>
+ </xsl:choose>Var<xsl:value-of select="regex-group(3)"/>
+ </xsl:matching-substring>
+
+ </xsl:analyze-string>
+ </xsl:attribute>
+</xsl:template>
+
+
+<!-- test that given var whose value was passed in via namelist has specific value. The value expr is evaluated -->
+<xsl:template match="//@conf:namelistIdVal">
+ <xsl:attribute name="cond">
+ <xsl:analyze-string select="."
+ regex="([0-9]+)([=&lt;&gt;]=?)(.*)">
+ <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/>
+ <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$op='='">==</xsl:when>
+ <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise>
+ </xsl:choose>
+ <xsl:value-of select="regex-group(3)"/>
+ </xsl:matching-substring>
+
+ </xsl:analyze-string>
+ </xsl:attribute>
+</xsl:template>
+
+<!-- true if the two vars/ids have the same value -->
+<xsl:template match="//@conf:VarEqVar">
+ <xsl:attribute name="cond">
+ <xsl:analyze-string select="."
+ regex="([0-9]+)(\W+)([0-9]+)">
+ <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/>==Var<xsl:value-of select="regex-group(3)"/>
+ </xsl:matching-substring>
+ </xsl:analyze-string>
+ </xsl:attribute>
+</xsl:template>
+
+<!-- true if the two vars/ids have the same value, which is a structure, not atomic -->
+<xsl:template match="//@conf:VarEqVarStruct">
+ <xsl:attribute name="cond">
+ <xsl:analyze-string select="."
+ regex="([0-9]+)(\W+)([0-9]+)">
+ <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/>==Var<xsl:value-of select="regex-group(3)"/>
+ </xsl:matching-substring>
+ </xsl:analyze-string>
+ </xsl:attribute>
+</xsl:template>
+
+<!-- the value is quoted -->
+<xsl:template match="//@conf:idQuoteVal">
+ <xsl:attribute name="cond">
+ <xsl:analyze-string select="."
+ regex="([0-9]+)([=&lt;&gt;]=?)(.*)">
+<xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/><xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable>
+<xsl:choose>
+<xsl:when test="$op='='">==</xsl:when>
+<xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise></xsl:choose>'<xsl:value-of select="regex-group(3)"/>'</xsl:matching-substring>
+</xsl:analyze-string>
+</xsl:attribute>
+</xsl:template>
+
+<!-- test on the value of two vars -->
+<xsl:template match="//@conf:compareIDVal">
+ <xsl:attribute name="cond">
+ <xsl:analyze-string select="."
+ regex="([0-9]+)([=&lt;&gt;]=?)([0-9+])">
+ <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/>
+ <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$op='='">=</xsl:when>
+ <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise>
+ </xsl:choose>Var<xsl:value-of select="regex-group(3)"/>
+ </xsl:matching-substring>
+ </xsl:analyze-string>
+ </xsl:attribute>
+</xsl:template>
+
+<!-- test that the specified var has the value specified by <conf:someInlineVal> -->
+<xsl:template match="//@conf:idSomeVal">
+ <xsl:attribute name="cond">Var<xsl:value-of select="." /> == 123</xsl:attribute>
+</xsl:template>
+
+<!-- test that the event's name fieldhas the value specified -->
+<xsl:template match="//@conf:eventNameVal">
+ <xsl:attribute name="cond">_event.name == <xsl:text>'</xsl:text><xsl:value-of select="."/><xsl:text>'</xsl:text>
+ </xsl:attribute>
+
+</xsl:template>
+
+<xsl:template match="//@conf:eventvarVal">
+ <xsl:attribute name="cond">
+ <xsl:analyze-string select="."
+ regex="([0-9]+)([=&lt;&gt;]=?)(.*)">
+ <xsl:matching-substring>_event.data.Var<xsl:value-of select="regex-group(1)"/><xsl:text></xsl:text>
+ <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$op='='">==</xsl:when>
+ <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise>
+ </xsl:choose>
+ <xsl:value-of select="regex-group(3)"/>
+ </xsl:matching-substring>
+
+ </xsl:analyze-string>
+ </xsl:attribute>
+
+</xsl:template>
+
+
+
+<!-- return true if variable matches value of system var (var number is first arg, system var name
+is the second argument -->
+<xsl:template match="//@conf:idSystemVarVal">
+ <xsl:attribute name="cond">
+ <xsl:analyze-string select="."
+ regex="([0-9]+)([=&lt;&gt;]=?)(.*)">
+<xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/><xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable>
+<xsl:choose>
+<xsl:when test="$op='='">==</xsl:when>
+<xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise></xsl:choose><xsl:value-of select="regex-group(3)"/></xsl:matching-substring>
+</xsl:analyze-string>
+</xsl:attribute>
+</xsl:template>
+
+<!-- return true if event.data field matches the specified value -->
+
+<xsl:template match="//@conf:eventdataVal">
+ <xsl:attribute name="cond">_event.data == <xsl:value-of select="."/></xsl:attribute>
+</xsl:template>
+
+<!-- test that _event.data is set to the value specified by <conf:someInlineVal> -->
+<xsl:template match="//@conf:eventdataSomeVal">
+ <xsl:attribute name="cond">_event.data == 123</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:emptyEventData">
+ <xsl:attribute name="cond">!(_event.data)</xsl:attribute>
+</xsl:template>
+
+<!-- return true if the _name system var has the specified quoted value -->
+<xsl:template match="//@conf:nameVarVal">
+ <xsl:attribute name="cond">_name == '<xsl:value-of select="."/>'</xsl:attribute>
+</xsl:template>
+
+<!-- return true if first var's value is a prefix of the second var's value. Input has form "n m" where n and m are ints.-->
+<xsl:template match="//@conf:varPrefix">
+ <xsl:attribute name="cond">
+ <xsl:analyze-string select="."
+ regex="(\w+)(\W)(\w+)">
+ <xsl:matching-substring>
+ <!-- the underscore.string.startswith function compressed into one line below:
+ <xsl:text>(function(str, starts){
+ if (starts == '') return true;
+ if (str == null || starts == null) return false;
+ str = String(str); starts = String(starts);
+ return str.length >= starts.length &amp;&amp; str.slice(0, starts.length) == starts;
+ })(</xsl:text>Var<xsl:value-of select="regex-group(3)"/>, Var<xsl:value-of select="regex-group(1)"/><xsl:text>)</xsl:text> -->
+<xsl:text>(function(str, starts){if (starts == '') return true;if (str == null || starts == null) return false;str = String(str); starts = String(starts);return str.length >= starts.length &amp;&amp; str.slice(0, starts.length) == starts;})(</xsl:text>Var<xsl:value-of select="regex-group(3)"/>, Var<xsl:value-of select="regex-group(1)"/><xsl:text>)</xsl:text>
+ </xsl:matching-substring>
+ </xsl:analyze-string>
+ </xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:inState">
+ <xsl:attribute name="cond">_x.states['<xsl:value-of select="."/>']</xsl:attribute>
+</xsl:template>
+
+<!-- returns a value that cannot be converted into a Boolean -->
+<xsl:template match="//@conf:nonBoolean">
+ <xsl:attribute name="cond">return</xsl:attribute>
+</xsl:template>
+
+<!-- true if id has a value -->
+<xsl:template match="//@conf:isBound[//conf:array123]" priority="5">
+ <xsl:attribute name="cond">Var<xsl:value-of select="." />[1]</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:isBound">
+ <xsl:attribute name="cond">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- return true if specified var has been created but is not bound -->
+<xsl:template match="//@conf:unboundVar">
+ <xsl:attribute name="cond">!(Var<xsl:value-of select="." />)</xsl:attribute>
+</xsl:template>
+
+<!-- true if system var has a value -->
+<xsl:template match="//@conf:systemVarIsBound">
+ <xsl:attribute name="cond"><xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- true if id does not have a value -->
+<xsl:template match="//@conf:noValue">
+ <xsl:attribute name="cond">!Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- always returns true -->
+<xsl:template match="//@conf:true">
+ <xsl:attribute name="cond">true</xsl:attribute>
+</xsl:template>
+
+<!-- always returns false -->
+<xsl:template match="//@conf:false">
+ <xsl:attribute name="cond">false</xsl:attribute>
+</xsl:template>
+
+<!-- returns true if all the required fields of _event are bound -->
+<xsl:template match="//@conf:eventFieldsAreBound">
+ <xsl:attribute name="cond">_event.name &amp;&amp; _event.type</xsl:attribute>
+</xsl:template>
+
+<!-- returns true if _event.data contains the specified item -->
+<xsl:template match="//@conf:eventDataHasField">
+ <xsl:attribute name="cond"><xsl:value-of select="."/> in _event.data</xsl:attribute>
+</xsl:template>
+
+<!-- returns true if specified field of _event has no value -->
+<xsl:template match="//@conf:eventFieldHasNoValue">
+ <xsl:attribute name="cond">!(_event.<xsl:value-of select="." />)</xsl:attribute>
+</xsl:template>
+
+<!-- true if the language of _event matches the processor's datamodel -->
+<xsl:template match="//@conf:eventLanguageMatchesDatamodel">
+ <xsl:attribute name="cond"> _event.language == 'promela'</xsl:attribute>
+</xsl:template>
+
+<!-- true if _event was delivered on the specified i/o processor -->
+<xsl:template match="//@conf:originTypeEq">
+ <xsl:attribute name="cond"> _event.origintype == '<xsl:value-of select="."/>'</xsl:attribute>
+</xsl:template>
+
+
+
+
+<!-- scripting -->
+
+<xsl:template match="conf:script">
+ <script xmlns="http://www.w3.org/2005/07/scxml">Var1 = 1</script>
+</xsl:template>
+
+
+<xsl:template match="//@conf:scriptGoodSrc">
+ <xsl:attribute name="src">D:\W3C\SCXMLTests\test300.js</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:scriptBadSrc">
+ <xsl:attribute name="src">D:\foo</xsl:attribute>
+</xsl:template>
+
+<!-- sends an event back to the sender of the current event -->
+<xsl:template match="conf:sendToSender">
+ <send xmlns="http://www.w3.org/2005/07/scxml">
+ <xsl:attribute name="event"><xsl:value-of select="@name" /></xsl:attribute>
+ <xsl:attribute name="targetexpr">_event.origin</xsl:attribute>
+ <xsl:attribute name="typeexpr">_event.origintype</xsl:attribute>
+ </send>
+</xsl:template>
+
+<!-- foreach -->
+<!-- this should produce an array containing 1 2 3 in that order -->
+<xsl:template match="//conf:array123">
+ Var<xsl:value-of select="../@conf:id" />[0] = 1;
+ Var<xsl:value-of select="../@conf:id" />[1] = 2;
+ Var<xsl:value-of select="../@conf:id" />[2] = 3;
+</xsl:template>
+
+<!-- this uses the value of the indicated variable as the 'array' attribute -->
+<xsl:template match="//@conf:arrayVar">
+ <xsl:attribute name="array">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- in Python, this is the same as arrayVar -->
+<xsl:template match="//@conf:arrayTextVar">
+ <xsl:attribute name="array">Var<xsl:value-of select="."/></xsl:attribute>
+</xsl:template>
+
+
+<!-- this should produce expr that yields an array containing 1 2 3 in that order -->
+<xsl:template match="//@conf:arrayExpr123">
+ <xsl:attribute name="expr">1, 2, 3]</xsl:attribute>
+</xsl:template>
+
+<!-- this should yield an expr that evaluates to something that is not a valid array -->
+<xsl:template match="//@conf:illegalArray">
+ <xsl:attribute name="expr">7</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:item">
+ <xsl:attribute name="item">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- this should return something that cannot be an variable name -->
+<xsl:template match="//@conf:illegalItem">
+ <xsl:attribute name="item">'continue'</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:index">
+ <xsl:attribute name="index">Var<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- this should add an extra item onto the end of the specified array, which
+is of the same type as array123 -->
+<xsl:template match="conf:extendArray">
+ <assign xmlns="http://www.w3.org/2005/07/scxml">
+ <xsl:attribute name="location">Var<xsl:value-of select="@id"/></xsl:attribute>
+ <xsl:attribute name="expr">[].concat(Var<xsl:value-of select="@id"/>, [4])</xsl:attribute>
+ </assign>
+ </xsl:template>
+
+<!-- this should create a multidimensional array all of whose cells are set to the specified value. Not
+currently used for any tests -->
+<xsl:template match="//@conf:multiDimensionalArrayExpr">
+ <xsl:attribute name="expr">[[<xsl:value-of select="."/>,<xsl:value-of select="."/>],[<xsl:value-of select="."/>,<xsl:value-of select="."/>]]</xsl:attribute>
+</xsl:template>
+
+
+<!-- this should create a <foreach> statement that increments the values of the specified array. Not
+currently used for any tests -->
+<xsl:template match="conf:incrementArray">
+ <xsl:variable name="targetArray">Var<xsl:value-of select="@id"/></xsl:variable>
+<foreach xmlns="http://www.w3.org/2005/07/scxml">
+ <xsl:attribute name="item">item</xsl:attribute>
+ <xsl:attribute name="index">index</xsl:attribute>
+ <xsl:attribute name="array"><xsl:value-of select="$targetArray"/></xsl:attribute>
+<script>
+<xsl:value-of select="$targetArray"/>[index][0] = <xsl:value-of select="$targetArray"/>[index][0] + 1
+<xsl:value-of select="$targetArray"/>[index][1] = <xsl:value-of select="$targetArray"/>[index][1] + 1
+</script>
+</foreach>
+</xsl:template>
+<!-- this should return true iff each cell in the specified multidimensional array has the specified value. Not
+currently used for any tests -->
+<xsl:template match="//@conf:arrayVal">
+ <xsl:attribute name="cond">
+ <xsl:analyze-string select="."
+ regex="([0-9]+)(\W+)(.*)">
+ <xsl:matching-substring>
+ <xsl:variable name="targetArray">Var<xsl:value-of select="regex-group(1)"/></xsl:variable>
+ <xsl:variable name="value"><xsl:value-of select="regex-group(3)"/></xsl:variable>
+<xsl:value-of select="$targetArray"/>[0][0]== <xsl:value-of select="$value"/> &amp;&amp; <xsl:value-of select="$targetArray"/>[0][1] == <xsl:value-of select="$value"/> &amp;&amp; <xsl:value-of select="$targetArray"/>[1][0] == <xsl:value-of select="$value"/> &amp;&amp; <xsl:value-of select="$targetArray"/>[1][1] == <xsl:value-of select="$value"/>
+</xsl:matching-substring>
+
+ </xsl:analyze-string>
+ </xsl:attribute>
+</xsl:template>
+
+<!-- SITE SPECIFIC INFORMATION FOR BASIC HTTP EVENT I/O PROCESSOR
+This template must be edited by each site that expects to test the Basic HTTP Event I/O
+processor. Other templates for the Basic HTTP Event I/O tests are below it -->
+
+<xsl:template match="//@conf:testOnServer">
+ <xsl:attribute name="target">SITE_SPECIFIC_ADDRESS<xsl:value-of select="." /></xsl:attribute>
+</xsl:template>
+
+<!-- use this template to import or set up anything you need for the code in
+the basic http tests. In the case of python, we have to import the regexp module.-->
+<xsl:template match="conf:setUpHTTPTest">
+<!-- <script xmlns="http://www.w3.org/2005/07/scxml">import re</script> -->
+</xsl:template>
+
+<!-- return an expression evaluating to the basic http access URI -->
+<xsl:template match="//@conf:basicHTTPAccessURI">
+ <xsl:attribute name="expr">_ioprocessors.basichttp.location</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:basicHTTPAccessURITarget">
+ <xsl:attribute name="targetexpr">_ioprocessors.basichttp.location</xsl:attribute>
+</xsl:template>
+
+<!-- generate an cond that evaluates to true if POST was used to send the message -->
+<xsl:template match="//@conf:methodIsPost">
+ <xsl:attribute name="cond">_event.raw.search('POST') !== -1</xsl:attribute>
+</xsl:template>
+
+<!-- generate a namelist attribute containing all the ids listed in the attribute's value -->
+<xsl:template match="//@conf:multipleNamelist">
+ <xsl:attribute name="namelist">
+ <xsl:analyze-string select="." regex="([0-9]+)">
+<xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/><xsl:text>&#xa;</xsl:text></xsl:matching-substring>
+</xsl:analyze-string>
+</xsl:attribute>
+</xsl:template>
+
+<!-- generate a cond that evaluates to true if the event is external -->
+<xsl:template match="//@conf:eventIsExternal">
+ <xsl:attribute name="cond">_event.type == 'external'</xsl:attribute>
+</xsl:template>
+
+<!-- returns true if _event/raw contains the var with the specified value -->
+<xsl:template match="//@conf:eventIdParamHasValue">
+ <xsl:attribute name="cond"><xsl:analyze-string select="." regex="(\S+)(\s+)(\S+)">
+<xsl:matching-substring>_event.raw.search(/Var<xsl:value-of select="regex-group(1)"/>=<xsl:value-of select="regex-group(3)"/>/) !== -1</xsl:matching-substring></xsl:analyze-string></xsl:attribute>
+</xsl:template>
+
+<!-- returns true if _event/raw contains the param with the specified value -->
+<xsl:template match="//@conf:eventNamedParamHasValue">
+ <xsl:attribute name="cond"><xsl:analyze-string select="." regex="(\S+)(\s+)(\S+)">
+ <xsl:matching-substring>_event.raw.search('<xsl:value-of select="regex-group(1)"/>=<xsl:value-of select="regex-group(3)"/>') !== -1</xsl:matching-substring></xsl:analyze-string></xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:messageBodyEquals">
+ <xsl:attribute name="cond">_event.raw.search(/<xsl:value-of select="."/>/) !== -1</xsl:attribute>
+</xsl:template>
+
+
+<!-- the following templates produce an expr that extracts the relevant item from _event.raw -->
+<xsl:template match="//@conf:getNamedParamVal">
+ <xsl:attribute name="expr">_event.raw.match(/<xsl:value-of select="."/>=(\S+)$/)[1]</xsl:attribute>
+</xsl:template>
+
+<!-- if input is 1, find param Var1, etc. -->
+<xsl:template match="//@conf:getIDParamVal">
+ <xsl:attribute name="expr">_event.raw.match(/Var<xsl:value-of select="."/>=(\S+)$/)[1]</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:getNthParamName">
+ <xsl:attribute name="expr">txt.match(/\n\n(.*)/)[2].split('&amp;')[<xsl:value-of select="."/>].split('=')[0]</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="//@conf:getNthParamVal">
+ <xsl:attribute name="expr">txt.match(/\n\n(.*)/)[2].split('&amp;')[<xsl:value-of select="."/>].split('=')[1]</xsl:attribute>
+</xsl:template>
+
+<!-- this should produce an 'expr' that evaluates to a valid SCXML Message structure -->
+<xsl:template match="//@conf:scxmlEventExpr">
+ <xsl:attribute name="expr">'&lt;message source="' + _ioprocessors['basichttp'] + '"'
++ 'xmlns:scxml="http://www.w3.org/2005/07/scxml" version="1.0" xmlns:xsi=:http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://www.w3.org/2005/07/scxml scxml-message.xsd" sourcetype=:scxml"'
++' 'name="name"' + '"' + <xsl:value-of select="."/> + '"' + /&gt;'</xsl:attribute>
+ </xsl:template>
+
+<!-- this should produce a <content> tag containing material to use as the message body. This
+content must include the address, so the far side can send a response back to us -->
+<xsl:template match="conf:msgContent">
+<content xmlns="http://www.w3.org/2005/07/scxml">
+ <xsl:attribute name="expr">'address=' + _ioprocessors['basichttp'] + "'"</xsl:attribute>
+ </content>
+</xsl:template>
+
+<!-- this should produce a test on _event.raw that checks whether the body matches the
+expression defined in the previous template. This may need to be tightened up because
+it allows anything after the = -->
+<xsl:template match="//@conf:msgIsBody">
+ <xsl:attribute name="cond">_event.raw.match(/\n\naddress=(.*)$/)</xsl:attribute>
+</xsl:template>
+</xsl:stylesheet> \ No newline at end of file
diff --git a/test/w3c/convert-tests.sh b/test/w3c/convert-tests.sh
index ea624ea..48aa452 100755
--- a/test/w3c/convert-tests.sh
+++ b/test/w3c/convert-tests.sh
@@ -5,26 +5,37 @@ cd $DIR
TXMLS=`ls txml/*.txml`
# see http://saxon.sourceforge.net/saxon6.5.1/using-xsl.html
-for TXML in $TXMLS
-do
- DEST=ecma/`basename $TXML .txml`.scxml
- echo "Processing $TXML to $DEST"
- java -jar /Users/sradomski/Developer/Applications/SaxonHE9-4-0-7J/saxon9he.jar $TXML confEcma.xsl -o:$DEST
-done
+# for TXML in $TXMLS
+# do
+# DEST=ecma/`basename $TXML .txml`.scxml
+# echo "Processing $TXML to $DEST"
+# java -jar /Users/sradomski/Developer/Applications/SaxonHE9-4-0-7J/saxon9he.jar $TXML confEcma.xsl -o:$DEST
+# done
+#
+# for TXML in $TXMLS
+# do
+# DEST=xpath/`basename $TXML .txml`.scxml
+# echo "Processing $TXML to $DEST"
+# java -jar /Users/sradomski/Developer/Applications/SaxonHE9-4-0-7J/saxon9he.jar $TXML confXPath.xsl -o:$DEST
+# done
for TXML in $TXMLS
do
- DEST=xpath/`basename $TXML .txml`.scxml
+ DEST=promela/`basename $TXML .txml`.scxml
echo "Processing $TXML to $DEST"
- java -jar /Users/sradomski/Developer/Applications/SaxonHE9-4-0-7J/saxon9he.jar $TXML confXPath.xsl -o:$DEST
+ java -jar /Users/sradomski/Developer/Applications/SaxonHE9-4-0-7J/saxon9he.jar $TXML confPromela.xsl -o:$DEST
done
cp txml/*.txt ecma/
cp txml/*.txt xpath/
+cp txml/*.txt promela/
-find ./ecma -type f -exec grep -Ili 'datamodel="xpath"' {} \; |xargs rm -fv
-find ./xpath -type f -exec grep -Ili 'datamodel="ecmascript"' {} \; |xargs rm -fv
+# find ./ecma -type f -exec grep -Ili 'datamodel="xpath"' {} \; |xargs rm -fv
+# find ./xpath -type f -exec grep -Ili 'datamodel="ecmascript"' {} \; |xargs rm -fv
+find ./promela -type f -exec grep -Ili 'datamodel="xpath"' {} \; |xargs rm -fv
+find ./promela -type f -exec grep -Ili 'datamodel="ecmascript"' {} \; |xargs rm -fv
+# format all SCXML files
SCXMLS=`find . -type f -name '*.scxml'`
for SCXML in $SCXMLS
do
diff --git a/test/w3c/draft/calc.scxml b/test/w3c/draft/calc.scxml
deleted file mode 100644
index bc6db8b..0000000
--- a/test/w3c/draft/calc.scxml
+++ /dev/null
@@ -1,157 +0,0 @@
-<?xml version="1.0"?>
-<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="on" datamodel="ecmascript" name="calc">
- <datamodel>
- <data id="long_expr"/>
- <data id="short_expr" expr="0"/>
- <data id="res"/>
- </datamodel>
- <state id="wrapper" initial="on">
- <state id="on" initial="ready">
- <onentry>
- <send event="DISPLAY.UPDATE"/>
- </onentry>
- <state id="ready" initial="begin">
- <state id="begin">
- <transition event="OPER.MINUS" target="negated1"/>
- <onentry>
- <send event="DISPLAY.UPDATE"/>
- </onentry>
- </state>
- <state id="result">
- </state>
- <transition event="OPER" target="opEntered"/>
- <transition event="DIGIT.0" target="zero1">
- <assign location="short_expr" expr="''"/>
- </transition>
- <transition event="DIGIT" target="int1">
- <assign location="short_expr" expr="''"/>
- </transition>
- <transition event="POINT" target="frac1">
- <assign location="short_expr" expr="''"/>
- </transition>
- </state>
- <state id="negated1">
- <onentry>
- <assign location="short_expr" expr="'-'"/>
- <send event="DISPLAY.UPDATE"/>
- </onentry>
- <transition event="DIGIT.0" target="zero1"/>
- <transition event="DIGIT" target="int1"/>
- <transition event="POINT" target="frac1"/>
- </state>
- <state id="operand1">
- <state id="zero1">
- <transition event="DIGIT" cond="_event.name != 'DIGIT.0'" target="int1"/>
- <transition event="POINT" target="frac1"/>
- </state>
- <state id="int1">
- <transition event="POINT" target="frac1"/>
- <transition event="DIGIT">
- <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)"/>
- <send event="DISPLAY.UPDATE"/>
- </transition>
- <onentry>
- <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)"/>
- <send event="DISPLAY.UPDATE"/>
- </onentry>
- </state>
- <state id="frac1">
- <onentry>
- <assign location="short_expr" expr="short_expr+'.'"/>
- <send event="DISPLAY.UPDATE"/>
- </onentry>
- <transition event="DIGIT">
- <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)"/>
- <send event="DISPLAY.UPDATE"/>
- </transition>
- </state>
- <transition event="OPER" target="opEntered"/>
- </state>
- <state id="opEntered">
- <transition event="OPER.MINUS" target="negated2"/>
- <transition event="POINT" target="frac2"/>
- <transition event="DIGIT.0" target="zero2"/>
- <transition event="DIGIT" target="int2"/>
- <onentry>
- <raise event="CALC.SUB"/>
- <send target="_internal" event="OP.INSERT">
- <param name="operator" expr="_event.name"/>
- </send>
- </onentry>
- </state>
- <state id="negated2">
- <onentry>
- <assign location="short_expr" expr="'-'"/>
- <send event="DISPLAY.UPDATE"/>
- </onentry>
- <transition event="DIGIT.0" target="zero2"/>
- <transition event="DIGIT" target="int2"/>
- <transition event="POINT" target="frac2"/>
- </state>
- <state id="operand2">
- <state id="zero2">
- <transition event="DIGIT" cond="_event.name != 'DIGIT.0'" target="int2"/>
- <transition event="POINT" target="frac2"/>
- </state>
- <state id="int2">
- <transition event="DIGIT">
- <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)"/>
- <send event="DISPLAY.UPDATE"/>
- </transition>
- <onentry>
- <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)"/>
- <send event="DISPLAY.UPDATE"/>
- </onentry>
- <transition event="POINT" target="frac2"/>
- </state>
- <state id="frac2">
- <onentry>
- <assign location="short_expr" expr="short_expr +'.'"/>
- <send event="DISPLAY.UPDATE"/>
- </onentry>
- <transition event="DIGIT">
- <assign location="short_expr" expr="short_expr +_event.name.substr(_event.name.lastIndexOf('.')+1)"/>
- <send event="DISPLAY.UPDATE"/>
- </transition>
- </state>
- <transition event="OPER" target="opEntered">
- <raise event="CALC.SUB"/>
- <raise event="OP.INSERT"/>
- </transition>
- <transition event="EQUALS" target="result">
- <raise event="CALC.SUB"/>
- <raise event="CALC.DO"/>
- </transition>
- </state>
- <transition event="C" target="on"/>
- </state>
- <transition event="CALC.DO">
- <assign location="short_expr" expr="''+ res"/>
- <assign location="long_expr" expr="''"/>
- <assign location="res" expr="0"/>
- </transition>
- <transition event="CALC.SUB">
- <if cond="short_expr!=''">
- <assign location="long_expr" expr="long_expr+'('+short_expr+')'"/>
- </if>
- <assign location="res" expr="eval(long_expr)"/>
- <assign location="short_expr" expr="''"/>
- <send event="DISPLAY.UPDATE"/>
- </transition>
- <transition event="DISPLAY.UPDATE">
- <!--log level="0" label="'result'" expr=".short_expr==''?res:short_expr" / -->
- </transition>
- <transition event="OP.INSERT">
- <log level="0" expr="_event.data[0]"/>
- <if cond="_event.data[0] == 'OPER.PLUS'">
- <assign location="long_expr" expr="long_expr+'+'"/>
- <elseif cond="_event.data[0]=='OPER.MINUS'"/>
- <assign location="long_expr" expr="long_expr+'-'"/>
- <elseif cond="_event.data[0]=='OPER.STAR'"/>
- <assign location="long_expr" expr="long_expr+'*'"/>
- <elseif cond="_event.data[0]=='OPER.DIV'"/>
- <assign location="long_expr" expr="long_expr+'/'"/>
- </if>
- </transition>
- </state>
-</scxml>
diff --git a/test/w3c/ecma/test403c.scxml b/test/w3c/ecma/test403c.scxml
index 8bb126d..f583851 100644
--- a/test/w3c/ecma/test403c.scxml
+++ b/test/w3c/ecma/test403c.scxml
@@ -17,20 +17,20 @@
<transition event="event2"/>
</state>
<state id="p0s2">
- <transition event="event1" target="p0s1">
+ <transition event="event1" target="p0s1" this="1">
<raise event="event2"/>
</transition>
</state>
<state id="p0s3">
<!-- this transition should be blocked by the one in p0s2-->
- <transition event="event1" target="fail"/>
+ <transition event="event1" target="fail" this="2"/>
<!-- this transition will preempt the one that p0s2 inherits
from an ancestor -->
<transition event="event2" target="s1"/>
</state>
<state id="p0s4">
<!-- this transition never gets preempted, should fire twice -->
- <transition event="*">
+ <transition event="*" this="3">
<assign location="Var1" expr="Var1 + 1"/>
</transition>
</state>
diff --git a/test/w3c/promela/robots.txt b/test/w3c/promela/robots.txt
new file mode 100644
index 0000000..9be2782
--- /dev/null
+++ b/test/w3c/promela/robots.txt
@@ -0,0 +1,96 @@
+#
+# robots.txt for http://www.w3.org/
+#
+# $Id: robots.txt,v 1.67 2014-06-25 13:06:01 ddavis Exp $
+#
+
+# For use by search.w3.org
+User-agent: W3C-gsa
+Disallow: /Out-Of-Date
+
+User-agent: W3T_SE
+Disallow: /Out-Of-Date
+
+User-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT; MS Search 4.0 Robot)
+Disallow: /
+
+# W3C Link checker
+User-agent: W3C-checklink
+Disallow:
+
+# the following settings apply to all bots
+User-agent: *
+# Blogs - WordPress
+# https://codex.wordpress.org/Search_Engine_Optimization_for_WordPress#Robots.txt_Optimization
+Disallow: /*/wp-admin/
+Disallow: /*/wp-includes/
+Disallow: /*/wp-content/plugins/
+Disallow: /*/wp-content/cache/
+Disallow: /*/wp-content/themes/
+Disallow: /blog/*/trackback/
+Disallow: /blog/*/feed/
+Disallow: /blog/*/comments/
+Disallow: /blog/*/category/*/*
+Disallow: /blog/*/*/trackback/
+Disallow: /blog/*/*/feed/
+Disallow: /blog/*/*/comments/
+Disallow: /blog/*/*?
+Disallow: /community/trackback/
+Disallow: /community/feed/
+Disallow: /community/comments/
+Disallow: /community/category/*/*
+Disallow: /community/*/trackback/
+Disallow: /community/*/feed/
+Disallow: /community/*/comments/
+Disallow: /community/*/category/*/*
+Disallow: /community/*?
+Disallow: /Consortium/Offices/trackback/
+Disallow: /Consortium/Offices/feed/
+Disallow: /Consortium/Offices/comments/
+Disallow: /Consortium/Offices/category/*/*
+Disallow: /Consortium/Offices/*/trackback/
+Disallow: /Consortium/Offices/*/feed/
+Disallow: /Consortium/Offices/*/comments/
+Disallow: /Consortium/Offices/*?
+# Wikis - Mediawiki
+# https://www.mediawiki.org/wiki/Manual:Robots.txt
+Disallow: /wiki/index.php?
+Disallow: /wiki/index.php/Help
+Disallow: /wiki/index.php/MediaWiki
+Disallow: /wiki/index.php/Special:
+Disallow: /wiki/index.php/Template
+Disallow: /wiki/skins/
+Disallow: /*/wiki/index.php?
+Disallow: /*/wiki/index.php/Help
+Disallow: /*/wiki/index.php/MediaWiki
+Disallow: /*/wiki/index.php/Special:
+Disallow: /*/wiki/index.php/Template
+# various other access-controlled or expensive areas
+Disallow: /2004/ontaria/basic
+Disallow: /Team/
+Disallow: /Project
+Disallow: /Web
+Disallow: /Systems
+Disallow: /History
+Disallow: /Out-Of-Date
+Disallow: /2002/02/mid
+Disallow: /mid/
+Disallow: /2005/06/blog/
+Disallow: /2004/08/W3CTalks
+Disallow: /2007/11/Talks/search
+Disallow: /People/all/
+Disallow: /RDF/Validator/ARPServlet
+Disallow: /2003/03/Translations/byLanguage
+Disallow: /2003/03/Translations/byTechnology
+Disallow: /2005/11/Translations/Query
+Disallow: /2000/06/webdata/xslt
+Disallow: /2000/09/webdata/xslt
+Disallow: /2005/08/online_xslt/xslt
+Disallow: /Bugs/
+Disallow: /Search/Mail/Public/
+Disallow: /2006/02/chartergen
+Disallow: /2004/01/pp-impl
+Disallow: /Consortium/supporters
+Disallow: /2007/08/pyRdfa/
+Disallow: /WAI/PF/comments/
+Disallow: /participate/conferences.xml
diff --git a/test/w3c/promela/test144.scxml b/test/w3c/promela/test144.scxml
new file mode 100644
index 0000000..18055c4
--- /dev/null
+++ b/test/w3c/promela/test144.scxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that events are inserted into the queue in the order in which they are raised. If
+foo occurs before bar, success, otherwise failure -->
+<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">
+ <state id="s0">
+ <onentry>
+ <raise event="foo"/>
+ <raise event="bar"/>
+ </onentry>
+ <transition event="foo" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition event="bar" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test147.scxml b/test/w3c/promela/test147.scxml
new file mode 100644
index 0000000..de4e35e
--- /dev/null
+++ b/test/w3c/promela/test147.scxml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the first clause that evaluates to true - and only that clause - is executed.
+Only one event should be raised, and it should be bar -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <if cond="false">
+ <raise event="foo"/>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ <elseif cond="true"/>
+ <raise event="bar"/>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ <else/>
+ <raise event="baz"/>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </if>
+ <raise event="bat"/>
+ </onentry>
+ <transition event="bar" cond="Var1==1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test148.scxml b/test/w3c/promela/test148.scxml
new file mode 100644
index 0000000..fafb41a
--- /dev/null
+++ b/test/w3c/promela/test148.scxml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the else clause executes if <if> and <elseif> evaluate to false.
+Baz should be the only event generated by the <if>. bat is raised to catch the case where the <else> clause
+fails and baz is not generated, i.e. it makes sure that the test doesn't hang. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <if cond="false">
+ <raise event="foo"/>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ <elseif cond="false"/>
+ <raise event="bar"/>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ <else/>
+ <raise event="baz"/>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </if>
+ <raise event="bat"/>
+ </onentry>
+ <transition event="baz" cond="Var1==1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test149.scxml b/test/w3c/promela/test149.scxml
new file mode 100644
index 0000000..a11083e
--- /dev/null
+++ b/test/w3c/promela/test149.scxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that neither if clause executes, so that bat is the only event raised. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <if cond="false">
+ <raise event="foo"/>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ <elseif cond="false"/>
+ <raise event="bar"/>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </if>
+ <raise event="bat"/>
+ </onentry>
+ <transition event="bat" cond="Var1==0" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test150.scxml b/test/w3c/promela/test150.scxml
new file mode 100644
index 0000000..7e4ca52
--- /dev/null
+++ b/test/w3c/promela/test150.scxml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that foreach causes a new variable to be declared if 'item' doesn't already exist. Also
+test that it will use an existing var if it does exist. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ <data id="Var2" type="int"/>
+ <data id="Var3" type="int[3]">
+
+ Var3[0] = 1;
+ Var3[1] = 2;
+ Var3[2] = 3;
+
+ </data>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <!-- first use declared variables -->
+ <foreach item="Var1" index="Var2" array="Var3"/>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error" target="fail"/>
+ <transition event="*" target="s1"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <!-- now use undeclared variables -->
+ <foreach item="Var4" index="Var5" array="Var3"/>
+ <raise event="bar"/>
+ </onentry>
+ <transition event="error" target="fail"/>
+ <transition event="*" target="s2"/>
+ </state>
+ <state id="s2">
+ <!-- check that var4 is bound -->
+ <transition cond="Var4" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test151.scxml b/test/w3c/promela/test151.scxml
new file mode 100644
index 0000000..ef380c9
--- /dev/null
+++ b/test/w3c/promela/test151.scxml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that foreach causes a new variable to be declared if 'item' doesn't already exist. Also
+test that it will use an existing var if it does exist. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ <data id="Var2" type="int"/>
+ <data id="Var3" type="int[3]">
+
+ Var3[0] = 1;
+ Var3[1] = 2;
+ Var3[2] = 3;
+
+ </data>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <!-- first use declared variables -->
+ <foreach item="Var1" index="Var2" array="Var3"/>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error" target="fail"/>
+ <transition event="*" target="s1"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <!-- now use undeclared variables -->
+ <foreach item="Var4" index="Var5" array="Var3"/>
+ <raise event="bar"/>
+ </onentry>
+ <transition event="error" target="fail"/>
+ <transition event="*" target="s2"/>
+ </state>
+ <state id="s2">
+ <!-- check that var5 is bound -->
+ <transition cond="Var5" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test152.scxml b/test/w3c/promela/test152.scxml
new file mode 100644
index 0000000..2fd3abe
--- /dev/null
+++ b/test/w3c/promela/test152.scxml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that an illegal array or item value causes error.execution and results in executable content
+not being executed. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ <data id="Var2" type="int"/>
+ <data id="Var3" type="int"/>
+ <data id="Var4" type="int" expr="7"/>
+ <data id="Var5" type="int[3]">
+
+ Var5[0] = 1;
+ Var5[1] = 2;
+ Var5[2] = 3;
+
+ </data>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <!-- invalid array, legal item -->
+ <foreach item="Var2" index="Var3" array="Var4">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </foreach>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error.execution" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <!-- illegal item, legal array -->
+ <foreach item="'continue'" index="Var3" array="Var5">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </foreach>
+ <raise event="bar"/>
+ </onentry>
+ <transition event="error.execution" target="s2"/>
+ <transition event="bar" target="fail"/>
+ </state>
+ <state id="s2">
+ <!-- check that var1 has its original value (so executable content never got executed -->
+ <transition cond="Var1==0" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test153.scxml b/test/w3c/promela/test153.scxml
new file mode 100644
index 0000000..4721606
--- /dev/null
+++ b/test/w3c/promela/test153.scxml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that foreach goes over the array in the right order. since the array contains 1 2 3, we compare the current
+value with the previous value, which is stored in var1. The current value should always be larger. If
+it ever isn't, set Var4 to 0, indicating failure -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ <!-- contains the previous value -->
+ <data id="Var2" type="int"/>
+ <!-- the item which will contain the current value -->
+ <data id="Var3" type="int[3]">
+
+ Var3[0] = 1;
+ Var3[1] = 2;
+ Var3[2] = 3;
+
+ </data>
+ <data id="Var4" type="int" expr="1"/>
+ <!-- 1 if success, 0 if failure -->
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <foreach item="Var2" array="Var3">
+ <if cond="Var1&lt;Var2">
+ <assign location="Var1" expr="Var2"/>
+ <else/>
+ <!-- values are out of order, record failure -->
+ <assign location="Var4" expr="0"/>
+ </if>
+ </foreach>
+ </onentry>
+ <!-- check that var1 has its original value -->
+ <transition cond="Var4==0" target="fail"/>
+ <transition target="pass"/>
+ </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/promela/test155.scxml b/test/w3c/promela/test155.scxml
new file mode 100644
index 0000000..ec76992
--- /dev/null
+++ b/test/w3c/promela/test155.scxml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that foreach executes the executable content once for each item in the list '(1,2,3)'. The executable
+content sums the items into var1 so it should be 6 at the end -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ <data id="Var2" type="int"/>
+ <data id="Var3" type="int[3]">
+
+ Var3[0] = 1;
+ Var3[1] = 2;
+ Var3[2] = 3;
+
+ </data>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <foreach item="Var2" array="Var3">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + Var2"/>
+ </foreach>
+ </onentry>
+ <transition cond="Var1==6" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test156.scxml b/test/w3c/promela/test156.scxml
new file mode 100644
index 0000000..b07d289
--- /dev/null
+++ b/test/w3c/promela/test156.scxml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that an error causes the foreach to stop execution. The second piece of executable content
+should cause an error, so var1 should be incremented only once -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ <data id="Var2" type="int"/>
+ <data id="Var3" type="int[3]">
+
+ Var3[0] = 1;
+ Var3[1] = 2;
+ Var3[2] = 3;
+
+ </data>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <foreach item="Var2" array="Var3">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ <!-- assign an illegal value to a non-existent var -->
+ <assign location="Var5" expr="return"/>
+ </foreach>
+ </onentry>
+ <transition cond="Var1==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test158.scxml b/test/w3c/promela/test158.scxml
new file mode 100644
index 0000000..d921652
--- /dev/null
+++ b/test/w3c/promela/test158.scxml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that executable content executes in document order. if event1 occurs then event2, succeed, otherwise fail -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <raise event="event1"/>
+ <raise event="event2"/>
+ </onentry>
+ <transition event="event1" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition event="event2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test159.scxml b/test/w3c/promela/test159.scxml
new file mode 100644
index 0000000..f59d1f9
--- /dev/null
+++ b/test/w3c/promela/test159.scxml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that any error raised by an element of executable content causes all subsequent elements to be skipped.
+The send tag will raise an error so var1 should not be incremented. If it is fail, otherwise succeed -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="thisWillFail" target="baz"/>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onentry>
+ <transition cond="Var1==1" target="fail"/>
+ <transition target="pass"/>
+ </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/promela/test172.scxml b/test/w3c/promela/test172.scxml
new file mode 100644
index 0000000..bd99e91
--- /dev/null
+++ b/test/w3c/promela/test172.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that eventexpr uses the current value of var1, not its initial value -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="string" expr="'event1'"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1" expr="'event2'"/>
+ <send eventexpr="Var1"/>
+ </onentry>
+ <transition event="event2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test173.scxml b/test/w3c/promela/test173.scxml
new file mode 100644
index 0000000..cb3728e
--- /dev/null
+++ b/test/w3c/promela/test173.scxml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that targetexpr uses the current value of var1, not its initial value
+(If it uses the initial value, it will generate an error. If it uses the current value, event1 will be raised -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="27"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1" expr="'#_internal'"/>
+ <send targetexpr="Var1" event="event1"/>
+ </onentry>
+ <transition event="event1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test174.scxml b/test/w3c/promela/test174.scxml
new file mode 100644
index 0000000..1e44370
--- /dev/null
+++ b/test/w3c/promela/test174.scxml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that typeexpr uses the current value of var1, not its initial value
+(If it uses the initial value, it will generate an error. If it uses the current value, event1 will be raised -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int" expr="27"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1" expr="'http://www.w3.org/TR/scxml/#SCXMLEventProcessor'"/>
+ <send typeexpr="Var1" event="event1"/>
+ </onentry>
+ <transition event="event1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test175.scxml b/test/w3c/promela/test175.scxml
new file mode 100644
index 0000000..9cd732f
--- /dev/null
+++ b/test/w3c/promela/test175.scxml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that delayexpr uses the current value of var1, not its initial value
+(If it uses the initial value, event2 will be generated first, before event1. If it uses the current value,
+event1 will be raised first. Succeed if event1 occurs before event2, otherwise fail -->
+<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">
+ <datamodel>
+ <data id="Var1" type="string" expr="'0s'"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1" expr="'1s'"/>
+ <send delayexpr="Var1" event="event2"/>
+ <send delayexpr="'.5s'" event="event1"/>
+ </onentry>
+ <transition event="event1" target="s1"/>
+ <transition event="event2" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition event="event2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test176.scxml b/test/w3c/promela/test176.scxml
new file mode 100644
index 0000000..d79b32e
--- /dev/null
+++ b/test/w3c/promela/test176.scxml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that <param> uses the current value of var1, not its initial value. If the value of
+aParam in event1 is 2 so that var2 gets set to 2, success, otherwise failure -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ <data id="Var2" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1" expr="2"/>
+ <send event="event1">
+ <param name="aParam" expr="Var1"/>
+ </send>
+ </onentry>
+ <transition event="event1" target="s1">
+ <assign location="Var2" expr="_event.data.aParam"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var2==2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test178.scxml b/test/w3c/promela/test178.scxml
new file mode 100644
index 0000000..5256cd3
--- /dev/null
+++ b/test/w3c/promela/test178.scxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that multiple key/value pairs are included, even when the keys are the same.
+This is a manual test. The tester must look at the log output and verify that both
+keys are there. (This test uses the SCXML Event I/O processor, which is the only
+one that all platforms must support. It does not specify the message format, so
+we cannot test _event.raw directly. Therefore we print it out for visual
+inspection.) -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="event1">
+ <param name="Var1" expr="2"/>
+ <param name="Var1" expr="3"/>
+ </send>
+ </onentry>
+ <transition event="event1" target="final">
+ <log label="_event " expr="_event.raw"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <final id="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/promela/test179.scxml b/test/w3c/promela/test179.scxml
new file mode 100644
index 0000000..c81030c
--- /dev/null
+++ b/test/w3c/promela/test179.scxml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that <content> can be used to populate body of a message -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="event1">
+ <content>123</content>
+ </send>
+ </onentry>
+ <transition event="event1" cond="_event.data == 123" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test183.scxml b/test/w3c/promela/test183.scxml
new file mode 100644
index 0000000..53ec8c7
--- /dev/null
+++ b/test/w3c/promela/test183.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that <send> stores the value of the sendid in idlocation. If it does,
+var1 has a value and we pass. Otherwise we fail -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="event1" idlocation="Var1"/>
+ </onentry>
+ <transition cond="Var1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test185.scxml b/test/w3c/promela/test185.scxml
new file mode 100644
index 0000000..8cb877c
--- /dev/null
+++ b/test/w3c/promela/test185.scxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that <send> respects the delay specification. If it does, event1 arrives before event2
+ and we pass. Otherwise we fail -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="event2" delayexpr="'1s'"/>
+ <send event="event1"/>
+ </onentry>
+ <transition event="event1" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition event="event2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test186.scxml b/test/w3c/promela/test186.scxml
new file mode 100644
index 0000000..d8c30ea
--- /dev/null
+++ b/test/w3c/promela/test186.scxml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that <send> evals its args when it is evaluated, not when the delay interval expires and the
+message is actually sent. If it does, aParam will have the value of 1 (even though var1 has been incremented
+in the interval.) If var2 ends up == 1, we pass. Otherwise we fail -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ <data id="Var2" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="event1" delayexpr="'1s'">
+ <param name="aParam" expr="Var1"/>
+ </send>
+ <assign location="Var1" expr="2"/>
+ </onentry>
+ <transition event="event1" target="s1">
+ <assign location="Var2" expr="_event.data.aParam"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var2==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test187.scxml b/test/w3c/promela/test187.scxml
new file mode 100644
index 0000000..1400694
--- /dev/null
+++ b/test/w3c/promela/test187.scxml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that delayed <send> is not sent if the sending session terminates. In this case,
+a subscript is invoked which sends the event childToParent delayed by 1 second, and then terminates. The
+parent session, should not receive childToParent. If it does, we fail. Otherwise the
+10 sec timer expires and we pass -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delayexpr="'1s'"/>
+ </onentry>
+ <invoke type="scxml">
+ <content>
+ <!-- exit before the delayed send can execute -->
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <state id="sub0">
+ <onentry>
+ <send event="childToParent" target="#_parent" delayexpr="'.5s'"/>
+ </onentry>
+ <transition target="subFinal"/>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="childToParent" target="fail"/>
+ <transition event="timeout" target="pass"/>
+ </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/promela/test189.scxml b/test/w3c/promela/test189.scxml
new file mode 100644
index 0000000..b1bbf2a
--- /dev/null
+++ b/test/w3c/promela/test189.scxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that #_internal as a target of <send> puts the event on the internal queue. If it does,
+event1 will be processed before event2, because event1 is added to the internal queue while event2 is
+added to the external queue (event though event2 is generated first) -->
+<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">
+ <state id="s0">
+ <onentry>
+ <!-- goes to the external queue -->
+ <send event="event2"/>
+ <!-- to the internal queue -->
+ <send event="event1" target="#_internal"/>
+ </onentry>
+ <!-- once we've entered the state, we should check for internal events first -->
+ <transition event="event1" target="pass"/>
+ <transition event="event2" target="fail"/>
+ </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/promela/test190.scxml b/test/w3c/promela/test190.scxml
new file mode 100644
index 0000000..2143e85
--- /dev/null
+++ b/test/w3c/promela/test190.scxml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that #_scxml_sessionid as a target of <send> puts the event on the external queue. If it does,
+event1 will be processed before event2, because event1 is added to the internal queue while event2 is
+added to the external queue (event though event2 is generated first). we have to make sure that event2
+is actually delivered. The delayed <send> makes sure another event is generated (so the test doesn't hang) -->
+<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">
+ <datamodel>
+ <data id="Var1" type="string" expr="'#_scxml_'"/>
+ <data id="Var2" type="string" expr="_sessionid"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + Var2"/>
+ <!-- goes to the external queue -->
+ <send event="event2" targetexpr="Var1"/>
+ <!-- to the internal queue -->
+ <raise event="event1"/>
+ <!-- this should get added to the external queue after event2 -->
+ <send event="timeout"/>
+ </onentry>
+ <!-- once we've entered the state, we should check for internal events first -->
+ <transition event="event1" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <!-- now check that we get event2 and not a timeout -->
+ <state id="s1">
+ <transition event="event2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test191.scxml b/test/w3c/promela/test191.scxml
new file mode 100644
index 0000000..760caf9
--- /dev/null
+++ b/test/w3c/promela/test191.scxml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that #_parent works as a target of <send> . a subscript is invoked and sends the event
+childToParent to its parent session (ths session) using #_parent as the target. If we get this event, we
+pass, otherwise we fail. The timer insures that some event is generated and that the test does not hang. -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="5s"/>
+ </onentry>
+ <invoke type="scxml">
+ <content>
+ <!-- send an event to the parent session using #_parent as the target -->
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <state id="sub0">
+ <onentry>
+ <send event="childToParent" target="#_parent"/>
+ </onentry>
+ <transition target="subFinal"/>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="childToParent" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test192.scxml b/test/w3c/promela/test192.scxml
new file mode 100644
index 0000000..0a50aed
--- /dev/null
+++ b/test/w3c/promela/test192.scxml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that #_invokeid works as a target of <send> . A child script is invoked and sends us
+childToParent once its running. Then we send it the event parentToChild using its invokeid as the target.
+If it receives this event, it sends sends the event eventReceived to its parent session (ths session).
+If we get this event, we pass, otherwise the child script eventually times out sends invoke.done and we fail.
+We also set a timeout in this process to make sure the test doesn't hang -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="5s"/>
+ </onentry>
+ <invoke type="scxml" id="invokedChild">
+ <content>
+ <!-- let the parent session know we're running by sending childToParent, then wait for parentToChild.
+ If we get it, send eventReceived. If we don't we eventually time out -->
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <state id="sub0">
+ <onentry>
+ <send event="childToParent" target="#_parent"/>
+ <send event="timeout" delay="3s"/>
+ </onentry>
+ <transition event="parentToChild" target="subFinal">
+ <send target="#_parent" event="eventReceived"/>
+ </transition>
+ <transition event="timeout" target="subFinal"/>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="timeout" target="fail"/>
+ <transition event="done.invoke" target="fail"/>
+ <state id="s01">
+ <transition event="childToParent" target="s02">
+ <send target="#_invokedChild" event="parentToChild"/>
+ </transition>
+ </state>
+ <state id="s02">
+ <transition event="eventReceived" target="pass"/>
+ </state>
+ </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/promela/test193.scxml b/test/w3c/promela/test193.scxml
new file mode 100644
index 0000000..aa2f297
--- /dev/null
+++ b/test/w3c/promela/test193.scxml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that omitting target and targetexpr of <send> when using the
+SCXML event i/o processor puts the event on the external queue. -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="internal"/>
+ <!-- this should put event1 in the external queue -->
+ <send event="event1" type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor"/>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="event1" target="fail"/>
+ <transition event="internal" target="s1"/>
+ </state>
+ <state id="s1">
+ <transition event="event1" target="pass"/>
+ <transition event="timeout" target="fail"/>
+ </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/promela/test194.scxml b/test/w3c/promela/test194.scxml
new file mode 100644
index 0000000..b9be1a2
--- /dev/null
+++ b/test/w3c/promela/test194.scxml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that specifying an illegal target for <send> causes the event error.execution to be raised. If it does,
+we succeed. Otherwise we eventually timeout and fail. -->
+<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">
+ <state id="s0">
+ <onentry>
+ <!-- should cause an error -->
+ <send target="baz" event="event2"/>
+ <!-- this will get added to the external event queue after the error has been raised -->
+ <send event="timeout"/>
+ </onentry>
+ <!-- once we've entered the state, we should check for internal events first -->
+ <transition event="error.execution" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test198.scxml b/test/w3c/promela/test198.scxml
new file mode 100644
index 0000000..2a45282
--- /dev/null
+++ b/test/w3c/promela/test198.scxml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that if type is not provided <send> uses the scxml event i/o processor. The only way to tell
+what processor was used is to look at the origintype of the resulting event -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="event1"/>
+ <send event="timeout"/>
+ </onentry>
+ <transition event="event1" cond=" _event.origintype == 'http://www.w3.org/TR/scxml/#SCXMLEventProcessor'" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test199.scxml b/test/w3c/promela/test199.scxml
new file mode 100644
index 0000000..dbea699
--- /dev/null
+++ b/test/w3c/promela/test199.scxml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that using an invalid send type results in error.execution -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send type="27" event="event1"/>
+ <send event="timeout"/>
+ </onentry>
+ <transition event="error.execution" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test200.scxml b/test/w3c/promela/test200.scxml
new file mode 100644
index 0000000..e4503fb
--- /dev/null
+++ b/test/w3c/promela/test200.scxml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that the processor supports the scxml event i/o processor -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" event="event1"/>
+ <send event="timeout"/>
+ </onentry>
+ <transition event="event1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test201.scxml b/test/w3c/promela/test201.scxml
new file mode 100644
index 0000000..d517776
--- /dev/null
+++ b/test/w3c/promela/test201.scxml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that the processor supports the basic http event i/o processor. This is an optional
+test since platforms are not required to support basic http event i/o -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor" targetexpr="_ioprocessors.basichttp.location" event="event1"/>
+ <send event="timeout"/>
+ </onentry>
+ <transition event="event1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test205.scxml b/test/w3c/promela/test205.scxml
new file mode 100644
index 0000000..604b311
--- /dev/null
+++ b/test/w3c/promela/test205.scxml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that the processor doesn't change the message. We can't test that it never does this, but
+at least we can check that the event name and included data are the same as we sent. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="event1">
+ <param name="aParam" expr="1"/>
+ </send>
+ <send event="timeout"/>
+ </onentry>
+ <transition event="event1" target="s1">
+ <assign location="Var1" expr="_event.data.aParam"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var1==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test207.scxml b/test/w3c/promela/test207.scxml
new file mode 100644
index 0000000..4adbfca
--- /dev/null
+++ b/test/w3c/promela/test207.scxml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that that we can't cancel an event in another session. We invoke a child process. It notifies
+us when it has generated a delayed event with sendid foo. We try to cancel foo. The child process sends us event
+ event success if the event is not cancelled, event fail otherwise. This doesn't test that there is absolutely no way to cancel an event
+raised in another session, but the spec doesn't define any way to refer to an event in another process -->
+<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">
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delayexpr="'2s'"/>
+ </onentry>
+ <invoke type="scxml">
+ <content>
+ <!-- when invoked, we raise a delayed event1 with sendid 'foo' and notify our parent. Then we wait.
+ If event1 occurs, the parent hasn't succeeded in canceling it and we return pass. If event2 occurs
+ it means event1 was canceled (because event2 is delayed longer than event1) and we return 'fail'. -->
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <state id="sub0">
+ <onentry>
+ <send event="event1" id="foo" delayexpr="'1s'"/>
+ <send event="event2" delayexpr="'1.5s'"/>
+ <send target="#_parent" event="childToParent"/>
+ </onentry>
+ <transition event="event1" target="subFinal">
+ <send target="#_parent" event="pass"/>
+ </transition>
+ <transition event="*" target="subFinal">
+ <send target="#_parent" event="fail"/>
+ </transition>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <state id="s01">
+ <transition event="childToParent" target="s02">
+ <cancel sendid="foo"/>
+ </transition>
+ </state>
+ <state id="s02">
+ <transition event="pass" target="pass"/>
+ <transition event="fail" target="fail"/>
+ <transition event="timeout" target="fail"/>
+ </state>
+ </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/promela/test208.scxml b/test/w3c/promela/test208.scxml
new file mode 100644
index 0000000..72f57a6
--- /dev/null
+++ b/test/w3c/promela/test208.scxml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that cancel works. We cancel delayed event1. If cancel works, we get event2 first and pass. If
+we get event1 or an error first, cancel didn't work and we fail. -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send id="foo" event="event1" delayexpr="'1s'"/>
+ <send event="event2" delayexpr="'1.5s'"/>
+ <cancel sendid="foo"/>
+ </onentry>
+ <transition event="event2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test210.scxml b/test/w3c/promela/test210.scxml
new file mode 100644
index 0000000..6b692be
--- /dev/null
+++ b/test/w3c/promela/test210.scxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that sendidexpr works with cancel. If it takes the most recent value of var1, it should cancel
+delayed event1. Thus we get event2 first and pass. If we get event1 or an error first, cancel didn't work and we fail. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="string" expr="'bar'"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send id="foo" event="event1" delayexpr="'1s'"/>
+ <send event="event2" delayexpr="'1.5s'"/>
+ <assign location="Var1" expr="'foo'"/>
+ <cancel sendidexpr="Var1"/>
+ </onentry>
+ <transition event="event2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test215.scxml b/test/w3c/promela/test215.scxml
new file mode 100644
index 0000000..1a0819b
--- /dev/null
+++ b/test/w3c/promela/test215.scxml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that typexpr is evaluated at runtime. If the original value of var1 is used, the invocation
+will fail (test215sub1.scxml is not of type 'foo', even if the platform supports foo as a type). If
+the runtime value is used, the invocation will succeed -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="string" expr="'foo'"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="5s"/>
+ <assign location="Var1" expr="'http://www.w3.org/TR/scxml/'"/>
+ </onentry>
+ <invoke typeexpr="Var1">
+ <content>
+ <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. -->
+ <scxml initial="subFinal" datamodel="promela" version="1.0">
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="done.invoke" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test216.scxml b/test/w3c/promela/test216.scxml
new file mode 100644
index 0000000..6a9aaa4
--- /dev/null
+++ b/test/w3c/promela/test216.scxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that srcexpr is evaluated at runtime. If the original value of var1 is used, the invocation
+will fail (assuming that there is no script named 'foo'). If
+the runtime value is used, the invocation will succeed -->
+<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">
+ <datamodel>
+ <data id="Var1" type="string" expr="'foo'"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="5s"/>
+ <assign location="Var1" expr="'file:test216sub1.scxml'"/>
+ </onentry>
+ <invoke srcexpr="Var1" type="http://www.w3.org/TR/scxml"/>
+ <transition event="done.invoke" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test216sub1.scxml b/test/w3c/promela/test216sub1.scxml
new file mode 100644
index 0000000..9a5d74e
--- /dev/null
+++ b/test/w3c/promela/test216sub1.scxml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="final" version="1.0" datamodel="promela">
+ <final id="final"/>
+</scxml>
diff --git a/test/w3c/promela/test220.scxml b/test/w3c/promela/test220.scxml
new file mode 100644
index 0000000..25bb26b
--- /dev/null
+++ b/test/w3c/promela/test220.scxml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that the scxml type is supported. -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="5s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <content>
+ <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. -->
+ <scxml initial="subFinal" version="1.0" datamodel="promela">
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="done.invoke" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test223.scxml b/test/w3c/promela/test223.scxml
new file mode 100644
index 0000000..5317ac7
--- /dev/null
+++ b/test/w3c/promela/test223.scxml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that idlocation is supported. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/" idlocation="Var1">
+ <content>
+ <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. -->
+ <scxml initial="subFinal" version="1.0" datamodel="promela">
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="*" target="s1"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test224.scxml b/test/w3c/promela/test224.scxml
new file mode 100644
index 0000000..3892083
--- /dev/null
+++ b/test/w3c/promela/test224.scxml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that the automatically generated id has the form stateid.platformid. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ <data id="Var2" type="string" expr="'s0.'"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/" idlocation="Var1">
+ <content>
+ <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. -->
+ <scxml version="1.0" initial="subFinal" datamodel="promela">
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="*" target="s1"/>
+ </state>
+ <state id="s1">
+ <transition cond="(function(str, starts){if (starts == '') return true;if (str == null || starts == null) return false;str = String(str); starts = String(starts);return str.length &gt;= starts.length &amp;&amp; str.slice(0, starts.length) == starts;})(Var1, Var2)" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test225.scxml b/test/w3c/promela/test225.scxml
new file mode 100644
index 0000000..25aa2f1
--- /dev/null
+++ b/test/w3c/promela/test225.scxml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that the automatically generated id is unique, we call invoke twice and compare the ids. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ <data id="Var2" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/" idlocation="Var1">
+ <content>
+ <scxml initial="subFinal1" version="1.0" datamodel="promela">
+ <final id="subFinal1"/>
+ </scxml>
+ </content>
+ </invoke>
+ <invoke type="http://www.w3.org/TR/scxml/" idlocation="Var2">
+ <content>
+ <scxml initial="subFinal2" version="1.0" datamodel="promela">
+ <final id="subFinal2"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="*" target="s1"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var1==Var2" target="fail"/>
+ <transition target="pass"/>
+ </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/promela/test226.scxml b/test/w3c/promela/test226.scxml
new file mode 100644
index 0000000..7ab32d8
--- /dev/null
+++ b/test/w3c/promela/test226.scxml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- this is basically just a test that invoke works correctly and that you can pass data
+to the invoked process. If the invoked session finds aParam==1, it exits, signalling
+success. otherwise it will hang and the timeout in this doc signifies failure. -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="3s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/" src="file:test226sub1.scxml">
+ <param name="Var1" expr="1"/>
+ </invoke>
+ <transition event="varBound" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test226sub1.scxml b/test/w3c/promela/test226sub1.scxml
new file mode 100644
index 0000000..3d7869a
--- /dev/null
+++ b/test/w3c/promela/test226sub1.scxml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- when invoked, if var1 has a value notify parent. Then terminate. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <transition cond="Var1" target="final">
+ <send target="#_parent" event="varBound"/>
+ </transition>
+ <transition target="final"/>
+ </state>
+ <final id="final"/>
+</scxml>
diff --git a/test/w3c/promela/test228.scxml b/test/w3c/promela/test228.scxml
new file mode 100644
index 0000000..9771a9e
--- /dev/null
+++ b/test/w3c/promela/test228.scxml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the invokeid is included in events returned from the invoked process. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="3s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/" id="foo">
+ <content>
+ <scxml initial="subFinal" version="1.0" datamodel="promela">
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="done.invoke" target="s1">
+ <assign location="Var1" expr="_event.invokeid"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var1=='foo'" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test229.scxml b/test/w3c/promela/test229.scxml
new file mode 100644
index 0000000..3ba733a
--- /dev/null
+++ b/test/w3c/promela/test229.scxml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that autofoward works. If the child process receives back a copy of the
+childToParent event that it sends to this doc, it sends eventReceived, signalling success. (Note
+that this doc is not required to process that event explicitly. It should be forwarded in any case.) Otherwise
+it eventually times out and the done.invoke signals failure -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="3s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/" autoforward="true">
+ <content>
+ <!-- when invoked, send childToParent to parent.
+ If it is forwarded back to us, send
+ eventReceived to signal success and terminate.
+ Otherwise wait for timer to expire and terminate. -->
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <state id="sub0">
+ <onentry>
+ <send target="#_parent" event="childToParent"/>
+ <send event="timeout" delay="3s"/>
+ </onentry>
+ <transition event="childToParent" target="subFinal">
+ <send target="#_parent" event="eventReceived"/>
+ </transition>
+ <transition event="*" target="subFinal"/>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="childToParent"/>
+ <transition event="eventReceived" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test230.scxml b/test/w3c/promela/test230.scxml
new file mode 100644
index 0000000..ee97cef
--- /dev/null
+++ b/test/w3c/promela/test230.scxml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- a manual test that an autofowarded event has the same fields and values as the original event.
+the child process sends the parent process an event which is forwarded back to it.
+Both the parent and child process print out the contents of the event. The tester
+must check if they are the same and report his result. -->
+<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">
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="3s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/" autoforward="true">
+ <content>
+ <!-- when invoked, send childToParent to parent. If it is forwarded back to us, print out its
+ fields and terminate. -->
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <state id="sub0">
+ <onentry>
+ <send target="#_parent" event="childToParent"/>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <transition event="childToParent" target="subFinal">
+ <log label="name is " expr="_event.name"/>
+ <log label="type is " expr="_event.type"/>
+ <log label="sendid is " expr="_event.sendid"/>
+ <log label="origin is " expr="_event.origin"/>
+ <log label="origintype is " expr="_event.origintype"/>
+ <log label="invokeid is " expr="_event.invokeid"/>
+ <log label="data is " expr="_event.data"/>
+ </transition>
+ <transition event="*" target="subFinal"/>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="timeout" target="final"/>
+ <state id="s01">
+ <transition event="childToParent" target="s02">
+ <log label="name is " expr="_event.name"/>
+ <log label="type is " expr="_event.type"/>
+ <log label="sendid is " expr="_event.sendid"/>
+ <log label="origin is " expr="_event.origin"/>
+ <log label="origintype is " expr="_event.origintype"/>
+ <log label="invokeid is " expr="_event.invokeid"/>
+ <log label="data is " expr="_event.data"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s02">
+ <!-- wait till we get the done event to ensure that the child process has time to print out its results -->
+ <transition event="done.invoke" target="final"/>
+ </state>
+ </state>
+ <final id="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/promela/test232.scxml b/test/w3c/promela/test232.scxml
new file mode 100644
index 0000000..2c8a8aa
--- /dev/null
+++ b/test/w3c/promela/test232.scxml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that a parent process can receive multiple events from a child process -->
+<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">
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="3s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <content>
+ <scxml initial="subFinal" version="1.0" datamodel="promela">
+ <final id="subFinal">
+ <onentry>
+ <send target="#_parent" event="childToParent1"/>
+ <send target="#_parent" event="childToParent2"/>
+ </onentry>
+ </final>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="timeout" target="fail"/>
+ <state id="s01">
+ <transition event="childToParent1" target="s02"/>
+ </state>
+ <state id="s02">
+ <transition event="childToParent2" target="s03"/>
+ </state>
+ <state id="s03">
+ <transition event="done.invoke" target="pass"/>
+ </state>
+ </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/promela/test233.scxml b/test/w3c/promela/test233.scxml
new file mode 100644
index 0000000..3087e1f
--- /dev/null
+++ b/test/w3c/promela/test233.scxml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that finalize markup runs before the event is processed. The invoked process will
+return 2 in _event.data.aParam, so that new value should be in force when we select
+the transtitions. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="3s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <content>
+ <scxml initial="subFinal" version="1.0" datamodel="promela">
+ <final id="subFinal">
+ <onentry>
+ <send target="#_parent" event="childToParent">
+ <param name="aParam" expr="2"/>
+ </send>
+ </onentry>
+ </final>
+ </scxml>
+ </content>
+ <finalize>
+ <assign location="Var1" expr="_event.data.aParam"/>
+ </finalize>
+ </invoke>
+ <transition event="childToParent" cond="Var1==2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test234.scxml b/test/w3c/promela/test234.scxml
new file mode 100644
index 0000000..ee59cad
--- /dev/null
+++ b/test/w3c/promela/test234.scxml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that only finalize markup in the invoking state runs. the first invoked process will
+return 2 in _event.data.aParam, while second invoked process sleeps without returning any events.
+Only the first finalize should execute. So when we get to s1 var1 should have value 2 but
+var2 should still be set to 1 -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="p0" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ <data id="Var2" type="int" expr="1"/>
+ </datamodel>
+ <parallel id="p0">
+ <onentry>
+ <send event="timeout" delay="3s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <state id="p01">
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <content>
+ <scxml version="1.0" initial="subFinal1" datamodel="promela">
+ <final id="subFinal1">
+ <onentry>
+ <send target="#_parent" event="childToParent">
+ <param name="aParam" expr="2"/>
+ </send>
+ </onentry>
+ </final>
+ </scxml>
+ </content>
+ <finalize>
+ <assign location="Var1" expr="_event.data.aParam"/>
+ </finalize>
+ </invoke>
+ <transition event="childToParent" cond="Var1==2" target="s1"/>
+ <transition event="childToParent" target="fail"/>
+ </state>
+ <state id="p02">
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <content>
+ <scxml version="1.0" initial="sub0" datamodel="promela">
+ <state id="sub0">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <transition event="timeout" target="subFinal2"/>
+ </state>
+ <final id="subFinal2"/>
+ </scxml>
+ </content>
+ <finalize>
+ <assign location="Var2" expr="_event.data.aParam"/>
+ </finalize>
+ </invoke>
+ </state>
+ </parallel>
+ <state id="s1">
+ <transition cond="Var2==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test235.scxml b/test/w3c/promela/test235.scxml
new file mode 100644
index 0000000..95b5827
--- /dev/null
+++ b/test/w3c/promela/test235.scxml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that done.invoke.id event has the right id. the invoked child terminates immediately
+and should generate done.invoke.foo -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/" id="foo">
+ <content>
+ <scxml initial="subFinal" version="1.0" datamodel="promela">
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="done.invoke.foo" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test236.scxml b/test/w3c/promela/test236.scxml
new file mode 100644
index 0000000..600b7f4
--- /dev/null
+++ b/test/w3c/promela/test236.scxml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that done.invoke.id event is the last event we receive. the invoked process sends childToParent
+in the exit handler of its final state. We should get it before the done.invoke, and we should get no
+events after the done.invoke. Hence timeout indicates success -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delayexpr="'2s'"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <content>
+ <scxml initial="subFinal" version="1.0" datamodel="promela">
+ <final id="subFinal">
+ <onexit>
+ <send target="#_parent" event="childToParent"/>
+ </onexit>
+ </final>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="childToParent" target="s1"/>
+ <transition event="done.invoke" target="fail"/>
+ </state>
+ <state id="s1">
+ <!-- here we should get done.invoke -->
+ <transition event="done.invoke" target="s2"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s2">
+ <transition event="timeout" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test237.scxml b/test/w3c/promela/test237.scxml
new file mode 100644
index 0000000..d23fc20
--- /dev/null
+++ b/test/w3c/promela/test237.scxml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that cancelling works. invoked child sleeps for two seconds, then terminates. We
+sleep for 1 sec in s0, then move to s1. This should cause the invocation to get cancelled.
+If we receive done.invoke, the invocation wasn't cancelled, and we fail. If we receive no events by
+the time timeout2 fires, success -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timeout1" delayexpr="'1s'"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <content>
+ <!-- when invoked, sleep for 2 secs then terminate. Parent will try to cancel this session -->
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <state id="sub0">
+ <onentry>
+ <send event="timeout" delayexpr="'2s'"/>
+ </onentry>
+ <transition event="timeout" target="subFinal"/>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="timeout1" target="s1"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <send event="timeout2" delayexpr="'1.5s'"/>
+ </onentry>
+ <!-- here we should NOT get done.invoke -->
+ <transition event="done.invoke" target="fail"/>
+ <transition event="*" target="pass"/>
+ </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/promela/test239.scxml b/test/w3c/promela/test239.scxml
new file mode 100644
index 0000000..dab80b9
--- /dev/null
+++ b/test/w3c/promela/test239.scxml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that markup can be specified both by 'src' and by <content> -->
+<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">
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <state id="s01">
+ <invoke type="http://www.w3.org/TR/scxml/" src="file:test239sub1.scxml"/>
+ <transition event="done.invoke" target="s02"/>
+ </state>
+ <state id="s02">
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <!-- identical to test239sub1.scxml. -->
+ <content>
+ <scxml version="1.0" initial="final" datamodel="promela">
+ <final id="final"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="done.invoke" target="pass"/>
+ </state>
+ </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/promela/test239sub1.scxml b/test/w3c/promela/test239sub1.scxml
new file mode 100644
index 0000000..4f0ea59
--- /dev/null
+++ b/test/w3c/promela/test239sub1.scxml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- when invoked, just terminate. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="final" version="1.0" datamodel="promela">
+ <final id="final"/>
+</scxml>
diff --git a/test/w3c/promela/test240.scxml b/test/w3c/promela/test240.scxml
new file mode 100644
index 0000000..e586d4e
--- /dev/null
+++ b/test/w3c/promela/test240.scxml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that datamodel values can be specified both by 'namelist' and by <param>.
+invoked child will return success if its Var1 is set to 1, failure otherwise. This
+test will fail schema validation because of the multiple occurences of Var1, but
+should run correctly. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <state id="s01">
+ <invoke type="http://www.w3.org/TR/scxml/" namelist="Var1">
+ <content>
+ <scxml initial="sub01" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="sub01">
+ <transition cond="Var1==1" target="subFinal1">
+ <send target="#_parent" event="success"/>
+ </transition>
+ <transition target="subFinal1">
+ <send target="#_parent" event="failure"/>
+ </transition>
+ </state>
+ <final id="subFinal1"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="success" target="s02"/>
+ <transition event="failure" target="fail"/>
+ </state>
+ <state id="s02">
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <param name="Var1" expr="1"/>
+ <content>
+ <scxml initial="sub02" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="sub02">
+ <transition cond="Var1==1" target="subFinal2">
+ <send target="#_parent" event="success"/>
+ </transition>
+ <transition target="subFinal1">
+ <send target="#_parent" event="failure"/>
+ </transition>
+ </state>
+ <final id="subFinal2"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="success" target="pass"/>
+ <transition event="failure" target="fail"/>
+ </state>
+ </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/promela/test241.scxml b/test/w3c/promela/test241.scxml
new file mode 100644
index 0000000..dff2920
--- /dev/null
+++ b/test/w3c/promela/test241.scxml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- The child process will return success ifits Var1 is set to 1, failure otherwise. For this test
+we try passing in Var1 by param and by namelist and check that we either get two successes
+or two failures. This test will fail schema validation due to multiple declarations of
+Var1, but should run correctly. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <state id="s01">
+ <invoke type="http://www.w3.org/TR/scxml/" namelist="Var1">
+ <content>
+ <scxml initial="sub01" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="sub01">
+ <transition cond="Var1==1" target="subFinal1">
+ <send target="#_parent" event="success"/>
+ </transition>
+ <transition target="subFinal1">
+ <send target="#_parent" event="failure"/>
+ </transition>
+ </state>
+ <final id="subFinal1"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="success" target="s02"/>
+ <transition event="failure" target="s03"/>
+ </state>
+ <state id="s02">
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <param name="Var1" expr="1"/>
+ <content>
+ <scxml initial="sub02" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="sub02">
+ <transition cond="Var1==1" target="subFinal2">
+ <send target="#_parent" event="success"/>
+ </transition>
+ <transition target="subFinal2">
+ <send target="#_parent" event="failure"/>
+ </transition>
+ </state>
+ <final id="subFinal2"/>
+ </scxml>
+ </content>
+ </invoke>
+ <!-- we got success in s01, so we need to do so here -->
+ <transition event="success" target="pass"/>
+ <transition event="failure" target="fail"/>
+ </state>
+ <state id="s03">
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <param name="Var1" expr="1"/>
+ <content>
+ <scxml initial="sub03" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="sub03">
+ <transition cond="Var1==1" target="subFinal3">
+ <send target="#_parent" event="success"/>
+ </transition>
+ <transition target="subFinal3">
+ <send target="#_parent" event="failure"/>
+ </transition>
+ </state>
+ <final id="subFinal3"/>
+ </scxml>
+ </content>
+ </invoke>
+ <!-- we got failure in s01, so we need to do so here -->
+ <transition event="failure" target="pass"/>
+ <transition event="success" target="fail"/>
+ </state>
+ </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/promela/test242.scxml b/test/w3c/promela/test242.scxml
new file mode 100644
index 0000000..01ea8d0
--- /dev/null
+++ b/test/w3c/promela/test242.scxml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that markup specified by 'src' and by <content> is treated the same way. That means that
+either we get done.invoke in both cases or in neither case (in which case we timeout) -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timeout1" delay="1s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <invoke type="http://www.w3.org/TR/scxml/" src="file:test242sub1.scxml"/>
+ <transition event="done.invoke" target="s02"/>
+ <transition event="timeout1" target="s03"/>
+ </state>
+ <state id="s02">
+ <onentry>
+ <send event="timeout2" delay="1s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <!-- identical to test242sub1.scxml. -->
+ <content>
+ <scxml version="1.0" initial="subFinal1" datamodel="promela">
+ <final id="subFinal1"/>
+ </scxml>
+ </content>
+ </invoke>
+ <!-- we got done.invoke last time, so we need it this time too -->
+ <transition event="done.invoke" target="pass"/>
+ <transition event="timeout2" target="fail"/>
+ </state>
+ <state id="s03">
+ <onentry>
+ <send event="timeout3" delay="1s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <!-- identical to test242sub1.scxml. -->
+ <content>
+ <scxml version="1.0" initial="subFinal2" datamodel="promela">
+ <final id="subFinal2"/>
+ </scxml>
+ </content>
+ </invoke>
+ <!-- we got timeout last time, so we need it this time too -->
+ <transition event="timeout3" target="pass"/>
+ <transition event="done.invoke" target="fail"/>
+ </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/promela/test242sub1.scxml b/test/w3c/promela/test242sub1.scxml
new file mode 100644
index 0000000..4f0ea59
--- /dev/null
+++ b/test/w3c/promela/test242sub1.scxml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- when invoked, just terminate. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="final" version="1.0" datamodel="promela">
+ <final id="final"/>
+</scxml>
diff --git a/test/w3c/promela/test243.scxml b/test/w3c/promela/test243.scxml
new file mode 100644
index 0000000..c29d49f
--- /dev/null
+++ b/test/w3c/promela/test243.scxml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that datamodel values can be specified by param.
+test240sub1 will return success ifits Var1 is set to 1, failure otherwise. -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <param name="Var1" expr="1"/>
+ <content>
+ <scxml version="1.0" initial="sub0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="sub0">
+ <transition cond="Var1==1" target="subFinal">
+ <send target="#_parent" event="success"/>
+ </transition>
+ <transition target="subFinal">
+ <send target="#_parent" event="failure"/>
+ </transition>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="success" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test244.scxml b/test/w3c/promela/test244.scxml
new file mode 100644
index 0000000..84b6ec3
--- /dev/null
+++ b/test/w3c/promela/test244.scxml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that datamodel values can be specified by namelist.
+invoked child will return success ifits Var1 is set to 1, failure otherwise.
+This test will fail schema validation due to multiple occurrences of Var1,
+but should run correctly. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/" namelist="Var1">
+ <content>
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="sub0">
+ <transition cond="Var1==1" target="subFinal">
+ <send target="#_parent" event="success"/>
+ </transition>
+ <transition target="subFinal">
+ <send target="#_parent" event="failure"/>
+ </transition>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="success" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test245.scxml b/test/w3c/promela/test245.scxml
new file mode 100644
index 0000000..5f00a42
--- /dev/null
+++ b/test/w3c/promela/test245.scxml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that non-existent datamodel values are not set. Var2 is not defined in
+invoked child's datamodel. It will will return success if its Var2 remains unbound, failure otherwise. -->
+<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">
+ <datamodel>
+ <data id="Var2" type="int" expr="3"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/" namelist="Var2">
+ <content>
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <state id="sub0">
+ <transition cond="Var2" target="subFinal">
+ <send target="#_parent" event="failure"/>
+ </transition>
+ <transition target="subFinal">
+ <send target="#_parent" event="success"/>
+ </transition>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="success" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test247.scxml b/test/w3c/promela/test247.scxml
new file mode 100644
index 0000000..822f97d
--- /dev/null
+++ b/test/w3c/promela/test247.scxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that we get done.invoke. timeout indicates failure -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <content>
+ <scxml version="1.0" initial="subFinal" datamodel="promela">
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="done.invoke" target="pass"/>
+ <transition event="timeout" target="fail"/>
+ </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/promela/test250.scxml b/test/w3c/promela/test250.scxml
new file mode 100644
index 0000000..e3f6b7a
--- /dev/null
+++ b/test/w3c/promela/test250.scxml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the onexit handlers run in the invoked process if it is cancelled. This has to be a
+manual test, since this process won't accept any events from the child process once it has been cancelled.
+Tester must examine log output from child process to determine success -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="foo"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <content>
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <state id="sub0" initial="sub01">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <transition event="timeout" target="subFinal"/>
+ <onexit>
+ <log expr="'Exiting sub0'"/>
+ </onexit>
+ <state id="sub01">
+ <onexit>
+ <log expr="'Exiting sub01'"/>
+ </onexit>
+ </state>
+ </state>
+ <final id="subFinal">
+ <onentry>
+ <log expr="'entering final state, invocation was not cancelled'"/>
+ </onentry>
+ </final>
+ </scxml>
+ </content>
+ </invoke>
+ <!-- this transition will cause the invocation to be cancelled -->
+ <transition event="foo" target="final"/>
+ </state>
+ <final id="final"/>
+</scxml>
diff --git a/test/w3c/promela/test252.scxml b/test/w3c/promela/test252.scxml
new file mode 100644
index 0000000..cb45517
--- /dev/null
+++ b/test/w3c/promela/test252.scxml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that we don't process any events received from the invoked process once it is cancelled. child
+process tries to send us childToParent in an onexit handler. If we get it, we fail.
+timeout indicates success. -->
+<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">
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delayexpr="'1s'"/>
+ </onentry>
+ <transition event="timeout" target="pass"/>
+ <transition event="childToParent" target="fail"/>
+ <transition event="done.invoke" target="fail"/>
+ <state id="s01">
+ <onentry>
+ <send event="foo"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <content>
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <state id="sub0">
+ <onentry>
+ <send event="timeout" delayexpr="'.5s'"/>
+ </onentry>
+ <transition event="timeout" target="subFinal"/>
+ <onexit>
+ <send target="#_parent" event="childToParent"/>
+ </onexit>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <!-- this transition will cause the invocation to be cancelled -->
+ <transition event="foo" target="s02"/>
+ </state>
+ <state id="s02"/>
+ </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/promela/test253.scxml b/test/w3c/promela/test253.scxml
new file mode 100644
index 0000000..467f7ff
--- /dev/null
+++ b/test/w3c/promela/test253.scxml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the scxml event processor is used in both directions. If child process uses the
+scxml event i/o processor to communicate with us, send it an event. It will send back success if
+this process uses the scxml processor to send the message to it, otherwise failure. For this test we allow
+'scxml' as an alternative to the full url. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ </datamodel>
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <invoke type="scxml" id="foo">
+ <content>
+ <!-- inform parent we're running then wait for it to send us an event. If it uses the scxml event i/o
+ processor to do so, return success, otherwise return failure. -->
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var2" type="int"/>
+ </datamodel>
+ <state id="sub0">
+ <onentry>
+ <send target="#_parent" event="childRunning"/>
+ </onentry>
+ <transition event="parentToChild" target="sub1">
+ <assign location="Var2" expr="_event.origintype"/>
+ </transition>
+ </state>
+ <state id="sub1">
+ <transition cond="Var2=='http://www.w3.org/TR/scxml/#SCXMLEventProcessor'" target="subFinal">
+ <send target="#_parent" event="success"/>
+ </transition>
+ <transition cond="Var2=='scxml'" target="subFinal">
+ <send target="#_parent" event="success"/>
+ </transition>
+ <transition target="subFinal">
+ <send target="#_parent" event="failure"/>
+ </transition>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <state id="s01">
+ <transition event="childRunning" target="s02">
+ <assign location="Var1" expr="_event.origintype"/>
+ </transition>
+ </state>
+ <state id="s02">
+ <transition cond="Var1=='http://www.w3.org/TR/scxml/#SCXMLEventProcessor'" target="s03">
+ <send target="#_foo" event="parentToChild"/>
+ </transition>
+ <transition cond="Var1=='scxml'" target="s03">
+ <send target="#_foo" event="parentToChild"/>
+ </transition>
+ <transition target="fail"/>
+ </state>
+ <state id="s03">
+ <transition event="success" target="pass"/>
+ <transition event="fail" target="fail"/>
+ </state>
+ </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/promela/test276.scxml b/test/w3c/promela/test276.scxml
new file mode 100644
index 0000000..3602bb0
--- /dev/null
+++ b/test/w3c/promela/test276.scxml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that values passed in from parent process override default values specified in the child, test276sub1.scxml.
+The child returns event1 if var1 has value 1, event0 if it has default value 0. -->
+<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">
+ <state id="s0">
+ <invoke type="scxml" src="file:test276sub1.scxml">
+ <param name="Var1" expr="1"/>
+ </invoke>
+ <transition event="event1" target="pass"/>
+ <transition event="event0" target="fail"/>
+ </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/promela/test276sub1.scxml b/test/w3c/promela/test276sub1.scxml
new file mode 100644
index 0000000..a95592e
--- /dev/null
+++ b/test/w3c/promela/test276sub1.scxml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- define var1 with default value 0. Parent will invoke this process setting var1 = 1. Return event1 if var1 == 1, event0 otherwise -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0">
+ <transition cond="Var1==1" target="final">
+ <send target="#_parent" event="event1"/>
+ </transition>
+ <transition target="final">
+ <send target="#_parent" event="event0"/>
+ </transition>
+ </state>
+ <final id="final"/>
+</scxml>
diff --git a/test/w3c/promela/test277.scxml b/test/w3c/promela/test277.scxml
new file mode 100644
index 0000000..89090d2
--- /dev/null
+++ b/test/w3c/promela/test277.scxml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that platform creates undound variable if we assign an illegal value to it. Thus
+ we can assign to it later in state s1. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="return"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error.execution" cond="!(Var1)" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <assign location="Var1" expr="1"/>
+ </onentry>
+ <transition cond="Var1==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test278.scxml b/test/w3c/promela/test278.scxml
new file mode 100644
index 0000000..a2d613a
--- /dev/null
+++ b/test/w3c/promela/test278.scxml
@@ -0,0 +1,23 @@
+<?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/promela/test279.scxml b/test/w3c/promela/test279.scxml
new file mode 100644
index 0000000..8c12d30
--- /dev/null
+++ b/test/w3c/promela/test279.scxml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- testing that in case of early binding variables are assigned values at init time, before
+ the state containing them is visited -->
+<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">
+ <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/promela/test280.scxml b/test/w3c/promela/test280.scxml
new file mode 100644
index 0000000..d43a883
--- /dev/null
+++ b/test/w3c/promela/test280.scxml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test late binding. var2 won't get bound until s1 is entered, so it shouldn't have a value in s0 and
+accessing it should cause an error. It should get bound before the onentry code in s1 so it should be
+possible access it there and assign its value to var1 -->
+<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" binding="late">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <transition cond="!(Var2)" target="s1"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s1">
+ <datamodel>
+ <data id="Var2" type="int" expr="1"/>
+ </datamodel>
+ <onentry>
+ <assign location="Var1" expr="Var2"/>
+ </onentry>
+ <transition cond="Var1==Var2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test286.scxml b/test/w3c/promela/test286.scxml
new file mode 100644
index 0000000..9b84ced
--- /dev/null
+++ b/test/w3c/promela/test286.scxml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that assigment to a non-declared var causes an error. the transition on foo catches the case
+where no error is raised -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <state id="s0">
+ <onentry>
+ <assign location="foo.bar.baz " expr="1"/>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error.execution" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test287.scxml b/test/w3c/promela/test287.scxml
new file mode 100644
index 0000000..2d22f15
--- /dev/null
+++ b/test/w3c/promela/test287.scxml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- a simple test that a legal value may be assigned to a valid data model location -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="promela" version="1.0" initial="s0">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1" expr="1"/>
+ </onentry>
+ <transition cond="Var1==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test288.scxml b/test/w3c/promela/test288.scxml
new file mode 100644
index 0000000..8e9b01a
--- /dev/null
+++ b/test/w3c/promela/test288.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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="promela" version="1.0" initial="s0">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1">123</assign>
+ </onentry>
+ <transition cond="Var1 == 123" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test294.scxml b/test/w3c/promela/test294.scxml
new file mode 100644
index 0000000..dd38f2d
--- /dev/null
+++ b/test/w3c/promela/test294.scxml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that a param inside donedata ends up in the data field of the done event and
+that content inside donedata sets the full value of the event.data field -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0" initial="s01">
+ <transition event="done.state.s0" cond="_event.data.Var1==1" target="s1">
+ </transition>
+ <transition event="done.state.s0" target="fail">
+ </transition>
+ <state id="s01">
+ <transition target="s02"/>
+ </state>
+ <final id="s02">
+ <donedata>
+ <param name="Var1" expr="1"/>
+ </donedata>
+ </final>
+ </state>
+ <state id="s1" initial="s11">
+ <transition event="done.state.s1" cond="_event.data == 'foo'" target="pass">
+ </transition>
+ <transition event="done.state.s1" target="fail">
+ </transition>
+ <state id="s11">
+ <transition target="s12"/>
+ </state>
+ <final id="s12">
+ <donedata>
+ <content xmlns:scxml="http://www.w3.org/2005/07/scxml">foo</content>
+ </donedata>
+ </final>
+ </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/promela/test298.scxml b/test/w3c/promela/test298.scxml
new file mode 100644
index 0000000..0f623b7
--- /dev/null
+++ b/test/w3c/promela/test298.scxml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- reference a non-existent data model location in param in donedata and see that the right error is raised -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="error.execution" target="pass"/>
+ <transition event="*" target="fail"/>
+ <state id="s01">
+ <transition target="s02"/>
+ </state>
+ <final id="s02">
+ <donedata>
+ <param name="Var3" location="foo.bar.baz "/>
+ </donedata>
+ </final>
+ </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/promela/test301.scxml b/test/w3c/promela/test301.scxml
new file mode 100644
index 0000000..f089387
--- /dev/null
+++ b/test/w3c/promela/test301.scxml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- the processor should reject this document because it can't download the script.
+Therefore we fail if it runs at all. This test is valid only for datamodels that support scripting -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0">
+ <script src="D:\foo"/>
+ <state id="s0">
+ <transition target="fail"/>
+ </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/promela/test302.scxml b/test/w3c/promela/test302.scxml
new file mode 100644
index 0000000..a8161f8
--- /dev/null
+++ b/test/w3c/promela/test302.scxml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that a script is evaluated at load time. <conf:script> shoudl assign the value 1 to
+Var1. Hence, if script is evaluated at download time, Var1 has a value in the initial state s0.
+This test is valid only for datamodels that support scripting -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <script xmlns:scxml="http://www.w3.org/2005/07/scxml">Var1 = 1</script>
+ <state id="s0">
+ <transition cond="Var1==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test303.scxml b/test/w3c/promela/test303.scxml
new file mode 100644
index 0000000..bf41d39
--- /dev/null
+++ b/test/w3c/promela/test303.scxml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- to test that scripts are run as part of executable content, we check that it changes the value of a var at the
+right point. This test is valid only for datamodels that support scripting -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1" expr="2"/>
+ <script xmlns:scxml="http://www.w3.org/2005/07/scxml">Var1 = 1</script>
+ </onentry>
+ <transition cond="Var1==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test304.scxml b/test/w3c/promela/test304.scxml
new file mode 100644
index 0000000..1f8197a
--- /dev/null
+++ b/test/w3c/promela/test304.scxml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that a variable declared by a script can be accessed like any other part of the data model -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="promela" version="1.0" initial="s0">
+ <script xmlns:scxml="http://www.w3.org/2005/07/scxml">Var1 = 1</script>
+ <state id="s0">
+ <transition cond="Var1==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test307.scxml b/test/w3c/promela/test307.scxml
new file mode 100644
index 0000000..91ad325
--- /dev/null
+++ b/test/w3c/promela/test307.scxml
@@ -0,0 +1,35 @@
+<?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" version="1.0" initial="s0" datamodel="promela" binding="late">
+ <!-- with binding=late, in s0 we access a variable that isn't created until we get to s1. Then in s1
+we access a non-existent substructure of a variable. We use log tags to report the values that both operations
+yield, and whether there are errors. This is a manual test, since the tester must report whether the output
+is the same in the two cases -->
+ <state id="s0">
+ <onentry>
+ <log label="entering s0 value of Var 1 is: " expr="Var1"/>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error" target="s1">
+ <log label="error in state s0" expr="_event"/>
+ </transition>
+ <transition event="foo" target="s1">
+ <log label="no error in s0" expr=""/>
+ </transition>
+ </state>
+ <state id="s1">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <onentry>
+ <log label="entering s1, value of non-existent substructure of Var 1 is: " expr="Var1.bar"/>
+ <raise event="bar"/>
+ </onentry>
+ <transition event="error" target="final">
+ <log label="error in state s1" expr="_event"/>
+ </transition>
+ <transition event="bar" target="final">
+ <log label="No error in s1" expr=""/>
+ </transition>
+ </state>
+ <final id="final"/>
+</scxml>
diff --git a/test/w3c/promela/test309.scxml b/test/w3c/promela/test309.scxml
new file mode 100644
index 0000000..fb1525c
--- /dev/null
+++ b/test/w3c/promela/test309.scxml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that an expression that cannot be interpreted as a boolean is treated as false -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <state id="s0">
+ <transition cond="return" target="fail"/>
+ <transition target="pass"/>
+ </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/promela/test310.scxml b/test/w3c/promela/test310.scxml
new file mode 100644
index 0000000..bbab164
--- /dev/null
+++ b/test/w3c/promela/test310.scxml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- simple test of the in() predicate -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="p">
+ <parallel id="p">
+ <state id="s0">
+ <transition cond="_x.states['s1']" target="pass"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s1"/>
+ </parallel>
+ <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/promela/test311.scxml b/test/w3c/promela/test311.scxml
new file mode 100644
index 0000000..7ee4a33
--- /dev/null
+++ b/test/w3c/promela/test311.scxml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that assignment to a non-existent location yields an error -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ <assign location="foo.bar.baz " expr="1"/>
+ </onentry>
+ <transition event="error.execution" target="pass"/>
+ <transition event=".*" target="fail"/>
+ </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/promela/test312.scxml b/test/w3c/promela/test312.scxml
new file mode 100644
index 0000000..10bc8cf
--- /dev/null
+++ b/test/w3c/promela/test312.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that assignment with an illegal expr raises an error -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1" expr="return"/>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error.execution" target="pass"/>
+ <transition event=".*" target="fail"/>
+ </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/promela/test313.scxml b/test/w3c/promela/test313.scxml
new file mode 100644
index 0000000..b16fa2f
--- /dev/null
+++ b/test/w3c/promela/test313.scxml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- this is a manual test. The processor is allowed to reject this doc, but if it executes it with its illegal
+expression, it must raise an error -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1" expr="return"/>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error.execution" target="pass"/>
+ <transition event=".*" target="fail"/>
+ </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/promela/test314.scxml b/test/w3c/promela/test314.scxml
new file mode 100644
index 0000000..9fea77d
--- /dev/null
+++ b/test/w3c/promela/test314.scxml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- this is a manual test because the processor is allowed to reject this document. But if it executes it,
+it should not raise an error until it gets to s03 and evaluates the illegal expr -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <state id="s0" initial="s01">
+ <transition event="error.execution" target="fail"/>
+ <state id="s01">
+ <transition target="s02"/>
+ </state>
+ <state id="s02">
+ <transition target="s03"/>
+ </state>
+ <state id="s03">
+ <onentry>
+ <assign location="Var1" expr="return"/>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error.execution" target="pass"/>
+ <transition event=".*" target="fail"/>
+ </state>
+ </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/promela/test318.scxml b/test/w3c/promela/test318.scxml
new file mode 100644
index 0000000..27651a4
--- /dev/null
+++ b/test/w3c/promela/test318.scxml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that _event stays bound during the onexit and entry into the next state -->
+<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" name="machineName">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="foo" target="s1"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <raise event="bar"/>
+ <!-- _event should still be bound to 'foo' at this point -->
+ <assign location="Var1" expr="_event.name"/>
+ </onentry>
+ <transition cond="Var1=='foo'" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test319.scxml b/test/w3c/promela/test319.scxml
new file mode 100644
index 0000000..2c7159e
--- /dev/null
+++ b/test/w3c/promela/test319.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that _event is not bound before any event has been raised -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0" name="machineName">
+ <state id="s0">
+ <onentry>
+ <if cond="_event">
+ <raise event="bound"/>
+ <else/>
+ <raise event="unbound"/>
+ </if>
+ </onentry>
+ <transition event="unbound" target="pass"/>
+ <transition event="bound" target="fail"/>
+ </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/promela/test321.scxml b/test/w3c/promela/test321.scxml
new file mode 100644
index 0000000..09c29dd
--- /dev/null
+++ b/test/w3c/promela/test321.scxml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that _sessionid is bound on startup -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0" name="machineName">
+ <datamodel>
+ <data id="Var1" type="string" expr="_sessionid"/>
+ </datamodel>
+ <state id="s0">
+ <transition cond="Var1" target="pass"/>
+ <transition cond="true" target="fail"/>
+ </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/promela/test322.scxml b/test/w3c/promela/test322.scxml
new file mode 100644
index 0000000..10bca29
--- /dev/null
+++ b/test/w3c/promela/test322.scxml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that _sessionid remains bound to the same value throught the session. this means that it can't
+be assigned to -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0" name="machineName">
+ <datamodel>
+ <data id="Var1" type="string" expr="_sessionid"/>
+ <data id="Var2" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <transition target="s1"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <assign location="_sessionid" expr="'otherName'"/>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error.execution" target="s2"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s2">
+ <transition cond="Var1==_sessionid" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test323.scxml b/test/w3c/promela/test323.scxml
new file mode 100644
index 0000000..28952fa
--- /dev/null
+++ b/test/w3c/promela/test323.scxml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that _name is bound on startup -->
+<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" name="machineName">
+ <datamodel>
+ <data id="Var1" type="string" expr="_name"/>
+ </datamodel>
+ <state id="s0">
+ <transition cond="Var1" target="pass"/>
+ <transition cond="true" target="fail"/>
+ </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/promela/test324.scxml b/test/w3c/promela/test324.scxml
new file mode 100644
index 0000000..12beb71
--- /dev/null
+++ b/test/w3c/promela/test324.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that _name stays bound till the session ends. This means that it cannot be assigned to -->
+<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" name="machineName">
+ <state id="s0">
+ <transition cond="_name == 'machineName'" target="s1"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <assign location="_name" expr="'otherName'"/>
+ </onentry>
+ <transition cond="_name == 'machineName'" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test325.scxml b/test/w3c/promela/test325.scxml
new file mode 100644
index 0000000..38c892f
--- /dev/null
+++ b/test/w3c/promela/test325.scxml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that _ioprocessors is bound at startup. I'm not sure how to test for a set value or
+how to test that the entries in it do represent I/O processors, since the set that each implementation
+supports may be different. Suggestions welcome -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0" name="machineName">
+ <datamodel>
+ <data id="Var1" type="string" expr="_ioprocessors"/>
+ </datamodel>
+ <state id="s0">
+ <transition cond="Var1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test326.scxml b/test/w3c/promela/test326.scxml
new file mode 100644
index 0000000..c649b8d
--- /dev/null
+++ b/test/w3c/promela/test326.scxml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that _ioprocessors stays bound till the session ends. This means that it cannot be assigned to -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0" name="machineName">
+ <datamodel>
+ <data id="Var1" type="string" expr="_ioprocessors"/>
+ <data id="Var2" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <transition cond="Var1" target="s1"/>
+ <transition cond="true" target="fail"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <assign location="_ioprocessors" expr="'otherName'"/>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error.execution" target="s2"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s2">
+ <onentry>
+ <assign location="Var2" expr="_ioprocessors"/>
+ </onentry>
+ <transition cond="Var1==Var2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test329.scxml b/test/w3c/promela/test329.scxml
new file mode 100644
index 0000000..6f6dd64
--- /dev/null
+++ b/test/w3c/promela/test329.scxml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that none of the system variables can be modified -->
+<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" name="machineName">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ <data id="Var2" type="int"/>
+ <data id="Var3" type="int"/>
+ <data id="Var4" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <!-- get _event bound so we can use it in s1-->
+ <raise event="foo"/>
+ <assign location="Var1" expr="_sessionid"/>
+ <assign location="_sessionid" expr="27"/>
+ </onentry>
+ <transition event="foo" cond="Var1==_sessionid" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <assign location="Var2" expr="_event"/>
+ <assign location="_event" expr="27"/>
+ </onentry>
+ <transition cond="Var2==_event" target="s2"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s2">
+ <onentry>
+ <assign location="Var3" expr="_name"/>
+ <assign location="_name" expr="27"/>
+ </onentry>
+ <transition cond="Var3==_name" target="s3"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s3">
+ <onentry>
+ <assign location="Var4" expr="_ioprocessors"/>
+ <assign location="_ioprocessors" expr="27"/>
+ </onentry>
+ <transition cond="Var4==_ioprocessors" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test330.scxml b/test/w3c/promela/test330.scxml
new file mode 100644
index 0000000..20f0bee
--- /dev/null
+++ b/test/w3c/promela/test330.scxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- check that the required fields are present in both internal and external events -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" name="machineName">
+ <state id="s0">
+ <onentry>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="foo" cond="_event.name &amp;&amp; _event.type" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <send event="foo"/>
+ </onentry>
+ <transition event="foo" cond="_event.name &amp;&amp; _event.type" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test331.scxml b/test/w3c/promela/test331.scxml
new file mode 100644
index 0000000..cd85652
--- /dev/null
+++ b/test/w3c/promela/test331.scxml
@@ -0,0 +1,59 @@
+<?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" version="1.0" datamodel="promela" initial="s0" name="machineName">
+ <!-- test that _event.type is set correctly for internal, platform, and external events -->
+ <datamodel>
+ <data id="Var1" type="string"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <!-- internal event -->
+ <raise event="foo"/>
+ </onentry>
+ <transition event="foo" target="s1">
+ <assign location="Var1" expr="_event.type"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var1=='internal'" target="s2"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s2">
+ <onentry>
+ <!-- this will generate an error, which is a platform event -->
+ <assign location="foo.bar.baz " expr="1"/>
+ </onentry>
+ <transition event="error" target="s3">
+ <assign location="Var1" expr="_event.type"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s3">
+ <transition cond="Var1=='platform'" target="s4"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s4">
+ <onentry>
+ <!-- external event -->
+ <send event="foo"/>
+ </onentry>
+ <transition event="foo" target="s5">
+ <assign location="Var1" expr="_event.type"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s5">
+ <transition cond="Var1=='external'" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test332.scxml b/test/w3c/promela/test332.scxml
new file mode 100644
index 0000000..74ffa55
--- /dev/null
+++ b/test/w3c/promela/test332.scxml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that sendid is present in error events triggered by send errors -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" datamodel="promela" name="machineName">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ <data id="Var2" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <!-- this will raise an error and also store the sendid in var1 -->
+ <send target="baz" event="foo" idlocation="Var1"/>
+ </onentry>
+ <transition event="error" target="s1">
+ <!-- get the sendid out of the error event -->
+ <assign location="Var2" expr="_event.sendid"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <!-- make sure that the sendid in the error event matches the one generated when send executed -->
+ <transition cond="Var1==Var2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test333.scxml b/test/w3c/promela/test333.scxml
new file mode 100644
index 0000000..f26c53c
--- /dev/null
+++ b/test/w3c/promela/test333.scxml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- make sure sendid is blank in a non-error event -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" datamodel="promela" name="machineName">
+ <state id="s0">
+ <onentry>
+ <send event="foo"/>
+ </onentry>
+ <transition event="foo" cond="!(_event.sendid)" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test335.scxml b/test/w3c/promela/test335.scxml
new file mode 100644
index 0000000..8d0a1ad
--- /dev/null
+++ b/test/w3c/promela/test335.scxml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that origin field is blank for internal events -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" datamodel="promela" name="machineName">
+ <state id="s0">
+ <onentry>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="foo" cond="!(_event.origin)" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test336.scxml b/test/w3c/promela/test336.scxml
new file mode 100644
index 0000000..6b502ae
--- /dev/null
+++ b/test/w3c/promela/test336.scxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the origin field of an external event contains a URL that lets you send back to the originator. In
+this case it's the same session, so if we get bar we succeed -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0" name="machineName">
+ <state id="s0">
+ <onentry>
+ <send event="foo"/>
+ </onentry>
+ <transition event="foo" target="s1">
+ <send xmlns:scxml="http://www.w3.org/2005/07/scxml" event="bar" targetexpr="_event.origin" typeexpr="_event.origintype"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <send event="baz"/>
+ </onentry>
+ <transition event="bar" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test337.scxml b/test/w3c/promela/test337.scxml
new file mode 100644
index 0000000..64500af
--- /dev/null
+++ b/test/w3c/promela/test337.scxml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that origintype is blank on internal events -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0" name="machineName">
+ <state id="s0">
+ <onentry>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="foo" cond="!(_event.origintype)" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test338.scxml b/test/w3c/promela/test338.scxml
new file mode 100644
index 0000000..244088a
--- /dev/null
+++ b/test/w3c/promela/test338.scxml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that invokeid is set correctly in events received from an invoked process. timeout event catches the
+case where the invoke doesn't work correctly -->
+<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">
+ <datamodel>
+ <data id="Var1" type="string"/>
+ <data id="Var2" type="string"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <invoke idlocation="Var1" type="http://www.w3.org/TR/scxml/">
+ <content>
+ <scxml initial="sub0" version="1.0" datamodel="promela" name="machineName">
+ <final id="sub0">
+ <onentry>
+ <send target="#_parent" event="event1"/>
+ </onentry>
+ </final>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="event1" target="s1">
+ <assign location="Var2" expr="_event.invokeid"/>
+ </transition>
+ <transition event="event0" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var1==Var2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test339.scxml b/test/w3c/promela/test339.scxml
new file mode 100644
index 0000000..b91fc5f
--- /dev/null
+++ b/test/w3c/promela/test339.scxml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that invokeid is blank in an event that wasn't returned from an invoked process -->
+<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" name="machineName">
+ <state id="s0">
+ <onentry>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="foo" cond="!(_event.invokeid)" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test342.scxml b/test/w3c/promela/test342.scxml
new file mode 100644
index 0000000..ab953e5
--- /dev/null
+++ b/test/w3c/promela/test342.scxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that eventexpr works and sets the name field of the resulting event -->
+<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" name="machineName">
+ <datamodel>
+ <data id="Var1" type="string" expr="'foo'"/>
+ <data id="Var2" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send eventexpr="Var1"/>
+ </onentry>
+ <transition event="foo" target="s1">
+ <assign location="Var2" expr="_event.name"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var1==Var2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test343.scxml b/test/w3c/promela/test343.scxml
new file mode 100644
index 0000000..38dac5c
--- /dev/null
+++ b/test/w3c/promela/test343.scxml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that illegal <param> produces error.execution and empty event.data -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <state id="s0" initial="s01">
+ <!-- we should get the error before the done event -->
+ <transition event="error.execution" target="s1"/>
+ <transition event="done.state.s0" target="fail"/>
+ <transition event="done.state.s0" target="fail">
+ </transition>
+ <state id="s01">
+ <transition target="s02"/>
+ </state>
+ <final id="s02">
+ <donedata>
+ <param location="foo.bar.baz " name="someParam"/>
+ </donedata>
+ </final>
+ </state>
+ <!-- if we get here, we received the error event. Now check that the done
+ event has empty event.data -->
+ <state id="s1">
+ <transition event="done.state.s0" cond="!(_event.data)" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test344.scxml b/test/w3c/promela/test344.scxml
new file mode 100644
index 0000000..eb3c292
--- /dev/null
+++ b/test/w3c/promela/test344.scxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that a cond expression that cannot be evaluated as a
+boolean cond expression evaluates to false and causes error.execution to be raised.
+In some languages, any valid expression/object can be converted to a boolean, so conf:nonBoolean will
+have to be mapped onto something that produces a syntax error or something similarly invalid -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <state id="s0">
+ <transition cond="return" target="fail"/>
+ <transition target="s1"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error.execution" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test346.scxml b/test/w3c/promela/test346.scxml
new file mode 100644
index 0000000..5d8dc30
--- /dev/null
+++ b/test/w3c/promela/test346.scxml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that any attempt to change the value of a system variable causes error.execution to be raised.
+Event1..4 are there to catch the case where the error event is not raised. In cases where it is, we have
+to dispose of eventn in the next state, hence the targetless transitions (which simply throw away the event.) -->
+<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" name="machineName">
+ <state id="s0">
+ <onentry>
+ <assign location="_sessionid" expr="'otherName'"/>
+ <raise event="event1"/>
+ </onentry>
+ <transition event="error.execution" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <assign location="_event" expr="'otherName'"/>
+ <raise event="event2"/>
+ </onentry>
+ <!-- throw out event1 if it's still around -->
+ <transition event="event1"/>
+ <transition event="error.execution" target="s2"/>
+ <!-- event1 would trigger this transition if we didn't drop it. We want this transition to have
+ a very general trigger to catch cases where the wrong error event was raised -->
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s2">
+ <onentry>
+ <assign location="_ioprocessors" expr="'otherName'"/>
+ <raise event="event3"/>
+ </onentry>
+ <transition event="event2"/>
+ <transition event="error.execution" target="s3"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s3">
+ <onentry>
+ <assign location="_name" expr="'otherName'"/>
+ <raise event="event4"/>
+ </onentry>
+ <transition event="event3"/>
+ <transition event="error.execution" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test347.scxml b/test/w3c/promela/test347.scxml
new file mode 100644
index 0000000..3b79584
--- /dev/null
+++ b/test/w3c/promela/test347.scxml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the scxml event I/O processor works by sending events back and forth between an invoked child
+and its parent process -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0" initial="s01">
+ <invoke id="child" type="scxml">
+ <content>
+ <scxml initial="sub0" version="1.0" datamodel="promela" name="machineName">
+ <state id="sub0">
+ <onentry>
+ <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" target="#_parent" event="childToParent"/>
+ </onentry>
+ <transition event="parentToChild" target="subFinal"/>
+ </state>
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <onentry>
+ <send delay="20s" event="timeout"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <state id="s01">
+ <transition event="childToParent" target="s02"/>
+ </state>
+ <state id="s02">
+ <onentry>
+ <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" target="#_child" event="parentToChild"/>
+ </onentry>
+ <transition event="done.invoke" target="pass"/>
+ <transition event="error" target="fail"/>
+ </state>
+ </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/promela/test348.scxml b/test/w3c/promela/test348.scxml
new file mode 100644
index 0000000..57d43d9
--- /dev/null
+++ b/test/w3c/promela/test348.scxml
@@ -0,0 +1,21 @@
+<?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" datamodel="promela" version="1.0">
+ <!-- test that event param of send sets the name of the event -->
+ <state id="s0">
+ <onentry>
+ <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" event="s0Event"/>
+ </onentry>
+ <transition event="s0Event" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test349.scxml b/test/w3c/promela/test349.scxml
new file mode 100644
index 0000000..57ac1cd
--- /dev/null
+++ b/test/w3c/promela/test349.scxml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that value in origin field can be used to send an event back to the sender -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" event="s0Event"/>
+ </onentry>
+ <transition event="s0Event" target="s2">
+ <assign location="Var1" expr="_event.origin"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s2">
+ <onentry>
+ <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" targetexpr="Var1" event="s0Event2"/>
+ </onentry>
+ <transition event="s0Event2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test350.scxml b/test/w3c/promela/test350.scxml
new file mode 100644
index 0000000..7ae6fe8
--- /dev/null
+++ b/test/w3c/promela/test350.scxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that target value is used to decide what session to deliver the event to. A session should be
+able to send an event to itself using its own session ID as the target -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="string" expr="'#_scxml_'"/>
+ <data id="Var2" type="string" expr="_sessionid"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + Var2"/>
+ <send delay="5s" event="timeout"/>
+ <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" targetexpr="Var1" event="s0Event"/>
+ </onentry>
+ <transition event="s0Event" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test351.scxml b/test/w3c/promela/test351.scxml
new file mode 100644
index 0000000..fb665ec
--- /dev/null
+++ b/test/w3c/promela/test351.scxml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that sendid is set in event if present in send, blank otherwise -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ <data id="Var2" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" id="send1" event="s0Event"/>
+ </onentry>
+ <transition event="s0Event" target="s1">
+ <assign location="Var1" expr="_event.sendid"/>
+ </transition>
+ <transition event="*" target="fail">
+ </transition>
+ </state>
+ <state id="s1">
+ <transition cond="Var1=='send1'" target="s2"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s2">
+ <onentry>
+ <send event="s0Event2"/>
+ </onentry>
+ <transition event="s0Event2" target="s3">
+ <assign location="Var2" expr="_event.sendid"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s3">
+ <transition cond="!Var2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test352.scxml b/test/w3c/promela/test352.scxml
new file mode 100644
index 0000000..464ee32
--- /dev/null
+++ b/test/w3c/promela/test352.scxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test the origintype is 'http://www.w3.org/TR/scxml/#SCXMLEventProcessor' -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" event="s0Event"/>
+ </onentry>
+ <transition event="s0Event" target="s1">
+ <assign location="Var1" expr="_event.origintype"/>
+ </transition>
+ <transition event="*" target="fail">
+ </transition>
+ </state>
+ <state id="s1">
+ <transition cond="Var1=='http://www.w3.org/TR/scxml/#SCXMLEventProcessor'" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test354.scxml b/test/w3c/promela/test354.scxml
new file mode 100644
index 0000000..91932ca
--- /dev/null
+++ b/test/w3c/promela/test354.scxml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that event.data can be populated using both namelist, param and <content>
+and that correct values are used -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ <data id="Var2" type="int"/>
+ <data id="Var3" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send delay="5s" event="timeout"/>
+ <send event="event1" type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" namelist="Var1">
+ <param name="param1" expr="2"/>
+ </send>
+ </onentry>
+ <transition event="event1" target="s1">
+ <assign location="Var2" expr="_event.data.Var1"/>
+ <assign location="Var3" expr="_event.data.param1"/>
+ </transition>
+ <transition event="*" target="fail">
+ </transition>
+ </state>
+ <state id="s1">
+ <transition cond="Var2==1" target="s2"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s2">
+ <transition cond="Var3==2" target="s3"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s3">
+ <onentry>
+ <send delay="5s" event="timeout"/>
+ <send event="event2">
+ <content>123</content>
+ </send>
+ </onentry>
+ <transition event="event2" cond="_event.data == 123" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test355.scxml b/test/w3c/promela/test355.scxml
new file mode 100644
index 0000000..91c6ecf
--- /dev/null
+++ b/test/w3c/promela/test355.scxml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that default initial state is first in document order. If we enter s0 first we succeed, if s1, failure. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="promela" version="1.0">
+ <state id="s0">
+ <transition target="pass"/>
+ </state>
+ <state id="s1">
+ <transition target="fail"/>
+ </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/promela/test364.scxml b/test/w3c/promela/test364.scxml
new file mode 100644
index 0000000..44ba527
--- /dev/null
+++ b/test/w3c/promela/test364.scxml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that default initial states are entered when a compound state is entered. First we test
+the 'initial' attribute, then the initial element, then default to the first child in document order.
+If we get to s01111 we succeed, if any other state, failure. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="promela" initial="s1" version="1.0">
+ <state id="s1" initial="s11p112 s11p122">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <state id="s11" initial="s111">
+ <state id="s111"/>
+ <parallel id="s11p1">
+ <state id="s11p11" initial="s11p111">
+ <state id="s11p111"/>
+ <state id="s11p112">
+ <onentry>
+ <raise event="In-s11p112"/>
+ </onentry>
+ </state>
+ </state>
+ <state id="s11p12" initial="s11p121">
+ <state id="s11p121"/>
+ <state id="s11p122">
+ <transition event="In-s11p112" target="s2"/>
+ </state>
+ </state>
+ </parallel>
+ </state>
+ </state>
+ <state id="s2">
+ <initial>
+ <transition target="s21p112 s21p122"/>
+ </initial>
+ <transition event="timeout" target="fail"/>
+ <state id="s21" initial="s211">
+ <state id="s211"/>
+ <parallel id="s21p1">
+ <state id="s21p11" initial="s21p111">
+ <state id="s21p111"/>
+ <state id="s21p112">
+ <onentry>
+ <raise event="In-s21p112"/>
+ </onentry>
+ </state>
+ </state>
+ <state id="s21p12" initial="s21p121">
+ <state id="s21p121"/>
+ <state id="s21p122">
+ <transition event="In-s21p112" target="s3"/>
+ </state>
+ </state>
+ </parallel>
+ </state>
+ </state>
+ <state id="s3">
+ <transition target="fail"/>
+ <state id="s31">
+ <state id="s311">
+ <state id="s3111">
+ <transition target="pass"/>
+ </state>
+ <state id="s3112"/>
+ <state id="s312"/>
+ <state id="s32"/>
+ </state>
+ </state>
+ </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/promela/test372.scxml b/test/w3c/promela/test372.scxml
new file mode 100644
index 0000000..6062428
--- /dev/null
+++ b/test/w3c/promela/test372.scxml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that entering a final state generates done.state.parentid after executing the onentry elements.
+Var1 should be set to 2 (but not 3) by the time the event is raised -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <state id="s0" initial="s0final">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="done.state.s0" cond="Var1==2" target="pass"/>
+ <transition event="*" target="fail"/>
+ <final id="s0final">
+ <onentry>
+ <assign location="Var1" expr="2"/>
+ </onentry>
+ <onexit>
+ <assign location="Var1" expr="3"/>
+ </onexit>
+ </final>
+ </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/promela/test375.scxml b/test/w3c/promela/test375.scxml
new file mode 100644
index 0000000..a78a9d1
--- /dev/null
+++ b/test/w3c/promela/test375.scxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that onentry handlers are executed in document order. event1 should be raised before event2 -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <raise event="event1"/>
+ </onentry>
+ <onentry>
+ <raise event="event2"/>
+ </onentry>
+ <transition event="event1" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition event="event2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test376.scxml b/test/w3c/promela/test376.scxml
new file mode 100644
index 0000000..d3d81bc
--- /dev/null
+++ b/test/w3c/promela/test376.scxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that each onentry handler is a separate block. The <send> of event1 will cause an error but
+ the increment to var1 should happen anyways -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send target="baz" event="event1"/>
+ </onentry>
+ <onentry>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onentry>
+ <transition cond="Var1==2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test377.scxml b/test/w3c/promela/test377.scxml
new file mode 100644
index 0000000..d105bbe
--- /dev/null
+++ b/test/w3c/promela/test377.scxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that onexit handlers are executed in document order. event1 should be raised before event2 -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onexit>
+ <raise event="event1"/>
+ </onexit>
+ <onexit>
+ <raise event="event2"/>
+ </onexit>
+ <transition target="s1"/>
+ </state>
+ <state id="s1">
+ <transition event="event1" target="s2"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s2">
+ <transition event="event2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test378.scxml b/test/w3c/promela/test378.scxml
new file mode 100644
index 0000000..e1c74c0
--- /dev/null
+++ b/test/w3c/promela/test378.scxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that each onexithandler is a separate block. The <send> of event1 will cause an error but
+ the increment to var1 should happen anyways -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <state id="s0">
+ <onexit>
+ <send target="baz" event="event1"/>
+ </onexit>
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onexit>
+ <transition target="s1"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var1==2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test387.scxml b/test/w3c/promela/test387.scxml
new file mode 100644
index 0000000..769d69b
--- /dev/null
+++ b/test/w3c/promela/test387.scxml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the default history state works correctly. From initial state s3 we take a transition to s0's default
+shallow history state. That should generate "enteringS011", which takes us to s4. In s4, we
+transition to s1's default deep history state. We should end up in s122, generating "enteringS122". Otherwise failure.-->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s3" version="1.0" datamodel="promela">
+ <state id="s0" initial="s01">
+ <transition event="enteringS011" target="s4"/>
+ <transition event="*" target="fail"/>
+ <history type="shallow" id="s0HistShallow">
+ <transition target="s01"/>
+ </history>
+ <history type="deep" id="s0HistDeep">
+ <transition target="s022"/>
+ </history>
+ <state id="s01" initial="s011">
+ <state id="s011">
+ <onentry>
+ <raise event="enteringS011"/>
+ </onentry>
+ </state>
+ <state id="s012">
+ <onentry>
+ <raise event="enteringS012"/>
+ </onentry>
+ </state>
+ </state>
+ <state id="s02" initial="s021">
+ <state id="s021">
+ <onentry>
+ <raise event="enteringS021"/>
+ </onentry>
+ </state>
+ <state id="s022">
+ <onentry>
+ <raise event="enteringS022"/>
+ </onentry>
+ </state>
+ </state>
+ </state>
+ <state id="s1" initial="s11">
+ <transition event="enteringS122" target="pass"/>
+ <transition event="*" target="fail"/>
+ <history type="shallow" id="s1HistShallow">
+ <transition target="s11"/>
+ </history>
+ <history type="deep" id="s1HistDeep">
+ <transition target="s122"/>
+ </history>
+ <state id="s11" initial="s111">
+ <state id="s111">
+ <onentry>
+ <raise event="enteringS111"/>
+ </onentry>
+ </state>
+ <state id="s112">
+ <onentry>
+ <raise event="enteringS112"/>
+ </onentry>
+ </state>
+ </state>
+ <state id="s12" initial="s121">
+ <state id="s121">
+ <onentry>
+ <raise event="enteringS121"/>
+ </onentry>
+ </state>
+ <state id="s122">
+ <onentry>
+ <raise event="enteringS122"/>
+ </onentry>
+ </state>
+ </state>
+ </state>
+ <state id="s3">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition target="s0HistShallow"/>
+ </state>
+ <state id="s4">
+ <transition target="s1HistDeep"/>
+ </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/promela/test388.scxml b/test/w3c/promela/test388.scxml
new file mode 100644
index 0000000..c6ffffc
--- /dev/null
+++ b/test/w3c/promela/test388.scxml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that history states works correctly. The counter Var1 counts how many times
+we have entered s0. The initial state is s012. We then transition to s1, which transitions
+to s0's deep history state. entering.s012 should be raised, otherwise failure. Then we transition
+to s02, which transitions to s0's shallow history state. That should have value s01, and its initial
+state is s011, so we should get entering.s011, otherwise failure.-->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s012" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0" initial="s01">
+ <onentry>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onentry>
+ <!-- the first time through, go to s1, setting a timer just in case something hangs -->
+ <transition event="entering.s012" cond="Var1==1" target="s1">
+ <send event="timeout" delay="2s"/>
+ </transition>
+ <!-- the second time, we should get entering.s012. If so, go to s2, otherwise fail -->
+ <transition event="entering.s012" cond="Var1==2" target="s2"/>
+ <transition event="entering" cond="Var1==2" target="fail"/>
+ <!-- the third time we should get entering-s011. If so, pass, otherwise fail -->
+ <transition event="entering.s011" cond="Var1==3" target="pass"/>
+ <transition event="entering" cond="Var1==3" target="fail"/>
+ <!-- if we timeout, the state machine is hung somewhere, so fail -->
+ <transition event="timeout" target="fail"/>
+ <history type="shallow" id="s0HistShallow">
+ <transition target="s02"/>
+ </history>
+ <history type="deep" id="s0HistDeep">
+ <transition target="s022"/>
+ </history>
+ <state id="s01" initial="s011">
+ <state id="s011">
+ <onentry>
+ <raise event="entering.s011"/>
+ </onentry>
+ </state>
+ <state id="s012">
+ <onentry>
+ <raise event="entering.s012"/>
+ </onentry>
+ </state>
+ </state>
+ <state id="s02" initial="s021">
+ <state id="s021">
+ <onentry>
+ <raise event="entering.s021"/>
+ </onentry>
+ </state>
+ <state id="s022">
+ <onentry>
+ <raise event="entering.s022"/>
+ </onentry>
+ </state>
+ </state>
+ </state>
+ <state id="s1">
+ <transition target="s0HistDeep"/>
+ </state>
+ <state id="s2">
+ <transition target="s0HistShallow"/>
+ </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/promela/test396.scxml b/test/w3c/promela/test396.scxml
new file mode 100644
index 0000000..745b7cf
--- /dev/null
+++ b/test/w3c/promela/test396.scxml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the value in _event.name matches the event name used to match against transitions -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="foo" cond="_event.name == 'foo'" target="pass"/>
+ <transition event="foo" target="fail"/>
+ </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/promela/test399.scxml b/test/w3c/promela/test399.scxml
new file mode 100644
index 0000000..5f4548a
--- /dev/null
+++ b/test/w3c/promela/test399.scxml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the event name matching works correctly, including prefix matching and the fact
+that the event attribute of transition may contain multiple event designators. -->
+<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">
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <!-- this will catch the failure case -->
+ <transition event="timeout" target="fail"/>
+ <state id="s01">
+ <onentry>
+ <raise event="foo"/>
+ </onentry>
+ <!-- test that an event can match against a transition with multiple descriptors -->
+ <transition event="foo bar" target="s02"/>
+ </state>
+ <state id="s02">
+ <onentry>
+ <raise event="bar"/>
+ </onentry>
+ <!-- test that an event can match the second descriptor as well -->
+ <transition event="foo bar" target="s03"/>
+ </state>
+ <state id="s03">
+ <onentry>
+ <raise event="foo.zoo"/>
+ </onentry>
+ <!-- test that a prefix descriptor matches -->
+ <transition event="foo bar" target="s04"/>
+ </state>
+ <state id="s04">
+ <onentry>
+ <raise event="foos"/>
+ </onentry>
+ <!-- test that only token prefixes match -->
+ <transition event="foo" target="fail"/>
+ <transition event="foos" target="s05"/>
+ </state>
+ <state id="s05">
+ <onentry>
+ <raise event="foo.zoo"/>
+ </onentry>
+ <!-- test that .* works at the end of a descriptor -->
+ <transition event="foo.*" target="s06"/>
+ </state>
+ <state id="s06">
+ <onentry>
+ <raise event="foo"/>
+ </onentry>
+ <!-- test that "*" works by itself -->
+ <transition event="*" target="pass"/>
+ </state>
+ </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/promela/test401.scxml b/test/w3c/promela/test401.scxml
new file mode 100644
index 0000000..96f3765
--- /dev/null
+++ b/test/w3c/promela/test401.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that errors go in the internal event queue. We send ourselves an external event foo, then perform
+and operation that raises an error. Then check that the error event is processed first, even though
+it was raised second -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="foo"/>
+ <!-- assigning to a non-existent location should raise an error -->
+ <assign location="foo.bar.baz " expr="2"/>
+ </onentry>
+ <transition event="foo" target="fail"/>
+ <transition event="error" target="pass"/>
+ </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/promela/test402.scxml b/test/w3c/promela/test402.scxml
new file mode 100644
index 0000000..3888751
--- /dev/null
+++ b/test/w3c/promela/test402.scxml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- the assertion that errors are 'like any other event' is pretty broad, but we can check that they
+are pulled off the internal queue in order, and that prefix matching works on them. -->
+<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">
+ <state id="s0" initial="s01">
+ <onentry>
+ <!-- catch the failure case -->
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <state id="s01">
+ <onentry>
+ <!-- the first internal event. The error will be the second, and event2 will be the third -->
+ <raise event="event1"/>
+ <!-- assigning to a non-existent location should raise an error -->
+ <assign location="foo.bar.baz " expr="2"/>
+ </onentry>
+ <transition event="event1" target="s02">
+ <raise event="event2"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s02">
+ <transition event="error" target="s03"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s03">
+ <transition event="event2" target="pass"/>
+ <transition event="*" target="fail"/>
+ </state>
+ </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/promela/test403a.scxml b/test/w3c/promela/test403a.scxml
new file mode 100644
index 0000000..5c8e398
--- /dev/null
+++ b/test/w3c/promela/test403a.scxml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test one part of 'optimal enablement' meaning that of all transitions that are enabled, we chose the ones
+in child states over parent states, and use document order to break ties. We have
+a parent state s0 with two children, s01 and s02. In s01, we test that a) if
+a transition in the child matches, we don't consider matches in the parent and b)
+that if two transitions match in any state, we take the first in document order.
+In s02 we test that we take a transition in the parent if there is no
+matching transition in the child. -->
+<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">
+ <state id="s0" initial="s01">
+ <onentry>
+ <!-- catch the failure case -->
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <transition event="event1" target="fail"/>
+ <transition event="event2" target="pass"/>
+ <state id="s01">
+ <onentry>
+ <!-- this should be caught by the first transition in this state, taking us to S02 -->
+ <raise event="event1"/>
+ </onentry>
+ <transition event="event1" target="s02"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s02">
+ <onentry>
+ <!-- since the local transition has a cond that evaluates to false this should be caught by a
+ transition in the parent state, taking us to pass -->
+ <raise event="event2"/>
+ </onentry>
+ <transition event="event1" target="fail"/>
+ <transition event="event2" cond="false" target="fail"/>
+ </state>
+ </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/promela/test403b.scxml b/test/w3c/promela/test403b.scxml
new file mode 100644
index 0000000..5c28ee2
--- /dev/null
+++ b/test/w3c/promela/test403b.scxml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that 'optimally enabled set' really is a set, specifically that if a transition is optimally enabled in
+two different states, it is taken only once. -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0" initial="p0">
+ <!-- this transition should never be taken because a transition in a lower state should
+ always be selected -->
+ <transition event="event1">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </transition>
+ <parallel id="p0">
+ <onentry>
+ <raise event="event1"/>
+ <raise event="event2"/>
+ </onentry>
+ <!-- this transition will be selected by both states p0s1 and p0s2, but should be executed only once -->
+ <transition event="event1">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </transition>
+ <state id="p0s1">
+ <transition event="event2" cond="Var1==1" target="pass"/>
+ <transition event="event2" target="fail"/>
+ </state>
+ <state id="p0s2"/>
+ </parallel>
+ </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/promela/test403c.scxml b/test/w3c/promela/test403c.scxml
new file mode 100644
index 0000000..335fc2e
--- /dev/null
+++ b/test/w3c/promela/test403c.scxml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test 'optimally enabled set', specifically that preemption works correctly -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0" initial="p0">
+ <onentry>
+ <raise event="event1"/>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="event2" target="fail"/>
+ <transition event="timeout" target="fail"/>
+ <parallel id="p0">
+ <state id="p0s1">
+ <transition event="event1"/>
+ <transition event="event2"/>
+ </state>
+ <state id="p0s2">
+ <transition event="event1" target="p0s1">
+ <raise event="event2"/>
+ </transition>
+ </state>
+ <state id="p0s3">
+ <!-- this transition should be blocked by the one in p0s2-->
+ <transition event="event1" target="fail"/>
+ <!-- this transition will preempt the one that p0s2 inherits
+ from an ancestor -->
+ <transition event="event2" target="s1"/>
+ </state>
+ <state id="p0s4">
+ <!-- this transition never gets preempted, should fire twice -->
+ <transition event="*">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </transition>
+ </state>
+ </parallel>
+ </state>
+ <state id="s1">
+ <transition cond="Var1==2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test404.scxml b/test/w3c/promela/test404.scxml
new file mode 100644
index 0000000..ce61f1e
--- /dev/null
+++ b/test/w3c/promela/test404.scxml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that states are exited in exit order (children before parents with reverse doc order used to break ties
+ before the executable content in the transitions. event1, event2, event3, event4 should be raised in that
+ order when s01p is exited -->
+<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">
+ <state id="s0" initial="s01p">
+ <parallel id="s01p">
+ <onexit>
+ <!-- this should be the 3rd event raised -->
+ <raise event="event3"/>
+ </onexit>
+ <transition target="s02">
+ <!-- this should be the fourth event raised -->
+ <raise event="event4"/>
+ </transition>
+ <state id="s01p1">
+ <onexit>
+ <!-- this should be the second event raised -->
+ <raise event="event2"/>
+ </onexit>
+ </state>
+ <state id="s01p2">
+ <!-- this should be the first event raised -->
+ <onexit>
+ <raise event="event1"/>
+ </onexit>
+ </state>
+ </parallel>
+ <state id="s02">
+ <transition event="event1" target="s03"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s03">
+ <transition event="event2" target="s04"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s04">
+ <transition event="event3" target="s05"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s05">
+ <transition event="event4" target="pass"/>
+ <transition event="*" target="fail"/>
+ </state>
+ </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/promela/test405.scxml b/test/w3c/promela/test405.scxml
new file mode 100644
index 0000000..ce89b3a
--- /dev/null
+++ b/test/w3c/promela/test405.scxml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the executable content in the transitions is executed in document order after
+the states are exited. event1, event2, event3, event4 should be raised in that order when the
+state machine is entered -->
+<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">
+ <state id="s0" initial="s01p">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <parallel id="s01p">
+ <transition event="event1" target="s02"/>
+ <state id="s01p1" initial="s01p11">
+ <state id="s01p11">
+ <onexit>
+ <!-- this should be the second event raised -->
+ <raise event="event2"/>
+ </onexit>
+ <transition target="s01p12">
+ <!-- this should be the third event raised -->
+ <raise event="event3"/>
+ </transition>
+ </state>
+ <state id="s01p12"/>
+ </state>
+ <!-- end s01p1 -->
+ <state id="s01p2" initial="s01p21">
+ <state id="s01p21">
+ <onexit>
+ <!-- this should be the first event raised -->
+ <raise event="event1"/>
+ </onexit>
+ <transition target="s01p22">
+ <!-- this should be the fourth event raised -->
+ <raise event="event4"/>
+ </transition>
+ </state>
+ <state id="s01p22"/>
+ </state>
+ <!-- end s01p2 -->
+ </parallel>
+ <state id="s02">
+ <transition event="event2" target="s03"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s03">
+ <transition event="event3" target="s04"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s04">
+ <transition event="event4" target="pass"/>
+ <transition event="*" target="fail"/>
+ </state>
+ </state>
+ <!-- end s01 -->
+ <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/promela/test406.scxml b/test/w3c/promela/test406.scxml
new file mode 100644
index 0000000..99c4c40
--- /dev/null
+++ b/test/w3c/promela/test406.scxml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Test that states are entered in entry order (parents before children with document order used to break ties)
+after the executable content in the transition is executed. event1, event2, event3, event4 should be raised in that
+order when the transition in s01 is taken -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" datamodel="promela">
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <state id="s01">
+ <transition target="s0p2">
+ <!-- this should be the first event raised -->
+ <raise event="event1"/>
+ </transition>
+ </state>
+ <parallel id="s0p2">
+ <transition event="event1" target="s03"/>
+ <state id="s01p21">
+ <onentry>
+ <!-- third event -->
+ <raise event="event3"/>
+ </onentry>
+ </state>
+ <state id="s01p22">
+ <onentry>
+ <!-- the fourth event -->
+ <raise event="event4"/>
+ </onentry>
+ </state>
+ <onentry>
+ <!-- this should be the second event raised -->
+ <raise event="event2"/>
+ </onentry>
+ </parallel>
+ <state id="s03">
+ <transition event="event2" target="s04"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s04">
+ <transition event="event3" target="s05"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s05">
+ <transition event="event4" target="pass"/>
+ <transition event="*" target="fail"/>
+ </state>
+ </state>
+ <!-- end s0 -->
+ <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/promela/test407.scxml b/test/w3c/promela/test407.scxml
new file mode 100644
index 0000000..9260c05
--- /dev/null
+++ b/test/w3c/promela/test407.scxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- a simple test that onexit handlers work. var1 should be incremented when we leave s0 -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s0">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onexit>
+ <transition target="s1"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var1==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test409.scxml b/test/w3c/promela/test409.scxml
new file mode 100644
index 0000000..98e3c81
--- /dev/null
+++ b/test/w3c/promela/test409.scxml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that states are removed from the active states list as they are exited. When s01's onexit handler
+fires, s011 should not be on the active state list, so in(S011) should be false, and event1 should not
+be raised. Therefore the timeout should fire to indicate success -->
+<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">
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delayexpr="'1s'"/>
+ </onentry>
+ <transition event="timeout" target="pass"/>
+ <transition event="event1" target="fail"/>
+ <state id="s01" initial="s011">
+ <onexit>
+ <if cond="_x.states['s011']">
+ <raise event="event1"/>
+ </if>
+ </onexit>
+ <state id="s011">
+ <transition target="s02"/>
+ </state>
+ </state>
+ <!-- end s01 -->
+ <state id="s02"/>
+ </state>
+ <!-- end s0 -->
+ <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/promela/test411.scxml b/test/w3c/promela/test411.scxml
new file mode 100644
index 0000000..aae7e3c
--- /dev/null
+++ b/test/w3c/promela/test411.scxml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that states are added to the active states list as they are entered and before onentry handlers
+are executed. When s0's onentry handler fires we should not be in s01. But when s01's onentry handler
+fires, we should be in s01. Therefore event1 should not fire, but event2 should. Either event1 or
+timeout also indicates failure -->
+<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">
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ <if cond="_x.states['s01']">
+ <raise event="event1"/>
+ </if>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <transition event="event1" target="fail"/>
+ <transition event="event2" target="pass"/>
+ <state id="s01">
+ <onentry>
+ <if cond="_x.states['s01']">
+ <raise event="event2"/>
+ </if>
+ </onentry>
+ </state>
+ </state>
+ <!-- end s0 -->
+ <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/promela/test412.scxml b/test/w3c/promela/test412.scxml
new file mode 100644
index 0000000..cc362be
--- /dev/null
+++ b/test/w3c/promela/test412.scxml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that executable content in the <initial> transition executes after the onentry handler on the state
+and before the onentry handler of the child states. Event1, event2, and event3 should occur in that order. -->
+<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">
+ <state id="s0" initial="s01">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <transition event="event1" target="fail"/>
+ <transition event="event2" target="pass"/>
+ <state id="s01">
+ <onentry>
+ <raise event="event1"/>
+ </onentry>
+ <initial>
+ <transition target="s011">
+ <raise event="event2"/>
+ </transition>
+ </initial>
+ <state id="s011">
+ <onentry>
+ <raise event="event3"/>
+ </onentry>
+ <transition target="s02"/>
+ </state>
+ </state>
+ <state id="s02">
+ <transition event="event1" target="s03"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s03">
+ <transition event="event2" target="s04"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s04">
+ <transition event="event3" target="pass"/>
+ <transition event="*" target="fail"/>
+ </state>
+ </state>
+ <!-- end s0 -->
+ <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/promela/test413.scxml b/test/w3c/promela/test413.scxml
new file mode 100644
index 0000000..2efec12
--- /dev/null
+++ b/test/w3c/promela/test413.scxml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the state machine is put into the configuration specified by the initial element, without regard
+to any other defaults. we should start off in s2p111 and s2p122. the atomic
+states we should not enter all have immediate transitions to failure in them -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s2p112 s2p122" version="1.0" datamodel="promela">
+ <state id="s1">
+ <transition target="fail"/>
+ </state>
+ <state id="s2" initial="s2p1">
+ <parallel id="s2p1">
+ <!-- this transition will be triggered only if we end up in an illegal configuration where we're in
+ either s2p112 or s2p122, but not both of them -->
+ <transition target="fail"/>
+ <state id="s2p11" initial="s2p111">
+ <state id="s2p111">
+ <transition target="fail"/>
+ </state>
+ <state id="s2p112">
+ <transition cond="_x.states['s2p122']" target="pass"/>
+ </state>
+ </state>
+ <!-- end s2p11 -->
+ <state id="s2p12" initial="s2p121">
+ <state id="s2p121">
+ <transition target="fail"/>
+ </state>
+ <state id="s2p122">
+ <transition cond="_x.states['s2p112']" target="pass"/>
+ </state>
+ </state>
+ </parallel>
+ </state>
+ <!-- end s2 -->
+ <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/promela/test415.scxml b/test/w3c/promela/test415.scxml
new file mode 100644
index 0000000..64d0c18
--- /dev/null
+++ b/test/w3c/promela/test415.scxml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Test that the state machine halts when it enters a top-level final state. Since
+ the initial state is a final state, this machine should halt immediately without
+ processing "event1" which is raised in the final state's on-entry handler. This
+ is a manual test since there is no platform-independent way to test that event1
+ is not processed -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="final" version="1.0" datamodel="promela">
+ <final id="final">
+ <onentry>
+ <raise event="event1"/>
+ </onentry>
+ </final>
+</scxml>
diff --git a/test/w3c/promela/test416.scxml b/test/w3c/promela/test416.scxml
new file mode 100644
index 0000000..763a48a
--- /dev/null
+++ b/test/w3c/promela/test416.scxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the done.state.id gets generated when we enter the final state of a compound state -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s1" datamodel="promela">
+ <state id="s1" initial="s11">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <state id="s11" initial="s111">
+ <transition event="done.state.s11" target="pass"/>
+ <state id="s111">
+ <transition target="s11final"/>
+ </state>
+ <final id="s11final"/>
+ </state>
+ </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/promela/test417.scxml b/test/w3c/promela/test417.scxml
new file mode 100644
index 0000000..abe4aa1
--- /dev/null
+++ b/test/w3c/promela/test417.scxml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that we get the done.state.id event when all of a
+parallel elements children enter final states. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s1" datamodel="promela">
+ <state id="s1" initial="s1p1">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <parallel id="s1p1">
+ <transition event="done.state.s1p1" target="pass"/>
+ <state id="s1p11" initial="s1p111">
+ <state id="s1p111">
+ <transition target="s1p11final"/>
+ </state>
+ <final id="s1p11final"/>
+ </state>
+ <state id="s1p12" initial="s1p121">
+ <state id="s1p121">
+ <transition target="s1p12final"/>
+ </state>
+ <final id="s1p12final"/>
+ </state>
+ </parallel>
+ </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/promela/test419.scxml b/test/w3c/promela/test419.scxml
new file mode 100644
index 0000000..1a26d2f
--- /dev/null
+++ b/test/w3c/promela/test419.scxml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that eventless transitions take precedence over event-driven ones -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s1" datamodel="promela">
+ <state id="s1">
+ <onentry>
+ <raise event="internalEvent"/>
+ <send event="externalEvent"/>
+ </onentry>
+ <transition event="*" target="fail"/>
+ <transition target="pass"/>
+ </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/promela/test421.scxml b/test/w3c/promela/test421.scxml
new file mode 100644
index 0000000..09483d2
--- /dev/null
+++ b/test/w3c/promela/test421.scxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that internal events take priority over external ones, and that the processor
+keeps pulling off internal events until it finds one that triggers a transition -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s1" datamodel="promela">
+ <state id="s1" initial="s11">
+ <onentry>
+ <send event="externalEvent"/>
+ <raise event="internalEvent1"/>
+ <raise event="internalEvent2"/>
+ <raise event="internalEvent3"/>
+ <raise event="internalEvent4"/>
+ </onentry>
+ <transition event="externalEvent" target="fail"/>
+ <state id="s11">
+ <transition event="internalEvent3" target="s12"/>
+ </state>
+ <state id="s12">
+ <transition event="internalEvent4" target="pass"/>
+ </state>
+ </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/promela/test422.scxml b/test/w3c/promela/test422.scxml
new file mode 100644
index 0000000..bc99d52
--- /dev/null
+++ b/test/w3c/promela/test422.scxml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Test that at the end of a macrostep, the processor executes all invokes in states
+that have been entered and not exited during the step. (The invokes are supposed to be executed
+in document order, but we can test that since each invocation is separate and they may take
+different amounts to time to start up.) In this case, there are three invoke statements,
+in states s1, s11 and s12. Each invoked process returns an event named after its parent state.
+The invokes in s1 and s12 should execute, but not the one
+in s11. So we should receive invokeS1, invokeS12, but not invokeS12. Furthermore, when the timeout fires, var1 should equal 2.-->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s1" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <state id="s1" initial="s11">
+ <onentry>
+ <send event="timeout" delayexpr="'2s'"/>
+ </onentry>
+ <transition event="invokeS1 invokeS12">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </transition>
+ <transition event="invokeS11" target="fail"/>
+ <transition event="timeout" cond="Var1==2" target="pass"/>
+ <transition event="timeout" target="fail"/>
+ <invoke>
+ <content>
+ <!-- when invoked, send 'foo' to parent, then terminate. -->
+ <scxml initial="sub0" version="1.0" datamodel="promela">
+ <state id="sub0">
+ <onentry>
+ <send target="#_parent" event="invokeS1"/>
+ </onentry>
+ <transition target="subFinal0"/>
+ </state>
+ <final id="subFinal0"/>
+ </scxml>
+ </content>
+ </invoke>
+ <state id="s11">
+ <invoke>
+ <content>
+ <!-- when invoked, send 'foo' to parent, then terminate. -->
+ <scxml initial="sub1" version="1.0" datamodel="promela">
+ <state id="sub1">
+ <onentry>
+ <send target="#_parent" event="invokeS11"/>
+ </onentry>
+ <transition target="subFinal1"/>
+ </state>
+ <final id="subFinal1"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition target="s12"/>
+ </state>
+ <state id="s12">
+ <invoke>
+ <content>
+ <!-- when invoked, send 'foo' to parent, then terminate. -->
+ <scxml initial="sub2" version="1.0" datamodel="promela">
+ <state id="sub2">
+ <onentry>
+ <send target="#_parent" event="invokeS12"/>
+ </onentry>
+ <transition target="subFinal2"/>
+ </state>
+ <final id="subFinal2"/>
+ </scxml>
+ </content>
+ </invoke>
+ </state>
+ </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/promela/test423.scxml b/test/w3c/promela/test423.scxml
new file mode 100644
index 0000000..6d87d30
--- /dev/null
+++ b/test/w3c/promela/test423.scxml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that we keep pulling external events off the queue till we find one that matches a transition. -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="externalEvent1"/>
+ <send event="externalEvent2" delayexpr="'1s'"/>
+ <raise event="internalEvent"/>
+ </onentry>
+ <!-- in this state we should process only internalEvent -->
+ <transition event="internalEvent" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <!-- in this state we ignore externalEvent1 and wait for externalEvent2 -->
+ <transition event="externalEvent2" target="pass"/>
+ <transition event="internalEvent" target="fail"/>
+ </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/promela/test436.scxml b/test/w3c/promela/test436.scxml
new file mode 100644
index 0000000..413b9ec
--- /dev/null
+++ b/test/w3c/promela/test436.scxml
@@ -0,0 +1,23 @@
+<?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="_x.states['s1']" target="fail"/>
+ <transition cond="_x.states['ps1']" target="pass"/>
+ <transition target="fail"/>
+ </state>
+ <state id="ps1"/>
+ </parallel>
+ <state id="s1"/>
+ <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/promela/test446.txt b/test/w3c/promela/test446.txt
new file mode 100644
index 0000000..3a26a2e
--- /dev/null
+++ b/test/w3c/promela/test446.txt
@@ -0,0 +1 @@
+[1,2,3] \ No newline at end of file
diff --git a/test/w3c/promela/test487.scxml b/test/w3c/promela/test487.scxml
new file mode 100644
index 0000000..3b81768
--- /dev/null
+++ b/test/w3c/promela/test487.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test illegal assignment. error.execution should be raised. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1" expr="return"/>
+ <raise event="event"/>
+ </onentry>
+ <transition event="error.execution" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test488.scxml b/test/w3c/promela/test488.scxml
new file mode 100644
index 0000000..78154b4
--- /dev/null
+++ b/test/w3c/promela/test488.scxml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that illegal expr in <param> produces error.execution and empty event.data -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <state id="s0" initial="s01">
+ <!-- we should get the error before the done event -->
+ <transition event="error.execution" target="s1"/>
+ <transition event="done.state.s0" target="fail"/>
+ <transition event="done.state.s0" target="fail">
+ </transition>
+ <state id="s01">
+ <transition target="s02"/>
+ </state>
+ <final id="s02">
+ <donedata>
+ <param expr="return" name="someParam"/>
+ </donedata>
+ </final>
+ </state>
+ <!-- if we get here, we received the error event. Now check that the done
+ event has empty event.data -->
+ <state id="s1">
+ <transition event="done.state.s0" cond="!(_event.data)" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test495.scxml b/test/w3c/promela/test495.scxml
new file mode 100644
index 0000000..2c07a91
--- /dev/null
+++ b/test/w3c/promela/test495.scxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the scxml event i/o processor puts events in the correct queues.-->
+<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">
+ <state id="s0">
+ <onentry>
+ <!-- default target is external queue -->
+ <send event="event1" type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor"/>
+ <send event="event2" target="#_internal" type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor"/>
+ </onentry>
+ <!-- we should get the internal event first -->
+ <transition event="event1" target="fail"/>
+ <transition event="event2" target="s1"/>
+ </state>
+ <state id="s1">
+ <transition event="event1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test496.scxml b/test/w3c/promela/test496.scxml
new file mode 100644
index 0000000..c3babeb
--- /dev/null
+++ b/test/w3c/promela/test496.scxml
@@ -0,0 +1,21 @@
+<?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">
+ <state id="s0">
+ <onentry>
+ <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" event="event" target="#_scxml_foo"/>
+ <raise event="foo"/>
+ </onentry>
+ <transition event="error.communication" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test500.scxml b/test/w3c/promela/test500.scxml
new file mode 100644
index 0000000..0b046d0
--- /dev/null
+++ b/test/w3c/promela/test500.scxml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that location field is found inside entry for SCXML Event I/O processor -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="_ioprocessors.scxml.location"/>
+ </datamodel>
+ <state id="s0">
+ <transition cond="Var1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test501.scxml b/test/w3c/promela/test501.scxml
new file mode 100644
index 0000000..02ae229
--- /dev/null
+++ b/test/w3c/promela/test501.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the location entry for the SCXML Event I/O processor can be used as the target for an event -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="_ioprocessors.scxml.location"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send targetexpr="Var1" event="foo"/>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <transition event="foo" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test503.scxml b/test/w3c/promela/test503.scxml
new file mode 100644
index 0000000..5914d69
--- /dev/null
+++ b/test/w3c/promela/test503.scxml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that a targetless transition does not exit and reenter its source state -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s1" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ <!-- how often we have exited s2 -->
+ <data id="Var2" type="int" expr="0"/>
+ <!-- how often the targetless transition in s2 has been executed -->
+ </datamodel>
+ <state id="s1">
+ <onentry>
+ <raise event="foo"/>
+ <raise event="bar"/>
+ </onentry>
+ <transition target="s2"/>
+ </state>
+ <state id="s2">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onexit>
+ <transition event="foo">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var2" expr="Var2 + 1"/>
+ </transition>
+ <!-- make sure the transition on foo was actually taken -->
+ <transition event="bar" cond="Var2==1" target="s3"/>
+ <transition event="bar" target="fail"/>
+ </state>
+ <state id="s3">
+ <!-- make sure that s2 was exited only once -->
+ <transition cond="Var1==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test504.scxml b/test/w3c/promela/test504.scxml
new file mode 100644
index 0000000..0aa69b4
--- /dev/null
+++ b/test/w3c/promela/test504.scxml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that an external transition exits all states up the the LCCA -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s1" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ <!-- how often we have exited p -->
+ <data id="Var2" type="int" expr="0"/>
+ <!-- how often we have exited ps1 -->
+ <data id="Var3" type="int" expr="0"/>
+ <!-- how often we have exited ps2 -->
+ <data id="Var4" type="int" expr="0"/>
+ <!-- how often the transition for foo has been taken -->
+ <data id="Var5" type="int" expr="0"/>
+ <!-- how often we have exited s2 -->
+ </datamodel>
+ <state id="s1">
+ <onentry>
+ <raise event="foo"/>
+ <raise event="bar"/>
+ </onentry>
+ <transition target="p"/>
+ </state>
+ <state id="s2">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var5" expr="Var5 + 1"/>
+ </onexit>
+ <parallel id="p">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onexit>
+ <transition event="foo" target="ps1">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var4" expr="Var4 + 1"/>
+ </transition>
+ <!-- make sure the transition on foo was actually taken -->
+ <transition event="bar" cond="Var4==1" target="s3"/>
+ <transition event="bar" target="fail"/>
+ <state id="ps1">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var2" expr="Var2 + 1"/>
+ </onexit>
+ </state>
+ <state id="ps2">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var3" expr="Var3 + 1"/>
+ </onexit>
+ </state>
+ </parallel>
+ </state>
+ <state id="s3">
+ <!-- make sure that p was exited twice -->
+ <transition cond="Var1==2" target="s4"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s4">
+ <!-- make sure that ps1 was exited twice -->
+ <transition cond="Var2==2" target="s5"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s5">
+ <!-- make sure that ps2 was exited twice -->
+ <transition cond="Var3==2" target="s6"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s6">
+ <!-- make sure that s1 was exited once -->
+ <transition cond="Var5==1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test505.scxml b/test/w3c/promela/test505.scxml
new file mode 100644
index 0000000..02e18b0
--- /dev/null
+++ b/test/w3c/promela/test505.scxml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that an internal transition does not exit its source state -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s1" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ <!-- how often we have exited s1 -->
+ <data id="Var2" type="int" expr="0"/>
+ <!-- how often we have exited s11 -->
+ <data id="Var3" type="int" expr="0"/>
+ <!-- how often the transition for foo has been taken -->
+ </datamodel>
+ <state id="s1">
+ <onentry>
+ <raise event="foo"/>
+ <raise event="bar"/>
+ </onentry>
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onexit>
+ <transition event="foo" type="internal" target="s11">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var3" expr="Var3 + 1"/>
+ </transition>
+ <!-- make sure the transition on foo was actually taken -->
+ <transition event="bar" cond="Var3==1" target="s2"/>
+ <transition event="bar" target="fail"/>
+ <state id="s11">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var2" expr="Var2 + 1"/>
+ </onexit>
+ </state>
+ </state>
+ <state id="s2">
+ <!-- make sure that s1 was exited once -->
+ <transition cond="Var1==1" target="s3"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s3">
+ <!-- make sure that s11 was exited twice -->
+ <transition cond="Var2==2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test506.scxml b/test/w3c/promela/test506.scxml
new file mode 100644
index 0000000..83b05b9
--- /dev/null
+++ b/test/w3c/promela/test506.scxml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that an internal transition whose targets are not proper descendants of its source state
+behaves like an external transition -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s1" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ <!-- how often we have exited s2 -->
+ <data id="Var2" type="int" expr="0"/>
+ <!-- how often we have exited s21 -->
+ <data id="Var3" type="int" expr="0"/>
+ <!-- how often the transition for foo has been taken -->
+ </datamodel>
+ <state id="s1">
+ <onentry>
+ <raise event="foo"/>
+ <raise event="bar"/>
+ </onentry>
+ <transition target="s2"/>
+ </state>
+ <state id="s2" initial="s21">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onexit>
+ <transition event="foo" type="internal" target="s2">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var3" expr="Var3 + 1"/>
+ </transition>
+ <!-- make sure the transition on foo was actually taken -->
+ <transition event="bar" cond="Var3==1" target="s3"/>
+ <transition event="bar" target="fail"/>
+ <state id="s21">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var2" expr="Var2 + 1"/>
+ </onexit>
+ </state>
+ </state>
+ <state id="s3">
+ <!-- make sure that s2 was exited twice -->
+ <transition cond="Var1==2" target="s4"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s4">
+ <!-- make sure that s21 was exited twice -->
+ <transition cond="Var2==2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test509.scxml b/test/w3c/promela/test509.scxml
new file mode 100644
index 0000000..4b7f540
--- /dev/null
+++ b/test/w3c/promela/test509.scxml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that Basic HTTP Event I/O processor uses POST method and that it can receive messages
+at the accessURI -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="30s"/>
+ <send event="test" targetexpr="_ioprocessors.basichttp.location" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"/>
+ </onentry>
+ <!-- if the event was send by http and we get it, we succeed -->
+ <transition event="test" cond="_event.raw.search('POST') !== -1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test510.scxml b/test/w3c/promela/test510.scxml
new file mode 100644
index 0000000..fbb2f25
--- /dev/null
+++ b/test/w3c/promela/test510.scxml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that Basic HTTP messages go into external queue. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="30s"/>
+ <send event="test" targetexpr="_ioprocessors.basichttp.location" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"/>
+ <!-- this creates an internal event -->
+ <raise event="internal"/>
+ </onentry>
+ <!-- we should get 'internal' first, then 'test' -->
+ <transition event="internal" target="s1"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition event="test" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test513.txt b/test/w3c/promela/test513.txt
new file mode 100644
index 0000000..08e9b01
--- /dev/null
+++ b/test/w3c/promela/test513.txt
@@ -0,0 +1,16 @@
+This is a fully manual test. You send a well formed event to the 'location' URL
+ specified for your SCXML interpreter and check that you get a 200 response code back.
+ One way of doing this, using wget, is shown below (you can use any event name you
+ want, but you must use '_scxmleventname' to indicate the name of the event):
+
+$ wget \
+--post-data='key1=value1&key2=value2' \
+--header '_scxmleventname: test' \
+<!-- URL of your processor goes here -->
+
+--2014-06-25 17:54:49-- http://epikur.local:8090/925c760f-2093-4054-a24c-d972d75f0dcd/basichttp
+Resolving epikur.local (epikur.local)... 10.211.55.2, 10.37.129.2, 10.0.1.54, ...
+Connecting to epikur.local (epikur.local)|10.211.55.2|:8090... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 0 [text/html]
+Saving to: ‘basichttp’ \ No newline at end of file
diff --git a/test/w3c/promela/test518.scxml b/test/w3c/promela/test518.scxml
new file mode 100644
index 0000000..d6f88d3
--- /dev/null
+++ b/test/w3c/promela/test518.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that that namelist values get encoded as POST parameters. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int" expr="2"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="30s"/>
+ <send event="test" targetexpr="_ioprocessors.basichttp.location" namelist="Var1" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"/>
+ </onentry>
+ <transition event="test" cond="_event.raw.search(/Var1=2/) !== -1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test519.scxml b/test/w3c/promela/test519.scxml
new file mode 100644
index 0000000..f3645c0
--- /dev/null
+++ b/test/w3c/promela/test519.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that that <param> values get encoded as POST parameters. . -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="30s"/>
+ <send event="test" targetexpr="_ioprocessors.basichttp.location" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor">
+ <param name="param1" expr="1"/>
+ </send>
+ </onentry>
+ <!-- if other end sends us back this event, we succeed -->
+ <transition event="test" cond="_event.raw.search('param1=1') !== -1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test520.scxml b/test/w3c/promela/test520.scxml
new file mode 100644
index 0000000..f25f8d3
--- /dev/null
+++ b/test/w3c/promela/test520.scxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that that <content> gets sent as the body of the message. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="30s"/>
+ <send targetexpr="_ioprocessors.basichttp.location" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor">
+ <content>this is some content</content>
+ </send>
+ </onentry>
+ <!-- if other end sends us back this event, we succeed. Test for two common
+ ways of encoding -->
+ <transition event="HTTP.POST" cond="_event.raw.search(/this+is+some+content/) !== -1" target="pass"/>
+ <transition event="HTTP.POST" cond="_event.raw.search(/this%20is%20some%20content/) !== -1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test521.scxml b/test/w3c/promela/test521.scxml
new file mode 100644
index 0000000..f5e5859
--- /dev/null
+++ b/test/w3c/promela/test521.scxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that the processor raises error.communication if it cannot dispatch the event.
+(To create an undispatchable event, we choose a non-existent session as target). If it raises
+the error event, we succeed. Otherwise we eventually timeout and fail. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <!-- should cause an error -->
+ <send target="#_scxml_foo" event="event2"/>
+ <!-- this will get added to the external event queue after the error has been raised -->
+ <send event="timeout"/>
+ </onentry>
+ <!-- once we've entered the state, we should check for internal events first -->
+ <transition event="error.communication" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test522.scxml b/test/w3c/promela/test522.scxml
new file mode 100644
index 0000000..e31c289
--- /dev/null
+++ b/test/w3c/promela/test522.scxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that location field the entry for Basic HTTP Event I/O processor can be used
+to send a message to the processor -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="30s"/>
+ <send event="test" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor" targetexpr="_ioprocessors.basichttp.location"/>
+ </onentry>
+ <!-- the event we receive should be called 'test', but that's not actually
+ required for this test. Only that the send deliver some event to us. So if
+ we get something other than timeout or error, we call it success -->
+ <transition event="timeout" target="fail"/>
+ <transition event="error" target="fail"/>
+ <transition event="*" target="pass"/>
+ </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/promela/test525.scxml b/test/w3c/promela/test525.scxml
new file mode 100644
index 0000000..5df4afa
--- /dev/null
+++ b/test/w3c/promela/test525.scxml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that <foreach> does a shallow copy, so that modifying the array does not change
+the iteration behavior. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int[3]">
+
+ Var1[0] = 1;
+ Var1[1] = 2;
+ Var1[2] = 3;
+
+ </data>
+ <data id="Var2" type="int" expr="0"/>
+ <!-- counts the number of iterations -->
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <foreach item="Var3" array="Var1">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="[].concat(Var1, [4])"/>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var2" expr="Var2 + 1"/>
+ </foreach>
+ </onentry>
+ <transition cond="Var2==3" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test527.scxml b/test/w3c/promela/test527.scxml
new file mode 100644
index 0000000..337c027
--- /dev/null
+++ b/test/w3c/promela/test527.scxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- simple test that 'expr' works with <content> -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <state id="s0" initial="s01">
+ <transition event="done.state.s0" cond="_event.data == 'foo'" target="pass">
+ </transition>
+ <transition event="done.state.s0" target="fail">
+ </transition>
+ <state id="s01">
+ <transition target="s02"/>
+ </state>
+ <final id="s02">
+ <donedata>
+ <content expr="'foo'"/>
+ </donedata>
+ </final>
+ </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/promela/test528.scxml b/test/w3c/promela/test528.scxml
new file mode 100644
index 0000000..8b79479
--- /dev/null
+++ b/test/w3c/promela/test528.scxml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that illegal 'expr' produces error.execution and empty event.data -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <state id="s0" initial="s01">
+ <!-- we should get the error before the done event -->
+ <transition event="error.execution" target="s1"/>
+ <transition event="done.state.s0" target="fail"/>
+ <state id="s01">
+ <transition target="s02"/>
+ </state>
+ <final id="s02">
+ <donedata>
+ <content expr="return"/>
+ </donedata>
+ </final>
+ </state>
+ <!-- if we get here, we received the error event. Now check that the done
+ event has empty event.data -->
+ <state id="s1">
+ <transition event="done.state.s0" cond="!(_event.data)" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test529.scxml b/test/w3c/promela/test529.scxml
new file mode 100644
index 0000000..4d5347c
--- /dev/null
+++ b/test/w3c/promela/test529.scxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- simple test that children workn with <content> -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="promela" initial="s0">
+ <state id="s0" initial="s01">
+ <transition event="done.state.s0" cond="_event.data == 21" target="pass">
+ </transition>
+ <transition event="done.state.s0" target="fail">
+ </transition>
+ <state id="s01">
+ <transition target="s02"/>
+ </state>
+ <final id="s02">
+ <donedata>
+ <content>21</content>
+ </donedata>
+ </final>
+ </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/promela/test530.scxml b/test/w3c/promela/test530.scxml
new file mode 100644
index 0000000..c23eb9a
--- /dev/null
+++ b/test/w3c/promela/test530.scxml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that <content> child is evaluated when <invoke> is. Var1 is initialized
+with an integer value, then set to an scxml script in the onentry to s0. If <content>
+is evaluated at the right time, we should get invoke.done, otherwise an error -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" expr="1"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <assign location="Var1">
+ <scxml version="1.0">
+ <final/>
+ </scxml>
+ </assign>
+ <send event="timeout" delay="2s"/>
+ </onentry>
+ <invoke type="http://www.w3.org/TR/scxml/">
+ <content expr="Var1"/>
+ </invoke>
+ <transition event="done.invoke" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test531.scxml b/test/w3c/promela/test531.scxml
new file mode 100644
index 0000000..1e8cd15
--- /dev/null
+++ b/test/w3c/promela/test531.scxml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that that the value of the <param> _scxmleventname gets used as the name
+of the raised event. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="3s"/>
+ <send targetexpr="_ioprocessors.basichttp.location" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor">
+ <param name="_scxmleventname" expr="'test'"/>
+ </send>
+ </onentry>
+ <!-- if we get an event named 'test' we succeed. Otherwise fail -->
+ <transition event="test" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test532.scxml b/test/w3c/promela/test532.scxml
new file mode 100644
index 0000000..69ffa54
--- /dev/null
+++ b/test/w3c/promela/test532.scxml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that that if _scxmleventname is not present, the name of the HTTP method is used
+as the name of the resulting event. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="3s"/>
+ <send targetexpr="_ioprocessors.basichttp.location" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor">
+ <!-- this content will be ignored, but it's here to make sure we have a message body -->
+ <content>some content</content>
+ </send>
+ </onentry>
+ <transition event="HTTP.POST" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test533.scxml b/test/w3c/promela/test533.scxml
new file mode 100644
index 0000000..68d9406
--- /dev/null
+++ b/test/w3c/promela/test533.scxml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that an internal transition whose source state is not compound does exit its source state -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s1" version="1.0" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ <!-- how often we have exited p -->
+ <data id="Var2" type="int" expr="0"/>
+ <!-- how often we have exited ps1 -->
+ <data id="Var3" type="int" expr="0"/>
+ <!-- how often we have exited ps2 -->
+ <data id="Var4" type="int" expr="0"/>
+ <!-- how often the transition for foo has been taken -->
+ </datamodel>
+ <state id="s1">
+ <onentry>
+ <raise event="foo"/>
+ <raise event="bar"/>
+ </onentry>
+ <transition target="p"/>
+ </state>
+ <parallel id="p">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onexit>
+ <transition event="foo" type="internal" target="ps1">
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var4" expr="Var4 + 1"/>
+ </transition>
+ <!-- make sure the transition on foo was actually taken -->
+ <transition event="bar" cond="Var4==1" target="s2"/>
+ <transition event="bar" target="fail"/>
+ <state id="ps1">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var2" expr="Var2 + 1"/>
+ </onexit>
+ </state>
+ <state id="ps2">
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var3" expr="Var3 + 1"/>
+ </onexit>
+ </state>
+ </parallel>
+ <state id="s2">
+ <!-- make sure that p was exited twice -->
+ <transition cond="Var1==2" target="s3"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s3">
+ <!-- make sure that ps1 was exited twice -->
+ <transition cond="Var2==2" target="s4"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s4">
+ <!-- make sure that ps2 was exited twice -->
+ <transition cond="Var3==2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test534.scxml b/test/w3c/promela/test534.scxml
new file mode 100644
index 0000000..65b03e4
--- /dev/null
+++ b/test/w3c/promela/test534.scxml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that that <send> 'event' value gets sent as the param _scxmleventname . -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="30s"/>
+ <send event="test" targetexpr="_ioprocessors.basichttp.location" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor">
+ </send>
+ </onentry>
+ <!-- if other end sends us back this event, we succeed -->
+ <transition event="test" cond="_event.raw.search('_scxmleventname=test') !== -1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test539.txt b/test/w3c/promela/test539.txt
new file mode 100644
index 0000000..de1b0a1
--- /dev/null
+++ b/test/w3c/promela/test539.txt
@@ -0,0 +1,4 @@
+ <books xmlns="">
+ <book title="title1"/>
+ <book title="title2"/>
+ </books> \ No newline at end of file
diff --git a/test/w3c/promela/test540.txt b/test/w3c/promela/test540.txt
new file mode 100644
index 0000000..2191239
--- /dev/null
+++ b/test/w3c/promela/test540.txt
@@ -0,0 +1,3 @@
+123
+4 5
+ \ No newline at end of file
diff --git a/test/w3c/promela/test550.scxml b/test/w3c/promela/test550.scxml
new file mode 100644
index 0000000..fc00d05
--- /dev/null
+++ b/test/w3c/promela/test550.scxml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that expr can be used to assign a value to a var. This test uses early binding -->
+<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" binding="early">
+ <state id="s0">
+ <transition cond="Var1==2" target="pass"/>
+ <transition target="fail"/>
+ </state>
+ <state id="s1">
+ <datamodel>
+ <data id="Var1" type="int" expr="2"/>
+ </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/promela/test551.scxml b/test/w3c/promela/test551.scxml
new file mode 100644
index 0000000..7fca0b4
--- /dev/null
+++ b/test/w3c/promela/test551.scxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- test that inline content can be used to assign a value to a var. --><scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" binding="early" datamodel="promela">
+
+
+ <state id="s0">
+
+ <transition cond="Var1[1]" target="pass"/>
+ <transition target="fail"/>
+ </state>
+
+<state id="s1">
+ <datamodel>
+ <data id="Var1" type="int[3]">
+
+ Var1[0] = 1;
+ Var1[1] = 2;
+ Var1[2] = 3;
+
+ </data>
+ </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> \ No newline at end of file
diff --git a/test/w3c/promela/test552.scxml b/test/w3c/promela/test552.scxml
new file mode 100644
index 0000000..320b42d
--- /dev/null
+++ b/test/w3c/promela/test552.scxml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that src content can be used to assign a value to a var. Edit
+test552.txt to have a value that's legal for the datamodel in question -->
+<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">
+ <datamodel>
+ <data id="Var1" type="int" src="file:test552.txt"/>
+ </datamodel>
+ <state id="s0">
+ <transition cond="Var1" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test552.txt b/test/w3c/promela/test552.txt
new file mode 100644
index 0000000..d8263ee
--- /dev/null
+++ b/test/w3c/promela/test552.txt
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/w3c/promela/test553.scxml b/test/w3c/promela/test553.scxml
new file mode 100644
index 0000000..ad056a8
--- /dev/null
+++ b/test/w3c/promela/test553.scxml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- we test that the processor does not dispatch the event if evaluation
+of <send>'s args causes an error.. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <!-- timeout event -->
+ <send event="timeout" delayexpr="'1s'"/>
+ <!-- generate an invalid namelist -->
+ <send event="event1" namelist="&quot;foo"/>
+ </onentry>
+ <!-- if we get the timeout before event1, we assume that event1 hasn't been sent
+ We ignore the error event here because this assertion doesn't mention it -->
+ <transition event="timeout" target="pass"/>
+ <transition event="event1" target="fail"/>
+ </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/promela/test554.scxml b/test/w3c/promela/test554.scxml
new file mode 100644
index 0000000..b93888a
--- /dev/null
+++ b/test/w3c/promela/test554.scxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that if the evaluation of <invoke>'s args causes an error, the
+invocation is cancelled. In this test, that means that we don't get done.invoke
+before the timer goes off. -->
+<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">
+ <state id="s0">
+ <onentry>
+ <send event="timer" delayexpr="'1s'"/>
+ </onentry>
+ <!-- reference an invalid namelist -->
+ <invoke type="http://www.w3.org/TR/scxml/" namelist="&quot;foo">
+ <content>
+ <scxml initial="subFinal" version="1.0" datamodel="promela">
+ <final id="subFinal"/>
+ </scxml>
+ </content>
+ </invoke>
+ <transition event="timer" target="pass"/>
+ <transition event="done.invoke" target="fail"/>
+ </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/promela/test557.txt b/test/w3c/promela/test557.txt
new file mode 100644
index 0000000..a8e51da
--- /dev/null
+++ b/test/w3c/promela/test557.txt
@@ -0,0 +1,4 @@
+<books xmlns="">
+ <book title="title1"/>
+ <book title="title2"/>
+ </books> \ No newline at end of file
diff --git a/test/w3c/promela/test558.txt b/test/w3c/promela/test558.txt
new file mode 100644
index 0000000..bb2bcc7
--- /dev/null
+++ b/test/w3c/promela/test558.txt
@@ -0,0 +1,3 @@
+
+this is
+a string \ No newline at end of file
diff --git a/test/w3c/promela/test567.scxml b/test/w3c/promela/test567.scxml
new file mode 100644
index 0000000..50eb4bd
--- /dev/null
+++ b/test/w3c/promela/test567.scxml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that that any content in the message other than _scxmleventname is used to populate
+_event.data. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int" expr="2"/>
+ </datamodel>
+ <state id="s0">
+ <onentry>
+ <send event="timeout" delay="3s"/>
+ <!-- in this case, 'test' will be placed in _scxmleventname. The <param> should
+ be used to populate _event.data -->
+ <send event="test" targetexpr="_ioprocessors.basichttp.location" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor">
+ <param name="param1" expr="2"/>
+ </send>
+ </onentry>
+ <!-- if we get this event, we succeed -->
+ <transition event="test" target="s1">
+ <assign location="Var1" expr="_event.data.param1"/>
+ </transition>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s1">
+ <transition cond="Var1==2" target="pass"/>
+ <transition target="fail"/>
+ </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/promela/test570.scxml b/test/w3c/promela/test570.scxml
new file mode 100644
index 0000000..6ec678b
--- /dev/null
+++ b/test/w3c/promela/test570.scxml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that we generate done.state.id when all a parallel state's children are in final states -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="p0" datamodel="promela" version="1.0">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <parallel id="p0">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ <raise event="e1"/>
+ <raise event="e2"/>
+ </onentry>
+ <!-- record that we get the first done event -->
+ <transition event="done.state.p0s1">
+ <assign location="Var1" expr="1"/>
+ </transition>
+ <!-- we should get the second done event before done.state.p0 -->
+ <transition event="done.state.p0s2" target="s1"/>
+ <transition event="timeout" target="fail"/>
+ <state id="p0s1" initial="p0s11">
+ <state id="p0s11">
+ <transition event="e1" target="p0s1final"/>
+ </state>
+ <final id="p0s1final"/>
+ </state>
+ <state id="p0s2" initial="p0s21">
+ <state id="p0s21">
+ <transition event="e2" target="p0s2final"/>
+ </state>
+ <final id="p0s2final"/>
+ </state>
+ </parallel>
+ <state id="s1">
+ <!-- if we get done.state.p0, success -->
+ <transition event="done.state.p0" cond="Var1==1" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test576.scxml b/test/w3c/promela/test576.scxml
new file mode 100644
index 0000000..1b40fd7
--- /dev/null
+++ b/test/w3c/promela/test576.scxml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that the 'initial' value of scxml is respected. We set the value to deeply nested non-default parallel siblings and
+test that both are entered. -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s11p112 s11p122" datamodel="promela" version="1.0">
+ <state id="s0">
+ <transition target="fail"/>
+ </state>
+ <state id="s1">
+ <onentry>
+ <send event="timeout" delay="1s"/>
+ </onentry>
+ <transition event="timeout" target="fail"/>
+ <state id="s11" initial="s111">
+ <state id="s111"/>
+ <parallel id="s11p1">
+ <state id="s11p11" initial="s11p111">
+ <state id="s11p111"/>
+ <state id="s11p112">
+ <onentry>
+ <raise event="In-s11p112"/>
+ </onentry>
+ </state>
+ </state>
+ <state id="s11p12" initial="s11p121">
+ <state id="s11p121"/>
+ <state id="s11p122">
+ <transition event="In-s11p112" target="pass"/>
+ </state>
+ </state>
+ </parallel>
+ </state>
+ </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/promela/test577.scxml b/test/w3c/promela/test577.scxml
new file mode 100644
index 0000000..b5922ca
--- /dev/null
+++ b/test/w3c/promela/test577.scxml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that that <send> without target in basichttp event i/o processor
+causes error.communication to get added to internal queue . -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="promela" version="1.0">
+ <state id="s0">
+ <onentry>
+ <!-- sent by scxml event i/o processor, added to external queue -->
+ <send event="event1"/>
+ <!-- should put error.communication on internal queue -->
+ <send event="test" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"/>
+ </onentry>
+ <transition event="error.communication" target="pass"/>
+ <transition event="*" target="fail"/>
+ </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/promela/test579.scxml b/test/w3c/promela/test579.scxml
new file mode 100644
index 0000000..20419d8
--- /dev/null
+++ b/test/w3c/promela/test579.scxml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that default history content is executed correctly. The Process MUST execute any executable content in the transition after the parent state's onentry handlers, and, in the case where the history pseudo-state is the target of an <initial> transition,
+the executable content inside the <initial> transition. However the Processor MUST
+execute this content only if there is no stored history. Once the history state's
+parent state has been visited and exited, the default history content must not be executed -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" datamodel="promela">
+ <state id="s0">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <initial>
+ <transition target="sh1">
+ <raise event="event2"/>
+ </transition>
+ </initial>
+ <onentry>
+ <send delayexpr="'1s'" event="timeout"/>
+ <raise event="event1"/>
+ </onentry>
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onexit>
+ <history id="sh1">
+ <transition target="s01">
+ <raise event="event3"/>
+ </transition>
+ </history>
+ <state id="s01">
+ <transition event="event1" target="s02"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s02">
+ <transition event="event2" target="s03"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s03">
+ <transition cond="Var1==0" event="event3" target="s0"/>
+ <transition cond="Var1==1" event="event1" target="s2"/>
+ <transition event="*" target="fail"/>
+ </state>
+ </state>
+ <state id="s2">
+ <transition event="event2" target="s3"/>
+ <transition event="*" target="fail"/>
+ </state>
+ <state id="s3">
+ <transition event="event3" target="fail"/>
+ <transition event="timeout" target="pass"/>
+ </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/promela/test580.scxml b/test/w3c/promela/test580.scxml
new file mode 100644
index 0000000..ac1cbb7
--- /dev/null
+++ b/test/w3c/promela/test580.scxml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- test that a history state never ends up part of the configuration -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="p1" datamodel="promela">
+ <datamodel>
+ <data id="Var1" type="int" expr="0"/>
+ </datamodel>
+ <parallel id="p1">
+ <onentry>
+ <send delay="2s" event="timeout"/>
+ </onentry>
+ <state id="s0">
+ <transition cond="_x.states['sh1']" target="fail"/>
+ <transition event="timeout" target="fail"/>
+ </state>
+ <state id="s1">
+ <initial>
+ <transition target="sh1"/>
+ </initial>
+ <history id="sh1">
+ <transition target="s11"/>
+ </history>
+ <state id="s11">
+ <transition cond="_x.states['sh1']" target="fail"/>
+ <transition target="s12"/>
+ </state>
+ <state id="s12"/>
+ <transition cond="_x.states['sh1']" target="fail"/>
+ <transition cond="Var1==0" target="sh1"/>
+ <transition cond="Var1==1" target="pass"/>
+ <onexit>
+ <assign xmlns:scxml="http://www.w3.org/2005/07/scxml" location="Var1" expr="Var1 + 1"/>
+ </onexit>
+ </state>
+ </parallel>
+ <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_promela_test.cmake b/test/w3c/run_promela_test.cmake
new file mode 100644
index 0000000..e46ab60
--- /dev/null
+++ b/test/w3c/run_promela_test.cmake
@@ -0,0 +1,23 @@
+# convert given file to promela and run spin
+
+get_filename_component(TEST_FILE_NAME ${TESTFILE} NAME)
+
+execute_process(COMMAND ${USCXML_TRANSFORM_BIN} -s -i ${TESTFILE} -o ${OUTDIR}/${TEST_FILE_NAME}.pml RESULT_VARIABLE CMD_RESULT)
+if(CMD_RESULT)
+ message(FATAL_ERROR "Error running ${USCXML_TRANSFORM_BIN}: ${CMD_RESULT}")
+endif()
+
+execute_process(COMMAND ${SPIN_BIN} -a ${OUTDIR}/${TEST_FILE_NAME}.pml RESULT_VARIABLE CMD_RESULT)
+if(CMD_RESULT)
+ message(FATAL_ERROR "Error running ${SPIN_BIN}: ${CMD_RESULT}")
+endif()
+
+execute_process(COMMAND ${GCC_BIN} -DMEMLIM=1024 -O2 -DXUSAFE -w -o ${OUTDIR}/pan ${OUTDIR}/pan.c RESULT_VARIABLE CMD_RESULT)
+if(CMD_RESULT)
+ message(FATAL_ERROR "Error running ${GCC_BIN}: ${CMD_RESULT}")
+endif()
+
+execute_process(COMMAND ${OUTDIR}/pan -m10000 -a RESULT_VARIABLE CMD_RESULT)
+if(CMD_RESULT)
+ message(FATAL_ERROR "Error running pan: ${CMD_RESULT}")
+endif()
diff --git a/test/w3c/txml/test307.txml b/test/w3c/txml/test307.txml
index 4065f5f..0cfeef2 100644
--- a/test/w3c/txml/test307.txml
+++ b/test/w3c/txml/test307.txml
@@ -1,5 +1,5 @@
<?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" version="1.0" initial="s0" binding="late">
+xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" conf:datamodel="" binding="late">
<!-- with binding=late, in s0 we access a variable that isn't created until we get to s1. Then in s1
we access a non-existent substructure of a variable. We use log tags to report the values that both operations