From fa90b5749693d9f5817ad1f106334a0877171fd3 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Sun, 12 Oct 2014 13:11:06 +0200 Subject: Major work on PROMELA datamodel --- CMakeLists.txt | 2 + apps/uscxml-browser.cpp | 4 +- contrib/cmake/FindSWI.cmake | 20 +- contrib/src/swi-pl/SWI-cpp.h | 16 +- src/uscxml/Convenience.h | 6 + src/uscxml/Factory.cpp | 8 +- src/uscxml/Factory.h | 2 +- src/uscxml/Interpreter.cpp | 280 ++-- src/uscxml/Interpreter.h | 6 +- src/uscxml/debug/InterpreterIssue.cpp | 71 +- src/uscxml/debug/InterpreterIssue.h | 6 +- src/uscxml/debug/SCXMLDotWriter.cpp | 22 +- src/uscxml/debug/SCXMLDotWriter.h | 2 +- src/uscxml/interpreter/InterpreterRC.cpp | 100 +- src/uscxml/interpreter/InterpreterRC.h | 1 + src/uscxml/messages/Event.h | 2 +- src/uscxml/messages/MMIMessages.cpp | 192 +-- src/uscxml/messages/MMIMessages.h | 46 +- src/uscxml/plugins/EventHandler.h | 4 +- .../ecmascript/JavaScriptCore/JSCDataModel.cpp | 4 +- .../SpiderMonkey/SpiderMonkeyDataModel.cpp | 82 +- .../SpiderMonkey/SpiderMonkeyDataModel.h | 2 +- .../datamodel/ecmascript/v8/V8DataModel.cpp | 6 +- src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp | 6 +- .../plugins/datamodel/prolog/swi/SWIConfig.h.in | 3 +- .../plugins/datamodel/prolog/swi/SWIDataModel.h | 3 +- .../plugins/datamodel/promela/PromelaDataModel.cpp | 442 ++++++- .../plugins/datamodel/promela/PromelaDataModel.h | 18 +- .../plugins/datamodel/promela/PromelaParser.cpp | 34 +- .../plugins/datamodel/promela/PromelaParser.h | 9 +- .../plugins/datamodel/promela/parser/promela.l | 17 +- .../datamodel/promela/parser/promela.lex.yy.cpp | 360 ++--- .../datamodel/promela/parser/promela.tab.cpp | 733 ++++++----- .../datamodel/promela/parser/promela.tab.hpp | 5 +- .../plugins/datamodel/promela/parser/promela.ypp | 38 +- .../plugins/invoker/vxml/VoiceXMLInvoker.cpp | 141 +- src/uscxml/plugins/invoker/vxml/VoiceXMLInvoker.h | 12 +- src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp | 42 +- .../invoker/xhtml/template/xhtml-invoker.inc.h | 1376 ++++++++++---------- src/uscxml/server/HTTPServer.cpp | 2 +- src/uscxml/server/HTTPServer.h | 2 +- src/uscxml/server/Socket.cpp | 18 +- src/uscxml/server/Socket.h | 2 +- src/uscxml/transform/ChartToFSM.cpp | 281 ++-- src/uscxml/transform/ChartToFSM.h | 16 +- src/uscxml/transform/FSMToPromela.cpp | 1115 ++++++++++++++-- src/uscxml/transform/FSMToPromela.h | 120 +- src/uscxml/transform/FlatStateIdentifier.h | 67 +- src/uscxml/util/Trie.cpp | 14 +- src/uscxml/util/Trie.h | 6 +- test/CMakeLists.txt | 26 + test/ctest/CTestCustom.ctest.in | 145 ++- test/src/test-flat-stateid.cpp | 12 +- test/src/test-issue-reporting.cpp | 352 ++--- test/src/test-mmi.cpp | 30 +- test/src/test-promela-parser.cpp | 18 +- test/src/test-sockets.cpp | 10 +- test/src/test-url.cpp | 2 +- test/src/test-vxml-mmi-http.cpp | 65 +- test/src/test-vxml-mmi-socket.cpp | 30 +- test/src/test-w3c.cpp | 36 +- test/uscxml/test-jvoicexml.scxml | 2 +- test/w3c/confPromela.xsl | 779 +++++++++++ test/w3c/convert-tests.sh | 31 +- test/w3c/draft/calc.scxml | 157 --- test/w3c/ecma/test403c.scxml | 6 +- test/w3c/promela/robots.txt | 96 ++ test/w3c/promela/test144.scxml | 27 + test/w3c/promela/test147.scxml | 35 + test/w3c/promela/test148.scxml | 36 + test/w3c/promela/test149.scxml | 31 + test/w3c/promela/test150.scxml | 49 + test/w3c/promela/test151.scxml | 49 + test/w3c/promela/test152.scxml | 55 + test/w3c/promela/test153.scxml | 46 + test/w3c/promela/test155.scxml | 35 + test/w3c/promela/test156.scxml | 37 + test/w3c/promela/test158.scxml | 29 + test/w3c/promela/test159.scxml | 26 + test/w3c/promela/test172.scxml | 25 + test/w3c/promela/test173.scxml | 26 + test/w3c/promela/test174.scxml | 26 + test/w3c/promela/test175.scxml | 32 + test/w3c/promela/test176.scxml | 35 + test/w3c/promela/test178.scxml | 27 + test/w3c/promela/test179.scxml | 23 + test/w3c/promela/test183.scxml | 25 + test/w3c/promela/test185.scxml | 27 + test/w3c/promela/test186.scxml | 36 + test/w3c/promela/test187.scxml | 38 + test/w3c/promela/test189.scxml | 27 + test/w3c/promela/test190.scxml | 40 + test/w3c/promela/test191.scxml | 37 + test/w3c/promela/test192.scxml | 52 + test/w3c/promela/test193.scxml | 29 + test/w3c/promela/test194.scxml | 26 + test/w3c/promela/test198.scxml | 23 + test/w3c/promela/test199.scxml | 22 + test/w3c/promela/test200.scxml | 22 + test/w3c/promela/test201.scxml | 23 + test/w3c/promela/test205.scxml | 34 + test/w3c/promela/test207.scxml | 55 + test/w3c/promela/test208.scxml | 24 + test/w3c/promela/test210.scxml | 28 + test/w3c/promela/test215.scxml | 35 + test/w3c/promela/test216.scxml | 28 + test/w3c/promela/test216sub1.scxml | 5 + test/w3c/promela/test220.scxml | 29 + test/w3c/promela/test223.scxml | 35 + test/w3c/promela/test224.scxml | 36 + test/w3c/promela/test225.scxml | 42 + test/w3c/promela/test226.scxml | 26 + test/w3c/promela/test226sub1.scxml | 14 + test/w3c/promela/test228.scxml | 37 + test/w3c/promela/test229.scxml | 46 + test/w3c/promela/test230.scxml | 60 + test/w3c/promela/test232.scxml | 41 + test/w3c/promela/test233.scxml | 42 + test/w3c/promela/test234.scxml | 69 + test/w3c/promela/test235.scxml | 29 + test/w3c/promela/test236.scxml | 43 + test/w3c/promela/test237.scxml | 45 + test/w3c/promela/test239.scxml | 35 + test/w3c/promela/test239sub1.scxml | 5 + test/w3c/promela/test240.scxml | 71 + test/w3c/promela/test241.scxml | 96 ++ test/w3c/promela/test242.scxml | 56 + test/w3c/promela/test242sub1.scxml | 5 + test/w3c/promela/test243.scxml | 41 + test/w3c/promela/test244.scxml | 45 + test/w3c/promela/test245.scxml | 40 + test/w3c/promela/test247.scxml | 28 + test/w3c/promela/test250.scxml | 39 + test/w3c/promela/test252.scxml | 48 + test/w3c/promela/test253.scxml | 75 ++ test/w3c/promela/test276.scxml | 22 + test/w3c/promela/test276sub1.scxml | 16 + test/w3c/promela/test277.scxml | 32 + test/w3c/promela/test278.scxml | 23 + test/w3c/promela/test279.scxml | 24 + test/w3c/promela/test280.scxml | 33 + test/w3c/promela/test286.scxml | 23 + test/w3c/promela/test287.scxml | 24 + test/w3c/promela/test288.scxml | 25 + test/w3c/promela/test294.scxml | 46 + test/w3c/promela/test298.scxml | 32 + test/w3c/promela/test301.scxml | 19 + test/w3c/promela/test302.scxml | 21 + test/w3c/promela/test303.scxml | 26 + test/w3c/promela/test304.scxml | 19 + test/w3c/promela/test307.scxml | 35 + test/w3c/promela/test309.scxml | 18 + test/w3c/promela/test310.scxml | 21 + test/w3c/promela/test311.scxml | 22 + test/w3c/promela/test312.scxml | 25 + test/w3c/promela/test313.scxml | 26 + test/w3c/promela/test314.scxml | 35 + test/w3c/promela/test318.scxml | 32 + test/w3c/promela/test319.scxml | 25 + test/w3c/promela/test321.scxml | 21 + test/w3c/promela/test322.scxml | 34 + test/w3c/promela/test323.scxml | 21 + test/w3c/promela/test324.scxml | 25 + test/w3c/promela/test325.scxml | 23 + test/w3c/promela/test326.scxml | 37 + test/w3c/promela/test329.scxml | 54 + test/w3c/promela/test330.scxml | 28 + test/w3c/promela/test331.scxml | 59 + test/w3c/promela/test332.scxml | 34 + test/w3c/promela/test333.scxml | 21 + test/w3c/promela/test335.scxml | 21 + test/w3c/promela/test336.scxml | 31 + test/w3c/promela/test337.scxml | 21 + test/w3c/promela/test338.scxml | 43 + test/w3c/promela/test339.scxml | 21 + test/w3c/promela/test342.scxml | 31 + test/w3c/promela/test343.scxml | 35 + test/w3c/promela/test344.scxml | 28 + test/w3c/promela/test346.scxml | 54 + test/w3c/promela/test347.scxml | 44 + test/w3c/promela/test348.scxml | 21 + test/w3c/promela/test349.scxml | 33 + test/w3c/promela/test350.scxml | 28 + test/w3c/promela/test351.scxml | 45 + test/w3c/promela/test352.scxml | 31 + test/w3c/promela/test354.scxml | 52 + test/w3c/promela/test355.scxml | 20 + test/w3c/promela/test364.scxml | 79 ++ test/w3c/promela/test372.scxml | 33 + test/w3c/promela/test375.scxml | 28 + test/w3c/promela/test376.scxml | 28 + test/w3c/promela/test377.scxml | 31 + test/w3c/promela/test378.scxml | 31 + test/w3c/promela/test387.scxml | 93 ++ test/w3c/promela/test388.scxml | 74 ++ test/w3c/promela/test396.scxml | 21 + test/w3c/promela/test399.scxml | 65 + test/w3c/promela/test401.scxml | 25 + test/w3c/promela/test402.scxml | 42 + test/w3c/promela/test403a.scxml | 46 + test/w3c/promela/test403b.scxml | 40 + test/w3c/promela/test403c.scxml | 53 + test/w3c/promela/test404.scxml | 56 + test/w3c/promela/test405.scxml | 66 + test/w3c/promela/test406.scxml | 60 + test/w3c/promela/test407.scxml | 27 + test/w3c/promela/test409.scxml | 36 + test/w3c/promela/test411.scxml | 36 + test/w3c/promela/test412.scxml | 52 + test/w3c/promela/test413.scxml | 44 + test/w3c/promela/test415.scxml | 13 + test/w3c/promela/test416.scxml | 27 + test/w3c/promela/test417.scxml | 36 + test/w3c/promela/test419.scxml | 22 + test/w3c/promela/test421.scxml | 31 + test/w3c/promela/test422.scxml | 81 ++ test/w3c/promela/test423.scxml | 29 + test/w3c/promela/test436.scxml | 23 + test/w3c/promela/test446.txt | 1 + test/w3c/promela/test487.scxml | 25 + test/w3c/promela/test488.scxml | 35 + test/w3c/promela/test495.scxml | 28 + test/w3c/promela/test496.scxml | 21 + test/w3c/promela/test500.scxml | 21 + test/w3c/promela/test501.scxml | 25 + test/w3c/promela/test503.scxml | 43 + test/w3c/promela/test504.scxml | 79 ++ test/w3c/promela/test505.scxml | 52 + test/w3c/promela/test506.scxml | 56 + test/w3c/promela/test509.scxml | 24 + test/w3c/promela/test510.scxml | 29 + test/w3c/promela/test513.txt | 16 + test/w3c/promela/test518.scxml | 25 + test/w3c/promela/test519.scxml | 25 + test/w3c/promela/test520.scxml | 27 + test/w3c/promela/test521.scxml | 27 + test/w3c/promela/test522.scxml | 27 + test/w3c/promela/test525.scxml | 36 + test/w3c/promela/test527.scxml | 28 + test/w3c/promela/test528.scxml | 33 + test/w3c/promela/test529.scxml | 28 + test/w3c/promela/test530.scxml | 34 + test/w3c/promela/test531.scxml | 26 + test/w3c/promela/test532.scxml | 26 + test/w3c/promela/test533.scxml | 67 + test/w3c/promela/test534.scxml | 24 + test/w3c/promela/test539.txt | 4 + test/w3c/promela/test540.txt | 3 + test/w3c/promela/test550.scxml | 23 + test/w3c/promela/test551.scxml | 27 + test/w3c/promela/test552.scxml | 22 + test/w3c/promela/test552.txt | 1 + test/w3c/promela/test553.scxml | 27 + test/w3c/promela/test554.scxml | 31 + test/w3c/promela/test557.txt | 4 + test/w3c/promela/test558.txt | 3 + test/w3c/promela/test567.scxml | 37 + test/w3c/promela/test570.scxml | 48 + test/w3c/promela/test576.scxml | 43 + test/w3c/promela/test577.scxml | 25 + test/w3c/promela/test579.scxml | 60 + test/w3c/promela/test580.scxml | 45 + test/w3c/run_promela_test.cmake | 23 + test/w3c/txml/test307.txml | 2 +- 264 files changed, 11648 insertions(+), 2562 deletions(-) create mode 100644 test/w3c/confPromela.xsl delete mode 100644 test/w3c/draft/calc.scxml create mode 100644 test/w3c/promela/robots.txt create mode 100644 test/w3c/promela/test144.scxml create mode 100644 test/w3c/promela/test147.scxml create mode 100644 test/w3c/promela/test148.scxml create mode 100644 test/w3c/promela/test149.scxml create mode 100644 test/w3c/promela/test150.scxml create mode 100644 test/w3c/promela/test151.scxml create mode 100644 test/w3c/promela/test152.scxml create mode 100644 test/w3c/promela/test153.scxml create mode 100644 test/w3c/promela/test155.scxml create mode 100644 test/w3c/promela/test156.scxml create mode 100644 test/w3c/promela/test158.scxml create mode 100644 test/w3c/promela/test159.scxml create mode 100644 test/w3c/promela/test172.scxml create mode 100644 test/w3c/promela/test173.scxml create mode 100644 test/w3c/promela/test174.scxml create mode 100644 test/w3c/promela/test175.scxml create mode 100644 test/w3c/promela/test176.scxml create mode 100644 test/w3c/promela/test178.scxml create mode 100644 test/w3c/promela/test179.scxml create mode 100644 test/w3c/promela/test183.scxml create mode 100644 test/w3c/promela/test185.scxml create mode 100644 test/w3c/promela/test186.scxml create mode 100644 test/w3c/promela/test187.scxml create mode 100644 test/w3c/promela/test189.scxml create mode 100644 test/w3c/promela/test190.scxml create mode 100644 test/w3c/promela/test191.scxml create mode 100644 test/w3c/promela/test192.scxml create mode 100644 test/w3c/promela/test193.scxml create mode 100644 test/w3c/promela/test194.scxml create mode 100644 test/w3c/promela/test198.scxml create mode 100644 test/w3c/promela/test199.scxml create mode 100644 test/w3c/promela/test200.scxml create mode 100644 test/w3c/promela/test201.scxml create mode 100644 test/w3c/promela/test205.scxml create mode 100644 test/w3c/promela/test207.scxml create mode 100644 test/w3c/promela/test208.scxml create mode 100644 test/w3c/promela/test210.scxml create mode 100644 test/w3c/promela/test215.scxml create mode 100644 test/w3c/promela/test216.scxml create mode 100644 test/w3c/promela/test216sub1.scxml create mode 100644 test/w3c/promela/test220.scxml create mode 100644 test/w3c/promela/test223.scxml create mode 100644 test/w3c/promela/test224.scxml create mode 100644 test/w3c/promela/test225.scxml create mode 100644 test/w3c/promela/test226.scxml create mode 100644 test/w3c/promela/test226sub1.scxml create mode 100644 test/w3c/promela/test228.scxml create mode 100644 test/w3c/promela/test229.scxml create mode 100644 test/w3c/promela/test230.scxml create mode 100644 test/w3c/promela/test232.scxml create mode 100644 test/w3c/promela/test233.scxml create mode 100644 test/w3c/promela/test234.scxml create mode 100644 test/w3c/promela/test235.scxml create mode 100644 test/w3c/promela/test236.scxml create mode 100644 test/w3c/promela/test237.scxml create mode 100644 test/w3c/promela/test239.scxml create mode 100644 test/w3c/promela/test239sub1.scxml create mode 100644 test/w3c/promela/test240.scxml create mode 100644 test/w3c/promela/test241.scxml create mode 100644 test/w3c/promela/test242.scxml create mode 100644 test/w3c/promela/test242sub1.scxml create mode 100644 test/w3c/promela/test243.scxml create mode 100644 test/w3c/promela/test244.scxml create mode 100644 test/w3c/promela/test245.scxml create mode 100644 test/w3c/promela/test247.scxml create mode 100644 test/w3c/promela/test250.scxml create mode 100644 test/w3c/promela/test252.scxml create mode 100644 test/w3c/promela/test253.scxml create mode 100644 test/w3c/promela/test276.scxml create mode 100644 test/w3c/promela/test276sub1.scxml create mode 100644 test/w3c/promela/test277.scxml create mode 100644 test/w3c/promela/test278.scxml create mode 100644 test/w3c/promela/test279.scxml create mode 100644 test/w3c/promela/test280.scxml create mode 100644 test/w3c/promela/test286.scxml create mode 100644 test/w3c/promela/test287.scxml create mode 100644 test/w3c/promela/test288.scxml create mode 100644 test/w3c/promela/test294.scxml create mode 100644 test/w3c/promela/test298.scxml create mode 100644 test/w3c/promela/test301.scxml create mode 100644 test/w3c/promela/test302.scxml create mode 100644 test/w3c/promela/test303.scxml create mode 100644 test/w3c/promela/test304.scxml create mode 100644 test/w3c/promela/test307.scxml create mode 100644 test/w3c/promela/test309.scxml create mode 100644 test/w3c/promela/test310.scxml create mode 100644 test/w3c/promela/test311.scxml create mode 100644 test/w3c/promela/test312.scxml create mode 100644 test/w3c/promela/test313.scxml create mode 100644 test/w3c/promela/test314.scxml create mode 100644 test/w3c/promela/test318.scxml create mode 100644 test/w3c/promela/test319.scxml create mode 100644 test/w3c/promela/test321.scxml create mode 100644 test/w3c/promela/test322.scxml create mode 100644 test/w3c/promela/test323.scxml create mode 100644 test/w3c/promela/test324.scxml create mode 100644 test/w3c/promela/test325.scxml create mode 100644 test/w3c/promela/test326.scxml create mode 100644 test/w3c/promela/test329.scxml create mode 100644 test/w3c/promela/test330.scxml create mode 100644 test/w3c/promela/test331.scxml create mode 100644 test/w3c/promela/test332.scxml create mode 100644 test/w3c/promela/test333.scxml create mode 100644 test/w3c/promela/test335.scxml create mode 100644 test/w3c/promela/test336.scxml create mode 100644 test/w3c/promela/test337.scxml create mode 100644 test/w3c/promela/test338.scxml create mode 100644 test/w3c/promela/test339.scxml create mode 100644 test/w3c/promela/test342.scxml create mode 100644 test/w3c/promela/test343.scxml create mode 100644 test/w3c/promela/test344.scxml create mode 100644 test/w3c/promela/test346.scxml create mode 100644 test/w3c/promela/test347.scxml create mode 100644 test/w3c/promela/test348.scxml create mode 100644 test/w3c/promela/test349.scxml create mode 100644 test/w3c/promela/test350.scxml create mode 100644 test/w3c/promela/test351.scxml create mode 100644 test/w3c/promela/test352.scxml create mode 100644 test/w3c/promela/test354.scxml create mode 100644 test/w3c/promela/test355.scxml create mode 100644 test/w3c/promela/test364.scxml create mode 100644 test/w3c/promela/test372.scxml create mode 100644 test/w3c/promela/test375.scxml create mode 100644 test/w3c/promela/test376.scxml create mode 100644 test/w3c/promela/test377.scxml create mode 100644 test/w3c/promela/test378.scxml create mode 100644 test/w3c/promela/test387.scxml create mode 100644 test/w3c/promela/test388.scxml create mode 100644 test/w3c/promela/test396.scxml create mode 100644 test/w3c/promela/test399.scxml create mode 100644 test/w3c/promela/test401.scxml create mode 100644 test/w3c/promela/test402.scxml create mode 100644 test/w3c/promela/test403a.scxml create mode 100644 test/w3c/promela/test403b.scxml create mode 100644 test/w3c/promela/test403c.scxml create mode 100644 test/w3c/promela/test404.scxml create mode 100644 test/w3c/promela/test405.scxml create mode 100644 test/w3c/promela/test406.scxml create mode 100644 test/w3c/promela/test407.scxml create mode 100644 test/w3c/promela/test409.scxml create mode 100644 test/w3c/promela/test411.scxml create mode 100644 test/w3c/promela/test412.scxml create mode 100644 test/w3c/promela/test413.scxml create mode 100644 test/w3c/promela/test415.scxml create mode 100644 test/w3c/promela/test416.scxml create mode 100644 test/w3c/promela/test417.scxml create mode 100644 test/w3c/promela/test419.scxml create mode 100644 test/w3c/promela/test421.scxml create mode 100644 test/w3c/promela/test422.scxml create mode 100644 test/w3c/promela/test423.scxml create mode 100644 test/w3c/promela/test436.scxml create mode 100644 test/w3c/promela/test446.txt create mode 100644 test/w3c/promela/test487.scxml create mode 100644 test/w3c/promela/test488.scxml create mode 100644 test/w3c/promela/test495.scxml create mode 100644 test/w3c/promela/test496.scxml create mode 100644 test/w3c/promela/test500.scxml create mode 100644 test/w3c/promela/test501.scxml create mode 100644 test/w3c/promela/test503.scxml create mode 100644 test/w3c/promela/test504.scxml create mode 100644 test/w3c/promela/test505.scxml create mode 100644 test/w3c/promela/test506.scxml create mode 100644 test/w3c/promela/test509.scxml create mode 100644 test/w3c/promela/test510.scxml create mode 100644 test/w3c/promela/test513.txt create mode 100644 test/w3c/promela/test518.scxml create mode 100644 test/w3c/promela/test519.scxml create mode 100644 test/w3c/promela/test520.scxml create mode 100644 test/w3c/promela/test521.scxml create mode 100644 test/w3c/promela/test522.scxml create mode 100644 test/w3c/promela/test525.scxml create mode 100644 test/w3c/promela/test527.scxml create mode 100644 test/w3c/promela/test528.scxml create mode 100644 test/w3c/promela/test529.scxml create mode 100644 test/w3c/promela/test530.scxml create mode 100644 test/w3c/promela/test531.scxml create mode 100644 test/w3c/promela/test532.scxml create mode 100644 test/w3c/promela/test533.scxml create mode 100644 test/w3c/promela/test534.scxml create mode 100644 test/w3c/promela/test539.txt create mode 100644 test/w3c/promela/test540.txt create mode 100644 test/w3c/promela/test550.scxml create mode 100644 test/w3c/promela/test551.scxml create mode 100644 test/w3c/promela/test552.scxml create mode 100644 test/w3c/promela/test552.txt create mode 100644 test/w3c/promela/test553.scxml create mode 100644 test/w3c/promela/test554.scxml create mode 100644 test/w3c/promela/test557.txt create mode 100644 test/w3c/promela/test558.txt create mode 100644 test/w3c/promela/test567.scxml create mode 100644 test/w3c/promela/test570.scxml create mode 100644 test/w3c/promela/test576.scxml create mode 100644 test/w3c/promela/test577.scxml create mode 100644 test/w3c/promela/test579.scxml create mode 100644 test/w3c/promela/test580.scxml create mode 100644 test/w3c/run_promela_test.cmake 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 issues = interpreter.validate(); for (std::list::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(f) for foreign functions with in SWI 7.x and above + check_cxx_source_compiles(" + #include + int main(){ + } + " SWI_REINTERPRET_FOREIGN) + check_cxx_source_compiles(" #include 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(f) +#else +# define PL_FOREIGN_TO_FUNCTION(f) (void *)f +#endif + #include #include #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 Factory::createInvoker(const std::string& type, InterpreterImpl* interpreter) { // do we have this type ourself? @@ -591,7 +591,7 @@ boost::shared_ptr Factory::createDataModel(const std::string& typ return boost::shared_ptr(); } - + 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 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& dom, tthread::lock_guard lock(_instanceMutex); boost::shared_ptr interpreterImpl = boost::shared_ptr(new INTERPRETER_IMPL); Interpreter interpreter(interpreterImpl); - + // *copy* the given DOM to get rid of event listeners - + DOMImplementation domFactory = Arabica::SimpleDOM::DOMImplementation::getDOMImplementation(); interpreterImpl->_document = domFactory.createDocument(dom.getNamespaceURI(), "", 0); - + Node child = dom.getFirstChild(); while (child) { Node 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 statesToExit = _configuration; statesToExit.forward(false); statesToExit.sort(); - + for (int i = 0; i < statesToExit.size(); i++) { Arabica::XPath::NodeSet onExitElems = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", statesToExit[i]); for (int j = 0; j < onExitElems.size(); j++) { @@ -643,26 +643,26 @@ void InterpreterImpl::exitInterpreter() { _configuration = NodeSet(); } - + 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 InterpreterImpl::getDocumentInitialTransitions() { NodeSet initialTransitions; - + if (_startConfiguration.size() > 0) { // we emulate entering a given configuration by creating a pseudo deep history Element 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 histStates; for (std::list::const_iterator stateIter = _startConfiguration.begin(); stateIter != _startConfiguration.end(); stateIter++) { histStates.push_back(getState(*stateIter)); } _historyValue[histId] = histStates; - + Element initialElem = _document.createElementNS(_nsInfo.nsURL, "initial"); _nsInfo.setPrefix(initialElem); - + initialElem.setAttribute("generated", "true"); Element 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 InterpreterImpl::getDocumentInitialTransitions() { for (int i = 0; i < initialStates.size(); i++) { Element initialElem = _document.createElementNS(_nsInfo.nsURL, "initial"); _nsInfo.setPrefix(initialElem); - + initialElem.setAttribute("generated", "true"); Element 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 InterpreterImpl::getDocumentInitialTransitions() { InterpreterState InterpreterImpl::step(int waitForMS) { try { tthread::lock_guard lock(_mutex); - + if (_state == USCXML_FINISHED || _state == USCXML_DESTROYED) { return _state; } - + NodeSet enabledTransitions; - + // setup document and interpreter if (!_isInitialized) { init(); // will throw } - + if (_configuration.size() == 0) { // goto initial configuration NodeSet 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(), - InterpreterIssue::USCXML_ISSUE_WARNING)); + InterpreterIssue("Reentering during microstep " + flat.getFlatActive() + " - possible endless loop", + Arabica::DOM::Node(), + 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 invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]); @@ -834,17 +834,17 @@ InterpreterState InterpreterImpl::step(int waitForMS) { } } _statesToInvoke = NodeSet(); - + 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 >::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& enabledTransitions) { - + USCXML_MONITOR_CALLBACK(beforeMicroStep) - + exitStates(enabledTransitions); - + for (int i = 0; i < enabledTransitions.size(); i++) { Element 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 enabledTransitions; _stable = false; - + if (_configuration.size() == 0) { // goto initial configuration NodeSet initialTransitions = getDocumentInitialTransitions(); @@ -967,11 +967,11 @@ void InterpreterImpl::stabilize() { } std::set 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 invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]); @@ -1014,14 +1014,14 @@ void InterpreterImpl::stabilize() { Arabica::XPath::NodeSet InterpreterImpl::selectTransitions(const std::string& event) { Arabica::XPath::NodeSet enabledTransitions; - + NodeSet states; for (unsigned int i = 0; i < _configuration.size(); i++) { if (isAtomic(Element(_configuration[i]))) states.push_back(_configuration[i]); } states.to_document_order(); - + unsigned int index = 0; while(states.size() > index) { NodeSet transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", states[index]); @@ -1037,25 +1037,25 @@ Arabica::XPath::NodeSet InterpreterImpl::selectTransitions(const st states.push_back(parent); } } - LOOP: +LOOP: index++; } - + enabledTransitions = removeConflictingTransitions(enabledTransitions); return enabledTransitions; } - - + + Arabica::XPath::NodeSet InterpreterImpl::selectEventlessTransitions() { Arabica::XPath::NodeSet enabledTransitions; - + NodeSet states; for (unsigned int i = 0; i < _configuration.size(); i++) { if (isAtomic(Element(_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 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 InterpreterImpl::selectEventlessTransitions } std::cout << std::endl; #endif - + enabledTransitions = removeConflictingTransitions(enabledTransitions); return enabledTransitions; } @@ -1105,7 +1105,7 @@ bool InterpreterImpl::isEnabledTransition(const Element& transition } else { return false; } - + std::list eventNames = tokenizeIdRefs(eventName); std::list::iterator eventIter = eventNames.begin(); while(eventIter != eventNames.end()) { @@ -1117,7 +1117,7 @@ bool InterpreterImpl::isEnabledTransition(const Element& transition return false; } - + InterpreterState InterpreterImpl::getInterpreterState() { return _state; } @@ -1217,19 +1217,19 @@ std::list 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)scxmls.item(0); } - + if (_nsInfo.getNSContext() != NULL) _xpath.setNamespaceContext(*_nsInfo.getNSContext()); @@ -1675,7 +1675,7 @@ void InterpreterImpl::send(const Arabica::DOM::Element& 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& 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& 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& 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 InterpreterImpl::findLCCA(const Arabica::XPath:: } std::cout << std::endl << std::flush; #endif - + Arabica::XPath::NodeSet ancestors = getProperAncestors(states[0], Arabica::DOM::Node()); Arabica::DOM::Node ancestor; - + for (int i = 0; i < ancestors.size(); i++) { if (!isCompound(Element(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 InterpreterImpl::getInitialStates(Arabica:: if (isAtomic(state)) { return Arabica::XPath::NodeSet(); } - + assert(isCompound(state) || isParallel(state)); if (isParallel(state)) { return getChildStates(state); } - + // initial attribute at element Arabica::DOM::Element stateElem = (Arabica::DOM::Element)state; if (stateElem.hasAttribute("initial")) { @@ -2873,7 +2878,10 @@ NodeSet InterpreterImpl::filterChildElements(const std::string& tag NodeSet InterpreterImpl::filterChildType(const Node_base::Type type, const NodeSet& nodeSet, bool recurse) { NodeSet 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& config) { } } - - + + // When the configuration contains an atomic state, it contains all of its and ancestors. for (int i = 0; i < config.size(); i++) { if (isAtomic(Element(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 _monitors; std::set _microstepConfigurations; - + long _lastRunOnMainThread; std::string _name; std::string _sessionId; @@ -635,7 +635,7 @@ public: std::list 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& node, std::map >& sets) { NodeList childs = node.getChildNodes(); @@ -60,10 +60,10 @@ NodeSet getReachableStates(const Node& 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 getReachableStates(const Node& scxml, Interpre } catch (Event e) { } } - + // reachable per target attribute in transitions for (int i = 0; i < reachable.size(); i++) { Element state = Element(reachable[i]); @@ -102,7 +102,7 @@ NodeSet getReachableStates(const Node& scxml, Interpre } } } - + // reachable via a reachable child state for (int i = 0; i < reachable.size(); i++) { Element state = Element(reachable[i]); @@ -121,17 +121,17 @@ NodeSet getReachableStates(const Node& scxml, Interpre } } } - + return reachable; } - + std::list InterpreterIssue::forInterpreter(InterpreterImpl* interpreter) { // some things we need to prepare first if (interpreter->_factory == NULL) interpreter->_factory = Factory::getInstance(); interpreter->setupDOM(); - + std::list issues; if (!interpreter->_scxml) { @@ -141,23 +141,23 @@ std::list InterpreterIssue::forInterpreter(InterpreterImpl* in } std::map > seenStates; - + // get some aliases Element& _scxml = interpreter->_scxml; NameSpaceInfo& _nsInfo = interpreter->_nsInfo; Factory* _factory = interpreter->_factory; DataModel& _dataModel = interpreter->_dataModel; - - + + std::map > nodeSets; assembleNodeSets(_nsInfo.xmlNSPrefix, _scxml, nodeSets); - - + + NodeSet scxmls = nodeSets["scxml"]; scxmls.push_back(_scxml); NodeSet reachable = getReachableStates(_scxml, interpreter, _nsInfo.xmlNSPrefix); - + NodeSet& states = nodeSets["state"]; NodeSet& parallels = nodeSets["parallel"]; NodeSet& transitions = nodeSets["transition"]; @@ -298,13 +298,13 @@ std::list InterpreterIssue::forInterpreter(InterpreterImpl* in } } - + for (int i = 0; i < allStates.size(); i++) { Element state = Element(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::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::forInterpreter(InterpreterImpl* in } seenStates[ATTR(state, "id")] = state; } - + for (int i = 0; i < transitions.size(); i++) { Element transition = Element(transitions[i]); - + // check for valid target std::list targetIds = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "target")); for (std::list::iterator targetIter = targetIds.begin(); targetIter != targetIds.end(); targetIter++) { @@ -345,7 +345,7 @@ std::list InterpreterIssue::forInterpreter(InterpreterImpl* in NodeSet transitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", state, false); transitions.to_document_order(); - + for (int j = 1; j < transitions.size(); j++) { Element transition = Element(transitions[j]); for (int k = 0; k < j; k++) { @@ -358,7 +358,7 @@ std::list 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 events = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "event")); @@ -370,7 +370,7 @@ std::list 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::forInterpreter(InterpreterImpl* in } } } - NEXT_TRANSITION:; +NEXT_TRANSITION: + ; } } @@ -410,7 +411,7 @@ std::list 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::forInterpreter(InterpreterImpl* in } } } - + // check that all custom executable content is known { NodeSet allExecContentContainers; @@ -446,7 +447,7 @@ std::list 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 block = Element(allExecContentContainers[i]); NodeSet execContents = InterpreterImpl::filterChildType(Node_base::ELEMENT_NODE, block); @@ -473,7 +474,7 @@ std::list InterpreterIssue::forInterpreter(InterpreterImpl* in issues.push_back(InterpreterIssue("Parent of " + localName + " is no element", element, InterpreterIssue::USCXML_ISSUE_WARNING)); continue; } - + Element parent = Element(element.getParentNode()); std::string parentName = LOCALNAME(parent); @@ -490,13 +491,13 @@ std::list 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::forInterpreter(InterpreterImpl* in } } - + // test all scripts for valid syntax { for (int i = 0; i < scripts.size(); i++) { Element script = Element(scripts[i]); - + if (script.hasChildNodes()) { // search for the text node with the actual script std::string scriptContent; @@ -522,7 +523,7 @@ std::list 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::forInterpreter(InterpreterImpl* in withCondAttrs.push_back(transitions); withCondAttrs.push_back(ifs); withCondAttrs.push_back(elseIfs); - + for (int i = 0; i < withCondAttrs.size(); i++) { Element condAttr = Element(withCondAttrs[i]); if (HAS_ATTR(condAttr, "cond")) { @@ -555,7 +556,7 @@ std::list 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 withExprAttr = Element(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 node, IssueSeverity severity); std::string xPath; std::string message; Arabica::DOM::Node node; IssueSeverity severity; - + private: static std::list 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::const_iterator listIter; std::stringstream labelSS; std::string seperator; - + labelSS << "active: "; 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 << "
init: "; - + 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 = "
"; - + labelSS << "
history: "; - + std::map >::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 > 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& transition = Arabica::DOM::Element()) { 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 InterpreterRC::removeConflictingTransitions(const Arabica::XPath::NodeSet& enabledTransitions) { Arabica::XPath::NodeSet filteredTransitions; - for (unsigned int i = 0; i < enabledTransitions.size(); i++) { Element t1(enabledTransitions[i]); bool t1Preempted = false; Arabica::XPath::NodeSet transitionsToRemove; for (unsigned int j = 0; j < filteredTransitions.size(); j++) { - Element t2(enabledTransitions[j]); + Element 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& enabl NodeSet invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToExit[i]); for (int j = 0; j < invokes.size(); j++) { Element invokeElem = (Element)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& 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 invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", s); + for (unsigned int j = 0; j < invokes.size(); j++) { + Element invokeElem = Element(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 uninvokes = filterChildElements(_nsInfo.xmlNSPrefix + "uninvoke", s); + for (int j = 0; j < uninvokes.size(); j++) { + Element uninvokeElem = (Element)uninvokes[j]; + cancelInvoke(uninvokeElem); + } + } + // std::cout << "HIST?: " << ATTR(s, "id") << std::endl; if (defaultHistoryContent.find(ATTR(s, "id")) != defaultHistoryContent.end()) { executeContent(Element(defaultHistoryContent[ATTR(s, "id")])); @@ -311,14 +331,14 @@ void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet& // add all descendants in a dedicated first step for (int i = 0; i < transitions.size(); i++) { Element t(transitions[i]); - + NodeSet targets = getTargetStates(t); for (int j = 0; j < targets.size(); j++) { Element s = Element(targets[j]); addDescendantStatesToEnter(s, statesToEnter, statesForDefaultEntry, defaultHistoryContent); } } - + // only now add the ancestors for (int i = 0; i < transitions.size(); i++) { Element t(transitions[i]); @@ -349,7 +369,7 @@ function getEffectiveTargetStates(transition) Arabica::XPath::NodeSet InterpreterRC::getEffectiveTargetStates(const Arabica::DOM::Element& transition) { NodeSet effectiveTargets; - + NodeSet targets; if (isState(transition)) { targets = getInitialStates(transition); @@ -357,7 +377,7 @@ Arabica::XPath::NodeSet InterpreterRC::getEffectiveTargetStates(con } else { targets = getTargetStates(transition); } - + for (int j = 0; j < targets.size(); j++) { Element s = Element(targets[j]); if (isHistory(s)) { @@ -421,19 +441,19 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state); if (transitions.size() > 0) { @@ -451,7 +471,7 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element targets = getTargetStates(Element(transitions[i])); for (int j = 0; j < targets.size(); j++) { @@ -463,19 +483,19 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element& s = Element(targets[i]); addAncestorStatesToEnter(s, state, statesToEnter, statesForDefaultEntry, defaultHistoryContent); } - + } else if(isParallel(state)) { NodeSet childStates = getChildStates(state); - + for (int i = 0; i < childStates.size(); i++) { const Element& child = Element(childStates[i]); - + for (int j = 0; j < statesToEnter.size(); j++) { const Node& 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 ancestors = getProperAncestors(state, ancestor); for (int i = 0; i < ancestors.size(); i++) { const Node& 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(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& enabledTransitions); void exitStates(const Arabica::XPath::NodeSet& enabledTransitions); Arabica::XPath::NodeSet removeConflictingTransitions(const Arabica::XPath::NodeSet& 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 params_t; typedef std::map 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 node) { return INVALID; } } - + if (boost::iequals(node.getLocalName(), "NEWCONTEXTREQUEST")) return NEWCONTEXTREQUEST; if (boost::iequals(node.getLocalName(), "NEWCONTEXTRESPONSE")) @@ -245,7 +245,7 @@ Arabica::DOM::Document StatusRequest::toXML(bool encapsulateInMMI) return doc; } - + MMIEvent MMIEvent::fromXML(Arabica::DOM::Node node, InterpreterImpl* interpreter) { MMIEvent msg; @@ -259,7 +259,7 @@ MMIEvent MMIEvent::fromXML(Arabica::DOM::Node node, InterpreterImpl msg.tagName = msgElem.getLocalName(); Element 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 node, InterpreterImpl* interpreter) { ContextualizedRequest msg(MMIEvent::fromXML(node, interpreter)); FIND_EVENT_NODE(node); - + Element msgElem(node); msg.context = STRING_ATTR_OR_EXPR(msgElem, Context); return msg; @@ -318,7 +318,7 @@ ContextualizedRequest ContextualizedRequest::fromXML(Arabica::DOM::Node node, InterpreterImpl* interpreter) { ExtensionNotification msg(ContextualizedRequest::fromXML(node, interpreter)); FIND_EVENT_NODE(node); - + Element msgElem(node); msg.name = STRING_ATTR_OR_EXPR(msgElem, Name); msg.type = EXTENSIONNOTIFICATION; @@ -347,7 +347,7 @@ ContentRequest ContentRequest::fromXML(Arabica::DOM::Node node, Int if(boost::iequals(contentElem.getLocalName(), "content")) { Arabica::DOM::Node 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 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 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 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 toXML(bool encapsulateInMMI = true) const; static ContextualizedRequest fromXML(Arabica::DOM::Node 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 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 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 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 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 toXML(bool encapsulateInMMI = true) const; static StatusResponse fromXML(Arabica::DOM::Node 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 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 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 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 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 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 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 _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 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 dm = boost::shared_ptr(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& 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& assignElem, - const Node& node, - const std::string& content) { + const Node& node, + const std::string& content) { } void SpiderMonkeyDataModel::assign(const std::string& location, - const Data& data) { + const Data& data) { } void SpiderMonkeyDataModel::init(const Element& dataElem, - const Node& doc, - const std::string& content) { + const Node& doc, + const std::string& content) { }; void SpiderMonkeyDataModel::init(const std::string& location, - const Data& data) { + const Data& data) { } std::string SpiderMonkeyDataModel::andExpressions(std::list 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 V8DataModel::getIOProcessors(v8::Local propert std::map ioProcessors = dataModel->_interpreter->getIOProcessors(); std::map::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 V8DataModel::getInvokers(v8::Local 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 LuaDataModel::create(InterpreterImpl* interpret } catch (luabridge::LuaException e) { LOG(INFO) << e.what(); } - + luabridge::getGlobalNamespace(dm->_luaState).beginClass("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 #include -#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 #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 PromelaDataModel::create(InterpreterImpl* interpreter) { boost::shared_ptr dm = boost::shared_ptr(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 ioProcessors = interpreter->getIOProcessors(); + for (std::map::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 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(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(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::iterator iter = data.array.begin(); iter != data.array.end(); iter++) { + adaptType(*iter); + } + return; + } + + if (data.compound.size() > 0) { + for (std::map::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& 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& 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& assignElem, const Node& 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::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(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::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(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::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(_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(_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(_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 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& dataElem, const Node& node, const std::string& content) { // from + if (HAS_ATTR(dataElem, "id")) { + Element 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 -#include +//#include +#include #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 expr_lst */ -%type expr pfld varref decl_lst stmnt_lst vardcl ivar var_list one_decl prargs -%type stmnt Stmnt const_expr nlst vis arg +%type expr pfld sfld varref decl_lst stmnt_lst vardcl ivar var_list one_decl prargs utype cmpnd +%type 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& 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 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 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 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 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 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 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 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 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::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 _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 +#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 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 imported = _flatDoc.importNode(childs[i], true); \ transientState.appendChild(imported); \ @@ -52,6 +62,15 @@ if (childs.size() > 0) { \ } \ childs = NodeSet(); +#define DETAIL_EXEC_CONTENT(field, actPtr) \ +std::cerr << " " << #field << " / " << TAGNAME_CAST(actPtr->field) << " ("; \ +NodeSet 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& doc) { _lastTimeStamp = tthread::chrono::system_clock::now(); _currGlobalTransition = NULL; _lastTransientStateId = 0; - + // just copy given doc into _document an create _flatDoc for the FSM DOMImplementation domFactory = Arabica::SimpleDOM::DOMImplementation::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 invokers = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true); + for (int i = 0; i < invokers.size(); i++) { + Element invokerElem = Element(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 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 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= 0; i--) { indexedTransitions.push_back(Element(levelTransitions[i])); } - + Arabica::XPath::NodeSet nextLevel = filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, root); for (int i = nextLevel.size() - 1; i >= 0; i--) { Element stateElem = Element(nextLevel[i]); @@ -424,7 +453,7 @@ bool GlobalTransition::operator< (const GlobalTransition& other) const { const std::list >& indexedTransitions = interpreter->indexedTransitions; for (std::list >::const_reverse_iterator transIter = indexedTransitions.rbegin(); transIter != indexedTransitions.rend(); transIter++) { const Element& 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 allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", configuration); @@ -534,7 +563,7 @@ void FlatteningInterpreter::explode() { std::map 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::max(); - int nrDepth = 0; - int prioPerLevel = 0; - for (int i = 0; i < transitions.size(); i++) { - int depth = strTo(ATTR_CAST(transitions[i], "depth")); - if (depth != currDepth) - continue; - nrDepth++; - int order = strTo(ATTR_CAST(transitions[i], "order")); - if (order < lowestOrder) - lowestOrder = order; - prioPerLevel += pow(static_cast(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(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(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 > sortedStates; sortedStates.insert(sortedStates.begin(), _globalConf.begin(), _globalConf.end()); std::sort(sortedStates.begin(), sortedStates.end(), sortStatesByIndex); - + int index = 0; for (std::list >::reverse_iterator transIter = indexedTransitions.rbegin(); transIter != indexedTransitions.rend(); transIter++) { const Element& refTrans = *transIter; std::cerr << index++ << ": " << refTrans << std::endl; } std::cerr << std::endl; - + for (std::vector >::iterator confIter = sortedStates.begin(); confIter != sortedStates.end(); confIter++) { @@ -761,8 +768,7 @@ void FlatteningInterpreter::createDocument() { } -template bool PtrComp(const T * const & a, const T * const & b) -{ +template 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 reapplyUniquePredicates(std::list list) { - + for (std::list::iterator outerIter = list.begin(); - outerIter != list.end(); - outerIter++) { + outerIter != list.end(); + outerIter++) { for (std::list::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 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 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 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 currActiveStates = flatId.getActive(); - NodeSet transientStateChain; +// std::cerr << "From " << globalTransition->source << " to " << globalTransition->destination << ":" << std::endl; // gather content for new transient state NodeSet childs; - // iterate all actions taken during the transition for (std::list::iterator actionIter = globalTransition->actions.begin(); actionIter != globalTransition->actions.end(); actionIter++) { if (actionIter->transition) { +// DETAIL_EXEC_CONTENT(transition, actionIter); + Element onexit = _flatDoc.createElementNS(_nsInfo.nsURL, "onexit"); _nsInfo.setPrefix(onexit); Node child = actionIter->transition.getFirstChild(); @@ -935,24 +920,31 @@ Node 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 invokeElem = Element(actionIter->invoke); invokeElem.setAttribute("persist", "true"); @@ -961,6 +953,7 @@ Node FlatteningInterpreter::globalTransitionToNode(GlobalTransition } if (actionIter->uninvoke) { +// DETAIL_EXEC_CONTENT(uninvoke, actionIter); Element uninvokeElem = _flatDoc.createElementNS(_nsInfo.nsURL, "uninvoke"); _nsInfo.setPrefix(uninvokeElem); @@ -980,7 +973,20 @@ Node 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 datamodel = filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", actionIter->entered); @@ -990,46 +996,58 @@ Node 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 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 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 prevExitTransitionElem; + for (int i = 0; i < transientStateChain.size(); i++) { Element transientStateElem = Element(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 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& activeStates_, const Arabica::XPath::NodeSet& alreadyEnteredStates_, // we need to remember for binding=late const std::map >& 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& activeState break; } } - + // sort configuration activeStates.to_document_order(); alreadyEnteredStates.to_document_order(); @@ -1176,6 +1194,9 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet& 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 #include #include @@ -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& activeStates, const Arabica::XPath::NodeSet& alreadyEnteredStates, // we need to remember for binding=late const std::map >& historyStates, - const std::string& xmlNSPrefix); + const std::string& xmlNSPrefix); Arabica::XPath::NodeSet activeStates; Arabica::XPath::NodeSet 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 getCommonEvents(const Arabica::XPath::NodeSet& transitions); }; -class USCXML_API FlatteningInterpreter : public InterpreterDraft6, public InterpreterMonitor { +class USCXML_API FlatteningInterpreter : public InterpreterRC, public InterpreterMonitor { public: FlatteningInterpreter(const Arabica::DOM::Document& doc); virtual ~FlatteningInterpreter(); @@ -161,7 +161,7 @@ protected: int maxOrder; size_t _lastTransientStateId; - + Arabica::DOM::Document _flatDoc; std::map _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 #include #include "uscxml/UUID.h" @@ -27,6 +30,15 @@ #include #include +#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 eventNames = trie->getChildsWithWords(trie->getNodeWithPrefix("")); + std::list eventNames = trie.getChildsWithWords(trie.getNodeWithPrefix("")); std::list::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::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& 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 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::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(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::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::const_iterator litIter = _strMacroNames.begin(); litIter != _strMacroNames.end(); litIter++) { + boost::replace_all(replaced, "'" + litIter->first + "'", litIter->second); + } + return replaced; +} + +std::set PromelaCodeAnalyzer::getEventsWithPrefix(const std::string& prefix) { + std::set eventNames; + std::list trieNodes = _eventTrie.getWordsWithPrefix(prefix); + + std::list::iterator trieIter = trieNodes.begin(); + while(trieIter != trieNodes.end()) { + eventNames.insert((*trieIter)->value); + trieIter++; + } + + return eventNames; +} + + void FSMToPromela::writeEvents(std::ostream& stream) { - std::list eventNames = _eventTrie.getWordsWithPrefix(""); - std::list::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 events = _analyzer.getEvents(); + std::map::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 origStates = _analyzer.getOrigStates(); + for (std::map::iterator origIter = origStates.begin(); origIter != origStates.end(); origIter++) { + stream << "#define " << _analyzer.macroForLiteral(origIter->first) << " " << origIter->second; + stream << " /* from \"" << origIter->first << "\" */" << std::endl; } +// std::map states = _analyzer.getStates(); +// size_t stateIndex = 0; +// for (std::map::iterator stateIter = states.begin(); stateIter != states.end(); stateIter++) { +// stream << "_x" +// std::list origStates = _analyzer.getOrigState(stateIter->first); +// size_t origIndex = 0; +// for (std::list::iterator origIter = origStates.begin(); origIter != origStates.end(); origIter++) { +// +// } +// } } -Arabica::XPath::NodeSet FSMToPromela::getTransientContent(const Arabica::DOM::Element& state) { +void FSMToPromela::writeTypeDefs(std::ostream& stream) { + stream << "/* typedefs */" << std::endl; + PromelaCodeAnalyzer::PromelaTypedef typeDefs = _analyzer.getTypes(); + if (typeDefs.types.size() == 0) + return; + + std::list individualDefs; + std::list 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::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::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::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::iterator typeIter = allTypes.types.begin(); + while(typeIter != allTypes.types.end()) { + stream << typeIter->second.name << " " << typeIter->first << ";" << std::endl; + typeIter++; + } + +} + +Arabica::XPath::NodeSet FSMToPromela::getTransientContent(const Arabica::DOM::Element& state, const std::string& source) { Arabica::XPath::NodeSet content; Arabica::DOM::Element 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 allOrigStates = _analyzer.getOrigStates(); + for (std::map::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 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 transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", currState); currState = _states[ATTR_CAST(transitions[0], "target")]; } - return content; } Node FSMToPromela::getUltimateTarget(const Arabica::DOM::Element& transition) { + if (!HAS_ATTR(transition, "target")) { + return transition.getParentNode(); + } + Arabica::DOM::Element 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& node, int indent) { +void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::DOM::Node& 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 nodeElem = Arabica::DOM::Element(node); + if (false) { - } else if(TAGNAME(node) == "state") { - if (HAS_ATTR(node, "transient") && DOMUtils::attributeIsTrue(ATTR(node, "transient"))) { - Arabica::XPath::NodeSet execContent = getTransientContent(node); - for (int i = 0; i < execContent.size(); i++) { - writeExecutableContent(stream, Arabica::DOM::Element(execContent[i]), indent); - } - } else { - Arabica::DOM::Node child = node.getFirstChild(); - while(child) { - writeExecutableContent(stream, Arabica::DOM::Element(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 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 source = node.getParentNode(); + stream << " /* from state " << ATTR_CAST(source, "id") << " */" << std::endl; + + // gather all executable content + NodeSet 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 newState = getUltimateTarget(node); + Node 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 allOrigStates = _analyzer.getOrigStates(); +// for (std::map::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(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 child = node.getFirstChild(); while(child) { - writeExecutableContent(stream, Arabica::DOM::Element(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 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 child = node.getFirstChild(); while(child) { - writeExecutableContent(stream, Arabica::DOM::Element(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 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 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 sendParams = filterChildElements(_nsInfo.xmlNSPrefix + "param", nodeElem); + NodeSet 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 paramElem = Element(sendParams[i]); + stream << padding << " tmpEvent.data." << ATTR(paramElem, "name") << " = " << ATTR(paramElem, "expr") << ";" << std::endl; + } + } + if (sendNameList.size() > 0) { + std::list nameListIds = tokenizeIdRefs(sendNameList); + std::list::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 contentElem = Element(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 child; + Arabica::DOM::Node child; if (TAGNAME(ifNode) == "if") { - child = Arabica::DOM::Element(ifNode.getFirstChild()); + child = ifNode.getFirstChild(); } else { - child = Arabica::DOM::Element(ifNode.getNextSibling()); + child = ifNode.getNextSibling(); } while(child) { if (child.getNodeType() == Node_base::ELEMENT_NODE) { - if (TAGNAME(child) == "elseif" || TAGNAME(child) == "else") + Arabica::DOM::Element childElem = Arabica::DOM::Element(child); + if (TAGNAME(childElem) == "elseif" || TAGNAME_CAST(childElem) == "else") break; + writeExecutableContent(stream, childElem, indent + 1); } - writeExecutableContent(stream, child, indent + 1); - child = Arabica::DOM::Element(child.getNextSibling()); + child = child.getNextSibling(); } stream << padding << "}" << std::endl; stream << padding << ":: else -> "; if (nextIsElse) { - child = Arabica::DOM::Element(condChain[1].getNextSibling()); + child = condChain[1].getNextSibling(); stream << "{" << std::endl; while(child) { - writeExecutableContent(stream, child, indent + 1); - child = Arabica::DOM::Element(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 literals = _analyzer.getLiterals(); + std::map events = _analyzer.getEvents(); + std::map origStates = _analyzer.getOrigStates(); + + for (std::set::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 datas = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "data", _scxml).asNodeSet(); - NodeSet dataText = filterChildType(Node_base::TEXT_NODE, datas, true); +// NodeSet 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 data = dataText[i]; - stream << beautifyIndentation(data.getNodeValue()) << std::endl; + stream << "/* datamodel variables */" << std::endl; + std::set processedIdentifiers; + for (int i = 0; i < datas.size(); i++) { + + Node 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 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 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(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 transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _globalStates[i]); for (int j = 0; j < transitions.size(); j++) { - writeExecutableContent(stream, Arabica::DOM::Element(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 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& 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 currTrans = Element(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 trieNodes = _eventTrie.getWordsWithPrefix(eventDesc); + tmpSS << padding << ":: ("; + } - std::list::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 eventNames = tokenizeIdRefs(eventDescs); + std::set eventPrefixes; + std::list::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 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::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::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 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(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 invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true); + NodeSet 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 promelaEventSourceComments; NodeSet 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(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 contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", _scxml, true); + for (int i = 0; i < contents.size(); i++) { + Element contentElem = Element(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 allCode; + std::set allStrings; + { + NodeSet 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 elem = Element(withCond[i]); + if (HAS_ATTR(elem, "cond")) { + std::string code = ATTR(elem, "cond"); + code = sanitizeCode(code); + elem.setAttribute("cond", code); + allCode.insert(code); + } + } + } + { + NodeSet 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 elem = Element(withExpr[i]); + if (HAS_ATTR(elem, "expr")) { + std::string code = ATTR(elem, "expr"); + code = sanitizeCode(code); + elem.setAttribute("expr", code); + allCode.insert(code); + } + } + } + { + NodeSet withLocation; + withLocation.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "assign", _scxml, true)); + for (int i = 0; i < withLocation.size(); i++) { + Element elem = Element(withLocation[i]); + if (HAS_ATTR(elem, "location")) { + std::string code = ATTR(elem, "location"); + code = sanitizeCode(code); + elem.setAttribute("location", code); + allCode.insert(code); + } + } + } + { + NodeSet 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 texts = filterChildType(Node_base::TEXT_NODE, withText[i], true); + for (int j = 0; j < texts.size(); j++) { + if (texts[j].getNodeValue().size() > 0) { + Text elem = Text(texts[j]); + std::string code = elem.getNodeValue(); + code = sanitizeCode(code); + elem.setNodeValue(code); + allCode.insert(code); + } + } + } + } + for (std::set::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 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 getLiterals() { + return _strLiterals; + } + std::set getEventsWithPrefix(const std::string& prefix); + std::map& getEvents() { + return _events; + } + + std::map& getStates() { + return _states; + } + + std::map& getOrigStates() { + return _origStateIndex; + } + + std::list& 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 _strLiterals; // all string literals + std::map _strMacroNames; // macronames for string literals + std::map _strIndex; // integer enumeration for string + std::map _origStateIndex; // state enumeration for original states + + std::map _states; + std::map > _origStateMap; // states from the original state chart + std::map _events; + + PromelaTypedef _typeDefs; + + Trie _eventTrie; + +private: + std::set _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 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& node, int indent = 0); + void writeExecutableContent(std::ostream& stream, const Arabica::DOM::Node& node, int indent = 0); void writeInlineComment(std::ostream& stream, const Arabica::DOM::Node& 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& condChain, int indent = 0); void writeDispatchingBlock(std::ostream& stream, const Arabica::XPath::NodeSet& transChain, int indent = 0); - Arabica::XPath::NodeSet getTransientContent(const Arabica::DOM::Element& state); + Arabica::XPath::NodeSet getTransientContent(const Arabica::DOM::Element& state, const std::string& source = ""); Arabica::DOM::Node getUltimateTarget(const Arabica::DOM::Element& transition); static PromelaInlines getInlinePromela(const std::string&); static PromelaInlines getInlinePromela(const Arabica::XPath::NodeSet& elements, bool recurse = false); static PromelaInlines getInlinePromela(const Arabica::DOM::Node& elements); - Trie _eventTrie; +// std::string replaceStringsInExpression(const std::string& expr); + + std::string sanitizeCode(const std::string& code); + Arabica::XPath::NodeSet _globalStates; Arabica::DOM::Node _startState; std::map > _states; std::map, int> _transitions; + std::list _varInitializers; + + PromelaCodeAnalyzer _analyzer; + std::map _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& activeStates, - const Arabica::XPath::NodeSet& alreadyEnteredStates, - const std::map >& historyStates) { + const Arabica::XPath::NodeSet& alreadyEnteredStates, + const std::map >& 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& active, - const std::list& visited, - const std::map >& histories) : active(active), visited(visited), histories(histories) { + const std::list& visited, + const std::map >& histories) : active(active), visited(visited), histories(histories) { initStateId(); } - + + static std::string toStateId(const std::list active, + const std::list visited = std::list(), + const std::map > histories = std::map >()) { + 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& getActive() { return active; } @@ -157,17 +182,17 @@ protected: std::list active; std::list visited; std::map > 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::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 +#include 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 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 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 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 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 issueLocationsForXML(const std::string xml) { Interpreter interpreter = Interpreter::fromXML(xml); std::list issues = interpreter.validate(); - + std::set issueLocations; - + for (std::list::iterator issueIter = issues.begin(); issueIter != issues.end(); issueIter++) { std::cout << *issueIter << std::endl; issueLocations.insert(issueIter->xPath); @@ -20,7 +20,9 @@ std::set 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 = - "" - " " - " " - " " - " 0\" />" - " " - " " - " " - ""; - + "" + " " + " " + " " + " 0\" />" + " " + " " + " " + ""; + 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 = - "" - " " - " " - " " - " " - " " - " " - " " - " " - ""; - + "" + " " + " " + " " + " " + " " + " " + " " + " " + ""; + std::set 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 = - "" - " " - " " - " " - ""; - + "" + " " + " " + " " + ""; + std::set 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 = - "" - " " - " " - " " - ""; + "" + " " + " " + " " + ""; std::set 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 = - "" - " " - " " - ""; - + "" + " " + " " + ""; + std::set 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 = - "" - " " - " " - " " - ""; - + "" + " " + " " + " " + ""; + std::set 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 = - "" - " " - " " - " " - " " - " " - ""; - + "" + " " + " " + " " + " " + " " + ""; + std::set 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 = - "" - " " - " " - " " - " " - " " - ""; - + "" + " " + " " + " " + " " + " " + ""; + std::set 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 = - "" - ""; - + "" + ""; + std::set 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 = - "" - " " - " " - " " - ""; - + "" + " " + " " + " " + ""; + std::set 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 = - "" - " " - " " - " " - " " - " " - ""; - + "" + " " + " " + " " + " " + " " + ""; + std::set 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 = - "" - ""; - + "" + ""; + std::set 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 = - "" - " " - " " - " " - " " - " " - ""; - + "" + " " + " " + " " + " " + " " + ""; + std::set 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 = - "" - " " - ""; - + "" + " " + ""; + std::set 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 = - "" - " " - " " - " " - " " - " " - " " - " " - " " - ""; - + "" + " " + " " + " " + " " + " " + " " + " " + " " + ""; + std::set 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 = - "" - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - ""; - + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + std::set 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 = - "" - " " - " " - " " - " " - " " - " " - ""; - + "" + " " + " " + " " + " " + " " + " " + ""; + std::set 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 = - "" - " " - " " - " " - " " - " " - ""; - + "" + " " + " " + " " + " " + " " + ""; + std::set 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 = - "" - " " - " " - " " - ""; - + "" + " " + " " + " " + ""; + std::set 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 = - "" - " " - " " - " " - " " - " " - ""; - + "" + " " + " " + " " + " " + " " + ""; + std::set 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 << ""; - + 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 lock(Mutex); - + const Arabica::DOM::Document& 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 newCtxReqXML1 = newCtxReq.toXML(); Arabica::DOM::Document 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 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(dfEnv); } - + int option; while ((option = getopt(argc, argv, "fd:")) != -1) { switch(option) { - case 'f': - withFlattening = true; - break; - case 'd': - delayFactor = strTo(optarg); - break; - default: - break; + case 'f': + withFlattening = true; + break; + case 'd': + delayFactor = strTo(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 document = interpreter.getDocument(); Arabica::DOM::Element root = document.getDocumentElement(); Arabica::XPath::NodeSet sends = InterpreterImpl::filterChildElements(interpreter.getNameSpaceInfo().xmlNSPrefix + "send", root, true); - + for (int i = 0; i < sends.size(); i++) { Arabica::DOM::Element send = Arabica::DOM::Element(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 @@ - 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 @@ + + + + + + + + + + + + + + + + + + + pass + + + + + + + + + + + + + + fail + + + + + + + + + + + + + promela + + + + + + + Var + int[3] + + + + Var + string + + + + Var + string + + + + Var + string + + + + Var + int + + + + + Var + + + + + + Var + + + + + foo.bar.baz + + + + + + + + + + + + + + + + + + Var + + + + + '' + + + + + Var + + + + + Var + + + + + + + + + + + Var.bar + + + + + + return + + + + + + Var + Var + 1 + + + + + + + Var + Var + Var + + + + + + +Var +Var + Var + + + + + + baz + + + + + #_scxml_foo + + + + + xyz + + + + + foo + + +123 + + + + 27 + + + + + 27 + + + + + 27 + + + + + + _event.name + + + + _event.type + + + + _event.sendid + + + + _event. + + + + + _event.raw + + + + + + _event.data. + + + + + _event.data. + + + + _event.data.Var + + + + + _ioprocessors.scxml.location + + + + + + + Var + + + + + Var + + + + + Var + + + + + Var + + + + + 's' + + + + + Var + + + + + Var + + + + + Var + + + + + Var + + + + + "foo + + + + + + + + + + + Var + + + == + + + + + + + + + + + + + Var + + + == + + Var + + + + + + + + + + + + Var + + + == + + + + + + + + + + + + + + Var==Var + + + + + + + + + + Var==Var + + + + + + + + + +Var + +== +'' + + + + + + + + + Var + + + = + + Var + + + + + + + + Var == 123 + + + + + _event.name == '' + + + + + + + + _event.data.Var + + + == + + + + + + + + + + + + + + + + +Var + +== + + + + + + + + + _event.data == + + + + + _event.data == 123 + + + + !(_event.data) + + + + + _name == '' + + + + + + + + +(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 && str.slice(0, starts.length) == starts;})(Var, Var) + + + + + + + _x.states[''] + + + + + return + + + + + Var[1] + + + + Var + + + + + !(Var) + + + + + + + + + + !Var + + + + + true + + + + + false + + + + + _event.name && _event.type + + + + + in _event.data + + + + + !(_event.) + + + + + _event.language == 'promela' + + + + + _event.origintype == '' + + + + + + + + + + + + + + D:\W3C\SCXMLTests\test300.js + + + + D:\foo + + + + + + + _event.origin + _event.origintype + + + + + + + Var[0] = 1; + Var[1] = 2; + Var[2] = 3; + + + + + Var + + + + + Var + + + + + + 1, 2, 3] + + + + + 7 + + + + Var + + + + + 'continue' + + + + Var + + + + + + Var + [].concat(Var, [4]) + + + + + + [[,],[,]] + + + + + + Var + + item + index + + + + + + + + + + Var + +[0][0]== && [0][1] == && [1][0] == && [1][1] == + + + + + + + + + + SITE_SPECIFIC_ADDRESS + + + + + + + + + + _ioprocessors.basichttp.location + + + + _ioprocessors.basichttp.location + + + + + _event.raw.search('POST') !== -1 + + + + + + +Var + + + + + + + _event.type == 'external' + + + + + +_event.raw.search(/Var=/) !== -1 + + + + + + _event.raw.search('=') !== -1 + + + + _event.raw.search(//) !== -1 + + + + + + _event.raw.match(/=(\S+)$/)[1] + + + + + _event.raw.match(/Var=(\S+)$/)[1] + + + + txt.match(/\n\n(.*)/)[2].split('&')[].split('=')[0] + + + + txt.match(/\n\n(.*)/)[2].split('&')[].split('=')[1] + + + + + '<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"' + '"' + + '"' + />' + + + + + + 'address=' + _ioprocessors['basichttp'] + "'" + + + + + + _event.raw.match(/\n\naddress=(.*)$/) + + \ 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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 @@
- + - + - + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + Var3[0] = 1; + Var3[1] = 2; + Var3[2] = 3; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + Var3[0] = 1; + Var3[1] = 2; + Var3[2] = 3; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + Var5[0] = 1; + Var5[1] = 2; + Var5[2] = 3; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + Var3[0] = 1; + Var3[1] = 2; + Var3[2] = 3; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + Var3[0] = 1; + Var3[1] = 2; + Var3[2] = 3; + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + Var3[0] = 1; + Var3[1] = 2; + Var3[2] = 3; + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + 123 + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + 123 + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + foo + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 123 + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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' \ + + +--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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + this is some content + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + Var1[0] = 1; + Var1[1] = 2; + Var1[2] = 3; + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + 21 + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + some content + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + \ 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 @@ + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + Var1[0] = 1; + Var1[1] = 2; + Var1[2] = 3; + + + + + + + + + + + \ 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 @@ + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + \ 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ +xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" conf:datamodel="" binding="late">